1 /* 2 * BSD LICENSE 3 * 4 * Copyright (C) Cavium Inc. 2017. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * * Neither the name of Cavium networks nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 #include <stdio.h> 33 #include <stdarg.h> 34 #include <stdbool.h> 35 #include <stdint.h> 36 #include <string.h> 37 #include <unistd.h> 38 39 #include <rte_alarm.h> 40 #include <rte_branch_prediction.h> 41 #include <rte_debug.h> 42 #include <rte_devargs.h> 43 #include <rte_dev.h> 44 #include <rte_kvargs.h> 45 #include <rte_malloc.h> 46 #include <rte_prefetch.h> 47 #include <rte_vdev.h> 48 49 #include "octeontx_ethdev.h" 50 #include "octeontx_rxtx.h" 51 #include "octeontx_logs.h" 52 53 struct octeontx_vdev_init_params { 54 uint8_t nr_port; 55 }; 56 57 enum octeontx_link_speed { 58 OCTEONTX_LINK_SPEED_SGMII, 59 OCTEONTX_LINK_SPEED_XAUI, 60 OCTEONTX_LINK_SPEED_RXAUI, 61 OCTEONTX_LINK_SPEED_10G_R, 62 OCTEONTX_LINK_SPEED_40G_R, 63 OCTEONTX_LINK_SPEED_RESERVE1, 64 OCTEONTX_LINK_SPEED_QSGMII, 65 OCTEONTX_LINK_SPEED_RESERVE2 66 }; 67 68 /* Parse integer from integer argument */ 69 static int 70 parse_integer_arg(const char *key __rte_unused, 71 const char *value, void *extra_args) 72 { 73 int *i = (int *)extra_args; 74 75 *i = atoi(value); 76 if (*i < 0) { 77 octeontx_log_err("argument has to be positive."); 78 return -1; 79 } 80 81 return 0; 82 } 83 84 static int 85 octeontx_parse_vdev_init_params(struct octeontx_vdev_init_params *params, 86 struct rte_vdev_device *dev) 87 { 88 struct rte_kvargs *kvlist = NULL; 89 int ret = 0; 90 91 static const char * const octeontx_vdev_valid_params[] = { 92 OCTEONTX_VDEV_NR_PORT_ARG, 93 NULL 94 }; 95 96 const char *input_args = rte_vdev_device_args(dev); 97 if (params == NULL) 98 return -EINVAL; 99 100 101 if (input_args) { 102 kvlist = rte_kvargs_parse(input_args, 103 octeontx_vdev_valid_params); 104 if (kvlist == NULL) 105 return -1; 106 107 ret = rte_kvargs_process(kvlist, 108 OCTEONTX_VDEV_NR_PORT_ARG, 109 &parse_integer_arg, 110 ¶ms->nr_port); 111 if (ret < 0) 112 goto free_kvlist; 113 } 114 115 free_kvlist: 116 rte_kvargs_free(kvlist); 117 return ret; 118 } 119 120 static int 121 octeontx_port_open(struct octeontx_nic *nic) 122 { 123 octeontx_mbox_bgx_port_conf_t bgx_port_conf; 124 int res; 125 126 res = 0; 127 128 PMD_INIT_FUNC_TRACE(); 129 130 res = octeontx_bgx_port_open(nic->port_id, &bgx_port_conf); 131 if (res < 0) { 132 octeontx_log_err("failed to open port %d", res); 133 return res; 134 } 135 136 nic->node = bgx_port_conf.node; 137 nic->port_ena = bgx_port_conf.enable; 138 nic->base_ichan = bgx_port_conf.base_chan; 139 nic->base_ochan = bgx_port_conf.base_chan; 140 nic->num_ichans = bgx_port_conf.num_chans; 141 nic->num_ochans = bgx_port_conf.num_chans; 142 nic->mtu = bgx_port_conf.mtu; 143 nic->bpen = bgx_port_conf.bpen; 144 nic->fcs_strip = bgx_port_conf.fcs_strip; 145 nic->bcast_mode = bgx_port_conf.bcast_mode; 146 nic->mcast_mode = bgx_port_conf.mcast_mode; 147 nic->speed = bgx_port_conf.mode; 148 149 memcpy(&nic->mac_addr[0], &bgx_port_conf.macaddr[0], ETHER_ADDR_LEN); 150 151 octeontx_log_dbg("port opened %d", nic->port_id); 152 return res; 153 } 154 155 static void 156 octeontx_port_close(struct octeontx_nic *nic) 157 { 158 PMD_INIT_FUNC_TRACE(); 159 160 octeontx_bgx_port_close(nic->port_id); 161 octeontx_log_dbg("port closed %d", nic->port_id); 162 } 163 164 static int 165 octeontx_port_start(struct octeontx_nic *nic) 166 { 167 PMD_INIT_FUNC_TRACE(); 168 169 return octeontx_bgx_port_start(nic->port_id); 170 } 171 172 static int 173 octeontx_port_stop(struct octeontx_nic *nic) 174 { 175 PMD_INIT_FUNC_TRACE(); 176 177 return octeontx_bgx_port_stop(nic->port_id); 178 } 179 180 static void 181 octeontx_port_promisc_set(struct octeontx_nic *nic, int en) 182 { 183 struct rte_eth_dev *dev; 184 int res; 185 186 res = 0; 187 PMD_INIT_FUNC_TRACE(); 188 dev = nic->dev; 189 190 res = octeontx_bgx_port_promisc_set(nic->port_id, en); 191 if (res < 0) 192 octeontx_log_err("failed to set promiscuous mode %d", 193 nic->port_id); 194 195 /* Set proper flag for the mode */ 196 dev->data->promiscuous = (en != 0) ? 1 : 0; 197 198 octeontx_log_dbg("port %d : promiscuous mode %s", 199 nic->port_id, en ? "set" : "unset"); 200 } 201 202 static void 203 octeontx_port_stats(struct octeontx_nic *nic, struct rte_eth_stats *stats) 204 { 205 octeontx_mbox_bgx_port_stats_t bgx_stats; 206 int res; 207 208 PMD_INIT_FUNC_TRACE(); 209 210 res = octeontx_bgx_port_stats(nic->port_id, &bgx_stats); 211 if (res < 0) 212 octeontx_log_err("failed to get port stats %d", nic->port_id); 213 214 stats->ipackets = bgx_stats.rx_packets; 215 stats->ibytes = bgx_stats.rx_bytes; 216 stats->imissed = bgx_stats.rx_dropped; 217 stats->ierrors = bgx_stats.rx_errors; 218 stats->opackets = bgx_stats.tx_packets; 219 stats->obytes = bgx_stats.tx_bytes; 220 stats->oerrors = bgx_stats.tx_errors; 221 222 octeontx_log_dbg("port%d stats inpkts=%" PRIx64 " outpkts=%" PRIx64 "", 223 nic->port_id, stats->ipackets, stats->opackets); 224 } 225 226 static void 227 octeontx_port_stats_clr(struct octeontx_nic *nic) 228 { 229 PMD_INIT_FUNC_TRACE(); 230 231 octeontx_bgx_port_stats_clr(nic->port_id); 232 } 233 234 static inline void 235 devconf_set_default_sane_values(struct rte_event_dev_config *dev_conf, 236 struct rte_event_dev_info *info) 237 { 238 memset(dev_conf, 0, sizeof(struct rte_event_dev_config)); 239 dev_conf->dequeue_timeout_ns = info->min_dequeue_timeout_ns; 240 241 dev_conf->nb_event_ports = info->max_event_ports; 242 dev_conf->nb_event_queues = info->max_event_queues; 243 244 dev_conf->nb_event_queue_flows = info->max_event_queue_flows; 245 dev_conf->nb_event_port_dequeue_depth = 246 info->max_event_port_dequeue_depth; 247 dev_conf->nb_event_port_enqueue_depth = 248 info->max_event_port_enqueue_depth; 249 dev_conf->nb_event_port_enqueue_depth = 250 info->max_event_port_enqueue_depth; 251 dev_conf->nb_events_limit = 252 info->max_num_events; 253 } 254 255 static int 256 octeontx_dev_configure(struct rte_eth_dev *dev) 257 { 258 struct rte_eth_dev_data *data = dev->data; 259 struct rte_eth_conf *conf = &data->dev_conf; 260 struct rte_eth_rxmode *rxmode = &conf->rxmode; 261 struct rte_eth_txmode *txmode = &conf->txmode; 262 struct octeontx_nic *nic = octeontx_pmd_priv(dev); 263 int ret; 264 265 PMD_INIT_FUNC_TRACE(); 266 RTE_SET_USED(conf); 267 268 if (!rte_eal_has_hugepages()) { 269 octeontx_log_err("huge page is not configured"); 270 return -EINVAL; 271 } 272 273 if (txmode->mq_mode) { 274 octeontx_log_err("tx mq_mode DCB or VMDq not supported"); 275 return -EINVAL; 276 } 277 278 if (rxmode->mq_mode != ETH_MQ_RX_NONE && 279 rxmode->mq_mode != ETH_MQ_RX_RSS) { 280 octeontx_log_err("unsupported rx qmode %d", rxmode->mq_mode); 281 return -EINVAL; 282 } 283 284 if (!rxmode->hw_strip_crc) { 285 PMD_INIT_LOG(NOTICE, "can't disable hw crc strip"); 286 rxmode->hw_strip_crc = 1; 287 } 288 289 if (rxmode->hw_ip_checksum) { 290 PMD_INIT_LOG(NOTICE, "rxcksum not supported"); 291 rxmode->hw_ip_checksum = 0; 292 } 293 294 if (rxmode->split_hdr_size) { 295 octeontx_log_err("rxmode does not support split header"); 296 return -EINVAL; 297 } 298 299 if (rxmode->hw_vlan_filter) { 300 octeontx_log_err("VLAN filter not supported"); 301 return -EINVAL; 302 } 303 304 if (rxmode->hw_vlan_extend) { 305 octeontx_log_err("VLAN extended not supported"); 306 return -EINVAL; 307 } 308 309 if (rxmode->enable_lro) { 310 octeontx_log_err("LRO not supported"); 311 return -EINVAL; 312 } 313 314 if (conf->link_speeds & ETH_LINK_SPEED_FIXED) { 315 octeontx_log_err("setting link speed/duplex not supported"); 316 return -EINVAL; 317 } 318 319 if (conf->dcb_capability_en) { 320 octeontx_log_err("DCB enable not supported"); 321 return -EINVAL; 322 } 323 324 if (conf->fdir_conf.mode != RTE_FDIR_MODE_NONE) { 325 octeontx_log_err("flow director not supported"); 326 return -EINVAL; 327 } 328 329 nic->num_tx_queues = dev->data->nb_tx_queues; 330 331 ret = octeontx_pko_channel_open(nic->port_id * PKO_VF_NUM_DQ, 332 nic->num_tx_queues, 333 nic->base_ochan); 334 if (ret) { 335 octeontx_log_err("failed to open channel %d no-of-txq %d", 336 nic->base_ochan, nic->num_tx_queues); 337 return -EFAULT; 338 } 339 340 nic->pki.classifier_enable = false; 341 nic->pki.hash_enable = true; 342 nic->pki.initialized = false; 343 344 return 0; 345 } 346 347 static void 348 octeontx_dev_close(struct rte_eth_dev *dev) 349 { 350 struct octeontx_txq *txq = NULL; 351 struct octeontx_nic *nic = octeontx_pmd_priv(dev); 352 unsigned int i; 353 int ret; 354 355 PMD_INIT_FUNC_TRACE(); 356 357 rte_event_dev_close(nic->evdev); 358 359 ret = octeontx_pko_channel_close(nic->base_ochan); 360 if (ret < 0) { 361 octeontx_log_err("failed to close channel %d VF%d %d %d", 362 nic->base_ochan, nic->port_id, nic->num_tx_queues, 363 ret); 364 } 365 /* Free txq resources for this port */ 366 for (i = 0; i < nic->num_tx_queues; i++) { 367 txq = dev->data->tx_queues[i]; 368 if (!txq) 369 continue; 370 371 rte_free(txq); 372 } 373 } 374 375 static int 376 octeontx_dev_start(struct rte_eth_dev *dev) 377 { 378 struct octeontx_nic *nic = octeontx_pmd_priv(dev); 379 int ret; 380 381 ret = 0; 382 383 PMD_INIT_FUNC_TRACE(); 384 /* 385 * Tx start 386 */ 387 dev->tx_pkt_burst = octeontx_xmit_pkts; 388 ret = octeontx_pko_channel_start(nic->base_ochan); 389 if (ret < 0) { 390 octeontx_log_err("fail to conf VF%d no. txq %d chan %d ret %d", 391 nic->port_id, nic->num_tx_queues, nic->base_ochan, 392 ret); 393 goto error; 394 } 395 396 /* 397 * Rx start 398 */ 399 dev->rx_pkt_burst = octeontx_recv_pkts; 400 ret = octeontx_pki_port_start(nic->port_id); 401 if (ret < 0) { 402 octeontx_log_err("fail to start Rx on port %d", nic->port_id); 403 goto channel_stop_error; 404 } 405 406 /* 407 * Start port 408 */ 409 ret = octeontx_port_start(nic); 410 if (ret < 0) { 411 octeontx_log_err("failed start port %d", ret); 412 goto pki_port_stop_error; 413 } 414 415 PMD_TX_LOG(DEBUG, "pko: start channel %d no.of txq %d port %d", 416 nic->base_ochan, nic->num_tx_queues, nic->port_id); 417 418 ret = rte_event_dev_start(nic->evdev); 419 if (ret < 0) { 420 octeontx_log_err("failed to start evdev: ret (%d)", ret); 421 goto pki_port_stop_error; 422 } 423 424 /* Success */ 425 return ret; 426 427 pki_port_stop_error: 428 octeontx_pki_port_stop(nic->port_id); 429 channel_stop_error: 430 octeontx_pko_channel_stop(nic->base_ochan); 431 error: 432 return ret; 433 } 434 435 static void 436 octeontx_dev_stop(struct rte_eth_dev *dev) 437 { 438 struct octeontx_nic *nic = octeontx_pmd_priv(dev); 439 int ret; 440 441 PMD_INIT_FUNC_TRACE(); 442 443 rte_event_dev_stop(nic->evdev); 444 445 ret = octeontx_port_stop(nic); 446 if (ret < 0) { 447 octeontx_log_err("failed to req stop port %d res=%d", 448 nic->port_id, ret); 449 return; 450 } 451 452 ret = octeontx_pki_port_stop(nic->port_id); 453 if (ret < 0) { 454 octeontx_log_err("failed to stop pki port %d res=%d", 455 nic->port_id, ret); 456 return; 457 } 458 459 ret = octeontx_pko_channel_stop(nic->base_ochan); 460 if (ret < 0) { 461 octeontx_log_err("failed to stop channel %d VF%d %d %d", 462 nic->base_ochan, nic->port_id, nic->num_tx_queues, 463 ret); 464 return; 465 } 466 467 dev->tx_pkt_burst = NULL; 468 dev->rx_pkt_burst = NULL; 469 } 470 471 static void 472 octeontx_dev_promisc_enable(struct rte_eth_dev *dev) 473 { 474 struct octeontx_nic *nic = octeontx_pmd_priv(dev); 475 476 PMD_INIT_FUNC_TRACE(); 477 octeontx_port_promisc_set(nic, 1); 478 } 479 480 static void 481 octeontx_dev_promisc_disable(struct rte_eth_dev *dev) 482 { 483 struct octeontx_nic *nic = octeontx_pmd_priv(dev); 484 485 PMD_INIT_FUNC_TRACE(); 486 octeontx_port_promisc_set(nic, 0); 487 } 488 489 static inline int 490 octeontx_atomic_write_link_status(struct rte_eth_dev *dev, 491 struct rte_eth_link *link) 492 { 493 struct rte_eth_link *dst = &dev->data->dev_link; 494 struct rte_eth_link *src = link; 495 496 if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst, 497 *(uint64_t *)src) == 0) 498 return -1; 499 500 return 0; 501 } 502 503 static int 504 octeontx_port_link_status(struct octeontx_nic *nic) 505 { 506 int res; 507 508 PMD_INIT_FUNC_TRACE(); 509 res = octeontx_bgx_port_link_status(nic->port_id); 510 if (res < 0) { 511 octeontx_log_err("failed to get port %d link status", 512 nic->port_id); 513 return res; 514 } 515 516 nic->link_up = (uint8_t)res; 517 octeontx_log_dbg("port %d link status %d", nic->port_id, nic->link_up); 518 519 return res; 520 } 521 522 /* 523 * Return 0 means link status changed, -1 means not changed 524 */ 525 static int 526 octeontx_dev_link_update(struct rte_eth_dev *dev, 527 int wait_to_complete __rte_unused) 528 { 529 struct octeontx_nic *nic = octeontx_pmd_priv(dev); 530 struct rte_eth_link link; 531 int res; 532 533 res = 0; 534 PMD_INIT_FUNC_TRACE(); 535 536 res = octeontx_port_link_status(nic); 537 if (res < 0) { 538 octeontx_log_err("failed to request link status %d", res); 539 return res; 540 } 541 542 link.link_status = nic->link_up; 543 544 switch (nic->speed) { 545 case OCTEONTX_LINK_SPEED_SGMII: 546 link.link_speed = ETH_SPEED_NUM_1G; 547 break; 548 549 case OCTEONTX_LINK_SPEED_XAUI: 550 link.link_speed = ETH_SPEED_NUM_10G; 551 break; 552 553 case OCTEONTX_LINK_SPEED_RXAUI: 554 case OCTEONTX_LINK_SPEED_10G_R: 555 link.link_speed = ETH_SPEED_NUM_10G; 556 break; 557 case OCTEONTX_LINK_SPEED_QSGMII: 558 link.link_speed = ETH_SPEED_NUM_5G; 559 break; 560 case OCTEONTX_LINK_SPEED_40G_R: 561 link.link_speed = ETH_SPEED_NUM_40G; 562 break; 563 564 case OCTEONTX_LINK_SPEED_RESERVE1: 565 case OCTEONTX_LINK_SPEED_RESERVE2: 566 default: 567 octeontx_log_err("incorrect link speed %d", nic->speed); 568 break; 569 } 570 571 link.link_duplex = ETH_LINK_AUTONEG; 572 link.link_autoneg = ETH_LINK_SPEED_AUTONEG; 573 574 return octeontx_atomic_write_link_status(dev, &link); 575 } 576 577 static void 578 octeontx_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) 579 { 580 struct octeontx_nic *nic = octeontx_pmd_priv(dev); 581 582 PMD_INIT_FUNC_TRACE(); 583 octeontx_port_stats(nic, stats); 584 } 585 586 static void 587 octeontx_dev_stats_reset(struct rte_eth_dev *dev) 588 { 589 struct octeontx_nic *nic = octeontx_pmd_priv(dev); 590 591 PMD_INIT_FUNC_TRACE(); 592 octeontx_port_stats_clr(nic); 593 } 594 595 static void 596 octeontx_dev_default_mac_addr_set(struct rte_eth_dev *dev, 597 struct ether_addr *addr) 598 { 599 struct octeontx_nic *nic = octeontx_pmd_priv(dev); 600 int ret; 601 602 ret = octeontx_bgx_port_mac_set(nic->port_id, addr->addr_bytes); 603 if (ret != 0) 604 octeontx_log_err("failed to set MAC address on port %d", 605 nic->port_id); 606 } 607 608 static void 609 octeontx_dev_info(struct rte_eth_dev *dev, 610 struct rte_eth_dev_info *dev_info) 611 { 612 RTE_SET_USED(dev); 613 614 /* Autonegotiation may be disabled */ 615 dev_info->speed_capa = ETH_LINK_SPEED_FIXED; 616 dev_info->speed_capa |= ETH_LINK_SPEED_10M | ETH_LINK_SPEED_100M | 617 ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G | 618 ETH_LINK_SPEED_40G; 619 620 dev_info->driver_name = RTE_STR(rte_octeontx_pmd); 621 dev_info->max_mac_addrs = 1; 622 dev_info->max_rx_pktlen = PKI_MAX_PKTLEN; 623 dev_info->max_rx_queues = 1; 624 dev_info->max_tx_queues = PKO_MAX_NUM_DQ; 625 dev_info->min_rx_bufsize = 0; 626 dev_info->pci_dev = NULL; 627 628 dev_info->default_rxconf = (struct rte_eth_rxconf) { 629 .rx_free_thresh = 0, 630 .rx_drop_en = 0, 631 }; 632 633 dev_info->default_txconf = (struct rte_eth_txconf) { 634 .tx_free_thresh = 0, 635 .txq_flags = 636 ETH_TXQ_FLAGS_NOMULTSEGS | 637 ETH_TXQ_FLAGS_NOOFFLOADS | 638 ETH_TXQ_FLAGS_NOXSUMS, 639 }; 640 641 dev_info->tx_offload_capa = DEV_TX_OFFLOAD_MT_LOCKFREE; 642 } 643 644 static void 645 octeontx_dq_info_getter(octeontx_dq_t *dq, void *out) 646 { 647 ((octeontx_dq_t *)out)->lmtline_va = dq->lmtline_va; 648 ((octeontx_dq_t *)out)->ioreg_va = dq->ioreg_va; 649 ((octeontx_dq_t *)out)->fc_status_va = dq->fc_status_va; 650 } 651 652 static int 653 octeontx_vf_start_tx_queue(struct rte_eth_dev *dev, struct octeontx_nic *nic, 654 uint16_t qidx) 655 { 656 struct octeontx_txq *txq; 657 int res; 658 659 PMD_INIT_FUNC_TRACE(); 660 661 if (dev->data->tx_queue_state[qidx] == RTE_ETH_QUEUE_STATE_STARTED) 662 return 0; 663 664 txq = dev->data->tx_queues[qidx]; 665 666 res = octeontx_pko_channel_query_dqs(nic->base_ochan, 667 &txq->dq, 668 sizeof(octeontx_dq_t), 669 txq->queue_id, 670 octeontx_dq_info_getter); 671 if (res < 0) { 672 res = -EFAULT; 673 goto close_port; 674 } 675 676 dev->data->tx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STARTED; 677 return res; 678 679 close_port: 680 (void)octeontx_port_stop(nic); 681 octeontx_pko_channel_stop(nic->base_ochan); 682 octeontx_pko_channel_close(nic->base_ochan); 683 dev->data->tx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STOPPED; 684 return res; 685 } 686 687 static int 688 octeontx_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t qidx) 689 { 690 struct octeontx_nic *nic = octeontx_pmd_priv(dev); 691 692 PMD_INIT_FUNC_TRACE(); 693 qidx = qidx % PKO_VF_NUM_DQ; 694 return octeontx_vf_start_tx_queue(dev, nic, qidx); 695 } 696 697 static inline int 698 octeontx_vf_stop_tx_queue(struct rte_eth_dev *dev, struct octeontx_nic *nic, 699 uint16_t qidx) 700 { 701 int ret = 0; 702 703 RTE_SET_USED(nic); 704 PMD_INIT_FUNC_TRACE(); 705 706 if (dev->data->tx_queue_state[qidx] == RTE_ETH_QUEUE_STATE_STOPPED) 707 return 0; 708 709 dev->data->tx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STOPPED; 710 return ret; 711 } 712 713 static int 714 octeontx_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t qidx) 715 { 716 struct octeontx_nic *nic = octeontx_pmd_priv(dev); 717 718 PMD_INIT_FUNC_TRACE(); 719 qidx = qidx % PKO_VF_NUM_DQ; 720 721 return octeontx_vf_stop_tx_queue(dev, nic, qidx); 722 } 723 724 static void 725 octeontx_dev_tx_queue_release(void *tx_queue) 726 { 727 struct octeontx_txq *txq = tx_queue; 728 int res; 729 730 PMD_INIT_FUNC_TRACE(); 731 732 if (txq) { 733 res = octeontx_dev_tx_queue_stop(txq->eth_dev, txq->queue_id); 734 if (res < 0) 735 octeontx_log_err("failed stop tx_queue(%d)\n", 736 txq->queue_id); 737 738 rte_free(txq); 739 } 740 } 741 742 static int 743 octeontx_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx, 744 uint16_t nb_desc, unsigned int socket_id, 745 const struct rte_eth_txconf *tx_conf) 746 { 747 struct octeontx_nic *nic = octeontx_pmd_priv(dev); 748 struct octeontx_txq *txq = NULL; 749 uint16_t dq_num; 750 int res = 0; 751 752 RTE_SET_USED(nb_desc); 753 RTE_SET_USED(socket_id); 754 RTE_SET_USED(tx_conf); 755 756 dq_num = (nic->port_id * PKO_VF_NUM_DQ) + qidx; 757 758 /* Socket id check */ 759 if (socket_id != (unsigned int)SOCKET_ID_ANY && 760 socket_id != (unsigned int)nic->node) 761 PMD_TX_LOG(INFO, "socket_id expected %d, configured %d", 762 socket_id, nic->node); 763 764 /* Free memory prior to re-allocation if needed. */ 765 if (dev->data->tx_queues[qidx] != NULL) { 766 PMD_TX_LOG(DEBUG, "freeing memory prior to re-allocation %d", 767 qidx); 768 octeontx_dev_tx_queue_release(dev->data->tx_queues[qidx]); 769 dev->data->tx_queues[qidx] = NULL; 770 } 771 772 /* Allocating tx queue data structure */ 773 txq = rte_zmalloc_socket("ethdev TX queue", sizeof(struct octeontx_txq), 774 RTE_CACHE_LINE_SIZE, nic->node); 775 if (txq == NULL) { 776 octeontx_log_err("failed to allocate txq=%d", qidx); 777 res = -ENOMEM; 778 goto err; 779 } 780 781 txq->eth_dev = dev; 782 txq->queue_id = dq_num; 783 dev->data->tx_queues[qidx] = txq; 784 dev->data->tx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STOPPED; 785 786 res = octeontx_pko_channel_query_dqs(nic->base_ochan, 787 &txq->dq, 788 sizeof(octeontx_dq_t), 789 txq->queue_id, 790 octeontx_dq_info_getter); 791 if (res < 0) { 792 res = -EFAULT; 793 goto err; 794 } 795 796 PMD_TX_LOG(DEBUG, "[%d]:[%d] txq=%p nb_desc=%d lmtline=%p ioreg_va=%p fc_status_va=%p", 797 qidx, txq->queue_id, txq, nb_desc, txq->dq.lmtline_va, 798 txq->dq.ioreg_va, 799 txq->dq.fc_status_va); 800 801 return res; 802 803 err: 804 if (txq) 805 rte_free(txq); 806 807 return res; 808 } 809 810 static int 811 octeontx_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx, 812 uint16_t nb_desc, unsigned int socket_id, 813 const struct rte_eth_rxconf *rx_conf, 814 struct rte_mempool *mb_pool) 815 { 816 struct octeontx_nic *nic = octeontx_pmd_priv(dev); 817 struct rte_mempool_ops *mp_ops = NULL; 818 struct octeontx_rxq *rxq = NULL; 819 pki_pktbuf_cfg_t pktbuf_conf; 820 pki_hash_cfg_t pki_hash; 821 pki_qos_cfg_t pki_qos; 822 uintptr_t pool; 823 int ret, port; 824 uint8_t gaura; 825 unsigned int ev_queues = (nic->ev_queues * nic->port_id) + qidx; 826 unsigned int ev_ports = (nic->ev_ports * nic->port_id) + qidx; 827 828 RTE_SET_USED(nb_desc); 829 830 memset(&pktbuf_conf, 0, sizeof(pktbuf_conf)); 831 memset(&pki_hash, 0, sizeof(pki_hash)); 832 memset(&pki_qos, 0, sizeof(pki_qos)); 833 834 mp_ops = rte_mempool_get_ops(mb_pool->ops_index); 835 if (strcmp(mp_ops->name, "octeontx_fpavf")) { 836 octeontx_log_err("failed to find octeontx_fpavf mempool"); 837 return -ENOTSUP; 838 } 839 840 /* Handle forbidden configurations */ 841 if (nic->pki.classifier_enable) { 842 octeontx_log_err("cannot setup queue %d. " 843 "Classifier option unsupported", qidx); 844 return -EINVAL; 845 } 846 847 port = nic->port_id; 848 849 /* Rx deferred start is not supported */ 850 if (rx_conf->rx_deferred_start) { 851 octeontx_log_err("rx deferred start not supported"); 852 return -EINVAL; 853 } 854 855 /* Verify queue index */ 856 if (qidx >= dev->data->nb_rx_queues) { 857 octeontx_log_err("QID %d not supporteded (0 - %d available)\n", 858 qidx, (dev->data->nb_rx_queues - 1)); 859 return -ENOTSUP; 860 } 861 862 /* Socket id check */ 863 if (socket_id != (unsigned int)SOCKET_ID_ANY && 864 socket_id != (unsigned int)nic->node) 865 PMD_RX_LOG(INFO, "socket_id expected %d, configured %d", 866 socket_id, nic->node); 867 868 /* Allocating rx queue data structure */ 869 rxq = rte_zmalloc_socket("ethdev RX queue", sizeof(struct octeontx_rxq), 870 RTE_CACHE_LINE_SIZE, nic->node); 871 if (rxq == NULL) { 872 octeontx_log_err("failed to allocate rxq=%d", qidx); 873 return -ENOMEM; 874 } 875 876 if (!nic->pki.initialized) { 877 pktbuf_conf.port_type = 0; 878 pki_hash.port_type = 0; 879 pki_qos.port_type = 0; 880 881 pktbuf_conf.mmask.f_wqe_skip = 1; 882 pktbuf_conf.mmask.f_first_skip = 1; 883 pktbuf_conf.mmask.f_later_skip = 1; 884 pktbuf_conf.mmask.f_mbuff_size = 1; 885 pktbuf_conf.mmask.f_cache_mode = 1; 886 887 pktbuf_conf.wqe_skip = OCTTX_PACKET_WQE_SKIP; 888 pktbuf_conf.first_skip = OCTTX_PACKET_FIRST_SKIP; 889 pktbuf_conf.later_skip = OCTTX_PACKET_LATER_SKIP; 890 pktbuf_conf.mbuff_size = (mb_pool->elt_size - 891 RTE_PKTMBUF_HEADROOM - 892 sizeof(struct rte_mbuf)); 893 894 pktbuf_conf.cache_mode = PKI_OPC_MODE_STF2_STT; 895 896 ret = octeontx_pki_port_pktbuf_config(port, &pktbuf_conf); 897 if (ret != 0) { 898 octeontx_log_err("fail to configure pktbuf for port %d", 899 port); 900 rte_free(rxq); 901 return ret; 902 } 903 PMD_RX_LOG(DEBUG, "Port %d Rx pktbuf configured:\n" 904 "\tmbuf_size:\t0x%0x\n" 905 "\twqe_skip:\t0x%0x\n" 906 "\tfirst_skip:\t0x%0x\n" 907 "\tlater_skip:\t0x%0x\n" 908 "\tcache_mode:\t%s\n", 909 port, 910 pktbuf_conf.mbuff_size, 911 pktbuf_conf.wqe_skip, 912 pktbuf_conf.first_skip, 913 pktbuf_conf.later_skip, 914 (pktbuf_conf.cache_mode == 915 PKI_OPC_MODE_STT) ? 916 "STT" : 917 (pktbuf_conf.cache_mode == 918 PKI_OPC_MODE_STF) ? 919 "STF" : 920 (pktbuf_conf.cache_mode == 921 PKI_OPC_MODE_STF1_STT) ? 922 "STF1_STT" : "STF2_STT"); 923 924 if (nic->pki.hash_enable) { 925 pki_hash.tag_dlc = 1; 926 pki_hash.tag_slc = 1; 927 pki_hash.tag_dlf = 1; 928 pki_hash.tag_slf = 1; 929 octeontx_pki_port_hash_config(port, &pki_hash); 930 } 931 932 pool = (uintptr_t)mb_pool->pool_id; 933 934 /* Get the gpool Id */ 935 gaura = octeontx_fpa_bufpool_gpool(pool); 936 937 pki_qos.qpg_qos = PKI_QPG_QOS_NONE; 938 pki_qos.num_entry = 1; 939 pki_qos.drop_policy = 0; 940 pki_qos.tag_type = 2L; 941 pki_qos.qos_entry[0].port_add = 0; 942 pki_qos.qos_entry[0].gaura = gaura; 943 pki_qos.qos_entry[0].ggrp_ok = ev_queues; 944 pki_qos.qos_entry[0].ggrp_bad = ev_queues; 945 pki_qos.qos_entry[0].grptag_bad = 0; 946 pki_qos.qos_entry[0].grptag_ok = 0; 947 948 ret = octeontx_pki_port_create_qos(port, &pki_qos); 949 if (ret < 0) { 950 octeontx_log_err("failed to create QOS port=%d, q=%d", 951 port, qidx); 952 rte_free(rxq); 953 return ret; 954 } 955 nic->pki.initialized = true; 956 } 957 958 rxq->port_id = nic->port_id; 959 rxq->eth_dev = dev; 960 rxq->queue_id = qidx; 961 rxq->evdev = nic->evdev; 962 rxq->ev_queues = ev_queues; 963 rxq->ev_ports = ev_ports; 964 965 dev->data->rx_queues[qidx] = rxq; 966 dev->data->rx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STOPPED; 967 return 0; 968 } 969 970 static void 971 octeontx_dev_rx_queue_release(void *rxq) 972 { 973 rte_free(rxq); 974 } 975 976 static const uint32_t * 977 octeontx_dev_supported_ptypes_get(struct rte_eth_dev *dev) 978 { 979 static const uint32_t ptypes[] = { 980 RTE_PTYPE_L3_IPV4, 981 RTE_PTYPE_L3_IPV4_EXT, 982 RTE_PTYPE_L3_IPV6, 983 RTE_PTYPE_L3_IPV6_EXT, 984 RTE_PTYPE_L4_TCP, 985 RTE_PTYPE_L4_UDP, 986 RTE_PTYPE_L4_FRAG, 987 RTE_PTYPE_UNKNOWN 988 }; 989 990 if (dev->rx_pkt_burst == octeontx_recv_pkts) 991 return ptypes; 992 993 return NULL; 994 } 995 996 /* Initialize and register driver with DPDK Application */ 997 static const struct eth_dev_ops octeontx_dev_ops = { 998 .dev_configure = octeontx_dev_configure, 999 .dev_infos_get = octeontx_dev_info, 1000 .dev_close = octeontx_dev_close, 1001 .dev_start = octeontx_dev_start, 1002 .dev_stop = octeontx_dev_stop, 1003 .promiscuous_enable = octeontx_dev_promisc_enable, 1004 .promiscuous_disable = octeontx_dev_promisc_disable, 1005 .link_update = octeontx_dev_link_update, 1006 .stats_get = octeontx_dev_stats_get, 1007 .stats_reset = octeontx_dev_stats_reset, 1008 .mac_addr_set = octeontx_dev_default_mac_addr_set, 1009 .tx_queue_start = octeontx_dev_tx_queue_start, 1010 .tx_queue_stop = octeontx_dev_tx_queue_stop, 1011 .tx_queue_setup = octeontx_dev_tx_queue_setup, 1012 .tx_queue_release = octeontx_dev_tx_queue_release, 1013 .rx_queue_setup = octeontx_dev_rx_queue_setup, 1014 .rx_queue_release = octeontx_dev_rx_queue_release, 1015 .dev_supported_ptypes_get = octeontx_dev_supported_ptypes_get, 1016 }; 1017 1018 /* Create Ethdev interface per BGX LMAC ports */ 1019 static int 1020 octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev, 1021 int socket_id) 1022 { 1023 int res; 1024 char octtx_name[OCTEONTX_MAX_NAME_LEN]; 1025 struct octeontx_nic *nic = NULL; 1026 struct rte_eth_dev *eth_dev = NULL; 1027 struct rte_eth_dev_data *data = NULL; 1028 const char *name = rte_vdev_device_name(dev); 1029 1030 PMD_INIT_FUNC_TRACE(); 1031 1032 sprintf(octtx_name, "%s_%d", name, port); 1033 if (rte_eal_process_type() != RTE_PROC_PRIMARY) { 1034 eth_dev = rte_eth_dev_attach_secondary(octtx_name); 1035 if (eth_dev == NULL) 1036 return -ENODEV; 1037 1038 eth_dev->tx_pkt_burst = octeontx_xmit_pkts; 1039 eth_dev->rx_pkt_burst = octeontx_recv_pkts; 1040 return 0; 1041 } 1042 1043 data = rte_zmalloc_socket(octtx_name, sizeof(*data), 0, socket_id); 1044 if (data == NULL) { 1045 octeontx_log_err("failed to allocate devdata"); 1046 res = -ENOMEM; 1047 goto err; 1048 } 1049 1050 nic = rte_zmalloc_socket(octtx_name, sizeof(*nic), 0, socket_id); 1051 if (nic == NULL) { 1052 octeontx_log_err("failed to allocate nic structure"); 1053 res = -ENOMEM; 1054 goto err; 1055 } 1056 1057 nic->port_id = port; 1058 nic->evdev = evdev; 1059 1060 res = octeontx_port_open(nic); 1061 if (res < 0) 1062 goto err; 1063 1064 /* Rx side port configuration */ 1065 res = octeontx_pki_port_open(port); 1066 if (res != 0) { 1067 octeontx_log_err("failed to open PKI port %d", port); 1068 res = -ENODEV; 1069 goto err; 1070 } 1071 1072 /* Reserve an ethdev entry */ 1073 eth_dev = rte_eth_dev_allocate(octtx_name); 1074 if (eth_dev == NULL) { 1075 octeontx_log_err("failed to allocate rte_eth_dev"); 1076 res = -ENOMEM; 1077 goto err; 1078 } 1079 1080 eth_dev->device = &dev->device; 1081 eth_dev->intr_handle = NULL; 1082 eth_dev->data->kdrv = RTE_KDRV_NONE; 1083 eth_dev->data->numa_node = dev->device.numa_node; 1084 1085 rte_memcpy(data, (eth_dev)->data, sizeof(*data)); 1086 data->dev_private = nic; 1087 1088 data->port_id = eth_dev->data->port_id; 1089 snprintf(data->name, sizeof(data->name), "%s", eth_dev->data->name); 1090 1091 nic->ev_queues = 1; 1092 nic->ev_ports = 1; 1093 1094 data->dev_link.link_status = ETH_LINK_DOWN; 1095 data->dev_started = 0; 1096 data->promiscuous = 0; 1097 data->all_multicast = 0; 1098 data->scattered_rx = 0; 1099 1100 data->mac_addrs = rte_zmalloc_socket(octtx_name, ETHER_ADDR_LEN, 0, 1101 socket_id); 1102 if (data->mac_addrs == NULL) { 1103 octeontx_log_err("failed to allocate memory for mac_addrs"); 1104 res = -ENOMEM; 1105 goto err; 1106 } 1107 1108 eth_dev->data = data; 1109 eth_dev->dev_ops = &octeontx_dev_ops; 1110 1111 /* Finally save ethdev pointer to the NIC structure */ 1112 nic->dev = eth_dev; 1113 1114 if (nic->port_id != data->port_id) { 1115 octeontx_log_err("eth_dev->port_id (%d) is diff to orig (%d)", 1116 data->port_id, nic->port_id); 1117 res = -EINVAL; 1118 goto err; 1119 } 1120 1121 /* Update port_id mac to eth_dev */ 1122 memcpy(data->mac_addrs, nic->mac_addr, ETHER_ADDR_LEN); 1123 1124 PMD_INIT_LOG(DEBUG, "ethdev info: "); 1125 PMD_INIT_LOG(DEBUG, "port %d, port_ena %d ochan %d num_ochan %d tx_q %d", 1126 nic->port_id, nic->port_ena, 1127 nic->base_ochan, nic->num_ochans, 1128 nic->num_tx_queues); 1129 PMD_INIT_LOG(DEBUG, "speed %d mtu %d", nic->speed, nic->mtu); 1130 1131 return data->port_id; 1132 1133 err: 1134 if (port) 1135 octeontx_port_close(nic); 1136 1137 if (eth_dev != NULL) { 1138 rte_free(eth_dev->data->mac_addrs); 1139 rte_free(data); 1140 rte_free(nic); 1141 rte_eth_dev_release_port(eth_dev); 1142 } 1143 1144 return res; 1145 } 1146 1147 /* Un initialize octeontx device */ 1148 static int 1149 octeontx_remove(struct rte_vdev_device *dev) 1150 { 1151 char octtx_name[OCTEONTX_MAX_NAME_LEN]; 1152 struct rte_eth_dev *eth_dev = NULL; 1153 struct octeontx_nic *nic = NULL; 1154 int i; 1155 1156 if (dev == NULL) 1157 return -EINVAL; 1158 1159 for (i = 0; i < OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT; i++) { 1160 sprintf(octtx_name, "eth_octeontx_%d", i); 1161 1162 /* reserve an ethdev entry */ 1163 eth_dev = rte_eth_dev_allocated(octtx_name); 1164 if (eth_dev == NULL) 1165 return -ENODEV; 1166 1167 nic = octeontx_pmd_priv(eth_dev); 1168 rte_event_dev_stop(nic->evdev); 1169 PMD_INIT_LOG(INFO, "Closing octeontx device %s", octtx_name); 1170 1171 rte_free(eth_dev->data->mac_addrs); 1172 rte_free(eth_dev->data->dev_private); 1173 rte_free(eth_dev->data); 1174 rte_eth_dev_release_port(eth_dev); 1175 rte_event_dev_close(nic->evdev); 1176 } 1177 1178 /* Free FC resource */ 1179 octeontx_pko_fc_free(); 1180 1181 return 0; 1182 } 1183 1184 /* Initialize octeontx device */ 1185 static int 1186 octeontx_probe(struct rte_vdev_device *dev) 1187 { 1188 const char *dev_name; 1189 static int probe_once; 1190 uint8_t socket_id, qlist; 1191 int tx_vfcnt, port_id, evdev, qnum, pnum, res, i; 1192 struct rte_event_dev_config dev_conf; 1193 const char *eventdev_name = "event_octeontx"; 1194 struct rte_event_dev_info info; 1195 1196 struct octeontx_vdev_init_params init_params = { 1197 OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT 1198 }; 1199 1200 dev_name = rte_vdev_device_name(dev); 1201 res = octeontx_parse_vdev_init_params(&init_params, dev); 1202 if (res < 0) 1203 return -EINVAL; 1204 1205 if (init_params.nr_port > OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT) { 1206 octeontx_log_err("nr_port (%d) > max (%d)", init_params.nr_port, 1207 OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT); 1208 return -ENOTSUP; 1209 } 1210 1211 PMD_INIT_LOG(DEBUG, "initializing %s pmd", dev_name); 1212 1213 socket_id = rte_socket_id(); 1214 1215 tx_vfcnt = octeontx_pko_vf_count(); 1216 1217 if (tx_vfcnt < init_params.nr_port) { 1218 octeontx_log_err("not enough PKO (%d) for port number (%d)", 1219 tx_vfcnt, init_params.nr_port); 1220 return -EINVAL; 1221 } 1222 evdev = rte_event_dev_get_dev_id(eventdev_name); 1223 if (evdev < 0) { 1224 octeontx_log_err("eventdev %s not found", eventdev_name); 1225 return -ENODEV; 1226 } 1227 1228 res = rte_event_dev_info_get(evdev, &info); 1229 if (res < 0) { 1230 octeontx_log_err("failed to eventdev info %d", res); 1231 return -EINVAL; 1232 } 1233 1234 PMD_INIT_LOG(DEBUG, "max_queue %d max_port %d", 1235 info.max_event_queues, info.max_event_ports); 1236 1237 if (octeontx_pko_init_fc(tx_vfcnt)) 1238 return -ENOMEM; 1239 1240 devconf_set_default_sane_values(&dev_conf, &info); 1241 res = rte_event_dev_configure(evdev, &dev_conf); 1242 if (res < 0) 1243 goto parse_error; 1244 1245 rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_PORT_COUNT, 1246 (uint32_t *)&pnum); 1247 rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_QUEUE_COUNT, 1248 (uint32_t *)&qnum); 1249 if (pnum < qnum) { 1250 octeontx_log_err("too few event ports (%d) for event_q(%d)", 1251 pnum, qnum); 1252 res = -EINVAL; 1253 goto parse_error; 1254 } 1255 if (pnum > qnum) { 1256 /* 1257 * We don't poll on event ports 1258 * that do not have any queues assigned. 1259 */ 1260 pnum = qnum; 1261 PMD_INIT_LOG(INFO, 1262 "reducing number of active event ports to %d", pnum); 1263 } 1264 for (i = 0; i < qnum; i++) { 1265 res = rte_event_queue_setup(evdev, i, NULL); 1266 if (res < 0) { 1267 octeontx_log_err("failed to setup event_q(%d): res %d", 1268 i, res); 1269 goto parse_error; 1270 } 1271 } 1272 1273 for (i = 0; i < pnum; i++) { 1274 res = rte_event_port_setup(evdev, i, NULL); 1275 if (res < 0) { 1276 res = -ENODEV; 1277 octeontx_log_err("failed to setup ev port(%d) res=%d", 1278 i, res); 1279 goto parse_error; 1280 } 1281 /* Link one queue to one event port */ 1282 qlist = i; 1283 res = rte_event_port_link(evdev, i, &qlist, NULL, 1); 1284 if (res < 0) { 1285 res = -ENODEV; 1286 octeontx_log_err("failed to link port (%d): res=%d", 1287 i, res); 1288 goto parse_error; 1289 } 1290 } 1291 1292 /* Create ethdev interface */ 1293 for (i = 0; i < init_params.nr_port; i++) { 1294 port_id = octeontx_create(dev, i, evdev, socket_id); 1295 if (port_id < 0) { 1296 octeontx_log_err("failed to create device %s", 1297 dev_name); 1298 res = -ENODEV; 1299 goto parse_error; 1300 } 1301 1302 PMD_INIT_LOG(INFO, "created ethdev %s for port %d", dev_name, 1303 port_id); 1304 } 1305 1306 if (probe_once) { 1307 octeontx_log_err("interface %s not supported", dev_name); 1308 octeontx_remove(dev); 1309 res = -ENOTSUP; 1310 goto parse_error; 1311 } 1312 probe_once = 1; 1313 1314 return 0; 1315 1316 parse_error: 1317 octeontx_pko_fc_free(); 1318 return res; 1319 } 1320 1321 static struct rte_vdev_driver octeontx_pmd_drv = { 1322 .probe = octeontx_probe, 1323 .remove = octeontx_remove, 1324 }; 1325 1326 RTE_PMD_REGISTER_VDEV(OCTEONTX_PMD, octeontx_pmd_drv); 1327 RTE_PMD_REGISTER_ALIAS(OCTEONTX_PMD, eth_octeontx); 1328 RTE_PMD_REGISTER_PARAM_STRING(OCTEONTX_PMD, "nr_port=<int> "); 1329