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