xref: /dpdk/drivers/net/mvneta/mvneta_ethdev.c (revision 4ccc8d77)
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 }
626