Skip to content

Commit c222f77

Browse files
Neil Chennbd168
authored andcommitted
wifi: mt76: mt7921: fix rx filter incorrect by drv/fw inconsistent
The rx filter, in mt7921 series, may be changed in fw operation. There is a racing problem if rx filter controlled by both driver and firmware at the same time. To avoid this issue, let mt7921 driver set rx filter by new command MCU_CE_CMD_SET_RX_FILTER and allow the firmware controlling it only. Reviewed-by: Lorenzo Bianconi <[email protected]> Co-developed-by: Deren Wu <[email protected]> Signed-off-by: Deren Wu <[email protected]> Signed-off-by: Neil Chen <[email protected]> Tested-by: AngeloGioacchino Del Regno <[email protected]> Signed-off-by: Felix Fietkau <[email protected]>
1 parent 5f54237 commit c222f77

File tree

6 files changed

+40
-50
lines changed

6 files changed

+40
-50
lines changed

drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,6 +1239,7 @@ enum {
12391239
MCU_CE_CMD_TEST_CTRL = 0x01,
12401240
MCU_CE_CMD_START_HW_SCAN = 0x03,
12411241
MCU_CE_CMD_SET_PS_PROFILE = 0x05,
1242+
MCU_CE_CMD_SET_RX_FILTER = 0x0a,
12421243
MCU_CE_CMD_SET_CHAN_DOMAIN = 0x0f,
12431244
MCU_CE_CMD_SET_BSS_CONNECTED = 0x16,
12441245
MCU_CE_CMD_SET_BSS_ABORT = 0x17,

drivers/net/wireless/mediatek/mt76/mt7921/init.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,6 @@ int mt7921_mac_init(struct mt7921_dev *dev)
238238
for (i = 0; i < 2; i++)
239239
mt7921_mac_init_band(dev, i);
240240

241-
dev->mt76.rxfilter = mt76_rr(dev, MT_WF_RFCR(0));
242-
243241
return mt76_connac_mcu_set_rts_thresh(&dev->mt76, 0x92b, 0);
244242
}
245243
EXPORT_SYMBOL_GPL(mt7921_mac_init);

drivers/net/wireless/mediatek/mt76/mt7921/main.c

Lines changed: 3 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,6 @@ static int mt7921_config(struct ieee80211_hw *hw, u32 changed)
676676
ieee80211_iterate_active_interfaces(hw,
677677
IEEE80211_IFACE_ITER_RESUME_ALL,
678678
mt7921_sniffer_interface_iter, dev);
679-
dev->mt76.rxfilter = mt76_rr(dev, MT_WF_RFCR(0));
680679
}
681680

682681
out:
@@ -705,53 +704,12 @@ static void mt7921_configure_filter(struct ieee80211_hw *hw,
705704
u64 multicast)
706705
{
707706
struct mt7921_dev *dev = mt7921_hw_dev(hw);
708-
u32 ctl_flags = MT_WF_RFCR1_DROP_ACK |
709-
MT_WF_RFCR1_DROP_BF_POLL |
710-
MT_WF_RFCR1_DROP_BA |
711-
MT_WF_RFCR1_DROP_CFEND |
712-
MT_WF_RFCR1_DROP_CFACK;
713-
u32 flags = 0;
714-
715-
#define MT76_FILTER(_flag, _hw) do { \
716-
flags |= *total_flags & FIF_##_flag; \
717-
dev->mt76.rxfilter &= ~(_hw); \
718-
dev->mt76.rxfilter |= !(flags & FIF_##_flag) * (_hw); \
719-
} while (0)
720707

721708
mt7921_mutex_acquire(dev);
722-
723-
dev->mt76.rxfilter &= ~(MT_WF_RFCR_DROP_OTHER_BSS |
724-
MT_WF_RFCR_DROP_OTHER_BEACON |
725-
MT_WF_RFCR_DROP_FRAME_REPORT |
726-
MT_WF_RFCR_DROP_PROBEREQ |
727-
MT_WF_RFCR_DROP_MCAST_FILTERED |
728-
MT_WF_RFCR_DROP_MCAST |
729-
MT_WF_RFCR_DROP_BCAST |
730-
MT_WF_RFCR_DROP_DUPLICATE |
731-
MT_WF_RFCR_DROP_A2_BSSID |
732-
MT_WF_RFCR_DROP_UNWANTED_CTL |
733-
MT_WF_RFCR_DROP_STBC_MULTI);
734-
735-
MT76_FILTER(OTHER_BSS, MT_WF_RFCR_DROP_OTHER_TIM |
736-
MT_WF_RFCR_DROP_A3_MAC |
737-
MT_WF_RFCR_DROP_A3_BSSID);
738-
739-
MT76_FILTER(FCSFAIL, MT_WF_RFCR_DROP_FCSFAIL);
740-
741-
MT76_FILTER(CONTROL, MT_WF_RFCR_DROP_CTS |
742-
MT_WF_RFCR_DROP_RTS |
743-
MT_WF_RFCR_DROP_CTL_RSV |
744-
MT_WF_RFCR_DROP_NDPA);
745-
746-
*total_flags = flags;
747-
mt76_wr(dev, MT_WF_RFCR(0), dev->mt76.rxfilter);
748-
749-
if (*total_flags & FIF_CONTROL)
750-
mt76_clear(dev, MT_WF_RFCR1(0), ctl_flags);
751-
else
752-
mt76_set(dev, MT_WF_RFCR1(0), ctl_flags);
753-
709+
mt7921_mcu_set_rxfilter(dev, *total_flags, 0, 0);
754710
mt7921_mutex_release(dev);
711+
712+
*total_flags &= (FIF_OTHER_BSS | FIF_FCSFAIL | FIF_CONTROL);
755713
}
756714

