ice: Fix FV offset searching
authorMichal Swiatkowski <michal.swiatkowski@linux.intel.com>
Fri, 4 Mar 2022 16:40:47 +0000 (17:40 +0100)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Fri, 11 Mar 2022 16:28:27 +0000 (08:28 -0800)
Checking only protocol ids while searching for correct FVs can lead to a
situation, when incorrect FV will be added to the list. Incorrect means
that FV has correct protocol id but incorrect offset.

Call ice_get_sw_fv_list with ice_prot_lkup_ext struct which contains all
protocol ids with offsets.

With this modification allocating and collecting protocol ids list is
not longer needed.

Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Tested-by: Sandeep Penigalapati <sandeep.penigalapati@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/ice/ice_flex_pipe.c
drivers/net/ethernet/intel/ice/ice_flex_pipe.h
drivers/net/ethernet/intel/ice/ice_switch.c

index 38fe0a7e697599751e1b2440ab64b3445e81894a..c9bb338789ed828ecd2822a9495f6118adcbe752 100644 (file)
@@ -1871,20 +1871,19 @@ ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type req_profs,
 /**
  * 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
+ * @lkups: list of protocol types
  * @bm: bitmap of field vectors to consider
  * @fv_list: Head of a list
  *
  * Finds all the field vector entries from switch block that contain
- * a given protocol ID and returns a list of structures of type
+ * a given protocol ID and offset and returns a list of structures of type
  * "ice_sw_fv_list_entry". Every structure in the list has a field vector
  * definition and profile ID information
  * NOTE: The caller of the function is responsible for freeing the memory
  * allocated for every list entry.
  */
 int
-ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt,
+ice_get_sw_fv_list(struct ice_hw *hw, struct ice_prot_lkup_ext *lkups,
                   unsigned long *bm, struct list_head *fv_list)
 {
        struct ice_sw_fv_list_entry *fvl;
@@ -1896,7 +1895,7 @@ ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt,
 
        memset(&state, 0, sizeof(state));
 
-       if (!ids_cnt || !hw->seg)
+       if (!lkups->n_val_words || !hw->seg)
                return -EINVAL;
 
        ice_seg = hw->seg;
@@ -1915,20 +1914,17 @@ ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt,
                if (!test_bit((u16)offset, bm))
                        continue;
 
-               for (i = 0; i < ids_cnt; i++) {
+               for (i = 0; i < lkups->n_val_words; i++) {
                        int j;
 
-                       /* This code assumes that if a switch field vector line
-                        * has a matching protocol, then this line will contain
-                        * the entries necessary to represent every field in
-                        * that protocol header.
-                        */
                        for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)
-                               if (fv->ew[j].prot_id == prot_ids[i])
+                               if (fv->ew[j].prot_id ==
+                                   lkups->fv_words[i].prot_id &&
+                                   fv->ew[j].off == lkups->fv_words[i].off)
                                        break;
                        if (j >= hw->blk[ICE_BLK_SW].es.fvw)
                                break;
-                       if (i + 1 == ids_cnt) {
+                       if (i + 1 == lkups->n_val_words) {
                                fvl = devm_kzalloc(ice_hw_to_dev(hw),
                                                   sizeof(*fvl), GFP_KERNEL);
                                if (!fvl)
index 2fd5312494c7e15738d1b7a746578655fb8d081c..9c530c86703ecd361a1e088c5006526440b62cfb 100644 (file)
@@ -87,7 +87,7 @@ ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type type,
 void
 ice_init_prof_result_bm(struct ice_hw *hw);
 int
-ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt,
+ice_get_sw_fv_list(struct ice_hw *hw, struct ice_prot_lkup_ext *lkups,
                   unsigned long *bm, struct list_head *fv_list);
 int
 ice_pkg_buf_unreserve_section(struct ice_buf_build *bld, u16 count);
index d98aa35c03377721263ecdf867c144cbd2d4645e..1f83bb3d73bb44b1a2400ebbc5068394cfb02a86 100644 (file)
@@ -4734,41 +4734,6 @@ ice_create_recipe_group(struct ice_hw *hw, struct ice_sw_recipe *rm,
        return status;
 }
 
-/**
- * ice_get_fv - get field vectors/extraction sequences for spec. lookup types
- * @hw: pointer to hardware structure
- * @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 int
-ice_get_fv(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
-          unsigned long *bm, struct list_head *fv_list)
-{
-       u8 *prot_ids;
-       int status;
-       u16 i;
-
-       prot_ids = kcalloc(lkups_cnt, sizeof(*prot_ids), GFP_KERNEL);
-       if (!prot_ids)
-               return -ENOMEM;
-
-       for (i = 0; i < lkups_cnt; i++)
-               if (!ice_prot_type_to_id(lkups[i].type, &prot_ids[i])) {
-                       status = -EIO;
-                       goto free_mem;
-               }
-
-       /* Find field vectors that include all specified protocol types */
-       status = ice_get_sw_fv_list(hw, prot_ids, lkups_cnt, bm, fv_list);
-
-free_mem:
-       kfree(prot_ids);
-       return status;
-}
-
 /**
  * ice_tun_type_match_word - determine if tun type needs a match mask
  * @tun_type: tunnel type
@@ -4917,11 +4882,11 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
 
        /* 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_sw_fv_list.
         */
        ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap);
 
-       status = ice_get_fv(hw, lkups, lkups_cnt, fv_bitmap, &rm->fv_list);
+       status = ice_get_sw_fv_list(hw, lkup_exts, fv_bitmap, &rm->fv_list);
        if (status)
                goto err_unroll;