developer | 21e74f6 | 2023-01-30 14:02:51 +0800 | [diff] [blame^] | 1 | From cf9c84fbe7863a9af60e00bbb18ebdc6a4f29020 Mon Sep 17 00:00:00 2001 |
developer | 3d5faf2 | 2022-11-29 18:07:22 +0800 | [diff] [blame] | 2 | From: Sujuan Chen <sujuan.chen@mediatek.com> |
developer | b9a9660 | 2023-01-10 19:53:25 +0800 | [diff] [blame] | 3 | Date: Thu, 5 Jan 2023 16:43:57 +0800 |
| 4 | Subject: [PATCH 3003/3014] mt76: connac: wed: add wed rx copy skb |
developer | 3d5faf2 | 2022-11-29 18:07:22 +0800 | [diff] [blame] | 5 | |
| 6 | Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com> |
| 7 | --- |
developer | 21e74f6 | 2023-01-30 14:02:51 +0800 | [diff] [blame^] | 8 | dma.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++------------- |
| 9 | 1 file changed, 52 insertions(+), 15 deletions(-) |
developer | 3d5faf2 | 2022-11-29 18:07:22 +0800 | [diff] [blame] | 10 | |
| 11 | diff --git a/dma.c b/dma.c |
developer | 21e74f6 | 2023-01-30 14:02:51 +0800 | [diff] [blame^] | 12 | index e05b7ca1..74e2169e 100644 |
developer | 3d5faf2 | 2022-11-29 18:07:22 +0800 | [diff] [blame] | 13 | --- a/dma.c |
| 14 | +++ b/dma.c |
developer | b9a9660 | 2023-01-10 19:53:25 +0800 | [diff] [blame] | 15 | @@ -207,11 +207,11 @@ mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q) |
| 16 | |
| 17 | static int |
| 18 | mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q, |
| 19 | - struct mt76_queue_buf *buf, void *data) |
| 20 | + struct mt76_queue_buf *buf, void *data, |
| 21 | + struct mt76_txwi_cache *txwi) |
| 22 | { |
| 23 | struct mt76_desc *desc = &q->desc[q->head]; |
| 24 | struct mt76_queue_entry *entry = &q->entry[q->head]; |
| 25 | - struct mt76_txwi_cache *txwi = NULL; |
| 26 | u32 buf1 = 0, ctrl; |
| 27 | int idx = q->head; |
| 28 | int rx_token; |
| 29 | @@ -220,9 +220,11 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q, |
| 30 | |
| 31 | if ((q->flags & MT_QFLAG_WED) && |
| 32 | FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX) { |
| 33 | - txwi = mt76_get_rxwi(dev); |
| 34 | - if (!txwi) |
| 35 | - return -ENOMEM; |
| 36 | + if(!txwi) { |
| 37 | + txwi = mt76_get_rxwi(dev); |
| 38 | + if (!txwi) |
| 39 | + return -ENOMEM; |
| 40 | + } |
| 41 | |
| 42 | rx_token = mt76_rx_token_consume(dev, data, txwi, buf->addr); |
| 43 | if (rx_token < 0) { |
developer | 21e74f6 | 2023-01-30 14:02:51 +0800 | [diff] [blame^] | 44 | @@ -386,7 +388,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush) |
developer | b9a9660 | 2023-01-10 19:53:25 +0800 | [diff] [blame] | 45 | |
developer | 21e74f6 | 2023-01-30 14:02:51 +0800 | [diff] [blame^] | 46 | static void * |
| 47 | mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx, |
| 48 | - int *len, u32 *info, bool *more, bool *drop) |
| 49 | + int *len, u32 *info, bool *more, bool *drop, bool flush) |
| 50 | { |
| 51 | struct mt76_queue_entry *e = &q->entry[idx]; |
| 52 | struct mt76_desc *desc = &q->desc[idx]; |
| 53 | @@ -413,12 +415,43 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx, |
| 54 | dma_unmap_single(dev->dma_dev, t->dma_addr, |
developer | 3d5faf2 | 2022-11-29 18:07:22 +0800 | [diff] [blame] | 55 | SKB_WITH_OVERHEAD(q->buf_size), |
| 56 | DMA_FROM_DEVICE); |
developer | 21e74f6 | 2023-01-30 14:02:51 +0800 | [diff] [blame^] | 57 | - |
developer | 3d5faf2 | 2022-11-29 18:07:22 +0800 | [diff] [blame] | 58 | - buf = t->ptr; |
developer | b9a9660 | 2023-01-10 19:53:25 +0800 | [diff] [blame] | 59 | - t->dma_addr = 0; |
| 60 | - t->ptr = NULL; |
developer | 21e74f6 | 2023-01-30 14:02:51 +0800 | [diff] [blame^] | 61 | - |
| 62 | - mt76_put_rxwi(dev, t); |
| 63 | + if (flush) { |
| 64 | + buf = t->ptr; |
| 65 | + t->dma_addr = 0; |
| 66 | + t->ptr = NULL; |
developer | b9a9660 | 2023-01-10 19:53:25 +0800 | [diff] [blame] | 67 | + |
developer | b9a9660 | 2023-01-10 19:53:25 +0800 | [diff] [blame] | 68 | + mt76_put_rxwi(dev, t); |
developer | 21e74f6 | 2023-01-30 14:02:51 +0800 | [diff] [blame^] | 69 | + } else { |
| 70 | + struct mt76_queue_buf qbuf; |
developer | 3d5faf2 | 2022-11-29 18:07:22 +0800 | [diff] [blame] | 71 | + |
developer | 21e74f6 | 2023-01-30 14:02:51 +0800 | [diff] [blame^] | 72 | + buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC); |
| 73 | + if (!buf) |
| 74 | + return NULL; |
| 75 | + |
| 76 | + memcpy(buf, t->ptr, SKB_WITH_OVERHEAD(q->buf_size)); |
| 77 | + |
| 78 | + t->dma_addr = dma_map_single(dev->dma_dev, t->ptr, |
| 79 | + SKB_WITH_OVERHEAD(q->buf_size), |
| 80 | + DMA_FROM_DEVICE); |
| 81 | + if (unlikely(dma_mapping_error(dev->dma_dev, t->dma_addr))) { |
| 82 | + skb_free_frag(t->ptr); |
| 83 | + mt76_put_rxwi(dev, t); |
| 84 | + return NULL; |
| 85 | + } |
| 86 | + |
| 87 | + qbuf.addr = t->dma_addr; |
| 88 | + qbuf.len = SKB_WITH_OVERHEAD(q->buf_size); |
| 89 | + qbuf.skip_unmap = false; |
| 90 | + |
| 91 | + if (mt76_dma_add_rx_buf(dev, q, &qbuf, t->ptr, t) < 0) { |
| 92 | + dma_unmap_single(dev->dma_dev, t->dma_addr, |
| 93 | + SKB_WITH_OVERHEAD(q->buf_size), |
| 94 | + DMA_FROM_DEVICE); |
| 95 | + skb_free_frag(t->ptr); |
| 96 | + mt76_put_rxwi(dev, t); |
| 97 | + return NULL; |
| 98 | + } |
developer | 3d5faf2 | 2022-11-29 18:07:22 +0800 | [diff] [blame] | 99 | + } |
| 100 | |
developer | b9a9660 | 2023-01-10 19:53:25 +0800 | [diff] [blame] | 101 | if (drop) { |
| 102 | u32 ctrl = le32_to_cpu(READ_ONCE(desc->ctrl)); |
developer | 21e74f6 | 2023-01-30 14:02:51 +0800 | [diff] [blame^] | 103 | @@ -455,7 +488,7 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush, |
| 104 | q->tail = (q->tail + 1) % q->ndesc; |
| 105 | q->queued--; |
| 106 | |
| 107 | - return mt76_dma_get_buf(dev, q, idx, len, info, more, drop); |
| 108 | + return mt76_dma_get_buf(dev, q, idx, len, info, more, drop, flush); |
| 109 | } |
| 110 | |
| 111 | static int |
| 112 | @@ -587,6 +620,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q) |
developer | b9a9660 | 2023-01-10 19:53:25 +0800 | [diff] [blame] | 113 | int len = SKB_WITH_OVERHEAD(q->buf_size); |
| 114 | int frames = 0, offset = q->buf_offset; |
| 115 | dma_addr_t addr; |
| 116 | + bool flags = false; |
developer | 3d5faf2 | 2022-11-29 18:07:22 +0800 | [diff] [blame] | 117 | |
developer | b9a9660 | 2023-01-10 19:53:25 +0800 | [diff] [blame] | 118 | if (!q->ndesc) |
| 119 | return 0; |
developer | 21e74f6 | 2023-01-30 14:02:51 +0800 | [diff] [blame^] | 120 | @@ -610,7 +644,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q) |
developer | b9a9660 | 2023-01-10 19:53:25 +0800 | [diff] [blame] | 121 | qbuf.addr = addr + offset; |
| 122 | qbuf.len = len - offset; |
| 123 | qbuf.skip_unmap = false; |
| 124 | - if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf) < 0) { |
| 125 | + if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf, NULL) < 0) { |
| 126 | dma_unmap_single(dev->dma_dev, addr, len, |
| 127 | DMA_FROM_DEVICE); |
| 128 | skb_free_frag(buf); |
developer | 21e74f6 | 2023-01-30 14:02:51 +0800 | [diff] [blame^] | 129 | @@ -619,7 +653,10 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q) |
developer | b9a9660 | 2023-01-10 19:53:25 +0800 | [diff] [blame] | 130 | frames++; |
| 131 | } |
| 132 | |
| 133 | - if (frames) |
| 134 | + flags = (q->flags & MT_QFLAG_WED) && |
| 135 | + FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX; |
developer | 3d5faf2 | 2022-11-29 18:07:22 +0800 | [diff] [blame] | 136 | + |
developer | b9a9660 | 2023-01-10 19:53:25 +0800 | [diff] [blame] | 137 | + if (frames || flags) |
| 138 | mt76_dma_kick_queue(dev, q); |
| 139 | |
| 140 | spin_unlock_bh(&q->lock); |
developer | 3d5faf2 | 2022-11-29 18:07:22 +0800 | [diff] [blame] | 141 | -- |
developer | 79a21a2 | 2023-01-09 13:57:39 +0800 | [diff] [blame] | 142 | 2.18.0 |
developer | 3d5faf2 | 2022-11-29 18:07:22 +0800 | [diff] [blame] | 143 | |