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 <rte_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 int mvneta_logtype; 38 39 static const char * const valid_args[] = { 40 MVNETA_IFACE_NAME_ARG, 41 NULL 42 }; 43 44 struct mvneta_ifnames { 45 const char *names[NETA_NUM_ETH_PPIO]; 46 int idx; 47 }; 48 49 static int mvneta_dev_num; 50 51 static int mvneta_stats_reset(struct rte_eth_dev *dev); 52 static int rte_pmd_mvneta_remove(struct rte_vdev_device *vdev); 53 54 55 /** 56 * Deinitialize packet processor. 57 */ 58 static void 59 mvneta_neta_deinit(void) 60 { 61 neta_deinit(); 62 } 63 64 /** 65 * Initialize packet processor. 66 * 67 * @return 68 * 0 on success, negative error value otherwise. 69 */ 70 static int 71 mvneta_neta_init(void) 72 { 73 return neta_init(); 74 } 75 76 /** 77 * Callback used by rte_kvargs_process() during argument parsing. 78 * 79 * @param key 80 * Pointer to the parsed key (unused). 81 * @param value 82 * Pointer to the parsed value. 83 * @param extra_args 84 * Pointer to the extra arguments which contains address of the 85 * table of pointers to parsed interface names. 86 * 87 * @return 88 * Always 0. 89 */ 90 static int 91 mvneta_ifnames_get(const char *key __rte_unused, const char *value, 92 void *extra_args) 93 { 94 struct mvneta_ifnames *ifnames = extra_args; 95 96 ifnames->names[ifnames->idx++] = value; 97 98 return 0; 99 } 100 101 /** 102 * Ethernet device configuration. 103 * 104 * Prepare the driver for a given number of TX and RX queues and 105 * configure RSS if supported. 106 * 107 * @param dev 108 * Pointer to Ethernet device structure. 109 * 110 * @return 111 * 0 on success, negative error value otherwise. 112 */ 113 static int 114 mvneta_dev_configure(struct rte_eth_dev *dev) 115 { 116 struct mvneta_priv *priv = dev->data->dev_private; 117 struct neta_ppio_params *ppio_params; 118 119 if (dev->data->dev_conf.rxmode.mq_mode != ETH_MQ_RX_NONE) { 120 MVNETA_LOG(INFO, "Unsupported RSS and rx multi queue mode %d", 121 dev->data->dev_conf.rxmode.mq_mode); 122 if (dev->data->nb_rx_queues > 1) 123 return -EINVAL; 124 } 125 126 if (dev->data->dev_conf.rxmode.split_hdr_size) { 127 MVNETA_LOG(INFO, "Split headers not supported"); 128 return -EINVAL; 129 } 130 131 if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) 132 dev->data->mtu = dev->data->dev_conf.rxmode.max_rx_pkt_len - 133 MRVL_NETA_ETH_HDRS_LEN; 134 135 if (dev->data->dev_conf.txmode.offloads & DEV_TX_OFFLOAD_MULTI_SEGS) 136 priv->multiseg = 1; 137 138 ppio_params = &priv->ppio_params; 139 ppio_params->outqs_params.num_outqs = dev->data->nb_tx_queues; 140 /* Default: 1 TC, no QoS supported. */ 141 ppio_params->inqs_params.num_tcs = 1; 142 ppio_params->inqs_params.tcs_params[0].pkt_offset = MRVL_NETA_PKT_OFFS; 143 priv->ppio_id = dev->data->port_id; 144 145 return 0; 146 } 147 148 /** 149 * DPDK callback to get information about the device. 150 * 151 * @param dev 152 * Pointer to Ethernet device structure (unused). 153 * @param info 154 * Info structure output buffer. 155 */ 156 static int 157 mvneta_dev_infos_get(struct rte_eth_dev *dev __rte_unused, 158 struct rte_eth_dev_info *info) 159 { 160 info->speed_capa = ETH_LINK_SPEED_10M | 161 ETH_LINK_SPEED_100M | 162 ETH_LINK_SPEED_1G | 163 ETH_LINK_SPEED_2_5G; 164 165 info->max_rx_queues = MRVL_NETA_RXQ_MAX; 166 info->max_tx_queues = MRVL_NETA_TXQ_MAX; 167 info->max_mac_addrs = MVNETA_MAC_ADDRS_MAX; 168 169 info->rx_desc_lim.nb_max = MRVL_NETA_RXD_MAX; 170 info->rx_desc_lim.nb_min = MRVL_NETA_RXD_MIN; 171 info->rx_desc_lim.nb_align = MRVL_NETA_RXD_ALIGN; 172 173 info->tx_desc_lim.nb_max = MRVL_NETA_TXD_MAX; 174 info->tx_desc_lim.nb_min = MRVL_NETA_TXD_MIN; 175 info->tx_desc_lim.nb_align = MRVL_NETA_TXD_ALIGN; 176 177 info->rx_offload_capa = MVNETA_RX_OFFLOADS; 178 info->rx_queue_offload_capa = MVNETA_RX_OFFLOADS; 179 180 info->tx_offload_capa = MVNETA_TX_OFFLOADS; 181 info->tx_queue_offload_capa = MVNETA_TX_OFFLOADS; 182 183 /* By default packets are dropped if no descriptors are available */ 184 info->default_rxconf.rx_drop_en = 1; 185 /* Deferred tx queue start is not supported */ 186 info->default_txconf.tx_deferred_start = 0; 187 info->default_txconf.offloads = 0; 188 189 info->max_rx_pktlen = MVNETA_PKT_SIZE_MAX; 190 191 return 0; 192 } 193 194 /** 195 * Return supported packet types. 196 * 197 * @param dev 198 * Pointer to Ethernet device structure (unused). 199 * 200 * @return 201 * Const pointer to the table with supported packet types. 202 */ 203 static const uint32_t * 204 mvneta_dev_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused) 205 { 206 static const uint32_t ptypes[] = { 207 RTE_PTYPE_L2_ETHER, 208 RTE_PTYPE_L2_ETHER_VLAN, 209 RTE_PTYPE_L3_IPV4, 210 RTE_PTYPE_L3_IPV6, 211 RTE_PTYPE_L4_TCP, 212 RTE_PTYPE_L4_UDP 213 }; 214 215 return ptypes; 216 } 217 218 /** 219 * DPDK callback to change the MTU. 220 * 221 * Setting the MTU affects hardware MRU (packets larger than the MRU 222 * will be dropped). 223 * 224 * @param dev 225 * Pointer to Ethernet device structure. 226 * @param mtu 227 * New MTU. 228 * 229 * @return 230 * 0 on success, negative error value otherwise. 231 */ 232 static int 233 mvneta_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) 234 { 235 struct mvneta_priv *priv = dev->data->dev_private; 236 uint16_t mbuf_data_size = 0; /* SW buffer size */ 237 uint16_t mru; 238 int ret; 239 240 mru = MRVL_NETA_MTU_TO_MRU(mtu); 241 /* 242 * min_rx_buf_size is equal to mbuf data size 243 * if pmd didn't set it differently 244 */ 245 mbuf_data_size = dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM; 246 /* Prevent PMD from: 247 * - setting mru greater than the mbuf size resulting in 248 * hw and sw buffer size mismatch 249 * - setting mtu that requires the support of scattered packets 250 * when this feature has not been enabled/supported so far. 251 */ 252 if (!dev->data->scattered_rx && 253 (mru + MRVL_NETA_PKT_OFFS > mbuf_data_size)) { 254 mru = mbuf_data_size - MRVL_NETA_PKT_OFFS; 255 mtu = MRVL_NETA_MRU_TO_MTU(mru); 256 MVNETA_LOG(WARNING, "MTU too big, max MTU possible limitted by" 257 " current mbuf size: %u. Set MTU to %u, MRU to %u", 258 mbuf_data_size, mtu, mru); 259 } 260 261 if (mtu < RTE_ETHER_MIN_MTU || mru > MVNETA_PKT_SIZE_MAX) { 262 MVNETA_LOG(ERR, "Invalid MTU [%u] or MRU [%u]", mtu, mru); 263 return -EINVAL; 264 } 265 266 dev->data->mtu = mtu; 267 dev->data->dev_conf.rxmode.max_rx_pkt_len = mru - MV_MH_SIZE; 268 269 if (!priv->ppio) 270 /* It is OK. New MTU will be set later on mvneta_dev_start */ 271 return 0; 272 273 ret = neta_ppio_set_mru(priv->ppio, mru); 274 if (ret) { 275 MVNETA_LOG(ERR, "Failed to change MRU"); 276 return ret; 277 } 278 279 ret = neta_ppio_set_mtu(priv->ppio, mtu); 280 if (ret) { 281 MVNETA_LOG(ERR, "Failed to change MTU"); 282 return ret; 283 } 284 MVNETA_LOG(INFO, "MTU changed to %u, MRU = %u", mtu, mru); 285 286 return 0; 287 } 288 289 /** 290 * DPDK callback to bring the link up. 291 * 292 * @param dev 293 * Pointer to Ethernet device structure. 294 * 295 * @return 296 * 0 on success, negative error value otherwise. 297 */ 298 static int 299 mvneta_dev_set_link_up(struct rte_eth_dev *dev) 300 { 301 struct mvneta_priv *priv = dev->data->dev_private; 302 303 if (!priv->ppio) 304 return 0; 305 306 return neta_ppio_enable(priv->ppio); 307 } 308 309 /** 310 * DPDK callback to bring the link down. 311 * 312 * @param dev 313 * Pointer to Ethernet device structure. 314 * 315 * @return 316 * 0 on success, negative error value otherwise. 317 */ 318 static int 319 mvneta_dev_set_link_down(struct rte_eth_dev *dev) 320 { 321 struct mvneta_priv *priv = dev->data->dev_private; 322 323 if (!priv->ppio) 324 return 0; 325 326 return neta_ppio_disable(priv->ppio); 327 } 328 329 /** 330 * DPDK callback to start the device. 331 * 332 * @param dev 333 * Pointer to Ethernet device structure. 334 * 335 * @return 336 * 0 on success, negative errno value on failure. 337 */ 338 static int 339 mvneta_dev_start(struct rte_eth_dev *dev) 340 { 341 struct mvneta_priv *priv = dev->data->dev_private; 342 char match[MVNETA_MATCH_LEN]; 343 int ret = 0, i; 344 345 if (priv->ppio) 346 return mvneta_dev_set_link_up(dev); 347 348 strlcpy(match, dev->data->name, sizeof(match)); 349 priv->ppio_params.match = match; 350 priv->ppio_params.inqs_params.mtu = dev->data->mtu; 351 352 ret = neta_ppio_init(&priv->ppio_params, &priv->ppio); 353 if (ret) { 354 MVNETA_LOG(ERR, "Failed to init ppio"); 355 return ret; 356 } 357 priv->ppio_id = priv->ppio->port_id; 358 359 mvneta_stats_reset(dev); 360 361 /* 362 * In case there are some some stale uc/mc mac addresses flush them 363 * here. It cannot be done during mvneta_dev_close() as port information 364 * is already gone at that point (due to neta_ppio_deinit() in 365 * mvneta_dev_stop()). 366 */ 367 if (!priv->uc_mc_flushed) { 368 ret = neta_ppio_flush_mac_addrs(priv->ppio, 0, 1); 369 if (ret) { 370 MVNETA_LOG(ERR, 371 "Failed to flush uc/mc filter list"); 372 goto out; 373 } 374 priv->uc_mc_flushed = 1; 375 } 376 377 ret = mvneta_alloc_rx_bufs(dev); 378 if (ret) 379 goto out; 380 381 ret = mvneta_mtu_set(dev, dev->data->mtu); 382 if (ret) { 383 MVNETA_LOG(ERR, "Failed to set MTU %d", dev->data->mtu); 384 goto out; 385 } 386 387 ret = mvneta_dev_set_link_up(dev); 388 if (ret) { 389 MVNETA_LOG(ERR, "Failed to set link up"); 390 goto out; 391 } 392 393 /* start tx queues */ 394 for (i = 0; i < dev->data->nb_tx_queues; i++) 395 dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED; 396 397 mvneta_set_tx_function(dev); 398 399 return 0; 400 401 out: 402 MVNETA_LOG(ERR, "Failed to start device"); 403 neta_ppio_deinit(priv->ppio); 404 return ret; 405 } 406 407 /** 408 * DPDK callback to stop the device. 409 * 410 * @param dev 411 * Pointer to Ethernet device structure. 412 */ 413 static void 414 mvneta_dev_stop(struct rte_eth_dev *dev) 415 { 416 struct mvneta_priv *priv = dev->data->dev_private; 417 418 if (!priv->ppio) 419 return; 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 428 /** 429 * DPDK callback to close the device. 430 * 431 * @param dev 432 * Pointer to Ethernet device structure. 433 */ 434 static void 435 mvneta_dev_close(struct rte_eth_dev *dev) 436 { 437 struct mvneta_priv *priv = dev->data->dev_private; 438 int i; 439 440 if (priv->ppio) 441 mvneta_dev_stop(dev); 442 443 for (i = 0; i < dev->data->nb_rx_queues; i++) { 444 mvneta_rx_queue_release(dev->data->rx_queues[i]); 445 dev->data->rx_queues[i] = NULL; 446 } 447 448 for (i = 0; i < dev->data->nb_tx_queues; i++) { 449 mvneta_tx_queue_release(dev->data->tx_queues[i]); 450 dev->data->tx_queues[i] = NULL; 451 } 452 453 mvneta_dev_num--; 454 455 if (mvneta_dev_num == 0) { 456 MVNETA_LOG(INFO, "Perform MUSDK deinit"); 457 mvneta_neta_deinit(); 458 rte_mvep_deinit(MVEP_MOD_T_NETA); 459 } 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 = ETH_SPEED_NUM_10M; 507 break; 508 case SPEED_100: 509 dev->data->dev_link.link_speed = ETH_SPEED_NUM_100M; 510 break; 511 case SPEED_1000: 512 dev->data->dev_link.link_speed = ETH_SPEED_NUM_1G; 513 break; 514 case SPEED_2500: 515 dev->data->dev_link.link_speed = ETH_SPEED_NUM_2_5G; 516 break; 517 default: 518 dev->data->dev_link.link_speed = ETH_SPEED_NUM_NONE; 519 } 520 521 dev->data->dev_link.link_duplex = edata.duplex ? ETH_LINK_FULL_DUPLEX : 522 ETH_LINK_HALF_DUPLEX; 523 dev->data->dev_link.link_autoneg = edata.autoneg ? ETH_LINK_AUTONEG : 524 ETH_LINK_FIXED; 525 526 neta_ppio_get_link_state(priv->ppio, &link_up); 527 dev->data->dev_link.link_status = link_up ? ETH_LINK_UP : 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 RTE_LOG(ERR, PMD, "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->data->kdrv = RTE_KDRV_NONE; 833 eth_dev->device = &vdev->device; 834 eth_dev->rx_pkt_burst = mvneta_rx_pkt_burst; 835 mvneta_set_tx_function(eth_dev); 836 eth_dev->dev_ops = &mvneta_ops; 837 838 /* Flag to call rte_eth_dev_release_port() in rte_eth_dev_close(). */ 839 eth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE; 840 841 rte_eth_dev_probing_finish(eth_dev); 842 return 0; 843 out_free: 844 rte_eth_dev_release_port(eth_dev); 845 846 return ret; 847 } 848 849 /** 850 * Cleanup previously created device representing Ethernet port. 851 * 852 * @param eth_dev 853 * Pointer to the corresponding rte_eth_dev structure. 854 */ 855 static void 856 mvneta_eth_dev_destroy(struct rte_eth_dev *eth_dev) 857 { 858 rte_eth_dev_release_port(eth_dev); 859 } 860 861 /** 862 * Cleanup previously created device representing Ethernet port. 863 * 864 * @param name 865 * Pointer to the port name. 866 */ 867 static void 868 mvneta_eth_dev_destroy_name(const char *name) 869 { 870 struct rte_eth_dev *eth_dev; 871 872 eth_dev = rte_eth_dev_allocated(name); 873 if (!eth_dev) 874 return; 875 876 mvneta_eth_dev_destroy(eth_dev); 877 } 878 879 /** 880 * DPDK callback to register the virtual device. 881 * 882 * @param vdev 883 * Pointer to the virtual device. 884 * 885 * @return 886 * 0 on success, negative error value otherwise. 887 */ 888 static int 889 rte_pmd_mvneta_probe(struct rte_vdev_device *vdev) 890 { 891 struct rte_kvargs *kvlist; 892 struct mvneta_ifnames ifnames; 893 int ret = -EINVAL; 894 uint32_t i, ifnum; 895 const char *params; 896 897 params = rte_vdev_device_args(vdev); 898 if (!params) 899 return -EINVAL; 900 901 kvlist = rte_kvargs_parse(params, valid_args); 902 if (!kvlist) 903 return -EINVAL; 904 905 ifnum = rte_kvargs_count(kvlist, MVNETA_IFACE_NAME_ARG); 906 if (ifnum > RTE_DIM(ifnames.names)) 907 goto out_free_kvlist; 908 909 ifnames.idx = 0; 910 rte_kvargs_process(kvlist, MVNETA_IFACE_NAME_ARG, 911 mvneta_ifnames_get, &ifnames); 912 913 /* 914 * The below system initialization should be done only once, 915 * on the first provided configuration file 916 */ 917 if (mvneta_dev_num) 918 goto init_devices; 919 920 MVNETA_LOG(INFO, "Perform MUSDK initializations"); 921 922 ret = rte_mvep_init(MVEP_MOD_T_NETA, kvlist); 923 if (ret) 924 goto out_free_kvlist; 925 926 ret = mvneta_neta_init(); 927 if (ret) { 928 MVNETA_LOG(ERR, "Failed to init NETA!"); 929 rte_mvep_deinit(MVEP_MOD_T_NETA); 930 goto out_free_kvlist; 931 } 932 933 init_devices: 934 for (i = 0; i < ifnum; i++) { 935 MVNETA_LOG(INFO, "Creating %s", ifnames.names[i]); 936 ret = mvneta_eth_dev_create(vdev, ifnames.names[i]); 937 if (ret) 938 goto out_cleanup; 939 940 mvneta_dev_num++; 941 } 942 943 rte_kvargs_free(kvlist); 944 945 return 0; 946 out_cleanup: 947 rte_pmd_mvneta_remove(vdev); 948 949 out_free_kvlist: 950 rte_kvargs_free(kvlist); 951 952 return ret; 953 } 954 955 /** 956 * DPDK callback to remove virtual device. 957 * 958 * @param vdev 959 * Pointer to the removed virtual device. 960 * 961 * @return 962 * 0 on success, negative error value otherwise. 963 */ 964 static int 965 rte_pmd_mvneta_remove(struct rte_vdev_device *vdev) 966 { 967 uint16_t port_id; 968 969 RTE_ETH_FOREACH_DEV(port_id) { 970 if (rte_eth_devices[port_id].device != &vdev->device) 971 continue; 972 rte_eth_dev_close(port_id); 973 } 974 975 return 0; 976 } 977 978 static struct rte_vdev_driver pmd_mvneta_drv = { 979 .probe = rte_pmd_mvneta_probe, 980 .remove = rte_pmd_mvneta_remove, 981 }; 982 983 RTE_PMD_REGISTER_VDEV(net_mvneta, pmd_mvneta_drv); 984 RTE_PMD_REGISTER_PARAM_STRING(net_mvneta, "iface=<ifc>"); 985 986 RTE_INIT(mvneta_init_log) 987 { 988 mvneta_logtype = rte_log_register("pmd.net.mvneta"); 989 if (mvneta_logtype >= 0) 990 rte_log_set_level(mvneta_logtype, RTE_LOG_NOTICE); 991 } 992