xref: /linux/drivers/net/ethernet/marvell/octeon_ep/octep_tx.c (revision 34dc1baba215b826e454b8d19e4f24adbeb7d00d)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Marvell Octeon EP (EndPoint) Ethernet Driver
3  *
4  * Copyright (C) 2020 Marvell.
5  *
6  */
7 
8 #include <linux/pci.h>
9 #include <linux/etherdevice.h>
10 #include <linux/vmalloc.h>
11 
12 #include "octep_config.h"
13 #include "octep_main.h"
14 
15 /* Reset various index of Tx queue data structure. */
16 static void octep_iq_reset_indices(struct octep_iq *iq)
17 {
18 	iq->fill_cnt = 0;
19 	iq->host_write_index = 0;
20 	iq->octep_read_index = 0;
21 	iq->flush_index = 0;
22 	iq->pkts_processed = 0;
23 	iq->pkt_in_done = 0;
24 	atomic_set(&iq->instr_pending, 0);
25 }
26 
27 /**
28  * octep_iq_process_completions() - Process Tx queue completions.
29  *
30  * @iq: Octeon Tx queue data structure.
31  * @budget: max number of completions to be processed in one invocation.
32  */
33 int octep_iq_process_completions(struct octep_iq *iq, u16 budget)
34 {
35 	u32 compl_pkts, compl_bytes, compl_sg;
36 	struct octep_device *oct = iq->octep_dev;
37 	struct octep_tx_buffer *tx_buffer;
38 	struct skb_shared_info *shinfo;
39 	u32 fi = iq->flush_index;
40 	struct sk_buff *skb;
41 	u8 frags, i;
42 
43 	compl_pkts = 0;
44 	compl_sg = 0;
45 	compl_bytes = 0;
46 	iq->octep_read_index = oct->hw_ops.update_iq_read_idx(iq);
47 
48 	while (likely(budget && (fi != iq->octep_read_index))) {
49 		tx_buffer = iq->buff_info + fi;
50 		skb = tx_buffer->skb;
51 
52 		fi++;
53 		if (unlikely(fi == iq->max_count))
54 			fi = 0;
55 		compl_bytes += skb->len;
56 		compl_pkts++;
57 		budget--;
58 
59 		if (!tx_buffer->gather) {
60 			dma_unmap_single(iq->dev, tx_buffer->dma,
61 					 tx_buffer->skb->len, DMA_TO_DEVICE);
62 			dev_kfree_skb_any(skb);
63 			continue;
64 		}
65 
66 		/* Scatter/Gather */
67 		shinfo = skb_shinfo(skb);
68 		frags = shinfo->nr_frags;
69 		compl_sg++;
70 
71 		dma_unmap_single(iq->dev, tx_buffer->sglist[0].dma_ptr[0],
72 				 tx_buffer->sglist[0].len[3], DMA_TO_DEVICE);
73 
74 		i = 1; /* entry 0 is main skb, unmapped above */
75 		while (frags--) {
76 			dma_unmap_page(iq->dev, tx_buffer->sglist[i >> 2].dma_ptr[i & 3],
77 				       tx_buffer->sglist[i >> 2].len[3 - (i & 3)], DMA_TO_DEVICE);
78 			i++;
79 		}
80 
81 		dev_kfree_skb_any(skb);
82 	}
83 
84 	iq->pkts_processed += compl_pkts;
85 	atomic_sub(compl_pkts, &iq->instr_pending);
86 	iq->stats.instr_completed += compl_pkts;
87 	iq->stats.bytes_sent += compl_bytes;
88 	iq->stats.sgentry_sent += compl_sg;
89 	iq->flush_index = fi;
90 
91 	netdev_tx_completed_queue(iq->netdev_q, compl_pkts, compl_bytes);
92 
93 	if (unlikely(__netif_subqueue_stopped(iq->netdev, iq->q_no)) &&
94 	    ((iq->max_count - atomic_read(&iq->instr_pending)) >
95 	     OCTEP_WAKE_QUEUE_THRESHOLD))
96 		netif_wake_subqueue(iq->netdev, iq->q_no);
97 	return !budget;
98 }
99 
100 /**
101  * octep_iq_free_pending() - Free Tx buffers for pending completions.
102  *
103  * @iq: Octeon Tx queue data structure.
104  */
105 static void octep_iq_free_pending(struct octep_iq *iq)
106 {
107 	struct octep_tx_buffer *tx_buffer;
108 	struct skb_shared_info *shinfo;
109 	u32 fi = iq->flush_index;
110 	struct sk_buff *skb;
111 	u8 frags, i;
112 
113 	while (fi != iq->host_write_index) {
114 		tx_buffer = iq->buff_info + fi;
115 		skb = tx_buffer->skb;
116 
117 		fi++;
118 		if (unlikely(fi == iq->max_count))
119 			fi = 0;
120 
121 		if (!tx_buffer->gather) {
122 			dma_unmap_single(iq->dev, tx_buffer->dma,
123 					 tx_buffer->skb->len, DMA_TO_DEVICE);
124 			dev_kfree_skb_any(skb);
125 			continue;
126 		}
127 
128 		/* Scatter/Gather */
129 		shinfo = skb_shinfo(skb);
130 		frags = shinfo->nr_frags;
131 
132 		dma_unmap_single(iq->dev,
133 				 tx_buffer->sglist[0].dma_ptr[0],
134 				 tx_buffer->sglist[0].len[3],
135 				 DMA_TO_DEVICE);
136 
137 		i = 1; /* entry 0 is main skb, unmapped above */
138 		while (frags--) {
139 			dma_unmap_page(iq->dev, tx_buffer->sglist[i >> 2].dma_ptr[i & 3],
140 				       tx_buffer->sglist[i >> 2].len[3 - (i & 3)], DMA_TO_DEVICE);
141 			i++;
142 		}
143 
144 		dev_kfree_skb_any(skb);
145 	}
146 
147 	atomic_set(&iq->instr_pending, 0);
148 	iq->flush_index = fi;
149 	netdev_tx_reset_queue(netdev_get_tx_queue(iq->netdev, iq->q_no));
150 }
151 
152 /**
153  * octep_clean_iqs()  - Clean Tx queues to shutdown the device.
154  *
155  * @oct: Octeon device private data structure.
156  *
157  * Free the buffers in Tx queue descriptors pending completion and
158  * reset queue indices
159  */
160 void octep_clean_iqs(struct octep_device *oct)
161 {
162 	int i;
163 
164 	for (i = 0; i < oct->num_iqs; i++) {
165 		octep_iq_free_pending(oct->iq[i]);
166 		octep_iq_reset_indices(oct->iq[i]);
167 	}
168 }
169 
170 /**
171  * octep_setup_iq() - Setup a Tx queue.
172  *
173  * @oct: Octeon device private data structure.
174  * @q_no: Tx queue number to be setup.
175  *
176  * Allocate resources for a Tx queue.
177  */
178 static int octep_setup_iq(struct octep_device *oct, int q_no)
179 {
180 	u32 desc_ring_size, buff_info_size, sglist_size;
181 	struct octep_iq *iq;
182 	int i;
183 
184 	iq = vzalloc(sizeof(*iq));
185 	if (!iq)
186 		goto iq_alloc_err;
187 	oct->iq[q_no] = iq;
188 
189 	iq->octep_dev = oct;
190 	iq->netdev = oct->netdev;
191 	iq->dev = &oct->pdev->dev;
192 	iq->q_no = q_no;
193 	iq->max_count = CFG_GET_IQ_NUM_DESC(oct->conf);
194 	iq->ring_size_mask = iq->max_count - 1;
195 	iq->fill_threshold = CFG_GET_IQ_DB_MIN(oct->conf);
196 	iq->netdev_q = netdev_get_tx_queue(iq->netdev, q_no);
197 
198 	/* Allocate memory for hardware queue descriptors */
199 	desc_ring_size = OCTEP_IQ_DESC_SIZE * CFG_GET_IQ_NUM_DESC(oct->conf);
200 	iq->desc_ring = dma_alloc_coherent(iq->dev, desc_ring_size,
201 					   &iq->desc_ring_dma, GFP_KERNEL);
202 	if (unlikely(!iq->desc_ring)) {
203 		dev_err(iq->dev,
204 			"Failed to allocate DMA memory for IQ-%d\n", q_no);
205 		goto desc_dma_alloc_err;
206 	}
207 
208 	/* Allocate memory for hardware SGLIST descriptors */
209 	sglist_size = OCTEP_SGLIST_SIZE_PER_PKT *
210 		      CFG_GET_IQ_NUM_DESC(oct->conf);
211 	iq->sglist = dma_alloc_coherent(iq->dev, sglist_size,
212 					&iq->sglist_dma, GFP_KERNEL);
213 	if (unlikely(!iq->sglist)) {
214 		dev_err(iq->dev,
215 			"Failed to allocate DMA memory for IQ-%d SGLIST\n",
216 			q_no);
217 		goto sglist_alloc_err;
218 	}
219 
220 	/* allocate memory to manage Tx packets pending completion */
221 	buff_info_size = OCTEP_IQ_TXBUFF_INFO_SIZE * iq->max_count;
222 	iq->buff_info = vzalloc(buff_info_size);
223 	if (!iq->buff_info) {
224 		dev_err(iq->dev,
225 			"Failed to allocate buff info for IQ-%d\n", q_no);
226 		goto buff_info_err;
227 	}
228 
229 	/* Setup sglist addresses in tx_buffer entries */
230 	for (i = 0; i < CFG_GET_IQ_NUM_DESC(oct->conf); i++) {
231 		struct octep_tx_buffer *tx_buffer;
232 
233 		tx_buffer = &iq->buff_info[i];
234 		tx_buffer->sglist =
235 			&iq->sglist[i * OCTEP_SGLIST_ENTRIES_PER_PKT];
236 		tx_buffer->sglist_dma =
237 			iq->sglist_dma + (i * OCTEP_SGLIST_SIZE_PER_PKT);
238 	}
239 
240 	octep_iq_reset_indices(iq);
241 	oct->hw_ops.setup_iq_regs(oct, q_no);
242 
243 	oct->num_iqs++;
244 	return 0;
245 
246 buff_info_err:
247 	dma_free_coherent(iq->dev, sglist_size, iq->sglist, iq->sglist_dma);
248 sglist_alloc_err:
249 	dma_free_coherent(iq->dev, desc_ring_size,
250 			  iq->desc_ring, iq->desc_ring_dma);
251 desc_dma_alloc_err:
252 	vfree(iq);
253 	oct->iq[q_no] = NULL;
254 iq_alloc_err:
255 	return -1;
256 }
257 
258 /**
259  * octep_free_iq() - Free Tx queue resources.
260  *
261  * @iq: Octeon Tx queue data structure.
262  *
263  * Free all the resources allocated for a Tx queue.
264  */
265 static void octep_free_iq(struct octep_iq *iq)
266 {
267 	struct octep_device *oct = iq->octep_dev;
268 	u64 desc_ring_size, sglist_size;
269 	int q_no = iq->q_no;
270 
271 	desc_ring_size = OCTEP_IQ_DESC_SIZE * CFG_GET_IQ_NUM_DESC(oct->conf);
272 
273 	vfree(iq->buff_info);
274 
275 	if (iq->desc_ring)
276 		dma_free_coherent(iq->dev, desc_ring_size,
277 				  iq->desc_ring, iq->desc_ring_dma);
278 
279 	sglist_size = OCTEP_SGLIST_SIZE_PER_PKT *
280 		      CFG_GET_IQ_NUM_DESC(oct->conf);
281 	if (iq->sglist)
282 		dma_free_coherent(iq->dev, sglist_size,
283 				  iq->sglist, iq->sglist_dma);
284 
285 	vfree(iq);
286 	oct->iq[q_no] = NULL;
287 	oct->num_iqs--;
288 }
289 
290 /**
291  * octep_setup_iqs() - setup resources for all Tx queues.
292  *
293  * @oct: Octeon device private data structure.
294  */
295 int octep_setup_iqs(struct octep_device *oct)
296 {
297 	int i;
298 
299 	oct->num_iqs = 0;
300 	for (i = 0; i < CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf); i++) {
301 		if (octep_setup_iq(oct, i)) {
302 			dev_err(&oct->pdev->dev,
303 				"Failed to setup IQ(TxQ)-%d.\n", i);
304 			goto iq_setup_err;
305 		}
306 		dev_dbg(&oct->pdev->dev, "Successfully setup IQ(TxQ)-%d.\n", i);
307 	}
308 
309 	return 0;
310 
311 iq_setup_err:
312 	while (i) {
313 		i--;
314 		octep_free_iq(oct->iq[i]);
315 	}
316 	return -1;
317 }
318 
319 /**
320  * octep_free_iqs() - Free resources of all Tx queues.
321  *
322  * @oct: Octeon device private data structure.
323  */
324 void octep_free_iqs(struct octep_device *oct)
325 {
326 	int i;
327 
328 	for (i = 0; i < CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf); i++) {
329 		octep_free_iq(oct->iq[i]);
330 		dev_dbg(&oct->pdev->dev,
331 			"Successfully destroyed IQ(TxQ)-%d.\n", i);
332 	}
333 	oct->num_iqs = 0;
334 }
335