diff options
author | Lorenzo Bianconi <lorenzo@kernel.org> | 2020-07-03 10:17:35 +0200 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2020-07-21 19:01:17 +0200 |
commit | 4bb586bc33b9845d76fc8d4efc2910e37876c399 (patch) | |
tree | e426347f75477de0d6f88fea8e4ff1df135774e3 /drivers/net/wireless/mediatek | |
parent | 894b7767ec2fc21574775c354ab5350e51c2171c (diff) |
mt76: mt7663u: sync probe sampling with rate configuration
On usb device rate configuration for sampling is performed relying on a
workqueue since it is not possible to access the device in the interrupt
context. Move the configuration of the probe_rate flag in the workqueue
in order to keep probe sampling in sync with actual rate configuration
Fixes: eb99cc95c3b6 ("mt76: mt7615: introduce mt7663u support")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'drivers/net/wireless/mediatek')
4 files changed, 22 insertions, 16 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c index abb81a56e908..af5716797475 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c @@ -917,6 +917,9 @@ mt7615_mac_queue_rate_update(struct mt7615_phy *phy, struct mt7615_sta *sta, struct mt7615_dev *dev = phy->dev; struct mt7615_wtbl_desc *wd; + if (work_pending(&dev->wtbl_work)) + return -EBUSY; + wd = kzalloc(sizeof(*wd), GFP_ATOMIC); if (!wd) return -ENOMEM; @@ -1023,6 +1026,7 @@ void mt7615_mac_set_rates(struct mt7615_phy *phy, struct mt7615_sta *sta, sta->rate_count = 2 * MT7615_RATE_RETRY * n_rates; sta->wcid.tx_info |= MT_WCID_TX_INFO_SET; + sta->rate_probe = !!probe_rate; } EXPORT_SYMBOL_GPL(mt7615_mac_set_rates); @@ -1231,7 +1235,6 @@ static bool mt7615_fill_txs(struct mt7615_dev *dev, struct mt7615_sta *sta, phy = dev->mt76.phy2->priv; mt7615_mac_set_rates(phy, sta, NULL, sta->rates); - sta->rate_probe = false; } spin_unlock_bh(&dev->mt76.lock); } else { diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c index b1cfae7c4b55..79453c890f20 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c @@ -683,10 +683,8 @@ static void mt7615_sta_rate_tbl_update(struct ieee80211_hw *hw, break; } msta->n_rates = i; - if (!test_bit(MT76_STATE_PM, &phy->mt76->state)) { + if (!test_bit(MT76_STATE_PM, &phy->mt76->state)) mt7615_mac_set_rates(phy, msta, NULL, msta->rates); - msta->rate_probe = false; - } spin_unlock_bh(&dev->mt76.lock); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c index 7ec91c0856f5..2d67f9a148cd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c @@ -155,7 +155,6 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, spin_lock_bh(&dev->mt76.lock); mt7615_mac_set_rates(phy, msta, &info->control.rates[0], msta->rates); - msta->rate_probe = true; spin_unlock_bh(&dev->mt76.lock); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/usb.c b/drivers/net/wireless/mediatek/mt76/mt7615/usb.c index a780127377bf..feda5d0c171e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/usb.c @@ -140,6 +140,8 @@ __mt7663u_mac_set_rates(struct mt7615_dev *dev, mt76_wr(dev, addr + 27 * 4, w27); + sta->rate_probe = sta->rateset[rate->rateset].probe_rate.idx != -1; + mt76_set(dev, MT_LPON_T0CR, MT_LPON_T0CR_MODE); /* TSF read */ val = mt76_rr(dev, MT_LPON_UTTR0); sta->rate_set_tsf = (val & ~BIT(0)) | rate->rateset; @@ -196,17 +198,21 @@ __mt7663u_mac_set_key(struct mt7615_dev *dev, void mt7663u_wtbl_work(struct work_struct *work) { struct mt7615_wtbl_desc *wd, *wd_next; + struct list_head wd_list; struct mt7615_dev *dev; dev = (struct mt7615_dev *)container_of(work, struct mt7615_dev, wtbl_work); - mt7615_mutex_acquire(dev); + INIT_LIST_HEAD(&wd_list); + spin_lock_bh(&dev->mt76.lock); + list_splice_init(&dev->wd_head, &wd_list); + spin_unlock_bh(&dev->mt76.lock); - list_for_each_entry_safe(wd, wd_next, &dev->wd_head, node) { - spin_lock_bh(&dev->mt76.lock); + list_for_each_entry_safe(wd, wd_next, &wd_list, node) { list_del(&wd->node); - spin_unlock_bh(&dev->mt76.lock); + + mt7615_mutex_acquire(dev); switch (wd->type) { case MT7615_WTBL_RATE_DESC: @@ -216,10 +222,11 @@ void mt7663u_wtbl_work(struct work_struct *work) __mt7663u_mac_set_key(dev, wd); break; } + + mt7615_mutex_release(dev); + kfree(wd); } - - mt7615_mutex_release(dev); } static void @@ -236,17 +243,16 @@ mt7663u_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, struct ieee80211_sta *sta, struct mt76_tx_info *tx_info) { + struct mt7615_sta *msta = container_of(wcid, struct mt7615_sta, wcid); struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb); - if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) { - struct mt7615_sta *msta; - - msta = container_of(wcid, struct mt7615_sta, wcid); + if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && + !msta->rate_probe) { + /* request to configure sampling rate */ spin_lock_bh(&dev->mt76.lock); mt7615_mac_set_rates(&dev->phy, msta, &info->control.rates[0], msta->rates); - msta->rate_probe = true; spin_unlock_bh(&dev->mt76.lock); } mt7663u_mac_write_txwi(dev, wcid, qid, sta, tx_info->skb); |