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