Message ID | 96fb46ff1e2e3a9c0646a3b3dce43c3840b7bae0.1607536573.git.ryder.lee@mediatek.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Felix Fietkau |
Headers | show |
Series | [1/2] mt76: mt7915: reset token when mac_reset happens | expand |
> Reset buffering token in mt7915_mac_reset_work() to avoid possible leakege, > which leads to Tx stop after mac reset. > > Tested-by: Bo Jiao <bo.jiao@mediatek.com> > Signed-off-by: Ryder Lee <ryder.lee@mediatek.com> > --- > .../net/wireless/mediatek/mt76/mt7915/init.c | 17 +------------- > .../net/wireless/mediatek/mt76/mt7915/mac.c | 23 +++++++++++++++++++ > .../wireless/mediatek/mt76/mt7915/mt7915.h | 1 + > 3 files changed, 25 insertions(+), 16 deletions(-) > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c > index ff29a8090739..255ccd7e3d27 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c > +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c > @@ -672,27 +672,12 @@ int mt7915_register_device(struct mt7915_dev *dev) > > void mt7915_unregister_device(struct mt7915_dev *dev) > { > - struct mt76_txwi_cache *txwi; > - int id; > - > mt7915_unregister_ext_phy(dev); > mt76_unregister_device(&dev->mt76); > mt7915_mcu_exit(dev); > mt7915_dma_cleanup(dev); > > - spin_lock_bh(&dev->token_lock); > - idr_for_each_entry(&dev->token, txwi, id) { > - mt7915_txp_skb_unmap(&dev->mt76, txwi); > - if (txwi->skb) { > - struct ieee80211_hw *hw; > - > - hw = mt76_tx_status_get_hw(&dev->mt76, txwi->skb); > - ieee80211_free_txskb(hw, txwi->skb); > - } > - mt76_put_txwi(&dev->mt76, txwi); it seems to me you are not using latest codebase here. I guess you are missing the commit below: commit 5342758d5522dbf8081360be9c8545bac84b80f3 Author: Felix Fietkau <nbd@nbd.name> Date: Sat Nov 21 16:00:14 2020 +0100 mt76: mt7915: stop queues when running out of tx tokens Avoids packet drops under load with lots of stations Regards, Lorenzo > - } > - spin_unlock_bh(&dev->token_lock); > - idr_destroy(&dev->token); > + mt7915_tx_token_put(dev); > > mt76_free_device(&dev->mt76); > } > diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c > index 7f08c88d3282..25623e450bc5 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c > +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c > @@ -1466,6 +1466,26 @@ mt7915_dma_reset(struct mt7915_phy *phy) > MT_WFDMA1_GLO_CFG_TX_DMA_EN | MT_WFDMA1_GLO_CFG_RX_DMA_EN); > } > > +void mt7915_tx_token_put(struct mt7915_dev *dev); > +{ > + struct mt76_txwi_cache *txwi; > + int id; > + > + spin_lock_bh(&dev->token_lock); > + idr_for_each_entry(&dev->token, txwi, id) { > + mt7915_txp_skb_unmap(&dev->mt76, txwi); > + if (txwi->skb) { > + struct ieee80211_hw *hw; > + > + hw = mt76_tx_status_get_hw(&dev->mt76, txwi->skb); > + ieee80211_free_txskb(hw, txwi->skb); > + } > + mt76_put_txwi(&dev->mt76, txwi); > + } > + spin_unlock_bh(&dev->token_lock); > + idr_destroy(&dev->token); > +} > + > /* system error recovery */ > void mt7915_mac_reset_work(struct work_struct *work) > { > @@ -1506,6 +1526,9 @@ void mt7915_mac_reset_work(struct work_struct *work) > > mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_DMA_STOPPED); > > + mt7915_tx_token_put(dev); > + idr_init(&dev->token); > + > if (mt7915_wait_reset_state(dev, MT_MCU_CMD_RESET_DONE)) { > mt7915_dma_reset(&dev->phy); > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h > index 5bf76c74373f..3cee1cffc95e 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h > +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h > @@ -468,6 +468,7 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, > struct ieee80211_sta *sta, > struct mt76_tx_info *tx_info); > void mt7915_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e); > +void mt7915_tx_token_put(struct mt7915_dev *dev); > int mt7915_init_tx_queues(struct mt7915_phy *phy, int idx, int n_desc); > void mt7915_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, > struct sk_buff *skb); > -- > 2.18.0 >
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c index ff29a8090739..255ccd7e3d27 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c @@ -672,27 +672,12 @@ int mt7915_register_device(struct mt7915_dev *dev) void mt7915_unregister_device(struct mt7915_dev *dev) { - struct mt76_txwi_cache *txwi; - int id; - mt7915_unregister_ext_phy(dev); mt76_unregister_device(&dev->mt76); mt7915_mcu_exit(dev); mt7915_dma_cleanup(dev); - spin_lock_bh(&dev->token_lock); - idr_for_each_entry(&dev->token, txwi, id) { - mt7915_txp_skb_unmap(&dev->mt76, txwi); - if (txwi->skb) { - struct ieee80211_hw *hw; - - hw = mt76_tx_status_get_hw(&dev->mt76, txwi->skb); - ieee80211_free_txskb(hw, txwi->skb); - } - mt76_put_txwi(&dev->mt76, txwi); - } - spin_unlock_bh(&dev->token_lock); - idr_destroy(&dev->token); + mt7915_tx_token_put(dev); mt76_free_device(&dev->mt76); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c index 7f08c88d3282..25623e450bc5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c @@ -1466,6 +1466,26 @@ mt7915_dma_reset(struct mt7915_phy *phy) MT_WFDMA1_GLO_CFG_TX_DMA_EN | MT_WFDMA1_GLO_CFG_RX_DMA_EN); } +void mt7915_tx_token_put(struct mt7915_dev *dev); +{ + struct mt76_txwi_cache *txwi; + int id; + + spin_lock_bh(&dev->token_lock); + idr_for_each_entry(&dev->token, txwi, id) { + mt7915_txp_skb_unmap(&dev->mt76, txwi); + if (txwi->skb) { + struct ieee80211_hw *hw; + + hw = mt76_tx_status_get_hw(&dev->mt76, txwi->skb); + ieee80211_free_txskb(hw, txwi->skb); + } + mt76_put_txwi(&dev->mt76, txwi); + } + spin_unlock_bh(&dev->token_lock); + idr_destroy(&dev->token); +} + /* system error recovery */ void mt7915_mac_reset_work(struct work_struct *work) { @@ -1506,6 +1526,9 @@ void mt7915_mac_reset_work(struct work_struct *work) mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_DMA_STOPPED); + mt7915_tx_token_put(dev); + idr_init(&dev->token); + if (mt7915_wait_reset_state(dev, MT_MCU_CMD_RESET_DONE)) { mt7915_dma_reset(&dev->phy); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h index 5bf76c74373f..3cee1cffc95e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -468,6 +468,7 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, struct ieee80211_sta *sta, struct mt76_tx_info *tx_info); void mt7915_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e); +void mt7915_tx_token_put(struct mt7915_dev *dev); int mt7915_init_tx_queues(struct mt7915_phy *phy, int idx, int n_desc); void mt7915_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, struct sk_buff *skb);