Thomas Bogendoerfer 0a43b8
From: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Thomas Bogendoerfer 0a43b8
Date: Fri, 4 Mar 2022 17:40:47 +0100
Thomas Bogendoerfer 0a43b8
Subject: ice: Fix FV offset searching
Thomas Bogendoerfer 0a43b8
Patch-mainline: v5.18-rc1
Thomas Bogendoerfer 0a43b8
Git-commit: e5dd661b8bb3751bfe65f4da45b4dec2bfe6d3b8
Thomas Bogendoerfer 0a43b8
References: jsc#PED-376
Thomas Bogendoerfer 0a43b8
Thomas Bogendoerfer 0a43b8
Checking only protocol ids while searching for correct FVs can lead to a
Thomas Bogendoerfer 0a43b8
situation, when incorrect FV will be added to the list. Incorrect means
Thomas Bogendoerfer 0a43b8
that FV has correct protocol id but incorrect offset.
Thomas Bogendoerfer 0a43b8
Thomas Bogendoerfer 0a43b8
Call ice_get_sw_fv_list with ice_prot_lkup_ext struct which contains all
Thomas Bogendoerfer 0a43b8
protocol ids with offsets.
Thomas Bogendoerfer 0a43b8
Thomas Bogendoerfer 0a43b8
With this modification allocating and collecting protocol ids list is
Thomas Bogendoerfer 0a43b8
not longer needed.
Thomas Bogendoerfer 0a43b8
Thomas Bogendoerfer 0a43b8
Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Thomas Bogendoerfer 0a43b8
Tested-by: Sandeep Penigalapati <sandeep.penigalapati@intel.com>
Thomas Bogendoerfer 0a43b8
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Thomas Bogendoerfer 0a43b8
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
Thomas Bogendoerfer 0a43b8
---
Thomas Bogendoerfer 0a43b8
 drivers/net/ethernet/intel/ice/ice_flex_pipe.c |   22 +++++---------
Thomas Bogendoerfer 0a43b8
 drivers/net/ethernet/intel/ice/ice_flex_pipe.h |    2 -
Thomas Bogendoerfer 0a43b8
 drivers/net/ethernet/intel/ice/ice_switch.c    |   39 +------------------------
Thomas Bogendoerfer 0a43b8
 3 files changed, 12 insertions(+), 51 deletions(-)
