f41716df8ddff0e924cf9a2a6b4b2ed0d8ff2e4e
[dpdk.git] / drivers / net / szedata2 / rte_eth_szedata2.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) 2015 - 2016 CESNET
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of CESNET nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <stdint.h>
35 #include <unistd.h>
36 #include <stdbool.h>
37 #include <err.h>
38 #include <sys/types.h>
39 #include <dirent.h>
40 #include <sys/stat.h>
41 #include <fcntl.h>
42 #include <sys/mman.h>
43
44 #include <libsze2.h>
45
46 #include <rte_mbuf.h>
47 #include <rte_ethdev_driver.h>
48 #include <rte_ethdev_pci.h>
49 #include <rte_malloc.h>
50 #include <rte_memcpy.h>
51 #include <rte_kvargs.h>
52 #include <rte_dev.h>
53
54 #include "rte_eth_szedata2.h"
55 #include "szedata2_iobuf.h"
56
57 #define RTE_ETH_SZEDATA2_MAX_RX_QUEUES 32
58 #define RTE_ETH_SZEDATA2_MAX_TX_QUEUES 32
59 #define RTE_ETH_SZEDATA2_TX_LOCK_SIZE (32 * 1024 * 1024)
60
61 /**
62  * size of szedata2_packet header with alignment
63  */
64 #define RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED 8
65
66 #define RTE_SZEDATA2_DRIVER_NAME net_szedata2
67
68 #define SZEDATA2_DEV_PATH_FMT "/dev/szedataII%u"
69
70 struct szedata2_rx_queue {
71         struct szedata *sze;
72         uint8_t rx_channel;
73         uint16_t in_port;
74         struct rte_mempool *mb_pool;
75         volatile uint64_t rx_pkts;
76         volatile uint64_t rx_bytes;
77         volatile uint64_t err_pkts;
78 };
79
80 struct szedata2_tx_queue {
81         struct szedata *sze;
82         uint8_t tx_channel;
83         volatile uint64_t tx_pkts;
84         volatile uint64_t tx_bytes;
85         volatile uint64_t err_pkts;
86 };
87
88 struct pmd_internals {
89         uint16_t max_rx_queues;
90         uint16_t max_tx_queues;
91         char sze_dev[PATH_MAX];
92         struct rte_mem_resource *pci_rsc;
93 };
94
95 static struct ether_addr eth_addr = {
96         .addr_bytes = { 0x00, 0x11, 0x17, 0x00, 0x00, 0x00 }
97 };
98
99 static uint16_t
100 eth_szedata2_rx(void *queue,
101                 struct rte_mbuf **bufs,
102                 uint16_t nb_pkts)
103 {
104         unsigned int i;
105         struct rte_mbuf *mbuf;
106         struct szedata2_rx_queue *sze_q = queue;
107         struct rte_pktmbuf_pool_private *mbp_priv;
108         uint16_t num_rx = 0;
109         uint16_t buf_size;
110         uint16_t sg_size;
111         uint16_t hw_size;
112         uint16_t packet_size;
113         uint64_t num_bytes = 0;
114         struct szedata *sze = sze_q->sze;
115         uint8_t *header_ptr = NULL; /* header of packet */
116         uint8_t *packet_ptr1 = NULL;
117         uint8_t *packet_ptr2 = NULL;
118         uint16_t packet_len1 = 0;
119         uint16_t packet_len2 = 0;
120         uint16_t hw_data_align;
121
122         if (unlikely(sze_q->sze == NULL || nb_pkts == 0))
123                 return 0;
124
125         /*
126          * Reads the given number of packets from szedata2 channel given
127          * by queue and copies the packet data into a newly allocated mbuf
128          * to return.
129          */
130         for (i = 0; i < nb_pkts; i++) {
131                 mbuf = rte_pktmbuf_alloc(sze_q->mb_pool);
132
133                 if (unlikely(mbuf == NULL))
134                         break;
135
136                 /* get the next sze packet */
137                 if (sze->ct_rx_lck != NULL && !sze->ct_rx_rem_bytes &&
138                                 sze->ct_rx_lck->next == NULL) {
139                         /* unlock old data */
140                         szedata_rx_unlock_data(sze_q->sze, sze->ct_rx_lck_orig);
141                         sze->ct_rx_lck_orig = NULL;
142                         sze->ct_rx_lck = NULL;
143                 }
144
145                 if (!sze->ct_rx_rem_bytes && sze->ct_rx_lck_orig == NULL) {
146                         /* nothing to read, lock new data */
147                         sze->ct_rx_lck = szedata_rx_lock_data(sze_q->sze, ~0U);
148                         sze->ct_rx_lck_orig = sze->ct_rx_lck;
149
150                         if (sze->ct_rx_lck == NULL) {
151                                 /* nothing to lock */
152                                 rte_pktmbuf_free(mbuf);
153                                 break;
154                         }
155
156                         sze->ct_rx_cur_ptr = sze->ct_rx_lck->start;
157                         sze->ct_rx_rem_bytes = sze->ct_rx_lck->len;
158
159                         if (!sze->ct_rx_rem_bytes) {
160                                 rte_pktmbuf_free(mbuf);
161                                 break;
162                         }
163                 }
164
165                 if (sze->ct_rx_rem_bytes < RTE_SZE2_PACKET_HEADER_SIZE) {
166                         /*
167                          * cut in header
168                          * copy parts of header to merge buffer
169                          */
170                         if (sze->ct_rx_lck->next == NULL) {
171                                 rte_pktmbuf_free(mbuf);
172                                 break;
173                         }
174
175                         /* copy first part of header */
176                         rte_memcpy(sze->ct_rx_buffer, sze->ct_rx_cur_ptr,
177                                         sze->ct_rx_rem_bytes);
178
179                         /* copy second part of header */
180                         sze->ct_rx_lck = sze->ct_rx_lck->next;
181                         sze->ct_rx_cur_ptr = sze->ct_rx_lck->start;
182                         rte_memcpy(sze->ct_rx_buffer + sze->ct_rx_rem_bytes,
183                                 sze->ct_rx_cur_ptr,
184                                 RTE_SZE2_PACKET_HEADER_SIZE -
185                                 sze->ct_rx_rem_bytes);
186
187                         sze->ct_rx_cur_ptr += RTE_SZE2_PACKET_HEADER_SIZE -
188                                 sze->ct_rx_rem_bytes;
189                         sze->ct_rx_rem_bytes = sze->ct_rx_lck->len -
190                                 RTE_SZE2_PACKET_HEADER_SIZE +
191                                 sze->ct_rx_rem_bytes;
192
193                         header_ptr = (uint8_t *)sze->ct_rx_buffer;
194                 } else {
195                         /* not cut */
196                         header_ptr = (uint8_t *)sze->ct_rx_cur_ptr;
197                         sze->ct_rx_cur_ptr += RTE_SZE2_PACKET_HEADER_SIZE;
198                         sze->ct_rx_rem_bytes -= RTE_SZE2_PACKET_HEADER_SIZE;
199                 }
200
201                 sg_size = le16toh(*((uint16_t *)header_ptr));
202                 hw_size = le16toh(*(((uint16_t *)header_ptr) + 1));
203                 packet_size = sg_size -
204                         RTE_SZE2_ALIGN8(RTE_SZE2_PACKET_HEADER_SIZE + hw_size);
205
206
207                 /* checks if packet all right */
208                 if (!sg_size)
209                         errx(5, "Zero segsize");
210
211                 /* check sg_size and hwsize */
212                 if (hw_size > sg_size - RTE_SZE2_PACKET_HEADER_SIZE) {
213                         errx(10, "Hwsize bigger than expected. Segsize: %d, "
214                                 "hwsize: %d", sg_size, hw_size);
215                 }
216
217                 hw_data_align =
218                         RTE_SZE2_ALIGN8(RTE_SZE2_PACKET_HEADER_SIZE + hw_size) -
219                         RTE_SZE2_PACKET_HEADER_SIZE;
220
221                 if (sze->ct_rx_rem_bytes >=
222                                 (uint16_t)(sg_size -
223                                 RTE_SZE2_PACKET_HEADER_SIZE)) {
224                         /* no cut */
225                         /* one packet ready - go to another */
226                         packet_ptr1 = sze->ct_rx_cur_ptr + hw_data_align;
227                         packet_len1 = packet_size;
228                         packet_ptr2 = NULL;
229                         packet_len2 = 0;
230
231                         sze->ct_rx_cur_ptr += RTE_SZE2_ALIGN8(sg_size) -
232                                 RTE_SZE2_PACKET_HEADER_SIZE;
233                         sze->ct_rx_rem_bytes -= RTE_SZE2_ALIGN8(sg_size) -
234                                 RTE_SZE2_PACKET_HEADER_SIZE;
235                 } else {
236                         /* cut in data */
237                         if (sze->ct_rx_lck->next == NULL) {
238                                 errx(6, "Need \"next\" lock, "
239                                         "but it is missing: %u",
240                                         sze->ct_rx_rem_bytes);
241                         }
242
243                         /* skip hw data */
244                         if (sze->ct_rx_rem_bytes <= hw_data_align) {
245                                 uint16_t rem_size = hw_data_align -
246                                         sze->ct_rx_rem_bytes;
247
248                                 /* MOVE to next lock */
249                                 sze->ct_rx_lck = sze->ct_rx_lck->next;
250                                 sze->ct_rx_cur_ptr =
251                                         (void *)(((uint8_t *)
252                                         (sze->ct_rx_lck->start)) + rem_size);
253
254                                 packet_ptr1 = sze->ct_rx_cur_ptr;
255                                 packet_len1 = packet_size;
256                                 packet_ptr2 = NULL;
257                                 packet_len2 = 0;
258
259                                 sze->ct_rx_cur_ptr +=
260                                         RTE_SZE2_ALIGN8(packet_size);
261                                 sze->ct_rx_rem_bytes = sze->ct_rx_lck->len -
262                                         rem_size - RTE_SZE2_ALIGN8(packet_size);
263                         } else {
264                                 /* get pointer and length from first part */
265                                 packet_ptr1 = sze->ct_rx_cur_ptr +
266                                         hw_data_align;
267                                 packet_len1 = sze->ct_rx_rem_bytes -
268                                         hw_data_align;
269
270                                 /* MOVE to next lock */
271                                 sze->ct_rx_lck = sze->ct_rx_lck->next;
272                                 sze->ct_rx_cur_ptr = sze->ct_rx_lck->start;
273
274                                 /* get pointer and length from second part */
275                                 packet_ptr2 = sze->ct_rx_cur_ptr;
276                                 packet_len2 = packet_size - packet_len1;
277
278                                 sze->ct_rx_cur_ptr +=
279                                         RTE_SZE2_ALIGN8(packet_size) -
280                                         packet_len1;
281                                 sze->ct_rx_rem_bytes = sze->ct_rx_lck->len -
282                                         (RTE_SZE2_ALIGN8(packet_size) -
283                                          packet_len1);
284                         }
285                 }
286
287                 if (unlikely(packet_ptr1 == NULL)) {
288                         rte_pktmbuf_free(mbuf);
289                         break;
290                 }
291
292                 /* get the space available for data in the mbuf */
293                 mbp_priv = rte_mempool_get_priv(sze_q->mb_pool);
294                 buf_size = (uint16_t)(mbp_priv->mbuf_data_room_size -
295                                 RTE_PKTMBUF_HEADROOM);
296
297                 if (packet_size <= buf_size) {
298                         /* sze packet will fit in one mbuf, go ahead and copy */
299                         rte_memcpy(rte_pktmbuf_mtod(mbuf, void *),
300                                         packet_ptr1, packet_len1);
301                         if (packet_ptr2 != NULL) {
302                                 rte_memcpy((void *)(rte_pktmbuf_mtod(mbuf,
303                                         uint8_t *) + packet_len1),
304                                         packet_ptr2, packet_len2);
305                         }
306                         mbuf->data_len = (uint16_t)packet_size;
307
308                         mbuf->pkt_len = packet_size;
309                         mbuf->port = sze_q->in_port;
310                         bufs[num_rx] = mbuf;
311                         num_rx++;
312                         num_bytes += packet_size;
313                 } else {
314                         /*
315                          * sze packet will not fit in one mbuf,
316                          * scattered mode is not enabled, drop packet
317                          */
318                         RTE_LOG(ERR, PMD,
319                                 "SZE segment %d bytes will not fit in one mbuf "
320                                 "(%d bytes), scattered mode is not enabled, "
321                                 "drop packet!!\n",
322                                 packet_size, buf_size);
323                         rte_pktmbuf_free(mbuf);
324                 }
325         }
326
327         sze_q->rx_pkts += num_rx;
328         sze_q->rx_bytes += num_bytes;
329         return num_rx;
330 }
331
332 static uint16_t
333 eth_szedata2_rx_scattered(void *queue,
334                 struct rte_mbuf **bufs,
335                 uint16_t nb_pkts)
336 {
337         unsigned int i;
338         struct rte_mbuf *mbuf;
339         struct szedata2_rx_queue *sze_q = queue;
340         struct rte_pktmbuf_pool_private *mbp_priv;
341         uint16_t num_rx = 0;
342         uint16_t buf_size;
343         uint16_t sg_size;
344         uint16_t hw_size;
345         uint16_t packet_size;
346         uint64_t num_bytes = 0;
347         struct szedata *sze = sze_q->sze;
348         uint8_t *header_ptr = NULL; /* header of packet */
349         uint8_t *packet_ptr1 = NULL;
350         uint8_t *packet_ptr2 = NULL;
351         uint16_t packet_len1 = 0;
352         uint16_t packet_len2 = 0;
353         uint16_t hw_data_align;
354
355         if (unlikely(sze_q->sze == NULL || nb_pkts == 0))
356                 return 0;
357
358         /*
359          * Reads the given number of packets from szedata2 channel given
360          * by queue and copies the packet data into a newly allocated mbuf
361          * to return.
362          */
363         for (i = 0; i < nb_pkts; i++) {
364                 const struct szedata_lock *ct_rx_lck_backup;
365                 unsigned int ct_rx_rem_bytes_backup;
366                 unsigned char *ct_rx_cur_ptr_backup;
367
368                 /* get the next sze packet */
369                 if (sze->ct_rx_lck != NULL && !sze->ct_rx_rem_bytes &&
370                                 sze->ct_rx_lck->next == NULL) {
371                         /* unlock old data */
372                         szedata_rx_unlock_data(sze_q->sze, sze->ct_rx_lck_orig);
373                         sze->ct_rx_lck_orig = NULL;
374                         sze->ct_rx_lck = NULL;
375                 }
376
377                 /*
378                  * Store items from sze structure which can be changed
379                  * before mbuf allocating. Use these items in case of mbuf
380                  * allocating failure.
381                  */
382                 ct_rx_lck_backup = sze->ct_rx_lck;
383                 ct_rx_rem_bytes_backup = sze->ct_rx_rem_bytes;
384                 ct_rx_cur_ptr_backup = sze->ct_rx_cur_ptr;
385
386                 if (!sze->ct_rx_rem_bytes && sze->ct_rx_lck_orig == NULL) {
387                         /* nothing to read, lock new data */
388                         sze->ct_rx_lck = szedata_rx_lock_data(sze_q->sze, ~0U);
389                         sze->ct_rx_lck_orig = sze->ct_rx_lck;
390
391                         /*
392                          * Backup items from sze structure must be updated
393                          * after locking to contain pointers to new locks.
394                          */
395                         ct_rx_lck_backup = sze->ct_rx_lck;
396                         ct_rx_rem_bytes_backup = sze->ct_rx_rem_bytes;
397                         ct_rx_cur_ptr_backup = sze->ct_rx_cur_ptr;
398
399                         if (sze->ct_rx_lck == NULL)
400                                 /* nothing to lock */
401                                 break;
402
403                         sze->ct_rx_cur_ptr = sze->ct_rx_lck->start;
404                         sze->ct_rx_rem_bytes = sze->ct_rx_lck->len;
405
406                         if (!sze->ct_rx_rem_bytes)
407                                 break;
408                 }
409
410                 if (sze->ct_rx_rem_bytes < RTE_SZE2_PACKET_HEADER_SIZE) {
411                         /*
412                          * cut in header - copy parts of header to merge buffer
413                          */
414                         if (sze->ct_rx_lck->next == NULL)
415                                 break;
416
417                         /* copy first part of header */
418                         rte_memcpy(sze->ct_rx_buffer, sze->ct_rx_cur_ptr,
419                                         sze->ct_rx_rem_bytes);
420
421                         /* copy second part of header */
422                         sze->ct_rx_lck = sze->ct_rx_lck->next;
423                         sze->ct_rx_cur_ptr = sze->ct_rx_lck->start;
424                         rte_memcpy(sze->ct_rx_buffer + sze->ct_rx_rem_bytes,
425                                 sze->ct_rx_cur_ptr,
426                                 RTE_SZE2_PACKET_HEADER_SIZE -
427                                 sze->ct_rx_rem_bytes);
428
429                         sze->ct_rx_cur_ptr += RTE_SZE2_PACKET_HEADER_SIZE -
430                                 sze->ct_rx_rem_bytes;
431                         sze->ct_rx_rem_bytes = sze->ct_rx_lck->len -
432                                 RTE_SZE2_PACKET_HEADER_SIZE +
433                                 sze->ct_rx_rem_bytes;
434
435                         header_ptr = (uint8_t *)sze->ct_rx_buffer;
436                 } else {
437                         /* not cut */
438                         header_ptr = (uint8_t *)sze->ct_rx_cur_ptr;
439                         sze->ct_rx_cur_ptr += RTE_SZE2_PACKET_HEADER_SIZE;
440                         sze->ct_rx_rem_bytes -= RTE_SZE2_PACKET_HEADER_SIZE;
441                 }
442
443                 sg_size = le16toh(*((uint16_t *)header_ptr));
444                 hw_size = le16toh(*(((uint16_t *)header_ptr) + 1));
445                 packet_size = sg_size -
446                         RTE_SZE2_ALIGN8(RTE_SZE2_PACKET_HEADER_SIZE + hw_size);
447
448
449                 /* checks if packet all right */
450                 if (!sg_size)
451                         errx(5, "Zero segsize");
452
453                 /* check sg_size and hwsize */
454                 if (hw_size > sg_size - RTE_SZE2_PACKET_HEADER_SIZE) {
455                         errx(10, "Hwsize bigger than expected. Segsize: %d, "
456                                         "hwsize: %d", sg_size, hw_size);
457                 }
458
459                 hw_data_align =
460                         RTE_SZE2_ALIGN8((RTE_SZE2_PACKET_HEADER_SIZE +
461                         hw_size)) - RTE_SZE2_PACKET_HEADER_SIZE;
462
463                 if (sze->ct_rx_rem_bytes >=
464                                 (uint16_t)(sg_size -
465                                 RTE_SZE2_PACKET_HEADER_SIZE)) {
466                         /* no cut */
467                         /* one packet ready - go to another */
468                         packet_ptr1 = sze->ct_rx_cur_ptr + hw_data_align;
469                         packet_len1 = packet_size;
470                         packet_ptr2 = NULL;
471                         packet_len2 = 0;
472
473                         sze->ct_rx_cur_ptr += RTE_SZE2_ALIGN8(sg_size) -
474                                 RTE_SZE2_PACKET_HEADER_SIZE;
475                         sze->ct_rx_rem_bytes -= RTE_SZE2_ALIGN8(sg_size) -
476                                 RTE_SZE2_PACKET_HEADER_SIZE;
477                 } else {
478                         /* cut in data */
479                         if (sze->ct_rx_lck->next == NULL) {
480                                 errx(6, "Need \"next\" lock, but it is "
481                                         "missing: %u", sze->ct_rx_rem_bytes);
482                         }
483
484                         /* skip hw data */
485                         if (sze->ct_rx_rem_bytes <= hw_data_align) {
486                                 uint16_t rem_size = hw_data_align -
487                                         sze->ct_rx_rem_bytes;
488
489                                 /* MOVE to next lock */
490                                 sze->ct_rx_lck = sze->ct_rx_lck->next;
491                                 sze->ct_rx_cur_ptr =
492                                         (void *)(((uint8_t *)
493                                         (sze->ct_rx_lck->start)) + rem_size);
494
495                                 packet_ptr1 = sze->ct_rx_cur_ptr;
496                                 packet_len1 = packet_size;
497                                 packet_ptr2 = NULL;
498                                 packet_len2 = 0;
499
500                                 sze->ct_rx_cur_ptr +=
501                                         RTE_SZE2_ALIGN8(packet_size);
502                                 sze->ct_rx_rem_bytes = sze->ct_rx_lck->len -
503                                         rem_size - RTE_SZE2_ALIGN8(packet_size);
504                         } else {
505                                 /* get pointer and length from first part */
506                                 packet_ptr1 = sze->ct_rx_cur_ptr +
507                                         hw_data_align;
508                                 packet_len1 = sze->ct_rx_rem_bytes -
509                                         hw_data_align;
510
511                                 /* MOVE to next lock */
512                                 sze->ct_rx_lck = sze->ct_rx_lck->next;
513                                 sze->ct_rx_cur_ptr = sze->ct_rx_lck->start;
514
515                                 /* get pointer and length from second part */
516                                 packet_ptr2 = sze->ct_rx_cur_ptr;
517                                 packet_len2 = packet_size - packet_len1;
518
519                                 sze->ct_rx_cur_ptr +=
520                                         RTE_SZE2_ALIGN8(packet_size) -
521                                         packet_len1;
522                                 sze->ct_rx_rem_bytes = sze->ct_rx_lck->len -
523                                         (RTE_SZE2_ALIGN8(packet_size) -
524                                          packet_len1);
525                         }
526                 }
527
528                 if (unlikely(packet_ptr1 == NULL))
529                         break;
530
531                 mbuf = rte_pktmbuf_alloc(sze_q->mb_pool);
532
533                 if (unlikely(mbuf == NULL)) {
534                         /*
535                          * Restore items from sze structure to state after
536                          * unlocking (eventually locking).
537                          */
538                         sze->ct_rx_lck = ct_rx_lck_backup;
539                         sze->ct_rx_rem_bytes = ct_rx_rem_bytes_backup;
540                         sze->ct_rx_cur_ptr = ct_rx_cur_ptr_backup;
541                         break;
542                 }
543
544                 /* get the space available for data in the mbuf */
545                 mbp_priv = rte_mempool_get_priv(sze_q->mb_pool);
546                 buf_size = (uint16_t)(mbp_priv->mbuf_data_room_size -
547                                 RTE_PKTMBUF_HEADROOM);
548
549                 if (packet_size <= buf_size) {
550                         /* sze packet will fit in one mbuf, go ahead and copy */
551                         rte_memcpy(rte_pktmbuf_mtod(mbuf, void *),
552                                         packet_ptr1, packet_len1);
553                         if (packet_ptr2 != NULL) {
554                                 rte_memcpy((void *)
555                                         (rte_pktmbuf_mtod(mbuf, uint8_t *) +
556                                         packet_len1), packet_ptr2, packet_len2);
557                         }
558                         mbuf->data_len = (uint16_t)packet_size;
559                 } else {
560                         /*
561                          * sze packet will not fit in one mbuf,
562                          * scatter packet into more mbufs
563                          */
564                         struct rte_mbuf *m = mbuf;
565                         uint16_t len = rte_pktmbuf_tailroom(mbuf);
566
567                         /* copy first part of packet */
568                         /* fill first mbuf */
569                         rte_memcpy(rte_pktmbuf_append(mbuf, len), packet_ptr1,
570                                 len);
571                         packet_len1 -= len;
572                         packet_ptr1 = ((uint8_t *)packet_ptr1) + len;
573
574                         while (packet_len1 > 0) {
575                                 /* fill new mbufs */
576                                 m->next = rte_pktmbuf_alloc(sze_q->mb_pool);
577
578                                 if (unlikely(m->next == NULL)) {
579                                         rte_pktmbuf_free(mbuf);
580                                         /*
581                                          * Restore items from sze structure
582                                          * to state after unlocking (eventually
583                                          * locking).
584                                          */
585                                         sze->ct_rx_lck = ct_rx_lck_backup;
586                                         sze->ct_rx_rem_bytes =
587                                                 ct_rx_rem_bytes_backup;
588                                         sze->ct_rx_cur_ptr =
589                                                 ct_rx_cur_ptr_backup;
590                                         goto finish;
591                                 }
592
593                                 m = m->next;
594
595                                 len = RTE_MIN(rte_pktmbuf_tailroom(m),
596                                         packet_len1);
597                                 rte_memcpy(rte_pktmbuf_append(mbuf, len),
598                                         packet_ptr1, len);
599
600                                 (mbuf->nb_segs)++;
601                                 packet_len1 -= len;
602                                 packet_ptr1 = ((uint8_t *)packet_ptr1) + len;
603                         }
604
605                         if (packet_ptr2 != NULL) {
606                                 /* copy second part of packet, if exists */
607                                 /* fill the rest of currently last mbuf */
608                                 len = rte_pktmbuf_tailroom(m);
609                                 rte_memcpy(rte_pktmbuf_append(mbuf, len),
610                                         packet_ptr2, len);
611                                 packet_len2 -= len;
612                                 packet_ptr2 = ((uint8_t *)packet_ptr2) + len;
613
614                                 while (packet_len2 > 0) {
615                                         /* fill new mbufs */
616                                         m->next = rte_pktmbuf_alloc(
617                                                         sze_q->mb_pool);
618
619                                         if (unlikely(m->next == NULL)) {
620                                                 rte_pktmbuf_free(mbuf);
621                                                 /*
622                                                  * Restore items from sze
623                                                  * structure to state after
624                                                  * unlocking (eventually
625                                                  * locking).
626                                                  */
627                                                 sze->ct_rx_lck =
628                                                         ct_rx_lck_backup;
629                                                 sze->ct_rx_rem_bytes =
630                                                         ct_rx_rem_bytes_backup;
631                                                 sze->ct_rx_cur_ptr =
632                                                         ct_rx_cur_ptr_backup;
633                                                 goto finish;
634                                         }
635
636                                         m = m->next;
637
638                                         len = RTE_MIN(rte_pktmbuf_tailroom(m),
639                                                 packet_len2);
640                                         rte_memcpy(
641                                                 rte_pktmbuf_append(mbuf, len),
642                                                 packet_ptr2, len);
643
644                                         (mbuf->nb_segs)++;
645                                         packet_len2 -= len;
646                                         packet_ptr2 = ((uint8_t *)packet_ptr2) +
647                                                 len;
648                                 }
649                         }
650                 }
651                 mbuf->pkt_len = packet_size;
652                 mbuf->port = sze_q->in_port;
653                 bufs[num_rx] = mbuf;
654                 num_rx++;
655                 num_bytes += packet_size;
656         }
657
658 finish:
659         sze_q->rx_pkts += num_rx;
660         sze_q->rx_bytes += num_bytes;
661         return num_rx;
662 }
663
664 static uint16_t
665 eth_szedata2_tx(void *queue,
666                 struct rte_mbuf **bufs,
667                 uint16_t nb_pkts)
668 {
669         struct rte_mbuf *mbuf;
670         struct szedata2_tx_queue *sze_q = queue;
671         uint16_t num_tx = 0;
672         uint64_t num_bytes = 0;
673
674         const struct szedata_lock *lck;
675         uint32_t lock_size;
676         uint32_t lock_size2;
677         void *dst;
678         uint32_t pkt_len;
679         uint32_t hwpkt_len;
680         uint32_t unlock_size;
681         uint32_t rem_len;
682         uint16_t mbuf_segs;
683         uint16_t pkt_left = nb_pkts;
684
685         if (sze_q->sze == NULL || nb_pkts == 0)
686                 return 0;
687
688         while (pkt_left > 0) {
689                 unlock_size = 0;
690                 lck = szedata_tx_lock_data(sze_q->sze,
691                         RTE_ETH_SZEDATA2_TX_LOCK_SIZE,
692                         sze_q->tx_channel);
693                 if (lck == NULL)
694                         continue;
695
696                 dst = lck->start;
697                 lock_size = lck->len;
698                 lock_size2 = lck->next ? lck->next->len : 0;
699
700 next_packet:
701                 mbuf = bufs[nb_pkts - pkt_left];
702
703                 pkt_len = mbuf->pkt_len;
704                 mbuf_segs = mbuf->nb_segs;
705
706                 hwpkt_len = RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED +
707                         RTE_SZE2_ALIGN8(pkt_len);
708
709                 if (lock_size + lock_size2 < hwpkt_len) {
710                         szedata_tx_unlock_data(sze_q->sze, lck, unlock_size);
711                         continue;
712                 }
713
714                 num_bytes += pkt_len;
715
716                 if (lock_size > hwpkt_len) {
717                         void *tmp_dst;
718
719                         rem_len = 0;
720
721                         /* write packet length at first 2 bytes in 8B header */
722                         *((uint16_t *)dst) = htole16(
723                                         RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED +
724                                         pkt_len);
725                         *(((uint16_t *)dst) + 1) = htole16(0);
726
727                         /* copy packet from mbuf */
728                         tmp_dst = ((uint8_t *)(dst)) +
729                                 RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED;
730                         if (mbuf_segs == 1) {
731                                 /*
732                                  * non-scattered packet,
733                                  * transmit from one mbuf
734                                  */
735                                 rte_memcpy(tmp_dst,
736                                         rte_pktmbuf_mtod(mbuf, const void *),
737                                         pkt_len);
738                         } else {
739                                 /* scattered packet, transmit from more mbufs */
740                                 struct rte_mbuf *m = mbuf;
741                                 while (m) {
742                                         rte_memcpy(tmp_dst,
743                                                 rte_pktmbuf_mtod(m,
744                                                 const void *),
745                                                 m->data_len);
746                                         tmp_dst = ((uint8_t *)(tmp_dst)) +
747                                                 m->data_len;
748                                         m = m->next;
749                                 }
750                         }
751
752
753                         dst = ((uint8_t *)dst) + hwpkt_len;
754                         unlock_size += hwpkt_len;
755                         lock_size -= hwpkt_len;
756
757                         rte_pktmbuf_free(mbuf);
758                         num_tx++;
759                         pkt_left--;
760                         if (pkt_left == 0) {
761                                 szedata_tx_unlock_data(sze_q->sze, lck,
762                                         unlock_size);
763                                 break;
764                         }
765                         goto next_packet;
766                 } else if (lock_size + lock_size2 >= hwpkt_len) {
767                         void *tmp_dst;
768                         uint16_t write_len;
769
770                         /* write packet length at first 2 bytes in 8B header */
771                         *((uint16_t *)dst) =
772                                 htole16(RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED +
773                                         pkt_len);
774                         *(((uint16_t *)dst) + 1) = htole16(0);
775
776                         /*
777                          * If the raw packet (pkt_len) is smaller than lock_size
778                          * get the correct length for memcpy
779                          */
780                         write_len =
781                                 pkt_len < lock_size -
782                                 RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED ?
783                                 pkt_len :
784                                 lock_size - RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED;
785
786                         rem_len = hwpkt_len - lock_size;
787
788                         tmp_dst = ((uint8_t *)(dst)) +
789                                 RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED;
790                         if (mbuf_segs == 1) {
791                                 /*
792                                  * non-scattered packet,
793                                  * transmit from one mbuf
794                                  */
795                                 /* copy part of packet to first area */
796                                 rte_memcpy(tmp_dst,
797                                         rte_pktmbuf_mtod(mbuf, const void *),
798                                         write_len);
799
800                                 if (lck->next)
801                                         dst = lck->next->start;
802
803                                 /* copy part of packet to second area */
804                                 rte_memcpy(dst,
805                                         (const void *)(rte_pktmbuf_mtod(mbuf,
806                                                         const uint8_t *) +
807                                         write_len), pkt_len - write_len);
808                         } else {
809                                 /* scattered packet, transmit from more mbufs */
810                                 struct rte_mbuf *m = mbuf;
811                                 uint16_t written = 0;
812                                 uint16_t to_write = 0;
813                                 bool new_mbuf = true;
814                                 uint16_t write_off = 0;
815
816                                 /* copy part of packet to first area */
817                                 while (m && written < write_len) {
818                                         to_write = RTE_MIN(m->data_len,
819                                                         write_len - written);
820                                         rte_memcpy(tmp_dst,
821                                                 rte_pktmbuf_mtod(m,
822                                                         const void *),
823                                                 to_write);
824
825                                         tmp_dst = ((uint8_t *)(tmp_dst)) +
826                                                 to_write;
827                                         if (m->data_len <= write_len -
828                                                         written) {
829                                                 m = m->next;
830                                                 new_mbuf = true;
831                                         } else {
832                                                 new_mbuf = false;
833                                         }
834                                         written += to_write;
835                                 }
836
837                                 if (lck->next)
838                                         dst = lck->next->start;
839
840                                 tmp_dst = dst;
841                                 written = 0;
842                                 write_off = new_mbuf ? 0 : to_write;
843
844                                 /* copy part of packet to second area */
845                                 while (m && written < pkt_len - write_len) {
846                                         rte_memcpy(tmp_dst, (const void *)
847                                                 (rte_pktmbuf_mtod(m,
848                                                 uint8_t *) + write_off),
849                                                 m->data_len - write_off);
850
851                                         tmp_dst = ((uint8_t *)(tmp_dst)) +
852                                                 (m->data_len - write_off);
853                                         written += m->data_len - write_off;
854                                         m = m->next;
855                                         write_off = 0;
856                                 }
857                         }
858
859                         dst = ((uint8_t *)dst) + rem_len;
860                         unlock_size += hwpkt_len;
861                         lock_size = lock_size2 - rem_len;
862                         lock_size2 = 0;
863
864                         rte_pktmbuf_free(mbuf);
865                         num_tx++;
866                 }
867
868                 szedata_tx_unlock_data(sze_q->sze, lck, unlock_size);
869                 pkt_left--;
870         }
871
872         sze_q->tx_pkts += num_tx;
873         sze_q->err_pkts += nb_pkts - num_tx;
874         sze_q->tx_bytes += num_bytes;
875         return num_tx;
876 }
877
878 static int
879 eth_rx_queue_start(struct rte_eth_dev *dev, uint16_t rxq_id)
880 {
881         struct szedata2_rx_queue *rxq = dev->data->rx_queues[rxq_id];
882         int ret;
883         struct pmd_internals *internals = (struct pmd_internals *)
884                 dev->data->dev_private;
885
886         if (rxq->sze == NULL) {
887                 uint32_t rx = 1 << rxq->rx_channel;
888                 uint32_t tx = 0;
889                 rxq->sze = szedata_open(internals->sze_dev);
890                 if (rxq->sze == NULL)
891                         return -EINVAL;
892                 ret = szedata_subscribe3(rxq->sze, &rx, &tx);
893                 if (ret != 0 || rx == 0)
894                         goto err;
895         }
896
897         ret = szedata_start(rxq->sze);
898         if (ret != 0)
899                 goto err;
900         dev->data->rx_queue_state[rxq_id] = RTE_ETH_QUEUE_STATE_STARTED;
901         return 0;
902
903 err:
904         szedata_close(rxq->sze);
905         rxq->sze = NULL;
906         return -EINVAL;
907 }
908
909 static int
910 eth_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rxq_id)
911 {
912         struct szedata2_rx_queue *rxq = dev->data->rx_queues[rxq_id];
913
914         if (rxq->sze != NULL) {
915                 szedata_close(rxq->sze);
916                 rxq->sze = NULL;
917         }
918
919         dev->data->rx_queue_state[rxq_id] = RTE_ETH_QUEUE_STATE_STOPPED;
920         return 0;
921 }
922
923 static int
924 eth_tx_queue_start(struct rte_eth_dev *dev, uint16_t txq_id)
925 {
926         struct szedata2_tx_queue *txq = dev->data->tx_queues[txq_id];
927         int ret;
928         struct pmd_internals *internals = (struct pmd_internals *)
929                 dev->data->dev_private;
930
931         if (txq->sze == NULL) {
932                 uint32_t rx = 0;
933                 uint32_t tx = 1 << txq->tx_channel;
934                 txq->sze = szedata_open(internals->sze_dev);
935                 if (txq->sze == NULL)
936                         return -EINVAL;
937                 ret = szedata_subscribe3(txq->sze, &rx, &tx);
938                 if (ret != 0 || tx == 0)
939                         goto err;
940         }
941
942         ret = szedata_start(txq->sze);
943         if (ret != 0)
944                 goto err;
945         dev->data->tx_queue_state[txq_id] = RTE_ETH_QUEUE_STATE_STARTED;
946         return 0;
947
948 err:
949         szedata_close(txq->sze);
950         txq->sze = NULL;
951         return -EINVAL;
952 }
953
954 static int
955 eth_tx_queue_stop(struct rte_eth_dev *dev, uint16_t txq_id)
956 {
957         struct szedata2_tx_queue *txq = dev->data->tx_queues[txq_id];
958
959         if (txq->sze != NULL) {
960                 szedata_close(txq->sze);
961                 txq->sze = NULL;
962         }
963
964         dev->data->tx_queue_state[txq_id] = RTE_ETH_QUEUE_STATE_STOPPED;
965         return 0;
966 }
967
968 static int
969 eth_dev_start(struct rte_eth_dev *dev)
970 {
971         int ret;
972         uint16_t i;
973         uint16_t nb_rx = dev->data->nb_rx_queues;
974         uint16_t nb_tx = dev->data->nb_tx_queues;
975
976         for (i = 0; i < nb_rx; i++) {
977                 ret = eth_rx_queue_start(dev, i);
978                 if (ret != 0)
979                         goto err_rx;
980         }
981
982         for (i = 0; i < nb_tx; i++) {
983                 ret = eth_tx_queue_start(dev, i);
984                 if (ret != 0)
985                         goto err_tx;
986         }
987
988         return 0;
989
990 err_tx:
991         for (i = 0; i < nb_tx; i++)
992                 eth_tx_queue_stop(dev, i);
993 err_rx:
994         for (i = 0; i < nb_rx; i++)
995                 eth_rx_queue_stop(dev, i);
996         return ret;
997 }
998
999 static void
1000 eth_dev_stop(struct rte_eth_dev *dev)
1001 {
1002         uint16_t i;
1003         uint16_t nb_rx = dev->data->nb_rx_queues;
1004         uint16_t nb_tx = dev->data->nb_tx_queues;
1005
1006         for (i = 0; i < nb_tx; i++)
1007                 eth_tx_queue_stop(dev, i);
1008
1009         for (i = 0; i < nb_rx; i++)
1010                 eth_rx_queue_stop(dev, i);
1011 }
1012
1013 static int
1014 eth_dev_configure(struct rte_eth_dev *dev)
1015 {
1016         struct rte_eth_dev_data *data = dev->data;
1017         if (data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_SCATTER) {
1018                 dev->rx_pkt_burst = eth_szedata2_rx_scattered;
1019                 data->scattered_rx = 1;
1020         } else {
1021                 dev->rx_pkt_burst = eth_szedata2_rx;
1022                 data->scattered_rx = 0;
1023         }
1024         return 0;
1025 }
1026
1027 static void
1028 eth_dev_info(struct rte_eth_dev *dev,
1029                 struct rte_eth_dev_info *dev_info)
1030 {
1031         struct pmd_internals *internals = dev->data->dev_private;
1032
1033         dev_info->pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1034         dev_info->if_index = 0;
1035         dev_info->max_mac_addrs = 1;
1036         dev_info->max_rx_pktlen = (uint32_t)-1;
1037         dev_info->max_rx_queues = internals->max_rx_queues;
1038         dev_info->max_tx_queues = internals->max_tx_queues;
1039         dev_info->min_rx_bufsize = 0;
1040         dev_info->rx_offload_capa = DEV_RX_OFFLOAD_SCATTER;
1041         dev_info->tx_offload_capa = 0;
1042         dev_info->rx_queue_offload_capa = 0;
1043         dev_info->tx_queue_offload_capa = 0;
1044         dev_info->speed_capa = ETH_LINK_SPEED_100G;
1045 }
1046
1047 static int
1048 eth_stats_get(struct rte_eth_dev *dev,
1049                 struct rte_eth_stats *stats)
1050 {
1051         uint16_t i;
1052         uint16_t nb_rx = dev->data->nb_rx_queues;
1053         uint16_t nb_tx = dev->data->nb_tx_queues;
1054         uint64_t rx_total = 0;
1055         uint64_t tx_total = 0;
1056         uint64_t tx_err_total = 0;
1057         uint64_t rx_total_bytes = 0;
1058         uint64_t tx_total_bytes = 0;
1059
1060         for (i = 0; i < nb_rx; i++) {
1061                 struct szedata2_rx_queue *rxq = dev->data->rx_queues[i];
1062
1063                 if (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
1064                         stats->q_ipackets[i] = rxq->rx_pkts;
1065                         stats->q_ibytes[i] = rxq->rx_bytes;
1066                 }
1067                 rx_total += rxq->rx_pkts;
1068                 rx_total_bytes += rxq->rx_bytes;
1069         }
1070
1071         for (i = 0; i < nb_tx; i++) {
1072                 struct szedata2_tx_queue *txq = dev->data->tx_queues[i];
1073
1074                 if (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
1075                         stats->q_opackets[i] = txq->tx_pkts;
1076                         stats->q_obytes[i] = txq->tx_bytes;
1077                         stats->q_errors[i] = txq->err_pkts;
1078                 }
1079                 tx_total += txq->tx_pkts;
1080                 tx_total_bytes += txq->tx_bytes;
1081                 tx_err_total += txq->err_pkts;
1082         }
1083
1084         stats->ipackets = rx_total;
1085         stats->opackets = tx_total;
1086         stats->ibytes = rx_total_bytes;
1087         stats->obytes = tx_total_bytes;
1088         stats->oerrors = tx_err_total;
1089
1090         return 0;
1091 }
1092
1093 static void
1094 eth_stats_reset(struct rte_eth_dev *dev)
1095 {
1096         uint16_t i;
1097         uint16_t nb_rx = dev->data->nb_rx_queues;
1098         uint16_t nb_tx = dev->data->nb_tx_queues;
1099
1100         for (i = 0; i < nb_rx; i++) {
1101                 struct szedata2_rx_queue *rxq = dev->data->rx_queues[i];
1102                 rxq->rx_pkts = 0;
1103                 rxq->rx_bytes = 0;
1104                 rxq->err_pkts = 0;
1105         }
1106         for (i = 0; i < nb_tx; i++) {
1107                 struct szedata2_tx_queue *txq = dev->data->tx_queues[i];
1108                 txq->tx_pkts = 0;
1109                 txq->tx_bytes = 0;
1110                 txq->err_pkts = 0;
1111         }
1112 }
1113
1114 static void
1115 eth_rx_queue_release(void *q)
1116 {
1117         struct szedata2_rx_queue *rxq = (struct szedata2_rx_queue *)q;
1118
1119         if (rxq != NULL) {
1120                 if (rxq->sze != NULL)
1121                         szedata_close(rxq->sze);
1122                 rte_free(rxq);
1123         }
1124 }
1125
1126 static void
1127 eth_tx_queue_release(void *q)
1128 {
1129         struct szedata2_tx_queue *txq = (struct szedata2_tx_queue *)q;
1130
1131         if (txq != NULL) {
1132                 if (txq->sze != NULL)
1133                         szedata_close(txq->sze);
1134                 rte_free(txq);
1135         }
1136 }
1137
1138 static void
1139 eth_dev_close(struct rte_eth_dev *dev)
1140 {
1141         uint16_t i;
1142         uint16_t nb_rx = dev->data->nb_rx_queues;
1143         uint16_t nb_tx = dev->data->nb_tx_queues;
1144
1145         eth_dev_stop(dev);
1146
1147         for (i = 0; i < nb_rx; i++) {
1148                 eth_rx_queue_release(dev->data->rx_queues[i]);
1149                 dev->data->rx_queues[i] = NULL;
1150         }
1151         dev->data->nb_rx_queues = 0;
1152         for (i = 0; i < nb_tx; i++) {
1153                 eth_tx_queue_release(dev->data->tx_queues[i]);
1154                 dev->data->tx_queues[i] = NULL;
1155         }
1156         dev->data->nb_tx_queues = 0;
1157 }
1158
1159 /**
1160  * Function takes value from first IBUF status register.
1161  * Values in IBUF and OBUF should be same.
1162  *
1163  * @param internals
1164  *     Pointer to device private structure.
1165  * @return
1166  *     Link speed constant.
1167  */
1168 static inline enum szedata2_link_speed
1169 get_link_speed(const struct pmd_internals *internals)
1170 {
1171         const volatile struct szedata2_ibuf *ibuf =
1172                 ibuf_ptr_by_index(internals->pci_rsc, 0);
1173         uint32_t speed = (szedata2_read32(&ibuf->ibuf_st) & 0x70) >> 4;
1174         switch (speed) {
1175         case 0x03:
1176                 return SZEDATA2_LINK_SPEED_10G;
1177         case 0x04:
1178                 return SZEDATA2_LINK_SPEED_40G;
1179         case 0x05:
1180                 return SZEDATA2_LINK_SPEED_100G;
1181         default:
1182                 return SZEDATA2_LINK_SPEED_DEFAULT;
1183         }
1184 }
1185
1186 static int
1187 eth_link_update(struct rte_eth_dev *dev,
1188                 int wait_to_complete __rte_unused)
1189 {
1190         struct rte_eth_link link;
1191         struct pmd_internals *internals = (struct pmd_internals *)
1192                 dev->data->dev_private;
1193         const volatile struct szedata2_ibuf *ibuf;
1194         uint32_t i;
1195         bool link_is_up = false;
1196
1197         memset(&link, 0, sizeof(link));
1198
1199         switch (get_link_speed(internals)) {
1200         case SZEDATA2_LINK_SPEED_10G:
1201                 link.link_speed = ETH_SPEED_NUM_10G;
1202                 break;
1203         case SZEDATA2_LINK_SPEED_40G:
1204                 link.link_speed = ETH_SPEED_NUM_40G;
1205                 break;
1206         case SZEDATA2_LINK_SPEED_100G:
1207                 link.link_speed = ETH_SPEED_NUM_100G;
1208                 break;
1209         default:
1210                 link.link_speed = ETH_SPEED_NUM_10G;
1211                 break;
1212         }
1213
1214         /* szedata2 uses only full duplex */
1215         link.link_duplex = ETH_LINK_FULL_DUPLEX;
1216
1217         for (i = 0; i < szedata2_ibuf_count; i++) {
1218                 ibuf = ibuf_ptr_by_index(internals->pci_rsc, i);
1219                 /*
1220                  * Link is considered up if at least one ibuf is enabled
1221                  * and up.
1222                  */
1223                 if (ibuf_is_enabled(ibuf) && ibuf_is_link_up(ibuf)) {
1224                         link_is_up = true;
1225                         break;
1226                 }
1227         }
1228
1229         link.link_status = link_is_up ? ETH_LINK_UP : ETH_LINK_DOWN;
1230
1231         link.link_autoneg = ETH_LINK_FIXED;
1232
1233         rte_eth_linkstatus_set(dev, &link);
1234         return 0;
1235 }
1236
1237 static int
1238 eth_dev_set_link_up(struct rte_eth_dev *dev)
1239 {
1240         struct pmd_internals *internals = (struct pmd_internals *)
1241                 dev->data->dev_private;
1242         uint32_t i;
1243
1244         for (i = 0; i < szedata2_ibuf_count; i++)
1245                 ibuf_enable(ibuf_ptr_by_index(internals->pci_rsc, i));
1246         for (i = 0; i < szedata2_obuf_count; i++)
1247                 obuf_enable(obuf_ptr_by_index(internals->pci_rsc, i));
1248         return 0;
1249 }
1250
1251 static int
1252 eth_dev_set_link_down(struct rte_eth_dev *dev)
1253 {
1254         struct pmd_internals *internals = (struct pmd_internals *)
1255                 dev->data->dev_private;
1256         uint32_t i;
1257
1258         for (i = 0; i < szedata2_ibuf_count; i++)
1259                 ibuf_disable(ibuf_ptr_by_index(internals->pci_rsc, i));
1260         for (i = 0; i < szedata2_obuf_count; i++)
1261                 obuf_disable(obuf_ptr_by_index(internals->pci_rsc, i));
1262         return 0;
1263 }
1264
1265 static int
1266 eth_rx_queue_setup(struct rte_eth_dev *dev,
1267                 uint16_t rx_queue_id,
1268                 uint16_t nb_rx_desc __rte_unused,
1269                 unsigned int socket_id,
1270                 const struct rte_eth_rxconf *rx_conf __rte_unused,
1271                 struct rte_mempool *mb_pool)
1272 {
1273         struct pmd_internals *internals = dev->data->dev_private;
1274         struct szedata2_rx_queue *rxq;
1275         int ret;
1276         uint32_t rx = 1 << rx_queue_id;
1277         uint32_t tx = 0;
1278
1279         if (dev->data->rx_queues[rx_queue_id] != NULL) {
1280                 eth_rx_queue_release(dev->data->rx_queues[rx_queue_id]);
1281                 dev->data->rx_queues[rx_queue_id] = NULL;
1282         }
1283
1284         rxq = rte_zmalloc_socket("szedata2 rx queue",
1285                         sizeof(struct szedata2_rx_queue),
1286                         RTE_CACHE_LINE_SIZE, socket_id);
1287         if (rxq == NULL) {
1288                 RTE_LOG(ERR, PMD, "rte_zmalloc_socket() failed for rx queue id "
1289                                 "%" PRIu16 "!\n", rx_queue_id);
1290                 return -ENOMEM;
1291         }
1292
1293         rxq->sze = szedata_open(internals->sze_dev);
1294         if (rxq->sze == NULL) {
1295                 RTE_LOG(ERR, PMD, "szedata_open() failed for rx queue id "
1296                                 "%" PRIu16 "!\n", rx_queue_id);
1297                 eth_rx_queue_release(rxq);
1298                 return -EINVAL;
1299         }
1300         ret = szedata_subscribe3(rxq->sze, &rx, &tx);
1301         if (ret != 0 || rx == 0) {
1302                 RTE_LOG(ERR, PMD, "szedata_subscribe3() failed for rx queue id "
1303                                 "%" PRIu16 "!\n", rx_queue_id);
1304                 eth_rx_queue_release(rxq);
1305                 return -EINVAL;
1306         }
1307         rxq->rx_channel = rx_queue_id;
1308         rxq->in_port = dev->data->port_id;
1309         rxq->mb_pool = mb_pool;
1310         rxq->rx_pkts = 0;
1311         rxq->rx_bytes = 0;
1312         rxq->err_pkts = 0;
1313
1314         dev->data->rx_queues[rx_queue_id] = rxq;
1315
1316         RTE_LOG(DEBUG, PMD, "Configured rx queue id %" PRIu16 " on socket "
1317                         "%u.\n", rx_queue_id, socket_id);
1318
1319         return 0;
1320 }
1321
1322 static int
1323 eth_tx_queue_setup(struct rte_eth_dev *dev,
1324                 uint16_t tx_queue_id,
1325                 uint16_t nb_tx_desc __rte_unused,
1326                 unsigned int socket_id,
1327                 const struct rte_eth_txconf *tx_conf __rte_unused)
1328 {
1329         struct pmd_internals *internals = dev->data->dev_private;
1330         struct szedata2_tx_queue *txq;
1331         int ret;
1332         uint32_t rx = 0;
1333         uint32_t tx = 1 << tx_queue_id;
1334
1335         if (dev->data->tx_queues[tx_queue_id] != NULL) {
1336                 eth_tx_queue_release(dev->data->tx_queues[tx_queue_id]);
1337                 dev->data->tx_queues[tx_queue_id] = NULL;
1338         }
1339
1340         txq = rte_zmalloc_socket("szedata2 tx queue",
1341                         sizeof(struct szedata2_tx_queue),
1342                         RTE_CACHE_LINE_SIZE, socket_id);
1343         if (txq == NULL) {
1344                 RTE_LOG(ERR, PMD, "rte_zmalloc_socket() failed for tx queue id "
1345                                 "%" PRIu16 "!\n", tx_queue_id);
1346                 return -ENOMEM;
1347         }
1348
1349         txq->sze = szedata_open(internals->sze_dev);
1350         if (txq->sze == NULL) {
1351                 RTE_LOG(ERR, PMD, "szedata_open() failed for tx queue id "
1352                                 "%" PRIu16 "!\n", tx_queue_id);
1353                 eth_tx_queue_release(txq);
1354                 return -EINVAL;
1355         }
1356         ret = szedata_subscribe3(txq->sze, &rx, &tx);
1357         if (ret != 0 || tx == 0) {
1358                 RTE_LOG(ERR, PMD, "szedata_subscribe3() failed for tx queue id "
1359                                 "%" PRIu16 "!\n", tx_queue_id);
1360                 eth_tx_queue_release(txq);
1361                 return -EINVAL;
1362         }
1363         txq->tx_channel = tx_queue_id;
1364         txq->tx_pkts = 0;
1365         txq->tx_bytes = 0;
1366         txq->err_pkts = 0;
1367
1368         dev->data->tx_queues[tx_queue_id] = txq;
1369
1370         RTE_LOG(DEBUG, PMD, "Configured tx queue id %" PRIu16 " on socket "
1371                         "%u.\n", tx_queue_id, socket_id);
1372
1373         return 0;
1374 }
1375
1376 static void
1377 eth_mac_addr_set(struct rte_eth_dev *dev __rte_unused,
1378                 struct ether_addr *mac_addr __rte_unused)
1379 {
1380 }
1381
1382 static void
1383 eth_promiscuous_enable(struct rte_eth_dev *dev)
1384 {
1385         struct pmd_internals *internals = (struct pmd_internals *)
1386                 dev->data->dev_private;
1387         uint32_t i;
1388
1389         for (i = 0; i < szedata2_ibuf_count; i++) {
1390                 ibuf_mac_mode_write(ibuf_ptr_by_index(internals->pci_rsc, i),
1391                                 SZEDATA2_MAC_CHMODE_PROMISC);
1392         }
1393 }
1394
1395 static void
1396 eth_promiscuous_disable(struct rte_eth_dev *dev)
1397 {
1398         struct pmd_internals *internals = (struct pmd_internals *)
1399                 dev->data->dev_private;
1400         uint32_t i;
1401
1402         for (i = 0; i < szedata2_ibuf_count; i++) {
1403                 ibuf_mac_mode_write(ibuf_ptr_by_index(internals->pci_rsc, i),
1404                                 SZEDATA2_MAC_CHMODE_ONLY_VALID);
1405         }
1406 }
1407
1408 static void
1409 eth_allmulticast_enable(struct rte_eth_dev *dev)
1410 {
1411         struct pmd_internals *internals = (struct pmd_internals *)
1412                 dev->data->dev_private;
1413         uint32_t i;
1414
1415         for (i = 0; i < szedata2_ibuf_count; i++) {
1416                 ibuf_mac_mode_write(ibuf_ptr_by_index(internals->pci_rsc, i),
1417                                 SZEDATA2_MAC_CHMODE_ALL_MULTICAST);
1418         }
1419 }
1420
1421 static void
1422 eth_allmulticast_disable(struct rte_eth_dev *dev)
1423 {
1424         struct pmd_internals *internals = (struct pmd_internals *)
1425                 dev->data->dev_private;
1426         uint32_t i;
1427
1428         for (i = 0; i < szedata2_ibuf_count; i++) {
1429                 ibuf_mac_mode_write(ibuf_ptr_by_index(internals->pci_rsc, i),
1430                                 SZEDATA2_MAC_CHMODE_ONLY_VALID);
1431         }
1432 }
1433
1434 static const struct eth_dev_ops ops = {
1435         .dev_start          = eth_dev_start,
1436         .dev_stop           = eth_dev_stop,
1437         .dev_set_link_up    = eth_dev_set_link_up,
1438         .dev_set_link_down  = eth_dev_set_link_down,
1439         .dev_close          = eth_dev_close,
1440         .dev_configure      = eth_dev_configure,
1441         .dev_infos_get      = eth_dev_info,
1442         .promiscuous_enable   = eth_promiscuous_enable,
1443         .promiscuous_disable  = eth_promiscuous_disable,
1444         .allmulticast_enable  = eth_allmulticast_enable,
1445         .allmulticast_disable = eth_allmulticast_disable,
1446         .rx_queue_start     = eth_rx_queue_start,
1447         .rx_queue_stop      = eth_rx_queue_stop,
1448         .tx_queue_start     = eth_tx_queue_start,
1449         .tx_queue_stop      = eth_tx_queue_stop,
1450         .rx_queue_setup     = eth_rx_queue_setup,
1451         .tx_queue_setup     = eth_tx_queue_setup,
1452         .rx_queue_release   = eth_rx_queue_release,
1453         .tx_queue_release   = eth_tx_queue_release,
1454         .link_update        = eth_link_update,
1455         .stats_get          = eth_stats_get,
1456         .stats_reset        = eth_stats_reset,
1457         .mac_addr_set       = eth_mac_addr_set,
1458 };
1459
1460 /*
1461  * This function goes through sysfs and looks for an index of szedata2
1462  * device file (/dev/szedataIIX, where X is the index).
1463  *
1464  * @return
1465  *           0 on success
1466  *          -1 on error
1467  */
1468 static int
1469 get_szedata2_index(const struct rte_pci_addr *pcislot_addr, uint32_t *index)
1470 {
1471         DIR *dir;
1472         struct dirent *entry;
1473         int ret;
1474         uint32_t tmp_index;
1475         FILE *fd;
1476         char pcislot_path[PATH_MAX];
1477         uint32_t domain;
1478         uint32_t bus;
1479         uint32_t devid;
1480         uint32_t function;
1481
1482         dir = opendir("/sys/class/combo");
1483         if (dir == NULL)
1484                 return -1;
1485
1486         /*
1487          * Iterate through all combosixX directories.
1488          * When the value in /sys/class/combo/combosixX/device/pcislot
1489          * file is the location of the ethernet device dev, "X" is the
1490          * index of the device.
1491          */
1492         while ((entry = readdir(dir)) != NULL) {
1493                 ret = sscanf(entry->d_name, "combosix%u", &tmp_index);
1494                 if (ret != 1)
1495                         continue;
1496
1497                 snprintf(pcislot_path, PATH_MAX,
1498                         "/sys/class/combo/combosix%u/device/pcislot",
1499                         tmp_index);
1500
1501                 fd = fopen(pcislot_path, "r");
1502                 if (fd == NULL)
1503                         continue;
1504
1505                 ret = fscanf(fd, "%4" PRIx16 ":%2" PRIx8 ":%2" PRIx8 ".%" PRIx8,
1506                                 &domain, &bus, &devid, &function);
1507                 fclose(fd);
1508                 if (ret != 4)
1509                         continue;
1510
1511                 if (pcislot_addr->domain == domain &&
1512                                 pcislot_addr->bus == bus &&
1513                                 pcislot_addr->devid == devid &&
1514                                 pcislot_addr->function == function) {
1515                         *index = tmp_index;
1516                         closedir(dir);
1517                         return 0;
1518                 }
1519         }
1520
1521         closedir(dir);
1522         return -1;
1523 }
1524
1525 static int
1526 rte_szedata2_eth_dev_init(struct rte_eth_dev *dev)
1527 {
1528         struct rte_eth_dev_data *data = dev->data;
1529         struct pmd_internals *internals = (struct pmd_internals *)
1530                 data->dev_private;
1531         struct szedata *szedata_temp;
1532         int ret;
1533         uint32_t szedata2_index;
1534         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1535         struct rte_pci_addr *pci_addr = &pci_dev->addr;
1536         struct rte_mem_resource *pci_rsc =
1537                 &pci_dev->mem_resource[PCI_RESOURCE_NUMBER];
1538         char rsc_filename[PATH_MAX];
1539         void *pci_resource_ptr = NULL;
1540         int fd;
1541
1542         RTE_LOG(INFO, PMD, "Initializing szedata2 device (" PCI_PRI_FMT ")\n",
1543                         pci_addr->domain, pci_addr->bus, pci_addr->devid,
1544                         pci_addr->function);
1545
1546         /* Get index of szedata2 device file and create path to device file */
1547         ret = get_szedata2_index(pci_addr, &szedata2_index);
1548         if (ret != 0) {
1549                 RTE_LOG(ERR, PMD, "Failed to get szedata2 device index!\n");
1550                 return -ENODEV;
1551         }
1552         snprintf(internals->sze_dev, PATH_MAX, SZEDATA2_DEV_PATH_FMT,
1553                         szedata2_index);
1554
1555         RTE_LOG(INFO, PMD, "SZEDATA2 path: %s\n", internals->sze_dev);
1556
1557         /*
1558          * Get number of available DMA RX and TX channels, which is maximum
1559          * number of queues that can be created and store it in private device
1560          * data structure.
1561          */
1562         szedata_temp = szedata_open(internals->sze_dev);
1563         if (szedata_temp == NULL) {
1564                 RTE_LOG(ERR, PMD, "szedata_open(): failed to open %s",
1565                                 internals->sze_dev);
1566                 return -EINVAL;
1567         }
1568         internals->max_rx_queues = szedata_ifaces_available(szedata_temp,
1569                         SZE2_DIR_RX);
1570         internals->max_tx_queues = szedata_ifaces_available(szedata_temp,
1571                         SZE2_DIR_TX);
1572         szedata_close(szedata_temp);
1573
1574         RTE_LOG(INFO, PMD, "Available DMA channels RX: %u TX: %u\n",
1575                         internals->max_rx_queues, internals->max_tx_queues);
1576
1577         /* Set rx, tx burst functions */
1578         if (data->scattered_rx == 1)
1579                 dev->rx_pkt_burst = eth_szedata2_rx_scattered;
1580         else
1581                 dev->rx_pkt_burst = eth_szedata2_rx;
1582         dev->tx_pkt_burst = eth_szedata2_tx;
1583
1584         /* Set function callbacks for Ethernet API */
1585         dev->dev_ops = &ops;
1586
1587         rte_eth_copy_pci_info(dev, pci_dev);
1588
1589         /* mmap pci resource0 file to rte_mem_resource structure */
1590         if (pci_dev->mem_resource[PCI_RESOURCE_NUMBER].phys_addr ==
1591                         0) {
1592                 RTE_LOG(ERR, PMD, "Missing resource%u file\n",
1593                                 PCI_RESOURCE_NUMBER);
1594                 return -EINVAL;
1595         }
1596         snprintf(rsc_filename, PATH_MAX,
1597                 "%s/" PCI_PRI_FMT "/resource%u", rte_pci_get_sysfs_path(),
1598                 pci_addr->domain, pci_addr->bus,
1599                 pci_addr->devid, pci_addr->function, PCI_RESOURCE_NUMBER);
1600         fd = open(rsc_filename, O_RDWR);
1601         if (fd < 0) {
1602                 RTE_LOG(ERR, PMD, "Could not open file %s\n", rsc_filename);
1603                 return -EINVAL;
1604         }
1605
1606         pci_resource_ptr = mmap(0,
1607                         pci_dev->mem_resource[PCI_RESOURCE_NUMBER].len,
1608                         PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
1609         close(fd);
1610         if (pci_resource_ptr == MAP_FAILED) {
1611                 RTE_LOG(ERR, PMD, "Could not mmap file %s (fd = %d)\n",
1612                                 rsc_filename, fd);
1613                 return -EINVAL;
1614         }
1615         pci_dev->mem_resource[PCI_RESOURCE_NUMBER].addr = pci_resource_ptr;
1616         internals->pci_rsc = pci_rsc;
1617
1618         RTE_LOG(DEBUG, PMD, "resource%u phys_addr = 0x%llx len = %llu "
1619                         "virt addr = %llx\n", PCI_RESOURCE_NUMBER,
1620                         (unsigned long long)pci_rsc->phys_addr,
1621                         (unsigned long long)pci_rsc->len,
1622                         (unsigned long long)pci_rsc->addr);
1623
1624         /* Get link state */
1625         eth_link_update(dev, 0);
1626
1627         /* Allocate space for one mac address */
1628         data->mac_addrs = rte_zmalloc(data->name, sizeof(struct ether_addr),
1629                         RTE_CACHE_LINE_SIZE);
1630         if (data->mac_addrs == NULL) {
1631                 RTE_LOG(ERR, PMD, "Could not alloc space for MAC address!\n");
1632                 munmap(pci_dev->mem_resource[PCI_RESOURCE_NUMBER].addr,
1633                        pci_dev->mem_resource[PCI_RESOURCE_NUMBER].len);
1634                 return -EINVAL;
1635         }
1636
1637         ether_addr_copy(&eth_addr, data->mac_addrs);
1638
1639         /* At initial state COMBO card is in promiscuous mode so disable it */
1640         eth_promiscuous_disable(dev);
1641
1642         RTE_LOG(INFO, PMD, "szedata2 device ("
1643                         PCI_PRI_FMT ") successfully initialized\n",
1644                         pci_addr->domain, pci_addr->bus, pci_addr->devid,
1645                         pci_addr->function);
1646
1647         return 0;
1648 }
1649
1650 static int
1651 rte_szedata2_eth_dev_uninit(struct rte_eth_dev *dev)
1652 {
1653         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1654         struct rte_pci_addr *pci_addr = &pci_dev->addr;
1655
1656         rte_free(dev->data->mac_addrs);
1657         dev->data->mac_addrs = NULL;
1658         munmap(pci_dev->mem_resource[PCI_RESOURCE_NUMBER].addr,
1659                pci_dev->mem_resource[PCI_RESOURCE_NUMBER].len);
1660
1661         RTE_LOG(INFO, PMD, "szedata2 device ("
1662                         PCI_PRI_FMT ") successfully uninitialized\n",
1663                         pci_addr->domain, pci_addr->bus, pci_addr->devid,
1664                         pci_addr->function);
1665
1666         return 0;
1667 }
1668
1669 static const struct rte_pci_id rte_szedata2_pci_id_table[] = {
1670         {
1671                 RTE_PCI_DEVICE(PCI_VENDOR_ID_NETCOPE,
1672                                 PCI_DEVICE_ID_NETCOPE_COMBO80G)
1673         },
1674         {
1675                 RTE_PCI_DEVICE(PCI_VENDOR_ID_NETCOPE,
1676                                 PCI_DEVICE_ID_NETCOPE_COMBO100G)
1677         },
1678         {
1679                 RTE_PCI_DEVICE(PCI_VENDOR_ID_NETCOPE,
1680                                 PCI_DEVICE_ID_NETCOPE_COMBO100G2)
1681         },
1682         {
1683                 .vendor_id = 0,
1684         }
1685 };
1686
1687 static int szedata2_eth_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
1688         struct rte_pci_device *pci_dev)
1689 {
1690         return rte_eth_dev_pci_generic_probe(pci_dev,
1691                 sizeof(struct pmd_internals), rte_szedata2_eth_dev_init);
1692 }
1693
1694 static int szedata2_eth_pci_remove(struct rte_pci_device *pci_dev)
1695 {
1696         return rte_eth_dev_pci_generic_remove(pci_dev,
1697                 rte_szedata2_eth_dev_uninit);
1698 }
1699
1700 static struct rte_pci_driver szedata2_eth_driver = {
1701         .id_table = rte_szedata2_pci_id_table,
1702         .probe = szedata2_eth_pci_probe,
1703         .remove = szedata2_eth_pci_remove,
1704 };
1705
1706 RTE_PMD_REGISTER_PCI(RTE_SZEDATA2_DRIVER_NAME, szedata2_eth_driver);
1707 RTE_PMD_REGISTER_PCI_TABLE(RTE_SZEDATA2_DRIVER_NAME, rte_szedata2_pci_id_table);
1708 RTE_PMD_REGISTER_KMOD_DEP(RTE_SZEDATA2_DRIVER_NAME,
1709         "* combo6core & combov3 & szedata2 & szedata2_cv3");