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