mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
net/mlx5: HWS, added actions handling
When a packet matches a flow, the actions specified for the flow are applied. The supported actions include (but not limited to) the following: - drop: packet processing is stopped - go to vport: packet is forwarded to a specified vport - go to flow table: packet is forwarded to a specified table and processing continues there - push/pop vlan: add/remove vlan header respectively to/from the packet - insert/remove header: add/remove a user-defined header to/from the packet - counter: count the packet bytes in the specified counter - tag: tag the matching flow with a provided tag value - reformat: change the packet format by adding or removing some of its headers - modify header: modify the value of the packet headers with set/add/copy ops - range: match packet on range of values Reviewed-by: Erez Shitrit <erezsh@nvidia.com> Signed-off-by: Yevgeny Kliteynik <kliteyn@nvidia.com> Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
This commit is contained in:
parent
00b9f0daef
commit
504e536d90
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,307 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
|
||||
/* Copyright (c) 2024 NVIDIA Corporation & Affiliates */
|
||||
|
||||
#ifndef MLX5HWS_ACTION_H_
|
||||
#define MLX5HWS_ACTION_H_
|
||||
|
||||
/* Max number of STEs needed for a rule (including match) */
|
||||
#define MLX5HWS_ACTION_MAX_STE 20
|
||||
|
||||
/* Max number of internal subactions of ipv6_ext */
|
||||
#define MLX5HWS_ACTION_IPV6_EXT_MAX_SA 4
|
||||
|
||||
enum mlx5hws_action_stc_idx {
|
||||
MLX5HWS_ACTION_STC_IDX_CTRL = 0,
|
||||
MLX5HWS_ACTION_STC_IDX_HIT = 1,
|
||||
MLX5HWS_ACTION_STC_IDX_DW5 = 2,
|
||||
MLX5HWS_ACTION_STC_IDX_DW6 = 3,
|
||||
MLX5HWS_ACTION_STC_IDX_DW7 = 4,
|
||||
MLX5HWS_ACTION_STC_IDX_MAX = 5,
|
||||
/* STC Jumvo STE combo: CTR, Hit */
|
||||
MLX5HWS_ACTION_STC_IDX_LAST_JUMBO_STE = 1,
|
||||
/* STC combo1: CTR, SINGLE, DOUBLE, Hit */
|
||||
MLX5HWS_ACTION_STC_IDX_LAST_COMBO1 = 3,
|
||||
/* STC combo2: CTR, 3 x SINGLE, Hit */
|
||||
MLX5HWS_ACTION_STC_IDX_LAST_COMBO2 = 4,
|
||||
/* STC combo2: CTR, TRIPLE, Hit */
|
||||
MLX5HWS_ACTION_STC_IDX_LAST_COMBO3 = 2,
|
||||
};
|
||||
|
||||
enum mlx5hws_action_offset {
|
||||
MLX5HWS_ACTION_OFFSET_DW0 = 0,
|
||||
MLX5HWS_ACTION_OFFSET_DW5 = 5,
|
||||
MLX5HWS_ACTION_OFFSET_DW6 = 6,
|
||||
MLX5HWS_ACTION_OFFSET_DW7 = 7,
|
||||
MLX5HWS_ACTION_OFFSET_HIT = 3,
|
||||
MLX5HWS_ACTION_OFFSET_HIT_LSB = 4,
|
||||
};
|
||||
|
||||
enum {
|
||||
MLX5HWS_ACTION_DOUBLE_SIZE = 8,
|
||||
MLX5HWS_ACTION_INLINE_DATA_SIZE = 4,
|
||||
MLX5HWS_ACTION_HDR_LEN_L2_MACS = 12,
|
||||
MLX5HWS_ACTION_HDR_LEN_L2_VLAN = 4,
|
||||
MLX5HWS_ACTION_HDR_LEN_L2_ETHER = 2,
|
||||
MLX5HWS_ACTION_HDR_LEN_L2 = (MLX5HWS_ACTION_HDR_LEN_L2_MACS +
|
||||
MLX5HWS_ACTION_HDR_LEN_L2_ETHER),
|
||||
MLX5HWS_ACTION_HDR_LEN_L2_W_VLAN = (MLX5HWS_ACTION_HDR_LEN_L2 +
|
||||
MLX5HWS_ACTION_HDR_LEN_L2_VLAN),
|
||||
MLX5HWS_ACTION_REFORMAT_DATA_SIZE = 64,
|
||||
DECAP_L3_NUM_ACTIONS_W_NO_VLAN = 6,
|
||||
DECAP_L3_NUM_ACTIONS_W_VLAN = 7,
|
||||
};
|
||||
|
||||
enum mlx5hws_action_setter_flag {
|
||||
ASF_SINGLE1 = 1 << 0,
|
||||
ASF_SINGLE2 = 1 << 1,
|
||||
ASF_SINGLE3 = 1 << 2,
|
||||
ASF_DOUBLE = ASF_SINGLE2 | ASF_SINGLE3,
|
||||
ASF_TRIPLE = ASF_SINGLE1 | ASF_DOUBLE,
|
||||
ASF_INSERT = 1 << 3,
|
||||
ASF_REMOVE = 1 << 4,
|
||||
ASF_MODIFY = 1 << 5,
|
||||
ASF_CTR = 1 << 6,
|
||||
ASF_HIT = 1 << 7,
|
||||
};
|
||||
|
||||
struct mlx5hws_action_default_stc {
|
||||
struct mlx5hws_pool_chunk nop_ctr;
|
||||
struct mlx5hws_pool_chunk nop_dw5;
|
||||
struct mlx5hws_pool_chunk nop_dw6;
|
||||
struct mlx5hws_pool_chunk nop_dw7;
|
||||
struct mlx5hws_pool_chunk default_hit;
|
||||
u32 refcount;
|
||||
};
|
||||
|
||||
struct mlx5hws_action_shared_stc {
|
||||
struct mlx5hws_pool_chunk stc_chunk;
|
||||
u32 refcount;
|
||||
};
|
||||
|
||||
struct mlx5hws_actions_apply_data {
|
||||
struct mlx5hws_send_engine *queue;
|
||||
struct mlx5hws_rule_action *rule_action;
|
||||
__be32 *wqe_data;
|
||||
struct mlx5hws_wqe_gta_ctrl_seg *wqe_ctrl;
|
||||
u32 jump_to_action_stc;
|
||||
struct mlx5hws_context_common_res *common_res;
|
||||
enum mlx5hws_table_type tbl_type;
|
||||
u32 next_direct_idx;
|
||||
u8 require_dep;
|
||||
};
|
||||
|
||||
struct mlx5hws_actions_wqe_setter;
|
||||
|
||||
typedef void (*mlx5hws_action_setter_fp)(struct mlx5hws_actions_apply_data *apply,
|
||||
struct mlx5hws_actions_wqe_setter *setter);
|
||||
|
||||
struct mlx5hws_actions_wqe_setter {
|
||||
mlx5hws_action_setter_fp set_single;
|
||||
mlx5hws_action_setter_fp set_double;
|
||||
mlx5hws_action_setter_fp set_triple;
|
||||
mlx5hws_action_setter_fp set_hit;
|
||||
mlx5hws_action_setter_fp set_ctr;
|
||||
u8 idx_single;
|
||||
u8 idx_double;
|
||||
u8 idx_triple;
|
||||
u8 idx_ctr;
|
||||
u8 idx_hit;
|
||||
u8 stage_idx;
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
struct mlx5hws_action_template {
|
||||
struct mlx5hws_actions_wqe_setter setters[MLX5HWS_ACTION_MAX_STE];
|
||||
enum mlx5hws_action_type *action_type_arr;
|
||||
u8 num_of_action_stes;
|
||||
u8 num_actions;
|
||||
u8 only_term;
|
||||
};
|
||||
|
||||
struct mlx5hws_action {
|
||||
u8 type;
|
||||
u8 flags;
|
||||
struct mlx5hws_context *ctx;
|
||||
union {
|
||||
struct {
|
||||
struct mlx5hws_pool_chunk stc[MLX5HWS_TABLE_TYPE_MAX];
|
||||
union {
|
||||
struct {
|
||||
u32 pat_id;
|
||||
u32 arg_id;
|
||||
__be64 single_action;
|
||||
u32 nope_locations;
|
||||
u8 num_of_patterns;
|
||||
u8 single_action_type;
|
||||
u8 num_of_actions;
|
||||
u8 max_num_of_actions;
|
||||
u8 require_reparse;
|
||||
} modify_header;
|
||||
struct {
|
||||
u32 arg_id;
|
||||
u32 header_size;
|
||||
u16 max_hdr_sz;
|
||||
u8 num_of_hdrs;
|
||||
u8 anchor;
|
||||
u8 e_anchor;
|
||||
u8 offset;
|
||||
bool encap;
|
||||
u8 require_reparse;
|
||||
} reformat;
|
||||
struct {
|
||||
u32 obj_id;
|
||||
u8 return_reg_id;
|
||||
} aso;
|
||||
struct {
|
||||
u16 vport_num;
|
||||
u16 esw_owner_vhca_id;
|
||||
bool esw_owner_vhca_id_valid;
|
||||
} vport;
|
||||
struct {
|
||||
u32 obj_id;
|
||||
} dest_obj;
|
||||
struct {
|
||||
struct mlx5hws_cmd_forward_tbl *fw_island;
|
||||
size_t num_dest;
|
||||
struct mlx5hws_cmd_set_fte_dest *dest_list;
|
||||
} dest_array;
|
||||
struct {
|
||||
u8 type;
|
||||
u8 start_anchor;
|
||||
u8 end_anchor;
|
||||
u8 num_of_words;
|
||||
bool decap;
|
||||
} insert_hdr;
|
||||
struct {
|
||||
/* PRM start anchor from which header will be removed */
|
||||
u8 anchor;
|
||||
/* Header remove offset in bytes, from the start
|
||||
* anchor to the location where remove header starts.
|
||||
*/
|
||||
u8 offset;
|
||||
/* Indicates the removed header size in bytes */
|
||||
size_t size;
|
||||
} remove_header;
|
||||
struct {
|
||||
struct mlx5hws_matcher_action_ste *table_ste;
|
||||
struct mlx5hws_action *hit_ft_action;
|
||||
struct mlx5hws_definer *definer;
|
||||
} range;
|
||||
};
|
||||
};
|
||||
|
||||
struct ibv_flow_action *flow_action;
|
||||
u32 obj_id;
|
||||
struct ibv_qp *qp;
|
||||
};
|
||||
};
|
||||
|
||||
const char *mlx5hws_action_type_to_str(enum mlx5hws_action_type action_type);
|
||||
|
||||
int mlx5hws_action_get_default_stc(struct mlx5hws_context *ctx,
|
||||
u8 tbl_type);
|
||||
|
||||
void mlx5hws_action_put_default_stc(struct mlx5hws_context *ctx,
|
||||
u8 tbl_type);
|
||||
|
||||
void mlx5hws_action_prepare_decap_l3_data(u8 *src, u8 *dst,
|
||||
u16 num_of_actions);
|
||||
|
||||
int mlx5hws_action_template_process(struct mlx5hws_action_template *at);
|
||||
|
||||
bool mlx5hws_action_check_combo(struct mlx5hws_context *ctx,
|
||||
enum mlx5hws_action_type *user_actions,
|
||||
enum mlx5hws_table_type table_type);
|
||||
|
||||
int mlx5hws_action_alloc_single_stc(struct mlx5hws_context *ctx,
|
||||
struct mlx5hws_cmd_stc_modify_attr *stc_attr,
|
||||
u32 table_type,
|
||||
struct mlx5hws_pool_chunk *stc);
|
||||
|
||||
void mlx5hws_action_free_single_stc(struct mlx5hws_context *ctx,
|
||||
u32 table_type,
|
||||
struct mlx5hws_pool_chunk *stc);
|
||||
|
||||
static inline void
|
||||
mlx5hws_action_setter_default_single(struct mlx5hws_actions_apply_data *apply,
|
||||
struct mlx5hws_actions_wqe_setter *setter)
|
||||
{
|
||||
apply->wqe_data[MLX5HWS_ACTION_OFFSET_DW5] = 0;
|
||||
apply->wqe_ctrl->stc_ix[MLX5HWS_ACTION_STC_IDX_DW5] =
|
||||
htonl(apply->common_res->default_stc->nop_dw5.offset);
|
||||
}
|
||||
|
||||
static inline void
|
||||
mlx5hws_action_setter_default_double(struct mlx5hws_actions_apply_data *apply,
|
||||
struct mlx5hws_actions_wqe_setter *setter)
|
||||
{
|
||||
apply->wqe_data[MLX5HWS_ACTION_OFFSET_DW6] = 0;
|
||||
apply->wqe_data[MLX5HWS_ACTION_OFFSET_DW7] = 0;
|
||||
apply->wqe_ctrl->stc_ix[MLX5HWS_ACTION_STC_IDX_DW6] =
|
||||
htonl(apply->common_res->default_stc->nop_dw6.offset);
|
||||
apply->wqe_ctrl->stc_ix[MLX5HWS_ACTION_STC_IDX_DW7] =
|
||||
htonl(apply->common_res->default_stc->nop_dw7.offset);
|
||||
}
|
||||
|
||||
static inline void
|
||||
mlx5hws_action_setter_default_ctr(struct mlx5hws_actions_apply_data *apply,
|
||||
struct mlx5hws_actions_wqe_setter *setter)
|
||||
{
|
||||
apply->wqe_data[MLX5HWS_ACTION_OFFSET_DW0] = 0;
|
||||
apply->wqe_ctrl->stc_ix[MLX5HWS_ACTION_STC_IDX_CTRL] =
|
||||
htonl(apply->common_res->default_stc->nop_ctr.offset);
|
||||
}
|
||||
|
||||
static inline void
|
||||
mlx5hws_action_apply_setter(struct mlx5hws_actions_apply_data *apply,
|
||||
struct mlx5hws_actions_wqe_setter *setter,
|
||||
bool is_jumbo)
|
||||
{
|
||||
u8 num_of_actions;
|
||||
|
||||
/* Set control counter */
|
||||
if (setter->set_ctr)
|
||||
setter->set_ctr(apply, setter);
|
||||
else
|
||||
mlx5hws_action_setter_default_ctr(apply, setter);
|
||||
|
||||
if (!is_jumbo) {
|
||||
if (unlikely(setter->set_triple)) {
|
||||
/* Set triple on match */
|
||||
setter->set_triple(apply, setter);
|
||||
num_of_actions = MLX5HWS_ACTION_STC_IDX_LAST_COMBO3;
|
||||
} else {
|
||||
/* Set single and double on match */
|
||||
if (setter->set_single)
|
||||
setter->set_single(apply, setter);
|
||||
else
|
||||
mlx5hws_action_setter_default_single(apply, setter);
|
||||
|
||||
if (setter->set_double)
|
||||
setter->set_double(apply, setter);
|
||||
else
|
||||
mlx5hws_action_setter_default_double(apply, setter);
|
||||
|
||||
num_of_actions = setter->set_double ?
|
||||
MLX5HWS_ACTION_STC_IDX_LAST_COMBO1 :
|
||||
MLX5HWS_ACTION_STC_IDX_LAST_COMBO2;
|
||||
}
|
||||
} else {
|
||||
apply->wqe_data[MLX5HWS_ACTION_OFFSET_DW5] = 0;
|
||||
apply->wqe_data[MLX5HWS_ACTION_OFFSET_DW6] = 0;
|
||||
apply->wqe_data[MLX5HWS_ACTION_OFFSET_DW7] = 0;
|
||||
apply->wqe_ctrl->stc_ix[MLX5HWS_ACTION_STC_IDX_DW5] = 0;
|
||||
apply->wqe_ctrl->stc_ix[MLX5HWS_ACTION_STC_IDX_DW6] = 0;
|
||||
apply->wqe_ctrl->stc_ix[MLX5HWS_ACTION_STC_IDX_DW7] = 0;
|
||||
num_of_actions = MLX5HWS_ACTION_STC_IDX_LAST_JUMBO_STE;
|
||||
}
|
||||
|
||||
/* Set next/final hit action */
|
||||
setter->set_hit(apply, setter);
|
||||
|
||||
/* Set number of actions */
|
||||
apply->wqe_ctrl->stc_ix[MLX5HWS_ACTION_STC_IDX_CTRL] |=
|
||||
htonl(num_of_actions << 29);
|
||||
}
|
||||
|
||||
#endif /* MLX5HWS_ACTION_H_ */
|
Loading…
Reference in New Issue
Block a user