[PATCH wireless] wifi: mt76: mt7921: honour FIF_FCSFAIL instead of hardcoding drop_err
Devin Wittmayer <[email protected]>
| Newsgroups | org.kernel.vger.linux-wireless,org.infradead.lists.linux-mediatek |
|---|---|
| Message-ID | <[email protected]> |
When a monitor interface asks to see frames that failed their checksum, mac80211 passes the request down to the driver. mt7921 works out the answer, sends it to the firmware as a receive filter, and then configures the sniffer with a hardcoded byte telling it to drop those frames anyway. The answer is used once and never kept, so the sniffer never gets to see it. That matters to anyone using monitor mode to judge a link honestly, which is most of the reason to be in monitor mode at all. Mark Anthony Agarro posted the same change for mt7925: keep what mac80211 asked for on the phy, and read it back when the sniffer is configured. This does that for mt7921, and applies on top of it, since that patch is what adds the field. https://lore.kernel.org/linux-wireless/[email protected]/ The stored value is read in one place only, configuring the sniffer, which has a single caller, and that call sits inside a branch reached only by a monitor interface. Nothing else changes. Measured on an MT7922 with a read-only probe on the command as the driver sends it, so these are the driver's own bytes rather than an inference from what came back: request arm drop_err none stock 1 1 1 1 none patched 1 1 1 1 fcsfail stock 1 1 fcsfail patched 0 0 Stock sends the drop byte whether or not anyone asked for it. Patched sends it only when nobody did. Withdrawing the request and making it again inside one driver load moves the byte back and forth, 0 then 1 then 0 across three changes, so nothing sticks once set. If it does appear to stick when trying this against an MT7927, that is mac80211 rather than the driver. It raises the filter count unconditionally when a monitor comes up, but skips lowering it again for drivers that set NO_VIRTUAL_MONITOR, and that is the only chip in this family which does. Fixes: 914189af23b8 ("wifi: mt76: mt7921: fix channel switch fail in monitor mode") Signed-off-by: Devin Wittmayer <[email protected]> --- Not standalone. This needs the mt7925 patch linked above, which is what adds rxfilter to struct mt792x_phy. Without it this will not build. drivers/net/wireless/mediatek/mt76/mt7921/main.c | 8 +++----- drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h | 5 +++++ 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c index 68a059504e83..95f7f56125ba 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c @@ -668,12 +668,8 @@ static void mt7921_configure_filter(struct ieee80211_hw *hw, unsigned int *total_flags, u64 multicast) { -#define MT7921_FILTER_FCSFAIL BIT(2) -#define MT7921_FILTER_CONTROL BIT(5) -#define MT7921_FILTER_OTHER_BSS BIT(6) -#define MT7921_FILTER_ENABLE BIT(31) - struct mt792x_dev *dev = mt792x_hw_dev(hw); + struct mt792x_phy *phy = mt792x_hw_phy(hw); u32 flags = MT7921_FILTER_ENABLE; #define MT7921_FILTER(_fif, _type) do { \ @@ -685,6 +681,8 @@ static void mt7921_configure_filter(struct ieee80211_hw *hw, MT7921_FILTER(FIF_CONTROL, CONTROL); MT7921_FILTER(FIF_OTHER_BSS, OTHER_BSS); + phy->rxfilter = flags; + mt792x_mutex_acquire(dev); mt7921_mcu_set_rxfilter(dev, flags, 0, 0); mt792x_mutex_release(dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index a118a301564c..7abd1d98feed 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -1226,7 +1226,7 @@ int mt7921_mcu_config_sniffer(struct mt792x_vif *vif, .len = cpu_to_le16(sizeof(req.tlv)), .control_ch = chandef->chan->hw_value, .center_ch = ieee80211_frequency_to_channel(freq1), - .drop_err = 1, + .drop_err = !(vif->phy->rxfilter & MT7921_FILTER_FCSFAIL), }, }; if (chandef->chan->band < ARRAY_SIZE(ch_band)) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h index fb8654b7c5e7..f7ed11353d28 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h @@ -7,6 +7,11 @@ #include "../mt792x.h" #include "regs.h" +#define MT7921_FILTER_FCSFAIL BIT(2) +#define MT7921_FILTER_CONTROL BIT(5) +#define MT7921_FILTER_OTHER_BSS BIT(6) +#define MT7921_FILTER_ENABLE BIT(31) + #define MT7921_MAX_AID 20 #define MT7921_TX_RING_SIZE 2048 -- 2.55.0