convert mt76 sdio to mt76 workers APIs
Subsystems (2)
Lorenzo Bianconi
maintainercover convert mt76 sdio to mt76 workers APIs
Convert mt76-sdio/mt7663s tx/rx path to mt76 worker threads APIs. On mt8183 device, this series improves available throughput of ~60Mbps.
- mt76-sdio tx-rx workqueue: tcp ~ 390Mbps
- mt76-sdio tx-rx workers: tcp ~ 450Mbps
Lorenzo Bianconi (4):
mt76: mt7663s: move tx/rx processing in the same txrx workqueue
mt76: mt7663s: convert txrx_work to mt76_worker
mt76: mt7663s: disable interrupt during txrx_worker processing
mt76: sdio: convert {status/net}_work to mt76_worker
drivers/net/wireless/mediatek/mt76/mt76.h | 13 +- .../wireless/mediatek/mt76/mt7615/mt7615.h | 2 +- .../net/wireless/mediatek/mt76/mt7615/sdio.c | 45 ++++-- .../wireless/mediatek/mt76/mt7615/sdio_txrx.c | 112 +++++++-------- drivers/net/wireless/mediatek/mt76/sdio.c | 130 +++++++++--------- 5 files changed, 154 insertions(+), 148 deletions(-)
Signature · 1 line
2.26.2
Lorenzo Bianconi
maintainerPATCH 1/4 mt76: mt7663s: move tx/rx processing in the same txrx workqueue
Move mt7663 tx and rx processing in the same workqueue in order to reduce jitter that can hit tcp performances. This is a preliminary patch to switch to mt76 workers APIs
--- drivers/net/wireless/mediatek/mt76/mt76.h | 11 +- .../wireless/mediatek/mt76/mt7615/mt7615.h | 2 +- .../net/wireless/mediatek/mt76/mt7615/sdio.c | 3 +- .../wireless/mediatek/mt76/mt7615/sdio_txrx.c | 106 +++++++++--------- drivers/net/wireless/mediatek/mt76/sdio.c | 17 ++- 5 files changed, 66 insertions(+), 73 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76.h +3 -8
@@ -446,15 +446,10 @@ struct mt76_usb {#define MT76S_XMIT_BUF_SZ (16 * PAGE_SIZE)struct mt76_sdio {struct workqueue_struct *txrx_wq; -struct { -struct work_struct xmit_work; -struct work_struct status_work; - } tx; -struct { -struct work_struct recv_work; -struct work_struct net_work; - } rx; +struct work_struct txrx_work; +struct work_struct status_work; +struct work_struct net_work;struct work_struct stat_work;u8 *xmit_buf[MT_TXQ_MCU_WA ];
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +1 -1
@@ -681,7 +681,7 @@ int mt7663u_mcu_init(struct mt7615_dev *dev);/* sdio */ u32 mt7663s_read_pcr (struct mt7615_dev *dev);int mt7663s_mcu_init (struct mt7615_dev *dev); -void mt7663s_tx_work (struct work_struct *work); +void mt7663s_txrx_work (struct work_struct *work);void mt7663s_rx_work (struct work_struct *work);void mt7663s_sdio_irq (struct sdio_func *func);
drivers/net/wireless/mediatek/mt76/mt7615/sdio.c +1 -2
@@ -368,8 +368,7 @@ static int mt7663s_probe(struct sdio_func *func,if (ret <0 ) goto err_free; -INIT_WORK (&mdev->sdio.tx.xmit_work, mt7663s_tx_work); -INIT_WORK (&mdev->sdio.rx.recv_work, mt7663s_rx_work); +INIT_WORK (&mdev->sdio.txrx_work, mt7663s_txrx_work); ret =mt7663s_hw_init (dev, func);if (ret)
drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c +53 -53
136 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/sdio.c +8 -9
@@ -66,10 +66,9 @@ void mt76s_stop_txrx(struct mt76_dev *dev) {struct mt76_sdio *sdio = &dev->sdio; -cancel_work_sync (&sdio->tx.xmit_work); -cancel_work_sync (&sdio->tx.status_work); -cancel_work_sync (&sdio->rx.recv_work); -cancel_work_sync (&sdio->rx.net_work); +cancel_work_sync (&sdio->txrx_work); +cancel_work_sync (&sdio->status_work); +cancel_work_sync (&sdio->net_work);cancel_work_sync (&sdio->stat_work);clear_bit (MT76_READING_STATS , &dev->phy.state);
@@ -257,7 +256,7 @@ static void mt76s_tx_kick(struct mt76_dev *dev, struct mt76_queue *q) {struct mt76_sdio *sdio = &dev->sdio; -queue_work (sdio->txrx_wq, &sdio->tx.xmit_work); +queue_work (sdio->txrx_wq, &sdio->txrx_work); }static const struct mt76_queue_ops sdio_queue_ops = {
@@ -269,7 +268,7 @@ static const struct mt76_queue_ops sdio_queue_ops = {static void mt76s_tx_work (struct work_struct *work) { struct mt76_sdio *sdio = container_of(work, struct mt76_sdio, - tx.status_work); + status_work); struct mt76_dev *dev = container_of(sdio, struct mt76_dev, sdio);int i;
@@ -284,7 +283,7 @@ static void mt76s_tx_work(struct work_struct *work)static void mt76s_rx_work (struct work_struct *work) { struct mt76_sdio *sdio = container_of(work, struct mt76_sdio, - rx.net_work); + net_work); struct mt76_dev *dev = container_of(sdio, struct mt76_dev, sdio);int i;
@@ -343,8 +342,8 @@ int mt76s_init(struct mt76_dev *dev, struct sdio_func *func,return -ENOMEM ;INIT_WORK (&sdio->stat_work, mt76s_tx_status_data); -INIT_WORK (&sdio->tx.status_work, mt76s_tx_work); -INIT_WORK (&sdio->rx.net_work, mt76s_rx_work); +INIT_WORK (&sdio->status_work, mt76s_tx_work); +INIT_WORK (&sdio->net_work, mt76s_rx_work);mutex_init (&sdio->sched.lock); dev->queue_ops = &sdio_queue_ops;
Signature · 1 line
2.26.2
Lorenzo Bianconi
maintainerPATCH 2/4 mt76: mt7663s: convert txrx_work to mt76_worker
In reply to Lorenzo BianconiIn order to improve driver throughput, convert txrx_work to mt76 worker threads APIs.
--- drivers/net/wireless/mediatek/mt76/mt76.h | 2 +- .../wireless/mediatek/mt76/mt7615/mt7615.h | 2 +- .../net/wireless/mediatek/mt76/mt7615/sdio.c | 19 +++++++-- .../wireless/mediatek/mt76/mt7615/sdio_txrx.c | 41 +++++++++---------- drivers/net/wireless/mediatek/mt76/sdio.c | 5 ++- 5 files changed, 41 insertions(+), 28 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76.h +1 -1
@@ -447,7 +447,7 @@ struct mt76_usb {struct mt76_sdio {struct workqueue_struct *txrx_wq; -struct work_struct txrx_work; +struct mt76_worker txrx_worker;struct work_struct status_work;struct work_struct net_work;struct work_struct stat_work;
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +1 -1
@@ -681,7 +681,7 @@ int mt7663u_mcu_init(struct mt7615_dev *dev);/* sdio */ u32 mt7663s_read_pcr (struct mt7615_dev *dev);int mt7663s_mcu_init (struct mt7615_dev *dev); -void mt7663s_txrx_work (struct work_struct *work); +void mt7663s_txrx_worker (struct mt76_worker *w);void mt7663s_rx_work (struct work_struct *work);void mt7663s_sdio_irq (struct sdio_func *func);
drivers/net/wireless/mediatek/mt76/mt7615/sdio.c +16 -3
@@ -368,8 +368,6 @@ static int mt7663s_probe(struct sdio_func *func,if (ret <0 ) goto err_free; -INIT_WORK (&mdev->sdio.txrx_work, mt7663s_txrx_work); - ret =mt7663s_hw_init (dev, func);if (ret) goto err_deinit;
@@ -400,6 +398,13 @@ static int mt7663s_probe(struct sdio_func *func,if (ret) goto err_deinit; + ret =mt76_worker_setup (mt76_hw (dev), &mdev->sdio.txrx_worker, + mt7663s_txrx_worker,"sdio-txrx" ); +if (ret) + goto err_deinit; + +sched_set_fifo_low (mdev->sdio.txrx_worker.task); + ret =mt7663_usb_sdio_register_device (dev);if (ret) goto err_deinit;
@@ -431,6 +436,7 @@ static int mt7663s_suspend(struct device *dev) {struct sdio_func *func =dev_to_sdio_func (dev);struct mt7615_dev *mdev =sdio_get_drvdata (func); +int err;if (!test_bit (MT76_STATE_SUSPEND , &mdev->mphy.state) &&mt7615_firmware_offload (mdev)) {
@@ -443,9 +449,14 @@ static int mt7663s_suspend(struct device *dev)sdio_set_host_pm_flags (func,MMC_PM_KEEP_POWER ); + err =mt7615_mcu_set_fw_ctrl (mdev); +if (err) +return err; + +mt76_worker_disable (&mdev->mt76.sdio.txrx_worker);mt76s_stop_txrx (&mdev->mt76); -return mt7615_mcu_set_fw_ctrl (mdev); +return 0 ; }static int mt7663s_resume (struct device *dev)
@@ -454,6 +465,8 @@ static int mt7663s_resume(struct device *dev)struct mt7615_dev *mdev =sdio_get_drvdata (func);int err; +mt76_worker_enable (&mdev->mt76.sdio.txrx_worker); + err =mt7615_mcu_set_drv_ctrl (mdev);if (err)return err;
drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c +20 -21
59 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/sdio.c +3 -2
@@ -66,7 +66,6 @@ void mt76s_stop_txrx(struct mt76_dev *dev) {struct mt76_sdio *sdio = &dev->sdio; -cancel_work_sync (&sdio->txrx_work);cancel_work_sync (&sdio->status_work);cancel_work_sync (&sdio->net_work);cancel_work_sync (&sdio->stat_work);
@@ -256,7 +255,7 @@ static void mt76s_tx_kick(struct mt76_dev *dev, struct mt76_queue *q) {struct mt76_sdio *sdio = &dev->sdio; -queue_work (sdio->txrx_wq, &sdio->txrx_work); +mt76_worker_schedule (&sdio->txrx_worker); }static const struct mt76_queue_ops sdio_queue_ops = {
@@ -303,6 +302,8 @@ void mt76s_deinit(struct mt76_dev *dev)struct mt76_sdio *sdio = &dev->sdio;int i; +mt76_worker_teardown (&sdio->txrx_worker); +mt76s_stop_txrx (dev);if (sdio->txrx_wq) {destroy_workqueue (sdio->txrx_wq);
Signature · 1 line
2.26.2
Lorenzo Bianconi
maintainerPATCH 3/4 mt76: mt7663s: disable interrupt during txrx_worker processing
In reply to Lorenzo BianconiIn order to reduce sdio bus contention, disable interrupts during txrx_worker processing
--- .../wireless/mediatek/mt76/mt7615/sdio_txrx.c | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c +9 -18
@@ -105,10 +105,7 @@ static int mt7663s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid, buf =page_address (page); -sdio_claim_host (sdio->func); err =sdio_readsb (sdio->func, buf,MCR_WRDR (qid), len); -sdio_release_host (sdio->func); -if (err <0 ) {dev_err (dev->dev,"sdio read data failed:%d\n" , err);__free_pages (page, order);
@@ -144,14 +141,9 @@ static int mt7663s_rx_handler(struct mt76_dev *dev)struct mt76s_intr *intr = sdio->intr_data;int nframes =0 , ret; -/* disable interrupt */ -sdio_claim_host (sdio->func); -sdio_writel (sdio->func,WHLPCR_INT_EN_CLR ,MCR_WHLPCR ,NULL ); ret =sdio_readsb (sdio->func, intr,MCR_WHISR ,sizeof (*intr)); -sdio_release_host (sdio->func); -if (ret <0 ) - goto out; +return ret;trace_dev_irq (dev, intr->isr,0 );
@@ -173,12 +165,6 @@ static int mt7663s_rx_handler(struct mt76_dev *dev) nframes += !!mt7663s_refill_sched_quota (dev, intr->tx.wtqcr); -out: -/* enable interrupt */ -sdio_claim_host (sdio->func); -sdio_writel (sdio->func,WHLPCR_INT_EN_SET ,MCR_WHLPCR ,NULL ); -sdio_release_host (sdio->func); -return nframes; }
@@ -225,10 +211,7 @@ static int __mt7663s_xmit_queue(struct mt76_dev *dev, u8 *data, int len)if (len > sdio->func->cur_blksize) len =roundup (len, sdio->func->cur_blksize); -sdio_claim_host (sdio->func); err =sdio_writesb (sdio->func,MCR_WTDR1 , data, len); -sdio_release_host (sdio->func); -if (err)dev_err (dev->dev,"sdio write failed: %d\n" , err);
@@ -298,6 +281,10 @@ void mt7663s_txrx_worker(struct mt76_worker *w) struct mt76_dev *dev = container_of(sdio, struct mt76_dev, sdio);int i, nframes, ret; +/* disable interrupt */ +sdio_claim_host (sdio->func); +sdio_writel (sdio->func,WHLPCR_INT_EN_CLR ,MCR_WHLPCR ,NULL ); + do { nframes = 0;
@@ -313,6 +300,10 @@ void mt7663s_txrx_worker(struct mt76_worker *w)if (ret >0 ) nframes += ret; }while (nframes >0 ); + +/* enable interrupt */ +sdio_writel (sdio->func,WHLPCR_INT_EN_SET ,MCR_WHLPCR ,NULL ); +sdio_release_host (sdio->func); }void mt7663s_sdio_irq (struct sdio_func *func)
Signature · 1 line
2.26.2
Lorenzo Bianconi
maintainerPATCH 4/4 mt76: sdio: convert {status/net}_work to mt76_worker
In reply to Lorenzo BianconiIn order to improve driver throughput, convert status_work and net_work to mt76 worker APIs.
Remove txrx_wq sdio workqueue since it is no longer used
--- drivers/net/wireless/mediatek/mt76/mt76.h | 8 +- .../net/wireless/mediatek/mt76/mt7615/sdio.c | 27 ++-- .../wireless/mediatek/mt76/mt7615/sdio_txrx.c | 6 +- drivers/net/wireless/mediatek/mt76/sdio.c | 124 +++++++++--------- 4 files changed, 87 insertions(+), 78 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76.h +3 -5
@@ -445,11 +445,10 @@ struct mt76_usb {#define MT76S_XMIT_BUF_SZ (16 * PAGE_SIZE)struct mt76_sdio { -struct workqueue_struct *txrx_wq; -struct mt76_worker txrx_worker; -struct work_struct status_work; -struct work_struct net_work; +struct mt76_worker status_worker; +struct mt76_worker net_worker; +struct work_struct stat_work;u8 *xmit_buf[MT_TXQ_MCU_WA ];
@@ -1059,7 +1058,6 @@ void mt76u_queues_deinit(struct mt76_dev *dev);int mt76s_init (struct mt76_dev *dev,struct sdio_func *func,const struct mt76_bus_ops *bus_ops);int mt76s_alloc_queues (struct mt76_dev *dev); -void mt76s_stop_txrx (struct mt76_dev *dev);void mt76s_deinit (struct mt76_dev *dev); struct sk_buff *
drivers/net/wireless/mediatek/mt76/mt7615/sdio.c +17 -10
@@ -366,11 +366,11 @@ static int mt7663s_probe(struct sdio_func *func, ret =mt76s_init (mdev, func, &mt7663s_ops);if (ret <0 ) - goto err_free; + goto error; ret =mt7663s_hw_init (dev, func);if (ret) - goto err_deinit; + goto error; mdev->rev = (mt76_rr (dev,MT_HW_CHIPID ) <<16 ) | (mt76_rr (dev,MT_HW_REV ) &0xff );
@@ -381,7 +381,7 @@ static int mt7663s_probe(struct sdio_func *func, GFP_KERNEL);if (!mdev->sdio.intr_data) { ret = -ENOMEM ; - goto err_deinit; + goto error; }for (i =0 ; i <ARRAY_SIZE (mdev->sdio.xmit_buf); i++) {
@@ -390,30 +390,29 @@ static int mt7663s_probe(struct sdio_func *func, GFP_KERNEL);if (!mdev->sdio.xmit_buf[i]) { ret = -ENOMEM ; - goto err_deinit; + goto error; } } ret =mt76s_alloc_queues (&dev->mt76);if (ret) - goto err_deinit; + goto error; ret =mt76_worker_setup (mt76_hw (dev), &mdev->sdio.txrx_worker, mt7663s_txrx_worker,"sdio-txrx" );if (ret) - goto err_deinit; + goto error;sched_set_fifo_low (mdev->sdio.txrx_worker.task); ret =mt7663_usb_sdio_register_device (dev);if (ret) - goto err_deinit; + goto error;return 0 ; -err_deinit: +error:mt76s_deinit (&dev->mt76); -err_free:mt76_free_device (&dev->mt76);return ret;
@@ -454,7 +453,13 @@ static int mt7663s_suspend(struct device *dev)return err;mt76_worker_disable (&mdev->mt76.sdio.txrx_worker); -mt76s_stop_txrx (&mdev->mt76); +mt76_worker_disable (&mdev->mt76.sdio.status_worker); +mt76_worker_disable (&mdev->mt76.sdio.net_worker); + +cancel_work_sync (&mdev->mt76.sdio.stat_work); +clear_bit (MT76_READING_STATS , &mdev->mphy.state); + +mt76_tx_status_check (&mdev->mt76,NULL , true);return 0 ; }
@@ -466,6 +471,8 @@ static int mt7663s_resume(struct device *dev)int err;mt76_worker_enable (&mdev->mt76.sdio.txrx_worker); +mt76_worker_enable (&mdev->mt76.sdio.status_worker); +mt76_worker_enable (&mdev->mt76.sdio.net_worker); err =mt7615_mcu_set_drv_ctrl (mdev);if (err)
drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c +3 -3
@@ -150,7 +150,7 @@ static int mt7663s_rx_handler(struct mt76_dev *dev)if (intr->isr &WHIER_RX0_DONE_INT_EN ) { ret =mt7663s_rx_run_queue (dev,0 , intr);if (ret >0 ) { -queue_work (sdio->txrx_wq, &sdio->net_work); +mt76_worker_schedule (&sdio->net_worker); nframes += ret; } }
@@ -158,7 +158,7 @@ static int mt7663s_rx_handler(struct mt76_dev *dev)if (intr->isr &WHIER_RX1_DONE_INT_EN ) { ret =mt7663s_rx_run_queue (dev,1 , intr);if (ret >0 ) { -queue_work (sdio->txrx_wq, &sdio->net_work); +mt76_worker_schedule (&sdio->net_worker); nframes += ret; } }
@@ -269,7 +269,7 @@ static int mt7663s_tx_run_queue(struct mt76_dev *dev, enum mt76_txq_id qid) }mt7663s_tx_update_quota (sdio, qid, pse_sz, ple_sz); -queue_work (sdio->txrx_wq, &sdio->status_work); +mt76_worker_schedule (&sdio->status_worker);return nframes; }
drivers/net/wireless/mediatek/mt76/sdio.c +64 -60
178 lines not on this page · raw message
Signature · 1 line
2.26.2