From 13f1e82f6f39bcd4868a666d595f5a854809f13b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 16 Nov 2018 10:59:28 +0100 Subject: [PATCH] mt7603: clear wtbl entry for removed stations Should fix some issues with reassociating stations Signed-off-by: Felix Fietkau --- mt7603/init.c | 1 + mt7603/mac.c | 13 +++++++++---- mt7603/main.c | 10 ++++++++++ mt7603/mt7603.h | 2 ++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/mt7603/init.c b/mt7603/init.c index b3978b95..ecbf39b0 100644 --- a/mt7603/init.c +++ b/mt7603/init.c @@ -30,6 +30,7 @@ struct mt7603_dev *mt7603_alloc_device(struct device *pdev) .rx_poll_complete = mt7603_rx_poll_complete, .sta_ps = mt7603_sta_ps, .sta_add = mt7603_sta_add, + .sta_remove = mt7603_sta_remove, .update_survey = mt7603_update_channel, }; struct mt7603_dev *dev; diff --git a/mt7603/mac.c b/mt7603/mac.c index 92c77ed3..af400fd8 100644 --- a/mt7603/mac.c +++ b/mt7603/mac.c @@ -118,10 +118,16 @@ void mt7603_wtbl_init(struct mt7603_dev *dev, int idx, int vif, { const void *_mac = mac_addr; u32 addr = mt7603_wtbl1_addr(idx); - u32 w0; + u32 w0 = 0, w1 = 0; int i; - w0 = FIELD_PREP(MT_WTBL1_W0_ADDR_HI, get_unaligned_le16(_mac + 4)); + if (_mac) { + w0 = FIELD_PREP(MT_WTBL1_W0_ADDR_HI, + get_unaligned_le16(_mac + 4)); + w1 = FIELD_PREP(MT_WTBL1_W1_ADDR_LO, + get_unaligned_le32(_mac)); + } + if (vif < 0) vif = 0; else @@ -131,8 +137,7 @@ void mt7603_wtbl_init(struct mt7603_dev *dev, int idx, int vif, mt76_poll(dev, MT_WTBL_UPDATE, MT_WTBL_UPDATE_BUSY, 0, 5000); mt76_set(dev, addr + 0 * 4, w0); - mt76_set(dev, addr + 1 * 4, - FIELD_PREP(MT_WTBL1_W1_ADDR_LO, get_unaligned_le32(_mac))); + mt76_set(dev, addr + 1 * 4, w1); mt76_set(dev, addr + 2 * 4, MT_WTBL1_W2_ADMISSION_CONTROL); mt76_stop_tx_ac(dev, GENMASK(3, 0)); diff --git a/mt7603/main.c b/mt7603/main.c index 6a7cc38f..aeb2eddf 100644 --- a/mt7603/main.c +++ b/mt7603/main.c @@ -318,6 +318,16 @@ mt7603_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, return ret; } +void +mt7603_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76); + struct mt76_wcid *wcid = (struct mt76_wcid *) sta->drv_priv; + + mt7603_wtbl_init(dev, wcid->idx, 0, NULL); +} + void mt7603_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps) { diff --git a/mt7603/mt7603.h b/mt7603/mt7603.h index e1d39ee7..1358ccf3 100644 --- a/mt7603/mt7603.h +++ b/mt7603/mt7603.h @@ -224,6 +224,8 @@ void mt7603_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q); void mt7603_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps); int mt7603_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); +void mt7603_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); void mt7603_tbtt(struct mt7603_dev *dev); void mt7603_pre_tbtt_tasklet(unsigned long arg);