net/ice/base: associate recipes by profile type
authorQi Zhang <qi.z.zhang@intel.com>
Thu, 29 Aug 2019 02:36:30 +0000 (10:36 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Mon, 7 Oct 2019 13:00:53 +0000 (15:00 +0200)
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 <dan.nowlin@intel.com>
Signed-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
Acked-by: Xiaolong Ye <xiaolong.ye@intel.com>
drivers/net/ice/base/ice_flex_pipe.c
drivers/net/ice/base/ice_flex_pipe.h
drivers/net/ice/base/ice_flex_type.h
drivers/net/ice/base/ice_protocol_type.h
drivers/net/ice/base/ice_switch.c

index f8dd1c4..3beb4d9 100644 (file)
@@ -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;
index 6af2465..17285ef 100644 (file)
@@ -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);
index 634897a..3a70668 100644 (file)
@@ -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_ */
index 29375d3..ee40bdc 100644 (file)
@@ -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
index 2b0c7c7..2a7ffc7 100644 (file)
@@ -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;