wifi: rtw89: mac: check queue empty according to chip gen
authorZong-Zhe Yang <kevin_yang@realtek.com>
Fri, 24 Nov 2023 07:17:00 +0000 (15:17 +0800)
committerKalle Valo <kvalo@kernel.org>
Fri, 1 Dec 2023 12:39:29 +0000 (14:39 +0200)
This function, currently called by WoWLAN flow, polls until specific HW
queues are empty. The polling bit definitions are not totally the same
between WiFi 6 and 7 chips. In addition, the check conditions are also
a little different. So, we differentiate the implementations according to
chip gen.

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@kernel.org>
Link: https://lore.kernel.org/r/20231124071703.132549-6-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/mac.c
drivers/net/wireless/realtek/rtw89/mac.h
drivers/net/wireless/realtek/rtw89/mac_be.c
drivers/net/wireless/realtek/rtw89/reg.h

index b5e32b830a17579e96f6ed9b3bb6d9b2e5360403..074c1edb0d25a17facc7c1d9eeaba97a8a3ce067 100644 (file)
@@ -174,8 +174,8 @@ static int dle_dfi_quota(struct rtw89_dev *rtwdev,
        return 0;
 }
 
-static int dle_dfi_qempty(struct rtw89_dev *rtwdev,
-                         struct rtw89_mac_dle_dfi_qempty *qempty)
+int rtw89_mac_dle_dfi_qempty_cfg(struct rtw89_dev *rtwdev,
+                                struct rtw89_mac_dle_dfi_qempty *qempty)
 {
        struct rtw89_mac_dle_dfi_ctrl ctrl;
        u32 ret;
@@ -220,7 +220,7 @@ static void rtw89_mac_dump_qta_lost(struct rtw89_dev *rtwdev)
        qempty.dle_type = DLE_CTRL_TYPE_PLE;
        qempty.grpsel = 0;
        qempty.qempty = ~(u32)0;
-       ret = dle_dfi_qempty(rtwdev, &qempty);
+       ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty);
        if (ret)
                rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__);
        else
@@ -1618,7 +1618,7 @@ int rtw89_mac_get_dle_rsvd_qt_cfg(struct rtw89_dev *rtwdev,
        return 0;
 }
 
