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