net/mvneta: add PMD skeleton
[dpdk.git] / drivers / net / mvneta / mvneta_ethdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Marvell International Ltd.
3  * Copyright(c) 2018 Semihalf.
4  * All rights reserved.
5  */
6
7 #include <rte_ethdev_driver.h>
8 #include <rte_kvargs.h>
9 #include <rte_log.h>
10 #include <rte_malloc.h>
11 #include <rte_bus_vdev.h>
12
13 #include <stdio.h>
14 #include <fcntl.h>
15 #include <linux/ethtool.h>
16 #include <linux/sockios.h>
17 #include <net/if.h>
18 #include <net/if_arp.h>
19 #include <sys/ioctl.h>
20 #include <sys/socket.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23
24 #include <rte_mvep_common.h>
25
26 #include "mvneta_ethdev.h"
27
28
29 #define MVNETA_IFACE_NAME_ARG "iface"
30
31 #define MVNETA_RX_OFFLOADS (DEV_RX_OFFLOAD_JUMBO_FRAME | \
32                           DEV_RX_OFFLOAD_CHECKSUM)
33
34 /** Port Tx offloads capabilities */
35 #define MVNETA_TX_OFFLOADS (DEV_TX_OFFLOAD_IPV4_CKSUM | \
36                           DEV_TX_OFFLOAD_UDP_CKSUM | \
37                           DEV_TX_OFFLOAD_TCP_CKSUM | \
38                           DEV_TX_OFFLOAD_MULTI_SEGS)
39
40 #define MVNETA_PKT_SIZE_MAX (16382 - MV_MH_SIZE) /* 9700B */
41 #define MVNETA_DEFAULT_MTU 1500
42
43 #define MVNETA_MAC_ADDRS_MAX 256 /*16 UC, 256 IP, 256 MC/BC */
44 /** Maximum length of a match string */
45 #define MVNETA_MATCH_LEN 16
46
47 int mvneta_logtype;
48
49 static const char * const valid_args[] = {
50         MVNETA_IFACE_NAME_ARG,
51         NULL
52 };
53
54 struct mvneta_ifnames {
55         const char *names[NETA_NUM_ETH_PPIO];
56         int idx;
57 };
58
59 static int mvneta_dev_num;
60
61 /**
62  * Deinitialize packet processor.
63  */
64 static void
65 mvneta_neta_deinit(void)
66 {
67         neta_deinit();
68 }
69
70 /**
71  * Initialize packet processor.
72  *
73  * @return
74  *   0 on success, negative error value otherwise.
75  */
76 static int
77 mvneta_neta_init(void)
78 {
79         return neta_init();
80 }
81
82 /**
83  * Callback used by rte_kvargs_process() during argument parsing.
84  *
85  * @param key
86  *   Pointer to the parsed key (unused).
87  * @param value
88  *   Pointer to the parsed value.
89  * @param extra_args
90  *   Pointer to the extra arguments which contains address of the
91  *   table of pointers to parsed interface names.
92  *
93  * @return
94  *   Always 0.
95  */
96 static int
97 mvneta_ifnames_get(const char *key __rte_unused, const char *value,
98                  void *extra_args)
99 {
100         struct mvneta_ifnames *ifnames = extra_args;
101
102         ifnames->names[ifnames->idx++] = value;
103
104         return 0;
105 }
106
107 /**
108  * Ethernet device configuration.
109  *
110  * Prepare the driver for a given number of TX and RX queues and
111  * configure RSS if supported.
112  *
113  * @param dev
114  *   Pointer to Ethernet device structure.
115  *
116  * @return
117  *   0 on success, negative error value otherwise.
118  */
119 static int
120 mvneta_dev_configure(struct rte_eth_dev *dev)
121 {
122         struct mvneta_priv *priv = dev->data->dev_private;
123         struct neta_ppio_params *ppio_params;
124
125         if (dev->data->dev_conf.rxmode.mq_mode != ETH_MQ_RX_NONE) {
126                 MVNETA_LOG(INFO, "Unsupported RSS and rx multi queue mode %d",
127                         dev->data->dev_conf.rxmode.mq_mode);
128                 if (dev->data->nb_rx_queues > 1)
129                         return -EINVAL;
130         }
131
132         if (dev->data->dev_conf.rxmode.split_hdr_size) {
133                 MVNETA_LOG(INFO, "Split headers not supported");
134                 return -EINVAL;
135         }
136
137         if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME)
138                 dev->data->mtu = dev->data->dev_conf.rxmode.max_rx_pkt_len -
139                                  MRVL_NETA_ETH_HDRS_LEN;
140
141         if (dev->data->dev_conf.txmode.offloads & DEV_TX_OFFLOAD_MULTI_SEGS)
142                 priv->multiseg = 1;
143
144         ppio_params = &priv->ppio_params;
145         ppio_params->outqs_params.num_outqs = dev->data->nb_tx_queues;
146         /* Default: 1 TC, no QoS supported. */
147         ppio_params->inqs_params.num_tcs = 1;
148         ppio_params->inqs_params.tcs_params[0].pkt_offset = MRVL_NETA_PKT_OFFS;
149         priv->ppio_id = dev->data->port_id;
150
151         return 0;
152 }
153
154 /**
155  * DPDK callback to get information about the device.
156  *
157  * @param dev
158  *   Pointer to Ethernet device structure (unused).
159  * @param info
160  *   Info structure output buffer.
161  */
162 static void
163 mvneta_dev_infos_get(struct rte_eth_dev *dev __rte_unused,
164                    struct rte_eth_dev_info *info)
165 {
166         info->speed_capa = ETH_LINK_SPEED_10M |
167                            ETH_LINK_SPEED_100M |
168                            ETH_LINK_SPEED_1G |
169                            ETH_LINK_SPEED_2_5G;
170
171         info->max_rx_queues = MRVL_NETA_RXQ_MAX;
172         info->max_tx_queues = MRVL_NETA_TXQ_MAX;
173         info->max_mac_addrs = MVNETA_MAC_ADDRS_MAX;
174
175         info->rx_desc_lim.nb_max = MRVL_NETA_RXD_MAX;
176         info->rx_desc_lim.nb_min = MRVL_NETA_RXD_MIN;
177         info->rx_desc_lim.nb_align = MRVL_NETA_RXD_ALIGN;
178
179         info->tx_desc_lim.nb_max = MRVL_NETA_TXD_MAX;
180         info->tx_desc_lim.nb_min = MRVL_NETA_TXD_MIN;
181         info->tx_desc_lim.nb_align = MRVL_NETA_TXD_ALIGN;
182
183         info->rx_offload_capa = MVNETA_RX_OFFLOADS;
184         info->rx_queue_offload_capa = MVNETA_RX_OFFLOADS;
185
186         info->tx_offload_capa =  MVNETA_TX_OFFLOADS;
187         info->tx_queue_offload_capa =  MVNETA_TX_OFFLOADS;
188
189         /* By default packets are dropped if no descriptors are available */
190         info->default_rxconf.rx_drop_en = 1;
191         /* Deferred tx queue start is not supported */
192         info->default_txconf.tx_deferred_start = 0;
193         info->default_txconf.offloads = 0;
194
195         info->max_rx_pktlen = MVNETA_PKT_SIZE_MAX;
196 }
197
198 /**
199  * Return supported packet types.
200  *
201  * @param dev
202  *   Pointer to Ethernet device structure (unused).
203  *
204  * @return
205  *   Const pointer to the table with supported packet types.
206  */
207 static const uint32_t *
208 mvneta_dev_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused)
209 {
210         static const uint32_t ptypes[] = {
211                 RTE_PTYPE_L2_ETHER,
212                 RTE_PTYPE_L2_ETHER_VLAN,
213                 RTE_PTYPE_L3_IPV4,
214                 RTE_PTYPE_L3_IPV6,
215                 RTE_PTYPE_L4_TCP,
216                 RTE_PTYPE_L4_UDP
217         };
218
219         return ptypes;
220 }
221
222 /**
223  * DPDK callback to bring the link up.
224  *
225  * @param dev
226  *   Pointer to Ethernet device structure.
227  *
228  * @return
229  *   0 on success, negative error value otherwise.
230  */
231 static int
232 mvneta_dev_set_link_up(struct rte_eth_dev *dev)
233 {
234         struct mvneta_priv *priv = dev->data->dev_private;
235
236         if (!priv->ppio)
237                 return 0;
238
239         return neta_ppio_enable(priv->ppio);
240 }
241
242 /**
243  * DPDK callback to bring the link down.
244  *
245  * @param dev
246  *   Pointer to Ethernet device structure.
247  *
248  * @return
249  *   0 on success, negative error value otherwise.
250  */
251 static int
252 mvneta_dev_set_link_down(struct rte_eth_dev *dev)
253 {
254         struct mvneta_priv *priv = dev->data->dev_private;
255
256         if (!priv->ppio)
257                 return 0;
258
259         return neta_ppio_disable(priv->ppio);
260 }
261
262 /**
263  * DPDK callback to start the device.
264  *
265  * @param dev
266  *   Pointer to Ethernet device structure.
267  *
268  * @return
269  *   0 on success, negative errno value on failure.
270  */
271 static int
272 mvneta_dev_start(struct rte_eth_dev *dev)
273 {
274         struct mvneta_priv *priv = dev->data->dev_private;
275         char match[MVNETA_MATCH_LEN];
276         int ret = 0, i;
277
278         if (priv->ppio)
279                 return mvneta_dev_set_link_up(dev);
280
281         snprintf(match, sizeof(match), "%s", dev->data->name);
282         priv->ppio_params.match = match;
283         priv->ppio_params.inqs_params.mtu = dev->data->mtu;
284
285         ret = neta_ppio_init(&priv->ppio_params, &priv->ppio);
286         if (ret) {
287                 MVNETA_LOG(ERR, "Failed to init ppio");
288                 return ret;
289         }
290         priv->ppio_id = priv->ppio->port_id;
291
292         /*
293          * In case there are some some stale uc/mc mac addresses flush them
294          * here. It cannot be done during mvneta_dev_close() as port information
295          * is already gone at that point (due to neta_ppio_deinit() in
296          * mvneta_dev_stop()).
297          */
298         if (!priv->uc_mc_flushed) {
299                 ret = neta_ppio_flush_mac_addrs(priv->ppio, 0, 1);
300                 if (ret) {
301                         MVNETA_LOG(ERR,
302                                 "Failed to flush uc/mc filter list");
303                         goto out;
304                 }
305                 priv->uc_mc_flushed = 1;
306         }
307
308         ret = mvneta_dev_set_link_up(dev);
309         if (ret) {
310                 MVNETA_LOG(ERR, "Failed to set link up");
311                 goto out;
312         }
313
314         /* start tx queues */
315         for (i = 0; i < dev->data->nb_tx_queues; i++)
316                 dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
317
318         return 0;
319
320 out:
321         MVNETA_LOG(ERR, "Failed to start device");
322         neta_ppio_deinit(priv->ppio);
323         return ret;
324 }
325
326 /**
327  * DPDK callback to stop the device.
328  *
329  * @param dev
330  *   Pointer to Ethernet device structure.
331  */
332 static void
333 mvneta_dev_stop(struct rte_eth_dev *dev)
334 {
335         struct mvneta_priv *priv = dev->data->dev_private;
336
337         if (!priv->ppio)
338                 return;
339
340         mvneta_dev_set_link_down(dev);
341
342         neta_ppio_deinit(priv->ppio);
343
344         priv->ppio = NULL;
345 }
346
347 /**
348  * DPDK callback to close the device.
349  *
350  * @param dev
351  *   Pointer to Ethernet device structure.
352  */
353 static void
354 mvneta_dev_close(struct rte_eth_dev *dev)
355 {
356         struct mvneta_priv *priv = dev->data->dev_private;
357
358         if (priv->ppio)
359                 mvneta_dev_stop(dev);
360 }
361
362 /**
363  * DPDK callback to set the primary MAC address.
364  *
365  * @param dev
366  *   Pointer to Ethernet device structure.
367  * @param mac_addr
368  *   MAC address to register.
369  */
370 static int
371 mvneta_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
372 {
373         struct mvneta_priv *priv = dev->data->dev_private;
374         int ret;
375
376         if (!priv->ppio)
377                 return -EINVAL;
378
379         ret = neta_ppio_set_mac_addr(priv->ppio, mac_addr->addr_bytes);
380         if (ret) {
381                 char buf[ETHER_ADDR_FMT_SIZE];
382                 ether_format_addr(buf, sizeof(buf), mac_addr);
383                 MVNETA_LOG(ERR, "Failed to set mac to %s", buf);
384         }
385         return 0;
386 }
387
388 static const struct eth_dev_ops mvneta_ops = {
389         .dev_configure = mvneta_dev_configure,
390         .dev_start = mvneta_dev_start,
391         .dev_stop = mvneta_dev_stop,
392         .dev_set_link_up = mvneta_dev_set_link_up,
393         .dev_set_link_down = mvneta_dev_set_link_down,
394         .dev_close = mvneta_dev_close,
395         .mac_addr_set = mvneta_mac_addr_set,
396         .dev_infos_get = mvneta_dev_infos_get,
397         .dev_supported_ptypes_get = mvneta_dev_supported_ptypes_get,
398 };
399
400 /**
401  * Create device representing Ethernet port.
402  *
403  * @param name
404  *   Pointer to the port's name.
405  *
406  * @return
407  *   0 on success, negative error value otherwise.
408  */
409 static int
410 mvneta_eth_dev_create(struct rte_vdev_device *vdev, const char *name)
411 {
412         int ret, fd = socket(AF_INET, SOCK_DGRAM, 0);
413         struct rte_eth_dev *eth_dev;
414         struct mvneta_priv *priv;
415         struct ifreq req;
416
417         eth_dev = rte_eth_dev_allocate(name);
418         if (!eth_dev)
419                 return -ENOMEM;
420
421         priv = rte_zmalloc_socket(name, sizeof(*priv), 0, rte_socket_id());
422         if (!priv) {
423                 ret = -ENOMEM;
424                 goto out_free_dev;
425         }
426
427         eth_dev->data->mac_addrs =
428                 rte_zmalloc("mac_addrs",
429                             ETHER_ADDR_LEN * MVNETA_MAC_ADDRS_MAX, 0);
430         if (!eth_dev->data->mac_addrs) {
431                 MVNETA_LOG(ERR, "Failed to allocate space for eth addrs");
432                 ret = -ENOMEM;
433                 goto out_free_priv;
434         }
435
436         memset(&req, 0, sizeof(req));
437         strcpy(req.ifr_name, name);
438         ret = ioctl(fd, SIOCGIFHWADDR, &req);
439         if (ret)
440                 goto out_free_mac;
441
442         memcpy(eth_dev->data->mac_addrs[0].addr_bytes,
443                req.ifr_addr.sa_data, ETHER_ADDR_LEN);
444
445         eth_dev->data->kdrv = RTE_KDRV_NONE;
446         eth_dev->data->dev_private = priv;
447         eth_dev->device = &vdev->device;
448         eth_dev->dev_ops = &mvneta_ops;
449
450         rte_eth_dev_probing_finish(eth_dev);
451         return 0;
452 out_free_mac:
453         rte_free(eth_dev->data->mac_addrs);
454 out_free_priv:
455         rte_free(priv);
456 out_free_dev:
457         rte_eth_dev_release_port(eth_dev);
458
459         return ret;
460 }
461
462 /**
463  * Cleanup previously created device representing Ethernet port.
464  *
465  * @param eth_dev
466  *   Pointer to the corresponding rte_eth_dev structure.
467  */
468 static void
469 mvneta_eth_dev_destroy(struct rte_eth_dev *eth_dev)
470 {
471         rte_free(eth_dev->data->dev_private);
472         rte_free(eth_dev->data->mac_addrs);
473         rte_eth_dev_release_port(eth_dev);
474 }
475
476 /**
477  * Cleanup previously created device representing Ethernet port.
478  *
479  * @param name
480  *   Pointer to the port name.
481  */
482 static void
483 mvneta_eth_dev_destroy_name(const char *name)
484 {
485         struct rte_eth_dev *eth_dev;
486
487         eth_dev = rte_eth_dev_allocated(name);
488         if (!eth_dev)
489                 return;
490
491         mvneta_eth_dev_destroy(eth_dev);
492 }
493
494 /**
495  * DPDK callback to register the virtual device.
496  *
497  * @param vdev
498  *   Pointer to the virtual device.
499  *
500  * @return
501  *   0 on success, negative error value otherwise.
502  */
503 static int
504 rte_pmd_mvneta_probe(struct rte_vdev_device *vdev)
505 {
506         struct rte_kvargs *kvlist;
507         struct mvneta_ifnames ifnames;
508         int ret = -EINVAL;
509         uint32_t i, ifnum;
510         const char *params;
511
512         params = rte_vdev_device_args(vdev);
513         if (!params)
514                 return -EINVAL;
515
516         kvlist = rte_kvargs_parse(params, valid_args);
517         if (!kvlist)
518                 return -EINVAL;
519
520         ifnum = rte_kvargs_count(kvlist, MVNETA_IFACE_NAME_ARG);
521         if (ifnum > RTE_DIM(ifnames.names))
522                 goto out_free_kvlist;
523
524         ifnames.idx = 0;
525         rte_kvargs_process(kvlist, MVNETA_IFACE_NAME_ARG,
526                            mvneta_ifnames_get, &ifnames);
527
528         /*
529          * The below system initialization should be done only once,
530          * on the first provided configuration file
531          */
532         if (mvneta_dev_num)
533                 goto init_devices;
534
535         MVNETA_LOG(INFO, "Perform MUSDK initializations");
536
537         ret = rte_mvep_init(MVEP_MOD_T_NETA, kvlist);
538         if (ret)
539                 goto out_free_kvlist;
540
541         ret = mvneta_neta_init();
542         if (ret) {
543                 MVNETA_LOG(ERR, "Failed to init NETA!");
544                 rte_mvep_deinit(MVEP_MOD_T_NETA);
545                 goto out_free_kvlist;
546         }
547
548 init_devices:
549         for (i = 0; i < ifnum; i++) {
550                 MVNETA_LOG(INFO, "Creating %s", ifnames.names[i]);
551                 ret = mvneta_eth_dev_create(vdev, ifnames.names[i]);
552                 if (ret)
553                         goto out_cleanup;
554         }
555         mvneta_dev_num += ifnum;
556
557         rte_kvargs_free(kvlist);
558
559         return 0;
560 out_cleanup:
561         for (; i > 0; i--)
562                 mvneta_eth_dev_destroy_name(ifnames.names[i]);
563
564         if (mvneta_dev_num == 0) {
565                 mvneta_neta_deinit();
566                 rte_mvep_deinit(MVEP_MOD_T_NETA);
567         }
568 out_free_kvlist:
569         rte_kvargs_free(kvlist);
570
571         return ret;
572 }
573
574 /**
575  * DPDK callback to remove virtual device.
576  *
577  * @param vdev
578  *   Pointer to the removed virtual device.
579  *
580  * @return
581  *   0 on success, negative error value otherwise.
582  */
583 static int
584 rte_pmd_mvneta_remove(struct rte_vdev_device *vdev)
585 {
586         int i;
587         const char *name;
588
589         name = rte_vdev_device_name(vdev);
590         if (!name)
591                 return -EINVAL;
592
593         MVNETA_LOG(INFO, "Removing %s", name);
594
595         RTE_ETH_FOREACH_DEV(i) {
596                 if (rte_eth_devices[i].device != &vdev->device)
597                         continue;
598
599                 mvneta_eth_dev_destroy(&rte_eth_devices[i]);
600                 mvneta_dev_num--;
601         }
602
603         if (mvneta_dev_num == 0) {
604                 MVNETA_LOG(INFO, "Perform MUSDK deinit");
605                 mvneta_neta_deinit();
606                 rte_mvep_deinit(MVEP_MOD_T_NETA);
607         }
608
609         return 0;
610 }
611
612 static struct rte_vdev_driver pmd_mvneta_drv = {
613         .probe = rte_pmd_mvneta_probe,
614         .remove = rte_pmd_mvneta_remove,
615 };
616
617 RTE_PMD_REGISTER_VDEV(net_mvneta, pmd_mvneta_drv);
618 RTE_PMD_REGISTER_PARAM_STRING(net_mvneta, "iface=<ifc>");
619
620 RTE_INIT(mvneta_init_log)
621 {
622         mvneta_logtype = rte_log_register("pmd.net.mvneta");
623         if (mvneta_logtype >= 0)
624                 rte_log_set_level(mvneta_logtype, RTE_LOG_NOTICE);
625 }