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