@@ -87,6 +87,7 @@ vlan = Y
vxlan = Y
vxlan_gpe = Y
represented_port = Y
+port_affinity = Y
[rte_flow actions]
age = I
@@ -106,6 +106,7 @@ Features
- Sub-Function representors.
- Sub-Function.
- Matching on represented port.
+- Matching on port affinity.
Limitations
@@ -595,10 +596,11 @@ Limitations
- key
- sequence
- Matching on checksum and sequence needs MLNX_OFED 5.6+.
+- Matching on checksum and sequence needs MLNX_OFED 5.6+.
- The NIC egress flow rules on representor port are not supported.
+- Match on port affinity is supported NIC ingress flow in group 0 only.
Statistics
----------
@@ -1406,6 +1406,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
sh->lag_rx_port_affinity_en = 1;
DRV_LOG(DEBUG, "LAG Rx Port Affinity enabled");
}
+ priv->num_lag_ports = hca_attr->num_lag_ports;
+ DRV_LOG(DEBUG, "The number of lag ports is %d", priv->num_lag_ports);
}
/* Process parameters and store port configuration on priv structure. */
err = mlx5_port_args_config(priv, mkvlist, &priv->config);
@@ -1739,6 +1739,7 @@ struct mlx5_priv {
unsigned int mtr_reg_share:1; /* Whether support meter REG_C share. */
unsigned int lb_used:1; /* Loopback queue is referred to. */
uint32_t mark_enabled:1; /* If mark action is enabled on rxqs. */
+ uint32_t num_lag_ports:4; /* Number of ports can be bonded. */
uint16_t domain_id; /* Switch domain identifier. */
uint16_t vport_id; /* Associated VF vport index (if any). */
uint32_t vport_meta_tag; /* Used for vport index match ove VF LAG. */
@@ -264,6 +264,9 @@ enum mlx5_feature_name {
/* IPSEC syndrome item */
#define MLX5_FLOW_ITEM_IPSEC_SYNDROME (UINT64_C(1) << 46)
+/* Port affinity item */
+#define MLX5_FLOW_ITEM_PORT_AFFINITY (UINT64_C(1) << 47)
+
/* Outer Masks. */
#define MLX5_FLOW_LAYER_OUTER_L3 \
(MLX5_FLOW_LAYER_OUTER_L3_IPV4 | MLX5_FLOW_LAYER_OUTER_L3_IPV6)
@@ -3888,6 +3888,74 @@ flow_dv_validate_item_ipsec_syndrome(struct rte_eth_dev *dev,
return 0;
}
+/**
+ * Validate Port affinity item.
+ *
+ * @param[in] dev
+ * Pointer to the rte_eth_dev structure.
+ * @param[in] item
+ * Item specification.
+ * @param[in] attr
+ * Attributes of flow that includes this item.
+ * @param[out] error
+ * Pointer to error structure.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+flow_dv_validate_item_port_affinity(struct rte_eth_dev *dev,
+ const struct rte_flow_item *item,
+ const struct rte_flow_attr *attr,
+ struct rte_flow_error *error)
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ const struct rte_flow_item_port_affinity *spec = item->spec;
+ const struct rte_flow_item_port_affinity *mask = item->mask;
+ struct rte_flow_item_port_affinity nic_mask = {
+ .affinity = UINT8_MAX
+ };
+ int ret;
+
+ if (!priv->sh->lag_rx_port_affinity_en)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM, NULL,
+ "Unsupported port affinity with Older FW");
+ if (!attr->ingress || attr->transfer || attr->group)
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+ item->spec,
+ "port affinity is supported with NIC-RX on Root");
+ if (!spec)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+ item->spec,
+ "data cannot be empty");
+ if (spec->affinity == 0)
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+ item->spec,
+ "zero affinity number not supported");
+ if (spec->affinity > priv->num_lag_ports)
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+ item->spec,
+ "exceed max affinity number in lag ports");
+ if (!mask)
+ mask = &rte_flow_item_port_affinity_mask;
+ if (!mask->affinity)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM_SPEC, NULL,
+ "mask cannot be zero");
+ ret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask,
+ (const uint8_t *)&nic_mask,
+ sizeof(struct rte_flow_item_port_affinity),
+ MLX5_ITEM_RANGE_NOT_ACCEPTED, error);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
int
flow_dv_encap_decap_match_cb(void *tool_ctx __rte_unused,
struct mlx5_list_entry *entry, void *cb_ctx)
@@ -7679,6 +7747,13 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
return ret;
last_item = MLX5_FLOW_ITEM_IPSEC_SYNDROME;
break;
+ case RTE_FLOW_ITEM_TYPE_PORT_AFFINITY:
+ ret = flow_dv_validate_item_port_affinity(dev, items,
+ attr, error);
+ if (ret < 0)
+ return ret;
+ last_item = MLX5_FLOW_ITEM_PORT_AFFINITY;
+ break;
default:
return rte_flow_error_set(error, ENOTSUP,
RTE_FLOW_ERROR_TYPE_ITEM,
@@ -10978,6 +11053,22 @@ flow_dv_translate_item_ipsec_syndrome(void *key,
spec->syndrome & mask->syndrome);
}
+static void
+flow_dv_translate_item_port_affinity(void *key,
+ const struct rte_flow_item *item,
+ uint32_t key_type)
+{
+ const struct rte_flow_item_port_affinity *affinity_v;
+ const struct rte_flow_item_port_affinity *affinity_m;
+ void *misc_v;
+
+ MLX5_ITEM_UPDATE(item, key_type, affinity_v, affinity_m,
+ &rte_flow_item_port_affinity_mask);
+ misc_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters);
+ MLX5_SET(fte_match_set_misc, misc_v, lag_rx_port_affinity,
+ affinity_v->affinity & affinity_m->affinity);
+}
+
static uint32_t matcher_zero[MLX5_ST_SZ_DW(fte_match_param)] = { 0 };
#define HEADER_IS_ZERO(match_criteria, headers) \
@@ -13779,6 +13870,10 @@ flow_dv_translate_items(struct rte_eth_dev *dev,
flow_dv_translate_item_ipsec_syndrome(key, items, key_type);
last_item = MLX5_FLOW_ITEM_IPSEC_SYNDROME;
break;
+ case RTE_FLOW_ITEM_TYPE_PORT_AFFINITY:
+ flow_dv_translate_item_port_affinity(key, items, key_type);
+ last_item = MLX5_FLOW_ITEM_PORT_AFFINITY;
+ break;
default:
break;
}
@@ -5015,6 +5015,20 @@ flow_hw_pattern_validate(struct rte_eth_dev *dev,
"Unsupported meter color register");
break;
}
+ case RTE_FLOW_ITEM_TYPE_PORT_AFFINITY:
+ {
+ if (!priv->sh->lag_rx_port_affinity_en)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM, NULL,
+ "Unsupported port affinity with Older FW");
+ if (!attr->ingress || attr->transfer)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM, NULL,
+ "Port affinity item not supported"
+ " with egress or transfer"
+ " attribute");
+ break;
+ }
case RTE_FLOW_ITEM_TYPE_VOID:
case RTE_FLOW_ITEM_TYPE_ETH:
case RTE_FLOW_ITEM_TYPE_VLAN: