When entering monitor mode or enabling FIF_OTHER_BSS, rtw89_ops_configure_filter() updates B_AX_SNIFFER_MODE or clears B_AX_A_A1_MATCH in hal.rx_fltr, but leaves hardware target-address, multicast, address CAM, beacon check, and UID drop masks active unless specific FIF_* flags happen to toggle: - B_AX_A_UC_CAM_MATCH and B_AX_A_BC_CAM_MATCH are only cleared when FIF_PROBE_REQ changes, dropping unicast and broadcast frames from arbitrary BSSs without a CAM entry in hardware. - B_AX_A_MC is only cleared when FIF_ALLMULTI is set, and B_AX_A_MC_LIST_CAM_MATCH is never cleared, dropping multicast frames when a monitor socket is opened without IFF_PROMISC. - B_AX_UID_FILTER_MASK is initialized in DEFAULT_AX_RX_FLTR and DEFAULT_BE_RX_FLTR via mac->default_rx_fltr and is never cleared by any FIF_* flag. - B_AX_A_A1_MATCH, B_AX_A_BC, and B_AX_A_BCN_CHK_EN must stay cleared whenever B_AX_SNIFFER_MODE or FIF_OTHER_BSS is active, including after rtw89_hw_scan_complete_cb(), rtw89_roc_end(), or MAC reinit writes rtwdev->hal.rx_fltr back to R_AX_RX_FLTR_OPT / R_BE_RX_FLTR_OPT. - FIF_CONTROL and FIF_PSPOLL are masked out of *new_flags even though rx_fltr_init_ax() and rx_fltr_init_be() already forward control frames to the host via R_AX_CTRL_FLTR / R_BE_CTRL_FLTR. Retain FIF_CONTROL and FIF_PSPOLL in *new_flags, record FIF_OTHER_BSS in hal.rx_fltr_other_bss so active monitor interfaces with MONITOR_FLAG_OTHER_BSS (and concurrent passive monitors) receive arbitrary-BSS frames without setting B_AX_SNIFFER_MODE, and add rtw89_mac_refine_rx_fltr() to clear the drop masks without mutating baseline rtwdev->hal.rx_fltr across mode transitions. The bit positions in R_AX_RX_FLTR_OPT and R_BE_RX_FLTR_OPT are identical. Signed-off-by: Enver Ikromov --- drivers/net/wireless/realtek/rtw89/core.h | 1 + drivers/net/wireless/realtek/rtw89/mac.c | 3 ++- drivers/net/wireless/realtek/rtw89/mac.h | 16 ++++++++++++++++ drivers/net/wireless/realtek/rtw89/mac80211.c | 5 ++++- drivers/net/wireless/realtek/rtw89/mac_be.c | 3 ++- 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 7f84ee5..7be8810 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -6499,6 +6499,7 @@ struct rtw89_hal { u8 cv; u8 cid; /* enum rtw89_core_chip_cid */ u8 acv; + bool rx_fltr_other_bss; u16 aid; /* enum rtw89_core_chip_aid */ u32 antenna_tx; u32 antenna_rx; diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 41796bf..06fb263 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -2681,6 +2681,7 @@ void rtw89_mac_set_rx_fltr(struct rtw89_dev *rtwdev, u8 mac_idx, u32 rx_fltr) u32 reg; u32 val; + rx_fltr = rtw89_mac_refine_rx_fltr(rtwdev, rx_fltr); reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, mac_idx); val = rtw89_read32(rtwdev, reg); @@ -2706,7 +2707,7 @@ static int rx_fltr_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx) if (ret) return ret; } - mac_ftlr = rtwdev->hal.rx_fltr; + mac_ftlr = rtw89_mac_refine_rx_fltr(rtwdev, rtwdev->hal.rx_fltr); plcp_ftlr = B_AX_CCK_CRC_CHK | B_AX_CCK_SIG_CHK | B_AX_LSIG_PARITY_CHK_EN | B_AX_SIGA_CRC_CHK | B_AX_VHT_SU_SIGB_CRC_CHK | B_AX_VHT_MU_SIGB_CRC_CHK | diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h index db42e33..b4a7cb7 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -1494,6 +1494,22 @@ void rtw89_mac_set_edcca_mode_bands(struct rtw89_dev *rtwdev, bool normal) rtw89_mac_set_edcca_mode(rtwdev, RTW89_MAC_1, normal); } +static inline u32 rtw89_mac_refine_rx_fltr(struct rtw89_dev *rtwdev, + u32 rx_fltr) +{ + if ((rx_fltr & B_AX_SNIFFER_MODE) || rtwdev->hal.rx_fltr_other_bss) + rx_fltr &= ~(B_AX_A_A1_MATCH | + B_AX_A_BC | + B_AX_A_MC | + B_AX_A_UC_CAM_MATCH | + B_AX_A_BC_CAM_MATCH | + B_AX_A_MC_LIST_CAM_MATCH | + B_AX_A_BCN_CHK_EN | + B_AX_UID_FILTER_MASK); + + return rx_fltr; +} + void rtw89_mac_set_rx_fltr(struct rtw89_dev *rtwdev, u8 mac_idx, u32 rx_fltr); void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev); void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop); diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c index 5a12639..2a3adf0 100644 --- a/drivers/net/wireless/realtek/rtw89/mac80211.c +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -335,7 +335,10 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw, rtw89_leave_ps_mode(rtwdev); *new_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_FCSFAIL | - FIF_BCN_PRBRESP_PROMISC | FIF_PROBE_REQ; + FIF_BCN_PRBRESP_PROMISC | FIF_PROBE_REQ | + FIF_CONTROL | FIF_PSPOLL; + + rtwdev->hal.rx_fltr_other_bss = !!(*new_flags & FIF_OTHER_BSS); if (changed_flags & FIF_ALLMULTI) { if (*new_flags & FIF_ALLMULTI) diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c index fa35caf..7147679 100644 --- a/drivers/net/wireless/realtek/rtw89/mac_be.c +++ b/drivers/net/wireless/realtek/rtw89/mac_be.c @@ -1328,7 +1328,8 @@ static int rx_fltr_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) rtw89_mac_typ_fltr_opt_be(rtwdev, RTW89_DATA, RTW89_FWD_TO_HOST, mac_idx); reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RX_FLTR_OPT, mac_idx); - rtw89_write32(rtwdev, reg, rtwdev->hal.rx_fltr); + rtw89_write32(rtwdev, reg, + rtw89_mac_refine_rx_fltr(rtwdev, rtwdev->hal.rx_fltr)); reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PLCP_HDR_FLTR, mac_idx); val = B_BE_HE_SIGB_CRC_CHK | B_BE_VHT_MU_SIGB_CRC_CHK | -- 2.56.0.windows.4