return;
for (i = 0; i != ind_tbl->queues_n; ++i) {
int idx = ind_tbl->queues[i];
- struct mlx5_rxq_ctrl *rxq_ctrl = mlx5_rxq_ctrl_get(dev, idx);
+ struct mlx5_rxq_ctrl *rxq_ctrl;
+ if (mlx5_is_external_rxq(dev, idx))
+ continue;
+ rxq_ctrl = mlx5_rxq_ctrl_get(dev, idx);
MLX5_ASSERT(rxq_ctrl != NULL);
if (rxq_ctrl == NULL)
continue;
MLX5_ASSERT(dev->data->dev_started);
for (i = 0; i != ind_tbl->queues_n; ++i) {
int idx = ind_tbl->queues[i];
- struct mlx5_rxq_ctrl *rxq_ctrl = mlx5_rxq_ctrl_get(dev, idx);
+ struct mlx5_rxq_ctrl *rxq_ctrl;
+ if (mlx5_is_external_rxq(dev, idx))
+ continue;
+ rxq_ctrl = mlx5_rxq_ctrl_get(dev, idx);
MLX5_ASSERT(rxq_ctrl != NULL);
if (rxq_ctrl == NULL)
continue;
uint32_t flow_id = 0;
uint32_t flow_id_reversed = 0;
uint8_t flow_id_bits = 0;
+ bool after_meter = false;
int shift;
/* Prepare the suffix subflow items. */
tag_action = actions_pre++;
action_cur = actions_pre++;
}
+ after_meter = true;
break;
case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP:
case RTE_FLOW_ACTION_TYPE_NVGRE_DECAP:
MLX5_RTE_FLOW_ITEM_TYPE_VLAN;
}
break;
+ case RTE_FLOW_ACTION_TYPE_COUNT:
+ if (fm->def_policy)
+ action_cur = after_meter ?
+ actions_sfx++ : actions_pre++;
+ break;
default:
break;
}
return flag ? actions_n + 1 : 0;
}
-#define SAMPLE_SUFFIX_ITEM 2
+#define SAMPLE_SUFFIX_ITEM 3
/**
* Split the sample flow.
static int
flow_sample_split_prep(struct rte_eth_dev *dev,
int add_tag,
+ const struct rte_flow_item items[],
struct rte_flow_item sfx_items[],
const struct rte_flow_action actions[],
struct rte_flow_action actions_sfx[],
struct mlx5_rte_flow_item_tag *tag_mask;
struct rte_flow_action_jump *jump_action;
uint32_t tag_id = 0;
- int index;
int append_index = 0;
+ int set_tag_idx = -1;
+ int index;
int ret;
if (sample_action_pos < 0)
NULL, "invalid position of sample "
"action in list");
/* Prepare the actions for prefix and suffix flow. */
+ if (add_tag) {
+ /* Update the new added tag action index preceding
+ * the PUSH_VLAN or ENCAP action.
+ */
+ const struct rte_flow_action_raw_encap *raw_encap;
+ const struct rte_flow_action *action = actions;
+ int encap_idx;
+ int action_idx = 0;
+ int raw_decap_idx = -1;
+ int push_vlan_idx = -1;
+ for (; action->type != RTE_FLOW_ACTION_TYPE_END; action++) {
+ switch (action->type) {
+ case RTE_FLOW_ACTION_TYPE_RAW_DECAP:
+ raw_decap_idx = action_idx;
+ break;
+ case RTE_FLOW_ACTION_TYPE_RAW_ENCAP:
+ raw_encap = action->conf;
+ if (raw_encap->size >
+ MLX5_ENCAPSULATION_DECISION_SIZE) {
+ encap_idx = raw_decap_idx != -1 ?
+ raw_decap_idx : action_idx;
+ if (encap_idx < sample_action_pos &&
+ push_vlan_idx == -1)
+ set_tag_idx = encap_idx;
+ }
+ break;
+ case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:
+ case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP:
+ encap_idx = action_idx;
+ if (encap_idx < sample_action_pos &&
+ push_vlan_idx == -1)
+ set_tag_idx = encap_idx;
+ break;
+ case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
+ case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
+ push_vlan_idx = action_idx;
+ if (push_vlan_idx < sample_action_pos)
+ set_tag_idx = action_idx;
+ break;
+ default:
+ break;
+ }
+ action_idx++;
+ }
+ }
+ /* Prepare the actions for prefix and suffix flow. */
if (qrss_action_pos >= 0 && qrss_action_pos < sample_action_pos) {
index = qrss_action_pos;
/* Put the preceding the Queue/RSS action into prefix flow. */
memcpy(actions_sfx, actions + qrss_action_pos,
sizeof(struct rte_flow_action));
actions_sfx++;
+ } else if (add_tag && set_tag_idx >= 0) {
+ if (set_tag_idx > 0)
+ memcpy(actions_pre, actions,
+ sizeof(struct rte_flow_action) * set_tag_idx);
+ memcpy(actions_pre + set_tag_idx + 1, actions + set_tag_idx,
+ sizeof(struct rte_flow_action) *
+ (sample_action_pos - set_tag_idx));
+ index = sample_action_pos;
} else {
index = sample_action_pos;
if (index != 0)
append_index++;
set_tag = (void *)(actions_pre + actions_n + append_index);
ret = mlx5_flow_get_reg_id(dev, MLX5_SAMPLE_ID, 0, error);
+ /* Trust VF/SF on CX5 not supported meter so that the reserved
+ * metadata regC is REG_NON, back to use application tag
+ * index 0.
+ */
+ if (unlikely(ret == REG_NON))
+ ret = mlx5_flow_get_reg_id(dev, MLX5_APP_TAG, 0, error);
if (ret < 0)
return ret;
mlx5_ipool_malloc(priv->sh->ipool
.data = tag_id,
};
/* Prepare the suffix subflow items. */
+ for (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) {
+ if (items->type == RTE_FLOW_ITEM_TYPE_PORT_ID) {
+ memcpy(sfx_items, items, sizeof(*sfx_items));
+ sfx_items++;
+ }
+ }
tag_spec = (void *)(sfx_items + SAMPLE_SUFFIX_ITEM);
tag_spec->data = tag_id;
tag_spec->id = set_tag->id;
RTE_FLOW_ITEM_TYPE_END,
};
/* Prepare the tag action in prefix subflow. */
- actions_pre[index++] =
+ set_tag_idx = (set_tag_idx == -1) ? index : set_tag_idx;
+ actions_pre[set_tag_idx] =
(struct rte_flow_action){
.type = (enum rte_flow_action_type)
MLX5_RTE_FLOW_ACTION_TYPE_TAG,
.conf = set_tag,
};
+ /* Update next sample position due to add one tag action */
+ index += 1;
}
+ /* Copy the sample action into prefix flow. */
memcpy(actions_pre + index, actions + sample_action_pos,
sizeof(struct rte_flow_action));
index += 1;
if (!fm->def_policy && !is_mtr_hierarchy &&
(!has_modify || !fm->drop_cnt))
set_mtr_reg = false;
- /* Prefix actions: meter, decap, encap, tag, jump, end. */
- act_size = sizeof(struct rte_flow_action) * (actions_n + 6) +
+ /* Prefix actions: meter, decap, encap, tag, jump, end, cnt. */
+#define METER_PREFIX_ACTION 7
+ act_size = (sizeof(struct rte_flow_action) *
+ (actions_n + METER_PREFIX_ACTION)) +
sizeof(struct mlx5_rte_flow_action_set_tag);
/* Suffix items: tag, vlan, port id, end. */
#define METER_SUFFIX_ITEM 4
jump_table = attr->group * MLX5_FLOW_TABLE_FACTOR +
next_ft_step;
pre_actions = sfx_actions + actions_n;
- tag_id = flow_sample_split_prep(dev, add_tag, sfx_items,
+ tag_id = flow_sample_split_prep(dev, add_tag, items, sfx_items,
actions, sfx_actions,
pre_actions, actions_n,
sample_action_pos,
struct rte_flow_error *error)
{
static const char err_msg[] = "flex item creation unsupported";
+ struct mlx5_priv *priv = dev->data->dev_private;
struct rte_flow_attr attr = { .transfer = 0 };
const struct mlx5_flow_driver_ops *fops =
flow_get_drv_ops(flow_get_drv_type(dev, &attr));
+ if (!priv->pci_dev) {
+ rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+ "create flex item on PF only");
+ return NULL;
+ }
+ switch (priv->pci_dev->id.device_id) {
+ case PCI_DEVICE_ID_MELLANOX_CONNECTX6DXBF:
+ case PCI_DEVICE_ID_MELLANOX_CONNECTX7BF:
+ break;
+ default:
+ rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+ "flex item available on BlueField ports only");
+ return NULL;
+ }
if (!fops->item_create) {
DRV_LOG(ERR, "port %u %s.", dev->data->port_id, err_msg);
rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,