-static bool mac_is_txq_empty(struct rtw89_dev *rtwdev)
+static bool mac_is_txq_empty_ax(struct rtw89_dev *rtwdev)
 {
        struct rtw89_mac_dle_dfi_qempty qempty;
        u32 grpnum, qtmp, val32, msk32;
@@ -1629,7 +1629,7 @@ static bool mac_is_txq_empty(struct rtw89_dev *rtwdev)
 
        for (i = 0; i < grpnum; i++) {
                qempty.grpsel = i;
-               ret = dle_dfi_qempty(rtwdev, &qempty);
+               ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty);
                if (ret) {
                        rtw89_warn(rtwdev, "dle dfi acq empty %d\n", ret);
                        return false;
@@ -1644,7 +1644,7 @@ static bool mac_is_txq_empty(struct rtw89_dev *rtwdev)
        }
 
        qempty.grpsel = rtwdev->chip->wde_qempty_mgq_grpsel;
-       ret = dle_dfi_qempty(rtwdev, &qempty);
+       ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty);
        if (ret) {
                rtw89_warn(rtwdev, "dle dfi mgq empty %d\n", ret);
                return false;
@@ -5797,6 +5797,7 @@ void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
 int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev,
                                        enum rtw89_mac_idx band)
 {
+       const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
        struct rtw89_pkt_drop_params params = {0};
        bool empty;
        int i, ret = 0, try_cnt = 3;
@@ -5805,7 +5806,7 @@ int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev,
        params.sel = RTW89_PKT_DROP_SEL_BAND_ONCE;
 
        for (i = 0; i < try_cnt; i++) {
-               ret = read_poll_timeout(mac_is_txq_empty, empty, empty, 50,
+               ret = read_poll_timeout(mac->is_txq_empty, empty, empty, 50,
                                        50000, false, rtwdev);
                if (ret && !RTW89_CHK_FW_FEATURE(NO_PACKET_DROP, &rtwdev->fw))
                        rtw89_fw_h2c_pkt_drop(rtwdev, &params);
@@ -5864,5 +5865,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
        .cnv_efuse_state = rtw89_cnv_efuse_state_ax,
 
        .get_txpwr_cr = rtw89_mac_get_txpwr_cr_ax,
+
+       .is_txq_empty = mac_is_txq_empty_ax,
 };
 EXPORT_SYMBOL(rtw89_mac_gen_ax);
index b16fa9bbd41260695ba9368b32835b54fb868f27..8beb278934bf8154aa94e4cc66cbee5e3be467d2 100644 (file)
@@ -537,6 +537,9 @@ enum rtw89_mac_bf_rrsc_rate {
 #define B_CMAC1_MGQ_NO_PWRSAV  BIT(11)
 #define B_CMAC1_CPUMGQ         BIT(12)
 
+#define B_CMAC0_MGQ_NORMAL_BE  BIT(2)
+#define B_CMAC1_MGQ_NORMAL_BE  BIT(30)
+
 #define QEMP_ACQ_GRP_MACID_NUM 8
 #define QEMP_ACQ_GRP_QSEL_SH   4
 #define QEMP_ACQ_GRP_QSEL_MASK 0xF
@@ -910,6 +913,8 @@ struct rtw89_mac_gen_def {
        bool (*get_txpwr_cr)(struct rtw89_dev *rtwdev,
                             enum rtw89_phy_idx phy_idx,
                             u32 reg_base, u32 *cr);
+
+       bool (*is_txq_empty)(struct rtw89_dev *rtwdev);
 };
 
 extern const struct rtw89_mac_gen_def rtw89_mac_gen_ax;
@@ -1015,6 +1020,8 @@ int rtw89_mac_check_mac_en(struct rtw89_dev *rtwdev, u8 band,
                           enum rtw89_mac_hwmod_sel sel);
 int rtw89_mac_write_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 val);
 int rtw89_mac_read_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 *val);
+int rtw89_mac_dle_dfi_qempty_cfg(struct rtw89_dev *rtwdev,
+                                struct rtw89_mac_dle_dfi_qempty *qempty);
 int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
 int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
 void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev,
index 1c607316f65258ad35818dba70bd25d07653356c..612baa8b83d9394cbf61cfa6e2e88ebee449a29a 100644 (file)
@@ -405,6 +405,51 @@ static void rtw89_mac_bf_assoc_be(struct rtw89_dev *rtwdev,
        }
 }
 
+static bool mac_is_txq_empty_be(struct rtw89_dev *rtwdev)
+{
+       struct rtw89_mac_dle_dfi_qempty qempty;
+       u32 val32, msk32;
+       u32 grpnum;
+       int ret;
+       int i;
+
+       grpnum = rtwdev->chip->wde_qempty_acq_grpnum;
+       qempty.dle_type = DLE_CTRL_TYPE_WDE;
+
+       for (i = 0; i < grpnum; i++) {
+               qempty.grpsel = i;
+               ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty);
+               if (ret) {
+                       rtw89_warn(rtwdev,
+                                  "%s: failed to dle dfi acq empty: %d\n",
+                                  __func__, ret);
+                       return false;
+               }
+
+               /* Each acq group contains 32 queues (8 macid * 4 acq),
+                * but here, we can simply check if all bits are set.
+                */
+               if (qempty.qempty != MASKDWORD)
+                       return false;
+       }
+
+       qempty.grpsel = rtwdev->chip->wde_qempty_mgq_grpsel;
+       ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty);
+       if (ret) {
+               rtw89_warn(rtwdev, "%s: failed to dle dfi mgq empty: %d\n",
+                          __func__, ret);
+               return false;
+       }
+
+       msk32 = B_CMAC0_MGQ_NORMAL_BE | B_CMAC1_MGQ_NORMAL_BE;
+       if ((qempty.qempty & msk32) != msk32)
+               return false;
+
+       msk32 = B_BE_WDE_EMPTY_QUE_OTHERS;
+       val32 = rtw89_read32(rtwdev, R_BE_DLE_EMPTY0);
+       return (val32 & msk32) == msk32;
+}
+
 const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
        .band1_offset = RTW89_MAC_BE_BAND_REG_OFFSET,
        .filter_model_addr = R_BE_FILTER_MODEL_ADDR,
