]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: rtw89: 8922a: Extend channel info field length for scan
authorPo-Hao Huang <phhuang@realtek.com>
Thu, 28 Nov 2024 05:54:28 +0000 (13:54 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Thu, 5 Dec 2024 06:22:07 +0000 (14:22 +0800)
Extend the bitfield for duration in channel info to 16 bits.
Update the related format in H2C and C2H, then increase firmware
format sequence to 3.

Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20241128055433.11851-2-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/fw.c
drivers/net/wireless/realtek/rtw89/fw.h
drivers/net/wireless/realtek/rtw89/mac.c
drivers/net/wireless/realtek/rtw89/rtw8922a.c

index 409cbdc6b92ae435f7e44df8f308dd84a9135dd0..8c7e8b1c954f447d7317731cfb4e4a3dbf093614 100644 (file)
@@ -4456,6 +4456,7 @@ enum rtw89_fw_feature {
        RTW89_FW_FEATURE_RFK_RXDCK_V0,
        RTW89_FW_FEATURE_NO_WOW_CPU_IO_RX,
        RTW89_FW_FEATURE_NOTIFY_AP_INFO,
+       RTW89_FW_FEATURE_CH_INFO_BE_V0,
 };
 
 struct rtw89_fw_suit {
index cbd759c844e5599d76859a6d051d6c33a669eaec..a0408fcd6799e3d79924a1b0363d135e5300c326 100644 (file)
@@ -729,6 +729,7 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
        __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 31, 0, RFK_PRE_NOTIFY_V0),
        __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 42, 0, RFK_RXDCK_V0),
        __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 46, 0, NOTIFY_AP_INFO),
+       __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 47, 0, CH_INFO_BE_V0),
 };
 
 static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw,
@@ -4956,13 +4957,14 @@ int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
        struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
        struct rtw89_h2c_chinfo_elem_be *elem;
        struct rtw89_mac_chinfo_be *ch_info;
-       struct rtw89_h2c_chinfo *h2c;
+       struct rtw89_h2c_chinfo_be *h2c;
        struct sk_buff *skb;
        unsigned int cond;
+       u8 ver = U8_MAX;
        int skb_len;
        int ret;
 
-       static_assert(sizeof(*elem) == RTW89_MAC_CHINFO_SIZE);
+       static_assert(sizeof(*elem) == RTW89_MAC_CHINFO_SIZE_BE);
 
        skb_len = struct_size(h2c, elem, ch_num);
        skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, skb_len);
@@ -4971,8 +4973,11 @@ int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
                return -ENOMEM;
        }
 
+       if (RTW89_CHK_FW_FEATURE(CH_INFO_BE_V0, &rtwdev->fw))
+               ver = 0;
+
        skb_put(skb, sizeof(*h2c));
-       h2c = (struct rtw89_h2c_chinfo *)skb->data;
+       h2c = (struct rtw89_h2c_chinfo_be *)skb->data;
 
        h2c->ch_num = ch_num;
        h2c->elem_size = sizeof(*elem) / 4; /* in unit of 4 bytes */
@@ -4982,8 +4987,7 @@ int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
        list_for_each_entry(ch_info, chan_list, list) {
                elem = (struct rtw89_h2c_chinfo_elem_be *)skb_put(skb, sizeof(*elem));
 
-               elem->w0 = le32_encode_bits(ch_info->period, RTW89_H2C_CHINFO_BE_W0_PERIOD) |
-                          le32_encode_bits(ch_info->dwell_time, RTW89_H2C_CHINFO_BE_W0_DWELL) |
+               elem->w0 = le32_encode_bits(ch_info->dwell_time, RTW89_H2C_CHINFO_BE_W0_DWELL) |
                           le32_encode_bits(ch_info->central_ch,
                                            RTW89_H2C_CHINFO_BE_W0_CENTER_CH) |
                           le32_encode_bits(ch_info->pri_ch, RTW89_H2C_CHINFO_BE_W0_PRI_CH);
@@ -5030,6 +5034,12 @@ int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
                                            RTW89_H2C_CHINFO_BE_W6_FW_PROBE0_SHORTSSIDS) |
                           le32_encode_bits(ch_info->fw_probe0_bssids,
                                            RTW89_H2C_CHINFO_BE_W6_FW_PROBE0_BSSIDS);
