diff options
author | Lorenzo Bianconi <lorenzo@kernel.org> | 2020-09-05 11:26:06 +0200 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2020-09-24 18:10:19 +0200 |
commit | 1522ff731f848cf87d8ac535dc8ce7bc62a17918 (patch) | |
tree | 02cb0ace31c8a53de8c48ea315d1ca36cc6d7ec0 /drivers/net/wireless/mediatek/mt76/mt7615 | |
parent | 598daa4dbe14082b9369f018e46e753b2d79f730 (diff) |
mt76: mt7663s: introduce sdio tx aggregation
Introduce sdio tx aggregation to reduce bus transaction ands improve tx
throughput. For the moment the skb are copied in a dedicated buffer
since mmc APIs do not support sg table for zero-copy.
Since skb data are already copied in xmit_buff[], avoid linearization in
ma80211 layer. Relying on tx aggregation, we improve tx tpt of ~65%.
Tested-by: Sean Wang <sean.wang@mediatek.com>
Co-developed-by: Sean Wang <sean.wang@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mt7615')
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7615/sdio.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c | 49 |
2 files changed, 46 insertions, 15 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c index 8621c6f579aa..874c929d8552 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c @@ -346,7 +346,7 @@ static int mt7663s_probe(struct sdio_func *func, struct ieee80211_ops *ops; struct mt7615_dev *dev; struct mt76_dev *mdev; - int ret; + int i, ret; ops = devm_kmemdup(&func->dev, &mt7615_ops, sizeof(mt7615_ops), GFP_KERNEL); @@ -387,6 +387,16 @@ static int mt7663s_probe(struct sdio_func *func, goto err_deinit; } + for (i = 0; i < ARRAY_SIZE(mdev->sdio.xmit_buf); i++) { + mdev->sdio.xmit_buf[i] = devm_kmalloc(mdev->dev, + MT76S_XMIT_BUF_SZ, + GFP_KERNEL); + if (!mdev->sdio.xmit_buf[i]) { + ret = -ENOMEM; + goto err_deinit; + } + } + ret = mt76s_alloc_queues(&dev->mt76); if (ret) goto err_deinit; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c index 4033fe431312..e82f6bdcbce4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c @@ -138,15 +138,11 @@ static int mt7663s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid, return i; } -static int mt7663s_tx_pick_quota(struct mt76_dev *dev, enum mt76_txq_id qid, +static int mt7663s_tx_pick_quota(struct mt76_sdio *sdio, enum mt76_txq_id qid, int buf_sz, int *pse_size, int *ple_size) { - struct mt76_sdio *sdio = &dev->sdio; int pse_sz; - if (!test_bit(MT76_STATE_MCU_RUNNING, &dev->phy.state)) - return 0; - pse_sz = DIV_ROUND_UP(buf_sz + sdio->sched.deficit, MT_PSE_PAGE_SZ); if (qid == MT_TXQ_MCU) { @@ -197,27 +193,52 @@ static int __mt7663s_xmit_queue(struct mt76_dev *dev, u8 *data, int len) static int mt7663s_tx_run_queue(struct mt76_dev *dev, enum mt76_txq_id qid) { - int nframes = 0, pse_sz = 0, ple_sz = 0; + int err, nframes = 0, len = 0, pse_sz = 0, ple_sz = 0; struct mt76_queue *q = dev->q_tx[qid]; struct mt76_sdio *sdio = &dev->sdio; while (q->first != q->head) { struct mt76_queue_entry *e = &q->entry[q->first]; - int err; + struct sk_buff *iter; + + if (!test_bit(MT76_STATE_MCU_RUNNING, &dev->phy.state)) { + __skb_put_zero(e->skb, 4); + err = __mt7663s_xmit_queue(dev, e->skb->data, + e->skb->len); + if (err) + return err; + + goto next; + } + + if (len + e->skb->len + 4 > MT76S_XMIT_BUF_SZ) + break; - if (mt7663s_tx_pick_quota(dev, qid, e->buf_sz, &pse_sz, + if (mt7663s_tx_pick_quota(sdio, qid, e->buf_sz, &pse_sz, &ple_sz)) break; - __skb_put_zero(e->skb, 4); + memcpy(sdio->xmit_buf[qid] + len, e->skb->data, + skb_headlen(e->skb)); + len += skb_headlen(e->skb); + nframes++; - err = __mt7663s_xmit_queue(dev, e->skb->data, e->skb->len); + skb_walk_frags(e->skb, iter) { + memcpy(sdio->xmit_buf[qid] + len, iter->data, + iter->len); + len += iter->len; + nframes++; + } +next: + q->first = (q->first + 1) % q->ndesc; + e->done = true; + } + + if (nframes) { + memset(sdio->xmit_buf[qid] + len, 0, 4); + err = __mt7663s_xmit_queue(dev, sdio->xmit_buf[qid], len + 4); if (err) return err; - - e->done = true; - q->first = (q->first + 1) % q->ndesc; - nframes++; } mt7663s_tx_update_quota(sdio, qid, pse_sz, ple_sz); |