@@ -435,5 +480,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
        .cnv_efuse_state = rtw89_cnv_efuse_state_be,
 
        .get_txpwr_cr = rtw89_mac_get_txpwr_cr_be,
+
+       .is_txq_empty = mac_is_txq_empty_be,
 };
 EXPORT_SYMBOL(rtw89_mac_gen_be);
index 197fbb40922ce3f8596274d212022fc357e63dcb..455038967af4c96f39991e4bca96409f3a32e5e8 100644 (file)
 #define B_BE_LTR_CMAC1_RX_USE_PG_TH_MASK GENMASK(27, 16)
 #define B_BE_LTR_CMAC0_RX_USE_PG_TH_MASK GENMASK(11, 0)
 
+#define R_BE_DLE_EMPTY0 0x8430
+#define B_BE_PLE_EMPTY_QTA_DMAC_H2D BIT(27)
+#define B_BE_PLE_EMPTY_QTA_DMAC_CPUIO BIT(26)
+#define B_BE_PLE_EMPTY_QTA_DMAC_MPDU_TX BIT(25)
+#define B_BE_PLE_EMPTY_QTA_DMAC_WLAN_CPU BIT(24)
+#define B_BE_PLE_EMPTY_QTA_DMAC_H2C BIT(23)
+#define B_BE_PLE_EMPTY_QTA_DMAC_B1_TXPL BIT(22)
+#define B_BE_PLE_EMPTY_QTA_DMAC_B0_TXPL BIT(21)
+#define B_BE_WDE_EMPTY_QTA_DMAC_CPUIO BIT(20)
+#define B_BE_WDE_EMPTY_QTA_DMAC_PKTIN BIT(19)
+#define B_BE_WDE_EMPTY_QTA_DMAC_DATA_CPU BIT(18)
+#define B_BE_WDE_EMPTY_QTA_DMAC_WLAN_CPU BIT(17)
+#define B_BE_WDE_EMPTY_QTA_DMAC_HIF BIT(16)
+#define B_BE_WDE_EMPTY_QUE_CMAC_B1_HIQ BIT(15)
+#define B_BE_WDE_EMPTY_QUE_CMAC_B1_MBH BIT(14)
+#define B_BE_WDE_EMPTY_QUE_CMAC_B0_OTHERS BIT(13)
+#define B_BE_WDE_EMPTY_QUE_DMAC_MLO_ACQ BIT(12)
+#define B_BE_WDE_EMPTY_QUE_DMAC_MLO_MISC BIT(11)
+#define B_BE_WDE_EMPTY_QUE_DMAC_PKTIN BIT(10)
+#define B_BE_PLE_EMPTY_QUE_DMAC_SEC_TX BIT(9)
+#define B_BE_PLE_EMPTY_QUE_DMAC_MPDU_TX BIT(8)
+#define B_BE_WDE_EMPTY_QUE_OTHERS BIT(7)
+#define B_BE_WDE_EMPTY_QUE_CMAC_WMM3 BIT(6)
+#define B_BE_WDE_EMPTY_QUE_CMAC_WMM2 BIT(5)
+#define B_BE_WDE_EMPTY_QUE_CMAC0_WMM1 BIT(4)
+#define B_BE_WDE_EMPTY_QUE_CMAC0_WMM0 BIT(3)
+#define B_BE_WDE_EMPTY_QUE_CMAC1_MBH BIT(2)
+#define B_BE_WDE_EMPTY_QUE_CMAC0_MBH BIT(1)
+#define B_BE_WDE_EMPTY_QUE_CMAC0_ALL_AC BIT(0)
+
 #define R_BE_PLE_DBG_FUN_INTF_CTL 0x9110
 #define B_BE_PLE_DFI_ACTIVE BIT(31)
 #define B_BE_PLE_DFI_TRGSEL_MASK GENMASK(19, 16)