1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2015 6WIND S.A. 3 * Copyright 2015 Mellanox Technologies, Ltd 4 */ 5 6 #include <stddef.h> 7 #include <unistd.h> 8 #include <string.h> 9 #include <stdint.h> 10 #include <stdlib.h> 11 #include <errno.h> 12 13 #include <ethdev_driver.h> 14 #include <bus_pci_driver.h> 15 #include <rte_mbuf.h> 16 #include <rte_common.h> 17 #include <rte_interrupts.h> 18 #include <rte_malloc.h> 19 #include <rte_string_fns.h> 20 #include <rte_rwlock.h> 21 #include <rte_cycles.h> 22 23 #include <mlx5_malloc.h> 24 25 #include "mlx5_rxtx.h" 26 #include "mlx5_rx.h" 27 #include "mlx5_tx.h" 28 #include "mlx5_autoconf.h" 29 #include "mlx5_devx.h" 30 #include "rte_pmd_mlx5.h" 31 32 /** 33 * Get the interface index from device name. 34 * 35 * @param[in] dev 36 * Pointer to Ethernet device. 37 * 38 * @return 39 * Nonzero interface index on success, zero otherwise and rte_errno is set. 40 */ 41 unsigned int 42 mlx5_ifindex(const struct rte_eth_dev *dev) 43 { 44 struct mlx5_priv *priv = dev->data->dev_private; 45 unsigned int ifindex; 46 47 MLX5_ASSERT(priv); 48 MLX5_ASSERT(priv->if_index); 49 if (priv->master && priv->sh->bond.ifindex > 0) 50 ifindex = priv->sh->bond.ifindex; 51 else 52 ifindex = priv->if_index; 53 if (!ifindex) 54 rte_errno = ENXIO; 55 return ifindex; 56 } 57 58 /** 59 * DPDK callback for Ethernet device configuration. 60 * 61 * @param dev 62 * Pointer to Ethernet device structure. 63 * 64 * @return 65 * 0 on success, a negative errno value otherwise and rte_errno is set. 66 */ 67 int 68 mlx5_dev_configure(struct rte_eth_dev *dev) 69 { 70 struct mlx5_priv *priv = dev->data->dev_private; 71 unsigned int rxqs_n = dev->data->nb_rx_queues; 72 unsigned int txqs_n = dev->data->nb_tx_queues; 73 const uint8_t use_app_rss_key = 74 !!dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key; 75 int ret = 0; 76 77 if (use_app_rss_key && 78 (dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len != 79 MLX5_RSS_HASH_KEY_LEN)) { 80 DRV_LOG(ERR, "port %u RSS key len must be %s Bytes long", 81 dev->data->port_id, RTE_STR(MLX5_RSS_HASH_KEY_LEN)); 82 rte_errno = EINVAL; 83 return -rte_errno; 84 } 85 priv->rss_conf.rss_key = mlx5_realloc(priv->rss_conf.rss_key, 86 MLX5_MEM_RTE, 87 MLX5_RSS_HASH_KEY_LEN, 0, 88 SOCKET_ID_ANY); 89 if (!priv->rss_conf.rss_key) { 90 DRV_LOG(ERR, "port %u cannot allocate RSS hash key memory (%u)", 91 dev->data->port_id, rxqs_n); 92 rte_errno = ENOMEM; 93 return -rte_errno; 94 } 95 96 if ((dev->data->dev_conf.txmode.offloads & 97 RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP) && 98 rte_mbuf_dyn_tx_timestamp_register(NULL, NULL) != 0) { 99 DRV_LOG(ERR, "port %u cannot register Tx timestamp field/flag", 100 dev->data->port_id); 101 return -rte_errno; 102 } 103 memcpy(priv->rss_conf.rss_key, 104 use_app_rss_key ? 105 dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key : 106 rss_hash_default_key, 107 MLX5_RSS_HASH_KEY_LEN); 108 priv->rss_conf.rss_key_len = MLX5_RSS_HASH_KEY_LEN; 109 priv->rss_conf.rss_hf = dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf; 110 priv->rxq_privs = mlx5_realloc(priv->rxq_privs, 111 MLX5_MEM_RTE | MLX5_MEM_ZERO, 112 sizeof(void *) * rxqs_n, 0, 113 SOCKET_ID_ANY); 114 if (rxqs_n && priv->rxq_privs == NULL) { 115 DRV_LOG(ERR, "port %u cannot allocate rxq private data", 116 dev->data->port_id); 117 rte_errno = ENOMEM; 118 return -rte_errno; 119 } 120 priv->txqs = (void *)dev->data->tx_queues; 121 if (txqs_n != priv->txqs_n) { 122 DRV_LOG(INFO, "port %u Tx queues number update: %u -> %u", 123 dev->data->port_id, priv->txqs_n, txqs_n); 124 priv->txqs_n = txqs_n; 125 } 126 if (priv->ext_txqs && txqs_n >= MLX5_EXTERNAL_TX_QUEUE_ID_MIN) { 127 DRV_LOG(ERR, "port %u cannot handle this many Tx queues (%u), " 128 "the maximal number of internal Tx queues is %u", 129 dev->data->port_id, txqs_n, 130 MLX5_EXTERNAL_TX_QUEUE_ID_MIN - 1); 131 rte_errno = EINVAL; 132 return -rte_errno; 133 } 134 if (rxqs_n > priv->sh->dev_cap.ind_table_max_size) { 135 DRV_LOG(ERR, "port %u cannot handle this many Rx queues (%u)", 136 dev->data->port_id, rxqs_n); 137 rte_errno = EINVAL; 138 return -rte_errno; 139 } 140 if (priv->ext_rxqs && rxqs_n >= RTE_PMD_MLX5_EXTERNAL_RX_QUEUE_ID_MIN) { 141 DRV_LOG(ERR, "port %u cannot handle this many Rx queues (%u), " 142 "the maximal number of internal Rx queues is %u", 143 dev->data->port_id, rxqs_n, 144 RTE_PMD_MLX5_EXTERNAL_RX_QUEUE_ID_MIN - 1); 145 rte_errno = EINVAL; 146 return -rte_errno; 147 } 148 if (rxqs_n != priv->rxqs_n) { 149 DRV_LOG(INFO, "port %u Rx queues number update: %u -> %u", 150 dev->data->port_id, priv->rxqs_n, rxqs_n); 151 priv->rxqs_n = rxqs_n; 152 } 153 priv->skip_default_rss_reta = 0; 154 ret = mlx5_proc_priv_init(dev); 155 if (ret) 156 return ret; 157 return 0; 158 } 159 160 /** 161 * Configure default RSS reta. 162 * 163 * @param dev 164 * Pointer to Ethernet device structure. 165 * 166 * @return 167 * 0 on success, a negative errno value otherwise and rte_errno is set. 168 */ 169 int 170 mlx5_dev_configure_rss_reta(struct rte_eth_dev *dev) 171 { 172 struct mlx5_priv *priv = dev->data->dev_private; 173 unsigned int rxqs_n = dev->data->nb_rx_queues; 174 unsigned int i; 175 unsigned int j; 176 unsigned int reta_idx_n; 177 int ret = 0; 178 unsigned int *rss_queue_arr = NULL; 179 unsigned int rss_queue_n = 0; 180 181 if (priv->skip_default_rss_reta) 182 return ret; 183 rss_queue_arr = mlx5_malloc(0, rxqs_n * sizeof(unsigned int), 0, 184 SOCKET_ID_ANY); 185 if (!rss_queue_arr) { 186 DRV_LOG(ERR, "port %u cannot allocate RSS queue list (%u)", 187 dev->data->port_id, rxqs_n); 188 rte_errno = ENOMEM; 189 return -rte_errno; 190 } 191 for (i = 0, j = 0; i < rxqs_n; i++) { 192 struct mlx5_rxq_ctrl *rxq_ctrl = mlx5_rxq_ctrl_get(dev, i); 193 194 if (rxq_ctrl && !rxq_ctrl->is_hairpin) 195 rss_queue_arr[j++] = i; 196 } 197 rss_queue_n = j; 198 if (rss_queue_n > priv->sh->dev_cap.ind_table_max_size) { 199 DRV_LOG(ERR, "port %u cannot handle this many Rx queues (%u)", 200 dev->data->port_id, rss_queue_n); 201 rte_errno = EINVAL; 202 mlx5_free(rss_queue_arr); 203 return -rte_errno; 204 } 205 DRV_LOG(INFO, "port %u Rx queues number update: %u -> %u", 206 dev->data->port_id, priv->rxqs_n, rxqs_n); 207 priv->rxqs_n = rxqs_n; 208 /* 209 * If the requested number of RX queues is not a power of two, 210 * use the maximum indirection table size for better balancing. 211 * The result is always rounded to the next power of two. 212 */ 213 reta_idx_n = (1 << log2above((rss_queue_n & (rss_queue_n - 1)) ? 214 priv->sh->dev_cap.ind_table_max_size : 215 rss_queue_n)); 216 ret = mlx5_rss_reta_index_resize(dev, reta_idx_n); 217 if (ret) { 218 mlx5_free(rss_queue_arr); 219 return ret; 220 } 221 /* 222 * When the number of RX queues is not a power of two, 223 * the remaining table entries are padded with reused WQs 224 * and hashes are not spread uniformly. 225 */ 226 for (i = 0, j = 0; (i != reta_idx_n); ++i) { 227 (*priv->reta_idx)[i] = rss_queue_arr[j]; 228 if (++j == rss_queue_n) 229 j = 0; 230 } 231 mlx5_free(rss_queue_arr); 232 return ret; 233 } 234 235 /** 236 * Sets default tuning parameters. 237 * 238 * @param dev 239 * Pointer to Ethernet device. 240 * @param[out] info 241 * Info structure output buffer. 242 */ 243 static void 244 mlx5_set_default_params(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) 245 { 246 struct mlx5_priv *priv = dev->data->dev_private; 247 248 /* Minimum CPU utilization. */ 249 info->default_rxportconf.ring_size = 256; 250 info->default_txportconf.ring_size = 256; 251 info->default_rxportconf.burst_size = MLX5_RX_DEFAULT_BURST; 252 info->default_txportconf.burst_size = MLX5_TX_DEFAULT_BURST; 253 if (priv->link_speed_capa >> rte_bsf32(RTE_ETH_LINK_SPEED_100G)) { 254 /* if supports at least 100G */ 255 info->default_rxportconf.nb_queues = 16; 256 info->default_txportconf.nb_queues = 16; 257 if (dev->data->nb_rx_queues > 2 || 258 dev->data->nb_tx_queues > 2) { 259 /* Max Throughput. */ 260 info->default_rxportconf.ring_size = 2048; 261 info->default_txportconf.ring_size = 2048; 262 } 263 } else { 264 info->default_rxportconf.nb_queues = 8; 265 info->default_txportconf.nb_queues = 8; 266 if (dev->data->nb_rx_queues > 2 || 267 dev->data->nb_tx_queues > 2) { 268 /* Max Throughput. */ 269 info->default_rxportconf.ring_size = 4096; 270 info->default_txportconf.ring_size = 4096; 271 } 272 } 273 } 274 275 /** 276 * Sets tx mbuf limiting parameters. 277 * 278 * @param dev 279 * Pointer to Ethernet device. 280 * @param[out] info 281 * Info structure output buffer. 282 */ 283 static void 284 mlx5_set_txlimit_params(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) 285 { 286 struct mlx5_priv *priv = dev->data->dev_private; 287 struct mlx5_port_config *config = &priv->config; 288 unsigned int inlen; 289 uint16_t nb_max; 290 291 inlen = (config->txq_inline_max == MLX5_ARG_UNSET) ? 292 MLX5_SEND_DEF_INLINE_LEN : 293 (unsigned int)config->txq_inline_max; 294 MLX5_ASSERT(config->txq_inline_min >= 0); 295 inlen = RTE_MAX(inlen, (unsigned int)config->txq_inline_min); 296 inlen = RTE_MIN(inlen, MLX5_WQE_SIZE_MAX + 297 MLX5_ESEG_MIN_INLINE_SIZE - 298 MLX5_WQE_CSEG_SIZE - 299 MLX5_WQE_ESEG_SIZE - 300 MLX5_WQE_DSEG_SIZE * 2); 301 nb_max = (MLX5_WQE_SIZE_MAX + 302 MLX5_ESEG_MIN_INLINE_SIZE - 303 MLX5_WQE_CSEG_SIZE - 304 MLX5_WQE_ESEG_SIZE - 305 MLX5_WQE_DSEG_SIZE - 306 inlen) / MLX5_WSEG_SIZE; 307 info->tx_desc_lim.nb_seg_max = nb_max; 308 info->tx_desc_lim.nb_mtu_seg_max = nb_max; 309 } 310 311 /** 312 * DPDK callback to get information about the device. 313 * 314 * @param dev 315 * Pointer to Ethernet device structure. 316 * @param[out] info 317 * Info structure output buffer. 318 */ 319 int 320 mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) 321 { 322 struct mlx5_priv *priv = dev->data->dev_private; 323 unsigned int max; 324 325 /* FIXME: we should ask the device for these values. */ 326 info->min_rx_bufsize = 32; 327 info->max_rx_pktlen = 65536; 328 info->max_lro_pkt_size = MLX5_MAX_LRO_SIZE; 329 /* 330 * Since we need one CQ per QP, the limit is the minimum number 331 * between the two values. 332 */ 333 max = RTE_MIN(priv->sh->dev_cap.max_cq, priv->sh->dev_cap.max_qp); 334 /* max_rx_queues is uint16_t. */ 335 max = RTE_MIN(max, (unsigned int)UINT16_MAX); 336 info->max_rx_queues = max; 337 info->max_tx_queues = max; 338 info->max_mac_addrs = MLX5_MAX_UC_MAC_ADDRESSES; 339 info->rx_queue_offload_capa = mlx5_get_rx_queue_offloads(dev); 340 info->rx_seg_capa.max_nseg = MLX5_MAX_RXQ_NSEG; 341 info->rx_seg_capa.multi_pools = !priv->config.mprq.enabled; 342 info->rx_seg_capa.offset_allowed = !priv->config.mprq.enabled; 343 info->rx_seg_capa.offset_align_log2 = 0; 344 info->rx_offload_capa = (mlx5_get_rx_port_offloads() | 345 info->rx_queue_offload_capa); 346 info->tx_offload_capa = mlx5_get_tx_port_offloads(dev); 347 info->dev_capa = RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP; 348 info->if_index = mlx5_ifindex(dev); 349 info->reta_size = priv->reta_idx_n ? 350 priv->reta_idx_n : priv->sh->dev_cap.ind_table_max_size; 351 info->hash_key_size = MLX5_RSS_HASH_KEY_LEN; 352 info->speed_capa = priv->link_speed_capa; 353 info->flow_type_rss_offloads = ~MLX5_RSS_HF_MASK; 354 mlx5_set_default_params(dev, info); 355 mlx5_set_txlimit_params(dev, info); 356 if (priv->sh->cdev->config.hca_attr.mem_rq_rmp && 357 priv->obj_ops.rxq_obj_new == devx_obj_ops.rxq_obj_new) 358 info->dev_capa |= RTE_ETH_DEV_CAPA_RXQ_SHARE; 359 info->switch_info.name = dev->data->name; 360 info->switch_info.domain_id = priv->domain_id; 361 info->switch_info.port_id = priv->representor_id; 362 info->switch_info.rx_domain = 0; /* No sub Rx domains. */ 363 if (priv->representor) { 364 uint16_t port_id; 365 366 MLX5_ETH_FOREACH_DEV(port_id, dev->device) { 367 struct mlx5_priv *opriv = 368 rte_eth_devices[port_id].data->dev_private; 369 370 if (!opriv || 371 opriv->representor || 372 opriv->sh != priv->sh || 373 opriv->domain_id != priv->domain_id) 374 continue; 375 /* 376 * Override switch name with that of the master 377 * device. 378 */ 379 info->switch_info.name = opriv->dev_data->name; 380 break; 381 } 382 } 383 return 0; 384 } 385 386 /** 387 * Calculate representor ID from port switch info. 388 * 389 * Uint16 representor ID bits definition: 390 * pf: 2 391 * type: 2 392 * vf/sf: 12 393 * 394 * @param info 395 * Port switch info. 396 * @param hpf_type 397 * Use this type if port is HPF. 398 * 399 * @return 400 * Encoded representor ID. 401 */ 402 uint16_t 403 mlx5_representor_id_encode(const struct mlx5_switch_info *info, 404 enum rte_eth_representor_type hpf_type) 405 { 406 enum rte_eth_representor_type type; 407 uint16_t repr = info->port_name; 408 int32_t pf = info->pf_num; 409 410 switch (info->name_type) { 411 case MLX5_PHYS_PORT_NAME_TYPE_UPLINK: 412 if (!info->representor) 413 return UINT16_MAX; 414 type = RTE_ETH_REPRESENTOR_PF; 415 pf = info->mpesw_owner; 416 break; 417 case MLX5_PHYS_PORT_NAME_TYPE_PFSF: 418 type = RTE_ETH_REPRESENTOR_SF; 419 break; 420 case MLX5_PHYS_PORT_NAME_TYPE_PFHPF: 421 type = hpf_type; 422 repr = UINT16_MAX; 423 break; 424 case MLX5_PHYS_PORT_NAME_TYPE_PFVF: 425 default: 426 type = RTE_ETH_REPRESENTOR_VF; 427 break; 428 } 429 return MLX5_REPRESENTOR_ID(pf, type, repr); 430 } 431 432 /** 433 * DPDK callback to get information about representor. 434 * 435 * Representor ID bits definition: 436 * vf/sf: 12 437 * type: 2 438 * pf: 2 439 * 440 * @param dev 441 * Pointer to Ethernet device structure. 442 * @param[out] info 443 * Nullable info structure output buffer. 444 * 445 * @return 446 * negative on error, or the number of representor ranges. 447 */ 448 int 449 mlx5_representor_info_get(struct rte_eth_dev *dev, 450 struct rte_eth_representor_info *info) 451 { 452 struct mlx5_priv *priv = dev->data->dev_private; 453 int n_type = 5; /* Representor types: PF, VF, HPF@VF, SF and HPF@SF. */ 454 int n_pf = 2; /* Number of PFs. */ 455 int i = 0, pf; 456 int n_entries; 457 458 if (info == NULL) 459 goto out; 460 461 n_entries = n_type * n_pf; 462 if ((uint32_t)n_entries > info->nb_ranges_alloc) 463 n_entries = info->nb_ranges_alloc; 464 465 info->controller = 0; 466 info->pf = 0; 467 if (mlx5_is_port_on_mpesw_device(priv)) { 468 info->pf = priv->mpesw_port; 469 /* PF range, both ports will show the same information. */ 470 info->ranges[i].type = RTE_ETH_REPRESENTOR_PF; 471 info->ranges[i].controller = 0; 472 info->ranges[i].pf = priv->mpesw_owner + 1; 473 info->ranges[i].vf = 0; 474 /* 475 * The representor indexes should be the values set of "priv->mpesw_port". 476 * In the real case now, only 1 PF/UPLINK representor is supported. 477 * The port index will always be the value of "owner + 1". 478 */ 479 info->ranges[i].id_base = 480 MLX5_REPRESENTOR_ID(priv->mpesw_owner, info->ranges[i].type, 481 info->ranges[i].pf); 482 info->ranges[i].id_end = 483 MLX5_REPRESENTOR_ID(priv->mpesw_owner, info->ranges[i].type, 484 info->ranges[i].pf); 485 snprintf(info->ranges[i].name, sizeof(info->ranges[i].name), 486 "pf%d", info->ranges[i].pf); 487 i++; 488 } else if (priv->pf_bond >= 0) 489 info->pf = priv->pf_bond; 490 for (pf = 0; pf < n_pf; ++pf) { 491 /* VF range. */ 492 info->ranges[i].type = RTE_ETH_REPRESENTOR_VF; 493 info->ranges[i].controller = 0; 494 info->ranges[i].pf = pf; 495 info->ranges[i].vf = 0; 496 info->ranges[i].id_base = 497 MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, 0); 498 info->ranges[i].id_end = 499 MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1); 500 snprintf(info->ranges[i].name, 501 sizeof(info->ranges[i].name), "pf%dvf", pf); 502 i++; 503 if (i == n_entries) 504 break; 505 /* HPF range of VF type. */ 506 info->ranges[i].type = RTE_ETH_REPRESENTOR_VF; 507 info->ranges[i].controller = 0; 508 info->ranges[i].pf = pf; 509 info->ranges[i].vf = UINT16_MAX; 510 info->ranges[i].id_base = 511 MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1); 512 info->ranges[i].id_end = 513 MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1); 514 snprintf(info->ranges[i].name, 515 sizeof(info->ranges[i].name), "pf%dvf", pf); 516 i++; 517 if (i == n_entries) 518 break; 519 /* SF range. */ 520 info->ranges[i].type = RTE_ETH_REPRESENTOR_SF; 521 info->ranges[i].controller = 0; 522 info->ranges[i].pf = pf; 523 info->ranges[i].vf = 0; 524 info->ranges[i].id_base = 525 MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, 0); 526 info->ranges[i].id_end = 527 MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1); 528 snprintf(info->ranges[i].name, 529 sizeof(info->ranges[i].name), "pf%dsf", pf); 530 i++; 531 if (i == n_entries) 532 break; 533 /* HPF range of SF type. */ 534 info->ranges[i].type = RTE_ETH_REPRESENTOR_SF; 535 info->ranges[i].controller = 0; 536 info->ranges[i].pf = pf; 537 info->ranges[i].vf = UINT16_MAX; 538 info->ranges[i].id_base = 539 MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1); 540 info->ranges[i].id_end = 541 MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1); 542 snprintf(info->ranges[i].name, 543 sizeof(info->ranges[i].name), "pf%dsf", pf); 544 i++; 545 if (i == n_entries) 546 break; 547 } 548 info->nb_ranges = i; 549 out: 550 return n_type * n_pf; 551 } 552 553 /** 554 * Get firmware version of a device. 555 * 556 * @param dev 557 * Ethernet device port. 558 * @param fw_ver 559 * String output allocated by caller. 560 * @param fw_size 561 * Size of the output string, including terminating null byte. 562 * 563 * @return 564 * 0 on success, or the size of the non truncated string if too big. 565 */ 566 int 567 mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size) 568 { 569 struct mlx5_priv *priv = dev->data->dev_private; 570 struct mlx5_dev_cap *attr = &priv->sh->dev_cap; 571 size_t size = strnlen(attr->fw_ver, sizeof(attr->fw_ver)) + 1; 572 573 if (fw_size < size) 574 return size; 575 if (fw_ver != NULL) 576 strlcpy(fw_ver, attr->fw_ver, fw_size); 577 return 0; 578 } 579 580 /** 581 * Get supported packet types. 582 * 583 * @param dev 584 * Pointer to Ethernet device structure. 585 * 586 * @return 587 * A pointer to the supported Packet types array. 588 */ 589 const uint32_t * 590 mlx5_dev_supported_ptypes_get(struct rte_eth_dev *dev, size_t *no_of_elements) 591 { 592 static const uint32_t ptypes[] = { 593 /* refers to rxq_cq_to_pkt_type() */ 594 RTE_PTYPE_L2_ETHER, 595 RTE_PTYPE_L3_IPV4_EXT_UNKNOWN, 596 RTE_PTYPE_L3_IPV6_EXT_UNKNOWN, 597 RTE_PTYPE_L4_NONFRAG, 598 RTE_PTYPE_L4_FRAG, 599 RTE_PTYPE_L4_TCP, 600 RTE_PTYPE_L4_UDP, 601 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN, 602 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN, 603 RTE_PTYPE_INNER_L4_NONFRAG, 604 RTE_PTYPE_INNER_L4_FRAG, 605 RTE_PTYPE_INNER_L4_TCP, 606 RTE_PTYPE_INNER_L4_UDP, 607 }; 608 609 if (dev->rx_pkt_burst == mlx5_rx_burst || 610 dev->rx_pkt_burst == mlx5_rx_burst_mprq || 611 dev->rx_pkt_burst == mlx5_rx_burst_vec || 612 dev->rx_pkt_burst == mlx5_rx_burst_mprq_vec) { 613 *no_of_elements = RTE_DIM(ptypes); 614 return ptypes; 615 } 616 return NULL; 617 } 618 619 /** 620 * DPDK callback to change the MTU. 621 * 622 * @param dev 623 * Pointer to Ethernet device structure. 624 * @param in_mtu 625 * New MTU. 626 * 627 * @return 628 * 0 on success, a negative errno value otherwise and rte_errno is set. 629 */ 630 int 631 mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) 632 { 633 struct mlx5_priv *priv = dev->data->dev_private; 634 uint16_t kern_mtu = 0; 635 int ret; 636 637 ret = mlx5_get_mtu(dev, &kern_mtu); 638 if (ret) 639 return ret; 640 /* Set kernel interface MTU first. */ 641 ret = mlx5_set_mtu(dev, mtu); 642 if (ret) 643 return ret; 644 ret = mlx5_get_mtu(dev, &kern_mtu); 645 if (ret) 646 return ret; 647 if (kern_mtu == mtu) { 648 priv->mtu = mtu; 649 DRV_LOG(DEBUG, "port %u adapter MTU set to %u", 650 dev->data->port_id, mtu); 651 return 0; 652 } 653 rte_errno = EAGAIN; 654 return -rte_errno; 655 } 656 657 /** 658 * Configure the RX function to use. 659 * 660 * @param dev 661 * Pointer to private data structure. 662 * 663 * @return 664 * Pointer to selected Rx burst function. 665 */ 666 eth_rx_burst_t 667 mlx5_select_rx_function(struct rte_eth_dev *dev) 668 { 669 eth_rx_burst_t rx_pkt_burst = mlx5_rx_burst; 670 671 MLX5_ASSERT(dev != NULL); 672 if (mlx5_check_vec_rx_support(dev) > 0) { 673 if (mlx5_mprq_enabled(dev)) { 674 rx_pkt_burst = mlx5_rx_burst_mprq_vec; 675 DRV_LOG(DEBUG, "port %u selected vectorized" 676 " MPRQ Rx function", dev->data->port_id); 677 } else { 678 rx_pkt_burst = mlx5_rx_burst_vec; 679 DRV_LOG(DEBUG, "port %u selected vectorized" 680 " SPRQ Rx function", dev->data->port_id); 681 } 682 } else if (mlx5_mprq_enabled(dev)) { 683 rx_pkt_burst = mlx5_rx_burst_mprq; 684 DRV_LOG(DEBUG, "port %u selected MPRQ Rx function", 685 dev->data->port_id); 686 } else { 687 DRV_LOG(DEBUG, "port %u selected SPRQ Rx function", 688 dev->data->port_id); 689 } 690 return rx_pkt_burst; 691 } 692 693 /** 694 * Get the E-Switch parameters by port id. 695 * 696 * @param[in] port 697 * Device port id. 698 * @param[in] valid 699 * Device port id is valid, skip check. This flag is useful 700 * when trials are performed from probing and device is not 701 * flagged as valid yet (in attaching process). 702 * @param[out] es_domain_id 703 * E-Switch domain id. 704 * @param[out] es_port_id 705 * The port id of the port in the E-Switch. 706 * 707 * @return 708 * pointer to device private data structure containing data needed 709 * on success, NULL otherwise and rte_errno is set. 710 */ 711 struct mlx5_priv * 712 mlx5_port_to_eswitch_info(uint16_t port, bool valid) 713 { 714 struct rte_eth_dev *dev; 715 struct mlx5_priv *priv; 716 717 if (port >= RTE_MAX_ETHPORTS) { 718 rte_errno = EINVAL; 719 return NULL; 720 } 721 if (!valid && !rte_eth_dev_is_valid_port(port)) { 722 rte_errno = ENODEV; 723 return NULL; 724 } 725 dev = &rte_eth_devices[port]; 726 priv = dev->data->dev_private; 727 if (!priv->sh->esw_mode) { 728 rte_errno = EINVAL; 729 return NULL; 730 } 731 return priv; 732 } 733 734 /** 735 * Get the E-Switch parameters by device instance. 736 * 737 * @param[in] port 738 * Device port id. 739 * @param[out] es_domain_id 740 * E-Switch domain id. 741 * @param[out] es_port_id 742 * The port id of the port in the E-Switch. 743 * 744 * @return 745 * pointer to device private data structure containing data needed 746 * on success, NULL otherwise and rte_errno is set. 747 */ 748 struct mlx5_priv * 749 mlx5_dev_to_eswitch_info(struct rte_eth_dev *dev) 750 { 751 struct mlx5_priv *priv; 752 753 priv = dev->data->dev_private; 754 if (!priv->sh->esw_mode) { 755 rte_errno = EINVAL; 756 return NULL; 757 } 758 return priv; 759 } 760 761 /** 762 * DPDK callback to retrieve hairpin capabilities. 763 * 764 * @param dev 765 * Pointer to Ethernet device structure. 766 * @param[out] cap 767 * Storage for hairpin capability data. 768 * 769 * @return 770 * 0 on success, a negative errno value otherwise and rte_errno is set. 771 */ 772 int 773 mlx5_hairpin_cap_get(struct rte_eth_dev *dev, struct rte_eth_hairpin_cap *cap) 774 { 775 struct mlx5_priv *priv = dev->data->dev_private; 776 struct mlx5_hca_attr *hca_attr; 777 778 if (!mlx5_devx_obj_ops_en(priv->sh)) { 779 rte_errno = ENOTSUP; 780 return -rte_errno; 781 } 782 cap->max_nb_queues = UINT16_MAX; 783 cap->max_rx_2_tx = 1; 784 cap->max_tx_2_rx = 1; 785 cap->max_nb_desc = 8192; 786 hca_attr = &priv->sh->cdev->config.hca_attr; 787 cap->rx_cap.locked_device_memory = hca_attr->hairpin_data_buffer_locked; 788 cap->rx_cap.rte_memory = 0; 789 cap->tx_cap.locked_device_memory = 0; 790 cap->tx_cap.rte_memory = hca_attr->hairpin_sq_wq_in_host_mem; 791 return 0; 792 } 793