Commit be6d5dae authored by Yevgeny Kliteynik's avatar Yevgeny Kliteynik Committed by Saeed Mahameed

net/mlx5: DR, Add support for range match action

Add support for matching on range.
The supported type of range is L2 frame size.
Signed-off-by: default avatarYevgeny Kliteynik <kliteyn@nvidia.com>
Reviewed-by: default avatarErez Shitrit <erezsh@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent 1207a772
......@@ -49,7 +49,8 @@ enum dr_dump_rec_type {
DR_DUMP_REC_TYPE_ACTION_POP_VLAN = 3413,
DR_DUMP_REC_TYPE_ACTION_SAMPLER = 3415,
DR_DUMP_REC_TYPE_ACTION_INSERT_HDR = 3420,
DR_DUMP_REC_TYPE_ACTION_REMOVE_HDR = 3421
DR_DUMP_REC_TYPE_ACTION_REMOVE_HDR = 3421,
DR_DUMP_REC_TYPE_ACTION_MATCH_RANGE = 3425,
};
void mlx5dr_dbg_tbl_add(struct mlx5dr_table *tbl)
......@@ -107,6 +108,8 @@ dr_dump_rule_action_mem(struct seq_file *file, const u64 rule_id,
{
struct mlx5dr_action *action = action_mem->action;
const u64 action_id = DR_DBG_PTR_TO_ID(action);
u64 hit_tbl_ptr, miss_tbl_ptr;
u32 hit_tbl_id, miss_tbl_id;
switch (action->action_type) {
case DR_ACTION_TYP_DROP:
......@@ -198,6 +201,30 @@ dr_dump_rule_action_mem(struct seq_file *file, const u64 rule_id,
action->sampler->rx_icm_addr,
action->sampler->tx_icm_addr);
break;
case DR_ACTION_TYP_RANGE:
if (action->range->hit_tbl_action->dest_tbl->is_fw_tbl) {
hit_tbl_id = action->range->hit_tbl_action->dest_tbl->fw_tbl.id;
hit_tbl_ptr = 0;
} else {
hit_tbl_id = action->range->hit_tbl_action->dest_tbl->tbl->table_id;
hit_tbl_ptr =
DR_DBG_PTR_TO_ID(action->range->hit_tbl_action->dest_tbl->tbl);
}
if (action->range->miss_tbl_action->dest_tbl->is_fw_tbl) {
miss_tbl_id = action->range->miss_tbl_action->dest_tbl->fw_tbl.id;
miss_tbl_ptr = 0;
} else {
miss_tbl_id = action->range->miss_tbl_action->dest_tbl->tbl->table_id;
miss_tbl_ptr =
DR_DBG_PTR_TO_ID(action->range->miss_tbl_action->dest_tbl->tbl);
}
seq_printf(file, "%d,0x%llx,0x%llx,0x%x,0x%llx,0x%x,0x%llx,0x%x\n",
DR_DUMP_REC_TYPE_ACTION_MATCH_RANGE, action_id, rule_id,
hit_tbl_id, hit_tbl_ptr, miss_tbl_id, miss_tbl_ptr,
action->range->definer_id);
break;
default:
return 0;
}
......
......@@ -13,6 +13,7 @@ enum dr_ste_v1_entry_format {
DR_STE_V1_TYPE_BWC_BYTE = 0x0,
DR_STE_V1_TYPE_BWC_DW = 0x1,
DR_STE_V1_TYPE_MATCH = 0x2,
DR_STE_V1_TYPE_MATCH_RANGES = 0x7,
};
/* Lookup type is built from 2B: [ Definer mode 1B ][ Definer index 1B ] */
......@@ -269,7 +270,12 @@ static void dr_ste_v1_set_entry_type(u8 *hw_ste_p, u8 entry_type)
bool dr_ste_v1_is_miss_addr_set(u8 *hw_ste_p)
{
return false;
u8 entry_type = MLX5_GET(ste_match_bwc_v1, hw_ste_p, entry_format);
/* unlike MATCH STE, for MATCH_RANGES STE both hit and miss addresses
* are part of the action, so they both set as part of STE init
*/
return entry_type == DR_STE_V1_TYPE_MATCH_RANGES;
}
void dr_ste_v1_set_miss_addr(u8 *hw_ste_p, u64 miss_addr)
......@@ -525,6 +531,27 @@ static void dr_ste_v1_set_aso_flow_meter(u8 *d_action,
init_color);
}
static void dr_ste_v1_set_match_range_pkt_len(u8 *hw_ste_p, u32 definer_id,
u32 min, u32 max)
{
MLX5_SET(ste_match_ranges_v1, hw_ste_p, match_definer_ctx_idx, definer_id);
/* When the STE will be sent, its mask and tags will be swapped in
* dr_ste_v1_prepare_for_postsend(). This, however, is match range STE
* which doesn't have mask, and shouldn't have mask/tag swapped.
* We're using the common utilities functions to send this STE, so need
* to allow for this swapping - place the values in the corresponding
* locations to allow flipping them when writing to ICM.
*
* min/max_value_2 corresponds to match_dw_0 in its definer.
* To allow mask/tag swapping, writing the min/max_2 to min/max_0.
*
* Pkt len is 2 bytes that are stored in the higher section of the DW.
*/
MLX5_SET(ste_match_ranges_v1, hw_ste_p, min_value_0, min << 16);
MLX5_SET(ste_match_ranges_v1, hw_ste_p, max_value_0, max << 16);
}
static void dr_ste_v1_arr_init_next_match(u8 **last_ste,
u32 *added_stes,
u16 gvmi)
......@@ -540,6 +567,14 @@ static void dr_ste_v1_arr_init_next_match(u8 **last_ste,
memset(action, 0, MLX5_FLD_SZ_BYTES(ste_mask_and_match_v1, action));
}
static void dr_ste_v1_arr_init_next_match_range(u8 **last_ste,
u32 *added_stes,
u16 gvmi)
{
dr_ste_v1_arr_init_next_match(last_ste, added_stes, gvmi);
dr_ste_v1_set_entry_type(*last_ste, DR_STE_V1_TYPE_MATCH_RANGES);
}
void dr_ste_v1_set_actions_tx(struct mlx5dr_domain *dmn,
u8 *action_type_set,
u32 actions_caps,
......@@ -675,6 +710,20 @@ void dr_ste_v1_set_actions_tx(struct mlx5dr_domain *dmn,
action += DR_STE_ACTION_DOUBLE_SZ;
}
if (action_type_set[DR_ACTION_TYP_RANGE]) {
/* match ranges requires a new STE of its own type */
dr_ste_v1_arr_init_next_match_range(&last_ste, added_stes, attr->gvmi);
dr_ste_v1_set_miss_addr(last_ste, attr->range.miss_icm_addr);
/* we do not support setting any action on the match ranges STE */
action_sz = 0;
dr_ste_v1_set_match_range_pkt_len(last_ste,
attr->range.definer_id,
attr->range.min,
attr->range.max);
}
dr_ste_v1_set_hit_gvmi(last_ste, attr->hit_gvmi);
dr_ste_v1_set_hit_addr(last_ste, attr->final_icm_addr, 1);
}
......@@ -863,6 +912,20 @@ void dr_ste_v1_set_actions_rx(struct mlx5dr_domain *dmn,
action += DR_STE_ACTION_DOUBLE_SZ;
}
if (action_type_set[DR_ACTION_TYP_RANGE]) {
/* match ranges requires a new STE of its own type */
dr_ste_v1_arr_init_next_match_range(&last_ste, added_stes, attr->gvmi);
dr_ste_v1_set_miss_addr(last_ste, attr->range.miss_icm_addr);
/* we do not support setting any action on the match ranges STE */
action_sz = 0;
dr_ste_v1_set_match_range_pkt_len(last_ste,
attr->range.definer_id,
attr->range.min,
attr->range.max);
}
dr_ste_v1_set_hit_gvmi(last_ste, attr->hit_gvmi);
dr_ste_v1_set_hit_addr(last_ste, attr->final_icm_addr, 1);
}
......
......@@ -129,6 +129,7 @@ enum mlx5dr_action_type {
DR_ACTION_TYP_REMOVE_HDR,
DR_ACTION_TYP_SAMPLER,
DR_ACTION_TYP_ASO_FLOW_METER,
DR_ACTION_TYP_RANGE,
DR_ACTION_TYP_MAX,
};
......@@ -283,6 +284,13 @@ struct mlx5dr_ste_actions_attr {
u8 dest_reg_id;
u8 init_color;
} aso_flow_meter;
struct {
u64 miss_icm_addr;
u32 definer_id;
u32 min;
u32 max;
} range;
};
void mlx5dr_ste_set_actions_rx(struct mlx5dr_ste_ctx *ste_ctx,
......@@ -1029,6 +1037,15 @@ struct mlx5dr_action_dest_tbl {
};
};
struct mlx5dr_action_range {
struct mlx5dr_domain *dmn;
struct mlx5dr_action *hit_tbl_action;
struct mlx5dr_action *miss_tbl_action;
u32 definer_id;
u32 min;
u32 max;
};
struct mlx5dr_action_ctr {
u32 ctr_id;
u32 offset;
......@@ -1075,6 +1092,7 @@ struct mlx5dr_action {
struct mlx5dr_action_push_vlan *push_vlan;
struct mlx5dr_action_flow_tag *flow_tag;
struct mlx5dr_action_aso_flow_meter *aso;
struct mlx5dr_action_range *range;
};
};
......@@ -1500,4 +1518,12 @@ static inline bool mlx5dr_is_fw_table(struct mlx5_flow_table *ft)
return !ft->fs_dr_table.dr_table;
}
static inline bool mlx5dr_supp_match_ranges(struct mlx5_core_dev *dev)
{
return (MLX5_CAP_GEN(dev, steering_format_version) >=
MLX5_STEERING_FORMAT_CONNECTX_6DX) &&
(MLX5_CAP_GEN_64(dev, match_definer_format_supported) &
(1ULL << MLX5_IFC_DEFINER_FORMAT_ID_SELECT));
}
#endif /* _DR_TYPES_H_ */
......@@ -215,6 +215,17 @@ static struct mlx5dr_action *create_ft_action(struct mlx5dr_domain *domain,
return mlx5dr_action_create_dest_table(dest_ft->fs_dr_table.dr_table);
}
static struct mlx5dr_action *create_range_action(struct mlx5dr_domain *domain,
struct mlx5_flow_rule *dst)
{
return mlx5dr_action_create_dest_match_range(domain,
dst->dest_attr.range.field,
dst->dest_attr.range.hit_ft,
dst->dest_attr.range.miss_ft,
dst->dest_attr.range.min,
dst->dest_attr.range.max);
}
static struct mlx5dr_action *create_action_push_vlan(struct mlx5dr_domain *domain,
struct mlx5_fs_vlan *vlan)
{
......@@ -468,6 +479,15 @@ static int mlx5_cmd_dr_create_fte(struct mlx5_flow_root_namespace *ns,
fs_dr_actions[fs_dr_num_actions++] = tmp_action;
term_actions[num_term_actions++].dest = tmp_action;
break;
case MLX5_FLOW_DESTINATION_TYPE_RANGE:
tmp_action = create_range_action(domain, dst);
if (!tmp_action) {
err = -ENOMEM;
goto free_actions;
}
fs_dr_actions[fs_dr_num_actions++] = tmp_action;
term_actions[num_term_actions++].dest = tmp_action;
break;
default:
err = -EOPNOTSUPP;
goto free_actions;
......@@ -781,11 +801,19 @@ static int mlx5_cmd_dr_destroy_ns(struct mlx5_flow_root_namespace *ns)
static u32 mlx5_cmd_dr_get_capabilities(struct mlx5_flow_root_namespace *ns,
enum fs_flow_table_type ft_type)
{
u32 steering_caps = 0;
if (ft_type != FS_FT_FDB ||
MLX5_CAP_GEN(ns->dev, steering_format_version) == MLX5_STEERING_FORMAT_CONNECTX_5)
return 0;
return MLX5_FLOW_STEERING_CAP_VLAN_PUSH_ON_RX | MLX5_FLOW_STEERING_CAP_VLAN_POP_ON_TX;
steering_caps |= MLX5_FLOW_STEERING_CAP_VLAN_PUSH_ON_RX;
steering_caps |= MLX5_FLOW_STEERING_CAP_VLAN_POP_ON_TX;
if (mlx5dr_supp_match_ranges(ns->dev))
steering_caps |= MLX5_FLOW_STEERING_CAP_MATCH_RANGES;
return steering_caps;
}
bool mlx5_fs_dr_is_supported(struct mlx5_core_dev *dev)
......
......@@ -165,6 +165,41 @@ struct mlx5_ifc_ste_mask_and_match_v1_bits {
u8 action[0x60];
};
struct mlx5_ifc_ste_match_ranges_v1_bits {
u8 entry_format[0x8];
u8 counter_id[0x18];
u8 miss_address_63_48[0x10];
u8 match_definer_ctx_idx[0x8];
u8 miss_address_39_32[0x8];
u8 miss_address_31_6[0x1a];
u8 reserved_at_5a[0x1];
u8 match_polarity[0x1];
u8 reparse[0x1];
u8 reserved_at_5d[0x3];
u8 next_table_base_63_48[0x10];
u8 hash_definer_ctx_idx[0x8];
u8 next_table_base_39_32_size[0x8];
u8 next_table_base_31_5_size[0x1b];
u8 hash_type[0x2];
u8 hash_after_actions[0x1];
u8 reserved_at_9e[0x2];
u8 action[0x60];
u8 max_value_0[0x20];
u8 min_value_0[0x20];
u8 max_value_1[0x20];
u8 min_value_1[0x20];
u8 max_value_2[0x20];
u8 min_value_2[0x20];
u8 max_value_3[0x20];
u8 min_value_3[0x20];
};
struct mlx5_ifc_ste_eth_l2_src_v1_bits {
u8 reserved_at_0[0x1];
u8 sx_sniffer[0x1];
......
......@@ -140,6 +140,14 @@ mlx5dr_action_create_aso(struct mlx5dr_domain *dmn,
u8 init_color,
u8 meter_id);
struct mlx5dr_action *
mlx5dr_action_create_dest_match_range(struct mlx5dr_domain *dmn,
u32 field,
struct mlx5_flow_table *hit_ft,
struct mlx5_flow_table *miss_ft,
u32 min,
u32 max);
int mlx5dr_action_destroy(struct mlx5dr_action *action);
int mlx5dr_definer_get(struct mlx5dr_domain *dmn, u16 format_id,
......
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