rtw88: support adaptivity for ETSI/JP DFS region
authorZong-Zhe Yang <kevin_yang@realtek.com>
Mon, 30 Aug 2021 07:20:13 +0000 (15:20 +0800)
committerKalle Valo <kvalo@codeaurora.org>
Tue, 21 Sep 2021 14:51:56 +0000 (17:51 +0300)
Add Energy Detected CCA (EDCCA) mechanism to detect energy on the channel.
And EDCCA support adaptivity mode now. From MIC Ordinance Regulating Radio
Equipment article 49.20, ETSI EN-300-328 and EN-301-893, the device should
be able to dynamically pause TX activity when energy detected on the air.
According to ETSI/JP DFS region, driver will set corresponding threshold
and stop TX activity if the detected energy exceeds the threshold. For now,
we support it on 8822b and 8822c first.

By default, EDCCA mechanism is turned on. For ETSI/JP DFS region, it will
turn to adaptivity mode. However, with adaptivity, if environment is too
noisy, TX may often be halted. So, a debugfs for EDCCA is added. It can
show what EDCCA mode is used currently. And EDCCA mechanism can be turned
on/off through the debugfs while debugging.

Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210830072014.12250-4-pkshih@realtek.com
drivers/net/wireless/realtek/rtw88/debug.c
drivers/net/wireless/realtek/rtw88/main.c
drivers/net/wireless/realtek/rtw88/main.h
drivers/net/wireless/realtek/rtw88/phy.c
drivers/net/wireless/realtek/rtw88/phy.h
drivers/net/wireless/realtek/rtw88/reg.h
drivers/net/wireless/realtek/rtw88/regd.c
drivers/net/wireless/realtek/rtw88/rtw8822b.c
drivers/net/wireless/realtek/rtw88/rtw8822b.h
drivers/net/wireless/realtek/rtw88/rtw8822c.c
drivers/net/wireless/realtek/rtw88/rtw8822c.h

index df0740e84f04c828e86d2f135abc6b95ce704d6b..babf7fb238ccdfd764f207c6ff6aa766b7d77d81 100644 (file)
@@ -829,6 +829,38 @@ static int rtw_debugfs_get_coex_enable(struct seq_file *m, void *v)
        return 0;
 }
 
+static ssize_t rtw_debugfs_set_edcca_enable(struct file *filp,
+                                           const char __user *buffer,
+                                           size_t count, loff_t *loff)
+{
+       struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
+       struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
+       struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
+       bool input;
+       int err;
+
+       err = kstrtobool_from_user(buffer, count, &input);
+       if (err)
+               return err;
+
+       rtw_edcca_enabled = input;
+       rtw_phy_adaptivity_set_mode(rtwdev);
+
+       return count;
+}
+
+static int rtw_debugfs_get_edcca_enable(struct seq_file *m, void *v)
+{
+       struct rtw_debugfs_priv *debugfs_priv = m->private;
+       struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
+       struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+
+       seq_printf(m, "EDCCA %s: EDCCA mode %d\n",
+                  rtw_edcca_enabled ? "enabled" : "disabled",
+                  dm_info->edcca_mode);
+       return 0;
+}
+
 static ssize_t rtw_debugfs_set_fw_crash(struct file *filp,
                                        const char __user *buffer,
                                        size_t count, loff_t *loff)
@@ -1049,6 +1081,11 @@ static struct rtw_debugfs_priv rtw_debug_priv_coex_info = {
        .cb_read = rtw_debugfs_get_coex_info,
 };
 
+static struct rtw_debugfs_priv rtw_debug_priv_edcca_enable = {
+       .cb_write = rtw_debugfs_set_edcca_enable,
+       .cb_read = rtw_debugfs_get_edcca_enable,
+};
+
 static struct rtw_debugfs_priv rtw_debug_priv_fw_crash = {
        .cb_write = rtw_debugfs_set_fw_crash,
        .cb_read = rtw_debugfs_get_fw_crash,
@@ -1132,6 +1169,7 @@ void rtw_debugfs_init(struct rtw_dev *rtwdev)
        }
        rtw_debugfs_add_r(rf_dump);
        rtw_debugfs_add_r(tx_pwr_tbl);
+       rtw_debugfs_add_rw(edcca_enable);
        rtw_debugfs_add_rw(fw_crash);
        rtw_debugfs_add_rw(dm_cap);
 }
index f458496bddd58f39e7db8b5c0a27d2c521741214..cee2acabb0423ef69950a492dad08e46c1a039e8 100644 (file)
@@ -23,6 +23,14 @@ EXPORT_SYMBOL(rtw_disable_lps_deep_mode);
 bool rtw_bf_support = true;
 unsigned int rtw_debug_mask;
 EXPORT_SYMBOL(rtw_debug_mask);
+/* EDCCA is enabled during normal behavior. For debugging purpose in
+ * a noisy environment, it can be disabled via edcca debugfs. Because
+ * all rtw88 devices will probably be affected if environment is noisy,
+ * rtw_edcca_enabled is just declared by driver instead of by device.
+ * So, turning it off will take effect for all rtw88 devices before
+ * there is a tough reason to maintain rtw_edcca_enabled by device.
+ */
+bool rtw_edcca_enabled = true;
 
 module_param_named(disable_lps_deep, rtw_disable_lps_deep_mode, bool, 0644);
 module_param_named(support_bf, rtw_bf_support, bool, 0644);
index 2e5cebba1f214a1ada2eed750f53e4f4c5ea5c65..723316347876e6dbbac6d3bebff65b6a3b8658fb 100644 (file)
@@ -41,6 +41,7 @@
 extern bool rtw_bf_support;
 extern bool rtw_disable_lps_deep_mode;
 extern unsigned int rtw_debug_mask;
+extern bool rtw_edcca_enabled;
 extern const struct ieee80211_ops rtw_ops;
 
 #define RTW_MAX_CHANNEL_NUM_2G 14
@@ -545,6 +546,11 @@ struct rtw_rf_sipi_addr {
        u32 lssi_read_pi;
 };
 
+struct rtw_hw_reg_offset {
+       struct rtw_hw_reg hw_reg;
+       u8 offset;
+};
+
 struct rtw_backup_info {
        u8 len;
        u32 reg;
@@ -815,6 +821,7 @@ enum rtw_regd_state {
 struct rtw_regd {
        enum rtw_regd_state state;
        const struct rtw_regulatory *regulatory;
+       enum nl80211_dfs_regions dfs_region;
 };
 
 struct rtw_chip_ops {
@@ -852,6 +859,8 @@ struct rtw_chip_ops {
                              struct ieee80211_bss_conf *conf);
        void (*cfg_csi_rate)(struct rtw_dev *rtwdev, u8 rssi, u8 cur_rate,
                             u8 fixrate_en, u8 *new_rate);
+       void (*adaptivity_init)(struct rtw_dev *rtwdev);
+       void (*adaptivity)(struct rtw_dev *rtwdev);
        void (*cfo_init)(struct rtw_dev *rtwdev);
        void (*cfo_track)(struct rtw_dev *rtwdev);
        void (*config_tx_path)(struct rtw_dev *rtwdev, u8 tx_path,
@@ -1207,6 +1216,10 @@ struct rtw_chip_info {
        u8 bfer_su_max_num;
        u8 bfer_mu_max_num;
 
+       struct rtw_hw_reg_offset *edcca_th;
+       s8 l2h_th_ini_cs;
+       s8 l2h_th_ini_ad;
+
        const char *wow_fw_name;
        const struct wiphy_wowlan_support *wowlan_stub;
        const u8 max_sched_scan_ssids;
@@ -1555,6 +1568,20 @@ struct rtw_gapk_info {
        u8 channel;
 };
 
+#define EDCCA_TH_L2H_IDX 0
+#define EDCCA_TH_H2L_IDX 1
+#define EDCCA_TH_L2H_LB 48
+#define EDCCA_ADC_BACKOFF 12
+#define EDCCA_IGI_BASE 50
+#define EDCCA_IGI_L2H_DIFF 8
+#define EDCCA_L2H_H2L_DIFF 7
+#define EDCCA_L2H_H2L_DIFF_NORMAL 8
+
+enum rtw_edcca_mode {
+       RTW_EDCCA_NORMAL        = 0,
+       RTW_EDCCA_ADAPTIVITY    = 1,
+};
+
 struct rtw_cfo_track {
        bool is_adjust;
        u8 crystal_cap;
@@ -1646,6 +1673,8 @@ struct rtw_dm_info {
        struct rtw_gapk_info gapk;
        bool is_bt_iqk_timeout;
 
+       s8 l2h_th_ini;
+       enum rtw_edcca_mode edcca_mode;
        u8 scan_density;
 };
 
index df4ca915228c1c900e3132cd3db8e2965e77838d..e0daf12d2484e48a92bc8615d67b27acca3d5129 100644 (file)
@@ -120,6 +120,63 @@ static void rtw_phy_cck_pd_init(struct rtw_dev *rtwdev)
        dm_info->cck_fa_avg = CCK_FA_AVG_RESET;
 }
 
+void rtw_phy_set_edcca_th(struct rtw_dev *rtwdev, u8 l2h, u8 h2l)
+{
+       struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
+
+       rtw_write32_mask(rtwdev,
+                        edcca_th[EDCCA_TH_L2H_IDX].hw_reg.addr,
+                        edcca_th[EDCCA_TH_L2H_IDX].hw_reg.mask,
+                        l2h + edcca_th[EDCCA_TH_L2H_IDX].offset);
+       rtw_write32_mask(rtwdev,
+                        edcca_th[EDCCA_TH_H2L_IDX].hw_reg.addr,
+                        edcca_th[EDCCA_TH_H2L_IDX].hw_reg.mask,
+                        h2l + edcca_th[EDCCA_TH_H2L_IDX].offset);
+}
+EXPORT_SYMBOL(rtw_phy_set_edcca_th);
+
+void rtw_phy_adaptivity_set_mode(struct rtw_dev *rtwdev)
+{
+       struct rtw_chip_info *chip = rtwdev->chip;
+       struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+
+       /* turn off in debugfs for debug usage */
+       if (!rtw_edcca_enabled) {
+               dm_info->edcca_mode = RTW_EDCCA_NORMAL;
+               rtw_dbg(rtwdev, RTW_DBG_PHY, "EDCCA disabled, cannot be set\n");
+               return;
+       }
+
+       switch (rtwdev->regd.dfs_region) {
+       case NL80211_DFS_ETSI:
+               dm_info->edcca_mode = RTW_EDCCA_ADAPTIVITY;
+               dm_info->l2h_th_ini = chip->l2h_th_ini_ad;
+               break;
+       case NL80211_DFS_JP:
+               dm_info->edcca_mode = RTW_EDCCA_ADAPTIVITY;
+               dm_info->l2h_th_ini = chip->l2h_th_ini_cs;
+               break;
+       default:
+               dm_info->edcca_mode = RTW_EDCCA_NORMAL;
+               break;
+       }
+}
+
+static void rtw_phy_adaptivity_init(struct rtw_dev *rtwdev)
+{
+       struct rtw_chip_info *chip = rtwdev->chip;
+
+       rtw_phy_adaptivity_set_mode(rtwdev);
+       if (chip->ops->adaptivity_init)
+               chip->ops->adaptivity_init(rtwdev);
+}
+
+static void rtw_phy_adaptivity(struct rtw_dev *rtwdev)
+{
+       if (rtwdev->chip->ops->adaptivity)
+               rtwdev->chip->ops->adaptivity(rtwdev);
+}
+
 static void rtw_phy_cfo_init(struct rtw_dev *rtwdev)
 {
        struct rtw_chip_info *chip = rtwdev->chip;
@@ -160,6 +217,7 @@ void rtw_phy_init(struct rtw_dev *rtwdev)
        rtw_phy_cck_pd_init(rtwdev);
 
        dm_info->iqk.done = false;
+       rtw_phy_adaptivity_init(rtwdev);
        rtw_phy_cfo_init(rtwdev);
        rtw_phy_tx_path_div_init(rtwdev);
 }
@@ -712,6 +770,7 @@ void rtw_phy_dynamic_mechanism(struct rtw_dev *rtwdev)
        rtw_phy_cfo_track(rtwdev);
        rtw_phy_dpk_track(rtwdev);
        rtw_phy_pwr_track(rtwdev);
+       rtw_phy_adaptivity(rtwdev);
 }
 
 #define FRAC_BITS 3
index 112ed125970a3d0641c5c49a819a3d96c61d70d8..02d1ec47ffb194683f4a17385a7dc1f5eb23dce8 100644 (file)
@@ -59,6 +59,8 @@ bool rtw_phy_pwrtrack_need_lck(struct rtw_dev *rtwdev);
 bool rtw_phy_pwrtrack_need_iqk(struct rtw_dev *rtwdev);
 void rtw_phy_config_swing_table(struct rtw_dev *rtwdev,
                                struct rtw_swing_table *swing_table);
+void rtw_phy_set_edcca_th(struct rtw_dev *rtwdev, u8 l2h, u8 h2l);
+void rtw_phy_adaptivity_set_mode(struct rtw_dev *rtwdev);
 void rtw_phy_parsing_cfo(struct rtw_dev *rtwdev,
                         struct rtw_rx_pkt_stat *pkt_stat);
 void rtw_phy_tx_path_diversity(struct rtw_dev *rtwdev);
index f5ce75095e904b82b85ab351d35101e5c47d6526..8adac30ee08e25042b562d2834f4e9a9cc053ab9 100644 (file)
 #define REG_AGGR_BREAK_TIME    0x051A
 #define REG_SLOT               0x051B
 #define REG_TX_PTCL_CTRL       0x0520
+#define BIT_DIS_EDCCA          BIT(15)
 #define BIT_SIFS_BK_EN         BIT(12)
 #define REG_TXPAUSE            0x0522
 #define BIT_AC_QUEUE           GENMASK(7, 0)
 #define REG_RD_CTRL            0x0524
+#define BIT_EDCCA_MSK_CNTDOWN_EN BIT(11)
 #define BIT_DIS_TXOP_CFE       BIT(10)
 #define BIT_DIS_LSIG_CFE       BIT(9)
 #define BIT_DIS_STBC_CFE       BIT(8)
index cd50f419f85d4f9ead5670fa0a0f283ce0e2b701..315c2b193e92cbef9cd541de3b757bc8d4eaae5a 100644 (file)
@@ -18,12 +18,13 @@ do {                                                                \
        struct rtw_dev *__d = (_dev);                           \
        const struct rtw_regd *__r =  &__d->regd;               \
        rtw_dbg(__d, RTW_DBG_REGD, _msg                         \
-               "apply alpha2 %c%c, regd {%d, %d}\n",           \
+               "apply alpha2 %c%c, regd {%d, %d}, dfs_region %d\n",\
                ##_args,                                        \
                __r->regulatory->alpha2[0],                     \
                __r->regulatory->alpha2[1],                     \
                __r->regulatory->txpwr_regd_2g,                 \
-               __r->regulatory->txpwr_regd_5g);                \
+               __r->regulatory->txpwr_regd_5g,                 \
+               __r->dfs_region);                               \
 } while (0)
 
 /* If country code is not correctly defined in efuse,
@@ -357,6 +358,7 @@ int rtw_regd_init(struct rtw_dev *rtwdev)
        }
 
        rtwdev->regd.regulatory = &rtw_reg_ww;
+       rtwdev->regd.dfs_region = NL80211_DFS_UNSET;
        rtw_dbg_regd_dump(rtwdev, "regd init state %d: ", rtwdev->regd.state);
 
        rtw_regd_apply_hw_cap_flags(wiphy);
@@ -450,6 +452,7 @@ static bool rtw_regd_state_hdl(struct rtw_dev *rtwdev,
                               struct regulatory_request *request)
 {
        next_regd->regulatory = rtw_reg_find_by_name(request->alpha2);
+       next_regd->dfs_region = request->dfs_region;
        return rtw_regd_handler[rtwdev->regd.state](rtwdev, next_regd, request);
 }
 
@@ -482,6 +485,7 @@ void rtw_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request)
                          request->alpha2[1],
                          request->initiator);
 
+       rtw_phy_adaptivity_set_mode(rtwdev);
        rtw_phy_set_tx_power_level(rtwdev, hal->current_channel);
 }
 
index 49e8420ab33e85634d7241a2c1f229f383beea57..c409c8c29ec8b8c23f5cb232acaf54d7a336f4f7 100644 (file)
@@ -1553,6 +1553,39 @@ static void rtw8822b_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif,
                rtw_warn(rtwdev, "wrong bfee role\n");
 }
 
+static void rtw8822b_adaptivity_init(struct rtw_dev *rtwdev)
+{
+       rtw_phy_set_edcca_th(rtwdev, RTW8822B_EDCCA_MAX, RTW8822B_EDCCA_MAX);
+
+       /* mac edcca state setting */
+       rtw_write32_clr(rtwdev, REG_TX_PTCL_CTRL, BIT_DIS_EDCCA);
+       rtw_write32_set(rtwdev, REG_RD_CTRL, BIT_EDCCA_MSK_CNTDOWN_EN);
+       rtw_write32_mask(rtwdev, REG_EDCCA_SOURCE, BIT_SOURCE_OPTION,
+                        RTW8822B_EDCCA_SRC_DEF);
+       rtw_write32_mask(rtwdev, REG_EDCCA_POW_MA, BIT_MA_LEVEL, 0);
+
+       /* edcca decision opt */
+       rtw_write32_set(rtwdev, REG_EDCCA_DECISION, BIT_EDCCA_OPTION);
+}
+
+static void rtw8822b_adaptivity(struct rtw_dev *rtwdev)
+{
+       struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+       s8 l2h, h2l;
+       u8 igi;
+
+       igi = dm_info->igi_history[0];
+       if (dm_info->edcca_mode == RTW_EDCCA_NORMAL) {
+               l2h = max_t(s8, igi + EDCCA_IGI_L2H_DIFF, EDCCA_TH_L2H_LB);
+               h2l = l2h - EDCCA_L2H_H2L_DIFF_NORMAL;
+       } else {
+               l2h = min_t(s8, igi, dm_info->l2h_th_ini);
+               h2l = l2h - EDCCA_L2H_H2L_DIFF;
+       }
+
+       rtw_phy_set_edcca_th(rtwdev, l2h, h2l);
+}
+
 static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822b[] = {
        {0x0086,
         RTW_PWR_CUT_ALL_MSK,
@@ -2126,6 +2159,8 @@ static struct rtw_chip_ops rtw8822b_ops = {
        .config_bfee            = rtw8822b_bf_config_bfee,
        .set_gid_table          = rtw_bf_set_gid_table,
        .cfg_csi_rate           = rtw_bf_cfg_csi_rate,
+       .adaptivity_init        = rtw8822b_adaptivity_init,
+       .adaptivity             = rtw8822b_adaptivity,
 
        .coex_set_init          = rtw8822b_coex_cfg_init,
        .coex_set_ant_switch    = rtw8822b_coex_cfg_ant_switch,
@@ -2455,6 +2490,11 @@ static const struct rtw_reg_domain coex_info_hw_regs_8822b[] = {
        {0xc50,  MASKBYTE0, RTW_REG_DOMAIN_MAC8},
 };
 
+static struct rtw_hw_reg_offset rtw8822b_edcca_th[] = {
+       [EDCCA_TH_L2H_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE0}, .offset = 0},
+       [EDCCA_TH_H2L_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE1}, .offset = 0},
+};
+
 struct rtw_chip_info rtw8822b_hw_spec = {
        .ops = &rtw8822b_ops,
        .id = RTW_CHIP_TYPE_8822B,
@@ -2503,6 +2543,9 @@ struct rtw_chip_info rtw8822b_hw_spec = {
        .bfer_su_max_num = 2,
        .bfer_mu_max_num = 1,
        .rx_ldpc = true,
+       .edcca_th = rtw8822b_edcca_th,
+       .l2h_th_ini_cs = 10 + EDCCA_IGI_BASE,
+       .l2h_th_ini_ad = -14 + EDCCA_IGI_BASE,
 
        .coex_para_ver = 0x20070206,
        .bt_desired_ver = 0x6,
index 6211f4b547b95f2cc050555a449eed53bb321aca..3fff8b881854b6e187f965f9b95afa660e5f8735 100644 (file)
@@ -140,6 +140,8 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
 #define GET_PHY_STAT_P1_RXSNR_B(phy_stat)                                      \
        le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(15, 8))
 
+#define RTW8822B_EDCCA_MAX     0x7f
+#define RTW8822B_EDCCA_SRC_DEF 1
 #define REG_HTSTFWT    0x800
 #define REG_RXPSEL     0x808
 #define BIT_RX_PSEL_RST                (BIT(28) | BIT(29))
@@ -152,11 +154,17 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
 #define REG_L1PKWT     0x840
 #define REG_MRC                0x850
 #define REG_CLKTRK     0x860
+#define REG_EDCCA_POW_MA       0x8a0
+#define BIT_MA_LEVEL   GENMASK(1, 0)
 #define REG_ADCCLK     0x8ac
 #define REG_ADC160     0x8c4
 #define REG_ADC40      0x8c8
+#define REG_EDCCA_DECISION     0x8dc
+#define BIT_EDCCA_OPTION       BIT(5)
 #define REG_CDDTXP     0x93c
 #define REG_TXPSEL1    0x940
+#define REG_EDCCA_SOURCE       0x944
+#define BIT_SOURCE_OPTION      GENMASK(29, 28)
 #define REG_ACBB0      0x948
 #define REG_ACBBRXFIR  0x94c
 #define REG_ACGG2TBL   0x958
index f3ad079967a68b032307d854b51665018e1783b5..46b881e8e4feb18d9d60c22aff183587a2f98ab7 100644 (file)
@@ -4497,6 +4497,39 @@ static void rtw8822c_pwr_track(struct rtw_dev *rtwdev)
        dm_info->pwr_trk_triggered = false;
 }
 
+static void rtw8822c_adaptivity_init(struct rtw_dev *rtwdev)
+{
+       rtw_phy_set_edcca_th(rtwdev, RTW8822C_EDCCA_MAX, RTW8822C_EDCCA_MAX);
+
+       /* mac edcca state setting */
+       rtw_write32_clr(rtwdev, REG_TX_PTCL_CTRL, BIT_DIS_EDCCA);
+       rtw_write32_set(rtwdev, REG_RD_CTRL, BIT_EDCCA_MSK_CNTDOWN_EN);
+
+       /* edcca decistion opt */
+       rtw_write32_clr(rtwdev, REG_EDCCA_DECISION, BIT_EDCCA_OPTION);
+}
+
+static void rtw8822c_adaptivity(struct rtw_dev *rtwdev)
+{
+       struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+       s8 l2h, h2l;
+       u8 igi;
+
+       igi = dm_info->igi_history[0];
+       if (dm_info->edcca_mode == RTW_EDCCA_NORMAL) {
+               l2h = max_t(s8, igi + EDCCA_IGI_L2H_DIFF, EDCCA_TH_L2H_LB);
+               h2l = l2h - EDCCA_L2H_H2L_DIFF_NORMAL;
+       } else {
+               if (igi < dm_info->l2h_th_ini - EDCCA_ADC_BACKOFF)
+                       l2h = igi + EDCCA_ADC_BACKOFF;
+               else
+                       l2h = dm_info->l2h_th_ini;
+               h2l = l2h - EDCCA_L2H_H2L_DIFF;
+       }
+
+       rtw_phy_set_edcca_th(rtwdev, l2h, h2l);
+}
+
 static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822c[] = {
        {0x0086,
         RTW_PWR_CUT_ALL_MSK,
@@ -4912,6 +4945,8 @@ static struct rtw_chip_ops rtw8822c_ops = {
        .config_bfee            = rtw8822c_bf_config_bfee,
        .set_gid_table          = rtw_bf_set_gid_table,
        .cfg_csi_rate           = rtw_bf_cfg_csi_rate,
+       .adaptivity_init        = rtw8822c_adaptivity_init,
+       .adaptivity             = rtw8822c_adaptivity,
        .cfo_init               = rtw8822c_cfo_init,
        .cfo_track              = rtw8822c_cfo_track,
        .config_tx_path         = rtw8822c_config_tx_path,
@@ -5197,6 +5232,15 @@ static const struct rtw_pwr_track_tbl rtw8822c_rtw_pwr_track_tbl = {
        .pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p,
 };
 
+static struct rtw_hw_reg_offset rtw8822c_edcca_th[] = {
+       [EDCCA_TH_L2H_IDX] = {
+               {.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80
+       },
+       [EDCCA_TH_H2L_IDX] = {
+               {.addr = 0x84c, .mask = MASKBYTE3}, .offset = 0x80
+       },
+};
+
 #ifdef CONFIG_PM
 static const struct wiphy_wowlan_support rtw_wowlan_stub_8822c = {
        .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_GTK_REKEY_FAILURE |
@@ -5289,6 +5333,9 @@ struct rtw_chip_info rtw8822c_hw_spec = {
        .bfer_mu_max_num = 1,
        .rx_ldpc = true,
        .tx_stbc = true,
+       .edcca_th = rtw8822c_edcca_th,
+       .l2h_th_ini_cs = 60,
+       .l2h_th_ini_ad = 45,
 
 #ifdef CONFIG_PM
        .wow_fw_name = "rtw88/rtw8822c_wow_fw.bin",
index 364afc6d851bf92c1311a2f7a46695fb897d63b3..3df627419d81b065c541ccde92f7ac39a0141005 100644 (file)
@@ -162,6 +162,7 @@ const struct rtw_table name ## _tbl = {                     \
 #define GET_PHY_STAT_P1_RXSNR_B(phy_stat)                                      \
        le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(15, 8))
 
+#define RTW8822C_EDCCA_MAX     0x7f
 #define REG_ANAPARLDO_POW_MAC  0x0029
 #define BIT_LDOE25_PON         BIT(0)
 #define XCAP_MASK              GENMASK(6, 0)
@@ -174,6 +175,8 @@ const struct rtw_table name ## _tbl = {                     \
 #define REG_ANTMAP0            0x820
 #define BIT_ANT_PATH           GENMASK(1, 0)
 #define REG_ANTMAP             0x824
+#define REG_EDCCA_DECISION     0x844
+#define BIT_EDCCA_OPTION       GENMASK(30, 29)
 #define REG_DYMPRITH           0x86c
 #define REG_DYMENTH0           0x870
 #define REG_DYMENTH            0x874