wifi: rtw89: consider RX info for WiFi 7 chips
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
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user