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
*/
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;
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
break;
}
}
- ice_seg = NULL;
} while (fv);
if (LIST_EMPTY(fv_list))
return ICE_ERR_CFG;
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);
#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_ */
};
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,
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
* @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;
}
/* 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
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;
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;