net/mlx5: add internal tag item and action
This commit introduce the setting and matching on registers. This item and and action will be used with number of different features like hairpin, metering, metadata. Signed-off-by: Ori Kam <orika@mellanox.com> Acked-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
This commit is contained in:
parent
63bd16292c
commit
70d84dc797
@ -316,6 +316,58 @@ static struct mlx5_flow_tunnel_info tunnels_info[] = {
|
||||
},
|
||||
};
|
||||
|
||||
enum mlx5_feature_name {
|
||||
MLX5_HAIRPIN_RX,
|
||||
MLX5_HAIRPIN_TX,
|
||||
MLX5_APPLICATION,
|
||||
};
|
||||
|
||||
/**
|
||||
* Translate tag ID to register.
|
||||
*
|
||||
* @param[in] dev
|
||||
* Pointer to the Ethernet device structure.
|
||||
* @param[in] feature
|
||||
* The feature that request the register.
|
||||
* @param[in] id
|
||||
* The request register ID.
|
||||
* @param[out] error
|
||||
* Error description in case of any.
|
||||
*
|
||||
* @return
|
||||
* The request register on success, a negative errno
|
||||
* value otherwise and rte_errno is set.
|
||||
*/
|
||||
__rte_unused
|
||||
static enum modify_reg flow_get_reg_id(struct rte_eth_dev *dev,
|
||||
enum mlx5_feature_name feature,
|
||||
uint32_t id,
|
||||
struct rte_flow_error *error)
|
||||
{
|
||||
static enum modify_reg id2reg[] = {
|
||||
[0] = REG_A,
|
||||
[1] = REG_C_2,
|
||||
[2] = REG_C_3,
|
||||
[3] = REG_C_4,
|
||||
[4] = REG_B,};
|
||||
|
||||
dev = (void *)dev;
|
||||
switch (feature) {
|
||||
case MLX5_HAIRPIN_RX:
|
||||
return REG_B;
|
||||
case MLX5_HAIRPIN_TX:
|
||||
return REG_A;
|
||||
case MLX5_APPLICATION:
|
||||
if (id > 4)
|
||||
return rte_flow_error_set(error, EINVAL,
|
||||
RTE_FLOW_ERROR_TYPE_ITEM,
|
||||
NULL, "invalid tag id");
|
||||
return id2reg[id];
|
||||
}
|
||||
return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
|
||||
NULL, "invalid feature name");
|
||||
}
|
||||
|
||||
/**
|
||||
* Discover the maximum number of priority available.
|
||||
*
|
||||
|
@ -27,6 +27,43 @@
|
||||
#include "mlx5.h"
|
||||
#include "mlx5_prm.h"
|
||||
|
||||
enum modify_reg {
|
||||
REG_A,
|
||||
REG_B,
|
||||
REG_C_0,
|
||||
REG_C_1,
|
||||
REG_C_2,
|
||||
REG_C_3,
|
||||
REG_C_4,
|
||||
REG_C_5,
|
||||
REG_C_6,
|
||||
REG_C_7,
|
||||
};
|
||||
|
||||
/* Private rte flow items. */
|
||||
enum mlx5_rte_flow_item_type {
|
||||
MLX5_RTE_FLOW_ITEM_TYPE_END = INT_MIN,
|
||||
MLX5_RTE_FLOW_ITEM_TYPE_TAG,
|
||||
};
|
||||
|
||||
/* Private rte flow actions. */
|
||||
enum mlx5_rte_flow_action_type {
|
||||
MLX5_RTE_FLOW_ACTION_TYPE_END = INT_MIN,
|
||||
MLX5_RTE_FLOW_ACTION_TYPE_TAG,
|
||||
};
|
||||
|
||||
/* Matches on selected register. */
|
||||
struct mlx5_rte_flow_item_tag {
|
||||
uint16_t id;
|
||||
rte_be32_t data;
|
||||
};
|
||||
|
||||
/* Modify selected register. */
|
||||
struct mlx5_rte_flow_action_set_tag {
|
||||
uint16_t id;
|
||||
rte_be32_t data;
|
||||
};
|
||||
|
||||
/* Pattern outer Layer bits. */
|
||||
#define MLX5_FLOW_LAYER_OUTER_L2 (1u << 0)
|
||||
#define MLX5_FLOW_LAYER_OUTER_L3_IPV4 (1u << 1)
|
||||
@ -53,11 +90,12 @@
|
||||
/* General pattern items bits. */
|
||||
#define MLX5_FLOW_ITEM_METADATA (1u << 16)
|
||||
#define MLX5_FLOW_ITEM_PORT_ID (1u << 17)
|
||||
#define MLX5_FLOW_ITEM_TAG (1u << 18)
|
||||
|
||||
/* Pattern MISC bits. */
|
||||
#define MLX5_FLOW_LAYER_ICMP (1u << 18)
|
||||
#define MLX5_FLOW_LAYER_ICMP6 (1u << 19)
|
||||
#define MLX5_FLOW_LAYER_GRE_KEY (1u << 20)
|
||||
#define MLX5_FLOW_LAYER_ICMP (1u << 19)
|
||||
#define MLX5_FLOW_LAYER_ICMP6 (1u << 20)
|
||||
#define MLX5_FLOW_LAYER_GRE_KEY (1u << 21)
|
||||
|
||||
/* Pattern tunnel Layer bits (continued). */
|
||||
#define MLX5_FLOW_LAYER_IPIP (1u << 21)
|
||||
@ -141,6 +179,7 @@
|
||||
#define MLX5_FLOW_ACTION_DEC_TCP_SEQ (1u << 29)
|
||||
#define MLX5_FLOW_ACTION_INC_TCP_ACK (1u << 30)
|
||||
#define MLX5_FLOW_ACTION_DEC_TCP_ACK (1u << 31)
|
||||
#define MLX5_FLOW_ACTION_SET_TAG (1ull << 32)
|
||||
|
||||
#define MLX5_FLOW_FATE_ACTIONS \
|
||||
(MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_QUEUE | \
|
||||
@ -174,7 +213,8 @@
|
||||
MLX5_FLOW_ACTION_DEC_TCP_SEQ | \
|
||||
MLX5_FLOW_ACTION_INC_TCP_ACK | \
|
||||
MLX5_FLOW_ACTION_DEC_TCP_ACK | \
|
||||
MLX5_FLOW_ACTION_OF_SET_VLAN_VID)
|
||||
MLX5_FLOW_ACTION_OF_SET_VLAN_VID | \
|
||||
MLX5_FLOW_ACTION_SET_TAG)
|
||||
|
||||
#define MLX5_FLOW_VLAN_ACTIONS (MLX5_FLOW_ACTION_OF_POP_VLAN | \
|
||||
MLX5_FLOW_ACTION_OF_PUSH_VLAN)
|
||||
|
@ -724,6 +724,59 @@ flow_dv_convert_action_modify_tcp_ack
|
||||
MLX5_MODIFICATION_TYPE_ADD, error);
|
||||
}
|
||||
|
||||
static enum mlx5_modification_field reg_to_field[] = {
|
||||
[REG_A] = MLX5_MODI_META_DATA_REG_A,
|
||||
[REG_B] = MLX5_MODI_META_DATA_REG_B,
|
||||
[REG_C_0] = MLX5_MODI_META_REG_C_0,
|
||||
[REG_C_1] = MLX5_MODI_META_REG_C_1,
|
||||
[REG_C_2] = MLX5_MODI_META_REG_C_2,
|
||||
[REG_C_3] = MLX5_MODI_META_REG_C_3,
|
||||
[REG_C_4] = MLX5_MODI_META_REG_C_4,
|
||||
[REG_C_5] = MLX5_MODI_META_REG_C_5,
|
||||
[REG_C_6] = MLX5_MODI_META_REG_C_6,
|
||||
[REG_C_7] = MLX5_MODI_META_REG_C_7,
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert register set to DV specification.
|
||||
*
|
||||
* @param[in,out] resource
|
||||
* Pointer to the modify-header resource.
|
||||
* @param[in] action
|
||||
* Pointer to action specification.
|
||||
* @param[out] error
|
||||
* Pointer to the error structure.
|
||||
*
|
||||
* @return
|
||||
* 0 on success, a negative errno value otherwise and rte_errno is set.
|
||||
*/
|
||||
static int
|
||||
flow_dv_convert_action_set_reg
|
||||
(struct mlx5_flow_dv_modify_hdr_resource *resource,
|
||||
const struct rte_flow_action *action,
|
||||
struct rte_flow_error *error)
|
||||
{
|
||||
const struct mlx5_rte_flow_action_set_tag *conf = (action->conf);
|
||||
struct mlx5_modification_cmd *actions = resource->actions;
|
||||
uint32_t i = resource->actions_num;
|
||||
|
||||
if (i >= MLX5_MODIFY_NUM)
|
||||
return rte_flow_error_set(error, EINVAL,
|
||||
RTE_FLOW_ERROR_TYPE_ACTION, NULL,
|
||||
"too many items to modify");
|
||||
actions[i].action_type = MLX5_MODIFICATION_TYPE_SET;
|
||||
actions[i].field = reg_to_field[conf->id];
|
||||
actions[i].data0 = rte_cpu_to_be_32(actions[i].data0);
|
||||
actions[i].data1 = conf->data;
|
||||
++i;
|
||||
resource->actions_num = i;
|
||||
if (!resource->actions_num)
|
||||
return rte_flow_error_set(error, EINVAL,
|
||||
RTE_FLOW_ERROR_TYPE_ACTION, NULL,
|
||||
"invalid modification flow item");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate META item.
|
||||
*
|
||||
@ -4719,6 +4772,94 @@ flow_dv_translate_item_meta_vport(void *matcher, void *key,
|
||||
MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_c_0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add tag item to matcher
|
||||
*
|
||||
* @param[in, out] matcher
|
||||
* Flow matcher.
|
||||
* @param[in, out] key
|
||||
* Flow matcher value.
|
||||
* @param[in] item
|
||||
* Flow pattern to translate.
|
||||
*/
|
||||
static void
|
||||
flow_dv_translate_item_tag(void *matcher, void *key,
|
||||
const struct rte_flow_item *item)
|
||||
{
|
||||
void *misc2_m =
|
||||
MLX5_ADDR_OF(fte_match_param, matcher, misc_parameters_2);
|
||||
void *misc2_v =
|
||||
MLX5_ADDR_OF(fte_match_param, key, misc_parameters_2);
|
||||
const struct mlx5_rte_flow_item_tag *tag_v = item->spec;
|
||||
const struct mlx5_rte_flow_item_tag *tag_m = item->mask;
|
||||
enum modify_reg reg = tag_v->id;
|
||||
rte_be32_t value = tag_v->data;
|
||||
rte_be32_t mask = tag_m->data;
|
||||
|
||||
switch (reg) {
|
||||
case REG_A:
|
||||
MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_a,
|
||||
rte_be_to_cpu_32(mask));
|
||||
MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_a,
|
||||
rte_be_to_cpu_32(value));
|
||||
break;
|
||||
case REG_B:
|
||||
MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_b,
|
||||
rte_be_to_cpu_32(mask));
|
||||
MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_b,
|
||||
rte_be_to_cpu_32(value));
|
||||
break;
|
||||
case REG_C_0:
|
||||
MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_c_0,
|
||||
rte_be_to_cpu_32(mask));
|
||||
MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_c_0,
|
||||
rte_be_to_cpu_32(value));
|
||||
break;
|
||||
case REG_C_1:
|
||||
MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_c_1,
|
||||
rte_be_to_cpu_32(mask));
|
||||
MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_c_1,
|
||||
rte_be_to_cpu_32(value));
|
||||
break;
|
||||
case REG_C_2:
|
||||
MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_c_2,
|
||||
rte_be_to_cpu_32(mask));
|
||||
MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_c_2,
|
||||
rte_be_to_cpu_32(value));
|
||||
break;
|
||||
case REG_C_3:
|
||||
MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_c_3,
|
||||
rte_be_to_cpu_32(mask));
|
||||
MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_c_3,
|
||||
rte_be_to_cpu_32(value));
|
||||
break;
|
||||
case REG_C_4:
|
||||
MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_c_4,
|
||||
rte_be_to_cpu_32(mask));
|
||||
MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_c_4,
|
||||
rte_be_to_cpu_32(value));
|
||||
break;
|
||||
case REG_C_5:
|
||||
MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_c_5,
|
||||
rte_be_to_cpu_32(mask));
|
||||
MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_c_5,
|
||||
rte_be_to_cpu_32(value));
|
||||
break;
|
||||
case REG_C_6:
|
||||
MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_c_6,
|
||||
rte_be_to_cpu_32(mask));
|
||||
MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_c_6,
|
||||
rte_be_to_cpu_32(value));
|
||||
break;
|
||||
case REG_C_7:
|
||||
MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_c_7,
|
||||
rte_be_to_cpu_32(mask));
|
||||
MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_c_7,
|
||||
rte_be_to_cpu_32(value));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add source vport match to the specified matcher.
|
||||
*
|
||||
@ -5305,8 +5446,9 @@ flow_dv_translate(struct rte_eth_dev *dev,
|
||||
struct mlx5_flow_tbl_resource *tbl;
|
||||
uint32_t port_id = 0;
|
||||
struct mlx5_flow_dv_port_id_action_resource port_id_resource;
|
||||
int action_type = actions->type;
|
||||
|
||||
switch (actions->type) {
|
||||
switch (action_type) {
|
||||
case RTE_FLOW_ACTION_TYPE_VOID:
|
||||
break;
|
||||
case RTE_FLOW_ACTION_TYPE_PORT_ID:
|
||||
@ -5621,6 +5763,12 @@ flow_dv_translate(struct rte_eth_dev *dev,
|
||||
MLX5_FLOW_ACTION_INC_TCP_ACK :
|
||||
MLX5_FLOW_ACTION_DEC_TCP_ACK;
|
||||
break;
|
||||
case MLX5_RTE_FLOW_ACTION_TYPE_TAG:
|
||||
if (flow_dv_convert_action_set_reg(&res, actions,
|
||||
error))
|
||||
return -rte_errno;
|
||||
action_flags |= MLX5_FLOW_ACTION_SET_TAG;
|
||||
break;
|
||||
case RTE_FLOW_ACTION_TYPE_END:
|
||||
actions_end = true;
|
||||
if (action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS) {
|
||||
@ -5645,8 +5793,9 @@ flow_dv_translate(struct rte_eth_dev *dev,
|
||||
flow->actions = action_flags;
|
||||
for (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) {
|
||||
int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL);
|
||||
int item_type = items->type;
|
||||
|
||||
switch (items->type) {
|
||||
switch (item_type) {
|
||||
case RTE_FLOW_ITEM_TYPE_PORT_ID:
|
||||
flow_dv_translate_item_port_id(dev, match_mask,
|
||||
match_value, items);
|
||||
@ -5797,6 +5946,11 @@ flow_dv_translate(struct rte_eth_dev *dev,
|
||||
items, tunnel);
|
||||
last_item = MLX5_FLOW_LAYER_ICMP6;
|
||||
break;
|
||||
case MLX5_RTE_FLOW_ITEM_TYPE_TAG:
|
||||
flow_dv_translate_item_tag(match_mask, match_value,
|
||||
items);
|
||||
last_item = MLX5_FLOW_ITEM_TAG;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -628,7 +628,8 @@ struct mlx5_ifc_fte_match_set_misc2_bits {
|
||||
u8 metadata_reg_c_1[0x20];
|
||||
u8 metadata_reg_c_0[0x20];
|
||||
u8 metadata_reg_a[0x20];
|
||||
u8 reserved_at_1a0[0x60];
|
||||
u8 metadata_reg_b[0x20];
|
||||
u8 reserved_at_1c0[0x40];
|
||||
};
|
||||
|
||||
struct mlx5_ifc_fte_match_set_misc3_bits {
|
||||
|
Loading…
Reference in New Issue
Block a user