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