]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: rtw89: consider RX info for WiFi 7 chips
authorPing-Ke Shih <pkshih@realtek.com>
Fri, 27 Oct 2023 01:50:58 +0000 (09:50 +0800)
committerKalle Valo <kvalo@kernel.org>
Mon, 30 Oct 2023 17:25:30 +0000 (19:25 +0200)
For WiFi 7 chips, some fields and predefined length are changed, so
add them accordingly.

The mac_id field is used to identify peer that send a packet, and we can
use it to know RSSI and traffic from the peer. For WiFi 7 chips,
RXWD.mac_id of PPDU status packet is not set by hardware. Instead, we
should fill it by rxinfo_user[].mac_id of PPDU status content.

Also, filter out invalid reports to prevent warning messages keep showing.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20231027015059.10032-4-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/core.c
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/txrx.h

index 4327f725cafe386bee9aa3d9957029a719ae0e6a..bc30be774037892c1ec52a37d2621bae0a96728f 100644 (file)
@@ -1409,29 +1409,63 @@ static int rtw89_core_rx_process_mac_ppdu(struct rtw89_dev *rtwdev,
 {
        const struct rtw89_chip_info *chip = rtwdev->chip;
        const struct rtw89_rxinfo *rxinfo = (const struct rtw89_rxinfo *)skb->data;
+       const struct rtw89_rxinfo_user *user;
+       enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen;
+       int rx_cnt_size = RTW89_PPDU_MAC_RX_CNT_SIZE;
        bool rx_cnt_valid = false;
+       bool invalid = false;
        u8 plcp_size = 0;
-       u8 usr_num = 0;
        u8 *phy_sts;
+       u8 usr_num;
+       int i;
+
+       if (chip_gen == RTW89_CHIP_BE) {
+               invalid = le32_get_bits(rxinfo->w0, RTW89_RXINFO_W0_INVALID_V1);
+               rx_cnt_size = RTW89_PPDU_MAC_RX_CNT_SIZE_V1;
+       }
+
+       if (invalid)
+               return -EINVAL;
 
        rx_cnt_valid = le32_get_bits(rxinfo->w0, RTW89_RXINFO_W0_RX_CNT_VLD);
-       plcp_size = le32_get_bits(rxinfo->w1, RTW89_RXINFO_W1_PLCP_LEN) << 3;
-       usr_num = le32_get_bits(rxinfo->w0, RTW89_RXINFO_W0_USR_NUM);
+       if (chip_gen == RTW89_CHIP_BE) {
+               plcp_size = le32_get_bits(rxinfo->w0, RTW89_RXINFO_W0_PLCP_LEN_V1) << 3;
+               usr_num = le32_get_bits(rxinfo->w0, RTW89_RXINFO_W0_USR_NUM_V1);
+       } else {
+               plcp_size = le32_get_bits(rxinfo->w1, RTW89_RXINFO_W1_PLCP_LEN) << 3;
+               usr_num = le32_get_bits(rxinfo->w0, RTW89_RXINFO_W0_USR_NUM);
+       }
        if (usr_num > chip->ppdu_max_usr) {
                rtw89_warn(rtwdev, "Invalid user number (%d) in mac info\n",
                           usr_num);
                return -EINVAL;
        }
 
+       /* For WiFi 7 chips, RXWD.mac_id of PPDU status is not set by hardware,
+        * so update mac_id by rxinfo_user[].mac_id.
+        */
+       for (i = 0; i < usr_num && chip_gen == RTW89_CHIP_BE; i++) {
+               user = &rxinfo->user[i];
+               if (!le32_get_bits(user->w0, RTW89_RXINFO_USER_MAC_ID_VALID))
+                       continue;
+
+               phy_ppdu->mac_id =
+                       le32_get_bits(user->w0, RTW89_RXINFO_USER_MACID);
+               break;
+       }
+
        phy_sts = skb->data + RTW89_PPDU_MAC_INFO_SIZE;
        phy_sts += usr_num * RTW89_PPDU_MAC_INFO_USR_SIZE;
        /* 8-byte alignment */
        if (usr_num & BIT(0))
                phy_sts += RTW89_PPDU_MAC_INFO_USR_SIZE;
        if (rx_cnt_valid)
-               phy_sts += RTW89_PPDU_MAC_RX_CNT_SIZE;
+               phy_sts += rx_cnt_size;
        phy_sts += plcp_size;
 
+       if (phy_sts > skb->data + skb->len)
+               return -EINVAL;
+
        phy_ppdu->buf = phy_sts;
        phy_ppdu->len = skb->data + skb->len - phy_sts;
 
@@ -1565,6 +1599,11 @@ static int rtw89_core_rx_process_phy_ppdu(struct rtw89_dev *rtwdev,
 {
        const struct rtw89_phy_sts_hdr *hdr = phy_ppdu->buf;
        u32 len_from_header;
+       bool physts_valid;
+
+       physts_valid = le32_get_bits(hdr->w0, RTW89_PHY_STS_HDR_W0_VALID);
+       if (!physts_valid)
+               return -EINVAL;
 
        len_from_header = le32_get_bits(hdr->w0, RTW89_PHY_STS_HDR_W0_LEN) << 3;
 
@@ -2054,13 +2093,19 @@ static void rtw89_core_rx_process_ppdu_sts(struct rtw89_dev *rtwdev,
                                             .mac_id = desc_info->mac_id};
        int ret;
 
-       if (desc_info->mac_info_valid)
-               rtw89_core_rx_process_mac_ppdu(rtwdev, skb, &phy_ppdu);
+       if (desc_info->mac_info_valid) {
+               ret = rtw89_core_rx_process_mac_ppdu(rtwdev, skb, &phy_ppdu);
+               if (ret)
+                       goto out;
+       }
+
        ret = rtw89_core_rx_process_phy_ppdu(rtwdev, &phy_ppdu);
        if (ret)
-               rtw89_debug(rtwdev, RTW89_DBG_TXRX, "process ppdu failed\n");
+               goto out;
 
        rtw89_core_rx_process_phy_sts(rtwdev, &phy_ppdu);
+
+out:
        rtw89_core_rx_pending_skb(rtwdev, &phy_ppdu, desc_info, skb);
        dev_kfree_skb_any(skb);
 }
index 2eb29ea9ff7b4d72c725f065c42232594b97156c..da8181539d1a53a6d68993d31073a418fb7f5664 100644 (file)
@@ -2818,6 +2818,7 @@ struct rtw89_ra_info {
 #define RTW89_PPDU_MAC_INFO_USR_SIZE 4
 #define RTW89_PPDU_MAC_INFO_SIZE 8
 #define RTW89_PPDU_MAC_RX_CNT_SIZE 96
+#define RTW89_PPDU_MAC_RX_CNT_SIZE_V1 128
 
 #define RTW89_MAX_RX_AGG_NUM 64
 #define RTW89_MAX_TX_AGG_NUM 128
index 7142cce167de4d3befc3360705e85bb08d26b1d4..c467a80ffa88d43e588b539df254d908ff14c7cc 100644 (file)
@@ -416,8 +416,11 @@ struct rtw89_rxinfo {
 } __packed;
 
 #define RTW89_RXINFO_W0_USR_NUM GENMASK(3, 0)
+#define RTW89_RXINFO_W0_USR_NUM_V1 GENMASK(4, 0)
 #define RTW89_RXINFO_W0_FW_DEFINE GENMASK(15, 8)
+#define RTW89_RXINFO_W0_PLCP_LEN_V1 GENMASK(23, 16)
 #define RTW89_RXINFO_W0_LSIG_LEN GENMASK(27, 16)
+#define RTW89_RXINFO_W0_INVALID_V1 BIT(27)
 #define RTW89_RXINFO_W0_IS_TO_SELF BIT(28)
 #define RTW89_RXINFO_W0_RX_CNT_VLD BIT(29)
 #define RTW89_RXINFO_W0_LONG_RXD GENMASK(31, 30)
@@ -430,6 +433,7 @@ struct rtw89_phy_sts_hdr {
 } __packed;
 
 #define RTW89_PHY_STS_HDR_W0_IE_MAP GENMASK(4, 0)
+#define RTW89_PHY_STS_HDR_W0_VALID BIT(7)
 #define RTW89_PHY_STS_HDR_W0_LEN GENMASK(15, 8)
 #define RTW89_PHY_STS_HDR_W0_RSSI_AVG GENMASK(31, 24)
 #define RTW89_PHY_STS_HDR_W1_RSSI_A GENMASK(7, 0)