net/mrvl: add net PMD skeleton
[dpdk.git] / drivers / net / mrvl / mrvl_ethdev.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2017 Semihalf. All rights reserved.
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in
14  *       the documentation and/or other materials provided with the
15  *       distribution.
16  *     * Neither the name of Semihalf nor the names of its
17  *       contributors may be used to endorse or promote products derived
18  *       from this software without specific prior written permission.
19  *
20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include <rte_ethdev.h>
34 #include <rte_kvargs.h>
35 #include <rte_log.h>
36 #include <rte_malloc.h>
37 #include <rte_vdev.h>
38
39 /* Unluckily, container_of is defined by both DPDK and MUSDK,
40  * we'll declare only one version.
41  *
42  * Note that it is not used in this PMD anyway.
43  */
44 #ifdef container_of
45 #undef container_of
46 #endif
47
48 #include <drivers/mv_pp2.h>
49 #include <drivers/mv_pp2_bpool.h>
50 #include <drivers/mv_pp2_hif.h>
51
52 #include <fcntl.h>
53 #include <linux/ethtool.h>
54 #include <linux/sockios.h>
55 #include <net/if.h>
56 #include <net/if_arp.h>
57 #include <sys/ioctl.h>
58 #include <sys/socket.h>
59 #include <sys/stat.h>
60 #include <sys/types.h>
61
62 #include "mrvl_ethdev.h"
63 #include "mrvl_qos.h"
64
65 /* bitmask with reserved hifs */
66 #define MRVL_MUSDK_HIFS_RESERVED 0x0F
67 /* bitmask with reserved bpools */
68 #define MRVL_MUSDK_BPOOLS_RESERVED 0x07
69 /* maximum number of available hifs */
70 #define MRVL_MUSDK_HIFS_MAX 9
71
72 #define MRVL_MAC_ADDRS_MAX 1
73 #define MRVL_MATCH_LEN 16
74 #define MRVL_PKT_EFFEC_OFFS (MRVL_PKT_OFFS + MV_MH_SIZE)
75 /* Maximum allowable packet size */
76 #define MRVL_PKT_SIZE_MAX (10240 - MV_MH_SIZE)
77
78 #define MRVL_IFACE_NAME_ARG "iface"
79 #define MRVL_CFG_ARG "cfg"
80
81 #define MRVL_BURST_SIZE 64
82
83 #define MRVL_ARP_LENGTH 28
84
85 #define MRVL_COOKIE_ADDR_INVALID ~0ULL
86
87 #define MRVL_COOKIE_HIGH_ADDR_SHIFT     (sizeof(pp2_cookie_t) * 8)
88 #define MRVL_COOKIE_HIGH_ADDR_MASK      (~0ULL << MRVL_COOKIE_HIGH_ADDR_SHIFT)
89
90 static const char * const valid_args[] = {
91         MRVL_IFACE_NAME_ARG,
92         MRVL_CFG_ARG,
93         NULL
94 };
95
96 static int used_hifs = MRVL_MUSDK_HIFS_RESERVED;
97 static struct pp2_hif *hifs[RTE_MAX_LCORE];
98 static int used_bpools[PP2_NUM_PKT_PROC] = {
99         MRVL_MUSDK_BPOOLS_RESERVED,
100         MRVL_MUSDK_BPOOLS_RESERVED
101 };
102
103 uint64_t cookie_addr_high = MRVL_COOKIE_ADDR_INVALID;
104
105 struct mrvl_rxq {
106         struct mrvl_priv *priv;
107         struct rte_mempool *mp;
108         int queue_id;
109         int port_id;
110 };
111
112 struct mrvl_txq {
113         struct mrvl_priv *priv;
114         int queue_id;
115         int port_id;
116 };
117
118 /** Number of ports configured. */
119 int mrvl_ports_nb;
120
121 static inline int
122 mrvl_reserve_bit(int *bitmap, int max)
123 {
124         int n = sizeof(*bitmap) * 8 - __builtin_clz(*bitmap);
125
126         if (n >= max)
127                 return -1;
128
129         *bitmap |= 1 << n;
130
131         return n;
132 }
133
134 /**
135  * Ethernet device configuration.
136  *
137  * Prepare the driver for a given number of TX and RX queues.
138  *
139  * @param dev
140  *   Pointer to Ethernet device structure.
141  *
142  * @return
143  *   0 on success, negative error value otherwise.
144  */
145 static int
146 mrvl_dev_configure(struct rte_eth_dev *dev)
147 {
148         struct mrvl_priv *priv = dev->data->dev_private;
149         int ret;
150
151         if (dev->data->dev_conf.rxmode.mq_mode != ETH_MQ_RX_NONE) {
152                 RTE_LOG(INFO, PMD, "Unsupported rx multi queue mode %d\n",
153                         dev->data->dev_conf.rxmode.mq_mode);
154                 return -EINVAL;
155         }
156
157         if (!dev->data->dev_conf.rxmode.hw_strip_crc) {
158                 RTE_LOG(INFO, PMD,
159                         "L2 CRC stripping is always enabled in hw\n");
160                 dev->data->dev_conf.rxmode.hw_strip_crc = 1;
161         }
162
163         if (dev->data->dev_conf.rxmode.hw_vlan_strip) {
164                 RTE_LOG(INFO, PMD, "VLAN stripping not supported\n");
165                 return -EINVAL;
166         }
167
168         if (dev->data->dev_conf.rxmode.split_hdr_size) {
169                 RTE_LOG(INFO, PMD, "Split headers not supported\n");
170                 return -EINVAL;
171         }
172
173         if (dev->data->dev_conf.rxmode.enable_scatter) {
174                 RTE_LOG(INFO, PMD, "RX Scatter/Gather not supported\n");
175                 return -EINVAL;
176         }
177
178         if (dev->data->dev_conf.rxmode.enable_lro) {
179                 RTE_LOG(INFO, PMD, "LRO not supported\n");
180                 return -EINVAL;
181         }
182
183         ret = mrvl_configure_rxqs(priv, dev->data->port_id,
184                                   dev->data->nb_rx_queues);
185         if (ret < 0)
186                 return ret;
187
188         priv->ppio_params.outqs_params.num_outqs = dev->data->nb_tx_queues;
189         priv->nb_rx_queues = dev->data->nb_rx_queues;
190
191         return 0;
192 }
193
194 /**
195  * DPDK callback to bring the link up.
196  *
197  * @param dev
198  *   Pointer to Ethernet device structure.
199  *
200  * @return
201  *   0 on success, negative error value otherwise.
202  */
203 static int
204 mrvl_dev_set_link_up(struct rte_eth_dev *dev)
205 {
206         struct mrvl_priv *priv = dev->data->dev_private;
207         int ret;
208
209         ret = pp2_ppio_enable(priv->ppio);
210         if (ret)
211                 return ret;
212
213         dev->data->dev_link.link_status = ETH_LINK_UP;
214
215         return ret;
216 }
217
218 /**
219  * DPDK callback to bring the link down.
220  *
221  * @param dev
222  *   Pointer to Ethernet device structure.
223  *
224  * @return
225  *   0 on success, negative error value otherwise.
226  */
227 static int
228 mrvl_dev_set_link_down(struct rte_eth_dev *dev)
229 {
230         struct mrvl_priv *priv = dev->data->dev_private;
231         int ret;
232
233         ret = pp2_ppio_disable(priv->ppio);
234         if (ret)
235                 return ret;
236
237         dev->data->dev_link.link_status = ETH_LINK_DOWN;
238
239         return ret;
240 }
241
242 /**
243  * DPDK callback to start the device.
244  *
245  * @param dev
246  *   Pointer to Ethernet device structure.
247  *
248  * @return
249  *   0 on success, negative errno value on failure.
250  */
251 static int
252 mrvl_dev_start(struct rte_eth_dev *dev)
253 {
254         struct mrvl_priv *priv = dev->data->dev_private;
255         char match[MRVL_MATCH_LEN];
256         int ret;
257
258         snprintf(match, sizeof(match), "ppio-%d:%d",
259                  priv->pp_id, priv->ppio_id);
260         priv->ppio_params.match = match;
261
262         /*
263          * Calculate the maximum bpool size for refill feature to 1.5 of the
264          * configured size. In case the bpool size will exceed this value,
265          * superfluous buffers will be removed
266          */
267         priv->bpool_max_size = priv->bpool_init_size +
268                               (priv->bpool_init_size >> 1);
269         /*
270          * Calculate the minimum bpool size for refill feature as follows:
271          * 2 default burst sizes multiply by number of rx queues.
272          * If the bpool size will be below this value, new buffers will
273          * be added to the pool.
274          */
275         priv->bpool_min_size = priv->nb_rx_queues * MRVL_BURST_SIZE * 2;
276
277         ret = pp2_ppio_init(&priv->ppio_params, &priv->ppio);
278         if (ret)
279                 return ret;
280
281         /* For default QoS config, don't start classifier. */
282         if (mrvl_qos_cfg) {
283                 ret = mrvl_start_qos_mapping(priv);
284                 if (ret) {
285                         pp2_ppio_deinit(priv->ppio);
286                         return ret;
287                 }
288         }
289
290         ret = mrvl_dev_set_link_up(dev);
291         if (ret)
292                 goto out;
293
294         return 0;
295 out:
296         pp2_ppio_deinit(priv->ppio);
297         return ret;
298 }
299
300 /**
301  * Flush receive queues.
302  *
303  * @param dev
304  *   Pointer to Ethernet device structure.
305  */
306 static void
307 mrvl_flush_rx_queues(struct rte_eth_dev *dev)
308 {
309         int i;
310
311         RTE_LOG(INFO, PMD, "Flushing rx queues\n");
312         for (i = 0; i < dev->data->nb_rx_queues; i++) {
313                 int ret, num;
314
315                 do {
316                         struct mrvl_rxq *q = dev->data->rx_queues[i];
317                         struct pp2_ppio_desc descs[MRVL_PP2_RXD_MAX];
318
319                         num = MRVL_PP2_RXD_MAX;
320                         ret = pp2_ppio_recv(q->priv->ppio,
321                                             q->priv->rxq_map[q->queue_id].tc,
322                                             q->priv->rxq_map[q->queue_id].inq,
323                                             descs, (uint16_t *)&num);
324                 } while (ret == 0 && num);
325         }
326 }
327
328 /**
329  * Flush hardware bpool (buffer-pool).
330  *
331  * @param dev
332  *   Pointer to Ethernet device structure.
333  */
334 static void
335 mrvl_flush_bpool(struct rte_eth_dev *dev)
336 {
337         struct mrvl_priv *priv = dev->data->dev_private;
338         uint32_t num;
339         int ret;
340
341         ret = pp2_bpool_get_num_buffs(priv->bpool, &num);
342         if (ret) {
343                 RTE_LOG(ERR, PMD, "Failed to get bpool buffers number\n");
344                 return;
345         }
346
347         while (num--) {
348                 struct pp2_buff_inf inf;
349                 uint64_t addr;
350
351                 ret = pp2_bpool_get_buff(hifs[rte_lcore_id()], priv->bpool,
352                                          &inf);
353                 if (ret)
354                         break;
355
356                 addr = cookie_addr_high | inf.cookie;
357                 rte_pktmbuf_free((struct rte_mbuf *)addr);
358         }
359 }
360
361 /**
362  * DPDK callback to stop the device.
363  *
364  * @param dev
365  *   Pointer to Ethernet device structure.
366  */
367 static void
368 mrvl_dev_stop(struct rte_eth_dev *dev)
369 {
370         struct mrvl_priv *priv = dev->data->dev_private;
371
372         mrvl_dev_set_link_down(dev);
373         mrvl_flush_rx_queues(dev);
374         if (priv->qos_tbl)
375                 pp2_cls_qos_tbl_deinit(priv->qos_tbl);
376         pp2_ppio_deinit(priv->ppio);
377         priv->ppio = NULL;
378 }
379
380 /**
381  * DPDK callback to close the device.
382  *
383  * @param dev
384  *   Pointer to Ethernet device structure.
385  */
386 static void
387 mrvl_dev_close(struct rte_eth_dev *dev)
388 {
389         struct mrvl_priv *priv = dev->data->dev_private;
390         size_t i;
391
392         for (i = 0; i < priv->ppio_params.inqs_params.num_tcs; ++i) {
393                 struct pp2_ppio_tc_params *tc_params =
394                         &priv->ppio_params.inqs_params.tcs_params[i];
395
396                 if (tc_params->inqs_params) {
397                         rte_free(tc_params->inqs_params);
398                         tc_params->inqs_params = NULL;
399                 }
400         }
401
402         mrvl_flush_bpool(dev);
403 }
404
405 /**
406  * DPDK callback to set the primary MAC address.
407  *
408  * @param dev
409  *   Pointer to Ethernet device structure.
410  * @param mac_addr
411  *   MAC address to register.
412  */
413 static void
414 mrvl_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
415 {
416         struct mrvl_priv *priv = dev->data->dev_private;
417
418         pp2_ppio_set_mac_addr(priv->ppio, mac_addr->addr_bytes);
419         /*
420          * TODO
421          * Port stops sending packets if pp2_ppio_set_mac_addr()
422          * was called after pp2_ppio_enable(). As a quick fix issue
423          * enable port once again.
424          */
425         pp2_ppio_enable(priv->ppio);
426 }
427
428 /**
429  * DPDK callback to get information about the device.
430  *
431  * @param dev
432  *   Pointer to Ethernet device structure (unused).
433  * @param info
434  *   Info structure output buffer.
435  */
436 static void
437 mrvl_dev_infos_get(struct rte_eth_dev *dev __rte_unused,
438                    struct rte_eth_dev_info *info)
439 {
440         info->max_rx_queues = MRVL_PP2_RXQ_MAX;
441         info->max_tx_queues = MRVL_PP2_TXQ_MAX;
442         info->max_mac_addrs = MRVL_MAC_ADDRS_MAX;
443
444         info->rx_desc_lim.nb_max = MRVL_PP2_RXD_MAX;
445         info->rx_desc_lim.nb_min = MRVL_PP2_RXD_MIN;
446         info->rx_desc_lim.nb_align = MRVL_PP2_RXD_ALIGN;
447
448         info->tx_desc_lim.nb_max = MRVL_PP2_TXD_MAX;
449         info->tx_desc_lim.nb_min = MRVL_PP2_TXD_MIN;
450         info->tx_desc_lim.nb_align = MRVL_PP2_TXD_ALIGN;
451
452         /* By default packets are dropped if no descriptors are available */
453         info->default_rxconf.rx_drop_en = 1;
454
455         info->max_rx_pktlen = MRVL_PKT_SIZE_MAX;
456 }
457
458 /**
459  * DPDK callback to get information about specific receive queue.
460  *
461  * @param dev
462  *   Pointer to Ethernet device structure.
463  * @param rx_queue_id
464  *   Receive queue index.
465  * @param qinfo
466  *   Receive queue information structure.
467  */
468 static void mrvl_rxq_info_get(struct rte_eth_dev *dev, uint16_t rx_queue_id,
469                               struct rte_eth_rxq_info *qinfo)
470 {
471         struct mrvl_rxq *q = dev->data->rx_queues[rx_queue_id];
472         struct mrvl_priv *priv = dev->data->dev_private;
473         int inq = priv->rxq_map[rx_queue_id].inq;
474         int tc = priv->rxq_map[rx_queue_id].tc;
475         struct pp2_ppio_tc_params *tc_params =
476                 &priv->ppio_params.inqs_params.tcs_params[tc];
477
478         qinfo->mp = q->mp;
479         qinfo->nb_desc = tc_params->inqs_params[inq].size;
480 }
481
482 /**
483  * DPDK callback to get information about specific transmit queue.
484  *
485  * @param dev
486  *   Pointer to Ethernet device structure.
487  * @param tx_queue_id
488  *   Transmit queue index.
489  * @param qinfo
490  *   Transmit queue information structure.
491  */
492 static void mrvl_txq_info_get(struct rte_eth_dev *dev, uint16_t tx_queue_id,
493                               struct rte_eth_txq_info *qinfo)
494 {
495         struct mrvl_priv *priv = dev->data->dev_private;
496
497         qinfo->nb_desc =
498                 priv->ppio_params.outqs_params.outqs_params[tx_queue_id].size;
499 }
500
501 /**
502  * Release buffers to hardware bpool (buffer-pool)
503  *
504  * @param rxq
505  *   Receive queue pointer.
506  * @param num
507  *   Number of buffers to release to bpool.
508  *
509  * @return
510  *   0 on success, negative error value otherwise.
511  */
512 static int
513 mrvl_fill_bpool(struct mrvl_rxq *rxq, int num)
514 {
515         struct buff_release_entry entries[MRVL_PP2_TXD_MAX];
516         struct rte_mbuf *mbufs[MRVL_PP2_TXD_MAX];
517         int i, ret;
518         unsigned int core_id = rte_lcore_id();
519         struct pp2_hif *hif = hifs[core_id];
520         struct pp2_bpool *bpool = rxq->priv->bpool;
521
522         ret = rte_pktmbuf_alloc_bulk(rxq->mp, mbufs, num);
523         if (ret)
524                 return ret;
525
526         if (cookie_addr_high == MRVL_COOKIE_ADDR_INVALID)
527                 cookie_addr_high =
528                         (uint64_t)mbufs[0] & MRVL_COOKIE_HIGH_ADDR_MASK;
529
530         for (i = 0; i < num; i++) {
531                 if (((uint64_t)mbufs[i] & MRVL_COOKIE_HIGH_ADDR_MASK)
532                         != cookie_addr_high) {
533                         RTE_LOG(ERR, PMD,
534                                 "mbuf virtual addr high 0x%lx out of range\n",
535                                 (uint64_t)mbufs[i] >> 32);
536                         goto out;
537                 }
538
539                 entries[i].buff.addr =
540                         rte_mbuf_data_dma_addr_default(mbufs[i]);
541                 entries[i].buff.cookie = (pp2_cookie_t)(uint64_t)mbufs[i];
542                 entries[i].bpool = bpool;
543         }
544
545         pp2_bpool_put_buffs(hif, entries, (uint16_t *)&i);
546
547         if (i != num)
548                 goto out;
549
550         return 0;
551 out:
552         for (; i < num; i++)
553                 rte_pktmbuf_free(mbufs[i]);
554
555         return -1;
556 }
557
558 /**
559  * DPDK callback to configure the receive queue.
560  *
561  * @param dev
562  *   Pointer to Ethernet device structure.
563  * @param idx
564  *   RX queue index.
565  * @param desc
566  *   Number of descriptors to configure in queue.
567  * @param socket
568  *   NUMA socket on which memory must be allocated.
569  * @param conf
570  *   Thresholds parameters (unused_).
571  * @param mp
572  *   Memory pool for buffer allocations.
573  *
574  * @return
575  *   0 on success, negative error value otherwise.
576  */
577 static int
578 mrvl_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
579                     unsigned int socket,
580                     const struct rte_eth_rxconf *conf __rte_unused,
581                     struct rte_mempool *mp)
582 {
583         struct mrvl_priv *priv = dev->data->dev_private;
584         struct mrvl_rxq *rxq;
585         uint32_t min_size,
586                  max_rx_pkt_len = dev->data->dev_conf.rxmode.max_rx_pkt_len;
587         int ret, tc, inq;
588
589         if (priv->rxq_map[idx].tc == MRVL_UNKNOWN_TC) {
590                 /*
591                  * Unknown TC mapping, mapping will not have a correct queue.
592                  */
593                 RTE_LOG(ERR, PMD, "Unknown TC mapping for queue %hu eth%hhu\n",
594                         idx, priv->ppio_id);
595                 return -EFAULT;
596         }
597
598         min_size = rte_pktmbuf_data_room_size(mp) - RTE_PKTMBUF_HEADROOM -
599                    MRVL_PKT_EFFEC_OFFS;
600         if (min_size < max_rx_pkt_len) {
601                 RTE_LOG(ERR, PMD,
602                         "Mbuf size must be increased to %u bytes to hold up to %u bytes of data.\n",
603                         max_rx_pkt_len + RTE_PKTMBUF_HEADROOM +
604                         MRVL_PKT_EFFEC_OFFS,
605                         max_rx_pkt_len);
606                 return -EINVAL;
607         }
608
609         if (dev->data->rx_queues[idx]) {
610                 rte_free(dev->data->rx_queues[idx]);
611                 dev->data->rx_queues[idx] = NULL;
612         }
613
614         rxq = rte_zmalloc_socket("rxq", sizeof(*rxq), 0, socket);
615         if (!rxq)
616                 return -ENOMEM;
617
618         rxq->priv = priv;
619         rxq->mp = mp;
620         rxq->queue_id = idx;
621         rxq->port_id = dev->data->port_id;
622
623         tc = priv->rxq_map[rxq->queue_id].tc,
624         inq = priv->rxq_map[rxq->queue_id].inq;
625         priv->ppio_params.inqs_params.tcs_params[tc].inqs_params[inq].size =
626                 desc;
627
628         ret = mrvl_fill_bpool(rxq, desc);
629         if (ret) {
630                 rte_free(rxq);
631                 return ret;
632         }
633
634         priv->bpool_init_size += desc;
635
636         dev->data->rx_queues[idx] = rxq;
637
638         return 0;
639 }
640
641 /**
642  * DPDK callback to release the receive queue.
643  *
644  * @param rxq
645  *   Generic receive queue pointer.
646  */
647 static void
648 mrvl_rx_queue_release(void *rxq)
649 {
650         struct mrvl_rxq *q = rxq;
651         struct pp2_ppio_tc_params *tc_params;
652         int i, num, tc, inq;
653
654         if (!q)
655                 return;
656
657         tc = q->priv->rxq_map[q->queue_id].tc;
658         inq = q->priv->rxq_map[q->queue_id].inq;
659         tc_params = &q->priv->ppio_params.inqs_params.tcs_params[tc];
660         num = tc_params->inqs_params[inq].size;
661         for (i = 0; i < num; i++) {
662                 struct pp2_buff_inf inf;
663                 uint64_t addr;
664
665                 pp2_bpool_get_buff(hifs[rte_lcore_id()], q->priv->bpool, &inf);
666                 addr = cookie_addr_high | inf.cookie;
667                 rte_pktmbuf_free((struct rte_mbuf *)addr);
668         }
669
670         rte_free(q);
671 }
672
673 /**
674  * DPDK callback to configure the transmit queue.
675  *
676  * @param dev
677  *   Pointer to Ethernet device structure.
678  * @param idx
679  *   Transmit queue index.
680  * @param desc
681  *   Number of descriptors to configure in the queue.
682  * @param socket
683  *   NUMA socket on which memory must be allocated.
684  * @param conf
685  *   Thresholds parameters (unused).
686  *
687  * @return
688  *   0 on success, negative error value otherwise.
689  */
690 static int
691 mrvl_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
692                     unsigned int socket,
693                     const struct rte_eth_txconf *conf __rte_unused)
694 {
695         struct mrvl_priv *priv = dev->data->dev_private;
696         struct mrvl_txq *txq;
697
698         if (dev->data->tx_queues[idx]) {
699                 rte_free(dev->data->tx_queues[idx]);
700                 dev->data->tx_queues[idx] = NULL;
701         }
702
703         txq = rte_zmalloc_socket("txq", sizeof(*txq), 0, socket);
704         if (!txq)
705                 return -ENOMEM;
706
707         txq->priv = priv;
708         txq->queue_id = idx;
709         txq->port_id = dev->data->port_id;
710         dev->data->tx_queues[idx] = txq;
711
712         priv->ppio_params.outqs_params.outqs_params[idx].size = desc;
713         priv->ppio_params.outqs_params.outqs_params[idx].weight = 1;
714
715         return 0;
716 }
717
718 /**
719  * DPDK callback to release the transmit queue.
720  *
721  * @param txq
722  *   Generic transmit queue pointer.
723  */
724 static void
725 mrvl_tx_queue_release(void *txq)
726 {
727         struct mrvl_txq *q = txq;
728
729         if (!q)
730                 return;
731
732         rte_free(q);
733 }
734
735 static const struct eth_dev_ops mrvl_ops = {
736         .dev_configure = mrvl_dev_configure,
737         .dev_start = mrvl_dev_start,
738         .dev_stop = mrvl_dev_stop,
739         .dev_set_link_up = mrvl_dev_set_link_up,
740         .dev_set_link_down = mrvl_dev_set_link_down,
741         .dev_close = mrvl_dev_close,
742         .mac_addr_set = mrvl_mac_addr_set,
743         .dev_infos_get = mrvl_dev_infos_get,
744         .rxq_info_get = mrvl_rxq_info_get,
745         .txq_info_get = mrvl_txq_info_get,
746         .rx_queue_setup = mrvl_rx_queue_setup,
747         .rx_queue_release = mrvl_rx_queue_release,
748         .tx_queue_setup = mrvl_tx_queue_setup,
749         .tx_queue_release = mrvl_tx_queue_release,
750 };
751
752 /**
753  * Initialize packet processor.
754  *
755  * @return
756  *   0 on success, negative error value otherwise.
757  */
758 static int
759 mrvl_init_pp2(void)
760 {
761         struct pp2_init_params init_params;
762
763         memset(&init_params, 0, sizeof(init_params));
764         init_params.hif_reserved_map = MRVL_MUSDK_HIFS_RESERVED;
765         init_params.bm_pool_reserved_map = MRVL_MUSDK_BPOOLS_RESERVED;
766
767         return pp2_init(&init_params);
768 }
769
770 /**
771  * Deinitialize packet processor.
772  *
773  * @return
774  *   0 on success, negative error value otherwise.
775  */
776 static void
777 mrvl_deinit_pp2(void)
778 {
779         pp2_deinit();
780 }
781
782 /**
783  * Create private device structure.
784  *
785  * @param dev_name
786  *   Pointer to the port name passed in the initialization parameters.
787  *
788  * @return
789  *   Pointer to the newly allocated private device structure.
790  */
791 static struct mrvl_priv *
792 mrvl_priv_create(const char *dev_name)
793 {
794         struct pp2_bpool_params bpool_params;
795         char match[MRVL_MATCH_LEN];
796         struct mrvl_priv *priv;
797         int ret, bpool_bit;
798
799         priv = rte_zmalloc_socket(dev_name, sizeof(*priv), 0, rte_socket_id());
800         if (!priv)
801                 return NULL;
802
803         ret = pp2_netdev_get_ppio_info((char *)(uintptr_t)dev_name,
804                                        &priv->pp_id, &priv->ppio_id);
805         if (ret)
806                 goto out_free_priv;
807
808         bpool_bit = mrvl_reserve_bit(&used_bpools[priv->pp_id],
809                                      PP2_BPOOL_NUM_POOLS);
810         if (bpool_bit < 0)
811                 goto out_free_priv;
812         priv->bpool_bit = bpool_bit;
813
814         snprintf(match, sizeof(match), "pool-%d:%d", priv->pp_id,
815                  priv->bpool_bit);
816         memset(&bpool_params, 0, sizeof(bpool_params));
817         bpool_params.match = match;
818         bpool_params.buff_len = MRVL_PKT_SIZE_MAX + MRVL_PKT_EFFEC_OFFS;
819         ret = pp2_bpool_init(&bpool_params, &priv->bpool);
820         if (ret)
821                 goto out_clear_bpool_bit;
822
823         priv->ppio_params.type = PP2_PPIO_T_NIC;
824
825         return priv;
826 out_clear_bpool_bit:
827         used_bpools[priv->pp_id] &= ~(1 << priv->bpool_bit);
828 out_free_priv:
829         rte_free(priv);
830         return NULL;
831 }
832
833 /**
834  * Create device representing Ethernet port.
835  *
836  * @param name
837  *   Pointer to the port's name.
838  *
839  * @return
840  *   0 on success, negative error value otherwise.
841  */
842 static int
843 mrvl_eth_dev_create(struct rte_vdev_device *vdev, const char *name)
844 {
845         int ret, fd = socket(AF_INET, SOCK_DGRAM, 0);
846         struct rte_eth_dev *eth_dev;
847         struct mrvl_priv *priv;
848         struct ifreq req;
849
850         eth_dev = rte_eth_dev_allocate(name);
851         if (!eth_dev)
852                 return -ENOMEM;
853
854         priv = mrvl_priv_create(name);
855         if (!priv) {
856                 ret = -ENOMEM;
857                 goto out_free_dev;
858         }
859
860         eth_dev->data->mac_addrs =
861                 rte_zmalloc("mac_addrs",
862                             ETHER_ADDR_LEN * MRVL_MAC_ADDRS_MAX, 0);
863         if (!eth_dev->data->mac_addrs) {
864                 RTE_LOG(ERR, PMD, "Failed to allocate space for eth addrs\n");
865                 ret = -ENOMEM;
866                 goto out_free_priv;
867         }
868
869         memset(&req, 0, sizeof(req));
870         strcpy(req.ifr_name, name);
871         ret = ioctl(fd, SIOCGIFHWADDR, &req);
872         if (ret)
873                 goto out_free_mac;
874
875         memcpy(eth_dev->data->mac_addrs[0].addr_bytes,
876                req.ifr_addr.sa_data, ETHER_ADDR_LEN);
877
878         eth_dev->data->dev_private = priv;
879         eth_dev->device = &vdev->device;
880         eth_dev->dev_ops = &mrvl_ops;
881
882         return 0;
883 out_free_mac:
884         rte_free(eth_dev->data->mac_addrs);
885 out_free_dev:
886         rte_eth_dev_release_port(eth_dev);
887 out_free_priv:
888         rte_free(priv);
889
890         return ret;
891 }
892
893 /**
894  * Cleanup previously created device representing Ethernet port.
895  *
896  * @param name
897  *   Pointer to the port name.
898  */
899 static void
900 mrvl_eth_dev_destroy(const char *name)
901 {
902         struct rte_eth_dev *eth_dev;
903         struct mrvl_priv *priv;
904
905         eth_dev = rte_eth_dev_allocated(name);
906         if (!eth_dev)
907                 return;
908
909         priv = eth_dev->data->dev_private;
910         pp2_bpool_deinit(priv->bpool);
911         rte_free(priv);
912         rte_free(eth_dev->data->mac_addrs);
913         rte_eth_dev_release_port(eth_dev);
914 }
915
916 /**
917  * Callback used by rte_kvargs_process() during argument parsing.
918  *
919  * @param key
920  *   Pointer to the parsed key (unused).
921  * @param value
922  *   Pointer to the parsed value.
923  * @param extra_args
924  *   Pointer to the extra arguments which contains address of the
925  *   table of pointers to parsed interface names.
926  *
927  * @return
928  *   Always 0.
929  */
930 static int
931 mrvl_get_ifnames(const char *key __rte_unused, const char *value,
932                  void *extra_args)
933 {
934         const char **ifnames = extra_args;
935
936         ifnames[mrvl_ports_nb++] = value;
937
938         return 0;
939 }
940
941 /**
942  * Initialize per-lcore MUSDK hardware interfaces (hifs).
943  *
944  * @return
945  *   0 on success, negative error value otherwise.
946  */
947 static int
948 mrvl_init_hifs(void)
949 {
950         struct pp2_hif_params params;
951         char match[MRVL_MATCH_LEN];
952         int i, ret;
953
954         RTE_LCORE_FOREACH(i) {
955                 ret = mrvl_reserve_bit(&used_hifs, MRVL_MUSDK_HIFS_MAX);
956                 if (ret < 0)
957                         return ret;
958
959                 snprintf(match, sizeof(match), "hif-%d", ret);
960                 memset(&params, 0, sizeof(params));
961                 params.match = match;
962                 params.out_size = MRVL_PP2_AGGR_TXQD_MAX;
963                 ret = pp2_hif_init(&params, &hifs[i]);
964                 if (ret) {
965                         RTE_LOG(ERR, PMD, "Failed to initialize hif %d\n", i);
966                         return ret;
967                 }
968         }
969
970         return 0;
971 }
972
973 /**
974  * Deinitialize per-lcore MUSDK hardware interfaces (hifs).
975  */
976 static void
977 mrvl_deinit_hifs(void)
978 {
979         int i;
980
981         RTE_LCORE_FOREACH(i) {
982                 if (hifs[i])
983                         pp2_hif_deinit(hifs[i]);
984         }
985 }
986
987 /**
988  * DPDK callback to register the virtual device.
989  *
990  * @param vdev
991  *   Pointer to the virtual device.
992  *
993  * @return
994  *   0 on success, negative error value otherwise.
995  */
996 static int
997 rte_pmd_mrvl_probe(struct rte_vdev_device *vdev)
998 {
999         struct rte_kvargs *kvlist;
1000         const char *ifnames[PP2_NUM_ETH_PPIO * PP2_NUM_PKT_PROC];
1001         int ret = -EINVAL;
1002         uint32_t i, ifnum, cfgnum;
1003         const char *params;
1004
1005         params = rte_vdev_device_args(vdev);
1006         if (!params)
1007                 return -EINVAL;
1008
1009         kvlist = rte_kvargs_parse(params, valid_args);
1010         if (!kvlist)
1011                 return -EINVAL;
1012
1013         ifnum = rte_kvargs_count(kvlist, MRVL_IFACE_NAME_ARG);
1014         if (ifnum > RTE_DIM(ifnames))
1015                 goto out_free_kvlist;
1016
1017         rte_kvargs_process(kvlist, MRVL_IFACE_NAME_ARG,
1018                            mrvl_get_ifnames, &ifnames);
1019
1020         cfgnum = rte_kvargs_count(kvlist, MRVL_CFG_ARG);
1021         if (cfgnum > 1) {
1022                 RTE_LOG(ERR, PMD, "Cannot handle more than one config file!\n");
1023                 goto out_free_kvlist;
1024         } else if (cfgnum == 1) {
1025                 rte_kvargs_process(kvlist, MRVL_CFG_ARG,
1026                                    mrvl_get_qoscfg, &mrvl_qos_cfg);
1027         }
1028
1029         /*
1030          * ret == -EEXIST is correct, it means DMA
1031          * has been already initialized (by another PMD).
1032          */
1033         ret = mv_sys_dma_mem_init(RTE_MRVL_MUSDK_DMA_MEMSIZE);
1034         if (ret < 0 && ret != -EEXIST)
1035                 goto out_free_kvlist;
1036
1037         ret = mrvl_init_pp2();
1038         if (ret) {
1039                 RTE_LOG(ERR, PMD, "Failed to init PP!\n");
1040                 goto out_deinit_dma;
1041         }
1042
1043         ret = mrvl_init_hifs();
1044         if (ret)
1045                 goto out_deinit_hifs;
1046
1047         for (i = 0; i < ifnum; i++) {
1048                 RTE_LOG(INFO, PMD, "Creating %s\n", ifnames[i]);
1049                 ret = mrvl_eth_dev_create(vdev, ifnames[i]);
1050                 if (ret)
1051                         goto out_cleanup;
1052         }
1053
1054         rte_kvargs_free(kvlist);
1055
1056         return 0;
1057 out_cleanup:
1058         for (; i > 0; i--)
1059                 mrvl_eth_dev_destroy(ifnames[i]);
1060 out_deinit_hifs:
1061         mrvl_deinit_hifs();
1062         mrvl_deinit_pp2();
1063 out_deinit_dma:
1064         mv_sys_dma_mem_destroy();
1065 out_free_kvlist:
1066         rte_kvargs_free(kvlist);
1067
1068         return ret;
1069 }
1070
1071 /**
1072  * DPDK callback to remove virtual device.
1073  *
1074  * @param vdev
1075  *   Pointer to the removed virtual device.
1076  *
1077  * @return
1078  *   0 on success, negative error value otherwise.
1079  */
1080 static int
1081 rte_pmd_mrvl_remove(struct rte_vdev_device *vdev)
1082 {
1083         int i;
1084         const char *name;
1085
1086         name = rte_vdev_device_name(vdev);
1087         if (!name)
1088                 return -EINVAL;
1089
1090         RTE_LOG(INFO, PMD, "Removing %s\n", name);
1091
1092         for (i = 0; i < rte_eth_dev_count(); i++) {
1093                 char ifname[RTE_ETH_NAME_MAX_LEN];
1094
1095                 rte_eth_dev_get_name_by_port(i, ifname);
1096                 mrvl_eth_dev_destroy(ifname);
1097         }
1098
1099         mrvl_deinit_hifs();
1100         mrvl_deinit_pp2();
1101         mv_sys_dma_mem_destroy();
1102
1103         return 0;
1104 }
1105
1106 static struct rte_vdev_driver pmd_mrvl_drv = {
1107         .probe = rte_pmd_mrvl_probe,
1108         .remove = rte_pmd_mrvl_remove,
1109 };
1110
1111 RTE_PMD_REGISTER_VDEV(net_mrvl, pmd_mrvl_drv);
1112 RTE_PMD_REGISTER_ALIAS(net_mrvl, eth_mrvl);