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