1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2015 - 2016 CESNET
3  */
4 
5 #include <stdint.h>
6 #include <unistd.h>
7 #include <stdbool.h>
8 #include <err.h>
9 #include <sys/types.h>
10 #include <dirent.h>
11 #include <sys/stat.h>
12 #include <fcntl.h>
13 #include <sys/mman.h>
14 
15 #include <libsze2.h>
16 
17 #include <rte_mbuf.h>
18 #include <rte_ethdev_driver.h>
19 #include <rte_ethdev_pci.h>
20 #include <rte_malloc.h>
21 #include <rte_memcpy.h>
22 #include <rte_kvargs.h>
23 #include <rte_dev.h>
24 
25 #include "rte_eth_szedata2.h"
26 #include "szedata2_logs.h"
27 
28 #define RTE_ETH_SZEDATA2_MAX_RX_QUEUES 32
29 #define RTE_ETH_SZEDATA2_MAX_TX_QUEUES 32
30 #define RTE_ETH_SZEDATA2_TX_LOCK_SIZE (32 * 1024 * 1024)
31 
32 /**
33  * size of szedata2_packet header with alignment
34  */
35 #define RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED 8
36 
37 #define RTE_SZEDATA2_DRIVER_NAME net_szedata2
38 
39 #define SZEDATA2_DEV_PATH_FMT "/dev/szedataII%u"
40 
41 /**
42  * Format string for suffix used to differentiate between Ethernet ports
43  * on the same PCI device.
44  */
45 #define SZEDATA2_ETH_DEV_NAME_SUFFIX_FMT "-port%u"
46 
47 /**
48  * Maximum number of ports for one device.
49  */
50 #define SZEDATA2_MAX_PORTS 2
51 
52 /**
53  * Entry in list of PCI devices for this driver.
54  */
55 struct pci_dev_list_entry;
56 struct pci_dev_list_entry {
57 	LIST_ENTRY(pci_dev_list_entry) next;
58 	struct rte_pci_device *pci_dev;
59 	unsigned int port_count;
60 };
61 
62 /* List of PCI devices with number of ports for this driver. */
63 LIST_HEAD(pci_dev_list, pci_dev_list_entry) szedata2_pci_dev_list =
64 	LIST_HEAD_INITIALIZER(szedata2_pci_dev_list);
65 
66 struct port_info {
67 	unsigned int rx_base_id;
68 	unsigned int tx_base_id;
69 	unsigned int rx_count;
70 	unsigned int tx_count;
71 	int numa_node;
72 };
73 
74 struct pmd_internals {
75 	struct rte_eth_dev *dev;
76 	uint16_t max_rx_queues;
77 	uint16_t max_tx_queues;
78 	unsigned int rxq_base_id;
79 	unsigned int txq_base_id;
80 	char *sze_dev_path;
81 };
82 
83 struct szedata2_rx_queue {
84 	struct pmd_internals *priv;
85 	struct szedata *sze;
86 	uint8_t rx_channel;
87 	uint16_t qid;
88 	uint16_t in_port;
89 	struct rte_mempool *mb_pool;
90 	volatile uint64_t rx_pkts;
91 	volatile uint64_t rx_bytes;
92 	volatile uint64_t err_pkts;
93 };
94 
95 struct szedata2_tx_queue {
96 	struct pmd_internals *priv;
97 	struct szedata *sze;
98 	uint8_t tx_channel;
99 	uint16_t qid;
100 	volatile uint64_t tx_pkts;
101 	volatile uint64_t tx_bytes;
102 	volatile uint64_t err_pkts;
103 };
104 
105 static struct rte_ether_addr eth_addr = {
106 	.addr_bytes = { 0x00, 0x11, 0x17, 0x00, 0x00, 0x00 }
107 };
108 
109 static uint16_t
eth_szedata2_rx(void * queue,struct rte_mbuf ** bufs,uint16_t nb_pkts)110 eth_szedata2_rx(void *queue,
111 		struct rte_mbuf **bufs,
112 		uint16_t nb_pkts)
113 {
114 	unsigned int i;
115 	struct rte_mbuf *mbuf;
116 	struct szedata2_rx_queue *sze_q = queue;
117 	struct rte_pktmbuf_pool_private *mbp_priv;
118 	uint16_t num_rx = 0;
119 	uint16_t buf_size;
120 	uint16_t sg_size;
121 	uint16_t hw_size;
122 	uint16_t packet_size;
123 	uint64_t num_bytes = 0;
124 	struct szedata *sze = sze_q->sze;
125 	uint8_t *header_ptr = NULL; /* header of packet */
126 	uint8_t *packet_ptr1 = NULL;
127 	uint8_t *packet_ptr2 = NULL;
128 	uint16_t packet_len1 = 0;
129 	uint16_t packet_len2 = 0;
130 	uint16_t hw_data_align;
131 
132 	if (unlikely(sze_q->sze == NULL || nb_pkts == 0))
133 		return 0;
134 
135 	/*
136 	 * Reads the given number of packets from szedata2 channel given
137 	 * by queue and copies the packet data into a newly allocated mbuf
138 	 * to return.
139 	 */
140 	for (i = 0; i < nb_pkts; i++) {
141 		mbuf = rte_pktmbuf_alloc(sze_q->mb_pool);
142 
143 		if (unlikely(mbuf == NULL)) {
144 			sze_q->priv->dev->data->rx_mbuf_alloc_failed++;
145 			break;
146 		}
147 
148 		/* get the next sze packet */
149 		if (sze->ct_rx_lck != NULL && !sze->ct_rx_rem_bytes &&
150 				sze->ct_rx_lck->next == NULL) {
151 			/* unlock old data */
152 			szedata_rx_unlock_data(sze_q->sze, sze->ct_rx_lck_orig);
153 			sze->ct_rx_lck_orig = NULL;
154 			sze->ct_rx_lck = NULL;
155 		}
156 
157 		if (!sze->ct_rx_rem_bytes && sze->ct_rx_lck_orig == NULL) {
158 			/* nothing to read, lock new data */
159 			sze->ct_rx_lck = szedata_rx_lock_data(sze_q->sze, ~0U);
160 			sze->ct_rx_lck_orig = sze->ct_rx_lck;
161 
162 			if (sze->ct_rx_lck == NULL) {
163 				/* nothing to lock */
164 				rte_pktmbuf_free(mbuf);
165 				break;
166 			}
167 
168 			sze->ct_rx_cur_ptr = sze->ct_rx_lck->start;
169 			sze->ct_rx_rem_bytes = sze->ct_rx_lck->len;
170 
171 			if (!sze->ct_rx_rem_bytes) {
172 				rte_pktmbuf_free(mbuf);
173 				break;
174 			}
175 		}
176 
177 		if (sze->ct_rx_rem_bytes < RTE_SZE2_PACKET_HEADER_SIZE) {
178 			/*
179 			 * cut in header
180 			 * copy parts of header to merge buffer
181 			 */
182 			if (sze->ct_rx_lck->next == NULL) {
183 				rte_pktmbuf_free(mbuf);
184 				break;
185 			}
186 
187 			/* copy first part of header */
188 			rte_memcpy(sze->ct_rx_buffer, sze->ct_rx_cur_ptr,
189 					sze->ct_rx_rem_bytes);
190 
191 			/* copy second part of header */
192 			sze->ct_rx_lck = sze->ct_rx_lck->next;
193 			sze->ct_rx_cur_ptr = sze->ct_rx_lck->start;
194 			rte_memcpy(sze->ct_rx_buffer + sze->ct_rx_rem_bytes,
195 				sze->ct_rx_cur_ptr,
196 				RTE_SZE2_PACKET_HEADER_SIZE -
197 				sze->ct_rx_rem_bytes);
198 
199 			sze->ct_rx_cur_ptr += RTE_SZE2_PACKET_HEADER_SIZE -
200 				sze->ct_rx_rem_bytes;
201 			sze->ct_rx_rem_bytes = sze->ct_rx_lck->len -
202 				RTE_SZE2_PACKET_HEADER_SIZE +
203 				sze->ct_rx_rem_bytes;
204 
205 			header_ptr = (uint8_t *)sze->ct_rx_buffer;
206 		} else {
207 			/* not cut */
208 			header_ptr = (uint8_t *)sze->ct_rx_cur_ptr;
209 			sze->ct_rx_cur_ptr += RTE_SZE2_PACKET_HEADER_SIZE;
210 			sze->ct_rx_rem_bytes -= RTE_SZE2_PACKET_HEADER_SIZE;
211 		}
212 
213 		sg_size = le16toh(*((uint16_t *)header_ptr));
214 		hw_size = le16toh(*(((uint16_t *)header_ptr) + 1));
215 		packet_size = sg_size -
216 			RTE_SZE2_ALIGN8(RTE_SZE2_PACKET_HEADER_SIZE + hw_size);
217 
218 
219 		/* checks if packet all right */
220 		if (!sg_size)
221 			errx(5, "Zero segsize");
222 
223 		/* check sg_size and hwsize */
224 		if (hw_size > sg_size - RTE_SZE2_PACKET_HEADER_SIZE) {
225 			errx(10, "Hwsize bigger than expected. Segsize: %d, "
226 				"hwsize: %d", sg_size, hw_size);
227 		}
228 
229 		hw_data_align =
230 			RTE_SZE2_ALIGN8(RTE_SZE2_PACKET_HEADER_SIZE + hw_size) -
231 			RTE_SZE2_PACKET_HEADER_SIZE;
232 
233 		if (sze->ct_rx_rem_bytes >=
234 				(uint16_t)(sg_size -
235 				RTE_SZE2_PACKET_HEADER_SIZE)) {
236 			/* no cut */
237 			/* one packet ready - go to another */
238 			packet_ptr1 = sze->ct_rx_cur_ptr + hw_data_align;
239 			packet_len1 = packet_size;
240 			packet_ptr2 = NULL;
241 			packet_len2 = 0;
242 
243 			sze->ct_rx_cur_ptr += RTE_SZE2_ALIGN8(sg_size) -
244 				RTE_SZE2_PACKET_HEADER_SIZE;
245 			sze->ct_rx_rem_bytes -= RTE_SZE2_ALIGN8(sg_size) -
246 				RTE_SZE2_PACKET_HEADER_SIZE;
247 		} else {
248 			/* cut in data */
249 			if (sze->ct_rx_lck->next == NULL) {
250 				errx(6, "Need \"next\" lock, "
251 					"but it is missing: %u",
252 					sze->ct_rx_rem_bytes);
253 			}
254 
255 			/* skip hw data */
256 			if (sze->ct_rx_rem_bytes <= hw_data_align) {
257 				uint16_t rem_size = hw_data_align -
258 					sze->ct_rx_rem_bytes;
259 
260 				/* MOVE to next lock */
261 				sze->ct_rx_lck = sze->ct_rx_lck->next;
262 				sze->ct_rx_cur_ptr =
263 					(void *)(((uint8_t *)
264 					(sze->ct_rx_lck->start)) + rem_size);
265 
266 				packet_ptr1 = sze->ct_rx_cur_ptr;
267 				packet_len1 = packet_size;
268 				packet_ptr2 = NULL;
269 				packet_len2 = 0;
270 
271 				sze->ct_rx_cur_ptr +=
272 					RTE_SZE2_ALIGN8(packet_size);
273 				sze->ct_rx_rem_bytes = sze->ct_rx_lck->len -
274 					rem_size - RTE_SZE2_ALIGN8(packet_size);
275 			} else {
276 				/* get pointer and length from first part */
277 				packet_ptr1 = sze->ct_rx_cur_ptr +
278 					hw_data_align;
279 				packet_len1 = sze->ct_rx_rem_bytes -
280 					hw_data_align;
281 
282 				/* MOVE to next lock */
283 				sze->ct_rx_lck = sze->ct_rx_lck->next;
284 				sze->ct_rx_cur_ptr = sze->ct_rx_lck->start;
285 
286 				/* get pointer and length from second part */
287 				packet_ptr2 = sze->ct_rx_cur_ptr;
288 				packet_len2 = packet_size - packet_len1;
289 
290 				sze->ct_rx_cur_ptr +=
291 					RTE_SZE2_ALIGN8(packet_size) -
292 					packet_len1;
293 				sze->ct_rx_rem_bytes = sze->ct_rx_lck->len -
294 					(RTE_SZE2_ALIGN8(packet_size) -
295 					 packet_len1);
296 			}
297 		}
298 
299 		if (unlikely(packet_ptr1 == NULL)) {
300 			rte_pktmbuf_free(mbuf);
301 			break;
302 		}
303 
304 		/* get the space available for data in the mbuf */
305 		mbp_priv = rte_mempool_get_priv(sze_q->mb_pool);
306 		buf_size = (uint16_t)(mbp_priv->mbuf_data_room_size -
307 				RTE_PKTMBUF_HEADROOM);
308 
309 		if (packet_size <= buf_size) {
310 			/* sze packet will fit in one mbuf, go ahead and copy */
311 			rte_memcpy(rte_pktmbuf_mtod(mbuf, void *),
312 					packet_ptr1, packet_len1);
313 			if (packet_ptr2 != NULL) {
314 				rte_memcpy((void *)(rte_pktmbuf_mtod(mbuf,
315 					uint8_t *) + packet_len1),
316 					packet_ptr2, packet_len2);
317 			}
318 			mbuf->data_len = (uint16_t)packet_size;
319 
320 			mbuf->pkt_len = packet_size;
321 			mbuf->port = sze_q->in_port;
322 			bufs[num_rx] = mbuf;
323 			num_rx++;
324 			num_bytes += packet_size;
325 		} else {
326 			/*
327 			 * sze packet will not fit in one mbuf,
328 			 * scattered mode is not enabled, drop packet
329 			 */
330 			PMD_DRV_LOG(ERR,
331 				"SZE segment %d bytes will not fit in one mbuf "
332 				"(%d bytes), scattered mode is not enabled, "
333 				"drop packet!!",
334 				packet_size, buf_size);
335 			rte_pktmbuf_free(mbuf);
336 		}
337 	}
338 
339 	sze_q->rx_pkts += num_rx;
340 	sze_q->rx_bytes += num_bytes;
341 	return num_rx;
342 }
343 
344 static uint16_t
eth_szedata2_rx_scattered(void * queue,struct rte_mbuf ** bufs,uint16_t nb_pkts)345 eth_szedata2_rx_scattered(void *queue,
346 		struct rte_mbuf **bufs,
347 		uint16_t nb_pkts)
348 {
349 	unsigned int i;
350 	struct rte_mbuf *mbuf;
351 	struct szedata2_rx_queue *sze_q = queue;
352 	struct rte_pktmbuf_pool_private *mbp_priv;
353 	uint16_t num_rx = 0;
354 	uint16_t buf_size;
355 	uint16_t sg_size;
356 	uint16_t hw_size;
357 	uint16_t packet_size;
358 	uint64_t num_bytes = 0;
359 	struct szedata *sze = sze_q->sze;
360 	uint8_t *header_ptr = NULL; /* header of packet */
361 	uint8_t *packet_ptr1 = NULL;
362 	uint8_t *packet_ptr2 = NULL;
363 	uint16_t packet_len1 = 0;
364 	uint16_t packet_len2 = 0;
365 	uint16_t hw_data_align;
366 	uint64_t *mbuf_failed_ptr =
367 		&sze_q->priv->dev->data->rx_mbuf_alloc_failed;
368 
369 	if (unlikely(sze_q->sze == NULL || nb_pkts == 0))
370 		return 0;
371 
372 	/*
373 	 * Reads the given number of packets from szedata2 channel given
374 	 * by queue and copies the packet data into a newly allocated mbuf
375 	 * to return.
376 	 */
377 	for (i = 0; i < nb_pkts; i++) {
378 		const struct szedata_lock *ct_rx_lck_backup;
379 		unsigned int ct_rx_rem_bytes_backup;
380 		unsigned char *ct_rx_cur_ptr_backup;
381 
382 		/* get the next sze packet */
383 		if (sze->ct_rx_lck != NULL && !sze->ct_rx_rem_bytes &&
384 				sze->ct_rx_lck->next == NULL) {
385 			/* unlock old data */
386 			szedata_rx_unlock_data(sze_q->sze, sze->ct_rx_lck_orig);
387 			sze->ct_rx_lck_orig = NULL;
388 			sze->ct_rx_lck = NULL;
389 		}
390 
391 		/*
392 		 * Store items from sze structure which can be changed
393 		 * before mbuf allocating. Use these items in case of mbuf
394 		 * allocating failure.
395 		 */
396 		ct_rx_lck_backup = sze->ct_rx_lck;
397 		ct_rx_rem_bytes_backup = sze->ct_rx_rem_bytes;
398 		ct_rx_cur_ptr_backup = sze->ct_rx_cur_ptr;
399 
400 		if (!sze->ct_rx_rem_bytes && sze->ct_rx_lck_orig == NULL) {
401 			/* nothing to read, lock new data */
402 			sze->ct_rx_lck = szedata_rx_lock_data(sze_q->sze, ~0U);
403 			sze->ct_rx_lck_orig = sze->ct_rx_lck;
404 
405 			/*
406 			 * Backup items from sze structure must be updated
407 			 * after locking to contain pointers to new locks.
408 			 */
409 			ct_rx_lck_backup = sze->ct_rx_lck;
410 			ct_rx_rem_bytes_backup = sze->ct_rx_rem_bytes;
411 			ct_rx_cur_ptr_backup = sze->ct_rx_cur_ptr;
412 
413 			if (sze->ct_rx_lck == NULL)
414 				/* nothing to lock */
415 				break;
416 
417 			sze->ct_rx_cur_ptr = sze->ct_rx_lck->start;
418 			sze->ct_rx_rem_bytes = sze->ct_rx_lck->len;
419 
420 			if (!sze->ct_rx_rem_bytes)
421 				break;
422 		}
423 
424 		if (sze->ct_rx_rem_bytes < RTE_SZE2_PACKET_HEADER_SIZE) {
425 			/*
426 			 * cut in header - copy parts of header to merge buffer
427 			 */
428 			if (sze->ct_rx_lck->next == NULL)
429 				break;
430 
431 			/* copy first part of header */
432 			rte_memcpy(sze->ct_rx_buffer, sze->ct_rx_cur_ptr,
433 					sze->ct_rx_rem_bytes);
434 
435 			/* copy second part of header */
436 			sze->ct_rx_lck = sze->ct_rx_lck->next;
437 			sze->ct_rx_cur_ptr = sze->ct_rx_lck->start;
438 			rte_memcpy(sze->ct_rx_buffer + sze->ct_rx_rem_bytes,
439 				sze->ct_rx_cur_ptr,
440 				RTE_SZE2_PACKET_HEADER_SIZE -
441 				sze->ct_rx_rem_bytes);
442 
443 			sze->ct_rx_cur_ptr += RTE_SZE2_PACKET_HEADER_SIZE -
444 				sze->ct_rx_rem_bytes;
445 			sze->ct_rx_rem_bytes = sze->ct_rx_lck->len -
446 				RTE_SZE2_PACKET_HEADER_SIZE +
447 				sze->ct_rx_rem_bytes;
448 
449 			header_ptr = (uint8_t *)sze->ct_rx_buffer;
450 		} else {
451 			/* not cut */
452 			header_ptr = (uint8_t *)sze->ct_rx_cur_ptr;
453 			sze->ct_rx_cur_ptr += RTE_SZE2_PACKET_HEADER_SIZE;
454 			sze->ct_rx_rem_bytes -= RTE_SZE2_PACKET_HEADER_SIZE;
455 		}
456 
457 		sg_size = le16toh(*((uint16_t *)header_ptr));
458 		hw_size = le16toh(*(((uint16_t *)header_ptr) + 1));
459 		packet_size = sg_size -
460 			RTE_SZE2_ALIGN8(RTE_SZE2_PACKET_HEADER_SIZE + hw_size);
461 
462 
463 		/* checks if packet all right */
464 		if (!sg_size)
465 			errx(5, "Zero segsize");
466 
467 		/* check sg_size and hwsize */
468 		if (hw_size > sg_size - RTE_SZE2_PACKET_HEADER_SIZE) {
469 			errx(10, "Hwsize bigger than expected. Segsize: %d, "
470 					"hwsize: %d", sg_size, hw_size);
471 		}
472 
473 		hw_data_align =
474 			RTE_SZE2_ALIGN8((RTE_SZE2_PACKET_HEADER_SIZE +
475 			hw_size)) - RTE_SZE2_PACKET_HEADER_SIZE;
476 
477 		if (sze->ct_rx_rem_bytes >=
478 				(uint16_t)(sg_size -
479 				RTE_SZE2_PACKET_HEADER_SIZE)) {
480 			/* no cut */
481 			/* one packet ready - go to another */
482 			packet_ptr1 = sze->ct_rx_cur_ptr + hw_data_align;
483 			packet_len1 = packet_size;
484 			packet_ptr2 = NULL;
485 			packet_len2 = 0;
486 
487 			sze->ct_rx_cur_ptr += RTE_SZE2_ALIGN8(sg_size) -
488 				RTE_SZE2_PACKET_HEADER_SIZE;
489 			sze->ct_rx_rem_bytes -= RTE_SZE2_ALIGN8(sg_size) -
490 				RTE_SZE2_PACKET_HEADER_SIZE;
491 		} else {
492 			/* cut in data */
493 			if (sze->ct_rx_lck->next == NULL) {
494 				errx(6, "Need \"next\" lock, but it is "
495 					"missing: %u", sze->ct_rx_rem_bytes);
496 			}
497 
498 			/* skip hw data */
499 			if (sze->ct_rx_rem_bytes <= hw_data_align) {
500 				uint16_t rem_size = hw_data_align -
501 					sze->ct_rx_rem_bytes;
502 
503 				/* MOVE to next lock */
504 				sze->ct_rx_lck = sze->ct_rx_lck->next;
505 				sze->ct_rx_cur_ptr =
506 					(void *)(((uint8_t *)
507 					(sze->ct_rx_lck->start)) + rem_size);
508 
509 				packet_ptr1 = sze->ct_rx_cur_ptr;
510 				packet_len1 = packet_size;
511 				packet_ptr2 = NULL;
512 				packet_len2 = 0;
513 
514 				sze->ct_rx_cur_ptr +=
515 					RTE_SZE2_ALIGN8(packet_size);
516 				sze->ct_rx_rem_bytes = sze->ct_rx_lck->len -
517 					rem_size - RTE_SZE2_ALIGN8(packet_size);
518 			} else {
519 				/* get pointer and length from first part */
520 				packet_ptr1 = sze->ct_rx_cur_ptr +
521 					hw_data_align;
522 				packet_len1 = sze->ct_rx_rem_bytes -
523 					hw_data_align;
524 
525 				/* MOVE to next lock */
526 				sze->ct_rx_lck = sze->ct_rx_lck->next;
527 				sze->ct_rx_cur_ptr = sze->ct_rx_lck->start;
528 
529 				/* get pointer and length from second part */
530 				packet_ptr2 = sze->ct_rx_cur_ptr;
531 				packet_len2 = packet_size - packet_len1;
532 
533 				sze->ct_rx_cur_ptr +=
534 					RTE_SZE2_ALIGN8(packet_size) -
535 					packet_len1;
536 				sze->ct_rx_rem_bytes = sze->ct_rx_lck->len -
537 					(RTE_SZE2_ALIGN8(packet_size) -
538 					 packet_len1);
539 			}
540 		}
541 
542 		if (unlikely(packet_ptr1 == NULL))
543 			break;
544 
545 		mbuf = rte_pktmbuf_alloc(sze_q->mb_pool);
546 
547 		if (unlikely(mbuf == NULL)) {
548 			/*
549 			 * Restore items from sze structure to state after
550 			 * unlocking (eventually locking).
551 			 */
552 			sze->ct_rx_lck = ct_rx_lck_backup;
553 			sze->ct_rx_rem_bytes = ct_rx_rem_bytes_backup;
554 			sze->ct_rx_cur_ptr = ct_rx_cur_ptr_backup;
555 			sze_q->priv->dev->data->rx_mbuf_alloc_failed++;
556 			break;
557 		}
558 
559 		/* get the space available for data in the mbuf */
560 		mbp_priv = rte_mempool_get_priv(sze_q->mb_pool);
561 		buf_size = (uint16_t)(mbp_priv->mbuf_data_room_size -
562 				RTE_PKTMBUF_HEADROOM);
563 
564 		if (packet_size <= buf_size) {
565 			/* sze packet will fit in one mbuf, go ahead and copy */
566 			rte_memcpy(rte_pktmbuf_mtod(mbuf, void *),
567 					packet_ptr1, packet_len1);
568 			if (packet_ptr2 != NULL) {
569 				rte_memcpy((void *)
570 					(rte_pktmbuf_mtod(mbuf, uint8_t *) +
571 					packet_len1), packet_ptr2, packet_len2);
572 			}
573 			mbuf->data_len = (uint16_t)packet_size;
574 		} else {
575 			/*
576 			 * sze packet will not fit in one mbuf,
577 			 * scatter packet into more mbufs
578 			 */
579 			struct rte_mbuf *m = mbuf;
580 			uint16_t len = rte_pktmbuf_tailroom(mbuf);
581 
582 			/* copy first part of packet */
583 			/* fill first mbuf */
584 			rte_memcpy(rte_pktmbuf_append(mbuf, len), packet_ptr1,
585 				len);
586 			packet_len1 -= len;
587 			packet_ptr1 = ((uint8_t *)packet_ptr1) + len;
588 
589 			while (packet_len1 > 0) {
590 				/* fill new mbufs */
591 				m->next = rte_pktmbuf_alloc(sze_q->mb_pool);
592 
593 				if (unlikely(m->next == NULL)) {
594 					rte_pktmbuf_free(mbuf);
595 					/*
596 					 * Restore items from sze structure
597 					 * to state after unlocking (eventually
598 					 * locking).
599 					 */
600 					sze->ct_rx_lck = ct_rx_lck_backup;
601 					sze->ct_rx_rem_bytes =
602 						ct_rx_rem_bytes_backup;
603 					sze->ct_rx_cur_ptr =
604 						ct_rx_cur_ptr_backup;
605 					(*mbuf_failed_ptr)++;
606 					goto finish;
607 				}
608 
609 				m = m->next;
610 
611 				len = RTE_MIN(rte_pktmbuf_tailroom(m),
612 					packet_len1);
613 				rte_memcpy(rte_pktmbuf_append(mbuf, len),
614 					packet_ptr1, len);
615 
616 				(mbuf->nb_segs)++;
617 				packet_len1 -= len;
618 				packet_ptr1 = ((uint8_t *)packet_ptr1) + len;
619 			}
620 
621 			if (packet_ptr2 != NULL) {
622 				/* copy second part of packet, if exists */
623 				/* fill the rest of currently last mbuf */
624 				len = rte_pktmbuf_tailroom(m);
625 				rte_memcpy(rte_pktmbuf_append(mbuf, len),
626 					packet_ptr2, len);
627 				packet_len2 -= len;
628 				packet_ptr2 = ((uint8_t *)packet_ptr2) + len;
629 
630 				while (packet_len2 > 0) {
631 					/* fill new mbufs */
632 					m->next = rte_pktmbuf_alloc(
633 							sze_q->mb_pool);
634 
635 					if (unlikely(m->next == NULL)) {
636 						rte_pktmbuf_free(mbuf);
637 						/*
638 						 * Restore items from sze
639 						 * structure to state after
640 						 * unlocking (eventually
641 						 * locking).
642 						 */
643 						sze->ct_rx_lck =
644 							ct_rx_lck_backup;
645 						sze->ct_rx_rem_bytes =
646 							ct_rx_rem_bytes_backup;
647 						sze->ct_rx_cur_ptr =
648 							ct_rx_cur_ptr_backup;
649 						(*mbuf_failed_ptr)++;
650 						goto finish;
651 					}
652 
653 					m = m->next;
654 
655 					len = RTE_MIN(rte_pktmbuf_tailroom(m),
656 						packet_len2);
657 					rte_memcpy(
658 						rte_pktmbuf_append(mbuf, len),
659 						packet_ptr2, len);
660 
661 					(mbuf->nb_segs)++;
662 					packet_len2 -= len;
663 					packet_ptr2 = ((uint8_t *)packet_ptr2) +
664 						len;
665 				}
666 			}
667 		}
668 		mbuf->pkt_len = packet_size;
669 		mbuf->port = sze_q->in_port;
670 		bufs[num_rx] = mbuf;
671 		num_rx++;
672 		num_bytes += packet_size;
673 	}
674 
675 finish:
676 	sze_q->rx_pkts += num_rx;
677 	sze_q->rx_bytes += num_bytes;
678 	return num_rx;
679 }
680 
681 static uint16_t
eth_szedata2_tx(void * queue,struct rte_mbuf ** bufs,uint16_t nb_pkts)682 eth_szedata2_tx(void *queue,
683 		struct rte_mbuf **bufs,
684 		uint16_t nb_pkts)
685 {
686 	struct rte_mbuf *mbuf;
687 	struct szedata2_tx_queue *sze_q = queue;
688 	uint16_t num_tx = 0;
689 	uint64_t num_bytes = 0;
690 
691 	const struct szedata_lock *lck;
692 	uint32_t lock_size;
693 	uint32_t lock_size2;
694 	void *dst;
695 	uint32_t pkt_len;
696 	uint32_t hwpkt_len;
697 	uint32_t unlock_size;
698 	uint32_t rem_len;
699 	uint16_t mbuf_segs;
700 	uint16_t pkt_left = nb_pkts;
701 
702 	if (sze_q->sze == NULL || nb_pkts == 0)
703 		return 0;
704 
705 	while (pkt_left > 0) {
706 		unlock_size = 0;
707 		lck = szedata_tx_lock_data(sze_q->sze,
708 			RTE_ETH_SZEDATA2_TX_LOCK_SIZE,
709 			sze_q->tx_channel);
710 		if (lck == NULL)
711 			continue;
712 
713 		dst = lck->start;
714 		lock_size = lck->len;
715 		lock_size2 = lck->next ? lck->next->len : 0;
716 
717 next_packet:
718 		mbuf = bufs[nb_pkts - pkt_left];
719 
720 		pkt_len = mbuf->pkt_len;
721 		mbuf_segs = mbuf->nb_segs;
722 
723 		hwpkt_len = RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED +
724 			RTE_SZE2_ALIGN8(pkt_len);
725 
726 		if (lock_size + lock_size2 < hwpkt_len) {
727 			szedata_tx_unlock_data(sze_q->sze, lck, unlock_size);
728 			continue;
729 		}
730 
731 		num_bytes += pkt_len;
732 
733 		if (lock_size > hwpkt_len) {
734 			void *tmp_dst;
735 
736 			rem_len = 0;
737 
738 			/* write packet length at first 2 bytes in 8B header */
739 			*((uint16_t *)dst) = htole16(
740 					RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED +
741 					pkt_len);
742 			*(((uint16_t *)dst) + 1) = htole16(0);
743 
744 			/* copy packet from mbuf */
745 			tmp_dst = ((uint8_t *)(dst)) +
746 				RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED;
747 			if (mbuf_segs == 1) {
748 				/*
749 				 * non-scattered packet,
750 				 * transmit from one mbuf
751 				 */
752 				rte_memcpy(tmp_dst,
753 					rte_pktmbuf_mtod(mbuf, const void *),
754 					pkt_len);
755 			} else {
756 				/* scattered packet, transmit from more mbufs */
757 				struct rte_mbuf *m = mbuf;
758 				while (m) {
759 					rte_memcpy(tmp_dst,
760 						rte_pktmbuf_mtod(m,
761 						const void *),
762 						m->data_len);
763 					tmp_dst = ((uint8_t *)(tmp_dst)) +
764 						m->data_len;
765 					m = m->next;
766 				}
767 			}
768 
769 
770 			dst = ((uint8_t *)dst) + hwpkt_len;
771 			unlock_size += hwpkt_len;
772 			lock_size -= hwpkt_len;
773 
774 			rte_pktmbuf_free(mbuf);
775 			num_tx++;
776 			pkt_left--;
777 			if (pkt_left == 0) {
778 				szedata_tx_unlock_data(sze_q->sze, lck,
779 					unlock_size);
780 				break;
781 			}
782 			goto next_packet;
783 		} else if (lock_size + lock_size2 >= hwpkt_len) {
784 			void *tmp_dst;
785 			uint16_t write_len;
786 
787 			/* write packet length at first 2 bytes in 8B header */
788 			*((uint16_t *)dst) =
789 				htole16(RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED +
790 					pkt_len);
791 			*(((uint16_t *)dst) + 1) = htole16(0);
792 
793 			/*
794 			 * If the raw packet (pkt_len) is smaller than lock_size
795 			 * get the correct length for memcpy
796 			 */
797 			write_len =
798 				pkt_len < lock_size -
799 				RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED ?
800 				pkt_len :
801 				lock_size - RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED;
802 
803 			rem_len = hwpkt_len - lock_size;
804 
805 			tmp_dst = ((uint8_t *)(dst)) +
806 				RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED;
807 			if (mbuf_segs == 1) {
808 				/*
809 				 * non-scattered packet,
810 				 * transmit from one mbuf
811 				 */
812 				/* copy part of packet to first area */
813 				rte_memcpy(tmp_dst,
814 					rte_pktmbuf_mtod(mbuf, const void *),
815 					write_len);
816 
817 				if (lck->next)
818 					dst = lck->next->start;
819 
820 				/* copy part of packet to second area */
821 				rte_memcpy(dst,
822 					(const void *)(rte_pktmbuf_mtod(mbuf,
823 							const uint8_t *) +
824 					write_len), pkt_len - write_len);
825 			} else {
826 				/* scattered packet, transmit from more mbufs */
827 				struct rte_mbuf *m = mbuf;
828 				uint16_t written = 0;
829 				uint16_t to_write = 0;
830 				bool new_mbuf = true;
831 				uint16_t write_off = 0;
832 
833 				/* copy part of packet to first area */
834 				while (m && written < write_len) {
835 					to_write = RTE_MIN(m->data_len,
836 							write_len - written);
837 					rte_memcpy(tmp_dst,
838 						rte_pktmbuf_mtod(m,
839 							const void *),
840 						to_write);
841 
842 					tmp_dst = ((uint8_t *)(tmp_dst)) +
843 						to_write;
844 					if (m->data_len <= write_len -
845 							written) {
846 						m = m->next;
847 						new_mbuf = true;
848 					} else {
849 						new_mbuf = false;
850 					}
851 					written += to_write;
852 				}
853 
854 				if (lck->next)
855 					dst = lck->next->start;
856 
857 				tmp_dst = dst;
858 				written = 0;
859 				write_off = new_mbuf ? 0 : to_write;
860 
861 				/* copy part of packet to second area */
862 				while (m && written < pkt_len - write_len) {
863 					rte_memcpy(tmp_dst, (const void *)
864 						(rte_pktmbuf_mtod(m,
865 						uint8_t *) + write_off),
866 						m->data_len - write_off);
867 
868 					tmp_dst = ((uint8_t *)(tmp_dst)) +
869 						(m->data_len - write_off);
870 					written += m->data_len - write_off;
871 					m = m->next;
872 					write_off = 0;
873 				}
874 			}
875 
876 			dst = ((uint8_t *)dst) + rem_len;
877 			unlock_size += hwpkt_len;
878 			lock_size = lock_size2 - rem_len;
879 			lock_size2 = 0;
880 
881 			rte_pktmbuf_free(mbuf);
882 			num_tx++;
883 		}
884 
885 		szedata_tx_unlock_data(sze_q->sze, lck, unlock_size);
886 		pkt_left--;
887 	}
888 
889 	sze_q->tx_pkts += num_tx;
890 	sze_q->err_pkts += nb_pkts - num_tx;
891 	sze_q->tx_bytes += num_bytes;
892 	return num_tx;
893 }
894 
895 static int
eth_rx_queue_start(struct rte_eth_dev * dev,uint16_t rxq_id)896 eth_rx_queue_start(struct rte_eth_dev *dev, uint16_t rxq_id)
897 {
898 	struct szedata2_rx_queue *rxq = dev->data->rx_queues[rxq_id];
899 	int ret;
900 	struct pmd_internals *internals = (struct pmd_internals *)
901 		dev->data->dev_private;
902 
903 	if (rxq->sze == NULL) {
904 		uint32_t rx = 1 << rxq->rx_channel;
905 		uint32_t tx = 0;
906 		rxq->sze = szedata_open(internals->sze_dev_path);
907 		if (rxq->sze == NULL)
908 			return -EINVAL;
909 		ret = szedata_subscribe3(rxq->sze, &rx, &tx);
910 		if (ret != 0 || rx == 0)
911 			goto err;
912 	}
913 
914 	ret = szedata_start(rxq->sze);
915 	if (ret != 0)
916 		goto err;
917 	dev->data->rx_queue_state[rxq_id] = RTE_ETH_QUEUE_STATE_STARTED;
918 	return 0;
919 
920 err:
921 	szedata_close(rxq->sze);
922 	rxq->sze = NULL;
923 	return -EINVAL;
924 }
925 
926 static int
eth_rx_queue_stop(struct rte_eth_dev * dev,uint16_t rxq_id)927 eth_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rxq_id)
928 {
929 	struct szedata2_rx_queue *rxq = dev->data->rx_queues[rxq_id];
930 
931 	if (rxq->sze != NULL) {
932 		szedata_close(rxq->sze);
933 		rxq->sze = NULL;
934 	}
935 
936 	dev->data->rx_queue_state[rxq_id] = RTE_ETH_QUEUE_STATE_STOPPED;
937 	return 0;
938 }
939 
940 static int
eth_tx_queue_start(struct rte_eth_dev * dev,uint16_t txq_id)941 eth_tx_queue_start(struct rte_eth_dev *dev, uint16_t txq_id)
942 {
943 	struct szedata2_tx_queue *txq = dev->data->tx_queues[txq_id];
944 	int ret;
945 	struct pmd_internals *internals = (struct pmd_internals *)
946 		dev->data->dev_private;
947 
948 	if (txq->sze == NULL) {
949 		uint32_t rx = 0;
950 		uint32_t tx = 1 << txq->tx_channel;
951 		txq->sze = szedata_open(internals->sze_dev_path);
952 		if (txq->sze == NULL)
953 			return -EINVAL;
954 		ret = szedata_subscribe3(txq->sze, &rx, &tx);
955 		if (ret != 0 || tx == 0)
956 			goto err;
957 	}
958 
959 	ret = szedata_start(txq->sze);
960 	if (ret != 0)
961 		goto err;
962 	dev->data->tx_queue_state[txq_id] = RTE_ETH_QUEUE_STATE_STARTED;
963 	return 0;
964 
965 err:
966 	szedata_close(txq->sze);
967 	txq->sze = NULL;
968 	return -EINVAL;
969 }
970 
971 static int
eth_tx_queue_stop(struct rte_eth_dev * dev,uint16_t txq_id)972 eth_tx_queue_stop(struct rte_eth_dev *dev, uint16_t txq_id)
973 {
974 	struct szedata2_tx_queue *txq = dev->data->tx_queues[txq_id];
975 
976 	if (txq->sze != NULL) {
977 		szedata_close(txq->sze);
978 		txq->sze = NULL;
979 	}
980 
981 	dev->data->tx_queue_state[txq_id] = RTE_ETH_QUEUE_STATE_STOPPED;
982 	return 0;
983 }
984 
985 static int
eth_dev_start(struct rte_eth_dev * dev)986 eth_dev_start(struct rte_eth_dev *dev)
987 {
988 	int ret;
989 	uint16_t i;
990 	uint16_t nb_rx = dev->data->nb_rx_queues;
991 	uint16_t nb_tx = dev->data->nb_tx_queues;
992 
993 	for (i = 0; i < nb_rx; i++) {
994 		ret = eth_rx_queue_start(dev, i);
995 		if (ret != 0)
996 			goto err_rx;
997 	}
998 
999 	for (i = 0; i < nb_tx; i++) {
1000 		ret = eth_tx_queue_start(dev, i);
1001 		if (ret != 0)
1002 			goto err_tx;
1003 	}
1004 
1005 	return 0;
1006 
1007 err_tx:
1008 	for (i = 0; i < nb_tx; i++)
1009 		eth_tx_queue_stop(dev, i);
1010 err_rx:
1011 	for (i = 0; i < nb_rx; i++)
1012 		eth_rx_queue_stop(dev, i);
1013 	return ret;
1014 }
1015 
1016 static int
eth_dev_stop(struct rte_eth_dev * dev)1017 eth_dev_stop(struct rte_eth_dev *dev)
1018 {
1019 	uint16_t i;
1020 	uint16_t nb_rx = dev->data->nb_rx_queues;
1021 	uint16_t nb_tx = dev->data->nb_tx_queues;
1022 	int ret;
1023 
1024 	dev->data->dev_started = 0;
1025 
1026 	for (i = 0; i < nb_tx; i++) {
1027 		ret = eth_tx_queue_stop(dev, i);
1028 		if (ret != 0)
1029 			return ret;
1030 	}
1031 
1032 	for (i = 0; i < nb_rx; i++) {
1033 		ret = eth_rx_queue_stop(dev, i);
1034 		if (ret != 0)
1035 			return ret;
1036 	}
1037 
1038 	return 0;
1039 }
1040 
1041 static int
eth_dev_configure(struct rte_eth_dev * dev)1042 eth_dev_configure(struct rte_eth_dev *dev)
1043 {
1044 	struct rte_eth_dev_data *data = dev->data;
1045 	if (data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_SCATTER) {
1046 		dev->rx_pkt_burst = eth_szedata2_rx_scattered;
1047 		data->scattered_rx = 1;
1048 	} else {
1049 		dev->rx_pkt_burst = eth_szedata2_rx;
1050 		data->scattered_rx = 0;
1051 	}
1052 	return 0;
1053 }
1054 
1055 static int
eth_dev_info(struct rte_eth_dev * dev,struct rte_eth_dev_info * dev_info)1056 eth_dev_info(struct rte_eth_dev *dev,
1057 		struct rte_eth_dev_info *dev_info)
1058 {
1059 	struct pmd_internals *internals = dev->data->dev_private;
1060 
1061 	dev_info->if_index = 0;
1062 	dev_info->max_mac_addrs = 1;
1063 	dev_info->max_rx_pktlen = (uint32_t)-1;
1064 	dev_info->max_rx_queues = internals->max_rx_queues;
1065 	dev_info->max_tx_queues = internals->max_tx_queues;
1066 	dev_info->min_rx_bufsize = 0;
1067 	dev_info->rx_offload_capa = DEV_RX_OFFLOAD_SCATTER;
1068 	dev_info->tx_offload_capa = 0;
1069 	dev_info->rx_queue_offload_capa = 0;
1070 	dev_info->tx_queue_offload_capa = 0;
1071 	dev_info->speed_capa = ETH_LINK_SPEED_100G;
1072 
1073 	return 0;
1074 }
1075 
1076 static int
eth_stats_get(struct rte_eth_dev * dev,struct rte_eth_stats * stats)1077 eth_stats_get(struct rte_eth_dev *dev,
1078 		struct rte_eth_stats *stats)
1079 {
1080 	uint16_t i;
1081 	uint16_t nb_rx = dev->data->nb_rx_queues;
1082 	uint16_t nb_tx = dev->data->nb_tx_queues;
1083 	uint64_t rx_total = 0;
1084 	uint64_t tx_total = 0;
1085 	uint64_t tx_err_total = 0;
1086 	uint64_t rx_total_bytes = 0;
1087 	uint64_t tx_total_bytes = 0;
1088 
1089 	for (i = 0; i < nb_rx; i++) {
1090 		struct szedata2_rx_queue *rxq = dev->data->rx_queues[i];
1091 
1092 		if (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
1093 			stats->q_ipackets[i] = rxq->rx_pkts;
1094 			stats->q_ibytes[i] = rxq->rx_bytes;
1095 		}
1096 		rx_total += rxq->rx_pkts;
1097 		rx_total_bytes += rxq->rx_bytes;
1098 	}
1099 
1100 	for (i = 0; i < nb_tx; i++) {
1101 		struct szedata2_tx_queue *txq = dev->data->tx_queues[i];
1102 
1103 		if (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
1104 			stats->q_opackets[i] = txq->tx_pkts;
1105 			stats->q_obytes[i] = txq->tx_bytes;
1106 		}
1107 		tx_total += txq->tx_pkts;
1108 		tx_total_bytes += txq->tx_bytes;
1109 		tx_err_total += txq->err_pkts;
1110 	}
1111 
1112 	stats->ipackets = rx_total;
1113 	stats->opackets = tx_total;
1114 	stats->ibytes = rx_total_bytes;
1115 	stats->obytes = tx_total_bytes;
1116 	stats->oerrors = tx_err_total;
1117 	stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed;
1118 
1119 	return 0;
1120 }
1121 
1122 static int
eth_stats_reset(struct rte_eth_dev * dev)1123 eth_stats_reset(struct rte_eth_dev *dev)
1124 {
1125 	uint16_t i;
1126 	uint16_t nb_rx = dev->data->nb_rx_queues;
1127 	uint16_t nb_tx = dev->data->nb_tx_queues;
1128 
1129 	for (i = 0; i < nb_rx; i++) {
1130 		struct szedata2_rx_queue *rxq = dev->data->rx_queues[i];
1131 		rxq->rx_pkts = 0;
1132 		rxq->rx_bytes = 0;
1133 		rxq->err_pkts = 0;
1134 	}
1135 	for (i = 0; i < nb_tx; i++) {
1136 		struct szedata2_tx_queue *txq = dev->data->tx_queues[i];
1137 		txq->tx_pkts = 0;
1138 		txq->tx_bytes = 0;
1139 		txq->err_pkts = 0;
1140 	}
1141 
1142 	return 0;
1143 }
1144 
1145 static void
eth_rx_queue_release(void * q)1146 eth_rx_queue_release(void *q)
1147 {
1148 	struct szedata2_rx_queue *rxq = (struct szedata2_rx_queue *)q;
1149 
1150 	if (rxq != NULL) {
1151 		if (rxq->sze != NULL)
1152 			szedata_close(rxq->sze);
1153 		rte_free(rxq);
1154 	}
1155 }
1156 
1157 static void
eth_tx_queue_release(void * q)1158 eth_tx_queue_release(void *q)
1159 {
1160 	struct szedata2_tx_queue *txq = (struct szedata2_tx_queue *)q;
1161 
1162 	if (txq != NULL) {
1163 		if (txq->sze != NULL)
1164 			szedata_close(txq->sze);
1165 		rte_free(txq);
1166 	}
1167 }
1168 
1169 static int
eth_dev_close(struct rte_eth_dev * dev)1170 eth_dev_close(struct rte_eth_dev *dev)
1171 {
1172 	struct pmd_internals *internals = dev->data->dev_private;
1173 	uint16_t i;
1174 	uint16_t nb_rx = dev->data->nb_rx_queues;
1175 	uint16_t nb_tx = dev->data->nb_tx_queues;
1176 	int ret;
1177 
1178 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1179 		return 0;
1180 
1181 	ret = eth_dev_stop(dev);
1182 
1183 	free(internals->sze_dev_path);
1184 
1185 	for (i = 0; i < nb_rx; i++) {
1186 		eth_rx_queue_release(dev->data->rx_queues[i]);
1187 		dev->data->rx_queues[i] = NULL;
1188 	}
1189 	dev->data->nb_rx_queues = 0;
1190 	for (i = 0; i < nb_tx; i++) {
1191 		eth_tx_queue_release(dev->data->tx_queues[i]);
1192 		dev->data->tx_queues[i] = NULL;
1193 	}
1194 	dev->data->nb_tx_queues = 0;
1195 
1196 	return ret;
1197 }
1198 
1199 static int
eth_link_update(struct rte_eth_dev * dev,int wait_to_complete __rte_unused)1200 eth_link_update(struct rte_eth_dev *dev,
1201 		int wait_to_complete __rte_unused)
1202 {
1203 	struct rte_eth_link link;
1204 
1205 	memset(&link, 0, sizeof(link));
1206 
1207 	link.link_speed = ETH_SPEED_NUM_100G;
1208 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
1209 	link.link_status = ETH_LINK_UP;
1210 	link.link_autoneg = ETH_LINK_FIXED;
1211 
1212 	rte_eth_linkstatus_set(dev, &link);
1213 	return 0;
1214 }
1215 
1216 static int
eth_dev_set_link_up(struct rte_eth_dev * dev __rte_unused)1217 eth_dev_set_link_up(struct rte_eth_dev *dev __rte_unused)
1218 {
1219 	PMD_DRV_LOG(WARNING, "Setting link up is not supported.");
1220 	return 0;
1221 }
1222 
1223 static int
eth_dev_set_link_down(struct rte_eth_dev * dev __rte_unused)1224 eth_dev_set_link_down(struct rte_eth_dev *dev __rte_unused)
1225 {
1226 	PMD_DRV_LOG(WARNING, "Setting link down is not supported.");
1227 	return 0;
1228 }
1229 
1230 static int
eth_rx_queue_setup(struct rte_eth_dev * dev,uint16_t rx_queue_id,uint16_t nb_rx_desc __rte_unused,unsigned int socket_id,const struct rte_eth_rxconf * rx_conf __rte_unused,struct rte_mempool * mb_pool)1231 eth_rx_queue_setup(struct rte_eth_dev *dev,
1232 		uint16_t rx_queue_id,
1233 		uint16_t nb_rx_desc __rte_unused,
1234 		unsigned int socket_id,
1235 		const struct rte_eth_rxconf *rx_conf __rte_unused,
1236 		struct rte_mempool *mb_pool)
1237 {
1238 	struct szedata2_rx_queue *rxq;
1239 	int ret;
1240 	struct pmd_internals *internals = dev->data->dev_private;
1241 	uint8_t rx_channel = internals->rxq_base_id + rx_queue_id;
1242 	uint32_t rx = 1 << rx_channel;
1243 	uint32_t tx = 0;
1244 
1245 	PMD_INIT_FUNC_TRACE();
1246 
1247 	if (dev->data->rx_queues[rx_queue_id] != NULL) {
1248 		eth_rx_queue_release(dev->data->rx_queues[rx_queue_id]);
1249 		dev->data->rx_queues[rx_queue_id] = NULL;
1250 	}
1251 
1252 	rxq = rte_zmalloc_socket("szedata2 rx queue",
1253 			sizeof(struct szedata2_rx_queue),
1254 			RTE_CACHE_LINE_SIZE, socket_id);
1255 	if (rxq == NULL) {
1256 		PMD_INIT_LOG(ERR, "rte_zmalloc_socket() failed for rx queue id "
1257 				"%" PRIu16 "!", rx_queue_id);
1258 		return -ENOMEM;
1259 	}
1260 
1261 	rxq->priv = internals;
1262 	rxq->sze = szedata_open(internals->sze_dev_path);
1263 	if (rxq->sze == NULL) {
1264 		PMD_INIT_LOG(ERR, "szedata_open() failed for rx queue id "
1265 				"%" PRIu16 "!", rx_queue_id);
1266 		eth_rx_queue_release(rxq);
1267 		return -EINVAL;
1268 	}
1269 	ret = szedata_subscribe3(rxq->sze, &rx, &tx);
1270 	if (ret != 0 || rx == 0) {
1271 		PMD_INIT_LOG(ERR, "szedata_subscribe3() failed for rx queue id "
1272 				"%" PRIu16 "!", rx_queue_id);
1273 		eth_rx_queue_release(rxq);
1274 		return -EINVAL;
1275 	}
1276 	rxq->rx_channel = rx_channel;
1277 	rxq->qid = rx_queue_id;
1278 	rxq->in_port = dev->data->port_id;
1279 	rxq->mb_pool = mb_pool;
1280 	rxq->rx_pkts = 0;
1281 	rxq->rx_bytes = 0;
1282 	rxq->err_pkts = 0;
1283 
1284 	dev->data->rx_queues[rx_queue_id] = rxq;
1285 
1286 	PMD_INIT_LOG(DEBUG, "Configured rx queue id %" PRIu16 " on socket "
1287 			"%u (channel id %u).", rxq->qid, socket_id,
1288 			rxq->rx_channel);
1289 
1290 	return 0;
1291 }
1292 
1293 static int
eth_tx_queue_setup(struct rte_eth_dev * dev,uint16_t tx_queue_id,uint16_t nb_tx_desc __rte_unused,unsigned int socket_id,const struct rte_eth_txconf * tx_conf __rte_unused)1294 eth_tx_queue_setup(struct rte_eth_dev *dev,
1295 		uint16_t tx_queue_id,
1296 		uint16_t nb_tx_desc __rte_unused,
1297 		unsigned int socket_id,
1298 		const struct rte_eth_txconf *tx_conf __rte_unused)
1299 {
1300 	struct szedata2_tx_queue *txq;
1301 	int ret;
1302 	struct pmd_internals *internals = dev->data->dev_private;
1303 	uint8_t tx_channel = internals->txq_base_id + tx_queue_id;
1304 	uint32_t rx = 0;
1305 	uint32_t tx = 1 << tx_channel;
1306 
1307 	PMD_INIT_FUNC_TRACE();
1308 
1309 	if (dev->data->tx_queues[tx_queue_id] != NULL) {
1310 		eth_tx_queue_release(dev->data->tx_queues[tx_queue_id]);
1311 		dev->data->tx_queues[tx_queue_id] = NULL;
1312 	}
1313 
1314 	txq = rte_zmalloc_socket("szedata2 tx queue",
1315 			sizeof(struct szedata2_tx_queue),
1316 			RTE_CACHE_LINE_SIZE, socket_id);
1317 	if (txq == NULL) {
1318 		PMD_INIT_LOG(ERR, "rte_zmalloc_socket() failed for tx queue id "
1319 				"%" PRIu16 "!", tx_queue_id);
1320 		return -ENOMEM;
1321 	}
1322 
1323 	txq->priv = internals;
1324 	txq->sze = szedata_open(internals->sze_dev_path);
1325 	if (txq->sze == NULL) {
1326 		PMD_INIT_LOG(ERR, "szedata_open() failed for tx queue id "
1327 				"%" PRIu16 "!", tx_queue_id);
1328 		eth_tx_queue_release(txq);
1329 		return -EINVAL;
1330 	}
1331 	ret = szedata_subscribe3(txq->sze, &rx, &tx);
1332 	if (ret != 0 || tx == 0) {
1333 		PMD_INIT_LOG(ERR, "szedata_subscribe3() failed for tx queue id "
1334 				"%" PRIu16 "!", tx_queue_id);
1335 		eth_tx_queue_release(txq);
1336 		return -EINVAL;
1337 	}
1338 	txq->tx_channel = tx_channel;
1339 	txq->qid = tx_queue_id;
1340 	txq->tx_pkts = 0;
1341 	txq->tx_bytes = 0;
1342 	txq->err_pkts = 0;
1343 
1344 	dev->data->tx_queues[tx_queue_id] = txq;
1345 
1346 	PMD_INIT_LOG(DEBUG, "Configured tx queue id %" PRIu16 " on socket "
1347 			"%u (channel id %u).", txq->qid, socket_id,
1348 			txq->tx_channel);
1349 
1350 	return 0;
1351 }
1352 
1353 static int
eth_mac_addr_set(struct rte_eth_dev * dev __rte_unused,struct rte_ether_addr * mac_addr __rte_unused)1354 eth_mac_addr_set(struct rte_eth_dev *dev __rte_unused,
1355 		struct rte_ether_addr *mac_addr __rte_unused)
1356 {
1357 	return 0;
1358 }
1359 
1360 static int
eth_promiscuous_enable(struct rte_eth_dev * dev __rte_unused)1361 eth_promiscuous_enable(struct rte_eth_dev *dev __rte_unused)
1362 {
1363 	PMD_DRV_LOG(WARNING, "Enabling promiscuous mode is not supported. "
1364 			"The card is always in promiscuous mode.");
1365 	return 0;
1366 }
1367 
1368 static int
eth_promiscuous_disable(struct rte_eth_dev * dev __rte_unused)1369 eth_promiscuous_disable(struct rte_eth_dev *dev __rte_unused)
1370 {
1371 	PMD_DRV_LOG(WARNING, "Disabling promiscuous mode is not supported. "
1372 			"The card is always in promiscuous mode.");
1373 	return -ENOTSUP;
1374 }
1375 
1376 static int
eth_allmulticast_enable(struct rte_eth_dev * dev __rte_unused)1377 eth_allmulticast_enable(struct rte_eth_dev *dev __rte_unused)
1378 {
1379 	PMD_DRV_LOG(WARNING, "Enabling allmulticast mode is not supported.");
1380 	return -ENOTSUP;
1381 }
1382 
1383 static int
eth_allmulticast_disable(struct rte_eth_dev * dev __rte_unused)1384 eth_allmulticast_disable(struct rte_eth_dev *dev __rte_unused)
1385 {
1386 	PMD_DRV_LOG(WARNING, "Disabling allmulticast mode is not supported.");
1387 	return -ENOTSUP;
1388 }
1389 
1390 static const struct eth_dev_ops ops = {
1391 	.dev_start          = eth_dev_start,
1392 	.dev_stop           = eth_dev_stop,
1393 	.dev_set_link_up    = eth_dev_set_link_up,
1394 	.dev_set_link_down  = eth_dev_set_link_down,
1395 	.dev_close          = eth_dev_close,
1396 	.dev_configure      = eth_dev_configure,
1397 	.dev_infos_get      = eth_dev_info,
1398 	.promiscuous_enable   = eth_promiscuous_enable,
1399 	.promiscuous_disable  = eth_promiscuous_disable,
1400 	.allmulticast_enable  = eth_allmulticast_enable,
1401 	.allmulticast_disable = eth_allmulticast_disable,
1402 	.rx_queue_start     = eth_rx_queue_start,
1403 	.rx_queue_stop      = eth_rx_queue_stop,
1404 	.tx_queue_start     = eth_tx_queue_start,
1405 	.tx_queue_stop      = eth_tx_queue_stop,
1406 	.rx_queue_setup     = eth_rx_queue_setup,
1407 	.tx_queue_setup     = eth_tx_queue_setup,
1408 	.rx_queue_release   = eth_rx_queue_release,
1409 	.tx_queue_release   = eth_tx_queue_release,
1410 	.link_update        = eth_link_update,
1411 	.stats_get          = eth_stats_get,
1412 	.stats_reset        = eth_stats_reset,
1413 	.mac_addr_set       = eth_mac_addr_set,
1414 };
1415 
1416 /*
1417  * This function goes through sysfs and looks for an index of szedata2
1418  * device file (/dev/szedataIIX, where X is the index).
1419  *
1420  * @return
1421  *           0 on success
1422  *          -1 on error
1423  */
1424 static int
get_szedata2_index(const struct rte_pci_addr * pcislot_addr,uint32_t * index)1425 get_szedata2_index(const struct rte_pci_addr *pcislot_addr, uint32_t *index)
1426 {
1427 	DIR *dir;
1428 	struct dirent *entry;
1429 	int ret;
1430 	uint32_t tmp_index;
1431 	FILE *fd;
1432 	char pcislot_path[PATH_MAX];
1433 	uint32_t domain;
1434 	uint8_t bus;
1435 	uint8_t devid;
1436 	uint8_t function;
1437 
1438 	dir = opendir("/sys/class/combo");
1439 	if (dir == NULL)
1440 		return -1;
1441 
1442 	/*
1443 	 * Iterate through all combosixX directories.
1444 	 * When the value in /sys/class/combo/combosixX/device/pcislot
1445 	 * file is the location of the ethernet device dev, "X" is the
1446 	 * index of the device.
1447 	 */
1448 	while ((entry = readdir(dir)) != NULL) {
1449 		ret = sscanf(entry->d_name, "combosix%u", &tmp_index);
1450 		if (ret != 1)
1451 			continue;
1452 
1453 		snprintf(pcislot_path, PATH_MAX,
1454 			"/sys/class/combo/combosix%u/device/pcislot",
1455 			tmp_index);
1456 
1457 		fd = fopen(pcislot_path, "r");
1458 		if (fd == NULL)
1459 			continue;
1460 
1461 		ret = fscanf(fd, "%8" SCNx32 ":%2" SCNx8 ":%2" SCNx8 ".%" SCNx8,
1462 				&domain, &bus, &devid, &function);
1463 		fclose(fd);
1464 		if (ret != 4)
1465 			continue;
1466 
1467 		if (pcislot_addr->domain == domain &&
1468 				pcislot_addr->bus == bus &&
1469 				pcislot_addr->devid == devid &&
1470 				pcislot_addr->function == function) {
1471 			*index = tmp_index;
1472 			closedir(dir);
1473 			return 0;
1474 		}
1475 	}
1476 
1477 	closedir(dir);
1478 	return -1;
1479 }
1480 
1481 /**
1482  * @brief Initializes rte_eth_dev device.
1483  * @param dev Device to initialize.
1484  * @param pi Structure with info about DMA queues.
1485  * @return 0 on success, negative error code on error.
1486  */
1487 static int
rte_szedata2_eth_dev_init(struct rte_eth_dev * dev,struct port_info * pi)1488 rte_szedata2_eth_dev_init(struct rte_eth_dev *dev, struct port_info *pi)
1489 {
1490 	int ret;
1491 	uint32_t szedata2_index;
1492 	char name[PATH_MAX];
1493 	struct rte_eth_dev_data *data = dev->data;
1494 	struct pmd_internals *internals = (struct pmd_internals *)
1495 		data->dev_private;
1496 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1497 
1498 	PMD_INIT_FUNC_TRACE();
1499 
1500 	PMD_INIT_LOG(INFO, "Initializing eth_dev %s (driver %s)", data->name,
1501 			RTE_STR(RTE_SZEDATA2_DRIVER_NAME));
1502 
1503 	/* Fill internal private structure. */
1504 	internals->dev = dev;
1505 	/* Get index of szedata2 device file and create path to device file */
1506 	ret = get_szedata2_index(&pci_dev->addr, &szedata2_index);
1507 	if (ret != 0) {
1508 		PMD_INIT_LOG(ERR, "Failed to get szedata2 device index!");
1509 		return -ENODEV;
1510 	}
1511 	snprintf(name, PATH_MAX, SZEDATA2_DEV_PATH_FMT, szedata2_index);
1512 	internals->sze_dev_path = strdup(name);
1513 	if (internals->sze_dev_path == NULL) {
1514 		PMD_INIT_LOG(ERR, "strdup() failed!");
1515 		return -ENOMEM;
1516 	}
1517 	PMD_INIT_LOG(INFO, "SZEDATA2 path: %s", internals->sze_dev_path);
1518 	internals->max_rx_queues = pi->rx_count;
1519 	internals->max_tx_queues = pi->tx_count;
1520 	internals->rxq_base_id = pi->rx_base_id;
1521 	internals->txq_base_id = pi->tx_base_id;
1522 	PMD_INIT_LOG(INFO, "%u RX DMA channels from id %u",
1523 			internals->max_rx_queues, internals->rxq_base_id);
1524 	PMD_INIT_LOG(INFO, "%u TX DMA channels from id %u",
1525 			internals->max_tx_queues, internals->txq_base_id);
1526 
1527 	/* Set rx, tx burst functions */
1528 	if (data->scattered_rx == 1)
1529 		dev->rx_pkt_burst = eth_szedata2_rx_scattered;
1530 	else
1531 		dev->rx_pkt_burst = eth_szedata2_rx;
1532 	dev->tx_pkt_burst = eth_szedata2_tx;
1533 
1534 	/* Set function callbacks for Ethernet API */
1535 	dev->dev_ops = &ops;
1536 
1537 	/* Get link state */
1538 	eth_link_update(dev, 0);
1539 
1540 	/* Allocate space for one mac address */
1541 	data->mac_addrs = rte_zmalloc(data->name, sizeof(struct rte_ether_addr),
1542 			RTE_CACHE_LINE_SIZE);
1543 	if (data->mac_addrs == NULL) {
1544 		PMD_INIT_LOG(ERR, "Could not alloc space for MAC address!");
1545 		free(internals->sze_dev_path);
1546 		return -ENOMEM;
1547 	}
1548 
1549 	rte_ether_addr_copy(&eth_addr, data->mac_addrs);
1550 
1551 	dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
1552 
1553 	PMD_INIT_LOG(INFO, "%s device %s successfully initialized",
1554 			RTE_STR(RTE_SZEDATA2_DRIVER_NAME), data->name);
1555 
1556 	return 0;
1557 }
1558 
1559 /**
1560  * @brief Unitializes rte_eth_dev device.
1561  * @param dev Device to uninitialize.
1562  * @return 0 on success, negative error code on error.
1563  */
1564 static int
rte_szedata2_eth_dev_uninit(struct rte_eth_dev * dev)1565 rte_szedata2_eth_dev_uninit(struct rte_eth_dev *dev)
1566 {
1567 	PMD_INIT_FUNC_TRACE();
1568 
1569 	eth_dev_close(dev);
1570 
1571 	PMD_DRV_LOG(INFO, "%s device %s successfully uninitialized",
1572 			RTE_STR(RTE_SZEDATA2_DRIVER_NAME), dev->data->name);
1573 
1574 	return 0;
1575 }
1576 
1577 static const struct rte_pci_id rte_szedata2_pci_id_table[] = {
1578 	{
1579 		RTE_PCI_DEVICE(PCI_VENDOR_ID_NETCOPE,
1580 				PCI_DEVICE_ID_NETCOPE_COMBO80G)
1581 	},
1582 	{
1583 		RTE_PCI_DEVICE(PCI_VENDOR_ID_NETCOPE,
1584 				PCI_DEVICE_ID_NETCOPE_COMBO100G)
1585 	},
1586 	{
1587 		RTE_PCI_DEVICE(PCI_VENDOR_ID_NETCOPE,
1588 				PCI_DEVICE_ID_NETCOPE_COMBO100G2)
1589 	},
1590 	{
1591 		RTE_PCI_DEVICE(PCI_VENDOR_ID_NETCOPE,
1592 				PCI_DEVICE_ID_NETCOPE_NFB200G2QL)
1593 	},
1594 	{
1595 		RTE_PCI_DEVICE(PCI_VENDOR_ID_SILICOM,
1596 				PCI_DEVICE_ID_FB2CGG3)
1597 	},
1598 	{
1599 		RTE_PCI_DEVICE(PCI_VENDOR_ID_SILICOM,
1600 				PCI_DEVICE_ID_FB2CGG3D)
1601 	},
1602 	{
1603 		.vendor_id = 0,
1604 	}
1605 };
1606 
1607 /**
1608  * @brief Gets info about DMA queues for ports.
1609  * @param pci_dev PCI device structure.
1610  * @param port_count Pointer to variable set with number of ports.
1611  * @param pi Pointer to array of structures with info about DMA queues
1612  *           for ports.
1613  * @param max_ports Maximum number of ports.
1614  * @return 0 on success, negative error code on error.
1615  */
1616 static int
get_port_info(struct rte_pci_device * pci_dev,unsigned int * port_count,struct port_info * pi,unsigned int max_ports)1617 get_port_info(struct rte_pci_device *pci_dev, unsigned int *port_count,
1618 		struct port_info *pi, unsigned int max_ports)
1619 {
1620 	struct szedata *szedata_temp;
1621 	char sze_dev_path[PATH_MAX];
1622 	uint32_t szedata2_index;
1623 	int ret;
1624 	uint16_t max_rx_queues;
1625 	uint16_t max_tx_queues;
1626 
1627 	if (max_ports == 0)
1628 		return -EINVAL;
1629 
1630 	memset(pi, 0, max_ports * sizeof(struct port_info));
1631 	*port_count = 0;
1632 
1633 	/* Get index of szedata2 device file and create path to device file */
1634 	ret = get_szedata2_index(&pci_dev->addr, &szedata2_index);
1635 	if (ret != 0) {
1636 		PMD_INIT_LOG(ERR, "Failed to get szedata2 device index!");
1637 		return -ENODEV;
1638 	}
1639 	snprintf(sze_dev_path, PATH_MAX, SZEDATA2_DEV_PATH_FMT, szedata2_index);
1640 
1641 	/*
1642 	 * Get number of available DMA RX and TX channels, which is maximum
1643 	 * number of queues that can be created.
1644 	 */
1645 	szedata_temp = szedata_open(sze_dev_path);
1646 	if (szedata_temp == NULL) {
1647 		PMD_INIT_LOG(ERR, "szedata_open(%s) failed", sze_dev_path);
1648 		return -EINVAL;
1649 	}
1650 	max_rx_queues = szedata_ifaces_available(szedata_temp, SZE2_DIR_RX);
1651 	max_tx_queues = szedata_ifaces_available(szedata_temp, SZE2_DIR_TX);
1652 	PMD_INIT_LOG(INFO, "Available DMA channels RX: %u TX: %u",
1653 			max_rx_queues, max_tx_queues);
1654 	if (max_rx_queues > RTE_ETH_SZEDATA2_MAX_RX_QUEUES) {
1655 		PMD_INIT_LOG(ERR, "%u RX queues exceeds supported number %u",
1656 				max_rx_queues, RTE_ETH_SZEDATA2_MAX_RX_QUEUES);
1657 		szedata_close(szedata_temp);
1658 		return -EINVAL;
1659 	}
1660 	if (max_tx_queues > RTE_ETH_SZEDATA2_MAX_TX_QUEUES) {
1661 		PMD_INIT_LOG(ERR, "%u TX queues exceeds supported number %u",
1662 				max_tx_queues, RTE_ETH_SZEDATA2_MAX_TX_QUEUES);
1663 		szedata_close(szedata_temp);
1664 		return -EINVAL;
1665 	}
1666 
1667 	if (pci_dev->id.device_id == PCI_DEVICE_ID_NETCOPE_NFB200G2QL) {
1668 		unsigned int i;
1669 		unsigned int rx_queues = max_rx_queues / max_ports;
1670 		unsigned int tx_queues = max_tx_queues / max_ports;
1671 
1672 		/*
1673 		 * Number of queues reported by szedata_ifaces_available()
1674 		 * is the number of all queues from all DMA controllers which
1675 		 * may reside at different numa locations.
1676 		 * All queues from the same DMA controller have the same numa
1677 		 * node.
1678 		 * Numa node from the first queue of each DMA controller is
1679 		 * retrieved.
1680 		 * If the numa node differs from the numa node of the queues
1681 		 * from the previous DMA controller the queues are assigned
1682 		 * to the next port.
1683 		 */
1684 
1685 		for (i = 0; i < max_ports; i++) {
1686 			int numa_rx = szedata_get_area_numa_node(szedata_temp,
1687 				SZE2_DIR_RX, rx_queues * i);
1688 			int numa_tx = szedata_get_area_numa_node(szedata_temp,
1689 				SZE2_DIR_TX, tx_queues * i);
1690 			unsigned int port_rx_queues = numa_rx != -1 ?
1691 				rx_queues : 0;
1692 			unsigned int port_tx_queues = numa_tx != -1 ?
1693 				tx_queues : 0;
1694 			PMD_INIT_LOG(DEBUG, "%u rx queues from id %u, numa %d",
1695 					rx_queues, rx_queues * i, numa_rx);
1696 			PMD_INIT_LOG(DEBUG, "%u tx queues from id %u, numa %d",
1697 					tx_queues, tx_queues * i, numa_tx);
1698 
1699 			if (port_rx_queues != 0 && port_tx_queues != 0 &&
1700 					numa_rx != numa_tx) {
1701 				PMD_INIT_LOG(ERR, "RX queue %u numa %d differs "
1702 						"from TX queue %u numa %d "
1703 						"unexpectedly",
1704 						rx_queues * i, numa_rx,
1705 						tx_queues * i, numa_tx);
1706 				szedata_close(szedata_temp);
1707 				return -EINVAL;
1708 			} else if (port_rx_queues == 0 && port_tx_queues == 0) {
1709 				continue;
1710 			} else {
1711 				unsigned int j;
1712 				unsigned int current = *port_count;
1713 				int port_numa = port_rx_queues != 0 ?
1714 					numa_rx : numa_tx;
1715 
1716 				for (j = 0; j < *port_count; j++) {
1717 					if (pi[j].numa_node ==
1718 							port_numa) {
1719 						current = j;
1720 						break;
1721 					}
1722 				}
1723 				if (pi[current].rx_count == 0 &&
1724 						pi[current].tx_count == 0) {
1725 					pi[current].rx_base_id = rx_queues * i;
1726 					pi[current].tx_base_id = tx_queues * i;
1727 					(*port_count)++;
1728 				} else if ((rx_queues * i !=
1729 						pi[current].rx_base_id +
1730 						pi[current].rx_count) ||
1731 						(tx_queues * i !=
1732 						 pi[current].tx_base_id +
1733 						 pi[current].tx_count)) {
1734 					PMD_INIT_LOG(ERR, "Queue ids does not "
1735 							"fulfill constraints");
1736 					szedata_close(szedata_temp);
1737 					return -EINVAL;
1738 				}
1739 				pi[current].rx_count += port_rx_queues;
1740 				pi[current].tx_count += port_tx_queues;
1741 				pi[current].numa_node = port_numa;
1742 			}
1743 		}
1744 	} else {
1745 		pi[0].rx_count = max_rx_queues;
1746 		pi[0].tx_count = max_tx_queues;
1747 		pi[0].numa_node = pci_dev->device.numa_node;
1748 		*port_count = 1;
1749 	}
1750 
1751 	szedata_close(szedata_temp);
1752 	return 0;
1753 }
1754 
1755 /**
1756  * @brief Allocates rte_eth_dev device.
1757  * @param pci_dev Corresponding PCI device.
1758  * @param numa_node NUMA node on which device is allocated.
1759  * @param port_no Id of rte_eth_device created on PCI device pci_dev.
1760  * @return Pointer to allocated device or NULL on error.
1761  */
1762 static struct rte_eth_dev *
szedata2_eth_dev_allocate(struct rte_pci_device * pci_dev,int numa_node,unsigned int port_no)1763 szedata2_eth_dev_allocate(struct rte_pci_device *pci_dev, int numa_node,
1764 		unsigned int port_no)
1765 {
1766 	struct rte_eth_dev *eth_dev;
1767 	char name[RTE_ETH_NAME_MAX_LEN];
1768 
1769 	PMD_INIT_FUNC_TRACE();
1770 
1771 	snprintf(name, RTE_ETH_NAME_MAX_LEN, "%s"
1772 			SZEDATA2_ETH_DEV_NAME_SUFFIX_FMT,
1773 			pci_dev->device.name, port_no);
1774 	PMD_INIT_LOG(DEBUG, "Allocating eth_dev %s", name);
1775 
1776 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
1777 		eth_dev = rte_eth_dev_allocate(name);
1778 		if (!eth_dev)
1779 			return NULL;
1780 
1781 		eth_dev->data->dev_private = rte_zmalloc_socket(name,
1782 			sizeof(struct pmd_internals), RTE_CACHE_LINE_SIZE,
1783 			numa_node);
1784 		if (!eth_dev->data->dev_private) {
1785 			rte_eth_dev_release_port(eth_dev);
1786 			return NULL;
1787 		}
1788 	} else {
1789 		eth_dev = rte_eth_dev_attach_secondary(name);
1790 		if (!eth_dev)
1791 			return NULL;
1792 	}
1793 
1794 	eth_dev->device = &pci_dev->device;
1795 	rte_eth_copy_pci_info(eth_dev, pci_dev);
1796 	eth_dev->data->numa_node = numa_node;
1797 	return eth_dev;
1798 }
1799 
1800 /**
1801  * @brief Releases interval of rte_eth_dev devices from array.
1802  * @param eth_devs Array of pointers to rte_eth_dev devices.
1803  * @param from Index in array eth_devs to start with.
1804  * @param to Index in array right after the last element to release.
1805  *
1806  * Used for releasing at failed initialization.
1807  */
1808 static void
szedata2_eth_dev_release_interval(struct rte_eth_dev ** eth_devs,unsigned int from,unsigned int to)1809 szedata2_eth_dev_release_interval(struct rte_eth_dev **eth_devs,
1810 		unsigned int from, unsigned int to)
1811 {
1812 	unsigned int i;
1813 
1814 	PMD_INIT_FUNC_TRACE();
1815 
1816 	for (i = from; i < to; i++) {
1817 		rte_szedata2_eth_dev_uninit(eth_devs[i]);
1818 		rte_eth_dev_release_port(eth_devs[i]);
1819 	}
1820 }
1821 
1822 /**
1823  * @brief Callback .probe for struct rte_pci_driver.
1824  */
szedata2_eth_pci_probe(struct rte_pci_driver * pci_drv __rte_unused,struct rte_pci_device * pci_dev)1825 static int szedata2_eth_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
1826 	struct rte_pci_device *pci_dev)
1827 {
1828 	struct port_info port_info[SZEDATA2_MAX_PORTS];
1829 	unsigned int port_count;
1830 	int ret;
1831 	unsigned int i;
1832 	struct pci_dev_list_entry *list_entry;
1833 	struct rte_eth_dev *eth_devs[SZEDATA2_MAX_PORTS] = {NULL,};
1834 
1835 	PMD_INIT_FUNC_TRACE();
1836 
1837 	ret = get_port_info(pci_dev, &port_count, port_info,
1838 			SZEDATA2_MAX_PORTS);
1839 	if (ret != 0)
1840 		return ret;
1841 
1842 	if (port_count == 0) {
1843 		PMD_INIT_LOG(ERR, "No available ports!");
1844 		return -ENODEV;
1845 	}
1846 
1847 	list_entry = rte_zmalloc(NULL, sizeof(struct pci_dev_list_entry),
1848 			RTE_CACHE_LINE_SIZE);
1849 	if (list_entry == NULL) {
1850 		PMD_INIT_LOG(ERR, "rte_zmalloc() failed!");
1851 		return -ENOMEM;
1852 	}
1853 
1854 	for (i = 0; i < port_count; i++) {
1855 		eth_devs[i] = szedata2_eth_dev_allocate(pci_dev,
1856 				port_info[i].numa_node, i);
1857 		if (eth_devs[i] == NULL) {
1858 			PMD_INIT_LOG(ERR, "Failed to alloc eth_dev for port %u",
1859 					i);
1860 			szedata2_eth_dev_release_interval(eth_devs, 0, i);
1861 			rte_free(list_entry);
1862 			return -ENOMEM;
1863 		}
1864 
1865 		ret = rte_szedata2_eth_dev_init(eth_devs[i], &port_info[i]);
1866 		if (ret != 0) {
1867 			PMD_INIT_LOG(ERR, "Failed to init eth_dev for port %u",
1868 					i);
1869 			rte_eth_dev_release_port(eth_devs[i]);
1870 			szedata2_eth_dev_release_interval(eth_devs, 0, i);
1871 			rte_free(list_entry);
1872 			return ret;
1873 		}
1874 
1875 		rte_eth_dev_probing_finish(eth_devs[i]);
1876 	}
1877 
1878 	/*
1879 	 * Add pci_dev to list of PCI devices for this driver
1880 	 * which is used at remove callback to release all created eth_devs.
1881 	 */
1882 	list_entry->pci_dev = pci_dev;
1883 	list_entry->port_count = port_count;
1884 	LIST_INSERT_HEAD(&szedata2_pci_dev_list, list_entry, next);
1885 	return 0;
1886 }
1887 
1888 /**
1889  * @brief Callback .remove for struct rte_pci_driver.
1890  */
szedata2_eth_pci_remove(struct rte_pci_device * pci_dev)1891 static int szedata2_eth_pci_remove(struct rte_pci_device *pci_dev)
1892 {
1893 	unsigned int i;
1894 	unsigned int port_count;
1895 	char name[RTE_ETH_NAME_MAX_LEN];
1896 	struct rte_eth_dev *eth_dev;
1897 	int ret;
1898 	int retval = 0;
1899 	bool found = false;
1900 	struct pci_dev_list_entry *list_entry = NULL;
1901 
1902 	PMD_INIT_FUNC_TRACE();
1903 
1904 	LIST_FOREACH(list_entry, &szedata2_pci_dev_list, next) {
1905 		if (list_entry->pci_dev == pci_dev) {
1906 			port_count = list_entry->port_count;
1907 			found = true;
1908 			break;
1909 		}
1910 	}
1911 	LIST_REMOVE(list_entry, next);
1912 	rte_free(list_entry);
1913 
1914 	if (!found) {
1915 		PMD_DRV_LOG(ERR, "PCI device " PCI_PRI_FMT " not found",
1916 				pci_dev->addr.domain, pci_dev->addr.bus,
1917 				pci_dev->addr.devid, pci_dev->addr.function);
1918 		return -ENODEV;
1919 	}
1920 
1921 	for (i = 0; i < port_count; i++) {
1922 		snprintf(name, RTE_ETH_NAME_MAX_LEN, "%s"
1923 				SZEDATA2_ETH_DEV_NAME_SUFFIX_FMT,
1924 				pci_dev->device.name, i);
1925 		PMD_DRV_LOG(DEBUG, "Removing eth_dev %s", name);
1926 		eth_dev = rte_eth_dev_allocated(name);
1927 		if (eth_dev == NULL)
1928 			continue; /* port already released */
1929 
1930 		ret = rte_szedata2_eth_dev_uninit(eth_dev);
1931 		if (ret != 0) {
1932 			PMD_DRV_LOG(ERR, "eth_dev %s uninit failed", name);
1933 			retval = retval ? retval : ret;
1934 		}
1935 
1936 		rte_eth_dev_release_port(eth_dev);
1937 	}
1938 
1939 	return retval;
1940 }
1941 
1942 static struct rte_pci_driver szedata2_eth_driver = {
1943 	.id_table = rte_szedata2_pci_id_table,
1944 	.probe = szedata2_eth_pci_probe,
1945 	.remove = szedata2_eth_pci_remove,
1946 };
1947 
1948 RTE_PMD_REGISTER_PCI(RTE_SZEDATA2_DRIVER_NAME, szedata2_eth_driver);
1949 RTE_PMD_REGISTER_PCI_TABLE(RTE_SZEDATA2_DRIVER_NAME, rte_szedata2_pci_id_table);
1950 RTE_PMD_REGISTER_KMOD_DEP(RTE_SZEDATA2_DRIVER_NAME,
1951 	"* combo6core & combov3 & szedata2 & ( szedata2_cv3 | szedata2_cv3_fdt )");
1952 RTE_LOG_REGISTER(szedata2_logtype_init, pmd.net.szedata2.init, NOTICE);
1953 RTE_LOG_REGISTER(szedata2_logtype_driver, pmd.net.szedata2.driver, NOTICE);
1954