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_string_fns.h> 8 #include <ethdev_driver.h> 9 #include <rte_kvargs.h> 10 #include <rte_bus_vdev.h> 11 12 #include <stdio.h> 13 #include <fcntl.h> 14 #include <linux/ethtool.h> 15 #include <linux/sockios.h> 16 #include <net/if.h> 17 #include <net/if_arp.h> 18 #include <sys/ioctl.h> 19 #include <sys/socket.h> 20 #include <sys/stat.h> 21 #include <sys/types.h> 22 23 #include <rte_mvep_common.h> 24 25 #include "mvneta_rxtx.h" 26 27 28 #define MVNETA_IFACE_NAME_ARG "iface" 29 30 #define MVNETA_PKT_SIZE_MAX (16382 - MV_MH_SIZE) /* 9700B */ 31 #define MVNETA_DEFAULT_MTU 1500 32 33 #define MVNETA_MAC_ADDRS_MAX 256 /*16 UC, 256 IP, 256 MC/BC */ 34 /** Maximum length of a match string */ 35 #define MVNETA_MATCH_LEN 16 36 37 static const char * const valid_args[] = { 38 MVNETA_IFACE_NAME_ARG, 39 NULL 40 }; 41 42 struct mvneta_ifnames { 43 const char *names[NETA_NUM_ETH_PPIO]; 44 int idx; 45 }; 46 47 static int mvneta_dev_num; 48 49 static int mvneta_stats_reset(struct rte_eth_dev *dev); 50 static int rte_pmd_mvneta_remove(struct rte_vdev_device *vdev); 51 52 53 /** 54 * Deinitialize packet processor. 55 */ 56 static void 57 mvneta_neta_deinit(void) 58 { 59 neta_deinit(); 60 } 61 62 /** 63 * Initialize packet processor. 64 * 65 * @return 66 * 0 on success, negative error value otherwise. 67 */ 68 static int 69 mvneta_neta_init(void) 70 { 71 return neta_init(); 72 } 73 74 /** 75 * Callback used by rte_kvargs_process() during argument parsing. 76 * 77 * @param key 78 * Pointer to the parsed key (unused). 79 * @param value 80 * Pointer to the parsed value. 81 * @param extra_args 82 * Pointer to the extra arguments which contains address of the 83 * table of pointers to parsed interface names. 84 * 85 * @return 86 * Always 0. 87 */ 88 static int 89 mvneta_ifnames_get(const char *key __rte_unused, const char *value, 90 void *extra_args) 91 { 92 struct mvneta_ifnames *ifnames = extra_args; 93 94 ifnames->names[ifnames->idx++] = value; 95 96 return 0; 97 } 98 99 /** 100 * Ethernet device configuration. 101 * 102 * Prepare the driver for a given number of TX and RX queues and 103 * configure RSS if supported. 104 * 105 * @param dev 106 * Pointer to Ethernet device structure. 107 * 108 * @return 109 * 0 on success, negative error value otherwise. 110 */ 111 static int 112 mvneta_dev_configure(struct rte_eth_dev *dev) 113 { 114 struct mvneta_priv *priv = dev->data->dev_private; 115 struct neta_ppio_params *ppio_params; 116 117 if (dev->data->dev_conf.rxmode.mq_mode != RTE_ETH_MQ_RX_NONE) { 118 MVNETA_LOG(INFO, "Unsupported RSS and rx multi queue mode %d", 119 dev->data->dev_conf.rxmode.mq_mode); 120 if (dev->data->nb_rx_queues > 1) 121 return -EINVAL; 122 } 123 124 if (dev->data->dev_conf.rxmode.split_hdr_size) { 125 MVNETA_LOG(INFO, "Split headers not supported"); 126 return -EINVAL; 127 } 128 129 if (dev->data->dev_conf.txmode.offloads & RTE_ETH_TX_OFFLOAD_MULTI_SEGS) 130 priv->multiseg = 1; 131 132 ppio_params = &priv->ppio_params; 133 ppio_params->outqs_params.num_outqs = dev->data->nb_tx_queues; 134 /* Default: 1 TC, no QoS supported. */ 135 ppio_params->inqs_params.num_tcs = 1; 136 ppio_params->inqs_params.tcs_params[0].pkt_offset = MRVL_NETA_PKT_OFFS; 137 priv->ppio_id = dev->data->port_id; 138 139 return 0; 140 } 141 142 /** 143 * DPDK callback to get information about the device. 144 * 145 * @param dev 146 * Pointer to Ethernet device structure (unused). 147 * @param info 148 * Info structure output buffer. 149 */ 150 static int 151 mvneta_dev_infos_get(struct rte_eth_dev *dev __rte_unused, 152 struct rte_eth_dev_info *info) 153 { 154 info->speed_capa = RTE_ETH_LINK_SPEED_10M | 155 RTE_ETH_LINK_SPEED_100M | 156 RTE_ETH_LINK_SPEED_1G | 157 RTE_ETH_LINK_SPEED_2_5G; 158 159 info->max_rx_queues = MRVL_NETA_RXQ_MAX; 160 info->max_tx_queues = MRVL_NETA_TXQ_MAX; 161 info->max_mac_addrs = MVNETA_MAC_ADDRS_MAX; 162 163 info->rx_desc_lim.nb_max = MRVL_NETA_RXD_MAX; 164 info->rx_desc_lim.nb_min = MRVL_NETA_RXD_MIN; 165 info->rx_desc_lim.nb_align = MRVL_NETA_RXD_ALIGN; 166 167 info->tx_desc_lim.nb_max = MRVL_NETA_TXD_MAX; 168 info->tx_desc_lim.nb_min = MRVL_NETA_TXD_MIN; 169 info->tx_desc_lim.nb_align = MRVL_NETA_TXD_ALIGN; 170 171 info->rx_offload_capa = MVNETA_RX_OFFLOADS; 172 info->rx_queue_offload_capa = MVNETA_RX_OFFLOADS; 173 174 info->tx_offload_capa = MVNETA_TX_OFFLOADS; 175 info->tx_queue_offload_capa = MVNETA_TX_OFFLOADS; 176 177 /* By default packets are dropped if no descriptors are available */ 178 info->default_rxconf.rx_drop_en = 1; 179 /* Deferred tx queue start is not supported */ 180 info->default_txconf.tx_deferred_start = 0; 181 info->default_txconf.offloads = 0; 182 183 info->max_rx_pktlen = MVNETA_PKT_SIZE_MAX; 184 185 return 0; 186 } 187 188 /** 189 * Return supported packet types. 190 * 191 * @param dev 192 * Pointer to Ethernet device structure (unused). 193 * 194 * @return 195 * Const pointer to the table with supported packet types. 196 */ 197 static const uint32_t * 198 mvneta_dev_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused) 199 { 200 static const uint32_t ptypes[] = { 201 RTE_PTYPE_L2_ETHER, 202 RTE_PTYPE_L2_ETHER_VLAN, 203 RTE_PTYPE_L3_IPV4, 204 RTE_PTYPE_L3_IPV6, 205 RTE_PTYPE_L4_TCP, 206 RTE_PTYPE_L4_UDP 207 }; 208 209 return ptypes; 210 } 211 212 /** 213 * DPDK callback to change the MTU. 214 * 215 * Setting the MTU affects hardware MRU (packets larger than the MRU 216 * will be dropped). 217 * 218 * @param dev 219 * Pointer to Ethernet device structure. 220 * @param mtu 221 * New MTU. 222 * 223 * @return 224 * 0 on success, negative error value otherwise. 225 */ 226 static int 227 mvneta_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) 228 { 229 struct mvneta_priv *priv = dev->data->dev_private; 230 uint16_t mbuf_data_size = 0; /* SW buffer size */ 231 uint16_t mru; 232 int ret; 233 234 mru = MRVL_NETA_MTU_TO_MRU(mtu); 235 /* 236 * min_rx_buf_size is equal to mbuf data size 237 * if pmd didn't set it differently 238 */ 239 mbuf_data_size = dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM; 240 /* Prevent PMD from: 241 * - setting mru greater than the mbuf size resulting in 242 * hw and sw buffer size mismatch 243 * - setting mtu that requires the support of scattered packets 244 * when this feature has not been enabled/supported so far. 245 */ 246 if (!dev->data->scattered_rx && 247 (mru + MRVL_NETA_PKT_OFFS > mbuf_data_size)) { 248 mru = mbuf_data_size - MRVL_NETA_PKT_OFFS; 249 mtu = MRVL_NETA_MRU_TO_MTU(mru); 250 MVNETA_LOG(WARNING, "MTU too big, max MTU possible limitted by" 251 " current mbuf size: %u. Set MTU to %u, MRU to %u", 252 mbuf_data_size, mtu, mru); 253 } 254 255 if (mtu < RTE_ETHER_MIN_MTU || mru > MVNETA_PKT_SIZE_MAX) { 256 MVNETA_LOG(ERR, "Invalid MTU [%u] or MRU [%u]", mtu, mru); 257 return -EINVAL; 258 } 259 260 if (!priv->ppio) 261 /* It is OK. New MTU will be set later on mvneta_dev_start */ 262 return 0; 263 264 ret = neta_ppio_set_mru(priv->ppio, mru); 265 if (ret) { 266 MVNETA_LOG(ERR, "Failed to change MRU"); 267 return ret; 268 } 269 270 ret = neta_ppio_set_mtu(priv->ppio, mtu); 271 if (ret) { 272 MVNETA_LOG(ERR, "Failed to change MTU"); 273 return ret; 274 } 275 MVNETA_LOG(INFO, "MTU changed to %u, MRU = %u", mtu, mru); 276 277 return 0; 278 } 279 280 /** 281 * DPDK callback to bring the link up. 282 * 283 * @param dev 284 * Pointer to Ethernet device structure. 285 * 286 * @return 287 * 0 on success, negative error value otherwise. 288 */ 289 static int 290 mvneta_dev_set_link_up(struct rte_eth_dev *dev) 291 { 292 struct mvneta_priv *priv = dev->data->dev_private; 293 294 if (!priv->ppio) 295 return 0; 296 297 return neta_ppio_enable(priv->ppio); 298 } 299 300 /** 301 * DPDK callback to bring the link down. 302 * 303 * @param dev 304 * Pointer to Ethernet device structure. 305 * 306 * @return 307 * 0 on success, negative error value otherwise. 308 */ 309 static int 310 mvneta_dev_set_link_down(struct rte_eth_dev *dev) 311 { 312 struct mvneta_priv *priv = dev->data->dev_private; 313 314 if (!priv->ppio) 315 return 0; 316 317 return neta_ppio_disable(priv->ppio); 318 } 319 320 /** 321 * DPDK callback to start the device. 322 * 323 * @param dev 324 * Pointer to Ethernet device structure. 325 * 326 * @return 327 * 0 on success, negative errno value on failure. 328 */ 329 static int 330 mvneta_dev_start(struct rte_eth_dev *dev) 331 { 332 struct mvneta_priv *priv = dev->data->dev_private; 333 char match[MVNETA_MATCH_LEN]; 334 int ret = 0, i; 335 336 if (priv->ppio) 337 return mvneta_dev_set_link_up(dev); 338 339 strlcpy(match, dev->data->name, sizeof(match)); 340 priv->ppio_params.match = match; 341 priv->ppio_params.inqs_params.mtu = dev->data->mtu; 342 343 ret = neta_ppio_init(&priv->ppio_params, &priv->ppio); 344 if (ret) { 345 MVNETA_LOG(ERR, "Failed to init ppio"); 346 return ret; 347 } 348 priv->ppio_id = priv->ppio->port_id; 349 350 mvneta_stats_reset(dev); 351 352 /* 353 * In case there are some some stale uc/mc mac addresses flush them 354 * here. It cannot be done during mvneta_dev_close() as port information 355 * is already gone at that point (due to neta_ppio_deinit() in 356 * mvneta_dev_stop()). 357 */ 358 if (!priv->uc_mc_flushed) { 359 ret = neta_ppio_flush_mac_addrs(priv->ppio, 0, 1); 360 if (ret) { 361 MVNETA_LOG(ERR, 362 "Failed to flush uc/mc filter list"); 363 goto out; 364 } 365 priv->uc_mc_flushed = 1; 366 } 367 368 ret = mvneta_alloc_rx_bufs(dev); 369 if (ret) 370 goto out; 371 372 ret = mvneta_mtu_set(dev, dev->data->mtu); 373 if (ret) { 374 MVNETA_LOG(ERR, "Failed to set MTU %d", dev->data->mtu); 375 goto out; 376 } 377 378 ret = mvneta_dev_set_link_up(dev); 379 if (ret) { 380 MVNETA_LOG(ERR, "Failed to set link up"); 381 goto out; 382 } 383 384 /* start tx queues */ 385 for (i = 0; i < dev->data->nb_tx_queues; i++) 386 dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED; 387 388 mvneta_set_tx_function(dev); 389 390 return 0; 391 392 out: 393 MVNETA_LOG(ERR, "Failed to start device"); 394 neta_ppio_deinit(priv->ppio); 395 return ret; 396 } 397 398 /** 399 * DPDK callback to stop the device. 400 * 401 * @param dev 402 * Pointer to Ethernet device structure. 403 */ 404 static int 405 mvneta_dev_stop(struct rte_eth_dev *dev) 406 { 407 struct mvneta_priv *priv = dev->data->dev_private; 408 409 dev->data->dev_started = 0; 410 411 if (!priv->ppio) 412 return 0; 413 414 mvneta_dev_set_link_down(dev); 415 mvneta_flush_queues(dev); 416 neta_ppio_deinit(priv->ppio); 417 418 priv->ppio = NULL; 419 420 return 0; 421 } 422 423 /** 424 * DPDK callback to close the device. 425 * 426 * @param dev 427 * Pointer to Ethernet device structure. 428 */ 429 static int 430 mvneta_dev_close(struct rte_eth_dev *dev) 431 { 432 struct mvneta_priv *priv = dev->data->dev_private; 433 int i, ret = 0; 434 435 if (rte_eal_process_type() != RTE_PROC_PRIMARY) 436 return 0; 437 438 if (priv->ppio) 439 ret = mvneta_dev_stop(dev); 440 441 for (i = 0; i < dev->data->nb_rx_queues; i++) { 442 mvneta_rx_queue_release(dev, i); 443 dev->data->rx_queues[i] = NULL; 444 } 445 446 for (i = 0; i < dev->data->nb_tx_queues; i++) { 447 mvneta_tx_queue_release(dev, i); 448 dev->data->tx_queues[i] = NULL; 449 } 450 451 mvneta_dev_num--; 452 453 if (mvneta_dev_num == 0) { 454 MVNETA_LOG(INFO, "Perform MUSDK deinit"); 455 mvneta_neta_deinit(); 456 rte_mvep_deinit(MVEP_MOD_T_NETA); 457 } 458 459 return ret; 460 } 461 462 /** 463 * DPDK callback to retrieve physical link information. 464 * 465 * @param dev 466 * Pointer to Ethernet device structure. 467 * @param wait_to_complete 468 * Wait for request completion (ignored). 469 * 470 * @return 471 * 0 on success, negative error value otherwise. 472 */ 473 static int 474 mvneta_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused) 475 { 476 /* 477 * TODO 478 * once MUSDK provides necessary API use it here 479 */ 480 struct mvneta_priv *priv = dev->data->dev_private; 481 struct ethtool_cmd edata; 482 struct ifreq req; 483 int ret, fd, link_up; 484 485 if (!priv->ppio) 486 return -EPERM; 487 488 edata.cmd = ETHTOOL_GSET; 489 490 strcpy(req.ifr_name, dev->data->name); 491 req.ifr_data = (void *)&edata; 492 493 fd = socket(AF_INET, SOCK_DGRAM, 0); 494 if (fd == -1) 495 return -EFAULT; 496 ret = ioctl(fd, SIOCETHTOOL, &req); 497 if (ret == -1) { 498 close(fd); 499 return -EFAULT; 500 } 501 502 close(fd); 503 504 switch (ethtool_cmd_speed(&edata)) { 505 case SPEED_10: 506 dev->data->dev_link.link_speed = RTE_ETH_SPEED_NUM_10M; 507 break; 508 case SPEED_100: 509 dev->data->dev_link.link_speed = RTE_ETH_SPEED_NUM_100M; 510 break; 511 case SPEED_1000: 512 dev->data->dev_link.link_speed = RTE_ETH_SPEED_NUM_1G; 513 break; 514 case SPEED_2500: 515 dev->data->dev_link.link_speed = RTE_ETH_SPEED_NUM_2_5G; 516 break; 517 default: 518 dev->data->dev_link.link_speed = RTE_ETH_SPEED_NUM_NONE; 519 } 520 521 dev->data->dev_link.link_duplex = edata.duplex ? RTE_ETH_LINK_FULL_DUPLEX : 522 RTE_ETH_LINK_HALF_DUPLEX; 523 dev->data->dev_link.link_autoneg = edata.autoneg ? RTE_ETH_LINK_AUTONEG : 524 RTE_ETH_LINK_FIXED; 525 526 neta_ppio_get_link_state(priv->ppio, &link_up); 527 dev->data->dev_link.link_status = link_up ? RTE_ETH_LINK_UP : RTE_ETH_LINK_DOWN; 528 529 return 0; 530 } 531 532 /** 533 * DPDK callback to enable promiscuous mode. 534 * 535 * @param dev 536 * Pointer to Ethernet device structure. 537 * 538 * @return 539 * always 0 540 */ 541 static int 542 mvneta_promiscuous_enable(struct rte_eth_dev *dev) 543 { 544 struct mvneta_priv *priv = dev->data->dev_private; 545 int ret, en; 546 547 if (!priv->ppio) 548 return 0; 549 550 neta_ppio_get_promisc(priv->ppio, &en); 551 if (en) { 552 MVNETA_LOG(INFO, "Promiscuous already enabled"); 553 return 0; 554 } 555 556 ret = neta_ppio_set_promisc(priv->ppio, 1); 557 if (ret) 558 MVNETA_LOG(ERR, "Failed to enable promiscuous mode"); 559 560 return 0; 561 } 562 563 /** 564 * DPDK callback to disable allmulticast mode. 565 * 566 * @param dev 567 * Pointer to Ethernet device structure. 568 * 569 * @return 570 * always 0 571 */ 572 static int 573 mvneta_promiscuous_disable(struct rte_eth_dev *dev) 574 { 575 struct mvneta_priv *priv = dev->data->dev_private; 576 int ret, en; 577 578 if (!priv->ppio) 579 return 0; 580 581 neta_ppio_get_promisc(priv->ppio, &en); 582 if (!en) { 583 MVNETA_LOG(INFO, "Promiscuous already disabled"); 584 return 0; 585 } 586 587 ret = neta_ppio_set_promisc(priv->ppio, 0); 588 if (ret) 589 MVNETA_LOG(ERR, "Failed to disable promiscuous mode"); 590 591 return 0; 592 } 593 594 /** 595 * DPDK callback to remove a MAC address. 596 * 597 * @param dev 598 * Pointer to Ethernet device structure. 599 * @param index 600 * MAC address index. 601 */ 602 static void 603 mvneta_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index) 604 { 605 struct mvneta_priv *priv = dev->data->dev_private; 606 char buf[RTE_ETHER_ADDR_FMT_SIZE]; 607 int ret; 608 609 if (!priv->ppio) 610 return; 611 612 ret = neta_ppio_remove_mac_addr(priv->ppio, 613 dev->data->mac_addrs[index].addr_bytes); 614 if (ret) { 615 rte_ether_format_addr(buf, sizeof(buf), 616 &dev->data->mac_addrs[index]); 617 MVNETA_LOG(ERR, "Failed to remove mac %s", buf); 618 } 619 } 620 621 /** 622 * DPDK callback to add a MAC address. 623 * 624 * @param dev 625 * Pointer to Ethernet device structure. 626 * @param mac_addr 627 * MAC address to register. 628 * @param index 629 * MAC address index. 630 * @param vmdq 631 * VMDq pool index to associate address with (unused). 632 * 633 * @return 634 * 0 on success, negative error value otherwise. 635 */ 636 static int 637 mvneta_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr, 638 uint32_t index, uint32_t vmdq __rte_unused) 639 { 640 struct mvneta_priv *priv = dev->data->dev_private; 641 char buf[RTE_ETHER_ADDR_FMT_SIZE]; 642 int ret; 643 644 if (index == 0) 645 /* For setting index 0, mrvl_mac_addr_set() should be used.*/ 646 return -1; 647 648 if (!priv->ppio) 649 return 0; 650 651 ret = neta_ppio_add_mac_addr(priv->ppio, mac_addr->addr_bytes); 652 if (ret) { 653 rte_ether_format_addr(buf, sizeof(buf), mac_addr); 654 MVNETA_LOG(ERR, "Failed to add mac %s", buf); 655 return -1; 656 } 657 658 return 0; 659 } 660 661 /** 662 * DPDK callback to set the primary MAC address. 663 * 664 * @param dev 665 * Pointer to Ethernet device structure. 666 * @param mac_addr 667 * MAC address to register. 668 */ 669 static int 670 mvneta_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr) 671 { 672 struct mvneta_priv *priv = dev->data->dev_private; 673 int ret; 674 675 if (!priv->ppio) 676 return -EINVAL; 677 678 ret = neta_ppio_set_mac_addr(priv->ppio, mac_addr->addr_bytes); 679 if (ret) { 680 char buf[RTE_ETHER_ADDR_FMT_SIZE]; 681 rte_ether_format_addr(buf, sizeof(buf), mac_addr); 682 MVNETA_LOG(ERR, "Failed to set mac to %s", buf); 683 } 684 return 0; 685 } 686 687 /** 688 * DPDK callback to get device statistics. 689 * 690 * @param dev 691 * Pointer to Ethernet device structure. 692 * @param stats 693 * Stats structure output buffer. 694 * 695 * @return 696 * 0 on success, negative error value otherwise. 697 */ 698 static int 699 mvneta_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) 700 { 701 struct mvneta_priv *priv = dev->data->dev_private; 702 struct neta_ppio_statistics ppio_stats; 703 unsigned int ret; 704 705 if (!priv->ppio) 706 return -EPERM; 707 708 ret = neta_ppio_get_statistics(priv->ppio, &ppio_stats); 709 if (unlikely(ret)) { 710 MVNETA_LOG(ERR, "Failed to update port statistics"); 711 return ret; 712 } 713 714 stats->ipackets += ppio_stats.rx_packets + 715 ppio_stats.rx_broadcast_packets + 716 ppio_stats.rx_multicast_packets - 717 priv->prev_stats.ipackets; 718 stats->opackets += ppio_stats.tx_packets + 719 ppio_stats.tx_broadcast_packets + 720 ppio_stats.tx_multicast_packets - 721 priv->prev_stats.opackets; 722 stats->ibytes += ppio_stats.rx_bytes - priv->prev_stats.ibytes; 723 stats->obytes += ppio_stats.tx_bytes - priv->prev_stats.obytes; 724 stats->imissed += ppio_stats.rx_discard + 725 ppio_stats.rx_overrun - 726 priv->prev_stats.imissed; 727 stats->ierrors = ppio_stats.rx_packets_err - 728 priv->prev_stats.ierrors; 729 stats->oerrors = ppio_stats.tx_errors - priv->prev_stats.oerrors; 730 731 return 0; 732 } 733 734 /** 735 * DPDK callback to clear device statistics. 736 * 737 * @param dev 738 * Pointer to Ethernet device structure. 739 * 740 * @return 741 * 0 on success, negative error value otherwise. 742 */ 743 static int 744 mvneta_stats_reset(struct rte_eth_dev *dev) 745 { 746 struct mvneta_priv *priv = dev->data->dev_private; 747 unsigned int ret; 748 749 if (!priv->ppio) 750 return 0; 751 752 ret = mvneta_stats_get(dev, &priv->prev_stats); 753 if (unlikely(ret)) 754 MVNETA_LOG(ERR, "Failed to reset port statistics"); 755 756 return ret; 757 } 758 759 760 static const struct eth_dev_ops mvneta_ops = { 761 .dev_configure = mvneta_dev_configure, 762 .dev_start = mvneta_dev_start, 763 .dev_stop = mvneta_dev_stop, 764 .dev_set_link_up = mvneta_dev_set_link_up, 765 .dev_set_link_down = mvneta_dev_set_link_down, 766 .dev_close = mvneta_dev_close, 767 .link_update = mvneta_link_update, 768 .promiscuous_enable = mvneta_promiscuous_enable, 769 .promiscuous_disable = mvneta_promiscuous_disable, 770 .mac_addr_remove = mvneta_mac_addr_remove, 771 .mac_addr_add = mvneta_mac_addr_add, 772 .mac_addr_set = mvneta_mac_addr_set, 773 .mtu_set = mvneta_mtu_set, 774 .stats_get = mvneta_stats_get, 775 .stats_reset = mvneta_stats_reset, 776 .dev_infos_get = mvneta_dev_infos_get, 777 .dev_supported_ptypes_get = mvneta_dev_supported_ptypes_get, 778 .rxq_info_get = mvneta_rxq_info_get, 779 .txq_info_get = mvneta_txq_info_get, 780 .rx_queue_setup = mvneta_rx_queue_setup, 781 .rx_queue_release = mvneta_rx_queue_release, 782 .tx_queue_setup = mvneta_tx_queue_setup, 783 .tx_queue_release = mvneta_tx_queue_release, 784 }; 785 786 /** 787 * Create device representing Ethernet port. 788 * 789 * @param name 790 * Pointer to the port's name. 791 * 792 * @return 793 * 0 on success, negative error value otherwise. 794 */ 795 static int 796 mvneta_eth_dev_create(struct rte_vdev_device *vdev, const char *name) 797 { 798 int ret, fd = socket(AF_INET, SOCK_DGRAM, 0); 799 struct rte_eth_dev *eth_dev; 800 struct mvneta_priv *priv; 801 struct ifreq req; 802 803 eth_dev = rte_eth_dev_allocate(name); 804 if (!eth_dev) 805 return -ENOMEM; 806 807 priv = rte_zmalloc_socket(name, sizeof(*priv), 0, rte_socket_id()); 808 if (!priv) { 809 ret = -ENOMEM; 810 goto out_free; 811 } 812 eth_dev->data->dev_private = priv; 813 814 eth_dev->data->mac_addrs = 815 rte_zmalloc("mac_addrs", 816 RTE_ETHER_ADDR_LEN * MVNETA_MAC_ADDRS_MAX, 0); 817 if (!eth_dev->data->mac_addrs) { 818 MVNETA_LOG(ERR, "Failed to allocate space for eth addrs"); 819 ret = -ENOMEM; 820 goto out_free; 821 } 822 823 memset(&req, 0, sizeof(req)); 824 strcpy(req.ifr_name, name); 825 ret = ioctl(fd, SIOCGIFHWADDR, &req); 826 if (ret) 827 goto out_free; 828 829 memcpy(eth_dev->data->mac_addrs[0].addr_bytes, 830 req.ifr_addr.sa_data, RTE_ETHER_ADDR_LEN); 831 832 eth_dev->device = &vdev->device; 833 eth_dev->rx_pkt_burst = mvneta_rx_pkt_burst; 834 mvneta_set_tx_function(eth_dev); 835 eth_dev->dev_ops = &mvneta_ops; 836 837 rte_eth_dev_probing_finish(eth_dev); 838 return 0; 839 out_free: 840 rte_eth_dev_release_port(eth_dev); 841 842 return ret; 843 } 844 845 /** 846 * Cleanup previously created device representing Ethernet port. 847 * 848 * @param eth_dev 849 * Pointer to the corresponding rte_eth_dev structure. 850 */ 851 static void 852 mvneta_eth_dev_destroy(struct rte_eth_dev *eth_dev) 853 { 854 rte_eth_dev_release_port(eth_dev); 855 } 856 857 /** 858 * Cleanup previously created device representing Ethernet port. 859 * 860 * @param name 861 * Pointer to the port name. 862 */ 863 static void 864 mvneta_eth_dev_destroy_name(const char *name) 865 { 866 struct rte_eth_dev *eth_dev; 867 868 eth_dev = rte_eth_dev_allocated(name); 869 if (!eth_dev) 870 return; 871 872 mvneta_eth_dev_destroy(eth_dev); 873 } 874 875 /** 876 * DPDK callback to register the virtual device. 877 * 878 * @param vdev 879 * Pointer to the virtual device. 880 * 881 * @return 882 * 0 on success, negative error value otherwise. 883 */ 884 static int 885 rte_pmd_mvneta_probe(struct rte_vdev_device *vdev) 886 { 887 struct rte_kvargs *kvlist; 888 struct mvneta_ifnames ifnames; 889 int ret = -EINVAL; 890 uint32_t i, ifnum; 891 const char *params; 892 893 params = rte_vdev_device_args(vdev); 894 if (!params) 895 return -EINVAL; 896 897 kvlist = rte_kvargs_parse(params, valid_args); 898 if (!kvlist) 899 return -EINVAL; 900 901 ifnum = rte_kvargs_count(kvlist, MVNETA_IFACE_NAME_ARG); 902 if (ifnum > RTE_DIM(ifnames.names)) 903 goto out_free_kvlist; 904 905 ifnames.idx = 0; 906 rte_kvargs_process(kvlist, MVNETA_IFACE_NAME_ARG, 907 mvneta_ifnames_get, &ifnames); 908 909 /* 910 * The below system initialization should be done only once, 911 * on the first provided configuration file 912 */ 913 if (mvneta_dev_num) 914 goto init_devices; 915 916 MVNETA_LOG(INFO, "Perform MUSDK initializations"); 917 918 ret = rte_mvep_init(MVEP_MOD_T_NETA, kvlist); 919 if (ret) 920 goto out_free_kvlist; 921 922 ret = mvneta_neta_init(); 923 if (ret) { 924 MVNETA_LOG(ERR, "Failed to init NETA!"); 925 rte_mvep_deinit(MVEP_MOD_T_NETA); 926 goto out_free_kvlist; 927 } 928 929 init_devices: 930 for (i = 0; i < ifnum; i++) { 931 MVNETA_LOG(INFO, "Creating %s", ifnames.names[i]); 932 ret = mvneta_eth_dev_create(vdev, ifnames.names[i]); 933 if (ret) 934 goto out_cleanup; 935 936 mvneta_dev_num++; 937 } 938 939 rte_kvargs_free(kvlist); 940 941 return 0; 942 out_cleanup: 943 rte_pmd_mvneta_remove(vdev); 944 945 out_free_kvlist: 946 rte_kvargs_free(kvlist); 947 948 return ret; 949 } 950 951 /** 952 * DPDK callback to remove virtual device. 953 * 954 * @param vdev 955 * Pointer to the removed virtual device. 956 * 957 * @return 958 * 0 on success, negative error value otherwise. 959 */ 960 static int 961 rte_pmd_mvneta_remove(struct rte_vdev_device *vdev) 962 { 963 uint16_t port_id; 964 int ret = 0; 965 966 RTE_ETH_FOREACH_DEV(port_id) { 967 if (rte_eth_devices[port_id].device != &vdev->device) 968 continue; 969 ret |= rte_eth_dev_close(port_id); 970 } 971 972 return ret == 0 ? 0 : -EIO; 973 } 974 975 static struct rte_vdev_driver pmd_mvneta_drv = { 976 .probe = rte_pmd_mvneta_probe, 977 .remove = rte_pmd_mvneta_remove, 978 }; 979 980 RTE_PMD_REGISTER_VDEV(net_mvneta, pmd_mvneta_drv); 981 RTE_PMD_REGISTER_PARAM_STRING(net_mvneta, "iface=<ifc>"); 982 RTE_LOG_REGISTER_DEFAULT(mvneta_logtype, NOTICE); 983