@@ -502,6 +502,14 @@ u8 rtw_regd_get(struct rtw_dev *rtwdev)
}
EXPORT_SYMBOL(rtw_regd_get);
+bool rtw_regd_srrc(struct rtw_dev *rtwdev)
+{
+ struct rtw_regd *regd = &rtwdev->regd;
+
+ return rtw_reg_match(regd->regulatory, "CN");
+}
+EXPORT_SYMBOL(rtw_regd_srrc);
+
struct rtw_regd_alternative_t {
bool set;
u8 alt;
@@ -68,4 +68,6 @@ int rtw_regd_init(struct rtw_dev *rtwdev);
int rtw_regd_hint(struct rtw_dev *rtwdev);
u8 rtw_regd_get(struct rtw_dev *rtwdev);
bool rtw_regd_has_alt(u8 regd, u8 *regd_alt);
+bool rtw_regd_srrc(struct rtw_dev *rtwdev);
+
#endif
@@ -381,6 +381,65 @@ static void rtw8821c_set_channel_rxdfir(struct rtw_dev *rtwdev, u8 bw)
}
}
+static void rtw8821c_cck_tx_filter_srrc(struct rtw_dev *rtwdev, u8 channel, u8 bw)
+{
+ struct rtw_hal *hal = &rtwdev->hal;
+
+ if (channel == 14) {
+ rtw_write32_mask(rtwdev, REG_CCA_FLTR, MASKHWORD, 0xe82c);
+ rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x0000b81c);
+ rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x0000);
+ rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD, 0x00003667);
+
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00002);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001e);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001c);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000e);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000c);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00000);
+ } else if (channel == 13 ||
+ (channel == 11 && bw == RTW_CHANNEL_WIDTH_40)) {
+ rtw_write32_mask(rtwdev, REG_CCA_FLTR, MASKHWORD, 0xf8fe);
+ rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x64b80c1c);
+ rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x8810);
+ rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD, 0x01235667);
+
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00002);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001e);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00027);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001c);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00027);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000e);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00029);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000c);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00026);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00000);
+ } else {
+ rtw_write32_mask(rtwdev, REG_CCA_FLTR, MASKHWORD, 0xe82c);
+ rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD,
+ hal->ch_param[0]);
+ rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD,
+ hal->ch_param[1] & MASKLWORD);
+ rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD,
+ hal->ch_param[2]);
+
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00002);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001e);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001c);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000e);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000c);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00000);
+ }
+}
+
static void rtw8821c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw,
u8 primary_ch_idx)
{
@@ -395,6 +454,13 @@ static void rtw8821c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw,
rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x0);
rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x96a);
+
+ if (rtw_regd_srrc(rtwdev)) {
+ rtw8821c_cck_tx_filter_srrc(rtwdev, channel, bw);
+ goto set_bw;
+ }
+
+ /* CCK TX filter parameters for default case */
if (channel == 14) {
rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x0000b81c);
rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x0000);
@@ -430,6 +496,7 @@ static void rtw8821c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw,
rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x412);
}
+set_bw:
switch (bw) {
case RTW_CHANNEL_WIDTH_20:
default:
@@ -238,6 +238,7 @@ extern const struct rtw_chip_info rtw8821c_hw_spec;
#define REG_RXSB 0xa00
#define REG_ADCINI 0xa04
#define REG_PWRTH 0xa08
+#define REG_CCA_FLTR 0xa20
#define REG_TXSF2 0xa24
#define REG_TXSF6 0xa28
#define REG_FA_CCK 0xa5c