a0116752ebef51d73aa22131e190f233923d2c74
[dpdk.git] / drivers / net / mrvl / mrvl_ethdev.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2017 Marvell International Ltd.
5  *   Copyright(c) 2017 Semihalf.
6  *   All rights reserved.
7  *
8  *   Redistribution and use in source and binary forms, with or without
9  *   modification, are permitted provided that the following conditions
10  *   are met:
11  *
12  *     * Redistributions of source code must retain the above copyright
13  *       notice, this list of conditions and the following disclaimer.
14  *     * Redistributions in binary form must reproduce the above copyright
15  *       notice, this list of conditions and the following disclaimer in
16  *       the documentation and/or other materials provided with the
17  *       distribution.
18  *     * Neither the name of Semihalf nor the names of its
19  *       contributors may be used to endorse or promote products derived
20  *       from this software without specific prior written permission.
21  *
22  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 #include <rte_ethdev.h>
36 #include <rte_kvargs.h>
37 #include <rte_log.h>
38 #include <rte_malloc.h>
39 #include <rte_bus_vdev.h>
40
41 /* Unluckily, container_of is defined by both DPDK and MUSDK,
42  * we'll declare only one version.
43  *
44  * Note that it is not used in this PMD anyway.
45  */
46 #ifdef container_of
47 #undef container_of
48 #endif
49
50 #include <fcntl.h>
51 #include <linux/ethtool.h>
52 #include <linux/sockios.h>
53 #include <net/if.h>
54 #include <net/if_arp.h>
55 #include <sys/ioctl.h>
56 #include <sys/socket.h>
57 #include <sys/stat.h>
58 #include <sys/types.h>
59
60 #include "mrvl_ethdev.h"
61 #include "mrvl_qos.h"
62
63 /* bitmask with reserved hifs */
64 #define MRVL_MUSDK_HIFS_RESERVED 0x0F
65 /* bitmask with reserved bpools */
66 #define MRVL_MUSDK_BPOOLS_RESERVED 0x07
67 /* bitmask with reserved kernel RSS tables */
68 #define MRVL_MUSDK_RSS_RESERVED 0x01
69 /* maximum number of available hifs */
70 #define MRVL_MUSDK_HIFS_MAX 9
71
72 /* prefetch shift */
73 #define MRVL_MUSDK_PREFETCH_SHIFT 2
74
75 /* TCAM has 25 entries reserved for uc/mc filter entries */
76 #define MRVL_MAC_ADDRS_MAX 25
77 #define MRVL_MATCH_LEN 16
78 #define MRVL_PKT_EFFEC_OFFS (MRVL_PKT_OFFS + MV_MH_SIZE)
79 /* Maximum allowable packet size */
80 #define MRVL_PKT_SIZE_MAX (10240 - MV_MH_SIZE)
81
82 #define MRVL_IFACE_NAME_ARG "iface"
83 #define MRVL_CFG_ARG "cfg"
84
85 #define MRVL_BURST_SIZE 64
86
87 #define MRVL_ARP_LENGTH 28
88
89 #define MRVL_COOKIE_ADDR_INVALID ~0ULL
90
91 #define MRVL_COOKIE_HIGH_ADDR_SHIFT     (sizeof(pp2_cookie_t) * 8)
92 #define MRVL_COOKIE_HIGH_ADDR_MASK      (~0ULL << MRVL_COOKIE_HIGH_ADDR_SHIFT)
93
94 /* Memory size (in bytes) for MUSDK dma buffers */
95 #define MRVL_MUSDK_DMA_MEMSIZE 41943040
96
97 static const char * const valid_args[] = {
98         MRVL_IFACE_NAME_ARG,
99         MRVL_CFG_ARG,
100         NULL
101 };
102
103 static int used_hifs = MRVL_MUSDK_HIFS_RESERVED;
104 static struct pp2_hif *hifs[RTE_MAX_LCORE];
105 static int used_bpools[PP2_NUM_PKT_PROC] = {
106         MRVL_MUSDK_BPOOLS_RESERVED,
107         MRVL_MUSDK_BPOOLS_RESERVED
108 };
109
110 struct pp2_bpool *mrvl_port_to_bpool_lookup[RTE_MAX_ETHPORTS];
111 int mrvl_port_bpool_size[PP2_NUM_PKT_PROC][PP2_BPOOL_NUM_POOLS][RTE_MAX_LCORE];
112 uint64_t cookie_addr_high = MRVL_COOKIE_ADDR_INVALID;
113
114 struct mrvl_ifnames {
115         const char *names[PP2_NUM_ETH_PPIO * PP2_NUM_PKT_PROC];
116         int idx;
117 };
118
119 /*
120  * To use buffer harvesting based on loopback port shadow queue structure
121  * was introduced for buffers information bookkeeping.
122  *
123  * Before sending the packet, related buffer information (pp2_buff_inf) is
124  * stored in shadow queue. After packet is transmitted no longer used
125  * packet buffer is released back to it's original hardware pool,
126  * on condition it originated from interface.
127  * In case it  was generated by application itself i.e: mbuf->port field is
128  * 0xff then its released to software mempool.
129  */
130 struct mrvl_shadow_txq {
131         int head;           /* write index - used when sending buffers */
132         int tail;           /* read index - used when releasing buffers */
133         u16 size;           /* queue occupied size */
134         u16 num_to_release; /* number of buffers sent, that can be released */
135         struct buff_release_entry ent[MRVL_PP2_TX_SHADOWQ_SIZE]; /* q entries */
136 };
137
138 struct mrvl_rxq {
139         struct mrvl_priv *priv;
140         struct rte_mempool *mp;
141         int queue_id;
142         int port_id;
143         int cksum_enabled;
144         uint64_t bytes_recv;
145         uint64_t drop_mac;
146 };
147
148 struct mrvl_txq {
149         struct mrvl_priv *priv;
150         int queue_id;
151         int port_id;
152         uint64_t bytes_sent;
153         struct mrvl_shadow_txq shadow_txqs[RTE_MAX_LCORE];
154 };
155
156 static int mrvl_lcore_first;
157 static int mrvl_lcore_last;
158 static int mrvl_dev_num;
159
160 static int mrvl_fill_bpool(struct mrvl_rxq *rxq, int num);
161 static inline void mrvl_free_sent_buffers(struct pp2_ppio *ppio,
162                         struct pp2_hif *hif, unsigned int core_id,
163                         struct mrvl_shadow_txq *sq, int qid, int force);
164
165 static inline int
166 mrvl_get_bpool_size(int pp2_id, int pool_id)
167 {
168         int i;
169         int size = 0;
170
171         for (i = mrvl_lcore_first; i <= mrvl_lcore_last; i++)
172                 size += mrvl_port_bpool_size[pp2_id][pool_id][i];
173
174         return size;
175 }
176
177 static inline int
178 mrvl_reserve_bit(int *bitmap, int max)
179 {
180         int n = sizeof(*bitmap) * 8 - __builtin_clz(*bitmap);
181
182         if (n >= max)
183                 return -1;
184
185         *bitmap |= 1 << n;
186
187         return n;
188 }
189
190 static int
191 mrvl_init_hif(int core_id)
192 {
193         struct pp2_hif_params params;
194         char match[MRVL_MATCH_LEN];
195         int ret;
196
197         ret = mrvl_reserve_bit(&used_hifs, MRVL_MUSDK_HIFS_MAX);
198         if (ret < 0) {
199                 RTE_LOG(ERR, PMD, "Failed to allocate hif %d\n", core_id);
200                 return ret;
201         }
202
203         snprintf(match, sizeof(match), "hif-%d", ret);
204         memset(&params, 0, sizeof(params));
205         params.match = match;
206         params.out_size = MRVL_PP2_AGGR_TXQD_MAX;
207         ret = pp2_hif_init(&params, &hifs[core_id]);
208         if (ret) {
209                 RTE_LOG(ERR, PMD, "Failed to initialize hif %d\n", core_id);
210                 return ret;
211         }
212
213         return 0;
214 }
215
216 static inline struct pp2_hif*
217 mrvl_get_hif(struct mrvl_priv *priv, int core_id)
218 {
219         int ret;
220
221         if (likely(hifs[core_id] != NULL))
222                 return hifs[core_id];
223
224         rte_spinlock_lock(&priv->lock);
225
226         ret = mrvl_init_hif(core_id);
227         if (ret < 0) {
228                 RTE_LOG(ERR, PMD, "Failed to allocate hif %d\n", core_id);
229                 goto out;
230         }
231
232         if (core_id < mrvl_lcore_first)
233                 mrvl_lcore_first = core_id;
234
235         if (core_id > mrvl_lcore_last)
236                 mrvl_lcore_last = core_id;
237 out:
238         rte_spinlock_unlock(&priv->lock);
239
240         return hifs[core_id];
241 }
242
243 /**
244  * Configure rss based on dpdk rss configuration.
245  *
246  * @param priv
247  *   Pointer to private structure.
248  * @param rss_conf
249  *   Pointer to RSS configuration.
250  *
251  * @return
252  *   0 on success, negative error value otherwise.
253  */
254 static int
255 mrvl_configure_rss(struct mrvl_priv *priv, struct rte_eth_rss_conf *rss_conf)
256 {
257         if (rss_conf->rss_key)
258                 RTE_LOG(WARNING, PMD, "Changing hash key is not supported\n");
259
260         if (rss_conf->rss_hf == 0) {
261                 priv->ppio_params.inqs_params.hash_type = PP2_PPIO_HASH_T_NONE;
262         } else if (rss_conf->rss_hf & ETH_RSS_IPV4) {
263                 priv->ppio_params.inqs_params.hash_type =
264                         PP2_PPIO_HASH_T_2_TUPLE;
265         } else if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) {
266                 priv->ppio_params.inqs_params.hash_type =
267                         PP2_PPIO_HASH_T_5_TUPLE;
268                 priv->rss_hf_tcp = 1;
269         } else if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV4_UDP) {
270                 priv->ppio_params.inqs_params.hash_type =
271                         PP2_PPIO_HASH_T_5_TUPLE;
272                 priv->rss_hf_tcp = 0;
273         } else {
274                 return -EINVAL;
275         }
276
277         return 0;
278 }
279
280 /**
281  * Ethernet device configuration.
282  *
283  * Prepare the driver for a given number of TX and RX queues and
284  * configure RSS.
285  *
286  * @param dev
287  *   Pointer to Ethernet device structure.
288  *
289  * @return
290  *   0 on success, negative error value otherwise.
291  */
292 static int
293 mrvl_dev_configure(struct rte_eth_dev *dev)
294 {
295         struct mrvl_priv *priv = dev->data->dev_private;
296         int ret;
297
298         if (dev->data->dev_conf.rxmode.mq_mode != ETH_MQ_RX_NONE &&
299             dev->data->dev_conf.rxmode.mq_mode != ETH_MQ_RX_RSS) {
300                 RTE_LOG(INFO, PMD, "Unsupported rx multi queue mode %d\n",
301                         dev->data->dev_conf.rxmode.mq_mode);
302                 return -EINVAL;
303         }
304
305         if (!dev->data->dev_conf.rxmode.hw_strip_crc) {
306                 RTE_LOG(INFO, PMD,
307                         "L2 CRC stripping is always enabled in hw\n");
308                 dev->data->dev_conf.rxmode.hw_strip_crc = 1;
309         }
310
311         if (dev->data->dev_conf.rxmode.hw_vlan_strip) {
312                 RTE_LOG(INFO, PMD, "VLAN stripping not supported\n");
313                 return -EINVAL;
314         }
315
316         if (dev->data->dev_conf.rxmode.split_hdr_size) {
317                 RTE_LOG(INFO, PMD, "Split headers not supported\n");
318                 return -EINVAL;
319         }
320
321         if (dev->data->dev_conf.rxmode.enable_scatter) {
322                 RTE_LOG(INFO, PMD, "RX Scatter/Gather not supported\n");
323                 return -EINVAL;
324         }
325
326         if (dev->data->dev_conf.rxmode.enable_lro) {
327                 RTE_LOG(INFO, PMD, "LRO not supported\n");
328                 return -EINVAL;
329         }
330
331         if (dev->data->dev_conf.rxmode.jumbo_frame)
332                 dev->data->mtu = dev->data->dev_conf.rxmode.max_rx_pkt_len -
333                                  ETHER_HDR_LEN - ETHER_CRC_LEN;
334
335         ret = mrvl_configure_rxqs(priv, dev->data->port_id,
336                                   dev->data->nb_rx_queues);
337         if (ret < 0)
338                 return ret;
339
340         priv->ppio_params.outqs_params.num_outqs = dev->data->nb_tx_queues;
341         priv->ppio_params.maintain_stats = 1;
342         priv->nb_rx_queues = dev->data->nb_rx_queues;
343
344         if (dev->data->nb_rx_queues == 1 &&
345             dev->data->dev_conf.rxmode.mq_mode == ETH_MQ_RX_RSS) {
346                 RTE_LOG(WARNING, PMD, "Disabling hash for 1 rx queue\n");
347                 priv->ppio_params.inqs_params.hash_type = PP2_PPIO_HASH_T_NONE;
348
349                 return 0;
350         }
351
352         return mrvl_configure_rss(priv,
353                                   &dev->data->dev_conf.rx_adv_conf.rss_conf);
354 }
355
356 /**
357  * DPDK callback to change the MTU.
358  *
359  * Setting the MTU affects hardware MRU (packets larger than the MRU
360  * will be dropped).
361  *
362  * @param dev
363  *   Pointer to Ethernet device structure.
364  * @param mtu
365  *   New MTU.
366  *
367  * @return
368  *   0 on success, negative error value otherwise.
369  */
370 static int
371 mrvl_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
372 {
373         struct mrvl_priv *priv = dev->data->dev_private;
374         /* extra MV_MH_SIZE bytes are required for Marvell tag */
375         uint16_t mru = mtu + MV_MH_SIZE + ETHER_HDR_LEN + ETHER_CRC_LEN;
376         int ret;
377
378         if (mtu < ETHER_MIN_MTU || mru > MRVL_PKT_SIZE_MAX)
379                 return -EINVAL;
380
381         if (!priv->ppio)
382                 return 0;
383
384         ret = pp2_ppio_set_mru(priv->ppio, mru);
385         if (ret)
386                 return ret;
387
388         return pp2_ppio_set_mtu(priv->ppio, mtu);
389 }
390
391 /**
392  * DPDK callback to bring the link up.
393  *
394  * @param dev
395  *   Pointer to Ethernet device structure.
396  *
397  * @return
398  *   0 on success, negative error value otherwise.
399  */
400 static int
401 mrvl_dev_set_link_up(struct rte_eth_dev *dev)
402 {
403         struct mrvl_priv *priv = dev->data->dev_private;
404         int ret;
405
406         if (!priv->ppio)
407                 return -EPERM;
408
409         ret = pp2_ppio_enable(priv->ppio);
410         if (ret)
411                 return ret;
412
413         /*
414          * mtu/mru can be updated if pp2_ppio_enable() was called at least once
415          * as pp2_ppio_enable() changes port->t_mode from default 0 to
416          * PP2_TRAFFIC_INGRESS_EGRESS.
417          *
418          * Set mtu to default DPDK value here.
419          */
420         ret = mrvl_mtu_set(dev, dev->data->mtu);
421         if (ret)
422                 pp2_ppio_disable(priv->ppio);
423
424         return ret;
425 }
426
427 /**
428  * DPDK callback to bring the link down.
429  *
430  * @param dev
431  *   Pointer to Ethernet device structure.
432  *
433  * @return
434  *   0 on success, negative error value otherwise.
435  */
436 static int
437 mrvl_dev_set_link_down(struct rte_eth_dev *dev)
438 {
439         struct mrvl_priv *priv = dev->data->dev_private;
440
441         if (!priv->ppio)
442                 return -EPERM;
443
444         return pp2_ppio_disable(priv->ppio);
445 }
446
447 /**
448  * DPDK callback to start the device.
449  *
450  * @param dev
451  *   Pointer to Ethernet device structure.
452  *
453  * @return
454  *   0 on success, negative errno value on failure.
455  */
456 static int
457 mrvl_dev_start(struct rte_eth_dev *dev)
458 {
459         struct mrvl_priv *priv = dev->data->dev_private;
460         char match[MRVL_MATCH_LEN];
461         int ret = 0, def_init_size;
462
463         snprintf(match, sizeof(match), "ppio-%d:%d",
464                  priv->pp_id, priv->ppio_id);
465         priv->ppio_params.match = match;
466
467         /*
468          * Calculate the minimum bpool size for refill feature as follows:
469          * 2 default burst sizes multiply by number of rx queues.
470          * If the bpool size will be below this value, new buffers will
471          * be added to the pool.
472          */
473         priv->bpool_min_size = priv->nb_rx_queues * MRVL_BURST_SIZE * 2;
474
475         /* In case initial bpool size configured in queues setup is
476          * smaller than minimum size add more buffers
477          */
478         def_init_size = priv->bpool_min_size + MRVL_BURST_SIZE * 2;
479         if (priv->bpool_init_size < def_init_size) {
480                 int buffs_to_add = def_init_size - priv->bpool_init_size;
481
482                 priv->bpool_init_size += buffs_to_add;
483                 ret = mrvl_fill_bpool(dev->data->rx_queues[0], buffs_to_add);
484                 if (ret)
485                         RTE_LOG(ERR, PMD, "Failed to add buffers to bpool\n");
486         }
487
488         /*
489          * Calculate the maximum bpool size for refill feature as follows:
490          * maximum number of descriptors in rx queue multiply by number
491          * of rx queues plus minimum bpool size.
492          * In case the bpool size will exceed this value, superfluous buffers
493          * will be removed
494          */
495         priv->bpool_max_size = (priv->nb_rx_queues * MRVL_PP2_RXD_MAX) +
496                                 priv->bpool_min_size;
497
498         ret = pp2_ppio_init(&priv->ppio_params, &priv->ppio);
499         if (ret) {
500                 RTE_LOG(ERR, PMD, "Failed to init ppio\n");
501                 return ret;
502         }
503
504         /*
505          * In case there are some some stale uc/mc mac addresses flush them
506          * here. It cannot be done during mrvl_dev_close() as port information
507          * is already gone at that point (due to pp2_ppio_deinit() in
508          * mrvl_dev_stop()).
509          */
510         if (!priv->uc_mc_flushed) {
511                 ret = pp2_ppio_flush_mac_addrs(priv->ppio, 1, 1);
512                 if (ret) {
513                         RTE_LOG(ERR, PMD,
514                                 "Failed to flush uc/mc filter list\n");
515                         goto out;
516                 }
517                 priv->uc_mc_flushed = 1;
518         }
519
520         if (!priv->vlan_flushed) {
521                 ret = pp2_ppio_flush_vlan(priv->ppio);
522                 if (ret) {
523                         RTE_LOG(ERR, PMD, "Failed to flush vlan list\n");
524                         /*
525                          * TODO
526                          * once pp2_ppio_flush_vlan() is supported jump to out
527                          * goto out;
528                          */
529                 }
530                 priv->vlan_flushed = 1;
531         }
532
533         /* For default QoS config, don't start classifier. */
534         if (mrvl_qos_cfg) {
535                 ret = mrvl_start_qos_mapping(priv);
536                 if (ret) {
537                         RTE_LOG(ERR, PMD, "Failed to setup QoS mapping\n");
538                         goto out;
539                 }
540         }
541
542         ret = mrvl_dev_set_link_up(dev);
543         if (ret) {
544                 RTE_LOG(ERR, PMD, "Failed to set link up\n");
545                 goto out;
546         }
547
548         return 0;
549 out:
550         RTE_LOG(ERR, PMD, "Failed to start device\n");
551         pp2_ppio_deinit(priv->ppio);
552         return ret;
553 }
554
555 /**
556  * Flush receive queues.
557  *
558  * @param dev
559  *   Pointer to Ethernet device structure.
560  */
561 static void
562 mrvl_flush_rx_queues(struct rte_eth_dev *dev)
563 {
564         int i;
565
566         RTE_LOG(INFO, PMD, "Flushing rx queues\n");
567         for (i = 0; i < dev->data->nb_rx_queues; i++) {
568                 int ret, num;
569
570                 do {
571                         struct mrvl_rxq *q = dev->data->rx_queues[i];
572                         struct pp2_ppio_desc descs[MRVL_PP2_RXD_MAX];
573
574                         num = MRVL_PP2_RXD_MAX;
575                         ret = pp2_ppio_recv(q->priv->ppio,
576                                             q->priv->rxq_map[q->queue_id].tc,
577                                             q->priv->rxq_map[q->queue_id].inq,
578                                             descs, (uint16_t *)&num);
579                 } while (ret == 0 && num);
580         }
581 }
582
583 /**
584  * Flush transmit shadow queues.
585  *
586  * @param dev
587  *   Pointer to Ethernet device structure.
588  */
589 static void
590 mrvl_flush_tx_shadow_queues(struct rte_eth_dev *dev)
591 {
592         int i, j;
593         struct mrvl_txq *txq;
594
595         RTE_LOG(INFO, PMD, "Flushing tx shadow queues\n");
596         for (i = 0; i < dev->data->nb_tx_queues; i++) {
597                 txq = (struct mrvl_txq *)dev->data->tx_queues[i];
598
599                 for (j = 0; j < RTE_MAX_LCORE; j++) {
600                         struct mrvl_shadow_txq *sq;
601
602                         if (!hifs[j])
603                                 continue;
604
605                         sq = &txq->shadow_txqs[j];
606                         mrvl_free_sent_buffers(txq->priv->ppio,
607                                 hifs[j], j, sq, txq->queue_id, 1);
608                         while (sq->tail != sq->head) {
609                                 uint64_t addr = cookie_addr_high |
610                                         sq->ent[sq->tail].buff.cookie;
611                                 rte_pktmbuf_free(
612                                         (struct rte_mbuf *)addr);
613                                 sq->tail = (sq->tail + 1) &
614                                             MRVL_PP2_TX_SHADOWQ_MASK;
615                         }
616                         memset(sq, 0, sizeof(*sq));
617                 }
618         }
619 }
620
621 /**
622  * Flush hardware bpool (buffer-pool).
623  *
624  * @param dev
625  *   Pointer to Ethernet device structure.
626  */
627 static void
628 mrvl_flush_bpool(struct rte_eth_dev *dev)
629 {
630         struct mrvl_priv *priv = dev->data->dev_private;
631         struct pp2_hif *hif;
632         uint32_t num;
633         int ret;
634         unsigned int core_id = rte_lcore_id();
635
636         if (core_id == LCORE_ID_ANY)
637                 core_id = 0;
638
639         hif = mrvl_get_hif(priv, core_id);
640
641         ret = pp2_bpool_get_num_buffs(priv->bpool, &num);
642         if (ret) {
643                 RTE_LOG(ERR, PMD, "Failed to get bpool buffers number\n");
644                 return;
645         }
646
647         while (num--) {
648                 struct pp2_buff_inf inf;
649                 uint64_t addr;
650
651                 ret = pp2_bpool_get_buff(hif, priv->bpool, &inf);
652                 if (ret)
653                         break;
654
655                 addr = cookie_addr_high | inf.cookie;
656                 rte_pktmbuf_free((struct rte_mbuf *)addr);
657         }
658 }
659
660 /**
661  * DPDK callback to stop the device.
662  *
663  * @param dev
664  *   Pointer to Ethernet device structure.
665  */
666 static void
667 mrvl_dev_stop(struct rte_eth_dev *dev)
668 {
669         struct mrvl_priv *priv = dev->data->dev_private;
670
671         mrvl_dev_set_link_down(dev);
672         mrvl_flush_rx_queues(dev);
673         mrvl_flush_tx_shadow_queues(dev);
674         if (priv->qos_tbl) {
675                 pp2_cls_qos_tbl_deinit(priv->qos_tbl);
676                 priv->qos_tbl = NULL;
677         }
678         pp2_ppio_deinit(priv->ppio);
679         priv->ppio = NULL;
680 }
681
682 /**
683  * DPDK callback to close the device.
684  *
685  * @param dev
686  *   Pointer to Ethernet device structure.
687  */
688 static void
689 mrvl_dev_close(struct rte_eth_dev *dev)
690 {
691         struct mrvl_priv *priv = dev->data->dev_private;
692         size_t i;
693
694         for (i = 0; i < priv->ppio_params.inqs_params.num_tcs; ++i) {
695                 struct pp2_ppio_tc_params *tc_params =
696                         &priv->ppio_params.inqs_params.tcs_params[i];
697
698                 if (tc_params->inqs_params) {
699                         rte_free(tc_params->inqs_params);
700                         tc_params->inqs_params = NULL;
701                 }
702         }
703
704         mrvl_flush_bpool(dev);
705 }
706
707 /**
708  * DPDK callback to retrieve physical link information.
709  *
710  * @param dev
711  *   Pointer to Ethernet device structure.
712  * @param wait_to_complete
713  *   Wait for request completion (ignored).
714  *
715  * @return
716  *   0 on success, negative error value otherwise.
717  */
718 static int
719 mrvl_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused)
720 {
721         /*
722          * TODO
723          * once MUSDK provides necessary API use it here
724          */
725         struct mrvl_priv *priv = dev->data->dev_private;
726         struct ethtool_cmd edata;
727         struct ifreq req;
728         int ret, fd, link_up;
729
730         if (!priv->ppio)
731                 return -EPERM;
732
733         edata.cmd = ETHTOOL_GSET;
734
735         strcpy(req.ifr_name, dev->data->name);
736         req.ifr_data = (void *)&edata;
737
738         fd = socket(AF_INET, SOCK_DGRAM, 0);
739         if (fd == -1)
740                 return -EFAULT;
741
742         ret = ioctl(fd, SIOCETHTOOL, &req);
743         if (ret == -1) {
744                 close(fd);
745                 return -EFAULT;
746         }
747
748         close(fd);
749
750         switch (ethtool_cmd_speed(&edata)) {
751         case SPEED_10:
752                 dev->data->dev_link.link_speed = ETH_SPEED_NUM_10M;
753                 break;
754         case SPEED_100:
755                 dev->data->dev_link.link_speed = ETH_SPEED_NUM_100M;
756                 break;
757         case SPEED_1000:
758                 dev->data->dev_link.link_speed = ETH_SPEED_NUM_1G;
759                 break;
760         case SPEED_10000:
761                 dev->data->dev_link.link_speed = ETH_SPEED_NUM_10G;
762                 break;
763         default:
764                 dev->data->dev_link.link_speed = ETH_SPEED_NUM_NONE;
765         }
766
767         dev->data->dev_link.link_duplex = edata.duplex ? ETH_LINK_FULL_DUPLEX :
768                                                          ETH_LINK_HALF_DUPLEX;
769         dev->data->dev_link.link_autoneg = edata.autoneg ? ETH_LINK_AUTONEG :
770                                                            ETH_LINK_FIXED;
771         pp2_ppio_get_link_state(priv->ppio, &link_up);
772         dev->data->dev_link.link_status = link_up ? ETH_LINK_UP : ETH_LINK_DOWN;
773
774         return 0;
775 }
776
777 /**
778  * DPDK callback to enable promiscuous mode.
779  *
780  * @param dev
781  *   Pointer to Ethernet device structure.
782  */
783 static void
784 mrvl_promiscuous_enable(struct rte_eth_dev *dev)
785 {
786         struct mrvl_priv *priv = dev->data->dev_private;
787         int ret;
788
789         if (!priv->ppio)
790                 return;
791
792         ret = pp2_ppio_set_promisc(priv->ppio, 1);
793         if (ret)
794                 RTE_LOG(ERR, PMD, "Failed to enable promiscuous mode\n");
795 }
796
797 /**
798  * DPDK callback to enable allmulti mode.
799  *
800  * @param dev
801  *   Pointer to Ethernet device structure.
802  */
803 static void
804 mrvl_allmulticast_enable(struct rte_eth_dev *dev)
805 {
806         struct mrvl_priv *priv = dev->data->dev_private;
807         int ret;
808
809         if (!priv->ppio)
810                 return;
811
812         ret = pp2_ppio_set_mc_promisc(priv->ppio, 1);
813         if (ret)
814                 RTE_LOG(ERR, PMD, "Failed enable all-multicast mode\n");
815 }
816
817 /**
818  * DPDK callback to disable promiscuous mode.
819  *
820  * @param dev
821  *   Pointer to Ethernet device structure.
822  */
823 static void
824 mrvl_promiscuous_disable(struct rte_eth_dev *dev)
825 {
826         struct mrvl_priv *priv = dev->data->dev_private;
827         int ret;
828
829         if (!priv->ppio)
830                 return;
831
832         ret = pp2_ppio_set_promisc(priv->ppio, 0);
833         if (ret)
834                 RTE_LOG(ERR, PMD, "Failed to disable promiscuous mode\n");
835 }
836
837 /**
838  * DPDK callback to disable allmulticast mode.
839  *
840  * @param dev
841  *   Pointer to Ethernet device structure.
842  */
843 static void
844 mrvl_allmulticast_disable(struct rte_eth_dev *dev)
845 {
846         struct mrvl_priv *priv = dev->data->dev_private;
847         int ret;
848
849         if (!priv->ppio)
850                 return;
851
852         ret = pp2_ppio_set_mc_promisc(priv->ppio, 0);
853         if (ret)
854                 RTE_LOG(ERR, PMD, "Failed to disable all-multicast mode\n");
855 }
856
857 /**
858  * DPDK callback to remove a MAC address.
859  *
860  * @param dev
861  *   Pointer to Ethernet device structure.
862  * @param index
863  *   MAC address index.
864  */
865 static void
866 mrvl_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
867 {
868         struct mrvl_priv *priv = dev->data->dev_private;
869         char buf[ETHER_ADDR_FMT_SIZE];
870         int ret;
871
872         if (!priv->ppio)
873                 return;
874
875         ret = pp2_ppio_remove_mac_addr(priv->ppio,
876                                        dev->data->mac_addrs[index].addr_bytes);
877         if (ret) {
878                 ether_format_addr(buf, sizeof(buf),
879                                   &dev->data->mac_addrs[index]);
880                 RTE_LOG(ERR, PMD, "Failed to remove mac %s\n", buf);
881         }
882 }
883
884 /**
885  * DPDK callback to add a MAC address.
886  *
887  * @param dev
888  *   Pointer to Ethernet device structure.
889  * @param mac_addr
890  *   MAC address to register.
891  * @param index
892  *   MAC address index.
893  * @param vmdq
894  *   VMDq pool index to associate address with (unused).
895  *
896  * @return
897  *   0 on success, negative error value otherwise.
898  */
899 static int
900 mrvl_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
901                   uint32_t index, uint32_t vmdq __rte_unused)
902 {
903         struct mrvl_priv *priv = dev->data->dev_private;
904         char buf[ETHER_ADDR_FMT_SIZE];
905         int ret;
906
907         if (index == 0)
908                 /* For setting index 0, mrvl_mac_addr_set() should be used.*/
909                 return -1;
910
911         if (!priv->ppio)
912                 return -EPERM;
913
914         /*
915          * Maximum number of uc addresses can be tuned via kernel module mvpp2x
916          * parameter uc_filter_max. Maximum number of mc addresses is then
917          * MRVL_MAC_ADDRS_MAX - uc_filter_max. Currently it defaults to 4 and
918          * 21 respectively.
919          *
920          * If more than uc_filter_max uc addresses were added to filter list
921          * then NIC will switch to promiscuous mode automatically.
922          *
923          * If more than MRVL_MAC_ADDRS_MAX - uc_filter_max number mc addresses
924          * were added to filter list then NIC will switch to all-multicast mode
925          * automatically.
926          */
927         ret = pp2_ppio_add_mac_addr(priv->ppio, mac_addr->addr_bytes);
928         if (ret) {
929                 ether_format_addr(buf, sizeof(buf), mac_addr);
930                 RTE_LOG(ERR, PMD, "Failed to add mac %s\n", buf);
931                 return -1;
932         }
933
934         return 0;
935 }
936
937 /**
938  * DPDK callback to set the primary MAC address.
939  *
940  * @param dev
941  *   Pointer to Ethernet device structure.
942  * @param mac_addr
943  *   MAC address to register.
944  */
945 static void
946 mrvl_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
947 {
948         struct mrvl_priv *priv = dev->data->dev_private;
949         int ret;
950
951         if (!priv->ppio)
952                 return;
953
954         ret = pp2_ppio_set_mac_addr(priv->ppio, mac_addr->addr_bytes);
955         if (ret) {
956                 char buf[ETHER_ADDR_FMT_SIZE];
957                 ether_format_addr(buf, sizeof(buf), mac_addr);
958                 RTE_LOG(ERR, PMD, "Failed to set mac to %s\n", buf);
959         }
960 }
961
962 /**
963  * DPDK callback to get device statistics.
964  *
965  * @param dev
966  *   Pointer to Ethernet device structure.
967  * @param stats
968  *   Stats structure output buffer.
969  *
970  * @return
971  *   0 on success, negative error value otherwise.
972  */
973 static int
974 mrvl_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
975 {
976         struct mrvl_priv *priv = dev->data->dev_private;
977         struct pp2_ppio_statistics ppio_stats;
978         uint64_t drop_mac = 0;
979         unsigned int i, idx, ret;
980
981         if (!priv->ppio)
982                 return -EPERM;
983
984         for (i = 0; i < dev->data->nb_rx_queues; i++) {
985                 struct mrvl_rxq *rxq = dev->data->rx_queues[i];
986                 struct pp2_ppio_inq_statistics rx_stats;
987
988                 if (!rxq)
989                         continue;
990
991                 idx = rxq->queue_id;
992                 if (unlikely(idx >= RTE_ETHDEV_QUEUE_STAT_CNTRS)) {
993                         RTE_LOG(ERR, PMD,
994                                 "rx queue %d stats out of range (0 - %d)\n",
995                                 idx, RTE_ETHDEV_QUEUE_STAT_CNTRS - 1);
996                         continue;
997                 }
998
999                 ret = pp2_ppio_inq_get_statistics(priv->ppio,
1000                                                   priv->rxq_map[idx].tc,
1001                                                   priv->rxq_map[idx].inq,
1002                                                   &rx_stats, 0);
1003                 if (unlikely(ret)) {
1004                         RTE_LOG(ERR, PMD,
1005                                 "Failed to update rx queue %d stats\n", idx);
1006                         break;
1007                 }
1008
1009                 stats->q_ibytes[idx] = rxq->bytes_recv;
1010                 stats->q_ipackets[idx] = rx_stats.enq_desc - rxq->drop_mac;
1011                 stats->q_errors[idx] = rx_stats.drop_early +
1012                                        rx_stats.drop_fullq +
1013                                        rx_stats.drop_bm +
1014                                        rxq->drop_mac;
1015                 stats->ibytes += rxq->bytes_recv;
1016                 drop_mac += rxq->drop_mac;
1017         }
1018
1019         for (i = 0; i < dev->data->nb_tx_queues; i++) {
1020                 struct mrvl_txq *txq = dev->data->tx_queues[i];
1021                 struct pp2_ppio_outq_statistics tx_stats;
1022
1023                 if (!txq)
1024                         continue;
1025
1026                 idx = txq->queue_id;
1027                 if (unlikely(idx >= RTE_ETHDEV_QUEUE_STAT_CNTRS)) {
1028                         RTE_LOG(ERR, PMD,
1029                                 "tx queue %d stats out of range (0 - %d)\n",
1030                                 idx, RTE_ETHDEV_QUEUE_STAT_CNTRS - 1);
1031                 }
1032
1033                 ret = pp2_ppio_outq_get_statistics(priv->ppio, idx,
1034                                                    &tx_stats, 0);
1035                 if (unlikely(ret)) {
1036                         RTE_LOG(ERR, PMD,
1037                                 "Failed to update tx queue %d stats\n", idx);
1038                         break;
1039                 }
1040
1041                 stats->q_opackets[idx] = tx_stats.deq_desc;
1042                 stats->q_obytes[idx] = txq->bytes_sent;
1043                 stats->obytes += txq->bytes_sent;
1044         }
1045
1046         ret = pp2_ppio_get_statistics(priv->ppio, &ppio_stats, 0);
1047         if (unlikely(ret)) {
1048                 RTE_LOG(ERR, PMD, "Failed to update port statistics\n");
1049                 return ret;
1050         }
1051
1052         stats->ipackets += ppio_stats.rx_packets - drop_mac;
1053         stats->opackets += ppio_stats.tx_packets;
1054         stats->imissed += ppio_stats.rx_fullq_dropped +
1055                           ppio_stats.rx_bm_dropped +
1056                           ppio_stats.rx_early_dropped +
1057                           ppio_stats.rx_fifo_dropped +
1058                           ppio_stats.rx_cls_dropped;
1059         stats->ierrors = drop_mac;
1060
1061         return 0;
1062 }
1063
1064 /**
1065  * DPDK callback to clear device statistics.
1066  *
1067  * @param dev
1068  *   Pointer to Ethernet device structure.
1069  */
1070 static void
1071 mrvl_stats_reset(struct rte_eth_dev *dev)
1072 {
1073         struct mrvl_priv *priv = dev->data->dev_private;
1074         int i;
1075
1076         if (!priv->ppio)
1077                 return;
1078
1079         for (i = 0; i < dev->data->nb_rx_queues; i++) {
1080                 struct mrvl_rxq *rxq = dev->data->rx_queues[i];
1081
1082                 pp2_ppio_inq_get_statistics(priv->ppio, priv->rxq_map[i].tc,
1083                                             priv->rxq_map[i].inq, NULL, 1);
1084                 rxq->bytes_recv = 0;
1085                 rxq->drop_mac = 0;
1086         }
1087
1088         for (i = 0; i < dev->data->nb_tx_queues; i++) {
1089                 struct mrvl_txq *txq = dev->data->tx_queues[i];
1090
1091                 pp2_ppio_outq_get_statistics(priv->ppio, i, NULL, 1);
1092                 txq->bytes_sent = 0;
1093         }
1094
1095         pp2_ppio_get_statistics(priv->ppio, NULL, 1);
1096 }
1097
1098 /**
1099  * DPDK callback to get information about the device.
1100  *
1101  * @param dev
1102  *   Pointer to Ethernet device structure (unused).
1103  * @param info
1104  *   Info structure output buffer.
1105  */
1106 static void
1107 mrvl_dev_infos_get(struct rte_eth_dev *dev __rte_unused,
1108                    struct rte_eth_dev_info *info)
1109 {
1110         info->speed_capa = ETH_LINK_SPEED_10M |
1111                            ETH_LINK_SPEED_100M |
1112                            ETH_LINK_SPEED_1G |
1113                            ETH_LINK_SPEED_10G;
1114
1115         info->max_rx_queues = MRVL_PP2_RXQ_MAX;
1116         info->max_tx_queues = MRVL_PP2_TXQ_MAX;
1117         info->max_mac_addrs = MRVL_MAC_ADDRS_MAX;
1118
1119         info->rx_desc_lim.nb_max = MRVL_PP2_RXD_MAX;
1120         info->rx_desc_lim.nb_min = MRVL_PP2_RXD_MIN;
1121         info->rx_desc_lim.nb_align = MRVL_PP2_RXD_ALIGN;
1122
1123         info->tx_desc_lim.nb_max = MRVL_PP2_TXD_MAX;
1124         info->tx_desc_lim.nb_min = MRVL_PP2_TXD_MIN;
1125         info->tx_desc_lim.nb_align = MRVL_PP2_TXD_ALIGN;
1126
1127         info->rx_offload_capa = DEV_RX_OFFLOAD_JUMBO_FRAME |
1128                                 DEV_RX_OFFLOAD_VLAN_FILTER |
1129                                 DEV_RX_OFFLOAD_IPV4_CKSUM |
1130                                 DEV_RX_OFFLOAD_UDP_CKSUM |
1131                                 DEV_RX_OFFLOAD_TCP_CKSUM;
1132
1133         info->tx_offload_capa = DEV_TX_OFFLOAD_IPV4_CKSUM |
1134                                 DEV_TX_OFFLOAD_UDP_CKSUM |
1135                                 DEV_TX_OFFLOAD_TCP_CKSUM;
1136
1137         info->flow_type_rss_offloads = ETH_RSS_IPV4 |
1138                                        ETH_RSS_NONFRAG_IPV4_TCP |
1139                                        ETH_RSS_NONFRAG_IPV4_UDP;
1140
1141         /* By default packets are dropped if no descriptors are available */
1142         info->default_rxconf.rx_drop_en = 1;
1143
1144         info->max_rx_pktlen = MRVL_PKT_SIZE_MAX;
1145 }
1146
1147 /**
1148  * Return supported packet types.
1149  *
1150  * @param dev
1151  *   Pointer to Ethernet device structure (unused).
1152  *
1153  * @return
1154  *   Const pointer to the table with supported packet types.
1155  */
1156 static const uint32_t *
1157 mrvl_dev_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused)
1158 {
1159         static const uint32_t ptypes[] = {
1160                 RTE_PTYPE_L2_ETHER,
1161                 RTE_PTYPE_L3_IPV4,
1162                 RTE_PTYPE_L3_IPV4_EXT,
1163                 RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
1164                 RTE_PTYPE_L3_IPV6,
1165                 RTE_PTYPE_L3_IPV6_EXT,
1166                 RTE_PTYPE_L2_ETHER_ARP,
1167                 RTE_PTYPE_L4_TCP,
1168                 RTE_PTYPE_L4_UDP
1169         };
1170
1171         return ptypes;
1172 }
1173
1174 /**
1175  * DPDK callback to get information about specific receive queue.
1176  *
1177  * @param dev
1178  *   Pointer to Ethernet device structure.
1179  * @param rx_queue_id
1180  *   Receive queue index.
1181  * @param qinfo
1182  *   Receive queue information structure.
1183  */
1184 static void mrvl_rxq_info_get(struct rte_eth_dev *dev, uint16_t rx_queue_id,
1185                               struct rte_eth_rxq_info *qinfo)
1186 {
1187         struct mrvl_rxq *q = dev->data->rx_queues[rx_queue_id];
1188         struct mrvl_priv *priv = dev->data->dev_private;
1189         int inq = priv->rxq_map[rx_queue_id].inq;
1190         int tc = priv->rxq_map[rx_queue_id].tc;
1191         struct pp2_ppio_tc_params *tc_params =
1192                 &priv->ppio_params.inqs_params.tcs_params[tc];
1193
1194         qinfo->mp = q->mp;
1195         qinfo->nb_desc = tc_params->inqs_params[inq].size;
1196 }
1197
1198 /**
1199  * DPDK callback to get information about specific transmit queue.
1200  *
1201  * @param dev
1202  *   Pointer to Ethernet device structure.
1203  * @param tx_queue_id
1204  *   Transmit queue index.
1205  * @param qinfo
1206  *   Transmit queue information structure.
1207  */
1208 static void mrvl_txq_info_get(struct rte_eth_dev *dev, uint16_t tx_queue_id,
1209                               struct rte_eth_txq_info *qinfo)
1210 {
1211         struct mrvl_priv *priv = dev->data->dev_private;
1212
1213         qinfo->nb_desc =
1214                 priv->ppio_params.outqs_params.outqs_params[tx_queue_id].size;
1215 }
1216
1217 /**
1218  * DPDK callback to Configure a VLAN filter.
1219  *
1220  * @param dev
1221  *   Pointer to Ethernet device structure.
1222  * @param vlan_id
1223  *   VLAN ID to filter.
1224  * @param on
1225  *   Toggle filter.
1226  *
1227  * @return
1228  *   0 on success, negative error value otherwise.
1229  */
1230 static int
1231 mrvl_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
1232 {
1233         struct mrvl_priv *priv = dev->data->dev_private;
1234
1235         if (!priv->ppio)
1236                 return -EPERM;
1237
1238         return on ? pp2_ppio_add_vlan(priv->ppio, vlan_id) :
1239                     pp2_ppio_remove_vlan(priv->ppio, vlan_id);
1240 }
1241
1242 /**
1243  * Release buffers to hardware bpool (buffer-pool)
1244  *
1245  * @param rxq
1246  *   Receive queue pointer.
1247  * @param num
1248  *   Number of buffers to release to bpool.
1249  *
1250  * @return
1251  *   0 on success, negative error value otherwise.
1252  */
1253 static int
1254 mrvl_fill_bpool(struct mrvl_rxq *rxq, int num)
1255 {
1256         struct buff_release_entry entries[MRVL_PP2_TXD_MAX];
1257         struct rte_mbuf *mbufs[MRVL_PP2_TXD_MAX];
1258         int i, ret;
1259         unsigned int core_id;
1260         struct pp2_hif *hif;
1261         struct pp2_bpool *bpool;
1262
1263         core_id = rte_lcore_id();
1264         if (core_id == LCORE_ID_ANY)
1265                 core_id = 0;
1266
1267         hif = mrvl_get_hif(rxq->priv, core_id);
1268         if (!hif)
1269                 return -1;
1270
1271         bpool = rxq->priv->bpool;
1272
1273         ret = rte_pktmbuf_alloc_bulk(rxq->mp, mbufs, num);
1274         if (ret)
1275                 return ret;
1276
1277         if (cookie_addr_high == MRVL_COOKIE_ADDR_INVALID)
1278                 cookie_addr_high =
1279                         (uint64_t)mbufs[0] & MRVL_COOKIE_HIGH_ADDR_MASK;
1280
1281         for (i = 0; i < num; i++) {
1282                 if (((uint64_t)mbufs[i] & MRVL_COOKIE_HIGH_ADDR_MASK)
1283                         != cookie_addr_high) {
1284                         RTE_LOG(ERR, PMD,
1285                                 "mbuf virtual addr high 0x%lx out of range\n",
1286                                 (uint64_t)mbufs[i] >> 32);
1287                         goto out;
1288                 }
1289
1290                 entries[i].buff.addr =
1291                         rte_mbuf_data_iova_default(mbufs[i]);
1292                 entries[i].buff.cookie = (pp2_cookie_t)(uint64_t)mbufs[i];
1293                 entries[i].bpool = bpool;
1294         }
1295
1296         pp2_bpool_put_buffs(hif, entries, (uint16_t *)&i);
1297         mrvl_port_bpool_size[bpool->pp2_id][bpool->id][core_id] += i;
1298
1299         if (i != num)
1300                 goto out;
1301
1302         return 0;
1303 out:
1304         for (; i < num; i++)
1305                 rte_pktmbuf_free(mbufs[i]);
1306
1307         return -1;
1308 }
1309
1310 /**
1311  * DPDK callback to configure the receive queue.
1312  *
1313  * @param dev
1314  *   Pointer to Ethernet device structure.
1315  * @param idx
1316  *   RX queue index.
1317  * @param desc
1318  *   Number of descriptors to configure in queue.
1319  * @param socket
1320  *   NUMA socket on which memory must be allocated.
1321  * @param conf
1322  *   Thresholds parameters (unused_).
1323  * @param mp
1324  *   Memory pool for buffer allocations.
1325  *
1326  * @return
1327  *   0 on success, negative error value otherwise.
1328  */
1329 static int
1330 mrvl_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
1331                     unsigned int socket,
1332                     const struct rte_eth_rxconf *conf __rte_unused,
1333                     struct rte_mempool *mp)
1334 {
1335         struct mrvl_priv *priv = dev->data->dev_private;
1336         struct mrvl_rxq *rxq;
1337         uint32_t min_size,
1338                  max_rx_pkt_len = dev->data->dev_conf.rxmode.max_rx_pkt_len;
1339         int ret, tc, inq;
1340
1341         if (priv->rxq_map[idx].tc == MRVL_UNKNOWN_TC) {
1342                 /*
1343                  * Unknown TC mapping, mapping will not have a correct queue.
1344                  */
1345                 RTE_LOG(ERR, PMD, "Unknown TC mapping for queue %hu eth%hhu\n",
1346                         idx, priv->ppio_id);
1347                 return -EFAULT;
1348         }
1349
1350         min_size = rte_pktmbuf_data_room_size(mp) - RTE_PKTMBUF_HEADROOM -
1351                    MRVL_PKT_EFFEC_OFFS;
1352         if (min_size < max_rx_pkt_len) {
1353                 RTE_LOG(ERR, PMD,
1354                         "Mbuf size must be increased to %u bytes to hold up to %u bytes of data.\n",
1355                         max_rx_pkt_len + RTE_PKTMBUF_HEADROOM +
1356                         MRVL_PKT_EFFEC_OFFS,
1357                         max_rx_pkt_len);
1358                 return -EINVAL;
1359         }
1360
1361         if (dev->data->rx_queues[idx]) {
1362                 rte_free(dev->data->rx_queues[idx]);
1363                 dev->data->rx_queues[idx] = NULL;
1364         }
1365
1366         rxq = rte_zmalloc_socket("rxq", sizeof(*rxq), 0, socket);
1367         if (!rxq)
1368                 return -ENOMEM;
1369
1370         rxq->priv = priv;
1371         rxq->mp = mp;
1372         rxq->cksum_enabled = dev->data->dev_conf.rxmode.hw_ip_checksum;
1373         rxq->queue_id = idx;
1374         rxq->port_id = dev->data->port_id;
1375         mrvl_port_to_bpool_lookup[rxq->port_id] = priv->bpool;
1376
1377         tc = priv->rxq_map[rxq->queue_id].tc,
1378         inq = priv->rxq_map[rxq->queue_id].inq;
1379         priv->ppio_params.inqs_params.tcs_params[tc].inqs_params[inq].size =
1380                 desc;
1381
1382         ret = mrvl_fill_bpool(rxq, desc);
1383         if (ret) {
1384                 rte_free(rxq);
1385                 return ret;
1386         }
1387
1388         priv->bpool_init_size += desc;
1389
1390         dev->data->rx_queues[idx] = rxq;
1391
1392         return 0;
1393 }
1394
1395 /**
1396  * DPDK callback to release the receive queue.
1397  *
1398  * @param rxq
1399  *   Generic receive queue pointer.
1400  */
1401 static void
1402 mrvl_rx_queue_release(void *rxq)
1403 {
1404         struct mrvl_rxq *q = rxq;
1405         struct pp2_ppio_tc_params *tc_params;
1406         int i, num, tc, inq;
1407         struct pp2_hif *hif;
1408         unsigned int core_id = rte_lcore_id();
1409
1410         if (core_id == LCORE_ID_ANY)
1411                 core_id = 0;
1412
1413         hif = mrvl_get_hif(q->priv, core_id);
1414
1415         if (!q || !hif)
1416                 return;
1417
1418         tc = q->priv->rxq_map[q->queue_id].tc;
1419         inq = q->priv->rxq_map[q->queue_id].inq;
1420         tc_params = &q->priv->ppio_params.inqs_params.tcs_params[tc];
1421         num = tc_params->inqs_params[inq].size;
1422         for (i = 0; i < num; i++) {
1423                 struct pp2_buff_inf inf;
1424                 uint64_t addr;
1425
1426                 pp2_bpool_get_buff(hif, q->priv->bpool, &inf);
1427                 addr = cookie_addr_high | inf.cookie;
1428                 rte_pktmbuf_free((struct rte_mbuf *)addr);
1429         }
1430
1431         rte_free(q);
1432 }
1433
1434 /**
1435  * DPDK callback to configure the transmit queue.
1436  *
1437  * @param dev
1438  *   Pointer to Ethernet device structure.
1439  * @param idx
1440  *   Transmit queue index.
1441  * @param desc
1442  *   Number of descriptors to configure in the queue.
1443  * @param socket
1444  *   NUMA socket on which memory must be allocated.
1445  * @param conf
1446  *   Thresholds parameters (unused).
1447  *
1448  * @return
1449  *   0 on success, negative error value otherwise.
1450  */
1451 static int
1452 mrvl_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
1453                     unsigned int socket,
1454                     const struct rte_eth_txconf *conf __rte_unused)
1455 {
1456         struct mrvl_priv *priv = dev->data->dev_private;
1457         struct mrvl_txq *txq;
1458
1459         if (dev->data->tx_queues[idx]) {
1460                 rte_free(dev->data->tx_queues[idx]);
1461                 dev->data->tx_queues[idx] = NULL;
1462         }
1463
1464         txq = rte_zmalloc_socket("txq", sizeof(*txq), 0, socket);
1465         if (!txq)
1466                 return -ENOMEM;
1467
1468         txq->priv = priv;
1469         txq->queue_id = idx;
1470         txq->port_id = dev->data->port_id;
1471         dev->data->tx_queues[idx] = txq;
1472
1473         priv->ppio_params.outqs_params.outqs_params[idx].size = desc;
1474         priv->ppio_params.outqs_params.outqs_params[idx].weight = 1;
1475
1476         return 0;
1477 }
1478
1479 /**
1480  * DPDK callback to release the transmit queue.
1481  *
1482  * @param txq
1483  *   Generic transmit queue pointer.
1484  */
1485 static void
1486 mrvl_tx_queue_release(void *txq)
1487 {
1488         struct mrvl_txq *q = txq;
1489
1490         if (!q)
1491                 return;
1492
1493         rte_free(q);
1494 }
1495
1496 /**
1497  * Update RSS hash configuration
1498  *
1499  * @param dev
1500  *   Pointer to Ethernet device structure.
1501  * @param rss_conf
1502  *   Pointer to RSS configuration.
1503  *
1504  * @return
1505  *   0 on success, negative error value otherwise.
1506  */
1507 static int
1508 mrvl_rss_hash_update(struct rte_eth_dev *dev,
1509                      struct rte_eth_rss_conf *rss_conf)
1510 {
1511         struct mrvl_priv *priv = dev->data->dev_private;
1512
1513         return mrvl_configure_rss(priv, rss_conf);
1514 }
1515
1516 /**
1517  * DPDK callback to get RSS hash configuration.
1518  *
1519  * @param dev
1520  *   Pointer to Ethernet device structure.
1521  * @rss_conf
1522  *   Pointer to RSS configuration.
1523  *
1524  * @return
1525  *   Always 0.
1526  */
1527 static int
1528 mrvl_rss_hash_conf_get(struct rte_eth_dev *dev,
1529                        struct rte_eth_rss_conf *rss_conf)
1530 {
1531         struct mrvl_priv *priv = dev->data->dev_private;
1532         enum pp2_ppio_hash_type hash_type =
1533                 priv->ppio_params.inqs_params.hash_type;
1534
1535         rss_conf->rss_key = NULL;
1536
1537         if (hash_type == PP2_PPIO_HASH_T_NONE)
1538                 rss_conf->rss_hf = 0;
1539         else if (hash_type == PP2_PPIO_HASH_T_2_TUPLE)
1540                 rss_conf->rss_hf = ETH_RSS_IPV4;
1541         else if (hash_type == PP2_PPIO_HASH_T_5_TUPLE && priv->rss_hf_tcp)
1542                 rss_conf->rss_hf = ETH_RSS_NONFRAG_IPV4_TCP;
1543         else if (hash_type == PP2_PPIO_HASH_T_5_TUPLE && !priv->rss_hf_tcp)
1544                 rss_conf->rss_hf = ETH_RSS_NONFRAG_IPV4_UDP;
1545
1546         return 0;
1547 }
1548
1549 static const struct eth_dev_ops mrvl_ops = {
1550         .dev_configure = mrvl_dev_configure,
1551         .dev_start = mrvl_dev_start,
1552         .dev_stop = mrvl_dev_stop,
1553         .dev_set_link_up = mrvl_dev_set_link_up,
1554         .dev_set_link_down = mrvl_dev_set_link_down,
1555         .dev_close = mrvl_dev_close,
1556         .link_update = mrvl_link_update,
1557         .promiscuous_enable = mrvl_promiscuous_enable,
1558         .allmulticast_enable = mrvl_allmulticast_enable,
1559         .promiscuous_disable = mrvl_promiscuous_disable,
1560         .allmulticast_disable = mrvl_allmulticast_disable,
1561         .mac_addr_remove = mrvl_mac_addr_remove,
1562         .mac_addr_add = mrvl_mac_addr_add,
1563         .mac_addr_set = mrvl_mac_addr_set,
1564         .mtu_set = mrvl_mtu_set,
1565         .stats_get = mrvl_stats_get,
1566         .stats_reset = mrvl_stats_reset,
1567         .dev_infos_get = mrvl_dev_infos_get,
1568         .dev_supported_ptypes_get = mrvl_dev_supported_ptypes_get,
1569         .rxq_info_get = mrvl_rxq_info_get,
1570         .txq_info_get = mrvl_txq_info_get,
1571         .vlan_filter_set = mrvl_vlan_filter_set,
1572         .rx_queue_setup = mrvl_rx_queue_setup,
1573         .rx_queue_release = mrvl_rx_queue_release,
1574         .tx_queue_setup = mrvl_tx_queue_setup,
1575         .tx_queue_release = mrvl_tx_queue_release,
1576         .rss_hash_update = mrvl_rss_hash_update,
1577         .rss_hash_conf_get = mrvl_rss_hash_conf_get,
1578 };
1579
1580 /**
1581  * Return packet type information and l3/l4 offsets.
1582  *
1583  * @param desc
1584  *   Pointer to the received packet descriptor.
1585  * @param l3_offset
1586  *   l3 packet offset.
1587  * @param l4_offset
1588  *   l4 packet offset.
1589  *
1590  * @return
1591  *   Packet type information.
1592  */
1593 static inline uint64_t
1594 mrvl_desc_to_packet_type_and_offset(struct pp2_ppio_desc *desc,
1595                                     uint8_t *l3_offset, uint8_t *l4_offset)
1596 {
1597         enum pp2_inq_l3_type l3_type;
1598         enum pp2_inq_l4_type l4_type;
1599         uint64_t packet_type;
1600
1601         pp2_ppio_inq_desc_get_l3_info(desc, &l3_type, l3_offset);
1602         pp2_ppio_inq_desc_get_l4_info(desc, &l4_type, l4_offset);
1603
1604         packet_type = RTE_PTYPE_L2_ETHER;
1605
1606         switch (l3_type) {
1607         case PP2_INQ_L3_TYPE_IPV4_NO_OPTS:
1608                 packet_type |= RTE_PTYPE_L3_IPV4;
1609                 break;
1610         case PP2_INQ_L3_TYPE_IPV4_OK:
1611                 packet_type |= RTE_PTYPE_L3_IPV4_EXT;
1612                 break;
1613         case PP2_INQ_L3_TYPE_IPV4_TTL_ZERO:
1614                 packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
1615                 break;
1616         case PP2_INQ_L3_TYPE_IPV6_NO_EXT:
1617                 packet_type |= RTE_PTYPE_L3_IPV6;
1618                 break;
1619         case PP2_INQ_L3_TYPE_IPV6_EXT:
1620                 packet_type |= RTE_PTYPE_L3_IPV6_EXT;
1621                 break;
1622         case PP2_INQ_L3_TYPE_ARP:
1623                 packet_type |= RTE_PTYPE_L2_ETHER_ARP;
1624                 /*
1625                  * In case of ARP l4_offset is set to wrong value.
1626                  * Set it to proper one so that later on mbuf->l3_len can be
1627                  * calculated subtracting l4_offset and l3_offset.
1628                  */
1629                 *l4_offset = *l3_offset + MRVL_ARP_LENGTH;
1630                 break;
1631         default:
1632                 RTE_LOG(DEBUG, PMD, "Failed to recognise l3 packet type\n");
1633                 break;
1634         }
1635
1636         switch (l4_type) {
1637         case PP2_INQ_L4_TYPE_TCP:
1638                 packet_type |= RTE_PTYPE_L4_TCP;
1639                 break;
1640         case PP2_INQ_L4_TYPE_UDP:
1641                 packet_type |= RTE_PTYPE_L4_UDP;
1642                 break;
1643         default:
1644                 RTE_LOG(DEBUG, PMD, "Failed to recognise l4 packet type\n");
1645                 break;
1646         }
1647
1648         return packet_type;
1649 }
1650
1651 /**
1652  * Get offload information from the received packet descriptor.
1653  *
1654  * @param desc
1655  *   Pointer to the received packet descriptor.
1656  *
1657  * @return
1658  *   Mbuf offload flags.
1659  */
1660 static inline uint64_t
1661 mrvl_desc_to_ol_flags(struct pp2_ppio_desc *desc)
1662 {
1663         uint64_t flags;
1664         enum pp2_inq_desc_status status;
1665
1666         status = pp2_ppio_inq_desc_get_l3_pkt_error(desc);
1667         if (unlikely(status != PP2_DESC_ERR_OK))
1668                 flags = PKT_RX_IP_CKSUM_BAD;
1669         else
1670                 flags = PKT_RX_IP_CKSUM_GOOD;
1671
1672         status = pp2_ppio_inq_desc_get_l4_pkt_error(desc);
1673         if (unlikely(status != PP2_DESC_ERR_OK))
1674                 flags |= PKT_RX_L4_CKSUM_BAD;
1675         else
1676                 flags |= PKT_RX_L4_CKSUM_GOOD;
1677
1678         return flags;
1679 }
1680
1681 /**
1682  * DPDK callback for receive.
1683  *
1684  * @param rxq
1685  *   Generic pointer to the receive queue.
1686  * @param rx_pkts
1687  *   Array to store received packets.
1688  * @param nb_pkts
1689  *   Maximum number of packets in array.
1690  *
1691  * @return
1692  *   Number of packets successfully received.
1693  */
1694 static uint16_t
1695 mrvl_rx_pkt_burst(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
1696 {
1697         struct mrvl_rxq *q = rxq;
1698         struct pp2_ppio_desc descs[nb_pkts];
1699         struct pp2_bpool *bpool;
1700         int i, ret, rx_done = 0;
1701         int num;
1702         struct pp2_hif *hif;
1703         unsigned int core_id = rte_lcore_id();
1704
1705         hif = mrvl_get_hif(q->priv, core_id);
1706
1707         if (unlikely(!q->priv->ppio || !hif))
1708                 return 0;
1709
1710         bpool = q->priv->bpool;
1711
1712         ret = pp2_ppio_recv(q->priv->ppio, q->priv->rxq_map[q->queue_id].tc,
1713                             q->priv->rxq_map[q->queue_id].inq, descs, &nb_pkts);
1714         if (unlikely(ret < 0)) {
1715                 RTE_LOG(ERR, PMD, "Failed to receive packets\n");
1716                 return 0;
1717         }
1718         mrvl_port_bpool_size[bpool->pp2_id][bpool->id][core_id] -= nb_pkts;
1719
1720         for (i = 0; i < nb_pkts; i++) {
1721                 struct rte_mbuf *mbuf;
1722                 uint8_t l3_offset, l4_offset;
1723                 enum pp2_inq_desc_status status;
1724                 uint64_t addr;
1725
1726                 if (likely(nb_pkts - i > MRVL_MUSDK_PREFETCH_SHIFT)) {
1727                         struct pp2_ppio_desc *pref_desc;
1728                         u64 pref_addr;
1729
1730                         pref_desc = &descs[i + MRVL_MUSDK_PREFETCH_SHIFT];
1731                         pref_addr = cookie_addr_high |
1732                                     pp2_ppio_inq_desc_get_cookie(pref_desc);
1733                         rte_mbuf_prefetch_part1((struct rte_mbuf *)(pref_addr));
1734                         rte_mbuf_prefetch_part2((struct rte_mbuf *)(pref_addr));
1735                 }
1736
1737                 addr = cookie_addr_high |
1738                        pp2_ppio_inq_desc_get_cookie(&descs[i]);
1739                 mbuf = (struct rte_mbuf *)addr;
1740                 rte_pktmbuf_reset(mbuf);
1741
1742                 /* drop packet in case of mac, overrun or resource error */
1743                 status = pp2_ppio_inq_desc_get_l2_pkt_error(&descs[i]);
1744                 if (unlikely(status != PP2_DESC_ERR_OK)) {
1745                         struct pp2_buff_inf binf = {
1746                                 .addr = rte_mbuf_data_iova_default(mbuf),
1747                                 .cookie = (pp2_cookie_t)(uint64_t)mbuf,
1748                         };
1749
1750                         pp2_bpool_put_buff(hif, bpool, &binf);
1751                         mrvl_port_bpool_size
1752                                 [bpool->pp2_id][bpool->id][core_id]++;
1753                         q->drop_mac++;
1754                         continue;
1755                 }
1756
1757                 mbuf->data_off += MRVL_PKT_EFFEC_OFFS;
1758                 mbuf->pkt_len = pp2_ppio_inq_desc_get_pkt_len(&descs[i]);
1759                 mbuf->data_len = mbuf->pkt_len;
1760                 mbuf->port = q->port_id;
1761                 mbuf->packet_type =
1762                         mrvl_desc_to_packet_type_and_offset(&descs[i],
1763                                                             &l3_offset,
1764                                                             &l4_offset);
1765                 mbuf->l2_len = l3_offset;
1766                 mbuf->l3_len = l4_offset - l3_offset;
1767
1768                 if (likely(q->cksum_enabled))
1769                         mbuf->ol_flags = mrvl_desc_to_ol_flags(&descs[i]);
1770
1771                 rx_pkts[rx_done++] = mbuf;
1772                 q->bytes_recv += mbuf->pkt_len;
1773         }
1774
1775         if (rte_spinlock_trylock(&q->priv->lock) == 1) {
1776                 num = mrvl_get_bpool_size(bpool->pp2_id, bpool->id);
1777
1778                 if (unlikely(num <= q->priv->bpool_min_size ||
1779                              (!rx_done && num < q->priv->bpool_init_size))) {
1780                         ret = mrvl_fill_bpool(q, MRVL_BURST_SIZE);
1781                         if (ret)
1782                                 RTE_LOG(ERR, PMD, "Failed to fill bpool\n");
1783                 } else if (unlikely(num > q->priv->bpool_max_size)) {
1784                         int i;
1785                         int pkt_to_remove = num - q->priv->bpool_init_size;
1786                         struct rte_mbuf *mbuf;
1787                         struct pp2_buff_inf buff;
1788
1789                         RTE_LOG(DEBUG, PMD,
1790                                 "\nport-%d:%d: bpool %d oversize - remove %d buffers (pool size: %d -> %d)\n",
1791                                 bpool->pp2_id, q->priv->ppio->port_id,
1792                                 bpool->id, pkt_to_remove, num,
1793                                 q->priv->bpool_init_size);
1794
1795                         for (i = 0; i < pkt_to_remove; i++) {
1796                                 ret = pp2_bpool_get_buff(hif, bpool, &buff);
1797                                 if (ret)
1798                                         break;
1799                                 mbuf = (struct rte_mbuf *)
1800                                         (cookie_addr_high | buff.cookie);
1801                                 rte_pktmbuf_free(mbuf);
1802                         }
1803                         mrvl_port_bpool_size
1804                                 [bpool->pp2_id][bpool->id][core_id] -= i;
1805                 }
1806                 rte_spinlock_unlock(&q->priv->lock);
1807         }
1808
1809         return rx_done;
1810 }
1811
1812 /**
1813  * Prepare offload information.
1814  *
1815  * @param ol_flags
1816  *   Offload flags.
1817  * @param packet_type
1818  *   Packet type bitfield.
1819  * @param l3_type
1820  *   Pointer to the pp2_ouq_l3_type structure.
1821  * @param l4_type
1822  *   Pointer to the pp2_outq_l4_type structure.
1823  * @param gen_l3_cksum
1824  *   Will be set to 1 in case l3 checksum is computed.
1825  * @param l4_cksum
1826  *   Will be set to 1 in case l4 checksum is computed.
1827  *
1828  * @return
1829  *   0 on success, negative error value otherwise.
1830  */
1831 static inline int
1832 mrvl_prepare_proto_info(uint64_t ol_flags, uint32_t packet_type,
1833                         enum pp2_outq_l3_type *l3_type,
1834                         enum pp2_outq_l4_type *l4_type,
1835                         int *gen_l3_cksum,
1836                         int *gen_l4_cksum)
1837 {
1838         /*
1839          * Based on ol_flags prepare information
1840          * for pp2_ppio_outq_desc_set_proto_info() which setups descriptor
1841          * for offloading.
1842          */
1843         if (ol_flags & PKT_TX_IPV4) {
1844                 *l3_type = PP2_OUTQ_L3_TYPE_IPV4;
1845                 *gen_l3_cksum = ol_flags & PKT_TX_IP_CKSUM ? 1 : 0;
1846         } else if (ol_flags & PKT_TX_IPV6) {
1847                 *l3_type = PP2_OUTQ_L3_TYPE_IPV6;
1848                 /* no checksum for ipv6 header */
1849                 *gen_l3_cksum = 0;
1850         } else {
1851                 /* if something different then stop processing */
1852                 return -1;
1853         }
1854
1855         ol_flags &= PKT_TX_L4_MASK;
1856         if ((packet_type & RTE_PTYPE_L4_TCP) &&
1857             ol_flags == PKT_TX_TCP_CKSUM) {
1858                 *l4_type = PP2_OUTQ_L4_TYPE_TCP;
1859                 *gen_l4_cksum = 1;
1860         } else if ((packet_type & RTE_PTYPE_L4_UDP) &&
1861                    ol_flags == PKT_TX_UDP_CKSUM) {
1862                 *l4_type = PP2_OUTQ_L4_TYPE_UDP;
1863                 *gen_l4_cksum = 1;
1864         } else {
1865                 *l4_type = PP2_OUTQ_L4_TYPE_OTHER;
1866                 /* no checksum for other type */
1867                 *gen_l4_cksum = 0;
1868         }
1869
1870         return 0;
1871 }
1872
1873 /**
1874  * Release already sent buffers to bpool (buffer-pool).
1875  *
1876  * @param ppio
1877  *   Pointer to the port structure.
1878  * @param hif
1879  *   Pointer to the MUSDK hardware interface.
1880  * @param sq
1881  *   Pointer to the shadow queue.
1882  * @param qid
1883  *   Queue id number.
1884  * @param force
1885  *   Force releasing packets.
1886  */
1887 static inline void
1888 mrvl_free_sent_buffers(struct pp2_ppio *ppio, struct pp2_hif *hif,
1889                        unsigned int core_id, struct mrvl_shadow_txq *sq,
1890                        int qid, int force)
1891 {
1892         struct buff_release_entry *entry;
1893         uint16_t nb_done = 0, num = 0, skip_bufs = 0;
1894         int i;
1895
1896         pp2_ppio_get_num_outq_done(ppio, hif, qid, &nb_done);
1897
1898         sq->num_to_release += nb_done;
1899
1900         if (likely(!force &&
1901                    sq->num_to_release < MRVL_PP2_BUF_RELEASE_BURST_SIZE))
1902                 return;
1903
1904         nb_done = sq->num_to_release;
1905         sq->num_to_release = 0;
1906
1907         for (i = 0; i < nb_done; i++) {
1908                 entry = &sq->ent[sq->tail + num];
1909                 if (unlikely(!entry->buff.addr)) {
1910                         RTE_LOG(ERR, PMD,
1911                                 "Shadow memory @%d: cookie(%lx), pa(%lx)!\n",
1912                                 sq->tail, (u64)entry->buff.cookie,
1913                                 (u64)entry->buff.addr);
1914                         skip_bufs = 1;
1915                         goto skip;
1916                 }
1917
1918                 if (unlikely(!entry->bpool)) {
1919                         struct rte_mbuf *mbuf;
1920
1921                         mbuf = (struct rte_mbuf *)
1922                                (cookie_addr_high | entry->buff.cookie);
1923                         rte_pktmbuf_free(mbuf);
1924                         skip_bufs = 1;
1925                         goto skip;
1926                 }
1927
1928                 mrvl_port_bpool_size
1929                         [entry->bpool->pp2_id][entry->bpool->id][core_id]++;
1930                 num++;
1931                 if (unlikely(sq->tail + num == MRVL_PP2_TX_SHADOWQ_SIZE))
1932                         goto skip;
1933                 continue;
1934 skip:
1935                 if (likely(num))
1936                         pp2_bpool_put_buffs(hif, &sq->ent[sq->tail], &num);
1937                 num += skip_bufs;
1938                 sq->tail = (sq->tail + num) & MRVL_PP2_TX_SHADOWQ_MASK;
1939                 sq->size -= num;
1940                 num = 0;
1941                 skip_bufs = 0;
1942         }
1943
1944         if (likely(num)) {
1945                 pp2_bpool_put_buffs(hif, &sq->ent[sq->tail], &num);
1946                 sq->tail = (sq->tail + num) & MRVL_PP2_TX_SHADOWQ_MASK;
1947                 sq->size -= num;
1948         }
1949 }
1950
1951 /**
1952  * DPDK callback for transmit.
1953  *
1954  * @param txq
1955  *   Generic pointer transmit queue.
1956  * @param tx_pkts
1957  *   Packets to transmit.
1958  * @param nb_pkts
1959  *   Number of packets in array.
1960  *
1961  * @return
1962  *   Number of packets successfully transmitted.
1963  */
1964 static uint16_t
1965 mrvl_tx_pkt_burst(void *txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
1966 {
1967         struct mrvl_txq *q = txq;
1968         struct mrvl_shadow_txq *sq;
1969         struct pp2_hif *hif;
1970         struct pp2_ppio_desc descs[nb_pkts];
1971         unsigned int core_id = rte_lcore_id();
1972         int i, ret, bytes_sent = 0;
1973         uint16_t num, sq_free_size;
1974         uint64_t addr;
1975
1976         hif = mrvl_get_hif(q->priv, core_id);
1977         sq = &q->shadow_txqs[core_id];
1978
1979         if (unlikely(!q->priv->ppio || !hif))
1980                 return 0;
1981
1982         if (sq->size)
1983                 mrvl_free_sent_buffers(q->priv->ppio, hif, core_id,
1984                                        sq, q->queue_id, 0);
1985
1986         sq_free_size = MRVL_PP2_TX_SHADOWQ_SIZE - sq->size - 1;
1987         if (unlikely(nb_pkts > sq_free_size)) {
1988                 RTE_LOG(DEBUG, PMD,
1989                         "No room in shadow queue for %d packets! %d packets will be sent.\n",
1990                         nb_pkts, sq_free_size);
1991                 nb_pkts = sq_free_size;
1992         }
1993
1994         for (i = 0; i < nb_pkts; i++) {
1995                 struct rte_mbuf *mbuf = tx_pkts[i];
1996                 int gen_l3_cksum, gen_l4_cksum;
1997                 enum pp2_outq_l3_type l3_type;
1998                 enum pp2_outq_l4_type l4_type;
1999
2000                 if (likely(nb_pkts - i > MRVL_MUSDK_PREFETCH_SHIFT)) {
2001                         struct rte_mbuf *pref_pkt_hdr;
2002
2003                         pref_pkt_hdr = tx_pkts[i + MRVL_MUSDK_PREFETCH_SHIFT];
2004                         rte_mbuf_prefetch_part1(pref_pkt_hdr);
2005                         rte_mbuf_prefetch_part2(pref_pkt_hdr);
2006                 }
2007
2008                 sq->ent[sq->head].buff.cookie = (pp2_cookie_t)(uint64_t)mbuf;
2009                 sq->ent[sq->head].buff.addr =
2010                         rte_mbuf_data_iova_default(mbuf);
2011                 sq->ent[sq->head].bpool =
2012                         (unlikely(mbuf->port == 0xff || mbuf->refcnt > 1)) ?
2013                          NULL : mrvl_port_to_bpool_lookup[mbuf->port];
2014                 sq->head = (sq->head + 1) & MRVL_PP2_TX_SHADOWQ_MASK;
2015                 sq->size++;
2016
2017                 pp2_ppio_outq_desc_reset(&descs[i]);
2018                 pp2_ppio_outq_desc_set_phys_addr(&descs[i],
2019                                                  rte_pktmbuf_iova(mbuf));
2020                 pp2_ppio_outq_desc_set_pkt_offset(&descs[i], 0);
2021                 pp2_ppio_outq_desc_set_pkt_len(&descs[i],
2022                                                rte_pktmbuf_pkt_len(mbuf));
2023
2024                 bytes_sent += rte_pktmbuf_pkt_len(mbuf);
2025                 /*
2026                  * in case unsupported ol_flags were passed
2027                  * do not update descriptor offload information
2028                  */
2029                 ret = mrvl_prepare_proto_info(mbuf->ol_flags, mbuf->packet_type,
2030                                               &l3_type, &l4_type, &gen_l3_cksum,
2031                                               &gen_l4_cksum);
2032                 if (unlikely(ret))
2033                         continue;
2034
2035                 pp2_ppio_outq_desc_set_proto_info(&descs[i], l3_type, l4_type,
2036                                                   mbuf->l2_len,
2037                                                   mbuf->l2_len + mbuf->l3_len,
2038                                                   gen_l3_cksum, gen_l4_cksum);
2039         }
2040
2041         num = nb_pkts;
2042         pp2_ppio_send(q->priv->ppio, hif, q->queue_id, descs, &nb_pkts);
2043         /* number of packets that were not sent */
2044         if (unlikely(num > nb_pkts)) {
2045                 for (i = nb_pkts; i < num; i++) {
2046                         sq->head = (MRVL_PP2_TX_SHADOWQ_SIZE + sq->head - 1) &
2047                                 MRVL_PP2_TX_SHADOWQ_MASK;
2048                         addr = cookie_addr_high | sq->ent[sq->head].buff.cookie;
2049                         bytes_sent -=
2050                                 rte_pktmbuf_pkt_len((struct rte_mbuf *)addr);
2051                 }
2052                 sq->size -= num - nb_pkts;
2053         }
2054
2055         q->bytes_sent += bytes_sent;
2056
2057         return nb_pkts;
2058 }
2059
2060 /**
2061  * Initialize packet processor.
2062  *
2063  * @return
2064  *   0 on success, negative error value otherwise.
2065  */
2066 static int
2067 mrvl_init_pp2(void)
2068 {
2069         struct pp2_init_params init_params;
2070
2071         memset(&init_params, 0, sizeof(init_params));
2072         init_params.hif_reserved_map = MRVL_MUSDK_HIFS_RESERVED;
2073         init_params.bm_pool_reserved_map = MRVL_MUSDK_BPOOLS_RESERVED;
2074         init_params.rss_tbl_reserved_map = MRVL_MUSDK_RSS_RESERVED;
2075
2076         return pp2_init(&init_params);
2077 }
2078
2079 /**
2080  * Deinitialize packet processor.
2081  *
2082  * @return
2083  *   0 on success, negative error value otherwise.
2084  */
2085 static void
2086 mrvl_deinit_pp2(void)
2087 {
2088         pp2_deinit();
2089 }
2090
2091 /**
2092  * Create private device structure.
2093  *
2094  * @param dev_name
2095  *   Pointer to the port name passed in the initialization parameters.
2096  *
2097  * @return
2098  *   Pointer to the newly allocated private device structure.
2099  */
2100 static struct mrvl_priv *
2101 mrvl_priv_create(const char *dev_name)
2102 {
2103         struct pp2_bpool_params bpool_params;
2104         char match[MRVL_MATCH_LEN];
2105         struct mrvl_priv *priv;
2106         int ret, bpool_bit;
2107
2108         priv = rte_zmalloc_socket(dev_name, sizeof(*priv), 0, rte_socket_id());
2109         if (!priv)
2110                 return NULL;
2111
2112         ret = pp2_netdev_get_ppio_info((char *)(uintptr_t)dev_name,
2113                                        &priv->pp_id, &priv->ppio_id);
2114         if (ret)
2115                 goto out_free_priv;
2116
2117         bpool_bit = mrvl_reserve_bit(&used_bpools[priv->pp_id],
2118                                      PP2_BPOOL_NUM_POOLS);
2119         if (bpool_bit < 0)
2120                 goto out_free_priv;
2121         priv->bpool_bit = bpool_bit;
2122
2123         snprintf(match, sizeof(match), "pool-%d:%d", priv->pp_id,
2124                  priv->bpool_bit);
2125         memset(&bpool_params, 0, sizeof(bpool_params));
2126         bpool_params.match = match;
2127         bpool_params.buff_len = MRVL_PKT_SIZE_MAX + MRVL_PKT_EFFEC_OFFS;
2128         ret = pp2_bpool_init(&bpool_params, &priv->bpool);
2129         if (ret)
2130                 goto out_clear_bpool_bit;
2131
2132         priv->ppio_params.type = PP2_PPIO_T_NIC;
2133         rte_spinlock_init(&priv->lock);
2134
2135         return priv;
2136 out_clear_bpool_bit:
2137         used_bpools[priv->pp_id] &= ~(1 << priv->bpool_bit);
2138 out_free_priv:
2139         rte_free(priv);
2140         return NULL;
2141 }
2142
2143 /**
2144  * Create device representing Ethernet port.
2145  *
2146  * @param name
2147  *   Pointer to the port's name.
2148  *
2149  * @return
2150  *   0 on success, negative error value otherwise.
2151  */
2152 static int
2153 mrvl_eth_dev_create(struct rte_vdev_device *vdev, const char *name)
2154 {
2155         int ret, fd = socket(AF_INET, SOCK_DGRAM, 0);
2156         struct rte_eth_dev *eth_dev;
2157         struct mrvl_priv *priv;
2158         struct ifreq req;
2159
2160         eth_dev = rte_eth_dev_allocate(name);
2161         if (!eth_dev)
2162                 return -ENOMEM;
2163
2164         priv = mrvl_priv_create(name);
2165         if (!priv) {
2166                 ret = -ENOMEM;
2167                 goto out_free_dev;
2168         }
2169
2170         eth_dev->data->mac_addrs =
2171                 rte_zmalloc("mac_addrs",
2172                             ETHER_ADDR_LEN * MRVL_MAC_ADDRS_MAX, 0);
2173         if (!eth_dev->data->mac_addrs) {
2174                 RTE_LOG(ERR, PMD, "Failed to allocate space for eth addrs\n");
2175                 ret = -ENOMEM;
2176                 goto out_free_priv;
2177         }
2178
2179         memset(&req, 0, sizeof(req));
2180         strcpy(req.ifr_name, name);
2181         ret = ioctl(fd, SIOCGIFHWADDR, &req);
2182         if (ret)
2183                 goto out_free_mac;
2184
2185         memcpy(eth_dev->data->mac_addrs[0].addr_bytes,
2186                req.ifr_addr.sa_data, ETHER_ADDR_LEN);
2187
2188         eth_dev->rx_pkt_burst = mrvl_rx_pkt_burst;
2189         eth_dev->tx_pkt_burst = mrvl_tx_pkt_burst;
2190         eth_dev->data->kdrv = RTE_KDRV_NONE;
2191         eth_dev->data->dev_private = priv;
2192         eth_dev->device = &vdev->device;
2193         eth_dev->dev_ops = &mrvl_ops;
2194
2195         return 0;
2196 out_free_mac:
2197         rte_free(eth_dev->data->mac_addrs);
2198 out_free_dev:
2199         rte_eth_dev_release_port(eth_dev);
2200 out_free_priv:
2201         rte_free(priv);
2202
2203         return ret;
2204 }
2205
2206 /**
2207  * Cleanup previously created device representing Ethernet port.
2208  *
2209  * @param name
2210  *   Pointer to the port name.
2211  */
2212 static void
2213 mrvl_eth_dev_destroy(const char *name)
2214 {
2215         struct rte_eth_dev *eth_dev;
2216         struct mrvl_priv *priv;
2217
2218         eth_dev = rte_eth_dev_allocated(name);
2219         if (!eth_dev)
2220                 return;
2221
2222         priv = eth_dev->data->dev_private;
2223         pp2_bpool_deinit(priv->bpool);
2224         used_bpools[priv->pp_id] &= ~(1 << priv->bpool_bit);
2225         rte_free(priv);
2226         rte_free(eth_dev->data->mac_addrs);
2227         rte_eth_dev_release_port(eth_dev);
2228 }
2229
2230 /**
2231  * Callback used by rte_kvargs_process() during argument parsing.
2232  *
2233  * @param key
2234  *   Pointer to the parsed key (unused).
2235  * @param value
2236  *   Pointer to the parsed value.
2237  * @param extra_args
2238  *   Pointer to the extra arguments which contains address of the
2239  *   table of pointers to parsed interface names.
2240  *
2241  * @return
2242  *   Always 0.
2243  */
2244 static int
2245 mrvl_get_ifnames(const char *key __rte_unused, const char *value,
2246                  void *extra_args)
2247 {
2248         struct mrvl_ifnames *ifnames = extra_args;
2249
2250         ifnames->names[ifnames->idx++] = value;
2251
2252         return 0;
2253 }
2254
2255 /**
2256  * Deinitialize per-lcore MUSDK hardware interfaces (hifs).
2257  */
2258 static void
2259 mrvl_deinit_hifs(void)
2260 {
2261         int i;
2262
2263         for (i = mrvl_lcore_first; i <= mrvl_lcore_last; i++) {
2264                 if (hifs[i])
2265                         pp2_hif_deinit(hifs[i]);
2266         }
2267         used_hifs = MRVL_MUSDK_HIFS_RESERVED;
2268         memset(hifs, 0, sizeof(hifs));
2269 }
2270
2271 /**
2272  * DPDK callback to register the virtual device.
2273  *
2274  * @param vdev
2275  *   Pointer to the virtual device.
2276  *
2277  * @return
2278  *   0 on success, negative error value otherwise.
2279  */
2280 static int
2281 rte_pmd_mrvl_probe(struct rte_vdev_device *vdev)
2282 {
2283         struct rte_kvargs *kvlist;
2284         struct mrvl_ifnames ifnames;
2285         int ret = -EINVAL;
2286         uint32_t i, ifnum, cfgnum;
2287         const char *params;
2288
2289         params = rte_vdev_device_args(vdev);
2290         if (!params)
2291                 return -EINVAL;
2292
2293         kvlist = rte_kvargs_parse(params, valid_args);
2294         if (!kvlist)
2295                 return -EINVAL;
2296
2297         ifnum = rte_kvargs_count(kvlist, MRVL_IFACE_NAME_ARG);
2298         if (ifnum > RTE_DIM(ifnames.names))
2299                 goto out_free_kvlist;
2300
2301         ifnames.idx = 0;
2302         rte_kvargs_process(kvlist, MRVL_IFACE_NAME_ARG,
2303                            mrvl_get_ifnames, &ifnames);
2304
2305
2306         /*
2307          * The below system initialization should be done only once,
2308          * on the first provided configuration file
2309          */
2310         if (!mrvl_qos_cfg) {
2311                 cfgnum = rte_kvargs_count(kvlist, MRVL_CFG_ARG);
2312                 RTE_LOG(INFO, PMD, "Parsing config file!\n");
2313                 if (cfgnum > 1) {
2314                         RTE_LOG(ERR, PMD, "Cannot handle more than one config file!\n");
2315                         goto out_free_kvlist;
2316                 } else if (cfgnum == 1) {
2317                         rte_kvargs_process(kvlist, MRVL_CFG_ARG,
2318                                            mrvl_get_qoscfg, &mrvl_qos_cfg);
2319                 }
2320         }
2321
2322         if (mrvl_dev_num)
2323                 goto init_devices;
2324
2325         RTE_LOG(INFO, PMD, "Perform MUSDK initializations\n");
2326         /*
2327          * ret == -EEXIST is correct, it means DMA
2328          * has been already initialized (by another PMD).
2329          */
2330         ret = mv_sys_dma_mem_init(MRVL_MUSDK_DMA_MEMSIZE);
2331         if (ret < 0) {
2332                 if (ret != -EEXIST)
2333                         goto out_free_kvlist;
2334                 else
2335                         RTE_LOG(INFO, PMD,
2336                                 "DMA memory has been already initialized by a different driver.\n");
2337         }
2338
2339         ret = mrvl_init_pp2();
2340         if (ret) {
2341                 RTE_LOG(ERR, PMD, "Failed to init PP!\n");
2342                 goto out_deinit_dma;
2343         }
2344
2345         memset(mrvl_port_bpool_size, 0, sizeof(mrvl_port_bpool_size));
2346
2347         mrvl_lcore_first = RTE_MAX_LCORE;
2348         mrvl_lcore_last = 0;
2349
2350 init_devices:
2351         for (i = 0; i < ifnum; i++) {
2352                 RTE_LOG(INFO, PMD, "Creating %s\n", ifnames.names[i]);
2353                 ret = mrvl_eth_dev_create(vdev, ifnames.names[i]);
2354                 if (ret)
2355                         goto out_cleanup;
2356         }
2357         mrvl_dev_num += ifnum;
2358
2359         rte_kvargs_free(kvlist);
2360
2361         return 0;
2362 out_cleanup:
2363         for (; i > 0; i--)
2364                 mrvl_eth_dev_destroy(ifnames.names[i]);
2365
2366         if (mrvl_dev_num == 0)
2367                 mrvl_deinit_pp2();
2368 out_deinit_dma:
2369         if (mrvl_dev_num == 0)
2370                 mv_sys_dma_mem_destroy();
2371 out_free_kvlist:
2372         rte_kvargs_free(kvlist);
2373
2374         return ret;
2375 }
2376
2377 /**
2378  * DPDK callback to remove virtual device.
2379  *
2380  * @param vdev
2381  *   Pointer to the removed virtual device.
2382  *
2383  * @return
2384  *   0 on success, negative error value otherwise.
2385  */
2386 static int
2387 rte_pmd_mrvl_remove(struct rte_vdev_device *vdev)
2388 {
2389         int i;
2390         const char *name;
2391
2392         name = rte_vdev_device_name(vdev);
2393         if (!name)
2394                 return -EINVAL;
2395
2396         RTE_LOG(INFO, PMD, "Removing %s\n", name);
2397
2398         for (i = 0; i < rte_eth_dev_count(); i++) {
2399                 char ifname[RTE_ETH_NAME_MAX_LEN];
2400
2401                 rte_eth_dev_get_name_by_port(i, ifname);
2402                 mrvl_eth_dev_destroy(ifname);
2403                 mrvl_dev_num--;
2404         }
2405
2406         if (mrvl_dev_num == 0) {
2407                 RTE_LOG(INFO, PMD, "Perform MUSDK deinit\n");
2408                 mrvl_deinit_hifs();
2409                 mrvl_deinit_pp2();
2410                 mv_sys_dma_mem_destroy();
2411         }
2412
2413         return 0;
2414 }
2415
2416 static struct rte_vdev_driver pmd_mrvl_drv = {
2417         .probe = rte_pmd_mrvl_probe,
2418         .remove = rte_pmd_mrvl_remove,
2419 };
2420
2421 RTE_PMD_REGISTER_VDEV(net_mrvl, pmd_mrvl_drv);
2422 RTE_PMD_REGISTER_ALIAS(net_mrvl, eth_mrvl);