- memset(&qp_init_attr, 0, sizeof(qp_init_attr));
- if (tunnel) {
- qp_init_attr.comp_mask =
- MLX5DV_QP_INIT_ATTR_MASK_QP_CREATE_FLAGS;
- qp_init_attr.create_flags =
- MLX5DV_QP_CREATE_TUNNEL_OFFLOADS;
- }
-#ifdef HAVE_IBV_FLOW_DV_SUPPORT
- if (dev->data->dev_conf.lpbk_mode) {
- /*
- * Allow packet sent from NIC loop back
- * w/o source MAC check.
- */
- qp_init_attr.comp_mask |=
- MLX5DV_QP_INIT_ATTR_MASK_QP_CREATE_FLAGS;
- qp_init_attr.create_flags |=
- MLX5DV_QP_CREATE_TIR_ALLOW_SELF_LOOPBACK_UC;
- }
-#endif
- qp = mlx5_glue->dv_create_qp
- (priv->sh->ctx,
- &(struct ibv_qp_init_attr_ex){
- .qp_type = IBV_QPT_RAW_PACKET,
- .comp_mask =
- IBV_QP_INIT_ATTR_PD |
- IBV_QP_INIT_ATTR_IND_TABLE |
- IBV_QP_INIT_ATTR_RX_HASH,
- .rx_hash_conf = (struct ibv_rx_hash_conf){
- .rx_hash_function =
- IBV_RX_HASH_FUNC_TOEPLITZ,
- .rx_hash_key_len = rss_key_len,
- .rx_hash_key =
- (void *)(uintptr_t)rss_key,
- .rx_hash_fields_mask = hash_fields,
- },
- .rwq_ind_tbl = ind_tbl->ind_table,
- .pd = priv->sh->pd,
- },
- &qp_init_attr);
-#else
- qp = mlx5_glue->create_qp_ex
- (priv->sh->ctx,
- &(struct ibv_qp_init_attr_ex){
- .qp_type = IBV_QPT_RAW_PACKET,
- .comp_mask =
- IBV_QP_INIT_ATTR_PD |
- IBV_QP_INIT_ATTR_IND_TABLE |
- IBV_QP_INIT_ATTR_RX_HASH,
- .rx_hash_conf = (struct ibv_rx_hash_conf){
- .rx_hash_function =
- IBV_RX_HASH_FUNC_TOEPLITZ,
- .rx_hash_key_len = rss_key_len,
- .rx_hash_key =
- (void *)(uintptr_t)rss_key,
- .rx_hash_fields_mask = hash_fields,
- },
- .rwq_ind_tbl = ind_tbl->ind_table,
- .pd = priv->sh->pd,
- });
-#endif
- if (!qp) {
- rte_errno = errno;
- goto error;
- }
- } else { /* ind_tbl->type == MLX5_IND_TBL_TYPE_DEVX */
- struct mlx5_devx_tir_attr tir_attr;
- uint32_t i;
- uint32_t lro = 1;
-
- /* Enable TIR LRO only if all the queues were configured for. */
- for (i = 0; i < queues_n; ++i) {
- if (!(*priv->rxqs)[queues[i]]->lro) {
- lro = 0;
- break;
- }
- }
- memset(&tir_attr, 0, sizeof(tir_attr));
- tir_attr.disp_type = MLX5_TIRC_DISP_TYPE_INDIRECT;
- tir_attr.rx_hash_fn = MLX5_RX_HASH_FN_TOEPLITZ;
- tir_attr.tunneled_offload_en = !!tunnel;
- /* If needed, translate hash_fields bitmap to PRM format. */
- if (hash_fields) {
-#ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
- struct mlx5_rx_hash_field_select *rx_hash_field_select =
- hash_fields & IBV_RX_HASH_INNER ?
- &tir_attr.rx_hash_field_selector_inner :
- &tir_attr.rx_hash_field_selector_outer;
-#else
- struct mlx5_rx_hash_field_select *rx_hash_field_select =
- &tir_attr.rx_hash_field_selector_outer;
-#endif
-
- /* 1 bit: 0: IPv4, 1: IPv6. */
- rx_hash_field_select->l3_prot_type =
- !!(hash_fields & MLX5_IPV6_IBV_RX_HASH);
- /* 1 bit: 0: TCP, 1: UDP. */
- rx_hash_field_select->l4_prot_type =
- !!(hash_fields & MLX5_UDP_IBV_RX_HASH);
- /* Bitmask which sets which fields to use in RX Hash. */
- rx_hash_field_select->selected_fields =
- ((!!(hash_fields & MLX5_L3_SRC_IBV_RX_HASH)) <<
- MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_SRC_IP) |
- (!!(hash_fields & MLX5_L3_DST_IBV_RX_HASH)) <<
- MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_DST_IP |
- (!!(hash_fields & MLX5_L4_SRC_IBV_RX_HASH)) <<
- MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_L4_SPORT |
- (!!(hash_fields & MLX5_L4_DST_IBV_RX_HASH)) <<
- MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_L4_DPORT;
- }
- if (rxq_ctrl->obj->type == MLX5_RXQ_OBJ_TYPE_DEVX_HAIRPIN)
- tir_attr.transport_domain = priv->sh->td->id;
- else
- tir_attr.transport_domain = priv->sh->tdn;
- memcpy(tir_attr.rx_hash_toeplitz_key, rss_key,
- MLX5_RSS_HASH_KEY_LEN);
- tir_attr.indirect_table = ind_tbl->rqt->id;
- if (dev->data->dev_conf.lpbk_mode)
- tir_attr.self_lb_block =
- MLX5_TIRC_SELF_LB_BLOCK_BLOCK_UNICAST;
- if (lro) {
- tir_attr.lro_timeout_period_usecs =
- priv->config.lro.timeout;
- tir_attr.lro_max_msg_sz = priv->max_lro_msg_size;
- tir_attr.lro_enable_mask =
- MLX5_TIRC_LRO_ENABLE_MASK_IPV4_LRO |
- MLX5_TIRC_LRO_ENABLE_MASK_IPV6_LRO;
- }
- tir = mlx5_devx_cmd_create_tir(priv->sh->ctx, &tir_attr);
- if (!tir) {
- DRV_LOG(ERR, "port %u cannot create DevX TIR",
- dev->data->port_id);
- rte_errno = errno;
- goto error;
- }
+/**
+ * Modify an indirection table.
+ *
+ * @param dev
+ * Pointer to Ethernet device.
+ * @param ind_table
+ * Indirection table to modify.
+ * @param queues
+ * Queues replacement for the indirection table.
+ * @param queues_n
+ * Number of queues in the array.
+ * @param standalone
+ * Indirection table for Standalone queue.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_ind_table_obj_modify(struct rte_eth_dev *dev,
+ struct mlx5_ind_table_obj *ind_tbl,
+ uint16_t *queues, const uint32_t queues_n,
+ bool standalone)
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ unsigned int i, j;
+ int ret = 0, err;
+ const unsigned int n = rte_is_power_of_2(queues_n) ?
+ log2above(queues_n) :
+ log2above(priv->config.ind_table_max_size);
+
+ MLX5_ASSERT(standalone);
+ RTE_SET_USED(standalone);
+ if (__atomic_load_n(&ind_tbl->refcnt, __ATOMIC_RELAXED) > 1) {
+ /*
+ * Modification of indirection ntables having more than 1
+ * reference unsupported. Intended for standalone indirection
+ * tables only.
+ */
+ DRV_LOG(DEBUG,
+ "Port %u cannot modify indirection table (refcnt> 1).",
+ dev->data->port_id);
+ rte_errno = EINVAL;
+ return -rte_errno;