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 stats->ierrors = ppio_stats.rx_packets_err - 710 priv->prev_stats.ierrors; 711 stats->oerrors = ppio_stats.tx_errors - priv->prev_stats.oerrors; 712 713 return 0; 714 } 715 716 /** 717 * DPDK callback to clear device statistics. 718 * 719 * @param dev 720 * Pointer to Ethernet device structure. 721 */ 722 static void 723 mvneta_stats_reset(struct rte_eth_dev *dev) 724 { 725 struct mvneta_priv *priv = dev->data->dev_private; 726 unsigned int ret; 727 728 if (!priv->ppio) 729 return; 730 731 ret = mvneta_stats_get(dev, &priv->prev_stats); 732 if (unlikely(ret)) 733 RTE_LOG(ERR, PMD, "Failed to reset port statistics"); 734 } 735 736 737 static const struct eth_dev_ops mvneta_ops = { 738 .dev_configure = mvneta_dev_configure, 739 .dev_start = mvneta_dev_start, 740 .dev_stop = mvneta_dev_stop, 741 .dev_set_link_up = mvneta_dev_set_link_up, 742 .dev_set_link_down = mvneta_dev_set_link_down, 743 .dev_close = mvneta_dev_close, 744 .link_update = mvneta_link_update, 745 .promiscuous_enable = mvneta_promiscuous_enable, 746 .promiscuous_disable = mvneta_promiscuous_disable, 747 .mac_addr_remove = mvneta_mac_addr_remove, 748 .mac_addr_add = mvneta_mac_addr_add, 749 .mac_addr_set = mvneta_mac_addr_set, 750 .mtu_set = mvneta_mtu_set, 751 .stats_get = mvneta_stats_get, 752 .stats_reset = mvneta_stats_reset, 753 .dev_infos_get = mvneta_dev_infos_get, 754 .dev_supported_ptypes_get = mvneta_dev_supported_ptypes_get, 755 .rxq_info_get = mvneta_rxq_info_get, 756 .txq_info_get = mvneta_txq_info_get, 757 .rx_queue_setup = mvneta_rx_queue_setup, 758 .rx_queue_release = mvneta_rx_queue_release, 759 .tx_queue_setup = mvneta_tx_queue_setup, 760 .tx_queue_release = mvneta_tx_queue_release, 761 }; 762 763 /** 764 * Create device representing Ethernet port. 765 * 766 * @param name 767 * Pointer to the port's name. 768 * 769 * @return 770 * 0 on success, negative error value otherwise. 771 */ 772 static int 773 mvneta_eth_dev_create(struct rte_vdev_device *vdev, const char *name) 774 { 775 int ret, fd = socket(AF_INET, SOCK_DGRAM, 0); 776 struct rte_eth_dev *eth_dev; 777 struct mvneta_priv *priv; 778 struct ifreq req; 779 780 eth_dev = rte_eth_dev_allocate(name); 781 if (!eth_dev) 782 return -ENOMEM; 783 784 priv = rte_zmalloc_socket(name, sizeof(*priv), 0, rte_socket_id()); 785 if (!priv) { 786 ret = -ENOMEM; 787 goto out_free; 788 } 789 eth_dev->data->dev_private = priv; 790 791 eth_dev->data->mac_addrs = 792 rte_zmalloc("mac_addrs", 793 ETHER_ADDR_LEN * MVNETA_MAC_ADDRS_MAX, 0); 794 if (!eth_dev->data->mac_addrs) { 795 MVNETA_LOG(ERR, "Failed to allocate space for eth addrs"); 796 ret = -ENOMEM; 797 goto out_free; 798 } 799 800 memset(&req, 0, sizeof(req)); 801 strcpy(req.ifr_name, name); 802 ret = ioctl(fd, SIOCGIFHWADDR, &req); 803 if (ret) 804 goto out_free; 805 806 memcpy(eth_dev->data->mac_addrs[0].addr_bytes, 807 req.ifr_addr.sa_data, ETHER_ADDR_LEN); 808 809 eth_dev->data->kdrv = RTE_KDRV_NONE; 810 eth_dev->device = &vdev->device; 811 eth_dev->rx_pkt_burst = mvneta_rx_pkt_burst; 812 mvneta_set_tx_function(eth_dev); 813 eth_dev->dev_ops = &mvneta_ops; 814 815 rte_eth_dev_probing_finish(eth_dev); 816 return 0; 817 out_free: 818 rte_eth_dev_release_port(eth_dev); 819 820 return ret; 821 } 822 823 /** 824 * Cleanup previously created device representing Ethernet port. 825 * 826 * @param eth_dev 827 * Pointer to the corresponding rte_eth_dev structure. 828 */ 829 static void 830 mvneta_eth_dev_destroy(struct rte_eth_dev *eth_dev) 831 { 832 rte_eth_dev_release_port(eth_dev); 833 } 834 835 /** 836 * Cleanup previously created device representing Ethernet port. 837 * 838 * @param name 839 * Pointer to the port name. 840 */ 841 static void 842 mvneta_eth_dev_destroy_name(const char *name) 843 { 844 struct rte_eth_dev *eth_dev; 845 846 eth_dev = rte_eth_dev_allocated(name); 847 if (!eth_dev) 848 return; 849 850 mvneta_eth_dev_destroy(eth_dev); 851 } 852 853 /** 854 * DPDK callback to register the virtual device. 855 * 856 * @param vdev 857 * Pointer to the virtual device. 858 * 859 * @return 860 * 0 on success, negative error value otherwise. 861 */ 862 static int 863 rte_pmd_mvneta_probe(struct rte_vdev_device *vdev) 864 { 865 struct rte_kvargs *kvlist; 866 struct mvneta_ifnames ifnames; 867 int ret = -EINVAL; 868 uint32_t i, ifnum; 869 const char *params; 870 871 params = rte_vdev_device_args(vdev); 872 if (!params) 873 return -EINVAL; 874 875 kvlist = rte_kvargs_parse(params, valid_args); 876 if (!kvlist) 877 return -EINVAL; 878 879 ifnum = rte_kvargs_count(kvlist, MVNETA_IFACE_NAME_ARG); 880 if (ifnum > RTE_DIM(ifnames.names)) 881 goto out_free_kvlist; 882 883 ifnames.idx = 0; 884 rte_kvargs_process(kvlist, MVNETA_IFACE_NAME_ARG, 885 mvneta_ifnames_get, &ifnames); 886 887 /* 888 * The below system initialization should be done only once, 889 * on the first provided configuration file 890 */ 891 if (mvneta_dev_num) 892 goto init_devices; 893 894 MVNETA_LOG(INFO, "Perform MUSDK initializations"); 895 896 ret = rte_mvep_init(MVEP_MOD_T_NETA, kvlist); 897 if (ret) 898 goto out_free_kvlist; 899 900 ret = mvneta_neta_init(); 901 if (ret) { 902 MVNETA_LOG(ERR, "Failed to init NETA!"); 903 rte_mvep_deinit(MVEP_MOD_T_NETA); 904 goto out_free_kvlist; 905 } 906 907 init_devices: 908 for (i = 0; i < ifnum; i++) { 909 MVNETA_LOG(INFO, "Creating %s", ifnames.names[i]); 910 ret = mvneta_eth_dev_create(vdev, ifnames.names[i]); 911 if (ret) 912 goto out_cleanup; 913 } 914 mvneta_dev_num += ifnum; 915 916 rte_kvargs_free(kvlist); 917 918 return 0; 919 out_cleanup: 920 for (; i > 0; i--) 921 mvneta_eth_dev_destroy_name(ifnames.names[i]); 922 923 if (mvneta_dev_num == 0) { 924 mvneta_neta_deinit(); 925 rte_mvep_deinit(MVEP_MOD_T_NETA); 926 } 927 out_free_kvlist: 928 rte_kvargs_free(kvlist); 929 930 return ret; 931 } 932 933 /** 934 * DPDK callback to remove virtual device. 935 * 936 * @param vdev 937 * Pointer to the removed virtual device. 938 * 939 * @return 940 * 0 on success, negative error value otherwise. 941 */ 942 static int 943 rte_pmd_mvneta_remove(struct rte_vdev_device *vdev) 944 { 945 int i; 946 const char *name; 947 948 name = rte_vdev_device_name(vdev); 949 if (!name) 950 return -EINVAL; 951 952 MVNETA_LOG(INFO, "Removing %s", name); 953 954 RTE_ETH_FOREACH_DEV(i) { 955 if (rte_eth_devices[i].device != &vdev->device) 956 continue; 957 958 mvneta_eth_dev_destroy(&rte_eth_devices[i]); 959 mvneta_dev_num--; 960 } 961 962 if (mvneta_dev_num == 0) { 963 MVNETA_LOG(INFO, "Perform MUSDK deinit"); 964 mvneta_neta_deinit(); 965 rte_mvep_deinit(MVEP_MOD_T_NETA); 966 } 967 968 return 0; 969 } 970 971 static struct rte_vdev_driver pmd_mvneta_drv = { 972 .probe = rte_pmd_mvneta_probe, 973 .remove = rte_pmd_mvneta_remove, 974 }; 975 976 RTE_PMD_REGISTER_VDEV(net_mvneta, pmd_mvneta_drv); 977 RTE_PMD_REGISTER_PARAM_STRING(net_mvneta, "iface=<ifc>"); 978 979 RTE_INIT(mvneta_init_log) 980 { 981 mvneta_logtype = rte_log_register("pmd.net.mvneta"); 982 if (mvneta_logtype >= 0) 983 rte_log_set_level(mvneta_logtype, RTE_LOG_NOTICE); 984 } 985