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_log.h> 10 #include <rte_malloc.h> 11 #include <rte_bus_vdev.h> 12 13 #include <stdio.h> 14 #include <fcntl.h> 15 #include <linux/ethtool.h> 16 #include <linux/sockios.h> 17 #include <net/if.h> 18 #include <net/if_arp.h> 19 #include <sys/ioctl.h> 20 #include <sys/socket.h> 21 #include <sys/stat.h> 22 #include <sys/types.h> 23 24 #include <rte_mvep_common.h> 25 26 #include "mvneta_ethdev.h" 27 28 29 #define MVNETA_IFACE_NAME_ARG "iface" 30 31 #define MVNETA_RX_OFFLOADS (DEV_RX_OFFLOAD_JUMBO_FRAME | \ 32 DEV_RX_OFFLOAD_CHECKSUM) 33 34 /** Port Tx offloads capabilities */ 35 #define MVNETA_TX_OFFLOADS (DEV_TX_OFFLOAD_IPV4_CKSUM | \ 36 DEV_TX_OFFLOAD_UDP_CKSUM | \ 37 DEV_TX_OFFLOAD_TCP_CKSUM | \ 38 DEV_TX_OFFLOAD_MULTI_SEGS) 39 40 #define MVNETA_PKT_SIZE_MAX (16382 - MV_MH_SIZE) /* 9700B */ 41 #define MVNETA_DEFAULT_MTU 1500 42 43 #define MVNETA_MAC_ADDRS_MAX 256 /*16 UC, 256 IP, 256 MC/BC */ 44 /** Maximum length of a match string */ 45 #define MVNETA_MATCH_LEN 16 46 47 int mvneta_logtype; 48 49 static const char * const valid_args[] = { 50 MVNETA_IFACE_NAME_ARG, 51 NULL 52 }; 53 54 struct mvneta_ifnames { 55 const char *names[NETA_NUM_ETH_PPIO]; 56 int idx; 57 }; 58 59 static int mvneta_dev_num; 60 61 /** 62 * Deinitialize packet processor. 63 */ 64 static void 65 mvneta_neta_deinit(void) 66 { 67 neta_deinit(); 68 } 69 70 /** 71 * Initialize packet processor. 72 * 73 * @return 74 * 0 on success, negative error value otherwise. 75 */ 76 static int 77 mvneta_neta_init(void) 78 { 79 return neta_init(); 80 } 81 82 /** 83 * Callback used by rte_kvargs_process() during argument parsing. 84 * 85 * @param key 86 * Pointer to the parsed key (unused). 87 * @param value 88 * Pointer to the parsed value. 89 * @param extra_args 90 * Pointer to the extra arguments which contains address of the 91 * table of pointers to parsed interface names. 92 * 93 * @return 94 * Always 0. 95 */ 96 static int 97 mvneta_ifnames_get(const char *key __rte_unused, const char *value, 98 void *extra_args) 99 { 100 struct mvneta_ifnames *ifnames = extra_args; 101 102 ifnames->names[ifnames->idx++] = value; 103 104 return 0; 105 } 106 107 /** 108 * Ethernet device configuration. 109 * 110 * Prepare the driver for a given number of TX and RX queues and 111 * configure RSS if supported. 112 * 113 * @param dev 114 * Pointer to Ethernet device structure. 115 * 116 * @return 117 * 0 on success, negative error value otherwise. 118 */ 119 static int 120 mvneta_dev_configure(struct rte_eth_dev *dev) 121 { 122 struct mvneta_priv *priv = dev->data->dev_private; 123 struct neta_ppio_params *ppio_params; 124 125 if (dev->data->dev_conf.rxmode.mq_mode != ETH_MQ_RX_NONE) { 126 MVNETA_LOG(INFO, "Unsupported RSS and rx multi queue mode %d", 127 dev->data->dev_conf.rxmode.mq_mode); 128 if (dev->data->nb_rx_queues > 1) 129 return -EINVAL; 130 } 131 132 if (dev->data->dev_conf.rxmode.split_hdr_size) { 133 MVNETA_LOG(INFO, "Split headers not supported"); 134 return -EINVAL; 135 } 136 137 if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) 138 dev->data->mtu = dev->data->dev_conf.rxmode.max_rx_pkt_len - 139 MRVL_NETA_ETH_HDRS_LEN; 140 141 if (dev->data->dev_conf.txmode.offloads & DEV_TX_OFFLOAD_MULTI_SEGS) 142 priv->multiseg = 1; 143 144 ppio_params = &priv->ppio_params; 145 ppio_params->outqs_params.num_outqs = dev->data->nb_tx_queues; 146 /* Default: 1 TC, no QoS supported. */ 147 ppio_params->inqs_params.num_tcs = 1; 148 ppio_params->inqs_params.tcs_params[0].pkt_offset = MRVL_NETA_PKT_OFFS; 149 priv->ppio_id = dev->data->port_id; 150 151 return 0; 152 } 153 154 /** 155 * DPDK callback to get information about the device. 156 * 157 * @param dev 158 * Pointer to Ethernet device structure (unused). 159 * @param info 160 * Info structure output buffer. 161 */ 162 static void 163 mvneta_dev_infos_get(struct rte_eth_dev *dev __rte_unused, 164 struct rte_eth_dev_info *info) 165 { 166 info->speed_capa = ETH_LINK_SPEED_10M | 167 ETH_LINK_SPEED_100M | 168 ETH_LINK_SPEED_1G | 169 ETH_LINK_SPEED_2_5G; 170 171 info->max_rx_queues = MRVL_NETA_RXQ_MAX; 172 info->max_tx_queues = MRVL_NETA_TXQ_MAX; 173 info->max_mac_addrs = MVNETA_MAC_ADDRS_MAX; 174 175 info->rx_desc_lim.nb_max = MRVL_NETA_RXD_MAX; 176 info->rx_desc_lim.nb_min = MRVL_NETA_RXD_MIN; 177 info->rx_desc_lim.nb_align = MRVL_NETA_RXD_ALIGN; 178 179 info->tx_desc_lim.nb_max = MRVL_NETA_TXD_MAX; 180 info->tx_desc_lim.nb_min = MRVL_NETA_TXD_MIN; 181 info->tx_desc_lim.nb_align = MRVL_NETA_TXD_ALIGN; 182 183 info->rx_offload_capa = MVNETA_RX_OFFLOADS; 184 info->rx_queue_offload_capa = MVNETA_RX_OFFLOADS; 185 186 info->tx_offload_capa = MVNETA_TX_OFFLOADS; 187 info->tx_queue_offload_capa = MVNETA_TX_OFFLOADS; 188 189 /* By default packets are dropped if no descriptors are available */ 190 info->default_rxconf.rx_drop_en = 1; 191 /* Deferred tx queue start is not supported */ 192 info->default_txconf.tx_deferred_start = 0; 193 info->default_txconf.offloads = 0; 194 195 info->max_rx_pktlen = MVNETA_PKT_SIZE_MAX; 196 } 197 198 /** 199 * Return supported packet types. 200 * 201 * @param dev 202 * Pointer to Ethernet device structure (unused). 203 * 204 * @return 205 * Const pointer to the table with supported packet types. 206 */ 207 static const uint32_t * 208 mvneta_dev_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused) 209 { 210 static const uint32_t ptypes[] = { 211 RTE_PTYPE_L2_ETHER, 212 RTE_PTYPE_L2_ETHER_VLAN, 213 RTE_PTYPE_L3_IPV4, 214 RTE_PTYPE_L3_IPV6, 215 RTE_PTYPE_L4_TCP, 216 RTE_PTYPE_L4_UDP 217 }; 218 219 return ptypes; 220 } 221 222 /** 223 * DPDK callback to bring the link up. 224 * 225 * @param dev 226 * Pointer to Ethernet device structure. 227 * 228 * @return 229 * 0 on success, negative error value otherwise. 230 */ 231 static int 232 mvneta_dev_set_link_up(struct rte_eth_dev *dev) 233 { 234 struct mvneta_priv *priv = dev->data->dev_private; 235 236 if (!priv->ppio) 237 return 0; 238 239 return neta_ppio_enable(priv->ppio); 240 } 241 242 /** 243 * DPDK callback to bring the link down. 244 * 245 * @param dev 246 * Pointer to Ethernet device structure. 247 * 248 * @return 249 * 0 on success, negative error value otherwise. 250 */ 251 static int 252 mvneta_dev_set_link_down(struct rte_eth_dev *dev) 253 { 254 struct mvneta_priv *priv = dev->data->dev_private; 255 256 if (!priv->ppio) 257 return 0; 258 259 return neta_ppio_disable(priv->ppio); 260 } 261 262 /** 263 * DPDK callback to start the device. 264 * 265 * @param dev 266 * Pointer to Ethernet device structure. 267 * 268 * @return 269 * 0 on success, negative errno value on failure. 270 */ 271 static int 272 mvneta_dev_start(struct rte_eth_dev *dev) 273 { 274 struct mvneta_priv *priv = dev->data->dev_private; 275 char match[MVNETA_MATCH_LEN]; 276 int ret = 0, i; 277 278 if (priv->ppio) 279 return mvneta_dev_set_link_up(dev); 280 281 snprintf(match, sizeof(match), "%s", dev->data->name); 282 priv->ppio_params.match = match; 283 priv->ppio_params.inqs_params.mtu = dev->data->mtu; 284 285 ret = neta_ppio_init(&priv->ppio_params, &priv->ppio); 286 if (ret) { 287 MVNETA_LOG(ERR, "Failed to init ppio"); 288 return ret; 289 } 290 priv->ppio_id = priv->ppio->port_id; 291 292 /* 293 * In case there are some some stale uc/mc mac addresses flush them 294 * here. It cannot be done during mvneta_dev_close() as port information 295 * is already gone at that point (due to neta_ppio_deinit() in 296 * mvneta_dev_stop()). 297 */ 298 if (!priv->uc_mc_flushed) { 299 ret = neta_ppio_flush_mac_addrs(priv->ppio, 0, 1); 300 if (ret) { 301 MVNETA_LOG(ERR, 302 "Failed to flush uc/mc filter list"); 303 goto out; 304 } 305 priv->uc_mc_flushed = 1; 306 } 307 308 ret = mvneta_dev_set_link_up(dev); 309 if (ret) { 310 MVNETA_LOG(ERR, "Failed to set link up"); 311 goto out; 312 } 313 314 /* start tx queues */ 315 for (i = 0; i < dev->data->nb_tx_queues; i++) 316 dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED; 317 318 return 0; 319 320 out: 321 MVNETA_LOG(ERR, "Failed to start device"); 322 neta_ppio_deinit(priv->ppio); 323 return ret; 324 } 325 326 /** 327 * DPDK callback to stop the device. 328 * 329 * @param dev 330 * Pointer to Ethernet device structure. 331 */ 332 static void 333 mvneta_dev_stop(struct rte_eth_dev *dev) 334 { 335 struct mvneta_priv *priv = dev->data->dev_private; 336 337 if (!priv->ppio) 338 return; 339 340 mvneta_dev_set_link_down(dev); 341 342 neta_ppio_deinit(priv->ppio); 343 344 priv->ppio = NULL; 345 } 346 347 /** 348 * DPDK callback to close the device. 349 * 350 * @param dev 351 * Pointer to Ethernet device structure. 352 */ 353 static void 354 mvneta_dev_close(struct rte_eth_dev *dev) 355 { 356 struct mvneta_priv *priv = dev->data->dev_private; 357 358 if (priv->ppio) 359 mvneta_dev_stop(dev); 360 } 361 362 /** 363 * DPDK callback to set the primary MAC address. 364 * 365 * @param dev 366 * Pointer to Ethernet device structure. 367 * @param mac_addr 368 * MAC address to register. 369 */ 370 static int 371 mvneta_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr) 372 { 373 struct mvneta_priv *priv = dev->data->dev_private; 374 int ret; 375 376 if (!priv->ppio) 377 return -EINVAL; 378 379 ret = neta_ppio_set_mac_addr(priv->ppio, mac_addr->addr_bytes); 380 if (ret) { 381 char buf[ETHER_ADDR_FMT_SIZE]; 382 ether_format_addr(buf, sizeof(buf), mac_addr); 383 MVNETA_LOG(ERR, "Failed to set mac to %s", buf); 384 } 385 return 0; 386 } 387 388 static const struct eth_dev_ops mvneta_ops = { 389 .dev_configure = mvneta_dev_configure, 390 .dev_start = mvneta_dev_start, 391 .dev_stop = mvneta_dev_stop, 392 .dev_set_link_up = mvneta_dev_set_link_up, 393 .dev_set_link_down = mvneta_dev_set_link_down, 394 .dev_close = mvneta_dev_close, 395 .mac_addr_set = mvneta_mac_addr_set, 396 .dev_infos_get = mvneta_dev_infos_get, 397 .dev_supported_ptypes_get = mvneta_dev_supported_ptypes_get, 398 }; 399 400 /** 401 * Create device representing Ethernet port. 402 * 403 * @param name 404 * Pointer to the port's name. 405 * 406 * @return 407 * 0 on success, negative error value otherwise. 408 */ 409 static int 410 mvneta_eth_dev_create(struct rte_vdev_device *vdev, const char *name) 411 { 412 int ret, fd = socket(AF_INET, SOCK_DGRAM, 0); 413 struct rte_eth_dev *eth_dev; 414 struct mvneta_priv *priv; 415 struct ifreq req; 416 417 eth_dev = rte_eth_dev_allocate(name); 418 if (!eth_dev) 419 return -ENOMEM; 420 421 priv = rte_zmalloc_socket(name, sizeof(*priv), 0, rte_socket_id()); 422 if (!priv) { 423 ret = -ENOMEM; 424 goto out_free_dev; 425 } 426 427 eth_dev->data->mac_addrs = 428 rte_zmalloc("mac_addrs", 429 ETHER_ADDR_LEN * MVNETA_MAC_ADDRS_MAX, 0); 430 if (!eth_dev->data->mac_addrs) { 431 MVNETA_LOG(ERR, "Failed to allocate space for eth addrs"); 432 ret = -ENOMEM; 433 goto out_free_priv; 434 } 435 436 memset(&req, 0, sizeof(req)); 437 strcpy(req.ifr_name, name); 438 ret = ioctl(fd, SIOCGIFHWADDR, &req); 439 if (ret) 440 goto out_free_mac; 441 442 memcpy(eth_dev->data->mac_addrs[0].addr_bytes, 443 req.ifr_addr.sa_data, ETHER_ADDR_LEN); 444 445 eth_dev->data->kdrv = RTE_KDRV_NONE; 446 eth_dev->data->dev_private = priv; 447 eth_dev->device = &vdev->device; 448 eth_dev->dev_ops = &mvneta_ops; 449 450 rte_eth_dev_probing_finish(eth_dev); 451 return 0; 452 out_free_mac: 453 rte_free(eth_dev->data->mac_addrs); 454 out_free_priv: 455 rte_free(priv); 456 out_free_dev: 457 rte_eth_dev_release_port(eth_dev); 458 459 return ret; 460 } 461 462 /** 463 * Cleanup previously created device representing Ethernet port. 464 * 465 * @param eth_dev 466 * Pointer to the corresponding rte_eth_dev structure. 467 */ 468 static void 469 mvneta_eth_dev_destroy(struct rte_eth_dev *eth_dev) 470 { 471 rte_free(eth_dev->data->dev_private); 472 rte_free(eth_dev->data->mac_addrs); 473 rte_eth_dev_release_port(eth_dev); 474 } 475 476 /** 477 * Cleanup previously created device representing Ethernet port. 478 * 479 * @param name 480 * Pointer to the port name. 481 */ 482 static void 483 mvneta_eth_dev_destroy_name(const char *name) 484 { 485 struct rte_eth_dev *eth_dev; 486 487 eth_dev = rte_eth_dev_allocated(name); 488 if (!eth_dev) 489 return; 490 491 mvneta_eth_dev_destroy(eth_dev); 492 } 493 494 /** 495 * DPDK callback to register the virtual device. 496 * 497 * @param vdev 498 * Pointer to the virtual device. 499 * 500 * @return 501 * 0 on success, negative error value otherwise. 502 */ 503 static int 504 rte_pmd_mvneta_probe(struct rte_vdev_device *vdev) 505 { 506 struct rte_kvargs *kvlist; 507 struct mvneta_ifnames ifnames; 508 int ret = -EINVAL; 509 uint32_t i, ifnum; 510 const char *params; 511 512 params = rte_vdev_device_args(vdev); 513 if (!params) 514 return -EINVAL; 515 516 kvlist = rte_kvargs_parse(params, valid_args); 517 if (!kvlist) 518 return -EINVAL; 519 520 ifnum = rte_kvargs_count(kvlist, MVNETA_IFACE_NAME_ARG); 521 if (ifnum > RTE_DIM(ifnames.names)) 522 goto out_free_kvlist; 523 524 ifnames.idx = 0; 525 rte_kvargs_process(kvlist, MVNETA_IFACE_NAME_ARG, 526 mvneta_ifnames_get, &ifnames); 527 528 /* 529 * The below system initialization should be done only once, 530 * on the first provided configuration file 531 */ 532 if (mvneta_dev_num) 533 goto init_devices; 534 535 MVNETA_LOG(INFO, "Perform MUSDK initializations"); 536 537 ret = rte_mvep_init(MVEP_MOD_T_NETA, kvlist); 538 if (ret) 539 goto out_free_kvlist; 540 541 ret = mvneta_neta_init(); 542 if (ret) { 543 MVNETA_LOG(ERR, "Failed to init NETA!"); 544 rte_mvep_deinit(MVEP_MOD_T_NETA); 545 goto out_free_kvlist; 546 } 547 548 init_devices: 549 for (i = 0; i < ifnum; i++) { 550 MVNETA_LOG(INFO, "Creating %s", ifnames.names[i]); 551 ret = mvneta_eth_dev_create(vdev, ifnames.names[i]); 552 if (ret) 553 goto out_cleanup; 554 } 555 mvneta_dev_num += ifnum; 556 557 rte_kvargs_free(kvlist); 558 559 return 0; 560 out_cleanup: 561 for (; i > 0; i--) 562 mvneta_eth_dev_destroy_name(ifnames.names[i]); 563 564 if (mvneta_dev_num == 0) { 565 mvneta_neta_deinit(); 566 rte_mvep_deinit(MVEP_MOD_T_NETA); 567 } 568 out_free_kvlist: 569 rte_kvargs_free(kvlist); 570 571 return ret; 572 } 573 574 /** 575 * DPDK callback to remove virtual device. 576 * 577 * @param vdev 578 * Pointer to the removed virtual device. 579 * 580 * @return 581 * 0 on success, negative error value otherwise. 582 */ 583 static int 584 rte_pmd_mvneta_remove(struct rte_vdev_device *vdev) 585 { 586 int i; 587 const char *name; 588 589 name = rte_vdev_device_name(vdev); 590 if (!name) 591 return -EINVAL; 592 593 MVNETA_LOG(INFO, "Removing %s", name); 594 595 RTE_ETH_FOREACH_DEV(i) { 596 if (rte_eth_devices[i].device != &vdev->device) 597 continue; 598 599 mvneta_eth_dev_destroy(&rte_eth_devices[i]); 600 mvneta_dev_num--; 601 } 602 603 if (mvneta_dev_num == 0) { 604 MVNETA_LOG(INFO, "Perform MUSDK deinit"); 605 mvneta_neta_deinit(); 606 rte_mvep_deinit(MVEP_MOD_T_NETA); 607 } 608 609 return 0; 610 } 611 612 static struct rte_vdev_driver pmd_mvneta_drv = { 613 .probe = rte_pmd_mvneta_probe, 614 .remove = rte_pmd_mvneta_remove, 615 }; 616 617 RTE_PMD_REGISTER_VDEV(net_mvneta, pmd_mvneta_drv); 618 RTE_PMD_REGISTER_PARAM_STRING(net_mvneta, "iface=<ifc>"); 619 620 RTE_INIT(mvneta_init_log) 621 { 622 mvneta_logtype = rte_log_register("pmd.net.mvneta"); 623 if (mvneta_logtype >= 0) 624 rte_log_set_level(mvneta_logtype, RTE_LOG_NOTICE); 625 } 626