From 55744222e6e2b4623de0626aef586d98e245bdd2 Mon Sep 17 00:00:00 2001 From: Qi Zhang Date: Thu, 29 Aug 2019 10:36:30 +0800 Subject: [PATCH] net/ice/base: associate recipes by profile type Change recipe to profile association logic to determine the profile type to determine if a profile is compatible with the rule being added. Signed-off-by: Dan Nowlin Signed-off-by: Paul M Stillwell Jr Signed-off-by: Qi Zhang Acked-by: Xiaolong Ye --- drivers/net/ice/base/ice_flex_pipe.c | 87 +++++++++++++++++++++++- drivers/net/ice/base/ice_flex_pipe.h | 5 +- drivers/net/ice/base/ice_flex_type.h | 8 +++ drivers/net/ice/base/ice_protocol_type.h | 5 +- drivers/net/ice/base/ice_switch.c | 54 ++++++++++++++- 5 files changed, 151 insertions(+), 8 deletions(-) diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c index f8dd1c4d1c..3beb4d9613 100644 --- a/drivers/net/ice/base/ice_flex_pipe.c +++ b/drivers/net/ice/base/ice_flex_pipe.c @@ -1505,11 +1505,84 @@ ice_sw_fv_handler(u32 sect_type, void *section, u32 index, u32 *offset) return fv_section->fv + index; } +/** + * ice_get_sw_prof_type - determine switch profile type + * @hw: pointer to the HW structure + * @fv: pointer to the switch field vector + */ +static enum ice_prof_type +ice_get_sw_prof_type(struct ice_hw *hw, struct ice_fv *fv) +{ + u16 i; + + for (i = 0; i < hw->blk[ICE_BLK_SW].es.fvw; i++) { + /* UDP tunnel will have UDP_OF protocol ID and VNI offset */ + if (fv->ew[i].prot_id == (u8)ICE_PROT_UDP_OF && + fv->ew[i].off == ICE_VNI_OFFSET) + return ICE_PROF_TUN_UDP; + + /* GRE tunnel will have GRE protocol */ + if (fv->ew[i].prot_id == (u8)ICE_PROT_GRE_OF) + return ICE_PROF_TUN_GRE; + + /* PPPOE tunnel will have PPPOE protocol */ + if (fv->ew[i].prot_id == (u8)ICE_PROT_PPPOE) + return ICE_PROF_TUN_PPPOE; + } + + return ICE_PROF_NON_TUN; +} + +/** + * ice_get_sw_fv_bitmap - Get switch field vector bitmap based on profile type + * @hw: pointer to hardware structure + * @type: type of profiles requested + * @bm: pointer to memory for returning the bitmap of field vectors + */ +void +ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type type, + ice_bitmap_t *bm) +{ + struct ice_pkg_enum state; + struct ice_seg *ice_seg; + struct ice_fv *fv; + + if (type == ICE_PROF_ALL) { + u16 i; + + for (i = 0; i < ICE_MAX_NUM_PROFILES; i++) + ice_set_bit(i, bm); + return; + } + + ice_zero_bitmap(bm, ICE_MAX_NUM_PROFILES); + + ice_seg = hw->seg; + do { + enum ice_prof_type prof_type; + u32 offset; + + fv = (struct ice_fv *) + ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW, + &offset, ice_sw_fv_handler); + ice_seg = NULL; + + if (fv) { + /* Determine field vector type */ + prof_type = ice_get_sw_prof_type(hw, fv); + + if (type & prof_type) + ice_set_bit((u16)offset, bm); + } + } while (fv); +} + /** * ice_get_sw_fv_list * @hw: pointer to the HW structure * @prot_ids: field vector to search for with a given protocol ID * @ids_cnt: lookup/protocol count + * @bm: bitmap of field vectors to consider * @fv_list: Head of a list * * Finds all the field vector entries from switch block that contain @@ -1521,7 +1594,7 @@ ice_sw_fv_handler(u32 sect_type, void *section, u32 index, u32 *offset) */ enum ice_status ice_get_sw_fv_list(struct ice_hw *hw, u16 *prot_ids, u8 ids_cnt, - struct LIST_HEAD_TYPE *fv_list) + ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list) { struct ice_sw_fv_list_entry *fvl; struct ice_sw_fv_list_entry *tmp; @@ -1540,8 +1613,17 @@ ice_get_sw_fv_list(struct ice_hw *hw, u16 *prot_ids, u8 ids_cnt, fv = (struct ice_fv *) ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW, &offset, ice_sw_fv_handler); + if (!fv) + break; + ice_seg = NULL; - for (i = 0; i < ids_cnt && fv; i++) { + /* If field vector is not in the bitmap list, then skip this + * profile. + */ + if (!ice_is_bit_set(bm, (u16)offset)) + continue; + + for (i = 0; i < ids_cnt; i++) { int j; /* This code assumes that if a switch field vector line @@ -1565,7 +1647,6 @@ ice_get_sw_fv_list(struct ice_hw *hw, u16 *prot_ids, u8 ids_cnt, break; } } - ice_seg = NULL; } while (fv); if (LIST_EMPTY(fv_list)) return ICE_ERR_CFG; diff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h index 6af24653bb..17285efe04 100644 --- a/drivers/net/ice/base/ice_flex_pipe.h +++ b/drivers/net/ice/base/ice_flex_pipe.h @@ -30,9 +30,12 @@ ice_find_prot_off(struct ice_hw *hw, enum ice_block blk, u8 prof, u8 fv_idx, enum ice_status ice_find_label_value(struct ice_seg *ice_seg, char const *name, u32 type, u16 *value); +void +ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type type, + ice_bitmap_t *bm); enum ice_status ice_get_sw_fv_list(struct ice_hw *hw, u16 *prot_ids, u8 ids_cnt, - struct LIST_HEAD_TYPE *fv_list); + ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list); enum ice_status ice_create_tunnel(struct ice_hw *hw, enum ice_tunnel_type type, u16 port); enum ice_status ice_destroy_tunnel(struct ice_hw *hw, u16 port, bool all); diff --git a/drivers/net/ice/base/ice_flex_type.h b/drivers/net/ice/base/ice_flex_type.h index 634897a287..3a70668d9f 100644 --- a/drivers/net/ice/base/ice_flex_type.h +++ b/drivers/net/ice/base/ice_flex_type.h @@ -710,4 +710,12 @@ struct ice_chs_chg { #define ICE_FLOW_PTYPE_MAX ICE_XLT1_CNT +enum ice_prof_type { + ICE_PROF_NON_TUN = 0x1, + ICE_PROF_TUN_UDP = 0x2, + ICE_PROF_TUN_GRE = 0x4, + ICE_PROF_TUN_PPPOE = 0x8, + ICE_PROF_TUN_ALL = 0xE, + ICE_PROF_ALL = 0xFF, +}; #endif /* _ICE_FLEX_TYPE_H_ */ diff --git a/drivers/net/ice/base/ice_protocol_type.h b/drivers/net/ice/base/ice_protocol_type.h index 29375d3aeb..ee40bdc30c 100644 --- a/drivers/net/ice/base/ice_protocol_type.h +++ b/drivers/net/ice/base/ice_protocol_type.h @@ -49,7 +49,8 @@ enum ice_protocol_type { }; enum ice_sw_tunnel_type { - ICE_NON_TUN, + ICE_NON_TUN = 0, + ICE_SW_TUN_AND_NON_TUN, ICE_SW_TUN_VXLAN_GPE, ICE_SW_TUN_GENEVE, ICE_SW_TUN_VXLAN, @@ -111,6 +112,8 @@ enum ice_prot_id { ICE_PROT_INVALID = 255 /* when offset == 0xFF */ }; +#define ICE_VNI_OFFSET 12 /* offset of VNI from ICE_PROT_UDP_OF */ + #define ICE_MAC_OFOS_HW 1 #define ICE_MAC_IL_HW 4 diff --git a/drivers/net/ice/base/ice_switch.c b/drivers/net/ice/base/ice_switch.c index 2b0c7c7a3b..2a7ffc7aac 100644 --- a/drivers/net/ice/base/ice_switch.c +++ b/drivers/net/ice/base/ice_switch.c @@ -5463,11 +5463,12 @@ out: * @lkups: lookup elements or match criteria for the advanced recipe, one * structure per protocol header * @lkups_cnt: number of protocols + * @bm: bitmap of field vectors to consider * @fv_list: pointer to a list that holds the returned field vectors */ static enum ice_status ice_get_fv(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, - struct LIST_HEAD_TYPE *fv_list) + ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list) { enum ice_status status; u16 *prot_ids; @@ -5484,13 +5485,53 @@ ice_get_fv(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, } /* Find field vectors that include all specified protocol types */ - status = ice_get_sw_fv_list(hw, prot_ids, lkups_cnt, fv_list); + status = ice_get_sw_fv_list(hw, prot_ids, lkups_cnt, bm, fv_list); free_mem: ice_free(hw, prot_ids); return status; } +/* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule + * @hw: pointer to hardware structure + * @rinfo: other information regarding the rule e.g. priority and action info + * @bm: pointer to memory for returning the bitmap of field vectors + */ +static void +ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo, + ice_bitmap_t *bm) +{ + enum ice_prof_type type; + + switch (rinfo->tun_type) { + case ICE_NON_TUN: + type = ICE_PROF_NON_TUN; + break; + case ICE_ALL_TUNNELS: + type = ICE_PROF_TUN_ALL; + break; + case ICE_SW_TUN_VXLAN_GPE: + case ICE_SW_TUN_GENEVE: + case ICE_SW_TUN_VXLAN: + case ICE_SW_TUN_UDP: + case ICE_SW_TUN_GTP: + type = ICE_PROF_TUN_UDP; + break; + case ICE_SW_TUN_NVGRE: + type = ICE_PROF_TUN_GRE; + break; + case ICE_SW_TUN_PPPOE: + type = ICE_PROF_TUN_PPPOE; + break; + case ICE_SW_TUN_AND_NON_TUN: + default: + type = ICE_PROF_ALL; + break; + } + + ice_get_sw_fv_bitmap(hw, type, bm); +} + /** * ice_add_adv_recipe - Add an advanced recipe that is not part of the default * @hw: pointer to hardware structure @@ -5504,6 +5545,7 @@ static enum ice_status ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, struct ice_adv_rule_info *rinfo, u16 *rid) { + ice_declare_bitmap(fv_bitmap, ICE_MAX_NUM_PROFILES); ice_declare_bitmap(profiles, ICE_MAX_NUM_PROFILES); struct ice_prot_lkup_ext *lkup_exts; struct ice_recp_grp_entry *r_entry; @@ -5553,7 +5595,13 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, INIT_LIST_HEAD(&rm->fv_list); INIT_LIST_HEAD(&rm->rg_list); - status = ice_get_fv(hw, lkups, lkups_cnt, &rm->fv_list); + /* Get bitmap of field vectors (profiles) that are compatible with the + * rule request; only these will be searched in the subsequent call to + * ice_get_fv. + */ + ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap); + + status = ice_get_fv(hw, lkups, lkups_cnt, fv_bitmap, &rm->fv_list); if (status) goto err_unroll; -- 2.20.1