757715
static void mt7921_bss_info_changed(struct ieee80211_hw *hw,

drivers/net/wireless/mediatek/mt76/mt7921/mcu.c

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,14 +1019,20 @@ int mt7921_mcu_set_beacon_filter(struct mt7921_dev *dev,
10191019
struct ieee80211_vif *vif,
10201020
bool enable)
10211021
{
1022+
#define MT7921_FIF_BIT_CLR BIT(1)
1023+
#define MT7921_FIF_BIT_SET BIT(0)
10221024
int err;
10231025

10241026
if (enable) {
10251027
err = mt7921_mcu_uni_bss_bcnft(dev, vif, true);
10261028
if (err)
10271029
return err;
10281030

1029-
mt76_set(dev, MT_WF_RFCR(0), MT_WF_RFCR_DROP_OTHER_BEACON);
1031+
err = mt7921_mcu_set_rxfilter(dev, 0,
1032+
MT7921_FIF_BIT_SET,
1033+
MT_WF_RFCR_DROP_OTHER_BEACON);
1034+
if (err)
1035+
return err;
10301036

10311037
return 0;
10321038
}
@@ -1035,7 +1041,11 @@ int mt7921_mcu_set_beacon_filter(struct mt7921_dev *dev,
10351041
if (err)
10361042
return err;
10371043

1038-
mt76_clear(dev, MT_WF_RFCR(0), MT_WF_RFCR_DROP_OTHER_BEACON);
1044+
err = mt7921_mcu_set_rxfilter(dev, 0,
1045+
MT7921_FIF_BIT_CLR,
1046+
MT_WF_RFCR_DROP_OTHER_BEACON);
1047+
if (err)
1048+
return err;
10391049

10401050
return 0;
10411051
}
@@ -1323,3 +1333,25 @@ int mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2,
13231333
}
13241334
return 0;
13251335
}
1336+
1337+
int mt7921_mcu_set_rxfilter(struct mt7921_dev *dev, u32 fif,
1338+
u8 bit_op, u32 bit_map)
1339+
{
1340+
struct {
1341+
u8 rsv[4];
1342+
u8 mode;
1343+
u8 rsv2[3];
1344+
__le32 fif;
1345+
__le32 bit_map; /* bit_* for bitmap update */
1346+
u8 bit_op;
1347+
u8 pad[51];
1348+
} __packed data = {
1349+
.mode = fif ? 1 : 2,
1350+
.fif = cpu_to_le32(fif),
1351+
.bit_map = cpu_to_le32(bit_map),
1352+
.bit_op = bit_op,
1353+
};
1354+
1355+
return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_RX_FILTER),
1356+
&data, sizeof(data), false);
1357+
}

drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,8 @@ int mt7921_mcu_get_rx_rate(struct mt7921_phy *phy, struct ieee80211_vif *vif,
388388
struct ieee80211_sta *sta, struct rate_info *rate);
389389
int mt7921_mcu_fw_log_2_host(struct mt7921_dev *dev, u8 ctrl);
390390
void mt7921_mcu_rx_event(struct mt7921_dev *dev, struct sk_buff *skb);
391+
int mt7921_mcu_set_rxfilter(struct mt7921_dev *dev, u32 fif,
392+
u8 bit_op, u32 bit_map);
391393

392394
static inline void mt7921_irq_enable(struct mt7921_dev *dev, u32 mask)
393395
{

drivers/net/wireless/mediatek/mt76/mt7921/testmode.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ mt7921_tm_set(struct mt7921_dev *dev, struct mt7921_tm_cmd *req)
5959
cancel_work_sync(&pm->wake_work);
6060
__mt7921_mcu_drv_pmctrl(dev);
6161

62-
mt76_wr(dev, MT_WF_RFCR(0), dev->mt76.rxfilter);
6362
phy->test.state = MT76_TM_STATE_ON;
6463
}
6564

0 commit comments

Comments
 (0)