Skip to contentSkip to conversation

convert mt76 sdio to mt76 workers APIs

PATCH New Lorenzo Bianconi 1 participant 5 messages Sep 26, 2020

Subsystems (2)
lore
Share & tools
lore

Lorenzo Bianconi

author maintainer
#0 lore raw

cover 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
author maintainer
#1 lore raw

PATCH 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
index a5be66de1cff..243cb89c0a92 100644
@@ -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
index 6a9f9187f76a..11b4caa5cb69 100644
@@ -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
index 874c929d8552..ad7e422ea52e 100644
@@ -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
index 9a4d95a2a707..6eb75ffa9e0f 100644
@@ -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
author maintainer
#2 lore raw

PATCH 2/4 mt76: mt7663s: convert txrx_work to mt76_worker

In reply to Lorenzo Bianconi

In 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
index 243cb89c0a92..e47696e5d3f0 100644
@@ -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
index 11b4caa5cb69..716956b58c13 100644
@@ -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
index ad7e422ea52e..6f8adba2a78b 100644
@@ -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
index 6eb75ffa9e0f..37e05ec40e1d 100644
@@ -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
author maintainer
#3 lore raw

PATCH 3/4 mt76: mt7663s: disable interrupt during txrx_worker processing

In reply to Lorenzo Bianconi

In 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
index 10ed211d7d11..d8f9148fe777 100644
@@ -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
author maintainer
#4 lore raw

PATCH 4/4 mt76: sdio: convert {status/net}_work to mt76_worker

In reply to Lorenzo Bianconi

In 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
index e47696e5d3f0..6bb162a2cdd3 100644
@@ -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
index 6f8adba2a78b..a3718c501eb8 100644
@@ -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
index d8f9148fe777..a4969380c860 100644
@@ -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