+               if (ver == 0)
+                       elem->w0 |=
+                          le32_encode_bits(ch_info->period, RTW89_H2C_CHINFO_BE_W0_PERIOD);
+               else
+                       elem->w7 = le32_encode_bits(ch_info->period,
+                                                   RTW89_H2C_CHINFO_BE_W7_PERIOD_V1);
        }
 
        rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
@@ -5173,6 +5183,7 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
        u8 probe_id[NUM_NL80211_BANDS];
        u8 cfg_len = sizeof(*h2c);
        unsigned int cond;
+       u8 ver = U8_MAX;
        void *ptr;
        int ret;
        u32 len;
@@ -5193,6 +5204,9 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
 
        memset(probe_id, RTW89_SCANOFLD_PKT_NONE, sizeof(probe_id));
 
+       if (RTW89_CHK_FW_FEATURE(CH_INFO_BE_V0, &rtwdev->fw))
+               ver = 0;
+
        if (!wowlan) {
                list_for_each_entry(pkt_info, &scan_info->pkt_list[NL80211_BAND_6GHZ], list) {
                        if (pkt_info->wildcard_6ghz) {
@@ -5288,9 +5302,7 @@ flex_member:
                           le32_encode_bits(RTW89_OFF_CHAN_TIME / 10,
                                            RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY_VAL);
 
-               opch->w1 = le32_encode_bits(RTW89_CHANNEL_TIME,
-                                           RTW89_H2C_SCANOFLD_BE_OPCH_W1_DURATION) |
-                          le32_encode_bits(op->band_type,
+               opch->w1 = le32_encode_bits(op->band_type,
                                            RTW89_H2C_SCANOFLD_BE_OPCH_W1_CH_BAND) |
                           le32_encode_bits(op->band_width,
                                            RTW89_H2C_SCANOFLD_BE_OPCH_W1_BW) |
@@ -5316,6 +5328,13 @@ flex_member:
                                            RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT2) |
                           le32_encode_bits(RTW89_SCANOFLD_PKT_NONE,
                                            RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT3);
+
+               if (ver == 0)
+                       opch->w1 |= le32_encode_bits(RTW89_CHANNEL_TIME,
+                                                    RTW89_H2C_SCANOFLD_BE_OPCH_W1_DURATION);
+               else
+                       opch->w4 = le32_encode_bits(RTW89_CHANNEL_TIME,
+                                                   RTW89_H2C_SCANOFLD_BE_OPCH_W4_DURATION_V1);
                ptr += sizeof(*opch);
        }
 
@@ -6498,7 +6517,7 @@ int rtw89_pno_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
 
        INIT_LIST_HEAD(&chan_list);
        for (idx = 0, list_len = 0;
-            idx < nd_config->n_channels && list_len < RTW89_SCAN_LIST_LIMIT;
+            idx < nd_config->n_channels && list_len < RTW89_SCAN_LIST_LIMIT_AX;
             idx++, list_len++) {
                channel = nd_config->channels[idx];
                ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
@@ -6549,7 +6568,7 @@ int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
 
        INIT_LIST_HEAD(&chan_list);
        for (idx = rtwdev->scan_info.last_chan_idx, list_len = 0;
-            idx < req->n_channels && list_len < RTW89_SCAN_LIST_LIMIT;
+            idx < req->n_channels && list_len < RTW89_SCAN_LIST_LIMIT_AX;
             idx++, list_len++) {
                channel = req->channels[idx];
                ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
@@ -6626,7 +6645,7 @@ int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
        INIT_LIST_HEAD(&chan_list);
 
        for (idx = 0, list_len = 0;
-            idx < nd_config->n_channels && list_len < RTW89_SCAN_LIST_LIMIT;
+            idx < nd_config->n_channels && list_len < RTW89_SCAN_LIST_LIMIT_BE;
             idx++, list_len++) {
                channel = nd_config->channels[idx];
                ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
@@ -6681,7 +6700,7 @@ int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
        INIT_LIST_HEAD(&chan_list);
 
        for (idx = rtwdev->scan_info.last_chan_idx, list_len = 0;
-            idx < req->n_channels && list_len < RTW89_SCAN_LIST_LIMIT;
+            idx < req->n_channels && list_len < RTW89_SCAN_LIST_LIMIT_BE;
             idx++, list_len++) {
                channel = req->channels[idx];
                ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
index 9106bcce185180765d0863d49819f97bd5d6557c..95681c390bb844ce395f7ac13a668801985106da 100644 (file)
@@ -310,9 +310,12 @@ struct rtw89_fw_macid_pause_sleep_grp {
 #define RTW89_SCANOFLD_DEBUG_MASK 0x1F
 #define RTW89_CHAN_INVALID 0xFF
 #define RTW89_MAC_CHINFO_SIZE 28
+#define RTW89_MAC_CHINFO_SIZE_BE 32
 #define RTW89_SCAN_LIST_GUARD 4
-#define RTW89_SCAN_LIST_LIMIT \
-               ((RTW89_H2C_MAX_SIZE / RTW89_MAC_CHINFO_SIZE) - RTW89_SCAN_LIST_GUARD)
+#define RTW89_SCAN_LIST_LIMIT(size) \
+               ((RTW89_H2C_MAX_SIZE / (size)) - RTW89_SCAN_LIST_GUARD)
+#define RTW89_SCAN_LIST_LIMIT_AX RTW89_SCAN_LIST_LIMIT(RTW89_MAC_CHINFO_SIZE)
+#define RTW89_SCAN_LIST_LIMIT_BE RTW89_SCAN_LIST_LIMIT(RTW89_MAC_CHINFO_SIZE_BE)
 
 #define RTW89_BCN_LOSS_CNT 10
 
@@ -2647,6 +2650,7 @@ struct rtw89_h2c_chinfo_elem_be {
        __le32 w4;
        __le32 w5;
        __le32 w6;
+       __le32 w7;
 } __packed;
 
 #define RTW89_H2C_CHINFO_BE_W0_PERIOD GENMASK(7, 0)
@@ -2678,6 +2682,7 @@ struct rtw89_h2c_chinfo_elem_be {
 #define RTW89_H2C_CHINFO_BE_W5_FW_PROBE0_SSIDS GENMASK(31, 16)
 #define RTW89_H2C_CHINFO_BE_W6_FW_PROBE0_SHORTSSIDS GENMASK(15, 0)
 #define RTW89_H2C_CHINFO_BE_W6_FW_PROBE0_BSSIDS GENMASK(31, 16)
+#define RTW89_H2C_CHINFO_BE_W7_PERIOD_V1 GENMASK(15, 0)
 
 struct rtw89_h2c_chinfo {
        u8 ch_num;
@@ -2687,6 +2692,14 @@ struct rtw89_h2c_chinfo {
        struct rtw89_h2c_chinfo_elem elem[] __counted_by(ch_num);
 } __packed;
 
+struct rtw89_h2c_chinfo_be {
+       u8 ch_num;
+       u8 elem_size;
+       u8 arg;
+       u8 rsvd0;
+       struct rtw89_h2c_chinfo_elem_be elem[] __counted_by(ch_num);
+} __packed;
+
 #define RTW89_H2C_CHINFO_ARG_MAC_IDX_MASK BIT(0)
 #define RTW89_H2C_CHINFO_ARG_APPEND_MASK BIT(1)
 
@@ -2733,6 +2746,7 @@ struct rtw89_h2c_scanofld_be_opch {
        __le32 w1;
        __le32 w2;
        __le32 w3;
+       __le32 w4;
 } __packed;
 
 #define RTW89_H2C_SCANOFLD_BE_OPCH_W0_MACID GENMASK(15, 0)
@@ -2754,6 +2768,7 @@ struct rtw89_h2c_scanofld_be_opch {
 #define RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT1 GENMASK(15, 8)
 #define RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT2 GENMASK(23, 16)
 #define RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT3 GENMASK(31, 24)
+#define RTW89_H2C_SCANOFLD_BE_OPCH_W4_DURATION_V1 GENMASK(15, 0)
 
 struct rtw89_h2c_scanofld_be {
        __le32 w0;
@@ -3596,6 +3611,7 @@ struct rtw89_c2h_scanofld {
        __le32 w5;
        __le32 w6;
        __le32 w7;
+       __le32 w8;
 } __packed;
 
 #define RTW89_C2H_SCANOFLD_W2_PRI_CH GENMASK(7, 0)
@@ -3610,6 +3626,8 @@ struct rtw89_c2h_scanofld {
 #define RTW89_C2H_SCANOFLD_W6_EXPECT_PERIOD GENMASK(15, 8)
 #define RTW89_C2H_SCANOFLD_W6_FW_DEF GENMASK(23, 16)
 #define RTW89_C2H_SCANOFLD_W7_REPORT_TSF GENMASK(31, 0)
+#define RTW89_C2H_SCANOFLD_W8_PERIOD_V1 GENMASK(15, 0)
+#define RTW89_C2H_SCANOFLD_W8_EXPECT_PERIOD_V1 GENMASK(31, 16)
 
 #define RTW89_GET_MAC_C2H_MCC_RCV_ACK_GROUP(c2h) \
        le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(1, 0))
index 03fc214402710904c9d487f03466fb5d56f6501a..95f2beb89fe6a4643e8a4f7b800c97ff5a64a099 100644 (file)
@@ -4788,9 +4788,11 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
        struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif;
        struct rtw89_vif *rtwvif;
        struct rtw89_chan new;
-       u8 reason, status, tx_fail, band, actual_period, expect_period;
        u32 last_chan = rtwdev->scan_info.last_chan_idx, report_tsf;
+       u16 actual_period, expect_period;
+       u8 reason, status, tx_fail, band;
        u8 mac_idx, sw_def, fw_def;
+       u8 ver = U8_MAX;
        u16 chan;
        int ret;
 
@@ -4799,6 +4801,9 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
 
        rtwvif = rtwvif_link->rtwvif;
 
+       if (RTW89_CHK_FW_FEATURE(CH_INFO_BE_V0, &rtwdev->fw))
+               ver = 0;
+
        tx_fail = le32_get_bits(c2h->w5, RTW89_C2H_SCANOFLD_W5_TX_FAIL);
        status = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_STATUS);
        chan = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_PRI_CH);
@@ -4811,21 +4816,28 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
        if (!(rtwdev->chip->support_bands & BIT(NL80211_BAND_6GHZ)))
                band = chan > 14 ? RTW89_BAND_5G : RTW89_BAND_2G;
 
-       rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
-                   "mac_idx[%d] band: %d, chan: %d, reason: %d, status: %d, tx_fail: %d, actual: %d\n",
-                   mac_idx, band, chan, reason, status, tx_fail, actual_period);
-
        if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) {
                sw_def = le32_get_bits(c2h->w6, RTW89_C2H_SCANOFLD_W6_SW_DEF);
-               expect_period = le32_get_bits(c2h->w6, RTW89_C2H_SCANOFLD_W6_EXPECT_PERIOD);
                fw_def = le32_get_bits(c2h->w6, RTW89_C2H_SCANOFLD_W6_FW_DEF);
                report_tsf = le32_get_bits(c2h->w7, RTW89_C2H_SCANOFLD_W7_REPORT_TSF);
+               if (ver == 0) {
+                       expect_period =
+                               le32_get_bits(c2h->w6, RTW89_C2H_SCANOFLD_W6_EXPECT_PERIOD);
+               } else {
+                       actual_period = le32_get_bits(c2h->w8, RTW89_C2H_SCANOFLD_W8_PERIOD_V1);
+                       expect_period =
+                               le32_get_bits(c2h->w8, RTW89_C2H_SCANOFLD_W8_EXPECT_PERIOD_V1);
+               }
 
                rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
                            "sw_def: %d, fw_def: %d, tsf: %x, expect: %d\n",
                            sw_def, fw_def, report_tsf, expect_period);
        }
 
+       rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
+                   "mac_idx[%d] band: %d, chan: %d, reason: %d, status: %d, tx_fail: %d, actual: %d\n",
+                   mac_idx, band, chan, reason, status, tx_fail, actual_period);
+
        switch (reason) {
        case RTW89_SCAN_LEAVE_OP_NOTIFY:
        case RTW89_SCAN_LEAVE_CH_NOTIFY:
index a5333099668a15b379e3e6ffd1f995e57b943603..a96b58ce65926b13bfe60ee46888a5c625c5aa14 100644 (file)
@@ -14,7 +14,7 @@
 #include "rtw8922a_rfk.h"
 #include "util.h"
 
-#define RTW8922A_FW_FORMAT_MAX 2
+#define RTW8922A_FW_FORMAT_MAX 3
 #define RTW8922A_FW_BASENAME "rtw89/rtw8922a_fw"
 #define RTW8922A_MODULE_FIRMWARE \
        RTW8922A_FW_BASENAME "-" __stringify(RTW8922A_FW_FORMAT_MAX) ".bin"