Commit 64c78942 authored by Yevgeny Kliteynik's avatar Yevgeny Kliteynik Committed by Saeed Mahameed

net/mlx5: DR, Move action apply logic to dr_ste

The action apply logic is device specific per STE version,
moving to the STE layer will allow implementing it for
both devices while keeping DR upper layers the same.
Signed-off-by: default avatarAlex Vesker <valex@nvidia.com>
Signed-off-by: default avatarYevgeny Kliteynik <kliteyn@nvidia.com>
Reviewed-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent 40ca842c
......@@ -348,28 +348,6 @@ static const struct dr_action_modify_field_conv dr_action_conv_arr[] = {
},
};
#define MAX_VLANS 2
struct dr_action_vlan_info {
int count;
u32 headers[MAX_VLANS];
};
struct dr_action_apply_attr {
u32 modify_index;
u16 modify_actions;
u32 decap_index;
u16 decap_actions;
u8 decap_with_vlan:1;
u64 final_icm_addr;
u32 flow_tag;
u32 ctr_id;
u16 gvmi;
u16 hit_gvmi;
u32 reformat_id;
u32 reformat_size;
struct dr_action_vlan_info vlans;
};
static int
dr_action_reformat_to_action_type(enum mlx5dr_action_reformat_type reformat_type,
enum mlx5dr_action_type *action_type)
......@@ -394,141 +372,6 @@ dr_action_reformat_to_action_type(enum mlx5dr_action_reformat_type reformat_type
return 0;
}
static void dr_actions_init_next_ste(u8 **last_ste,
u32 *added_stes,
enum mlx5dr_ste_entry_type entry_type,
u16 gvmi)
{
(*added_stes)++;
*last_ste += DR_STE_SIZE;
mlx5dr_ste_init(*last_ste, MLX5DR_STE_LU_TYPE_DONT_CARE, entry_type, gvmi);
}
static void dr_actions_apply_tx(struct mlx5dr_domain *dmn,
u8 *action_type_set,
u8 *last_ste,
struct dr_action_apply_attr *attr,
u32 *added_stes)
{
bool encap = action_type_set[DR_ACTION_TYP_L2_TO_TNL_L2] ||
action_type_set[DR_ACTION_TYP_L2_TO_TNL_L3];
/* We want to make sure the modify header comes before L2
* encapsulation. The reason for that is that we support
* modify headers for outer headers only
*/
if (action_type_set[DR_ACTION_TYP_MODIFY_HDR]) {
mlx5dr_ste_set_entry_type(last_ste, MLX5DR_STE_TYPE_MODIFY_PKT);
mlx5dr_ste_set_rewrite_actions(last_ste,
attr->modify_actions,
attr->modify_index);
}
if (action_type_set[DR_ACTION_TYP_PUSH_VLAN]) {
int i;
for (i = 0; i < attr->vlans.count; i++) {
if (i || action_type_set[DR_ACTION_TYP_MODIFY_HDR])
dr_actions_init_next_ste(&last_ste,
added_stes,
MLX5DR_STE_TYPE_TX,
attr->gvmi);
mlx5dr_ste_set_tx_push_vlan(last_ste,
attr->vlans.headers[i],
encap);
}
}
if (encap) {
/* Modify header and encapsulation require a different STEs.
* Since modify header STE format doesn't support encapsulation
* tunneling_action.
*/
if (action_type_set[DR_ACTION_TYP_MODIFY_HDR] ||
action_type_set[DR_ACTION_TYP_PUSH_VLAN])
dr_actions_init_next_ste(&last_ste,
added_stes,
MLX5DR_STE_TYPE_TX,
attr->gvmi);
mlx5dr_ste_set_tx_encap(last_ste,
attr->reformat_id,
attr->reformat_size,
action_type_set[DR_ACTION_TYP_L2_TO_TNL_L3]);
/* Whenever prio_tag_required enabled, we can be sure that the
* previous table (ACL) already push vlan to our packet,
* And due to HW limitation we need to set this bit, otherwise
* push vlan + reformat will not work.
*/
if (MLX5_CAP_GEN(dmn->mdev, prio_tag_required))
mlx5dr_ste_set_go_back_bit(last_ste);
}
if (action_type_set[DR_ACTION_TYP_CTR])
mlx5dr_ste_set_counter_id(last_ste, attr->ctr_id);
}
static void dr_actions_apply_rx(u8 *action_type_set,
u8 *last_ste,
struct dr_action_apply_attr *attr,
u32 *added_stes)
{
if (action_type_set[DR_ACTION_TYP_CTR])
mlx5dr_ste_set_counter_id(last_ste, attr->ctr_id);
if (action_type_set[DR_ACTION_TYP_TNL_L3_TO_L2]) {
mlx5dr_ste_set_entry_type(last_ste, MLX5DR_STE_TYPE_MODIFY_PKT);
mlx5dr_ste_set_rx_decap_l3(last_ste, attr->decap_with_vlan);
mlx5dr_ste_set_rewrite_actions(last_ste,
attr->decap_actions,
attr->decap_index);
}
if (action_type_set[DR_ACTION_TYP_TNL_L2_TO_L2])
mlx5dr_ste_set_rx_decap(last_ste);
if (action_type_set[DR_ACTION_TYP_POP_VLAN]) {
int i;
for (i = 0; i < attr->vlans.count; i++) {
if (i ||
action_type_set[DR_ACTION_TYP_TNL_L2_TO_L2] ||
action_type_set[DR_ACTION_TYP_TNL_L3_TO_L2])
dr_actions_init_next_ste(&last_ste,
added_stes,
MLX5DR_STE_TYPE_RX,
attr->gvmi);
mlx5dr_ste_set_rx_pop_vlan(last_ste);
}
}
if (action_type_set[DR_ACTION_TYP_MODIFY_HDR]) {
if (mlx5dr_ste_get_entry_type(last_ste) == MLX5DR_STE_TYPE_MODIFY_PKT)
dr_actions_init_next_ste(&last_ste,
added_stes,
MLX5DR_STE_TYPE_MODIFY_PKT,
attr->gvmi);
else
mlx5dr_ste_set_entry_type(last_ste, MLX5DR_STE_TYPE_MODIFY_PKT);
mlx5dr_ste_set_rewrite_actions(last_ste,
attr->modify_actions,
attr->modify_index);
}
if (action_type_set[DR_ACTION_TYP_TAG]) {
if (mlx5dr_ste_get_entry_type(last_ste) == MLX5DR_STE_TYPE_MODIFY_PKT)
dr_actions_init_next_ste(&last_ste,
added_stes,
MLX5DR_STE_TYPE_RX,
attr->gvmi);
mlx5dr_ste_rx_set_flow_tag(last_ste, attr->flow_tag);
}
}
/* Apply the actions on the rule STE array starting from the last_ste.
* Actions might require more than one STE, new_num_stes will return
* the new size of the STEs array, rule with actions.
......@@ -537,21 +380,19 @@ static void dr_actions_apply(struct mlx5dr_domain *dmn,
enum mlx5dr_ste_entry_type ste_type,
u8 *action_type_set,
u8 *last_ste,
struct dr_action_apply_attr *attr,
struct mlx5dr_ste_actions_attr *attr,
u32 *new_num_stes)
{
u32 added_stes = 0;
if (ste_type == MLX5DR_STE_TYPE_RX)
dr_actions_apply_rx(action_type_set, last_ste, attr, &added_stes);
mlx5dr_ste_set_actions_rx(dmn, action_type_set,
last_ste, attr, &added_stes);
else
dr_actions_apply_tx(dmn, action_type_set, last_ste, attr, &added_stes);
mlx5dr_ste_set_actions_tx(dmn, action_type_set,
last_ste, attr, &added_stes);
last_ste += added_stes * DR_STE_SIZE;
*new_num_stes += added_stes;
mlx5dr_ste_set_hit_gvmi(last_ste, attr->hit_gvmi);
mlx5dr_ste_set_hit_addr(last_ste, attr->final_icm_addr, 1);
}
static enum dr_action_domain
......@@ -643,9 +484,9 @@ int mlx5dr_actions_build_ste_arr(struct mlx5dr_matcher *matcher,
bool rx_rule = nic_dmn->ste_type == MLX5DR_STE_TYPE_RX;
struct mlx5dr_domain *dmn = matcher->tbl->dmn;
u8 action_type_set[DR_ACTION_TYP_MAX] = {};
struct mlx5dr_ste_actions_attr attr = {};
struct mlx5dr_action *dest_action = NULL;
u32 state = DR_ACTION_STATE_NO_ACTION;
struct dr_action_apply_attr attr = {};
enum dr_action_domain action_domain;
bool recalc_cs_required = false;
u8 *last_ste;
......@@ -756,12 +597,12 @@ int mlx5dr_actions_build_ste_arr(struct mlx5dr_matcher *matcher,
}
break;
case DR_ACTION_TYP_POP_VLAN:
max_actions_type = MAX_VLANS;
max_actions_type = MLX5DR_MAX_VLANS;
attr.vlans.count++;
break;
case DR_ACTION_TYP_PUSH_VLAN:
max_actions_type = MAX_VLANS;
if (attr.vlans.count == MAX_VLANS)
max_actions_type = MLX5DR_MAX_VLANS;
if (attr.vlans.count == MLX5DR_MAX_VLANS)
return -EINVAL;
attr.vlans.headers[attr.vlans.count++] = action->push_vlan.vlan_hdr;
......
......@@ -220,35 +220,47 @@ static inline void mlx5dr_htbl_get(struct mlx5dr_ste_htbl *htbl)
/* STE utils */
u32 mlx5dr_ste_calc_hash_index(u8 *hw_ste_p, struct mlx5dr_ste_htbl *htbl);
void mlx5dr_ste_init(u8 *hw_ste_p, u16 lu_type, u8 entry_type, u16 gvmi);
void mlx5dr_ste_always_hit_htbl(struct mlx5dr_ste *ste,
struct mlx5dr_ste_htbl *next_htbl);
void mlx5dr_ste_set_miss_addr(u8 *hw_ste, u64 miss_addr);
u64 mlx5dr_ste_get_miss_addr(u8 *hw_ste);
void mlx5dr_ste_set_hit_gvmi(u8 *hw_ste_p, u16 gvmi);
void mlx5dr_ste_set_hit_addr(u8 *hw_ste, u64 icm_addr, u32 ht_size);
void mlx5dr_ste_always_miss_addr(struct mlx5dr_ste *ste, u64 miss_addr);
void mlx5dr_ste_set_bit_mask(u8 *hw_ste_p, u8 *bit_mask);
bool mlx5dr_ste_is_last_in_rule(struct mlx5dr_matcher_rx_tx *nic_matcher,
u8 ste_location);
void mlx5dr_ste_rx_set_flow_tag(u8 *hw_ste_p, u32 flow_tag);
void mlx5dr_ste_set_counter_id(u8 *hw_ste_p, u32 ctr_id);
void mlx5dr_ste_set_tx_encap(void *hw_ste_p, u32 reformat_id,
int size, bool encap_l3);
void mlx5dr_ste_set_rx_decap(u8 *hw_ste_p);
void mlx5dr_ste_set_rx_decap_l3(u8 *hw_ste_p, bool vlan);
void mlx5dr_ste_set_rx_pop_vlan(u8 *hw_ste_p);
void mlx5dr_ste_set_tx_push_vlan(u8 *hw_ste_p, u32 vlan_tpid_pcp_dei_vid,
bool go_back);
void mlx5dr_ste_set_entry_type(u8 *hw_ste_p, u8 entry_type);
u8 mlx5dr_ste_get_entry_type(u8 *hw_ste_p);
void mlx5dr_ste_set_rewrite_actions(u8 *hw_ste_p, u16 num_of_actions,
u32 re_write_index);
void mlx5dr_ste_set_go_back_bit(u8 *hw_ste_p);
u64 mlx5dr_ste_get_icm_addr(struct mlx5dr_ste *ste);
u64 mlx5dr_ste_get_mr_addr(struct mlx5dr_ste *ste);
struct list_head *mlx5dr_ste_get_miss_list(struct mlx5dr_ste *ste);
#define MLX5DR_MAX_VLANS 2
struct mlx5dr_ste_actions_attr {
u32 modify_index;
u16 modify_actions;
u32 decap_index;
u16 decap_actions;
u8 decap_with_vlan:1;
u64 final_icm_addr;
u32 flow_tag;
u32 ctr_id;
u16 gvmi;
u16 hit_gvmi;
u32 reformat_id;
u32 reformat_size;
struct {
int count;
u32 headers[MLX5DR_MAX_VLANS];
} vlans;
};
void mlx5dr_ste_set_actions_rx(struct mlx5dr_domain *dmn,
u8 *action_type_set,
u8 *last_ste,
struct mlx5dr_ste_actions_attr *attr,
u32 *added_stes);
void mlx5dr_ste_set_actions_tx(struct mlx5dr_domain *dmn,
u8 *action_type_set,
u8 *last_ste,
struct mlx5dr_ste_actions_attr *attr,
u32 *added_stes);
struct mlx5dr_ste_ctx *mlx5dr_ste_get_ctx(u8 version);
void mlx5dr_ste_free(struct mlx5dr_ste *ste,
struct mlx5dr_matcher *matcher,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment