18fd92a66SOlivier Matz /* SPDX-License-Identifier: BSD-3-Clause 2771fa900SAdrien Mazarguil * Copyright 2015 6WIND S.A. 35feecc57SShahaf Shuler * Copyright 2015 Mellanox Technologies, Ltd 4771fa900SAdrien Mazarguil */ 5771fa900SAdrien Mazarguil 6771fa900SAdrien Mazarguil #include <stddef.h> 7771fa900SAdrien Mazarguil #include <unistd.h> 8771fa900SAdrien Mazarguil #include <string.h> 91256805dSOphir Munk #include <stdint.h> 10771fa900SAdrien Mazarguil #include <stdlib.h> 11771fa900SAdrien Mazarguil #include <errno.h> 12771fa900SAdrien Mazarguil 13771fa900SAdrien Mazarguil #include <rte_atomic.h> 14ffc905f3SFerruh Yigit #include <rte_ethdev_driver.h> 15c752998bSGaetan Rivet #include <rte_bus_pci.h> 16771fa900SAdrien Mazarguil #include <rte_mbuf.h> 17771fa900SAdrien Mazarguil #include <rte_common.h> 18198a3c33SNelio Laranjeiro #include <rte_interrupts.h> 19a48deadaSOr Ami #include <rte_malloc.h> 20c022cb40SBruce Richardson #include <rte_string_fns.h> 21974f1e7eSYongseok Koh #include <rte_rwlock.h> 225897ac13SViacheslav Ovsiienko #include <rte_cycles.h> 23771fa900SAdrien Mazarguil 2483c2047cSSuanming Mou #include <mlx5_malloc.h> 2583c2047cSSuanming Mou 26e60fbd5bSAdrien Mazarguil #include "mlx5_rxtx.h" 271256805dSOphir Munk #include "mlx5_autoconf.h" 282b730263SAdrien Mazarguil 292b730263SAdrien Mazarguil /** 30ccdcba53SNélio Laranjeiro * Get the interface index from device name. 31ccdcba53SNélio Laranjeiro * 32ccdcba53SNélio Laranjeiro * @param[in] dev 33ccdcba53SNélio Laranjeiro * Pointer to Ethernet device. 34ccdcba53SNélio Laranjeiro * 35ccdcba53SNélio Laranjeiro * @return 363f8cb05dSAdrien Mazarguil * Nonzero interface index on success, zero otherwise and rte_errno is set. 37ccdcba53SNélio Laranjeiro */ 383f8cb05dSAdrien Mazarguil unsigned int 39ccdcba53SNélio Laranjeiro mlx5_ifindex(const struct rte_eth_dev *dev) 40ccdcba53SNélio Laranjeiro { 41fa2e14d4SViacheslav Ovsiienko struct mlx5_priv *priv = dev->data->dev_private; 423f8cb05dSAdrien Mazarguil unsigned int ifindex; 43ccdcba53SNélio Laranjeiro 448e46d4e1SAlexander Kozyrev MLX5_ASSERT(priv); 458e46d4e1SAlexander Kozyrev MLX5_ASSERT(priv->if_index); 46fa2e14d4SViacheslav Ovsiienko ifindex = priv->if_index; 473f8cb05dSAdrien Mazarguil if (!ifindex) 48fa2e14d4SViacheslav Ovsiienko rte_errno = ENXIO; 493f8cb05dSAdrien Mazarguil return ifindex; 50ccdcba53SNélio Laranjeiro } 51ccdcba53SNélio Laranjeiro 52ccdcba53SNélio Laranjeiro /** 537b2423cdSNélio Laranjeiro * DPDK callback for Ethernet device configuration. 54e60fbd5bSAdrien Mazarguil * 55e60fbd5bSAdrien Mazarguil * @param dev 56e60fbd5bSAdrien Mazarguil * Pointer to Ethernet device structure. 57e60fbd5bSAdrien Mazarguil * 58e60fbd5bSAdrien Mazarguil * @return 59a6d83b6aSNélio Laranjeiro * 0 on success, a negative errno value otherwise and rte_errno is set. 60e60fbd5bSAdrien Mazarguil */ 617b2423cdSNélio Laranjeiro int 627b2423cdSNélio Laranjeiro mlx5_dev_configure(struct rte_eth_dev *dev) 63e60fbd5bSAdrien Mazarguil { 64dbeba4cfSThomas Monjalon struct mlx5_priv *priv = dev->data->dev_private; 65e60fbd5bSAdrien Mazarguil unsigned int rxqs_n = dev->data->nb_rx_queues; 66e60fbd5bSAdrien Mazarguil unsigned int txqs_n = dev->data->nb_tx_queues; 6729c1d8bbSNélio Laranjeiro const uint8_t use_app_rss_key = 6821e3a974SShahaf Shuler !!dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key; 69a6d83b6aSNélio Laranjeiro int ret = 0; 70e60fbd5bSAdrien Mazarguil 7129c1d8bbSNélio Laranjeiro if (use_app_rss_key && 7229c1d8bbSNélio Laranjeiro (dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len != 73c388a2f6SNelio Laranjeiro MLX5_RSS_HASH_KEY_LEN)) { 74c388a2f6SNelio Laranjeiro DRV_LOG(ERR, "port %u RSS key len must be %s Bytes long", 75c388a2f6SNelio Laranjeiro dev->data->port_id, RTE_STR(MLX5_RSS_HASH_KEY_LEN)); 76a6d83b6aSNélio Laranjeiro rte_errno = EINVAL; 77a6d83b6aSNélio Laranjeiro return -rte_errno; 7829c1d8bbSNélio Laranjeiro } 7929c1d8bbSNélio Laranjeiro priv->rss_conf.rss_key = 8083c2047cSSuanming Mou mlx5_realloc(priv->rss_conf.rss_key, MLX5_MEM_RTE, 8183c2047cSSuanming Mou MLX5_RSS_HASH_KEY_LEN, 0, SOCKET_ID_ANY); 8229c1d8bbSNélio Laranjeiro if (!priv->rss_conf.rss_key) { 83a170a30dSNélio Laranjeiro DRV_LOG(ERR, "port %u cannot allocate RSS hash key memory (%u)", 840f99970bSNélio Laranjeiro dev->data->port_id, rxqs_n); 85a6d83b6aSNélio Laranjeiro rte_errno = ENOMEM; 86a6d83b6aSNélio Laranjeiro return -rte_errno; 8729c1d8bbSNélio Laranjeiro } 888b945a7fSPavan Nikhilesh 8973fb89ddSAndrew Rybchenko if (dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) 908b945a7fSPavan Nikhilesh dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_RSS_HASH; 918b945a7fSPavan Nikhilesh 9229c1d8bbSNélio Laranjeiro memcpy(priv->rss_conf.rss_key, 9329c1d8bbSNélio Laranjeiro use_app_rss_key ? 9429c1d8bbSNélio Laranjeiro dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key : 9529c1d8bbSNélio Laranjeiro rss_hash_default_key, 96c388a2f6SNelio Laranjeiro MLX5_RSS_HASH_KEY_LEN); 97c388a2f6SNelio Laranjeiro priv->rss_conf.rss_key_len = MLX5_RSS_HASH_KEY_LEN; 9829c1d8bbSNélio Laranjeiro priv->rss_conf.rss_hf = dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf; 99e60fbd5bSAdrien Mazarguil priv->rxqs = (void *)dev->data->rx_queues; 100e60fbd5bSAdrien Mazarguil priv->txqs = (void *)dev->data->tx_queues; 101e60fbd5bSAdrien Mazarguil if (txqs_n != priv->txqs_n) { 102a170a30dSNélio Laranjeiro DRV_LOG(INFO, "port %u Tx queues number update: %u -> %u", 1030f99970bSNélio Laranjeiro dev->data->port_id, priv->txqs_n, txqs_n); 104e60fbd5bSAdrien Mazarguil priv->txqs_n = txqs_n; 105e60fbd5bSAdrien Mazarguil } 1067fe24446SShahaf Shuler if (rxqs_n > priv->config.ind_table_max_size) { 107a170a30dSNélio Laranjeiro DRV_LOG(ERR, "port %u cannot handle this many Rx queues (%u)", 1080f99970bSNélio Laranjeiro dev->data->port_id, rxqs_n); 109a6d83b6aSNélio Laranjeiro rte_errno = EINVAL; 110a6d83b6aSNélio Laranjeiro return -rte_errno; 111634efbc2SNelio Laranjeiro } 11209ba4c58SDekel Peled if (rxqs_n != priv->rxqs_n) { 113a170a30dSNélio Laranjeiro DRV_LOG(INFO, "port %u Rx queues number update: %u -> %u", 1140f99970bSNélio Laranjeiro dev->data->port_id, priv->rxqs_n, rxqs_n); 115e60fbd5bSAdrien Mazarguil priv->rxqs_n = rxqs_n; 11663bd1629SOri Kam } 11763bd1629SOri Kam priv->skip_default_rss_reta = 0; 11863bd1629SOri Kam ret = mlx5_proc_priv_init(dev); 11963bd1629SOri Kam if (ret) 12063bd1629SOri Kam return ret; 12163bd1629SOri Kam return 0; 12263bd1629SOri Kam } 12363bd1629SOri Kam 12463bd1629SOri Kam /** 12563bd1629SOri Kam * Configure default RSS reta. 12663bd1629SOri Kam * 12763bd1629SOri Kam * @param dev 12863bd1629SOri Kam * Pointer to Ethernet device structure. 12963bd1629SOri Kam * 13063bd1629SOri Kam * @return 13163bd1629SOri Kam * 0 on success, a negative errno value otherwise and rte_errno is set. 13263bd1629SOri Kam */ 13363bd1629SOri Kam int 13463bd1629SOri Kam mlx5_dev_configure_rss_reta(struct rte_eth_dev *dev) 13563bd1629SOri Kam { 13663bd1629SOri Kam struct mlx5_priv *priv = dev->data->dev_private; 13763bd1629SOri Kam unsigned int rxqs_n = dev->data->nb_rx_queues; 13863bd1629SOri Kam unsigned int i; 13963bd1629SOri Kam unsigned int j; 14063bd1629SOri Kam unsigned int reta_idx_n; 14163bd1629SOri Kam int ret = 0; 14263bd1629SOri Kam unsigned int *rss_queue_arr = NULL; 14363bd1629SOri Kam unsigned int rss_queue_n = 0; 14463bd1629SOri Kam 14563bd1629SOri Kam if (priv->skip_default_rss_reta) 14663bd1629SOri Kam return ret; 14783c2047cSSuanming Mou rss_queue_arr = mlx5_malloc(0, rxqs_n * sizeof(unsigned int), 0, 14883c2047cSSuanming Mou SOCKET_ID_ANY); 14963bd1629SOri Kam if (!rss_queue_arr) { 15063bd1629SOri Kam DRV_LOG(ERR, "port %u cannot allocate RSS queue list (%u)", 15163bd1629SOri Kam dev->data->port_id, rxqs_n); 15263bd1629SOri Kam rte_errno = ENOMEM; 15363bd1629SOri Kam return -rte_errno; 15463bd1629SOri Kam } 15563bd1629SOri Kam for (i = 0, j = 0; i < rxqs_n; i++) { 15663bd1629SOri Kam struct mlx5_rxq_data *rxq_data; 15763bd1629SOri Kam struct mlx5_rxq_ctrl *rxq_ctrl; 15863bd1629SOri Kam 15963bd1629SOri Kam rxq_data = (*priv->rxqs)[i]; 16063bd1629SOri Kam rxq_ctrl = container_of(rxq_data, struct mlx5_rxq_ctrl, rxq); 161bf864e82STonghao Zhang if (rxq_ctrl && rxq_ctrl->type == MLX5_RXQ_TYPE_STANDARD) 16263bd1629SOri Kam rss_queue_arr[j++] = i; 16363bd1629SOri Kam } 16463bd1629SOri Kam rss_queue_n = j; 16563bd1629SOri Kam if (rss_queue_n > priv->config.ind_table_max_size) { 16663bd1629SOri Kam DRV_LOG(ERR, "port %u cannot handle this many Rx queues (%u)", 16763bd1629SOri Kam dev->data->port_id, rss_queue_n); 16863bd1629SOri Kam rte_errno = EINVAL; 16983c2047cSSuanming Mou mlx5_free(rss_queue_arr); 17063bd1629SOri Kam return -rte_errno; 17163bd1629SOri Kam } 17263bd1629SOri Kam DRV_LOG(INFO, "port %u Rx queues number update: %u -> %u", 17363bd1629SOri Kam dev->data->port_id, priv->rxqs_n, rxqs_n); 17463bd1629SOri Kam priv->rxqs_n = rxqs_n; 17509ba4c58SDekel Peled /* 17609ba4c58SDekel Peled * If the requested number of RX queues is not a power of two, 17709ba4c58SDekel Peled * use the maximum indirection table size for better balancing. 17809ba4c58SDekel Peled * The result is always rounded to the next power of two. 17909ba4c58SDekel Peled */ 18063bd1629SOri Kam reta_idx_n = (1 << log2above((rss_queue_n & (rss_queue_n - 1)) ? 1817fe24446SShahaf Shuler priv->config.ind_table_max_size : 18263bd1629SOri Kam rss_queue_n)); 183a6d83b6aSNélio Laranjeiro ret = mlx5_rss_reta_index_resize(dev, reta_idx_n); 18463bd1629SOri Kam if (ret) { 18583c2047cSSuanming Mou mlx5_free(rss_queue_arr); 186a6d83b6aSNélio Laranjeiro return ret; 18763bd1629SOri Kam } 18809ba4c58SDekel Peled /* 18909ba4c58SDekel Peled * When the number of RX queues is not a power of two, 19009ba4c58SDekel Peled * the remaining table entries are padded with reused WQs 19109ba4c58SDekel Peled * and hashes are not spread uniformly. 19209ba4c58SDekel Peled */ 193634efbc2SNelio Laranjeiro for (i = 0, j = 0; (i != reta_idx_n); ++i) { 19463bd1629SOri Kam (*priv->reta_idx)[i] = rss_queue_arr[j]; 19563bd1629SOri Kam if (++j == rss_queue_n) 196634efbc2SNelio Laranjeiro j = 0; 197634efbc2SNelio Laranjeiro } 19883c2047cSSuanming Mou mlx5_free(rss_queue_arr); 199120dc4a7SYongseok Koh return ret; 200e60fbd5bSAdrien Mazarguil } 201e60fbd5bSAdrien Mazarguil 202e60fbd5bSAdrien Mazarguil /** 203d11d651fSShahaf Shuler * Sets default tuning parameters. 204d11d651fSShahaf Shuler * 205d11d651fSShahaf Shuler * @param dev 206d11d651fSShahaf Shuler * Pointer to Ethernet device. 207d11d651fSShahaf Shuler * @param[out] info 208d11d651fSShahaf Shuler * Info structure output buffer. 209d11d651fSShahaf Shuler */ 210d11d651fSShahaf Shuler static void 211d11d651fSShahaf Shuler mlx5_set_default_params(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) 212d11d651fSShahaf Shuler { 213dbeba4cfSThomas Monjalon struct mlx5_priv *priv = dev->data->dev_private; 214d11d651fSShahaf Shuler 215d11d651fSShahaf Shuler /* Minimum CPU utilization. */ 216d11d651fSShahaf Shuler info->default_rxportconf.ring_size = 256; 217d11d651fSShahaf Shuler info->default_txportconf.ring_size = 256; 218f078ceb6SViacheslav Ovsiienko info->default_rxportconf.burst_size = MLX5_RX_DEFAULT_BURST; 219f078ceb6SViacheslav Ovsiienko info->default_txportconf.burst_size = MLX5_TX_DEFAULT_BURST; 2206e3a4595SAsaf Penso if ((priv->link_speed_capa & ETH_LINK_SPEED_200G) | 2216e3a4595SAsaf Penso (priv->link_speed_capa & ETH_LINK_SPEED_100G)) { 222d11d651fSShahaf Shuler info->default_rxportconf.nb_queues = 16; 223d11d651fSShahaf Shuler info->default_txportconf.nb_queues = 16; 224d11d651fSShahaf Shuler if (dev->data->nb_rx_queues > 2 || 225d11d651fSShahaf Shuler dev->data->nb_tx_queues > 2) { 226d11d651fSShahaf Shuler /* Max Throughput. */ 227d11d651fSShahaf Shuler info->default_rxportconf.ring_size = 2048; 228d11d651fSShahaf Shuler info->default_txportconf.ring_size = 2048; 229d11d651fSShahaf Shuler } 230d11d651fSShahaf Shuler } else { 231d11d651fSShahaf Shuler info->default_rxportconf.nb_queues = 8; 232d11d651fSShahaf Shuler info->default_txportconf.nb_queues = 8; 233d11d651fSShahaf Shuler if (dev->data->nb_rx_queues > 2 || 234d11d651fSShahaf Shuler dev->data->nb_tx_queues > 2) { 235d11d651fSShahaf Shuler /* Max Throughput. */ 236d11d651fSShahaf Shuler info->default_rxportconf.ring_size = 4096; 237d11d651fSShahaf Shuler info->default_txportconf.ring_size = 4096; 238d11d651fSShahaf Shuler } 239d11d651fSShahaf Shuler } 240d11d651fSShahaf Shuler } 241d11d651fSShahaf Shuler 242d11d651fSShahaf Shuler /** 243cb9cb61eSViacheslav Ovsiienko * Sets tx mbuf limiting parameters. 244cb9cb61eSViacheslav Ovsiienko * 245cb9cb61eSViacheslav Ovsiienko * @param dev 246cb9cb61eSViacheslav Ovsiienko * Pointer to Ethernet device. 247cb9cb61eSViacheslav Ovsiienko * @param[out] info 248cb9cb61eSViacheslav Ovsiienko * Info structure output buffer. 249cb9cb61eSViacheslav Ovsiienko */ 250cb9cb61eSViacheslav Ovsiienko static void 251cb9cb61eSViacheslav Ovsiienko mlx5_set_txlimit_params(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) 252cb9cb61eSViacheslav Ovsiienko { 253cb9cb61eSViacheslav Ovsiienko struct mlx5_priv *priv = dev->data->dev_private; 254cb9cb61eSViacheslav Ovsiienko struct mlx5_dev_config *config = &priv->config; 255cb9cb61eSViacheslav Ovsiienko unsigned int inlen; 256cb9cb61eSViacheslav Ovsiienko uint16_t nb_max; 257cb9cb61eSViacheslav Ovsiienko 258cb9cb61eSViacheslav Ovsiienko inlen = (config->txq_inline_max == MLX5_ARG_UNSET) ? 259cb9cb61eSViacheslav Ovsiienko MLX5_SEND_DEF_INLINE_LEN : 260cb9cb61eSViacheslav Ovsiienko (unsigned int)config->txq_inline_max; 2618e46d4e1SAlexander Kozyrev MLX5_ASSERT(config->txq_inline_min >= 0); 262cb9cb61eSViacheslav Ovsiienko inlen = RTE_MAX(inlen, (unsigned int)config->txq_inline_min); 263cb9cb61eSViacheslav Ovsiienko inlen = RTE_MIN(inlen, MLX5_WQE_SIZE_MAX + 264cb9cb61eSViacheslav Ovsiienko MLX5_ESEG_MIN_INLINE_SIZE - 265cb9cb61eSViacheslav Ovsiienko MLX5_WQE_CSEG_SIZE - 266cb9cb61eSViacheslav Ovsiienko MLX5_WQE_ESEG_SIZE - 267cb9cb61eSViacheslav Ovsiienko MLX5_WQE_DSEG_SIZE * 2); 268cb9cb61eSViacheslav Ovsiienko nb_max = (MLX5_WQE_SIZE_MAX + 269cb9cb61eSViacheslav Ovsiienko MLX5_ESEG_MIN_INLINE_SIZE - 270cb9cb61eSViacheslav Ovsiienko MLX5_WQE_CSEG_SIZE - 271cb9cb61eSViacheslav Ovsiienko MLX5_WQE_ESEG_SIZE - 272cb9cb61eSViacheslav Ovsiienko MLX5_WQE_DSEG_SIZE - 273cb9cb61eSViacheslav Ovsiienko inlen) / MLX5_WSEG_SIZE; 274cb9cb61eSViacheslav Ovsiienko info->tx_desc_lim.nb_seg_max = nb_max; 275cb9cb61eSViacheslav Ovsiienko info->tx_desc_lim.nb_mtu_seg_max = nb_max; 276cb9cb61eSViacheslav Ovsiienko } 277cb9cb61eSViacheslav Ovsiienko 278cb9cb61eSViacheslav Ovsiienko /** 279e60fbd5bSAdrien Mazarguil * DPDK callback to get information about the device. 280e60fbd5bSAdrien Mazarguil * 281e60fbd5bSAdrien Mazarguil * @param dev 282e60fbd5bSAdrien Mazarguil * Pointer to Ethernet device structure. 283e60fbd5bSAdrien Mazarguil * @param[out] info 284e60fbd5bSAdrien Mazarguil * Info structure output buffer. 285e60fbd5bSAdrien Mazarguil */ 286bdad90d1SIvan Ilchenko int 287e60fbd5bSAdrien Mazarguil mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) 288e60fbd5bSAdrien Mazarguil { 289dbeba4cfSThomas Monjalon struct mlx5_priv *priv = dev->data->dev_private; 2907fe24446SShahaf Shuler struct mlx5_dev_config *config = &priv->config; 291e60fbd5bSAdrien Mazarguil unsigned int max; 292e60fbd5bSAdrien Mazarguil 293e60fbd5bSAdrien Mazarguil /* FIXME: we should ask the device for these values. */ 294e60fbd5bSAdrien Mazarguil info->min_rx_bufsize = 32; 295e60fbd5bSAdrien Mazarguil info->max_rx_pktlen = 65536; 2961c7e57f9SDekel Peled info->max_lro_pkt_size = MLX5_MAX_LRO_SIZE; 297e60fbd5bSAdrien Mazarguil /* 298e60fbd5bSAdrien Mazarguil * Since we need one CQ per QP, the limit is the minimum number 299e60fbd5bSAdrien Mazarguil * between the two values. 300e60fbd5bSAdrien Mazarguil */ 301e85f623eSOphir Munk max = RTE_MIN(priv->sh->device_attr.max_cq, 302e85f623eSOphir Munk priv->sh->device_attr.max_qp); 303b689a781SThomas Monjalon /* max_rx_queues is uint16_t. */ 304b689a781SThomas Monjalon max = RTE_MIN(max, (unsigned int)UINT16_MAX); 305e60fbd5bSAdrien Mazarguil info->max_rx_queues = max; 306e60fbd5bSAdrien Mazarguil info->max_tx_queues = max; 30718c01b98SNélio Laranjeiro info->max_mac_addrs = MLX5_MAX_UC_MAC_ADDRESSES; 308af4f09f2SNélio Laranjeiro info->rx_queue_offload_capa = mlx5_get_rx_queue_offloads(dev); 30917ed314cSMatan Azrad info->rx_offload_capa = (mlx5_get_rx_port_offloads() | 31017b843ebSShahaf Shuler info->rx_queue_offload_capa); 311af4f09f2SNélio Laranjeiro info->tx_offload_capa = mlx5_get_tx_port_offloads(dev); 312fa2e14d4SViacheslav Ovsiienko info->if_index = mlx5_ifindex(dev); 313d365210eSYongseok Koh info->reta_size = priv->reta_idx_n ? 3147fe24446SShahaf Shuler priv->reta_idx_n : config->ind_table_max_size; 315c388a2f6SNelio Laranjeiro info->hash_key_size = MLX5_RSS_HASH_KEY_LEN; 31675ef62a9SNélio Laranjeiro info->speed_capa = priv->link_speed_capa; 317b233b027SShahaf Shuler info->flow_type_rss_offloads = ~MLX5_RSS_HF_MASK; 318d11d651fSShahaf Shuler mlx5_set_default_params(dev, info); 319cb9cb61eSViacheslav Ovsiienko mlx5_set_txlimit_params(dev, info); 3202b730263SAdrien Mazarguil info->switch_info.name = dev->data->name; 3212b730263SAdrien Mazarguil info->switch_info.domain_id = priv->domain_id; 3222b730263SAdrien Mazarguil info->switch_info.port_id = priv->representor_id; 3232b730263SAdrien Mazarguil if (priv->representor) { 324f7e95215SViacheslav Ovsiienko uint16_t port_id; 3252b730263SAdrien Mazarguil 326bee57a0aSViacheslav Ovsiienko if (priv->pf_bond >= 0) { 327bee57a0aSViacheslav Ovsiienko /* 328bee57a0aSViacheslav Ovsiienko * Switch port ID is opaque value with driver defined 329bee57a0aSViacheslav Ovsiienko * format. Push the PF index in bonding configurations 330bee57a0aSViacheslav Ovsiienko * in upper four bits of port ID. If we get too many 331bee57a0aSViacheslav Ovsiienko * representors (more than 4K) or PFs (more than 15) 332bee57a0aSViacheslav Ovsiienko * this approach must be reconsidered. 333bee57a0aSViacheslav Ovsiienko */ 334bee57a0aSViacheslav Ovsiienko if ((info->switch_info.port_id >> 335bee57a0aSViacheslav Ovsiienko MLX5_PORT_ID_BONDING_PF_SHIFT) || 336bee57a0aSViacheslav Ovsiienko priv->pf_bond > MLX5_PORT_ID_BONDING_PF_MASK) { 337bee57a0aSViacheslav Ovsiienko DRV_LOG(ERR, "can't update switch port ID" 338bee57a0aSViacheslav Ovsiienko " for bonding device"); 3398e46d4e1SAlexander Kozyrev MLX5_ASSERT(false); 340bee57a0aSViacheslav Ovsiienko return -ENODEV; 341bee57a0aSViacheslav Ovsiienko } 342bee57a0aSViacheslav Ovsiienko info->switch_info.port_id |= 343bee57a0aSViacheslav Ovsiienko priv->pf_bond << MLX5_PORT_ID_BONDING_PF_SHIFT; 344bee57a0aSViacheslav Ovsiienko } 345fbc83412SViacheslav Ovsiienko MLX5_ETH_FOREACH_DEV(port_id, priv->pci_dev) { 346dbeba4cfSThomas Monjalon struct mlx5_priv *opriv = 347f7e95215SViacheslav Ovsiienko rte_eth_devices[port_id].data->dev_private; 3482b730263SAdrien Mazarguil 3492b730263SAdrien Mazarguil if (!opriv || 3502b730263SAdrien Mazarguil opriv->representor || 351f7e95215SViacheslav Ovsiienko opriv->sh != priv->sh || 3522b730263SAdrien Mazarguil opriv->domain_id != priv->domain_id) 3532b730263SAdrien Mazarguil continue; 3542b730263SAdrien Mazarguil /* 3552b730263SAdrien Mazarguil * Override switch name with that of the master 3562b730263SAdrien Mazarguil * device. 3572b730263SAdrien Mazarguil */ 3582b730263SAdrien Mazarguil info->switch_info.name = opriv->dev_data->name; 3592b730263SAdrien Mazarguil break; 3602b730263SAdrien Mazarguil } 3612b730263SAdrien Mazarguil } 362bdad90d1SIvan Ilchenko return 0; 363e60fbd5bSAdrien Mazarguil } 364e60fbd5bSAdrien Mazarguil 365fb732b0aSNélio Laranjeiro /** 366714bf46eSThomas Monjalon * Get firmware version of a device. 367714bf46eSThomas Monjalon * 368714bf46eSThomas Monjalon * @param dev 369714bf46eSThomas Monjalon * Ethernet device port. 370714bf46eSThomas Monjalon * @param fw_ver 371714bf46eSThomas Monjalon * String output allocated by caller. 372714bf46eSThomas Monjalon * @param fw_size 373714bf46eSThomas Monjalon * Size of the output string, including terminating null byte. 374714bf46eSThomas Monjalon * 375714bf46eSThomas Monjalon * @return 376714bf46eSThomas Monjalon * 0 on success, or the size of the non truncated string if too big. 377714bf46eSThomas Monjalon */ 3781256805dSOphir Munk int 3791256805dSOphir Munk mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size) 380714bf46eSThomas Monjalon { 381dbeba4cfSThomas Monjalon struct mlx5_priv *priv = dev->data->dev_private; 382e85f623eSOphir Munk struct mlx5_dev_attr *attr = &priv->sh->device_attr; 383714bf46eSThomas Monjalon size_t size = strnlen(attr->fw_ver, sizeof(attr->fw_ver)) + 1; 384714bf46eSThomas Monjalon 385714bf46eSThomas Monjalon if (fw_size < size) 386714bf46eSThomas Monjalon return size; 387714bf46eSThomas Monjalon if (fw_ver != NULL) 388714bf46eSThomas Monjalon strlcpy(fw_ver, attr->fw_ver, fw_size); 389714bf46eSThomas Monjalon return 0; 390714bf46eSThomas Monjalon } 391714bf46eSThomas Monjalon 392714bf46eSThomas Monjalon /** 393fb732b0aSNélio Laranjeiro * Get supported packet types. 394fb732b0aSNélio Laranjeiro * 395fb732b0aSNélio Laranjeiro * @param dev 396fb732b0aSNélio Laranjeiro * Pointer to Ethernet device structure. 397fb732b0aSNélio Laranjeiro * 398fb732b0aSNélio Laranjeiro * @return 399fb732b0aSNélio Laranjeiro * A pointer to the supported Packet types array. 400fb732b0aSNélio Laranjeiro */ 40178a38edfSJianfeng Tan const uint32_t * 40278a38edfSJianfeng Tan mlx5_dev_supported_ptypes_get(struct rte_eth_dev *dev) 40378a38edfSJianfeng Tan { 40478a38edfSJianfeng Tan static const uint32_t ptypes[] = { 40578a38edfSJianfeng Tan /* refers to rxq_cq_to_pkt_type() */ 406ea16068cSYongseok Koh RTE_PTYPE_L2_ETHER, 407c4ba5434SNélio Laranjeiro RTE_PTYPE_L3_IPV4_EXT_UNKNOWN, 408c4ba5434SNélio Laranjeiro RTE_PTYPE_L3_IPV6_EXT_UNKNOWN, 409ea16068cSYongseok Koh RTE_PTYPE_L4_NONFRAG, 410ea16068cSYongseok Koh RTE_PTYPE_L4_FRAG, 411ea16068cSYongseok Koh RTE_PTYPE_L4_TCP, 412ea16068cSYongseok Koh RTE_PTYPE_L4_UDP, 413c4ba5434SNélio Laranjeiro RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN, 414c4ba5434SNélio Laranjeiro RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN, 415ea16068cSYongseok Koh RTE_PTYPE_INNER_L4_NONFRAG, 416ea16068cSYongseok Koh RTE_PTYPE_INNER_L4_FRAG, 417ea16068cSYongseok Koh RTE_PTYPE_INNER_L4_TCP, 418ea16068cSYongseok Koh RTE_PTYPE_INNER_L4_UDP, 41978a38edfSJianfeng Tan RTE_PTYPE_UNKNOWN 42078a38edfSJianfeng Tan }; 42178a38edfSJianfeng Tan 4226cb559d6SYongseok Koh if (dev->rx_pkt_burst == mlx5_rx_burst || 4237d6bf6b8SYongseok Koh dev->rx_pkt_burst == mlx5_rx_burst_mprq || 4246cb559d6SYongseok Koh dev->rx_pkt_burst == mlx5_rx_burst_vec) 42578a38edfSJianfeng Tan return ptypes; 42678a38edfSJianfeng Tan return NULL; 42778a38edfSJianfeng Tan } 42878a38edfSJianfeng Tan 429e60fbd5bSAdrien Mazarguil /** 430cf37ca95SAdrien Mazarguil * DPDK callback to change the MTU. 431cf37ca95SAdrien Mazarguil * 432cf37ca95SAdrien Mazarguil * @param dev 433cf37ca95SAdrien Mazarguil * Pointer to Ethernet device structure. 434cf37ca95SAdrien Mazarguil * @param in_mtu 435cf37ca95SAdrien Mazarguil * New MTU. 436cf37ca95SAdrien Mazarguil * 437cf37ca95SAdrien Mazarguil * @return 438a6d83b6aSNélio Laranjeiro * 0 on success, a negative errno value otherwise and rte_errno is set. 439cf37ca95SAdrien Mazarguil */ 440cf37ca95SAdrien Mazarguil int 441cf37ca95SAdrien Mazarguil mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) 442cf37ca95SAdrien Mazarguil { 443dbeba4cfSThomas Monjalon struct mlx5_priv *priv = dev->data->dev_private; 444a6d83b6aSNélio Laranjeiro uint16_t kern_mtu = 0; 445a6d83b6aSNélio Laranjeiro int ret; 446cf37ca95SAdrien Mazarguil 447af4f09f2SNélio Laranjeiro ret = mlx5_get_mtu(dev, &kern_mtu); 448a0edafe4SNelio Laranjeiro if (ret) 449a6d83b6aSNélio Laranjeiro return ret; 450cf37ca95SAdrien Mazarguil /* Set kernel interface MTU first. */ 451af4f09f2SNélio Laranjeiro ret = mlx5_set_mtu(dev, mtu); 452a0edafe4SNelio Laranjeiro if (ret) 453a6d83b6aSNélio Laranjeiro return ret; 454af4f09f2SNélio Laranjeiro ret = mlx5_get_mtu(dev, &kern_mtu); 455a0edafe4SNelio Laranjeiro if (ret) 456a6d83b6aSNélio Laranjeiro return ret; 457a0edafe4SNelio Laranjeiro if (kern_mtu == mtu) { 458a0edafe4SNelio Laranjeiro priv->mtu = mtu; 459a170a30dSNélio Laranjeiro DRV_LOG(DEBUG, "port %u adapter MTU set to %u", 460a170a30dSNélio Laranjeiro dev->data->port_id, mtu); 461a0edafe4SNelio Laranjeiro return 0; 462a6d83b6aSNélio Laranjeiro } 463a6d83b6aSNélio Laranjeiro rte_errno = EAGAIN; 464a6d83b6aSNélio Laranjeiro return -rte_errno; 465cf37ca95SAdrien Mazarguil } 466cf37ca95SAdrien Mazarguil 467cf37ca95SAdrien Mazarguil /** 468cdab90cbSNélio Laranjeiro * Configure the RX function to use. 469cdab90cbSNélio Laranjeiro * 470aee1b165SXueming Li * @param dev 471af4f09f2SNélio Laranjeiro * Pointer to private data structure. 4721cfa649bSShahaf Shuler * 4731cfa649bSShahaf Shuler * @return 4741cfa649bSShahaf Shuler * Pointer to selected Rx burst function. 475cdab90cbSNélio Laranjeiro */ 4761cfa649bSShahaf Shuler eth_rx_burst_t 477af4f09f2SNélio Laranjeiro mlx5_select_rx_function(struct rte_eth_dev *dev) 478cdab90cbSNélio Laranjeiro { 4791cfa649bSShahaf Shuler eth_rx_burst_t rx_pkt_burst = mlx5_rx_burst; 4801cfa649bSShahaf Shuler 4818e46d4e1SAlexander Kozyrev MLX5_ASSERT(dev != NULL); 482af4f09f2SNélio Laranjeiro if (mlx5_check_vec_rx_support(dev) > 0) { 4831cfa649bSShahaf Shuler rx_pkt_burst = mlx5_rx_burst_vec; 484a170a30dSNélio Laranjeiro DRV_LOG(DEBUG, "port %u selected Rx vectorized function", 4850f99970bSNélio Laranjeiro dev->data->port_id); 4867d6bf6b8SYongseok Koh } else if (mlx5_mprq_enabled(dev)) { 4877d6bf6b8SYongseok Koh rx_pkt_burst = mlx5_rx_burst_mprq; 488cdab90cbSNélio Laranjeiro } 4891cfa649bSShahaf Shuler return rx_pkt_burst; 4906cb559d6SYongseok Koh } 491d3e0f392SMatan Azrad 492d3e0f392SMatan Azrad /** 49309a16bcaSViacheslav Ovsiienko * Get the E-Switch parameters by port id. 4942e4c987aSOri Kam * 4952e4c987aSOri Kam * @param[in] port 4962e4c987aSOri Kam * Device port id. 4975e61bcddSViacheslav Ovsiienko * @param[in] valid 4985e61bcddSViacheslav Ovsiienko * Device port id is valid, skip check. This flag is useful 4995e61bcddSViacheslav Ovsiienko * when trials are performed from probing and device is not 5005e61bcddSViacheslav Ovsiienko * flagged as valid yet (in attaching process). 5012e4c987aSOri Kam * @param[out] es_domain_id 5022e4c987aSOri Kam * E-Switch domain id. 5032e4c987aSOri Kam * @param[out] es_port_id 5042e4c987aSOri Kam * The port id of the port in the E-Switch. 5052e4c987aSOri Kam * 5062e4c987aSOri Kam * @return 50709a16bcaSViacheslav Ovsiienko * pointer to device private data structure containing data needed 50809a16bcaSViacheslav Ovsiienko * on success, NULL otherwise and rte_errno is set. 5092e4c987aSOri Kam */ 51009a16bcaSViacheslav Ovsiienko struct mlx5_priv * 5115e61bcddSViacheslav Ovsiienko mlx5_port_to_eswitch_info(uint16_t port, bool valid) 5122e4c987aSOri Kam { 5132e4c987aSOri Kam struct rte_eth_dev *dev; 5142e4c987aSOri Kam struct mlx5_priv *priv; 5152e4c987aSOri Kam 5162e4c987aSOri Kam if (port >= RTE_MAX_ETHPORTS) { 5172e4c987aSOri Kam rte_errno = EINVAL; 51809a16bcaSViacheslav Ovsiienko return NULL; 5192e4c987aSOri Kam } 5205e61bcddSViacheslav Ovsiienko if (!valid && !rte_eth_dev_is_valid_port(port)) { 5212e4c987aSOri Kam rte_errno = ENODEV; 52209a16bcaSViacheslav Ovsiienko return NULL; 5232e4c987aSOri Kam } 5242e4c987aSOri Kam dev = &rte_eth_devices[port]; 5252e4c987aSOri Kam priv = dev->data->dev_private; 5262e4c987aSOri Kam if (!(priv->representor || priv->master)) { 5272e4c987aSOri Kam rte_errno = EINVAL; 52809a16bcaSViacheslav Ovsiienko return NULL; 5292e4c987aSOri Kam } 53009a16bcaSViacheslav Ovsiienko return priv; 53109a16bcaSViacheslav Ovsiienko } 53209a16bcaSViacheslav Ovsiienko 53309a16bcaSViacheslav Ovsiienko /** 53409a16bcaSViacheslav Ovsiienko * Get the E-Switch parameters by device instance. 53509a16bcaSViacheslav Ovsiienko * 53609a16bcaSViacheslav Ovsiienko * @param[in] port 53709a16bcaSViacheslav Ovsiienko * Device port id. 53809a16bcaSViacheslav Ovsiienko * @param[out] es_domain_id 53909a16bcaSViacheslav Ovsiienko * E-Switch domain id. 54009a16bcaSViacheslav Ovsiienko * @param[out] es_port_id 54109a16bcaSViacheslav Ovsiienko * The port id of the port in the E-Switch. 54209a16bcaSViacheslav Ovsiienko * 54309a16bcaSViacheslav Ovsiienko * @return 54409a16bcaSViacheslav Ovsiienko * pointer to device private data structure containing data needed 54509a16bcaSViacheslav Ovsiienko * on success, NULL otherwise and rte_errno is set. 54609a16bcaSViacheslav Ovsiienko */ 54709a16bcaSViacheslav Ovsiienko struct mlx5_priv * 54809a16bcaSViacheslav Ovsiienko mlx5_dev_to_eswitch_info(struct rte_eth_dev *dev) 54909a16bcaSViacheslav Ovsiienko { 55009a16bcaSViacheslav Ovsiienko struct mlx5_priv *priv; 55109a16bcaSViacheslav Ovsiienko 55209a16bcaSViacheslav Ovsiienko priv = dev->data->dev_private; 55309a16bcaSViacheslav Ovsiienko if (!(priv->representor || priv->master)) { 55409a16bcaSViacheslav Ovsiienko rte_errno = EINVAL; 55509a16bcaSViacheslav Ovsiienko return NULL; 55609a16bcaSViacheslav Ovsiienko } 55709a16bcaSViacheslav Ovsiienko return priv; 5582e4c987aSOri Kam } 5592e4c987aSOri Kam 5602e4c987aSOri Kam /** 561b6b3bf86SOri Kam * DPDK callback to retrieve hairpin capabilities. 562b6b3bf86SOri Kam * 563b6b3bf86SOri Kam * @param dev 564b6b3bf86SOri Kam * Pointer to Ethernet device structure. 565b6b3bf86SOri Kam * @param[out] cap 566b6b3bf86SOri Kam * Storage for hairpin capability data. 567b6b3bf86SOri Kam * 568b6b3bf86SOri Kam * @return 569b6b3bf86SOri Kam * 0 on success, a negative errno value otherwise and rte_errno is set. 570b6b3bf86SOri Kam */ 5711256805dSOphir Munk int 572*b00f7603SMichael Baum mlx5_hairpin_cap_get(struct rte_eth_dev *dev, struct rte_eth_hairpin_cap *cap) 573b6b3bf86SOri Kam { 574b6b3bf86SOri Kam struct mlx5_priv *priv = dev->data->dev_private; 575*b00f7603SMichael Baum struct mlx5_dev_config *config = &priv->config; 576b6b3bf86SOri Kam 577*b00f7603SMichael Baum if (!priv->sh->devx || !config->dest_tir || !config->dv_flow_en) { 578b6b3bf86SOri Kam rte_errno = ENOTSUP; 579b6b3bf86SOri Kam return -rte_errno; 580b6b3bf86SOri Kam } 581b6b3bf86SOri Kam cap->max_nb_queues = UINT16_MAX; 582b6b3bf86SOri Kam cap->max_rx_2_tx = 1; 583b6b3bf86SOri Kam cap->max_tx_2_rx = 1; 584b6b3bf86SOri Kam cap->max_nb_desc = 8192; 585b6b3bf86SOri Kam return 0; 586b6b3bf86SOri Kam } 587