mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 10:09:10 +02:00
wifi: rtw89: phy: enable IE-09/IE-10 PHY status report for monitor mode
The IE-09/IE-10 of PHY status contain SIG-A/SIG-B respectively, so enable them in monitor mode to have rich information. If the parser detects length invalid, ignore to reference IE-09/IE-10 to prevent accessing out of range. The RTL8922D is generation 2 of PHY status, which doesn't report SIG-B by IE-10, so not enable it. Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Link: https://patch.msgid.link/20260506131000.1706298-6-pkshih@realtek.com
This commit is contained in:
parent
c847d0c14c
commit
847758f15f
|
|
@ -2152,14 +2152,38 @@ static void rtw89_core_parse_phy_status_ie00_v2(struct rtw89_dev *rtwdev,
|
|||
rpl_path[i] = tmp_rpl[i] >> 1;
|
||||
}
|
||||
|
||||
static void rtw89_core_parse_phy_status_ie09(struct rtw89_dev *rtwdev,
|
||||
const struct rtw89_phy_sts_iehdr *iehdr,
|
||||
struct rtw89_rx_phy_ppdu *phy_ppdu)
|
||||
{
|
||||
phy_ppdu->ie09 = (const void *)iehdr;
|
||||
}
|
||||
|
||||
static void rtw89_core_parse_phy_status_ie10(struct rtw89_dev *rtwdev,
|
||||
const struct rtw89_phy_sts_iehdr *iehdr,
|
||||
struct rtw89_rx_phy_ppdu *phy_ppdu)
|
||||
{
|
||||
phy_ppdu->ie10 = (const void *)iehdr;
|
||||
}
|
||||
|
||||
static int rtw89_core_process_phy_status_ie(struct rtw89_dev *rtwdev,
|
||||
const struct rtw89_phy_sts_iehdr *iehdr,
|
||||
struct rtw89_rx_phy_ppdu *phy_ppdu)
|
||||
{
|
||||
bool accept;
|
||||
u8 ie;
|
||||
|
||||
ie = le32_get_bits(iehdr->w0, RTW89_PHY_STS_IEHDR_TYPE);
|
||||
|
||||
/*
|
||||
* For normal mode, only parse ppdu_sts that are A1-matched, except for
|
||||
* scanning that needs to get chan_idx in IE01.
|
||||
*/
|
||||
accept = phy_ppdu->to_self || ie == RTW89_PHYSTS_IE01_CMN_OFDM ||
|
||||
rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR;
|
||||
if (!accept)
|
||||
return 0;
|
||||
|
||||
switch (ie) {
|
||||
case RTW89_PHYSTS_IE00_CMN_CCK:
|
||||
rtw89_core_parse_phy_status_ie00(rtwdev, iehdr, phy_ppdu);
|
||||
|
|
@ -2169,6 +2193,12 @@ static int rtw89_core_process_phy_status_ie(struct rtw89_dev *rtwdev,
|
|||
case RTW89_PHYSTS_IE01_CMN_OFDM:
|
||||
rtw89_core_parse_phy_status_ie01(rtwdev, iehdr, phy_ppdu);
|
||||
break;
|
||||
case RTW89_PHYSTS_IE09_FTR_0:
|
||||
rtw89_core_parse_phy_status_ie09(rtwdev, iehdr, phy_ppdu);
|
||||
break;
|
||||
case RTW89_PHYSTS_IE10_FTR_PLCP_EXT:
|
||||
rtw89_core_parse_phy_status_ie10(rtwdev, iehdr, phy_ppdu);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -2228,11 +2258,14 @@ static int rtw89_core_rx_process_phy_ppdu(struct rtw89_dev *rtwdev,
|
|||
static int rtw89_core_rx_parse_phy_sts(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_rx_phy_ppdu *phy_ppdu)
|
||||
{
|
||||
u16 ie_len;
|
||||
void *pos, *end;
|
||||
bool accept;
|
||||
u16 ie_len;
|
||||
|
||||
/* mark invalid reports and bypass them */
|
||||
if (phy_ppdu->ie < RTW89_CCK_PKT)
|
||||
/* for normal mode, mark invalid reports and bypass them */
|
||||
accept = phy_ppdu->ie >= RTW89_CCK_PKT ||
|
||||
rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR;
|
||||
if (!accept)
|
||||
return -EINVAL;
|
||||
|
||||
pos = phy_ppdu->buf + PHY_STS_HDR_LEN;
|
||||
|
|
@ -2246,6 +2279,10 @@ static int rtw89_core_rx_parse_phy_sts(struct rtw89_dev *rtwdev,
|
|||
rtw89_core_process_phy_status_ie(rtwdev, iehdr, phy_ppdu);
|
||||
pos += ie_len;
|
||||
if (pos > end || ie_len == 0) {
|
||||
/* clear pointers to prevent accessing out of IE */
|
||||
phy_ppdu->ie09 = NULL;
|
||||
phy_ppdu->ie10 = NULL;
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_TXRX,
|
||||
"phy status parse failed\n");
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ struct rtw89_h2c_rf_tssi;
|
|||
struct rtw89_fw_txpwr_track_cfg;
|
||||
struct rtw89_phy_rfk_log_fmt;
|
||||
struct rtw89_phy_calc_efuse_gain;
|
||||
struct rtw89_phy_sts_ie09;
|
||||
struct rtw89_phy_sts_ie10;
|
||||
struct rtw89_debugfs;
|
||||
struct rtw89_regd_data;
|
||||
struct rtw89_wow_cam_info;
|
||||
|
|
@ -840,7 +842,7 @@ struct rtw89_rx_phy_ppdu {
|
|||
u8 mac_id;
|
||||
u8 chan_idx;
|
||||
u8 phy_idx;
|
||||
u8 ie;
|
||||
u8 ie; /* enum rtw89_phy_status_bitmap */
|
||||
u16 rate;
|
||||
u8 rpl_avg;
|
||||
u8 rpl_path[RF_PATH_MAX];
|
||||
|
|
@ -862,6 +864,8 @@ struct rtw89_rx_phy_ppdu {
|
|||
bool to_self;
|
||||
bool valid;
|
||||
bool hdr_2_en;
|
||||
const struct rtw89_phy_sts_ie09 *ie09; /* SIG-A */
|
||||
const struct rtw89_phy_sts_ie10 *ie10; /* SIG-B */
|
||||
};
|
||||
|
||||
enum rtw89_mac_idx {
|
||||
|
|
|
|||
|
|
@ -98,6 +98,9 @@ static int rtw89_ops_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)
|
|||
!rtwdev->scanning)
|
||||
rtw89_enter_ips(rtwdev);
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_MONITOR)
|
||||
rtw89_physts_parsing_init(rtwdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7085,10 +7085,21 @@ static void rtw89_physts_enable_hdr_2(struct rtw89_dev *rtwdev, enum rtw89_phy_i
|
|||
static void __rtw89_physts_parsing_init(struct rtw89_dev *rtwdev,
|
||||
enum rtw89_phy_idx phy_idx)
|
||||
{
|
||||
const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
u32 monitor_mode_mu_ies = 0;
|
||||
u32 monitor_mode_su_ies = 0;
|
||||
u32 val;
|
||||
u8 i;
|
||||
|
||||
if (rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR) {
|
||||
monitor_mode_mu_ies = BIT(RTW89_PHYSTS_IE09_FTR_0);
|
||||
if (phy->physt_gen < 2)
|
||||
monitor_mode_mu_ies |= BIT(RTW89_PHYSTS_IE10_FTR_PLCP_EXT);
|
||||
|
||||
monitor_mode_su_ies = BIT(RTW89_PHYSTS_IE09_FTR_0);
|
||||
}
|
||||
|
||||
rtw89_physts_enable_fail_report(rtwdev, false, phy_idx);
|
||||
|
||||
/* enable hdr_2 for 8922D (PHYSTS_BE_GEN2 above) */
|
||||
|
|
@ -7102,6 +7113,7 @@ static void __rtw89_physts_parsing_init(struct rtw89_dev *rtwdev,
|
|||
val = rtw89_physts_get_ie_bitmap(rtwdev, i, phy_idx);
|
||||
if (i == RTW89_HE_MU || i == RTW89_VHT_MU) {
|
||||
val |= BIT(RTW89_PHYSTS_IE13_DL_MU_DEF);
|
||||
val |= monitor_mode_mu_ies;
|
||||
} else if (i == RTW89_TRIG_BASE_PPDU) {
|
||||
val |= BIT(RTW89_PHYSTS_IE13_DL_MU_DEF) |
|
||||
BIT(RTW89_PHYSTS_IE01_CMN_OFDM);
|
||||
|
|
@ -7115,11 +7127,14 @@ static void __rtw89_physts_parsing_init(struct rtw89_dev *rtwdev,
|
|||
val |= BIT(RTW89_PHYSTS_IE20_DBG_OFDM_FD_USER_SEG_0);
|
||||
}
|
||||
|
||||
if (i == RTW89_HE_PKT || i == RTW89_VHT_PKT)
|
||||
val |= monitor_mode_su_ies;
|
||||
|
||||
rtw89_physts_set_ie_bitmap(rtwdev, i, val, phy_idx);
|
||||
}
|
||||
}
|
||||
|
||||
static void rtw89_physts_parsing_init(struct rtw89_dev *rtwdev)
|
||||
void rtw89_physts_parsing_init(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
__rtw89_physts_parsing_init(rtwdev, RTW89_PHY_0);
|
||||
if (rtwdev->dbcc_en)
|
||||
|
|
|
|||
|
|
@ -914,6 +914,7 @@ void rtw89_phy_config_rf_reg_v1(struct rtw89_dev *rtwdev,
|
|||
void rtw89_phy_dm_init(struct rtw89_dev *rtwdev);
|
||||
void rtw89_phy_dm_reinit(struct rtw89_dev *rtwdev);
|
||||
void rtw89_phy_dm_init_data(struct rtw89_dev *rtwdev);
|
||||
void rtw89_physts_parsing_init(struct rtw89_dev *rtwdev);
|
||||
void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
|
||||
u32 data, enum rtw89_phy_idx phy_idx);
|
||||
void rtw89_phy_write32_idx_set(struct rtw89_dev *rtwdev, u32 addr, u32 bits,
|
||||
|
|
|
|||
|
|
@ -658,6 +658,15 @@ struct rtw89_phy_sts_ie01_v2 {
|
|||
#define RTW89_PHY_STS_IE01_V2_W9_RPL_FD_C GENMASK(11, 4)
|
||||
#define RTW89_PHY_STS_IE01_V2_W9_RPL_FD_D GENMASK(23, 16)
|
||||
|
||||
struct rtw89_phy_sts_ie09 {
|
||||
__le64 qw0;
|
||||
} __packed;
|
||||
|
||||
struct rtw89_phy_sts_ie10 {
|
||||
__le64 qw0;
|
||||
u8 sigb[];
|
||||
} __packed;
|
||||
|
||||
enum rtw89_tx_channel {
|
||||
RTW89_TXCH_ACH0 = 0,
|
||||
RTW89_TXCH_ACH1 = 1,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user