mt76: add wed reset callbacks
Subsystems (2)
Lorenzo Bianconi
maintainerv2 cover mt76: add wed reset callbacks
Introduce Wireless Ethernet Dispatcher reset callbacks in order to complete reset requested by ethernet NIC.
This series is based on the following mtk_eth_soc series:
https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/log/
This series is based on the following mt76 series:
https://lore.kernel.org/linux-wireless/[email protected]/T/#mc93e54dc09bb6ee00855645f88b85928e9a4c371
Changes since v1:
- rebase on top of mt76 tree.
Lorenzo Bianconi (2):
wifi: mt76: mt7915: add mt7915 wed reset callbacks
wifi: mt76: mt7915: complete wed reset support
Sujuan Chen (2):
wifi: mt76: dma: add reset to mt76_dma_wed_setup signature
wifi: mt76: dma: reset wed queues in mt76_dma_rx_reset
drivers/net/wireless/mediatek/mt76/dma.c | 27 +++++++---- drivers/net/wireless/mediatek/mt76/dma.h | 1 + drivers/net/wireless/mediatek/mt76/mt76.h | 3 ++ .../net/wireless/mediatek/mt76/mt7915/dma.c | 45 ++++++++++++++++--- .../net/wireless/mediatek/mt76/mt7915/mac.c | 6 +++ .../net/wireless/mediatek/mt76/mt7915/mmio.c | 40 +++++++++++++++++ 6 files changed, 109 insertions(+), 13 deletions(-)
Signature · 1 line
2.39.0
Lorenzo Bianconi
maintainerPATCH v2 1/4 wifi: mt76: dma: add reset to mt76_dma_wed_setup signature
From: Sujuan Chen <[email protected]>
Export mt76_dma_wed_setup routine. This is a preliminary patch to introduce proper wed reset support.
--- drivers/net/wireless/mediatek/mt76/dma.c | 16 ++++++++++------ drivers/net/wireless/mediatek/mt76/dma.h | 1 + 2 files changed, 11 insertions(+), 6 deletions(-)
drivers/net/wireless/mediatek/mt76/dma.c +10 -6
@@ -634,14 +634,17 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,return frames; } -static int -mt76_dma_wed_setup (struct mt76_dev *dev,struct mt76_queue *q) +int mt76_dma_wed_setup (struct mt76_dev *dev,struct mt76_queue *q,bool reset) {#ifdef CONFIG_NET_MEDIATEK_SOC_WED struct mtk_wed_device *wed = &dev->mmio.wed;int ret, type, ring; -u8 flags = q->flags; +u8 flags; + +if (!q || !q->ndesc) +return -EINVAL ; + flags = q->flags;if (!mtk_wed_device_active (wed)) q->flags &= ~MT_QFLAG_WED ;
@@ -653,7 +656,7 @@ mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q)switch (type) {case MT76_WED_Q_TX : - ret =mtk_wed_device_tx_ring_setup (wed, ring, q->regs, false); + ret =mtk_wed_device_tx_ring_setup (wed, ring, q->regs, reset);if (!ret) q->wed_regs = wed->tx_ring[ring].reg_base;break ;
@@ -669,7 +672,7 @@ mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q) q->wed_regs = wed->txfree_ring.reg_base;break ;case MT76_WED_Q_RX : - ret =mtk_wed_device_rx_ring_setup (wed, ring, q->regs, false); + ret =mtk_wed_device_rx_ring_setup (wed, ring, q->regs, reset);if (!ret) q->wed_regs = wed->rx_ring[ring].reg_base;break ;
@@ -682,6 +685,7 @@ mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q)return 0 ;#endif } +EXPORT_SYMBOL_GPL (mt76_dma_wed_setup); static int mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
@@ -712,7 +716,7 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,if (ret)return ret; - ret =mt76_dma_wed_setup (dev, q); + ret =mt76_dma_wed_setup (dev, q, false);if (ret)return ret;
drivers/net/wireless/mediatek/mt76/dma.h +1 -0
@@ -56,5 +56,6 @@ enum mt76_mcu_evt_type {int mt76_dma_rx_poll (struct napi_struct *napi,int budget);void mt76_dma_attach (struct mt76_dev *dev);void mt76_dma_cleanup (struct mt76_dev *dev); +int mt76_dma_wed_setup (struct mt76_dev *dev,struct mt76_queue *q,bool reset);#endif
Signature · 1 line
2.39.0
Lorenzo Bianconi
maintainerPATCH v2 2/4 wifi: mt76: dma: reset wed queues in mt76_dma_rx_reset
In reply to Lorenzo BianconiFrom: Sujuan Chen <[email protected]>
This is a preliminary patch to introduce proper wed reset support.
--- drivers/net/wireless/mediatek/mt76/dma.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/net/wireless/mediatek/mt76/dma.c +7 -2
@@ -766,8 +766,13 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid) q->desc[i].ctrl =cpu_to_le32 (MT_DMA_CTL_DMA_DONE );mt76_dma_rx_cleanup (dev, q); -mt76_dma_sync_idx (dev, q); -mt76_dma_rx_fill (dev, q, false); + +/* reset WED rx queues */ +mt76_dma_wed_setup (dev, q, true); +if (q->flags !=MT_WED_Q_TXFREE ) { +mt76_dma_sync_idx (dev, q); +mt76_dma_rx_fill (dev, q, false); + } } static void
Signature · 1 line
2.39.0
Lorenzo Bianconi
maintainerPATCH v2 3/4 wifi: mt76: mt7915: add mt7915 wed reset callbacks
In reply to Lorenzo BianconiIntroduce mt7915_mmio_wed_reset_complete and mt7915_mmio_wed_reset_complete callbacks and the related wait queues in order to wait for wed reset completion during wlan reset.
--- drivers/net/wireless/mediatek/mt76/dma.c | 2 + drivers/net/wireless/mediatek/mt76/mt76.h | 3 ++ .../net/wireless/mediatek/mt76/mt7915/dma.c | 15 +++++++ .../net/wireless/mediatek/mt76/mt7915/mmio.c | 40 +++++++++++++++++++ 4 files changed, 60 insertions(+)
drivers/net/wireless/mediatek/mt76/dma.c +2 -0
@@ -922,6 +922,8 @@ mt76_dma_init(struct mt76_dev *dev,snprintf (dev->napi_dev.name,sizeof (dev->napi_dev.name),"%s" ,wiphy_name (dev->hw->wiphy)); dev->napi_dev.threaded =1 ; +init_completion (&dev->mmio.wed_reset); +init_completion (&dev->mmio.wed_reset_complete);mt76_for_each_q_rx (dev, i) {netif_napi_add (&dev->napi_dev, &dev->napi[i], poll);
drivers/net/wireless/mediatek/mt76/mt76.h +3 -0
@@ -413,6 +413,7 @@ enum {MT76_STATE_SUSPEND ,MT76_STATE_ROC ,MT76_STATE_PM , + MT76_STATE_WED_RESET, }; struct mt76_hw_cap {
@@ -591,6 +592,8 @@ struct mt76_mmio {u32 irqmask;struct mtk_wed_device wed; +struct completion wed_reset; +struct completion wed_reset_complete; };struct mt76_rx_status {
drivers/net/wireless/mediatek/mt76/mt7915/dma.c +15 -0
@@ -559,6 +559,20 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)return 0 ; } +static void mt7915_dma_wed_reset (struct mt7915_dev *dev) +{ +struct mt76_dev *mdev = &dev->mt76; + +if (!test_bit (MT76_STATE_WED_RESET , &dev->mphy.state)) +return ; + +complete (&mdev->mmio.wed_reset); + +if (!wait_for_completion_timeout (&dev->mt76.mmio.wed_reset_complete, +3 *HZ )) +dev_err (dev->mt76.dev,"wed reset complete timeout\n" ); +} +int mt7915_dma_reset (struct mt7915_dev *dev,bool force) {struct mt76_phy *mphy_ext = dev->mt76.phys[MT_BAND1 ];
@@ -582,6 +596,7 @@ int mt7915_dma_reset(struct mt7915_dev *dev, bool force)mt7915_wfsys_reset (dev);mt7915_dma_disable (dev, force); +mt7915_dma_wed_reset (dev);/* reset hw queues */ for (i =0 ; i < __MT_TXQ_MAX; i++) {
drivers/net/wireless/mediatek/mt76/mt7915/mmio.c +40 -0
@@ -4,10 +4,12 @@#include <linux/kernel.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/rtnetlink.h> #include <linux/pci.h> #include "mt7915.h" #include "mac.h" +#include "mcu.h" #include "../trace.h" #include "../dma.h"
@@ -695,6 +697,42 @@ static void mt7915_mmio_wed_update_rx_stats(struct mtk_wed_device *wed,rcu_read_unlock (); } + +static int mt7915_mmio_wed_reset (struct mtk_wed_device *wed) +{ + struct mt76_dev *mdev = container_of(wed, struct mt76_dev, mmio.wed); + struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76); +struct mt76_phy *mphy = &dev->mphy; +int ret; + +ASSERT_RTNL (); + +if (test_and_set_bit (MT76_STATE_WED_RESET , &mphy->state)) +return -EBUSY ; + + ret =mt7915_mcu_set_ser (dev,SER_RECOVER ,SER_SET_RECOVER_L1 , + mphy->band_idx); +if (ret) + goto out; + +rtnl_unlock (); +if (!wait_for_completion_timeout (&mdev->mmio.wed_reset,20 *HZ )) { +dev_err (mdev->dev,"wed reset timeout\n" ); + ret = -ETIMEDOUT ; + } +rtnl_lock (); +out: +clear_bit (MT76_STATE_WED_RESET , &mphy->state); + +return ret; +} + +static void mt7915_mmio_wed_reset_complete (struct mtk_wed_device *wed) +{ + struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); + +complete (&dev->mmio.wed_reset_complete); +}#endif int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
@@ -777,6 +815,8 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr, wed->wlan.init_rx_buf = mt7915_mmio_wed_init_rx_buf; wed->wlan.release_rx_buf = mt7915_mmio_wed_release_rx_buf; wed->wlan.update_wo_rx_stats = mt7915_mmio_wed_update_rx_stats; + wed->wlan.reset = mt7915_mmio_wed_reset; + wed->wlan.reset_complete = mt7915_mmio_wed_reset_complete; dev->mt76.rx_token_size = wed->wlan.rx_npkt;
Signature · 1 line
2.39.0
Lorenzo Bianconi
maintainerPATCH v2 4/4 wifi: mt76: mt7915: complete wed reset support
In reply to Lorenzo BianconiStop Wireless Ethernet Dispatcher during mt7915 reset procedure.
--- .../net/wireless/mediatek/mt76/mt7915/dma.c | 30 +++++++++++++++---- .../net/wireless/mediatek/mt76/mt7915/mac.c | 6 ++++ 2 files changed, 31 insertions(+), 5 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7915/dma.c +25 -5
@@ -573,9 +573,18 @@ static void mt7915_dma_wed_reset(struct mt7915_dev *dev)dev_err (dev->mt76.dev,"wed reset complete timeout\n" ); } +static void +mt7915_dma_reset_tx_queue (struct mt7915_dev *dev,struct mt76_queue *q) +{ +mt76_queue_reset (dev, q); +if (mtk_wed_device_active (&dev->mt76.mmio.wed)) +mt76_dma_wed_setup (&dev->mt76, q, true); +} +int mt7915_dma_reset (struct mt7915_dev *dev,bool force) {struct mt76_phy *mphy_ext = dev->mt76.phys[MT_BAND1 ]; +struct mtk_wed_device *wed = &dev->mt76.mmio.wed;int i;/* clean up hw queues */
@@ -595,29 +604,40 @@ int mt7915_dma_reset(struct mt7915_dev *dev, bool force)if (force)mt7915_wfsys_reset (dev); +if (mtk_wed_device_active (wed)) +mtk_wed_device_dma_reset (wed); +mt7915_dma_disable (dev, force);mt7915_dma_wed_reset (dev);/* reset hw queues */ for (i =0 ; i < __MT_TXQ_MAX; i++) { -mt76_queue_reset (dev, dev->mphy.q_tx[i]); +mt7915_dma_reset_tx_queue (dev, dev->mphy.q_tx[i]);if (mphy_ext) -mt76_queue_reset (dev, mphy_ext->q_tx[i]); +mt7915_dma_reset_tx_queue (dev, mphy_ext->q_tx[i]); }for (i =0 ; i < __MT_MCUQ_MAX; i++)mt76_queue_reset (dev, dev->mt76.q_mcu[i]); -mt76_for_each_q_rx (&dev->mt76, i) +mt76_for_each_q_rx (&dev->mt76, i) { +if (dev->mt76.q_rx[i].flags ==MT_WED_Q_TXFREE ) +continue ; +mt76_queue_reset (dev, &dev->mt76.q_rx[i]); + }mt76_tx_status_check (&dev->mt76, true); -mt7915_dma_enable (dev); -mt76_for_each_q_rx (&dev->mt76, i)mt76_queue_rx_reset (dev, i); +if (mtk_wed_device_active (wed) &&is_mt7915 (&dev->mt76)) +mt76_rmw (dev,MT_WFDMA0_EXT0_CFG ,MT_WFDMA0_EXT0_RXWB_KEEP , +MT_WFDMA0_EXT0_RXWB_KEEP ); + +mt7915_dma_enable (dev); +return 0 ; }
drivers/net/wireless/mediatek/mt76/mt7915/mac.c +6 -0
@@ -1581,6 +1581,12 @@ void mt7915_mac_reset_work(struct work_struct *work)if (!(READ_ONCE (dev->recovery.state) &MT_MCU_CMD_STOP_DMA ))return ; +if (mtk_wed_device_active (&dev->mt76.mmio.wed)) { +mtk_wed_device_stop (&dev->mt76.mmio.wed); +if (!is_mt7986 (&dev->mt76)) +mt76_wr (dev,MT_INT_WED_MASK_CSR ,0 ); + } +ieee80211_stop_queues (mt76_hw (dev));if (ext_phy)ieee80211_stop_queues (ext_phy->hw);
Signature · 1 line
2.39.0