mt76: add tx napi polling support to mt7603/mt7615
Subsystems (2)
Lorenzo Bianconi
maintainercover mt76: add tx napi polling support to mt7603/mt7615
Use napi polling for tx cleanup in mt7603 and mt7615 drivers in order to allow tx scheduling and tx cleanup to run concurrently
Lorenzo Bianconi (4):
mt76: move tx_napi in mt76_dev
mt76: mt7603: use napi polling for tx cleanup
mt76: mt7615: use napi polling for tx cleanup
mt76: move netif_napi_del in mt76_dma_cleanup
drivers/net/wireless/mediatek/mt76/dma.c | 1 + drivers/net/wireless/mediatek/mt76/mt76.h | 1 + .../net/wireless/mediatek/mt76/mt7603/core.c | 2 +- .../net/wireless/mediatek/mt76/mt7603/dma.c | 29 +++++++++++++++++-- .../net/wireless/mediatek/mt76/mt7603/mac.c | 4 ++- .../net/wireless/mediatek/mt76/mt7615/dma.c | 23 +++++++++++++-- .../net/wireless/mediatek/mt76/mt7615/pci.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x02.h | 1 - .../net/wireless/mediatek/mt76/mt76x02_mmio.c | 18 ++++++------ 9 files changed, 63 insertions(+), 18 deletions(-)
Signature · 1 line
2.20.1
Lorenzo Bianconi
maintainerPATCH 1/4 mt76: move tx_napi in mt76_dev
Move tx_napi in mt76_dev data structure in order to implement concurrency between tx scheduling and tx cleanup in mt7603 and mt7615 drivers
--- drivers/net/wireless/mediatek/mt76/mt76.h | 1 + drivers/net/wireless/mediatek/mt76/mt76x02.h | 1 - .../net/wireless/mediatek/mt76/mt76x02_mmio.c | 19 ++++++++++--------- 3 files changed, 11 insertions(+), 10 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76.h +1 -0
@@ -452,6 +452,7 @@ struct mt76_dev {int tx_dma_idx[4 ];struct tasklet_struct tx_tasklet; +struct napi_struct tx_napi;struct delayed_work mac_work;wait_queue_head_t tx_wait;
drivers/net/wireless/mediatek/mt76/mt76x02.h +0 -1
@@ -90,7 +90,6 @@ struct mt76x02_dev {struct sk_buff *rx_head; -struct napi_struct tx_napi;struct delayed_work cal_work;struct delayed_work wdt_work;
drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c +10 -9
@@ -166,7 +166,8 @@ static void mt76x02_tx_tasklet(unsigned long data)static int mt76x02_poll_tx (struct napi_struct *napi,int budget) { - struct mt76x02_dev *dev = container_of(napi, struct mt76x02_dev, tx_napi); + struct mt76x02_dev *dev = container_of(napi, struct mt76x02_dev, + mt76.tx_napi);int i;mt76x02_mac_poll_tx_status (dev, false);
@@ -245,9 +246,9 @@ int mt76x02_dma_init(struct mt76x02_dev *dev)if (ret)return ret; -netif_tx_napi_add (&dev->mt76.napi_dev, &dev->tx_napi, mt76x02_poll_tx, -NAPI_POLL_WEIGHT ); -napi_enable (&dev->tx_napi); +netif_tx_napi_add (&dev->mt76.napi_dev, &dev->mt76.tx_napi, + mt76x02_poll_tx,NAPI_POLL_WEIGHT ); +napi_enable (&dev->mt76.tx_napi);return 0 ; }
@@ -303,7 +304,7 @@ irqreturn_t mt76x02_irq_handler(int irq, void *dev_instance)if (intr & (MT_INT_TX_STAT |MT_INT_TX_DONE_ALL )) {mt76x02_irq_disable (dev,MT_INT_TX_DONE_ALL ); -napi_schedule (&dev->tx_napi); +napi_schedule (&dev->mt76.tx_napi); }if (intr &MT_INT_GPTIMER ) {
@@ -334,7 +335,7 @@ static void mt76x02_dma_enable(struct mt76x02_dev *dev)void mt76x02_dma_cleanup (struct mt76x02_dev *dev) {tasklet_kill (&dev->mt76.tx_tasklet); -netif_napi_del (&dev->tx_napi); +netif_napi_del (&dev->mt76.tx_napi);mt76_dma_cleanup (&dev->mt76); }EXPORT_SYMBOL_GPL (mt76x02_dma_cleanup);
@@ -454,7 +455,7 @@ static void mt76x02_watchdog_reset(struct mt76x02_dev *dev)tasklet_disable (&dev->mt76.pre_tbtt_tasklet);tasklet_disable (&dev->mt76.tx_tasklet); -napi_disable (&dev->tx_napi); +napi_disable (&dev->mt76.tx_napi);for (i =0 ; i <ARRAY_SIZE (dev->mt76.napi); i++)napi_disable (&dev->mt76.napi[i]);
@@ -508,8 +509,8 @@ static void mt76x02_watchdog_reset(struct mt76x02_dev *dev)clear_bit (MT76_RESET , &dev->mt76.state);tasklet_enable (&dev->mt76.tx_tasklet); -napi_enable (&dev->tx_napi); -napi_schedule (&dev->tx_napi); +napi_enable (&dev->mt76.tx_napi); +napi_schedule (&dev->mt76.tx_napi);tasklet_enable (&dev->mt76.pre_tbtt_tasklet);
Signature · 1 line
2.20.1
Lorenzo Bianconi
maintainerPATCH 2/4 mt76: mt7603: use napi polling for tx cleanup
In reply to Lorenzo BianconiThis allows tx scheduling and tx cleanup to run concurrently
--- .../net/wireless/mediatek/mt76/mt7603/core.c | 2 +- .../net/wireless/mediatek/mt76/mt7603/dma.c | 30 +++++++++++++++++-- .../net/wireless/mediatek/mt76/mt7603/mac.c | 4 ++- 3 files changed, 31 insertions(+), 5 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7603/core.c +1 -1
@@ -35,7 +35,7 @@ irqreturn_t mt7603_irq_handler(int irq, void *dev_instance)if (intr &MT_INT_TX_DONE_ALL ) {mt7603_irq_disable (dev,MT_INT_TX_DONE_ALL ); -tasklet_schedule (&dev->mt76.tx_tasklet); +napi_schedule (&dev->mt76.tx_napi); }if (intr &MT_INT_RX_DONE (0 )) {
drivers/net/wireless/mediatek/mt76/mt7603/dma.c +27 -3
@@ -139,15 +139,30 @@ static void mt7603_tx_tasklet(unsigned long data) {struct mt7603_dev *dev = (struct mt7603_dev *)data; + +mt76_txq_schedule_all (&dev->mt76); +} + +static int mt7603_poll_tx (struct napi_struct *napi,int budget) +{ +struct mt7603_dev *dev;int i; + dev = container_of(napi, struct mt7603_dev, mt76.tx_napi); dev->tx_dma_check =0 ; +for (i =MT_TXQ_MCU ; i >=0 ; i--)mt76_queue_tx_cleanup (dev, i, false); -mt76_txq_schedule_all (&dev->mt76); +if (napi_complete_done (napi,0 )) +mt7603_irq_enable (dev,MT_INT_TX_DONE_ALL ); -mt7603_irq_enable (dev,MT_INT_TX_DONE_ALL ); +for (i =MT_TXQ_MCU ; i >=0 ; i--) +mt76_queue_tx_cleanup (dev, i, false); + +tasklet_schedule (&dev->mt76.tx_tasklet); + +return 0 ; }int mt7603_dma_init (struct mt7603_dev *dev)
@@ -216,7 +231,15 @@ int mt7603_dma_init(struct mt7603_dev *dev)return ret;mt76_wr (dev,MT_DELAY_INT_CFG ,0 ); -return mt76_init_queues (dev); + ret =mt76_init_queues (dev); +if (ret) +return ret; + +netif_tx_napi_add (&dev->mt76.napi_dev, &dev->mt76.tx_napi, + mt7603_poll_tx,NAPI_POLL_WEIGHT ); +napi_enable (&dev->mt76.tx_napi); + +return 0 ; }void mt7603_dma_cleanup (struct mt7603_dev *dev)
@@ -227,5 +250,6 @@ void mt7603_dma_cleanup(struct mt7603_dev *dev) MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE);tasklet_kill (&dev->mt76.tx_tasklet); +netif_napi_del (&dev->mt76.tx_napi);mt76_dma_cleanup (&dev->mt76); }
drivers/net/wireless/mediatek/mt76/mt7603/mac.c +3 -1
@@ -1282,6 +1282,7 @@ static void mt7603_mac_watchdog_reset(struct mt7603_dev *dev)tasklet_disable (&dev->mt76.pre_tbtt_tasklet);napi_disable (&dev->mt76.napi[0 ]);napi_disable (&dev->mt76.napi[1 ]); +napi_disable (&dev->mt76.tx_napi);mutex_lock (&dev->mt76.mutex);
@@ -1326,7 +1327,8 @@ static void mt7603_mac_watchdog_reset(struct mt7603_dev *dev)mutex_unlock (&dev->mt76.mutex);tasklet_enable (&dev->mt76.tx_tasklet); -tasklet_schedule (&dev->mt76.tx_tasklet); +napi_enable (&dev->mt76.tx_napi); +napi_schedule (&dev->mt76.tx_napi);tasklet_enable (&dev->mt76.pre_tbtt_tasklet);mt7603_beacon_set_timer (dev,-1 , beacon_int);
Signature · 1 line
2.20.1
Lorenzo Bianconi
maintainerPATCH 3/4 mt76: mt7615: use napi polling for tx cleanup
In reply to Lorenzo BianconiThis allows tx scheduling and tx cleanup to run concurrently
--- .../net/wireless/mediatek/mt76/mt7615/dma.c | 24 +++++++++++++++++-- .../net/wireless/mediatek/mt76/mt7615/pci.c | 2 +- 2 files changed, 23 insertions(+), 3 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7615/dma.c +22 -2
@@ -93,18 +93,33 @@ void mt7615_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,static void mt7615_tx_tasklet (unsigned long data) {struct mt7615_dev *dev = (struct mt7615_dev *)data; + +mt76_txq_schedule_all (&dev->mt76); +} + +static int mt7615_poll_tx (struct napi_struct *napi,int budget) +{static const u8 queue_map[] = {MT_TXQ_MCU ,MT_TXQ_BE }; +struct mt7615_dev *dev;int i; + dev = container_of(napi, struct mt7615_dev, mt76.tx_napi); +for (i =0 ; i <ARRAY_SIZE (queue_map); i++)mt76_queue_tx_cleanup (dev, queue_map[i], false); -mt76_txq_schedule_all (&dev->mt76); +if (napi_complete_done (napi,0 )) +mt7615_irq_enable (dev,MT_INT_TX_DONE_ALL ); -mt7615_irq_enable (dev,MT_INT_TX_DONE_ALL ); +for (i =0 ; i <ARRAY_SIZE (queue_map); i++) +mt76_queue_tx_cleanup (dev, queue_map[i], false); + +tasklet_schedule (&dev->mt76.tx_tasklet); + +return 0 ; }int mt7615_dma_init (struct mt7615_dev *dev)
@@ -178,6 +193,10 @@ int mt7615_dma_init(struct mt7615_dev *dev)if (ret <0 )return ret; +netif_tx_napi_add (&dev->mt76.napi_dev, &dev->mt76.tx_napi, + mt7615_poll_tx,NAPI_POLL_WEIGHT ); +napi_enable (&dev->mt76.tx_napi); +mt76_poll (dev,MT_WPDMA_GLO_CFG ,MT_WPDMA_GLO_CFG_TX_DMA_BUSY |MT_WPDMA_GLO_CFG_RX_DMA_BUSY ,0 ,1000 );
@@ -201,5 +220,6 @@ void mt7615_dma_cleanup(struct mt7615_dev *dev)mt76_set (dev,MT_WPDMA_GLO_CFG ,MT_WPDMA_GLO_CFG_SW_RESET );tasklet_kill (&dev->mt76.tx_tasklet); +netif_napi_del (&dev->mt76.tx_napi);mt76_dma_cleanup (&dev->mt76); }
drivers/net/wireless/mediatek/mt76/mt7615/pci.c +1 -1
@@ -49,7 +49,7 @@ irqreturn_t mt7615_irq_handler(int irq, void *dev_instance)if (intr &MT_INT_TX_DONE_ALL ) {mt7615_irq_disable (dev,MT_INT_TX_DONE_ALL ); -tasklet_schedule (&dev->mt76.tx_tasklet); +napi_schedule (&dev->mt76.tx_napi); }if (intr &MT_INT_RX_DONE (0 )) {
Signature · 1 line
2.20.1
Lorenzo Bianconi
maintainerPATCH 4/4 mt76: move netif_napi_del in mt76_dma_cleanup
In reply to Lorenzo BianconiMove netif_napi_del in mt76_dma_cleanup routine since it is done by all drivers
--- drivers/net/wireless/mediatek/mt76/dma.c | 1 + drivers/net/wireless/mediatek/mt76/mt7603/dma.c | 1 - drivers/net/wireless/mediatek/mt76/mt7615/dma.c | 1 - drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c | 1 - 4 files changed, 1 insertion(+), 3 deletions(-)
drivers/net/wireless/mediatek/mt76/dma.c +1 -0
@@ -588,6 +588,7 @@ void mt76_dma_cleanup(struct mt76_dev *dev) {int i; +netif_napi_del (&dev->tx_napi);for (i =0 ; i <ARRAY_SIZE (dev->q_tx); i++)mt76_dma_tx_cleanup (dev, i, true);
drivers/net/wireless/mediatek/mt76/mt7603/dma.c +0 -1
@@ -250,6 +250,5 @@ void mt7603_dma_cleanup(struct mt7603_dev *dev) MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE);tasklet_kill (&dev->mt76.tx_tasklet); -netif_napi_del (&dev->mt76.tx_napi);mt76_dma_cleanup (&dev->mt76); }
drivers/net/wireless/mediatek/mt76/mt7615/dma.c +0 -1
@@ -220,6 +220,5 @@ void mt7615_dma_cleanup(struct mt7615_dev *dev)mt76_set (dev,MT_WPDMA_GLO_CFG ,MT_WPDMA_GLO_CFG_SW_RESET );tasklet_kill (&dev->mt76.tx_tasklet); -netif_napi_del (&dev->mt76.tx_napi);mt76_dma_cleanup (&dev->mt76); }
drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c +0 -1
@@ -335,7 +335,6 @@ static void mt76x02_dma_enable(struct mt76x02_dev *dev)void mt76x02_dma_cleanup (struct mt76x02_dev *dev) {tasklet_kill (&dev->mt76.tx_tasklet); -netif_napi_del (&dev->mt76.tx_napi);mt76_dma_cleanup (&dev->mt76); }EXPORT_SYMBOL_GPL (mt76x02_dma_cleanup);
Signature · 1 line
2.20.1
Quoted 8 lines · Lorenzo Bianconi
Use napi polling for tx cleanup in mt7603 and mt7615 drivers in order to allow tx scheduling and tx cleanup to run concurrently
Lorenzo Bianconi (4):
mt76: movetx_napiinmt76_dev
mt76: mt7603: use napi polling for tx cleanup
mt76: mt7615: use napi polling for tx cleanup
mt76: movenetif_napi_delinmt76_dma_cleanup
Applied, thanks.
- Felix