Thomas Bogendoerfer 0a43b8
Thomas Bogendoerfer 0a43b8
--- a/drivers/net/ethernet/intel/ice/ice_flex_pipe.c
Thomas Bogendoerfer 0a43b8
+++ b/drivers/net/ethernet/intel/ice/ice_flex_pipe.c
Thomas Bogendoerfer 0a43b8
@@ -1871,20 +1871,19 @@ ice_get_sw_fv_bitmap(struct ice_hw *hw,
Thomas Bogendoerfer 0a43b8
 /**
Thomas Bogendoerfer 0a43b8
  * ice_get_sw_fv_list
Thomas Bogendoerfer 0a43b8
  * @hw: pointer to the HW structure
Thomas Bogendoerfer 0a43b8
- * @prot_ids: field vector to search for with a given protocol ID
Thomas Bogendoerfer 0a43b8
- * @ids_cnt: lookup/protocol count
Thomas Bogendoerfer 0a43b8
+ * @lkups: list of protocol types
Thomas Bogendoerfer 0a43b8
  * @bm: bitmap of field vectors to consider
Thomas Bogendoerfer 0a43b8
  * @fv_list: Head of a list
Thomas Bogendoerfer 0a43b8
  *
Thomas Bogendoerfer 0a43b8
  * Finds all the field vector entries from switch block that contain
Thomas Bogendoerfer 0a43b8
- * a given protocol ID and returns a list of structures of type
Thomas Bogendoerfer 0a43b8
+ * a given protocol ID and offset and returns a list of structures of type
Thomas Bogendoerfer 0a43b8
  * "ice_sw_fv_list_entry". Every structure in the list has a field vector
Thomas Bogendoerfer 0a43b8
  * definition and profile ID information
Thomas Bogendoerfer 0a43b8
  * NOTE: The caller of the function is responsible for freeing the memory
Thomas Bogendoerfer 0a43b8
  * allocated for every list entry.
Thomas Bogendoerfer 0a43b8
  */
Thomas Bogendoerfer 0a43b8
 int
Thomas Bogendoerfer 0a43b8
-ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt,
Thomas Bogendoerfer 0a43b8
+ice_get_sw_fv_list(struct ice_hw *hw, struct ice_prot_lkup_ext *lkups,
Thomas Bogendoerfer 0a43b8
 		   unsigned long *bm, struct list_head *fv_list)
Thomas Bogendoerfer 0a43b8
 {
Thomas Bogendoerfer 0a43b8
 	struct ice_sw_fv_list_entry *fvl;
Thomas Bogendoerfer 0a43b8
@@ -1896,7 +1895,7 @@ ice_get_sw_fv_list(struct ice_hw *hw, u8
Thomas Bogendoerfer 0a43b8
 
Thomas Bogendoerfer 0a43b8
 	memset(&state, 0, sizeof(state));
Thomas Bogendoerfer 0a43b8
 
Thomas Bogendoerfer 0a43b8
-	if (!ids_cnt || !hw->seg)
Thomas Bogendoerfer 0a43b8
+	if (!lkups->n_val_words || !hw->seg)
Thomas Bogendoerfer 0a43b8
 		return -EINVAL;
Thomas Bogendoerfer 0a43b8
 
Thomas Bogendoerfer 0a43b8
 	ice_seg = hw->seg;
Thomas Bogendoerfer 0a43b8
@@ -1915,20 +1914,17 @@ ice_get_sw_fv_list(struct ice_hw *hw, u8
Thomas Bogendoerfer 0a43b8
 		if (!test_bit((u16)offset, bm))
Thomas Bogendoerfer 0a43b8
 			continue;
Thomas Bogendoerfer 0a43b8
 
Thomas Bogendoerfer 0a43b8
-		for (i = 0; i < ids_cnt; i++) {
Thomas Bogendoerfer 0a43b8
+		for (i = 0; i < lkups->n_val_words; i++) {
Thomas Bogendoerfer 0a43b8
 			int j;
Thomas Bogendoerfer 0a43b8
 
Thomas Bogendoerfer 0a43b8
-			/* This code assumes that if a switch field vector line
Thomas Bogendoerfer 0a43b8
-			 * has a matching protocol, then this line will contain
Thomas Bogendoerfer 0a43b8
-			 * the entries necessary to represent every field in
Thomas Bogendoerfer 0a43b8
-			 * that protocol header.
Thomas Bogendoerfer 0a43b8
-			 */
Thomas Bogendoerfer 0a43b8
 			for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)
Thomas Bogendoerfer 0a43b8
-				if (fv->ew[j].prot_id == prot_ids[i])
Thomas Bogendoerfer 0a43b8
+				if (fv->ew[j].prot_id ==
Thomas Bogendoerfer 0a43b8
+				    lkups->fv_words[i].prot_id &&
Thomas Bogendoerfer 0a43b8
+				    fv->ew[j].off == lkups->fv_words[i].off)
Thomas Bogendoerfer 0a43b8
 					break;
Thomas Bogendoerfer 0a43b8
 			if (j >= hw->blk[ICE_BLK_SW].es.fvw)
Thomas Bogendoerfer 0a43b8
 				break;
Thomas Bogendoerfer 0a43b8
-			if (i + 1 == ids_cnt) {
Thomas Bogendoerfer 0a43b8
+			if (i + 1 == lkups->n_val_words) {
Thomas Bogendoerfer 0a43b8
 				fvl = devm_kzalloc(ice_hw_to_dev(hw),
Thomas Bogendoerfer 0a43b8
 						   sizeof(*fvl), GFP_KERNEL);
Thomas Bogendoerfer 0a43b8
 				if (!fvl)
Thomas Bogendoerfer 0a43b8
--- a/drivers/net/ethernet/intel/ice/ice_flex_pipe.h
Thomas Bogendoerfer 0a43b8
+++ b/drivers/net/ethernet/intel/ice/ice_flex_pipe.h
Thomas Bogendoerfer 0a43b8
@@ -87,7 +87,7 @@ ice_get_sw_fv_bitmap(struct ice_hw *hw,
Thomas Bogendoerfer 0a43b8
 void
Thomas Bogendoerfer 0a43b8
 ice_init_prof_result_bm(struct ice_hw *hw);
Thomas Bogendoerfer 0a43b8
 int
Thomas Bogendoerfer 0a43b8
-ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt,
Thomas Bogendoerfer 0a43b8
+ice_get_sw_fv_list(struct ice_hw *hw, struct ice_prot_lkup_ext *lkups,
Thomas Bogendoerfer 0a43b8
 		   unsigned long *bm, struct list_head *fv_list);
Thomas Bogendoerfer 0a43b8
 int
Thomas Bogendoerfer 0a43b8
 ice_pkg_buf_unreserve_section(struct ice_buf_build *bld, u16 count);
Thomas Bogendoerfer 0a43b8
--- a/drivers/net/ethernet/intel/ice/ice_switch.c
Thomas Bogendoerfer 0a43b8
+++ b/drivers/net/ethernet/intel/ice/ice_switch.c
Thomas Bogendoerfer 0a43b8
@@ -4735,41 +4735,6 @@ ice_create_recipe_group(struct ice_hw *h
Thomas Bogendoerfer 0a43b8
 }
Thomas Bogendoerfer 0a43b8
 
Thomas Bogendoerfer 0a43b8
 /**
Thomas Bogendoerfer 0a43b8
- * ice_get_fv - get field vectors/extraction sequences for spec. lookup types
Thomas Bogendoerfer 0a43b8
- * @hw: pointer to hardware structure
Thomas Bogendoerfer 0a43b8
- * @lkups: lookup elements or match criteria for the advanced recipe, one
Thomas Bogendoerfer 0a43b8
- *	   structure per protocol header
Thomas Bogendoerfer 0a43b8
- * @lkups_cnt: number of protocols
Thomas Bogendoerfer 0a43b8
- * @bm: bitmap of field vectors to consider
Thomas Bogendoerfer 0a43b8
- * @fv_list: pointer to a list that holds the returned field vectors
Thomas Bogendoerfer 0a43b8
- */
Thomas Bogendoerfer 0a43b8
-static int
Thomas Bogendoerfer 0a43b8
-ice_get_fv(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
Thomas Bogendoerfer 0a43b8
-	   unsigned long *bm, struct list_head *fv_list)
Thomas Bogendoerfer 0a43b8
-{
Thomas Bogendoerfer 0a43b8
-	u8 *prot_ids;
Thomas Bogendoerfer 0a43b8
-	int status;
Thomas Bogendoerfer 0a43b8
-	u16 i;
Thomas Bogendoerfer 0a43b8
-
Thomas Bogendoerfer 0a43b8
-	prot_ids = kcalloc(lkups_cnt, sizeof(*prot_ids), GFP_KERNEL);
Thomas Bogendoerfer 0a43b8
-	if (!prot_ids)
Thomas Bogendoerfer 0a43b8
-		return -ENOMEM;
Thomas Bogendoerfer 0a43b8
-
Thomas Bogendoerfer 0a43b8
-	for (i = 0; i < lkups_cnt; i++)
Thomas Bogendoerfer 0a43b8
-		if (!ice_prot_type_to_id(lkups[i].type, &prot_ids[i])) {
Thomas Bogendoerfer 0a43b8
-			status = -EIO;
Thomas Bogendoerfer 0a43b8
-			goto free_mem;
Thomas Bogendoerfer 0a43b8
-		}
Thomas Bogendoerfer 0a43b8
-
Thomas Bogendoerfer 0a43b8
-	/* Find field vectors that include all specified protocol types */
Thomas Bogendoerfer 0a43b8
-	status = ice_get_sw_fv_list(hw, prot_ids, lkups_cnt, bm, fv_list);
Thomas Bogendoerfer 0a43b8
-
Thomas Bogendoerfer 0a43b8
-free_mem:
Thomas Bogendoerfer 0a43b8
-	kfree(prot_ids);
Thomas Bogendoerfer 0a43b8
-	return status;
Thomas Bogendoerfer 0a43b8
-}
Thomas Bogendoerfer 0a43b8
-
Thomas Bogendoerfer 0a43b8
-/**
Thomas Bogendoerfer 0a43b8
  * ice_tun_type_match_word - determine if tun type needs a match mask
Thomas Bogendoerfer 0a43b8
  * @tun_type: tunnel type
Thomas Bogendoerfer 0a43b8
  * @mask: mask to be used for the tunnel
Thomas Bogendoerfer 0a43b8
@@ -4917,11 +4882,11 @@ ice_add_adv_recipe(struct ice_hw *hw, st
Thomas Bogendoerfer 0a43b8
 
Thomas Bogendoerfer 0a43b8
 	/* Get bitmap of field vectors (profiles) that are compatible with the
Thomas Bogendoerfer 0a43b8
 	 * rule request; only these will be searched in the subsequent call to
Thomas Bogendoerfer 0a43b8
-	 * ice_get_fv.
Thomas Bogendoerfer 0a43b8
+	 * ice_get_sw_fv_list.
Thomas Bogendoerfer 0a43b8
 	 */
Thomas Bogendoerfer 0a43b8
 	ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap);
Thomas Bogendoerfer 0a43b8
 
Thomas Bogendoerfer 0a43b8
-	status = ice_get_fv(hw, lkups, lkups_cnt, fv_bitmap, &rm->fv_list);
Thomas Bogendoerfer 0a43b8
+	status = ice_get_sw_fv_list(hw, lkup_exts, fv_bitmap, &rm->fv_list);
Thomas Bogendoerfer 0a43b8
 	if (status)
Thomas Bogendoerfer 0a43b8
 		goto err_unroll;
Thomas Bogendoerfer 0a43b8