net/sfc/base: add APIs for PTP privilege configuration
[dpdk.git] / drivers / net / ice / base / ice_flex_pipe.c
index 493bc4e..14e632f 100644 (file)
@@ -325,11 +325,11 @@ ice_pkg_enum_entry(struct ice_seg *ice_seg, struct ice_pkg_enum *state,
  * ice_boost_tcam_handler
  * @sect_type: section type
  * @section: pointer to section
- * @index: index of the boost tcam entry to be returned
- * @offset: pointer to receive absolute offset, always 0 for boost tcam sections
+ * @index: index of the boost TCAM entry to be returned
+ * @offset: pointer to receive absolute offset, always 0 for boost TCAM sections
  *
  * This is a callback function that can be passed to ice_pkg_enum_entry.
- * Handles enumeration of individual boost tcam entries.
+ * Handles enumeration of individual boost TCAM entries.
  */
 static void *
 ice_boost_tcam_handler(u32 sect_type, void *section, u32 index, u32 *offset)
@@ -501,7 +501,7 @@ void ice_init_pkg_hints(struct ice_hw *hw, struct ice_seg *ice_seg)
                label_name = ice_enum_labels(NULL, 0, &state, &val);
        }
 
-       /* Cache the appropriate boost tcam entry pointers */
+       /* Cache the appropriate boost TCAM entry pointers */
        for (i = 0; i < hw->tnl.count; i++) {
                ice_find_boost_entry(ice_seg, hw->tnl.tbl[i].boost_addr,
                                     &hw->tnl.tbl[i].boost_entry);
@@ -1078,7 +1078,7 @@ enum ice_status ice_download_pkg(struct ice_hw *hw, struct ice_seg *ice_seg)
  * @hw: pointer to the hardware structure
  * @pkg_hdr: pointer to the driver's package hdr
  *
- * Saves off the package details into the hw structure.
+ * Saves off the package details into the HW structure.
  */
 enum ice_status
 ice_init_pkg_info(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr)
@@ -1269,10 +1269,30 @@ void ice_free_seg(struct ice_hw *hw)
        if (hw->pkg_copy) {
                ice_free(hw, hw->pkg_copy);
                hw->pkg_copy = NULL;
+               hw->pkg_size = 0;
        }
        hw->seg = NULL;
 }
 
+/**
+ * ice_init_fd_mask_regs - initialize Flow Director mask registers
+ * @hw: pointer to the HW struct
+ *
+ * This function sets up the Flow Director mask registers to allow for complete
+ * masking off of any of the 24 Field Vector words. After this call, mask 0 will
+ * mask off all of FV index 0, mask 1 will mask off all of FV index 1, etc.
+ */
+static void ice_init_fd_mask_regs(struct ice_hw *hw)
+{
+       u16 i;
+
+       for (i = 0; i < hw->blk[ICE_BLK_FD].es.fvw; i++) {
+               wr32(hw, GLQF_FDMASK(i), i);
+               ice_debug(hw, ICE_DBG_INIT, "init fd mask(%d): %x = %x\n", i,
+                         GLQF_FDMASK(i), i);
+       }
+}
+
 /**
  * ice_init_pkg_regs - initialize additional package registers
  * @hw: pointer to the hardware structure
@@ -1286,6 +1306,8 @@ static void ice_init_pkg_regs(struct ice_hw *hw)
        /* setup Switch block input mask, which is 48-bits in two parts */
        wr32(hw, GL_PREEXT_L2_PMASK0(ICE_SW_BLK_IDX), ICE_SW_BLK_INP_MASK_L);
        wr32(hw, GL_PREEXT_L2_PMASK1(ICE_SW_BLK_IDX), ICE_SW_BLK_INP_MASK_H);
+       /* setup default flow director masks */
+       ice_init_fd_mask_regs(hw);
 }
 
 /**
@@ -1313,7 +1335,7 @@ static void ice_init_pkg_regs(struct ice_hw *hw)
  * ice_copy_and_init_pkg() instead of directly calling ice_init_pkg() in this
  * case.
  */
-static enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buf, u32 len)
+enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buf, u32 len)
 {
        struct ice_pkg_hdr *pkg;
        enum ice_status status;
@@ -1351,8 +1373,6 @@ static enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buf, u32 len)
                status = ICE_SUCCESS;
        }
 
-       /* Free a previous segment, if necessary */
-       ice_free_seg(hw);
        if (!status) {
                hw->seg = seg;
                /* on successful package download, update other required
@@ -1401,12 +1421,14 @@ enum ice_status ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len)
        buf_copy = (u8 *)ice_memdup(hw, buf, len, ICE_NONDMA_TO_NONDMA);
 
        status = ice_init_pkg(hw, buf_copy, len);
-       if (status)
+       if (status) {
                /* Free the copy, since we failed to initialize the package */
                ice_free(hw, buf_copy);
-       else
+       } else {
                /* Track the copied pkg so we can free it later */
                hw->pkg_copy = buf_copy;
+               hw->pkg_size = len;
+       }
 
        return status;
 }
@@ -1468,14 +1490,14 @@ ice_sw_fv_handler(u32 sect_type, void *section, u32 index, u32 *offset)
 /**
  * ice_get_sw_fv_list
  * @hw: pointer to the HW structure
- * @prot_ids: field vector to search for with a given protocol id
+ * @prot_ids: field vector to search for with a given protocol ID
  * @ids_cnt: lookup/protocol count
  * @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 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
+ * definition and profile ID information
  * NOTE: The caller of the function is responsible for freeing the memory
  * allocated for every list entry.
  */
@@ -1782,11 +1804,11 @@ void ice_pkg_buf_free(struct ice_hw *hw, struct ice_buf_build *bld)
 /* PTG Management */
 
 /**
- * ice_ptg_update_xlt1 - Updates packet type groups in hw via xlt1 table
+ * ice_ptg_update_xlt1 - Updates packet type groups in HW via XLT1 table
  * @hw: pointer to the hardware structure
- * @blk: hw block
+ * @blk: HW block
  *
- * This function will update the xlt1 hardware table to reflect the new
+ * This function will update the XLT1 hardware table to reflect the new
  * packet type group configuration.
  */
 enum ice_status ice_ptg_update_xlt1(struct ice_hw *hw, enum ice_block blk)
@@ -1817,7 +1839,7 @@ enum ice_status ice_ptg_update_xlt1(struct ice_hw *hw, enum ice_block blk)
 /**
  * ice_ptg_find_ptype - Search for packet type group using packet type (ptype)
  * @hw: pointer to the hardware structure
- * @blk: hw block
+ * @blk: HW block
  * @ptype: the ptype to search for
  * @ptg: pointer to variable that receives the PTG
  *
@@ -1838,7 +1860,7 @@ ice_ptg_find_ptype(struct ice_hw *hw, enum ice_block blk, u16 ptype, u8 *ptg)
 /**
  * ice_ptg_alloc_val - Allocates a new packet type group ID by value
  * @hw: pointer to the hardware structure
- * @blk: hw block
+ * @blk: HW block
  * @ptg: the ptg to allocate
  *
  * This function allocates a given packet type group ID specified by the ptg
@@ -1853,7 +1875,7 @@ void ice_ptg_alloc_val(struct ice_hw *hw, enum ice_block blk, u8 ptg)
 /**
  * ice_ptg_alloc - Find a free entry and allocates a new packet type group ID
  * @hw: pointer to the hardware structure
- * @blk: hw block
+ * @blk: HW block
  *
  * This function allocates and returns a new packet type group ID. Note
  * that 0 is the default packet type group, so successfully created PTGs will
@@ -1877,7 +1899,7 @@ u8 ice_ptg_alloc(struct ice_hw *hw, enum ice_block blk)
 /**
  * ice_ptg_free - Frees a packet type group
  * @hw: pointer to the hardware structure
- * @blk: hw block
+ * @blk: HW block
  * @ptg: the ptg ID to free
  *
  * This function frees a packet type group, and returns all the current ptypes
@@ -1902,7 +1924,7 @@ void ice_ptg_free(struct ice_hw *hw, enum ice_block blk, u8 ptg)
 /**
  * ice_ptg_remove_ptype - Removes ptype from a particular packet type group
  * @hw: pointer to the hardware structure
- * @blk: hw block
+ * @blk: HW block
  * @ptype: the ptype to remove
  * @ptg: the ptg to remove the ptype from
  *
@@ -1947,7 +1969,7 @@ ice_ptg_remove_ptype(struct ice_hw *hw, enum ice_block blk, u16 ptype, u8 ptg)
 /**
  * ice_ptg_add_mv_ptype - Adds/moves ptype to a particular packet type group
  * @hw: pointer to the hardware structure
- * @blk: hw block
+ * @blk: HW block
  * @ptype: the ptype to add or move
  * @ptg: the ptg to add or move the ptype to
  *
@@ -1998,10 +2020,10 @@ ice_ptg_add_mv_ptype(struct ice_hw *hw, enum ice_block blk, u16 ptype, u8 ptg)
 
 /* Block / table size info */
 struct ice_blk_size_details {
-       u16 xlt1;                       /* # xlt1 entries */
-       u16 xlt2;                       /* # xlt2 entries */
-       u16 prof_tcam;                  /* # profile id tcam entries */
-       u16 prof_id;                    /* # profile ids */
+       u16 xlt1;                       /* # XLT1 entries */
+       u16 xlt2;                       /* # XLT2 entries */
+       u16 prof_tcam;                  /* # profile ID TCAM entries */
+       u16 prof_id;                    /* # profile IDs */
        u8 prof_cdid_bits;              /* # cdid one-hot bits used in key */
        u16 prof_redir;                 /* # profile redirection entries */
        u16 es;                         /* # extraction sequence entries */
@@ -2079,7 +2101,7 @@ ice_match_prop_lst(struct LIST_HEAD_TYPE *list1, struct LIST_HEAD_TYPE *list2)
        /* profile cookies must compare, and in the exact same order to take
         * into account priority
         */
-       while (--count) {
+       while (count--) {
                if (tmp2->profile_cookie != tmp1->profile_cookie)
                        return false;
 
@@ -2093,13 +2115,13 @@ ice_match_prop_lst(struct LIST_HEAD_TYPE *list1, struct LIST_HEAD_TYPE *list2)
 /* VSIG Management */
 
 /**
- * ice_vsig_update_xlt2_sect - update one section of xlt2 table
+ * ice_vsig_update_xlt2_sect - update one section of XLT2 table
  * @hw: pointer to the hardware structure
- * @blk: hw block
- * @vsi: hw vsi number to program
- * @vsig: vsig for the vsi
+ * @blk: HW block
+ * @vsi: HW VSI number to program
+ * @vsig: vsig for the VSI
  *
- * This function will update the xlt2 hardware table with the input vsi
+ * This function will update the XLT2 hardware table with the input VSI
  * group configuration.
  */
 static enum ice_status
@@ -2128,11 +2150,11 @@ ice_vsig_update_xlt2_sect(struct ice_hw *hw, enum ice_block blk, u16 vsi,
 }
 
 /**
- * ice_vsig_update_xlt2 - update xlt2 table with VSIG configuration
+ * ice_vsig_update_xlt2 - update XLT2 table with VSIG configuration
  * @hw: pointer to the hardware structure
- * @blk: hw block
+ * @blk: HW block
  *
- * This function will update the xlt2 hardware table with the input vsi
+ * This function will update the XLT2 hardware table with the input VSI
  * group configuration of used vsis.
  */
 enum ice_status ice_vsig_update_xlt2(struct ice_hw *hw, enum ice_block blk)
@@ -2158,14 +2180,14 @@ enum ice_status ice_vsig_update_xlt2(struct ice_hw *hw, enum ice_block blk)
 }
 
 /**
- * ice_vsig_find_vsi - find a VSIG that contains a specified vsi
+ * ice_vsig_find_vsi - find a VSIG that contains a specified VSI
  * @hw: pointer to the hardware structure
- * @blk: hw block
- * @vsi: vsi of interest
- * @vsig: pointer to receive the vsi group
+ * @blk: HW block
+ * @vsi: VSI of interest
+ * @vsig: pointer to receive the VSI group
  *
- * This function will lookup the vsi entry in the XLT2 list and return
- * the vsi group its associated with.
+ * This function will lookup the VSI entry in the XLT2 list and return
+ * the VSI group its associated with.
  */
 enum ice_status
 ice_vsig_find_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 *vsig)
@@ -2174,7 +2196,7 @@ ice_vsig_find_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 *vsig)
                return ICE_ERR_PARAM;
 
        /* As long as there's a default or valid VSIG associated with the input
-        * vsi, the functions returns a success. Any handling of VSIG will be
+        * VSI, the functions returns a success. Any handling of VSIG will be
         * done by the following add, update or remove functions.
         */
        *vsig = hw->blk[blk].xlt2.vsis[vsi].vsig;
@@ -2185,7 +2207,7 @@ ice_vsig_find_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 *vsig)
 /**
  * ice_vsig_alloc_val - allocate a new VSIG by value
  * @hw: pointer to the hardware structure
- * @blk: hw block
+ * @blk: HW block
  * @vsig: the vsig to allocate
  *
  * This function will allocate a given VSIG specified by the vsig parameter.
@@ -2205,7 +2227,7 @@ static u16 ice_vsig_alloc_val(struct ice_hw *hw, enum ice_block blk, u16 vsig)
 /**
  * ice_vsig_alloc - Finds a free entry and allocates a new VSIG
  * @hw: pointer to the hardware structure
- * @blk: hw block
+ * @blk: HW block
  *
  * This function will iterate through the VSIG list and mark the first
  * unused entry for the new VSIG entry as used and return that value.
@@ -2222,16 +2244,16 @@ static u16 ice_vsig_alloc(struct ice_hw *hw, enum ice_block blk)
 }
 
 /**
- * ice_find_dup_props_vsig - find vsi group with a specified set of properties
+ * ice_find_dup_props_vsig - find VSI group with a specified set of properties
  * @hw: pointer to the hardware structure
- * @blk: hw block
+ * @blk: HW block
  * @chs: characteristic list
  * @vsig: returns the VSIG with the matching profiles, if found
  *
- * Each VSIG is associated with a characteristic set; i.e. all vsis under
+ * Each VSIG is associated with a characteristic set; i.e. all VSIs under
  * a group have the same characteristic set. To check if there exists a VSIG
  * which has the same characteristics as the input characteristics; this
- * function will iterate through the xlt2 list and return the VSIG that has a
+ * function will iterate through the XLT2 list and return the VSIG that has a
  * matching configuration. In order to make sure that priorities are accounted
  * for, the list must match exactly, including the order in which the
  * characteristics are listed.
@@ -2246,8 +2268,6 @@ ice_find_dup_props_vsig(struct ice_hw *hw, enum ice_block blk,
        for (i = 0; i < xlt2->count; i++) {
                if (xlt2->vsig_tbl[i].in_use &&
                    ice_match_prop_lst(chs, &xlt2->vsig_tbl[i].prop_lst)) {
-                       *vsig = (i | ((hw->pf_id << ICE_PF_NUM_S) &
-                                     ICE_PF_NUM_M));
                        *vsig = ICE_VSIG_VALUE(i, hw->pf_id);
                        return ICE_SUCCESS;
                }
@@ -2257,12 +2277,12 @@ ice_find_dup_props_vsig(struct ice_hw *hw, enum ice_block blk,
 }
 
 /**
- * ice_vsig_free - free vsi group
+ * ice_vsig_free - free VSI group
  * @hw: pointer to the hardware structure
- * @blk: hw block
+ * @blk: HW block
  * @vsig: VSIG to remove
  *
- * The function will remove all vsis associated with the input VSIG and move
+ * The function will remove all VSIs associated with the input VSIG and move
  * them to the DEFAULT_VSIG and mark the VSIG available.
  */
 enum ice_status
@@ -2282,21 +2302,23 @@ ice_vsig_free(struct ice_hw *hw, enum ice_block blk, u16 vsig)
        hw->blk[blk].xlt2.vsig_tbl[idx].in_use = false;
 
        vsi_cur = hw->blk[blk].xlt2.vsig_tbl[idx].first_vsi;
-       if (!vsi_cur)
-               return ICE_ERR_CFG;
-
-       /* remove all vsis associated with this VSIG XLT2 entry */
-       do {
-               struct ice_vsig_vsi *tmp = vsi_cur->next_vsi;
-
-               vsi_cur->vsig = ICE_DEFAULT_VSIG;
-               vsi_cur->changed = 1;
-               vsi_cur->next_vsi = NULL;
-               vsi_cur = tmp;
-       } while (vsi_cur);
-
-       /* NULL terminate head of vsi list */
-       hw->blk[blk].xlt2.vsig_tbl[idx].first_vsi = NULL;
+       /* If the VSIG has at least 1 VSI then iterate through the
+        * list and remove the VSIs before deleting the group.
+        */
+       if (vsi_cur) {
+               /* remove all vsis associated with this VSIG XLT2 entry */
+               do {
+                       struct ice_vsig_vsi *tmp = vsi_cur->next_vsi;
+
+                       vsi_cur->vsig = ICE_DEFAULT_VSIG;
+                       vsi_cur->changed = 1;
+                       vsi_cur->next_vsi = NULL;
+                       vsi_cur = tmp;
+               } while (vsi_cur);
+
+               /* NULL terminate head of VSI list */
+               hw->blk[blk].xlt2.vsig_tbl[idx].first_vsi = NULL;
+       }
 
        /* free characteristic list */
        LIST_FOR_EACH_ENTRY_SAFE(del, dtmp,
@@ -2310,14 +2332,14 @@ ice_vsig_free(struct ice_hw *hw, enum ice_block blk, u16 vsig)
 }
 
 /**
- * ice_vsig_add_mv_vsi - add or move a vsi to a vsi group
+ * ice_vsig_add_mv_vsi - add or move a VSI to a VSI group
  * @hw: pointer to the hardware structure
- * @blk: hw block
- * @vsi: vsi to move
- * @vsig: destination vsi group
+ * @blk: HW block
+ * @vsi: VSI to move
+ * @vsig: destination VSI group
  *
- * This function will move or add the input vsi to the target VSIG.
- * The function will find the original VSIG the vsi belongs to and
+ * This function will move or add the input VSI to the target VSIG.
+ * The function will find the original VSIG the VSI belongs to and
  * move the entry to the DEFAULT_VSIG, update the original VSIG and
  * then move entry to the new VSIG.
  */
@@ -2358,7 +2380,7 @@ ice_vsig_add_mv_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 vsig)
        if (idx == ICE_DEFAULT_VSIG)
                return ICE_SUCCESS;
 
-       /* Create vsi entry and add VSIG and prop_mask values */
+       /* Create VSI entry and add VSIG and prop_mask values */
        hw->blk[blk].xlt2.vsis[vsi].vsig = vsig;
        hw->blk[blk].xlt2.vsis[vsi].changed = 1;
 
@@ -2373,13 +2395,13 @@ ice_vsig_add_mv_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 vsig)
 }
 
 /**
- * ice_vsig_remove_vsi - remove vsi from VSIG
+ * ice_vsig_remove_vsi - remove VSI from VSIG
  * @hw: pointer to the hardware structure
- * @blk: hw block
- * @vsi: vsi to remove
- * @vsig: vsi group to remove from
+ * @blk: HW block
+ * @vsi: VSI to remove
+ * @vsig: VSI group to remove from
  *
- * The function will remove the input vsi from its vsi group and move it
+ * The function will remove the input VSI from its VSI group and move it
  * to the DEFAULT_VSIG.
  */
 enum ice_status
@@ -2396,7 +2418,7 @@ ice_vsig_remove_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 vsig)
        if (!hw->blk[blk].xlt2.vsig_tbl[idx].in_use)
                return ICE_ERR_DOES_NOT_EXIST;
 
-       /* entry already in default VSIG, dont have to remove */
+       /* entry already in default VSIG, don't have to remove */
        if (idx == ICE_DEFAULT_VSIG)
                return ICE_SUCCESS;
 
@@ -2407,7 +2429,7 @@ ice_vsig_remove_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 vsig)
        vsi_tgt = &hw->blk[blk].xlt2.vsis[vsi];
        vsi_cur = (*vsi_head);
 
-       /* iterate the vsi list, skip over the entry to be removed */
+       /* iterate the VSI list, skip over the entry to be removed */
        while (vsi_cur) {
                if (vsi_tgt == vsi_cur) {
                        (*vsi_head) = vsi_cur->next_vsi;
@@ -2417,7 +2439,7 @@ ice_vsig_remove_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 vsig)
                vsi_cur = vsi_cur->next_vsi;
        }
 
-       /* verify if vsi was removed from group list */
+       /* verify if VSI was removed from group list */
        if (!vsi_cur)
                return ICE_ERR_DOES_NOT_EXIST;
 
@@ -2429,11 +2451,11 @@ ice_vsig_remove_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 vsig)
 }
 
 /**
- * ice_find_prof_id - find profile id for a given field vector
+ * ice_find_prof_id - find profile ID for a given field vector
  * @hw: pointer to the hardware structure
- * @blk: hw block
+ * @blk: HW block
  * @fv: field vector to search for
- * @prof_id: receives the profile id
+ * @prof_id: receives the profile ID
  */
 static enum ice_status
 ice_find_prof_id(struct ice_hw *hw, enum ice_block blk,
@@ -2445,7 +2467,7 @@ ice_find_prof_id(struct ice_hw *hw, enum ice_block blk,
        for (i = 0; i < es->count; i++) {
                off = i * es->fvw;
 
-               if (memcmp(&es->t[off], fv, es->fvw * 2))
+               if (memcmp(&es->t[off], fv, es->fvw * sizeof(*fv)))
                        continue;
 
                *prof_id = i;
@@ -2456,7 +2478,7 @@ ice_find_prof_id(struct ice_hw *hw, enum ice_block blk,
 }
 
 /**
- * ice_prof_id_rsrc_type - get profile id resource type for a block type
+ * ice_prof_id_rsrc_type - get profile ID resource type for a block type
  * @blk: the block type
  * @rsrc_type: pointer to variable to receive the resource type
  */
@@ -2485,7 +2507,7 @@ static bool ice_prof_id_rsrc_type(enum ice_block blk, u16 *rsrc_type)
 }
 
 /**
- * ice_tcam_ent_rsrc_type - get tcam entry resource type for a block type
+ * ice_tcam_ent_rsrc_type - get TCAM entry resource type for a block type
  * @blk: the block type
  * @rsrc_type: pointer to variable to receive the resource type
  */
@@ -2514,203 +2536,10 @@ static bool ice_tcam_ent_rsrc_type(enum ice_block blk, u16 *rsrc_type)
 }
 
 /**
- * ice_workaround_get_res_blk - determine the block from a resource type
- * @type: type of resource
- * @blk: pointer to a enum that will receive the block type
- * @tcam: pointer to variable that will be set to true for a TCAM resource type
- */
-static enum
-ice_status ice_workaround_get_res_blk(u16 type, enum ice_block *blk, bool *tcam)
-{
-       /* just need to support TCAM entries and Profile IDs for now */
-       *tcam = false;
-
-       switch (type) {
-       case ICE_AQC_RES_TYPE_SWITCH_PROF_BLDR_TCAM:
-               *blk = ICE_BLK_SW;
-               *tcam = true;
-               break;
-       case ICE_AQC_RES_TYPE_ACL_PROF_BLDR_TCAM:
-               *blk = ICE_BLK_ACL;
-               *tcam = true;
-               break;
-       case ICE_AQC_RES_TYPE_FD_PROF_BLDR_TCAM:
-               *blk = ICE_BLK_FD;
-               *tcam = true;
-               break;
-       case ICE_AQC_RES_TYPE_HASH_PROF_BLDR_TCAM:
-               *blk = ICE_BLK_RSS;
-               *tcam = true;
-               break;
-       case ICE_AQC_RES_TYPE_QHASH_PROF_BLDR_TCAM:
-               *blk = ICE_BLK_PE;
-               *tcam = true;
-               break;
-       case ICE_AQC_RES_TYPE_SWITCH_PROF_BLDR_PROFID:
-               *blk = ICE_BLK_SW;
-               break;
-       case ICE_AQC_RES_TYPE_ACL_PROF_BLDR_PROFID:
-               *blk = ICE_BLK_ACL;
-               break;
-       case ICE_AQC_RES_TYPE_FD_PROF_BLDR_PROFID:
-               *blk = ICE_BLK_FD;
-               break;
-       case ICE_AQC_RES_TYPE_HASH_PROF_BLDR_PROFID:
-               *blk = ICE_BLK_RSS;
-               break;
-       case ICE_AQC_RES_TYPE_QHASH_PROF_BLDR_PROFID:
-               *blk = ICE_BLK_PE;
-               break;
-       default:
-               return ICE_ERR_PARAM;
-       }
-
-       return ICE_SUCCESS;
-}
-
-/**
- * ice_alloc_res_workaround
- * @hw: pointer to the hw struct
- * @type: type of resource
- * @num: number of resources to allocate
- * @res: pointer to array that will receive the resources
- */
-static enum ice_status
-ice_alloc_res_workaround(struct ice_hw *hw, u16 type, u16 num, u16 *res)
-{
-       enum ice_block blk;
-       u16 count = 0;
-       bool tcam;
-       u16 first;
-       u16 last;
-       u16 max;
-       u16 i;
-
-/* Number of PFs we support with this workaround */
-#define ICE_WA_PF_COUNT        4
-#define ICE_WA_1ST_TCAM        4
-#define ICE_WA_1ST_FV  4
-
-       /* Only allow our supported PFs */
-       if (hw->pf_id >= ICE_WA_PF_COUNT)
-               return ICE_ERR_AQ_ERROR;
-
-       if (ice_workaround_get_res_blk(type, &blk, &tcam))
-               return ICE_ERR_AQ_ERROR;
-
-       if (tcam) {
-               /* range of entries based on PF */
-               max = hw->blk[blk].prof.count / ICE_WA_PF_COUNT;
-               first = max * hw->pf_id;
-               last = first + max;
-
-               /* Profile IDs - start at non-zero index for PROF ID TCAM table
-                * The first few entries are for bypass, default and errors
-                * (only relevant for PF 0)
-                */
-               first += hw->pf_id ? 0 : ICE_WA_1ST_TCAM;
-
-               for (i = first; i < last && count < num; i++) {
-                       if (!hw->blk[blk].prof.resource_used_hack[i]) {
-                               res[count++] = i;
-                               hw->blk[blk].prof.resource_used_hack[i] = true;
-                       }
-               }
-
-               /* handle failure case */
-               if (count < num) {
-                       for (i = 0; i < count; i++) {
-                               hw->blk[blk].prof.resource_used_hack[res[i]] =
-                                       false;
-                               res[i] = 0;
-                       }
-
-                       return ICE_ERR_AQ_ERROR;
-               }
-       } else {
-               /* range of entries based on PF */
-               max = hw->blk[blk].es.count / ICE_WA_PF_COUNT;
-               first = max * hw->pf_id;
-               last = first + max;
-
-               /* FV index - start at non-zero index for Field vector table
-                * The first few entries are for bypass, default and errors
-                * (only relevant for PF 0)
-                */
-               first += hw->pf_id ? 0 : ICE_WA_1ST_FV;
-
-               for (i = first; i < last && count < num; i++) {
-                       if (!hw->blk[blk].es.resource_used_hack[i]) {
-                               res[count++] = i;
-                               hw->blk[blk].es.resource_used_hack[i] = true;
-                       }
-               }
-
-               /* handle failure case */
-               if (count < num) {
-                       for (i = 0; i < count; i++) {
-                               hw->blk[blk].es.resource_used_hack[res[i]] =
-                                       false;
-                               res[i] = 0;
-                       }
-
-                       return ICE_ERR_AQ_ERROR;
-               }
-       }
-
-       return ICE_SUCCESS;
-}
-
-/**
- * ice_free_res_workaround
- * @hw: pointer to the hw struct
- * @type: type of resource to free
- * @num: number of resources
- * @res: array of resource ids to free
- */
-static enum ice_status
-ice_free_res_workaround(struct ice_hw *hw, u16 type, u16 num, u16 *res)
-{
-       enum ice_block blk;
-       bool tcam = false;
-       u16 i;
-
-       if (ice_workaround_get_res_blk(type, &blk, &tcam))
-               return ICE_ERR_AQ_ERROR;
-
-       if (tcam) {
-               /* TCAM entries */
-               for (i = 0; i < num; i++) {
-                       if (res[i] < hw->blk[blk].prof.count) {
-                               u16 idx = res[i];
-
-                               ice_free_hw_res(hw, type, 1, &idx);
-                               hw->blk[blk].prof.resource_used_hack[res[i]] =
-                                       false;
-                       }
-               }
-
-       } else {
-               /* Profile IDs */
-               for (i = 0; i < num; i++) {
-                       if (res[i] < hw->blk[blk].es.count) {
-                               u16 idx = res[i];
-
-                               ice_free_hw_res(hw, type, 1, &idx);
-                               hw->blk[blk].es.resource_used_hack[res[i]] =
-                                       false;
-                       }
-               }
-       }
-
-       return ICE_SUCCESS;
-}
-
-/**
- * ice_alloc_tcam_ent - allocate hardware tcam entry
- * @hw: pointer to the hw struct
- * @blk: the block to allocate the tcam for
- * @tcam_idx: pointer to variable to receive the tcam entry
+ * ice_alloc_tcam_ent - allocate hardware TCAM entry
+ * @hw: pointer to the HW struct
+ * @blk: the block to allocate the TCAM for
+ * @tcam_idx: pointer to variable to receive the TCAM entry
  *
  * This function allocates a new entry in a Profile ID TCAM for a specific
  * block.
@@ -2723,14 +2552,14 @@ ice_alloc_tcam_ent(struct ice_hw *hw, enum ice_block blk, u16 *tcam_idx)
        if (!ice_tcam_ent_rsrc_type(blk, &res_type))
                return ICE_ERR_PARAM;
 
-       return ice_alloc_res_workaround(hw, res_type, 1, tcam_idx);
+       return ice_alloc_hw_res(hw, res_type, 1, true, tcam_idx);
 }
 
 /**
- * ice_free_tcam_ent - free hardware tcam entry
- * @hw: pointer to the hw struct
- * @blk: the block from which to free the tcam entry
- * @tcam_idx: the tcam entry to free
+ * ice_free_tcam_ent - free hardware TCAM entry
+ * @hw: pointer to the HW struct
+ * @blk: the block from which to free the TCAM entry
+ * @tcam_idx: the TCAM entry to free
  *
  * This function frees an entry in a Profile ID TCAM for a specific block.
  */
@@ -2742,16 +2571,16 @@ ice_free_tcam_ent(struct ice_hw *hw, enum ice_block blk, u16 tcam_idx)
        if (!ice_tcam_ent_rsrc_type(blk, &res_type))
                return ICE_ERR_PARAM;
 
-       return ice_free_res_workaround(hw, res_type, 1, &tcam_idx);
+       return ice_free_hw_res(hw, res_type, 1, &tcam_idx);
 }
 
 /**
- * ice_alloc_prof_id - allocate profile id
- * @hw: pointer to the hw struct
- * @blk: the block to allocate the profile id for
- * @prof_id: pointer to variable to receive the profile id
+ * ice_alloc_prof_id - allocate profile ID
+ * @hw: pointer to the HW struct
+ * @blk: the block to allocate the profile ID for
+ * @prof_id: pointer to variable to receive the profile ID
  *
- * This function allocates a new profile id, which also corresponds to a Field
+ * This function allocates a new profile ID, which also corresponds to a Field
  * Vector (Extraction Sequence) entry.
  */
 static enum ice_status
@@ -2764,7 +2593,7 @@ ice_alloc_prof_id(struct ice_hw *hw, enum ice_block blk, u8 *prof_id)
        if (!ice_prof_id_rsrc_type(blk, &res_type))
                return ICE_ERR_PARAM;
 
-       status = ice_alloc_res_workaround(hw, res_type, 1, &get_prof);
+       status = ice_alloc_hw_res(hw, res_type, 1, false, &get_prof);
        if (!status)
                *prof_id = (u8)get_prof;
 
@@ -2772,12 +2601,12 @@ ice_alloc_prof_id(struct ice_hw *hw, enum ice_block blk, u8 *prof_id)
 }
 
 /**
- * ice_free_prof_id - free profile id
- * @hw: pointer to the hw struct
- * @blk: the block from which to free the profile id
- * @prof_id: the profile id to free
+ * ice_free_prof_id - free profile ID
+ * @hw: pointer to the HW struct
+ * @blk: the block from which to free the profile ID
+ * @prof_id: the profile ID to free
  *
- * This function frees a profile id, which also corresponds to a Field Vector.
+ * This function frees a profile ID, which also corresponds to a Field Vector.
  */
 static enum ice_status
 ice_free_prof_id(struct ice_hw *hw, enum ice_block blk, u8 prof_id)
@@ -2788,22 +2617,14 @@ ice_free_prof_id(struct ice_hw *hw, enum ice_block blk, u8 prof_id)
        if (!ice_prof_id_rsrc_type(blk, &res_type))
                return ICE_ERR_PARAM;
 
-       return ice_free_res_workaround(hw, res_type, 1, &tmp_prof_id);
-       /* The following code is a WORKAROUND until DCR 076 is available.
-        * DCR 076 - Update to Profile ID TCAM Resource Allocation
-        *
-        * Once the DCR 076 changes are available in FW, this code can be
-        * restored. Original code:
-        *
-        * return ice_free_res(hw, res_type, 1, &tmp_prof_id);
-        */
+       return ice_free_hw_res(hw, res_type, 1, &tmp_prof_id);
 }
 
 /**
  * ice_prof_inc_ref - increment reference count for profile
- * @hw: pointer to the hw struct
- * @blk: the block from which to free the profile id
- * @prof_id: the profile id for which to increment the reference count
+ * @hw: pointer to the HW struct
+ * @blk: the block from which to free the profile ID
+ * @prof_id: the profile ID for which to increment the reference count
  */
 static enum ice_status
 ice_prof_inc_ref(struct ice_hw *hw, enum ice_block blk, u8 prof_id)
@@ -2816,11 +2637,35 @@ ice_prof_inc_ref(struct ice_hw *hw, enum ice_block blk, u8 prof_id)
        return ICE_SUCCESS;
 }
 
+/**
+ * ice_write_es - write an extraction sequence to hardware
+ * @hw: pointer to the HW struct
+ * @blk: the block in which to write the extraction sequence
+ * @prof_id: the profile ID to write
+ * @fv: pointer to the extraction sequence to write - NULL to clear extraction
+ */
+static void
+ice_write_es(struct ice_hw *hw, enum ice_block blk, u8 prof_id,
+            struct ice_fv_word *fv)
+{
+       u16 off;
+
+       off = prof_id * hw->blk[blk].es.fvw;
+       if (!fv) {
+               ice_memset(&hw->blk[blk].es.t[off], 0, hw->blk[blk].es.fvw *
+                          sizeof(*fv), ICE_NONDMA_MEM);
+               hw->blk[blk].es.written[prof_id] = false;
+       } else {
+               ice_memcpy(&hw->blk[blk].es.t[off], fv, hw->blk[blk].es.fvw *
+                          sizeof(*fv), ICE_NONDMA_TO_NONDMA);
+       }
+}
+
 /**
  * ice_prof_dec_ref - decrement reference count for profile
- * @hw: pointer to the hw struct
- * @blk: the block from which to free the profile id
- * @prof_id: the profile id for which to decrement the reference count
+ * @hw: pointer to the HW struct
+ * @blk: the block from which to free the profile ID
+ * @prof_id: the profile ID for which to decrement the reference count
  */
 static enum ice_status
 ice_prof_dec_ref(struct ice_hw *hw, enum ice_block blk, u8 prof_id)
@@ -2829,31 +2674,15 @@ ice_prof_dec_ref(struct ice_hw *hw, enum ice_block blk, u8 prof_id)
                return ICE_ERR_PARAM;
 
        if (hw->blk[blk].es.ref_count[prof_id] > 0) {
-               if (!--hw->blk[blk].es.ref_count[prof_id])
+               if (!--hw->blk[blk].es.ref_count[prof_id]) {
+                       ice_write_es(hw, blk, prof_id, NULL);
                        return ice_free_prof_id(hw, blk, prof_id);
+               }
        }
 
        return ICE_SUCCESS;
 }
 
-/**
- * ice_write_es - write an extraction sequence to hardware
- * @hw: pointer to the hw struct
- * @blk: the block in which to write the extraction sequence
- * @prof_id: the profile id to write
- * @fv: pointer to the extraction sequence to write
- */
-static void
-ice_write_es(struct ice_hw *hw, enum ice_block blk, u8 prof_id,
-            struct ice_fv_word *fv)
-{
-       u16 off;
-
-       off = prof_id * hw->blk[blk].es.fvw;
-       ice_memcpy(&hw->blk[blk].es.t[off], fv, hw->blk[blk].es.fvw * 2,
-                  ICE_NONDMA_TO_NONDMA);
-}
-
 /* Block / table section IDs */
 static const u32 ice_blk_sids[ICE_BLK_COUNT][ICE_SID_OFF_COUNT] = {
        /* SWITCH */
@@ -2921,7 +2750,7 @@ static void ice_fill_tbl(struct ice_hw *hw, enum ice_block block_id, u32 sid)
        u8 *src, *dst;
        void *sect;
 
-       /* if the hw segment pointer is null then the first iteration of
+       /* if the HW segment pointer is null then the first iteration of
         * ice_pkg_enum_section() will fail. In this case the Hw tables will
         * not be filled and return success.
         */
@@ -2936,9 +2765,11 @@ static void ice_fill_tbl(struct ice_hw *hw, enum ice_block block_id, u32 sid)
 
        while (sect) {
                switch (sid) {
+               case ICE_SID_XLT1_SW:
                case ICE_SID_XLT1_FD:
                case ICE_SID_XLT1_RSS:
                case ICE_SID_XLT1_ACL:
+               case ICE_SID_XLT1_PE:
                        xlt1 = (struct ice_xlt1_section *)sect;
                        src = xlt1->value;
                        sect_len = LE16_TO_CPU(xlt1->count) *
@@ -2947,9 +2778,11 @@ static void ice_fill_tbl(struct ice_hw *hw, enum ice_block block_id, u32 sid)
                        dst_len = hw->blk[block_id].xlt1.count *
                                sizeof(*hw->blk[block_id].xlt1.t);
                        break;
+               case ICE_SID_XLT2_SW:
                case ICE_SID_XLT2_FD:
                case ICE_SID_XLT2_RSS:
                case ICE_SID_XLT2_ACL:
+               case ICE_SID_XLT2_PE:
                        xlt2 = (struct ice_xlt2_section *)sect;
                        src = (u8 *)xlt2->value;
                        sect_len = LE16_TO_CPU(xlt2->count) *
@@ -2958,9 +2791,11 @@ static void ice_fill_tbl(struct ice_hw *hw, enum ice_block block_id, u32 sid)
                        dst_len = hw->blk[block_id].xlt2.count *
                                sizeof(*hw->blk[block_id].xlt2.t);
                        break;
+               case ICE_SID_PROFID_TCAM_SW:
                case ICE_SID_PROFID_TCAM_FD:
                case ICE_SID_PROFID_TCAM_RSS:
                case ICE_SID_PROFID_TCAM_ACL:
+               case ICE_SID_PROFID_TCAM_PE:
                        pid = (struct ice_prof_id_section *)sect;
                        src = (u8 *)pid->entry;
                        sect_len = LE16_TO_CPU(pid->count) *
@@ -2969,9 +2804,11 @@ static void ice_fill_tbl(struct ice_hw *hw, enum ice_block block_id, u32 sid)
                        dst_len = hw->blk[block_id].prof.count *
                                sizeof(*hw->blk[block_id].prof.t);
                        break;
+               case ICE_SID_PROFID_REDIR_SW:
                case ICE_SID_PROFID_REDIR_FD:
                case ICE_SID_PROFID_REDIR_RSS:
                case ICE_SID_PROFID_REDIR_ACL:
+               case ICE_SID_PROFID_REDIR_PE:
                        pr = (struct ice_prof_redir_section *)sect;
                        src = pr->redir_value;
                        sect_len = LE16_TO_CPU(pr->count) *
@@ -2980,15 +2817,19 @@ static void ice_fill_tbl(struct ice_hw *hw, enum ice_block block_id, u32 sid)
                        dst_len = hw->blk[block_id].prof_redir.count *
                                sizeof(*hw->blk[block_id].prof_redir.t);
                        break;
+               case ICE_SID_FLD_VEC_SW:
                case ICE_SID_FLD_VEC_FD:
                case ICE_SID_FLD_VEC_RSS:
                case ICE_SID_FLD_VEC_ACL:
+               case ICE_SID_FLD_VEC_PE:
                        es = (struct ice_sw_fv_section *)sect;
                        src = (u8 *)es->fv;
                        sect_len = LE16_TO_CPU(es->count) *
-                               sizeof(*hw->blk[block_id].prof_redir.t);
+                               hw->blk[block_id].es.fvw *
+                               sizeof(*hw->blk[block_id].es.t);
                        dst = (u8 *)hw->blk[block_id].es.t;
                        dst_len = hw->blk[block_id].es.count *
+                               hw->blk[block_id].es.fvw *
                                sizeof(*hw->blk[block_id].es.t);
                        break;
                default:
@@ -3072,7 +2913,7 @@ static void ice_free_flow_profs(struct ice_hw *hw)
 /**
  * ice_free_prof_map - frees the profile map
  * @hw: pointer to the hardware structure
- * @blk: the hw block which contains the profile map to be freed
+ * @blk: the HW block which contains the profile map to be freed
  */
 static void ice_free_prof_map(struct ice_hw *hw, enum ice_block blk)
 {
@@ -3083,15 +2924,14 @@ static void ice_free_prof_map(struct ice_hw *hw, enum ice_block blk)
 
        LIST_FOR_EACH_ENTRY_SAFE(del, tmp, &hw->blk[blk].es.prof_map,
                                 ice_prof_map, list) {
-               LIST_DEL(&del->list);
-               ice_free(hw, del);
+               ice_rem_prof(hw, blk, del->profile_cookie);
        }
 }
 
 /**
  * ice_free_vsig_tbl - free complete VSIG table entries
  * @hw: pointer to the hardware structure
- * @blk: the hw block on which to free the VSIG table entries
+ * @blk: the HW block on which to free the VSIG table entries
  */
 static void ice_free_vsig_tbl(struct ice_hw *hw, enum ice_block blk)
 {
@@ -3126,9 +2966,7 @@ void ice_free_hw_tbls(struct ice_hw *hw)
                ice_free(hw, hw->blk[i].prof_redir.t);
                ice_free(hw, hw->blk[i].es.t);
                ice_free(hw, hw->blk[i].es.ref_count);
-
-               ice_free(hw, hw->blk[i].es.resource_used_hack);
-               ice_free(hw, hw->blk[i].prof.resource_used_hack);
+               ice_free(hw, hw->blk[i].es.written);
        }
 
        ice_memset(hw->blk, 0, sizeof(hw->blk), ICE_NONDMA_MEM);
@@ -3151,9 +2989,9 @@ static void ice_init_flow_profs(struct ice_hw *hw)
 }
 
 /**
- * ice_init_sw_xlt1_db - init software xlt1 database from hw tables
+ * ice_init_sw_xlt1_db - init software XLT1 database from HW tables
  * @hw: pointer to the hardware structure
- * @blk: the hw block to initialize
+ * @blk: the HW block to initialize
  */
 static
 void ice_init_sw_xlt1_db(struct ice_hw *hw, enum ice_block blk)
@@ -3172,9 +3010,9 @@ void ice_init_sw_xlt1_db(struct ice_hw *hw, enum ice_block blk)
 }
 
 /**
- * ice_init_sw_xlt2_db - init software xlt2 database from hw tables
+ * ice_init_sw_xlt2_db - init software XLT2 database from HW tables
  * @hw: pointer to the hardware structure
- * @blk: the hw block to initialize
+ * @blk: the HW block to initialize
  */
 static
 void ice_init_sw_xlt2_db(struct ice_hw *hw, enum ice_block blk)
@@ -3197,7 +3035,7 @@ void ice_init_sw_xlt2_db(struct ice_hw *hw, enum ice_block blk)
 }
 
 /**
- * ice_init_sw_db - init software database from hw tables
+ * ice_init_sw_db - init software database from HW tables
  * @hw: pointer to the hardware structure
  */
 static
@@ -3298,19 +3136,10 @@ enum ice_status ice_init_hw_tbls(struct ice_hw *hw)
                es->ref_count = (u16 *)
                        ice_calloc(hw, es->count, sizeof(*es->ref_count));
 
-               if (!es->ref_count)
-                       goto err;
+               es->written = (u8 *)
+                       ice_calloc(hw, es->count, sizeof(*es->written));
 
-               es->resource_used_hack = (u8 *)
-                       ice_calloc(hw, hw->blk[i].es.count, sizeof(u8));
-
-               if (!es->resource_used_hack)
-                       goto err;
-
-               prof->resource_used_hack = (u8 *)ice_calloc(hw, prof->count,
-                                                           sizeof(u8));
-
-               if (!prof->resource_used_hack)
+               if (!es->ref_count)
                        goto err;
 
                INIT_LIST_HEAD(&es->prof_map);
@@ -3329,9 +3158,9 @@ err:
 }
 
 /**
- * ice_prof_gen_key - generate profile id key
- * @hw: pointer to the hw struct
- * @blk: the block in which to write profile id to
+ * ice_prof_gen_key - generate profile ID key
+ * @hw: pointer to the HW struct
+ * @blk: the block in which to write profile ID to
  * @ptg: packet type group (PTG) portion of key
  * @vsig: VSIG portion of key
  * @cdid: cdid portion of key
@@ -3339,7 +3168,7 @@ err:
  * @vl_msk: valid mask
  * @dc_msk: don't care mask
  * @nm_msk: never match mask
- * @key: output of profile id key
+ * @key: output of profile ID key
  */
 static enum ice_status
 ice_prof_gen_key(struct ice_hw *hw, enum ice_block blk, u8 ptg, u16 vsig,
@@ -3384,11 +3213,11 @@ ice_prof_gen_key(struct ice_hw *hw, enum ice_block blk, u8 ptg, u16 vsig,
 }
 
 /**
- * ice_tcam_write_entry - write tcam entry
- * @hw: pointer to the hw struct
- * @blk: the block in which to write profile id to
+ * ice_tcam_write_entry - write TCAM entry
+ * @hw: pointer to the HW struct
+ * @blk: the block in which to write profile ID to
  * @idx: the entry index to write to
- * @prof_id: profile id
+ * @prof_id: profile ID
  * @ptg: packet type group (PTG) portion of key
  * @vsig: VSIG portion of key
  * @cdid: cdid portion of key
@@ -3418,9 +3247,9 @@ ice_tcam_write_entry(struct ice_hw *hw, enum ice_block blk, u16 idx,
 }
 
 /**
- * ice_vsig_get_ref - returns number of vsis belong to a VSIG
+ * ice_vsig_get_ref - returns number of VSIs belong to a VSIG
  * @hw: pointer to the hardware structure
- * @blk: hw block
+ * @blk: HW block
  * @vsig: VSIG to query
  * @refs: pointer to variable to receive the reference count
  */
@@ -3446,7 +3275,7 @@ ice_vsig_get_ref(struct ice_hw *hw, enum ice_block blk, u16 vsig, u16 *refs)
 /**
  * ice_get_ptg - get or allocate a ptg for a ptype
  * @hw: pointer to the hardware structure
- * @blk: hw block
+ * @blk: HW block
  * @ptype: the ptype to retrieve the PTG for
  * @ptg: receives the PTG of the ptype
  * @add: receive boolean indicating whether PTG was added or not
@@ -3483,7 +3312,7 @@ ice_get_ptg(struct ice_hw *hw, enum ice_block blk, u16 ptype, u8 *ptg,
 /**
  * ice_has_prof_vsig - check to see if VSIG has a specific profile
  * @hw: pointer to the hardware structure
- * @blk: hw block
+ * @blk: HW block
  * @vsig: VSIG to check against
  * @hdl: profile handle
  */
@@ -3500,14 +3329,14 @@ ice_has_prof_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl)
        }
 
        ice_debug(hw, ICE_DBG_INIT,
-                 "Characteristic list for vsi group %d not found.\n",
+                 "Characteristic list for VSI group %d not found.\n",
                  vsig);
        return false;
 }
 
 /**
- * ice_prof_bld_es - build profile id extraction sequence changes
- * @hw: pointer to the hw struct
+ * ice_prof_bld_es - build profile ID extraction sequence changes
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @bld: the update package buffer build to add to
  * @chgs: the list of changes to make in hardware
@@ -3546,8 +3375,8 @@ ice_prof_bld_es(struct ice_hw *hw, enum ice_block blk,
 }
 
 /**
- * ice_prof_bld_tcam - build profile id tcam changes
- * @hw: pointer to the hw struct
+ * ice_prof_bld_tcam - build profile ID TCAM changes
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @bld: the update package buffer build to add to
  * @chgs: the list of changes to make in hardware
@@ -3559,8 +3388,7 @@ ice_prof_bld_tcam(struct ice_hw *hw, enum ice_block blk,
        struct ice_chs_chg *tmp;
 
        LIST_FOR_EACH_ENTRY(tmp, chgs, ice_chs_chg, list_entry) {
-               if ((tmp->type == ICE_TCAM_ADD && tmp->add_tcam_idx) ||
-                   tmp->type == ICE_TCAM_REM) {
+               if (tmp->type == ICE_TCAM_ADD && tmp->add_tcam_idx) {
                        struct ice_prof_id_section *p;
                        u32 id;
 
@@ -3586,7 +3414,7 @@ ice_prof_bld_tcam(struct ice_hw *hw, enum ice_block blk,
 }
 
 /**
- * ice_prof_bld_xlt1 - build xlt1 changes
+ * ice_prof_bld_xlt1 - build XLT1 changes
  * @blk: hardware block
  * @bld: the update package buffer build to add to
  * @chgs: the list of changes to make in hardware
@@ -3619,7 +3447,7 @@ ice_prof_bld_xlt1(enum ice_block blk, struct ice_buf_build *bld,
 }
 
 /**
- * ice_prof_bld_xlt2 - build xlt2 changes
+ * ice_prof_bld_xlt2 - build XLT2 changes
  * @blk: hardware block
  * @bld: the update package buffer build to add to
  * @chgs: the list of changes to make in hardware
@@ -3662,7 +3490,7 @@ ice_prof_bld_xlt2(enum ice_block blk, struct ice_buf_build *bld,
 
 /**
  * ice_upd_prof_hw - update hardware using the change list
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @chgs: the list of changes to make in hardware
  */
@@ -3690,7 +3518,6 @@ ice_upd_prof_hw(struct ice_hw *hw, enum ice_block blk,
                                es++;
                        break;
                case ICE_TCAM_ADD:
-               case ICE_TCAM_REM:
                        tcam++;
                        break;
                case ICE_VSIG_ADD:
@@ -3761,18 +3588,217 @@ error_tmp:
        return status;
 }
 
+/**
+ * ice_update_fd_mask - set Flow Director Field Vector mask for a profile
+ * @hw: pointer to the HW struct
+ * @prof_id: profile ID
+ * @mask_sel: mask select
+ *
+ * This function enable any of the masks selected by the mask select parameter
+ * for the profile specified.
+ */
+static void ice_update_fd_mask(struct ice_hw *hw, u16 prof_id, u32 mask_sel)
+{
+       wr32(hw, GLQF_FDMASK_SEL(prof_id), mask_sel);
+
+       ice_debug(hw, ICE_DBG_INIT, "fd mask(%d): %x = %x\n", prof_id,
+                 GLQF_FDMASK_SEL(prof_id), mask_sel);
+}
+
+#define ICE_SRC_DST_MAX_COUNT  8
+
+struct ice_fd_src_dst_pair {
+       u8 prot_id;
+       u8 count;
+       u16 off;
+};
+
+static const struct ice_fd_src_dst_pair ice_fd_pairs[] = {
+       /* These are defined in pairs */
+       { ICE_PROT_IPV4_OF_OR_S, 2, 12 },
+       { ICE_PROT_IPV4_OF_OR_S, 2, 16 },
+
+       { ICE_PROT_IPV4_IL, 2, 12 },
+       { ICE_PROT_IPV4_IL, 2, 16 },
+
+       { ICE_PROT_IPV6_OF_OR_S, 8, 8 },
+       { ICE_PROT_IPV6_OF_OR_S, 8, 24 },
+
+       { ICE_PROT_IPV6_IL, 8, 8 },
+       { ICE_PROT_IPV6_IL, 8, 24 },
+
+       { ICE_PROT_TCP_IL, 1, 0 },
+       { ICE_PROT_TCP_IL, 1, 2 },
+
+       { ICE_PROT_UDP_OF, 1, 0 },
+       { ICE_PROT_UDP_OF, 1, 2 },
+
+       { ICE_PROT_UDP_IL_OR_S, 1, 0 },
+       { ICE_PROT_UDP_IL_OR_S, 1, 2 },
+
+       { ICE_PROT_SCTP_IL, 1, 0 },
+       { ICE_PROT_SCTP_IL, 1, 2 }
+};
+
+#define ICE_FD_SRC_DST_PAIR_COUNT      ARRAY_SIZE(ice_fd_pairs)
+
+/**
+ * ice_update_fd_swap - set register appropriately for a FD FV extraction
+ * @hw: pointer to the HW struct
+ * @prof_id: profile ID
+ * @es: extraction sequence (length of array is determined by the block)
+ */
+static enum ice_status
+ice_update_fd_swap(struct ice_hw *hw, u16 prof_id, struct ice_fv_word *es)
+{
+       ice_declare_bitmap(pair_list, ICE_FD_SRC_DST_PAIR_COUNT);
+       u8 pair_start[ICE_FD_SRC_DST_PAIR_COUNT] = { 0 };
+#define ICE_FD_FV_NOT_FOUND (-2)
+       s8 first_free = ICE_FD_FV_NOT_FOUND;
+       u8 used[ICE_MAX_FV_WORDS] = { 0 };
+       s8 orig_free, si;
+       u32 mask_sel = 0;
+       u8 i, j, k;
+
+       ice_memset(pair_list, 0, sizeof(pair_list), ICE_NONDMA_MEM);
+
+       ice_init_fd_mask_regs(hw);
+
+       /* This code assumes that the Flow Director field vectors are assigned
+        * from the end of the FV indexes working towards the zero index, that
+        * only complete fields will be included and will be consecutive, and
+        * that there are no gaps between valid indexes.
+        */
+
+       /* Determine swap fields present */
+       for (i = 0; i < hw->blk[ICE_BLK_FD].es.fvw; i++) {
+               /* Find the first free entry, assuming right to left population.
+                * This is where we can start adding additional pairs if needed.
+                */
+               if (first_free == ICE_FD_FV_NOT_FOUND && es[i].prot_id !=
+                   ICE_PROT_INVALID)
+                       first_free = i - 1;
+
+               for (j = 0; j < ICE_FD_SRC_DST_PAIR_COUNT; j++) {
+                       if (es[i].prot_id == ice_fd_pairs[j].prot_id &&
+                           es[i].off == ice_fd_pairs[j].off) {
+                               ice_set_bit(j, pair_list);
+                               pair_start[j] = i;
+                       }
+               }
+       }
+
+       orig_free = first_free;
+
+       /* determine missing swap fields that need to be added */
+       for (i = 0; i < ICE_FD_SRC_DST_PAIR_COUNT; i += 2) {
+               u8 bit1 = ice_is_bit_set(pair_list, i + 1);
+               u8 bit0 = ice_is_bit_set(pair_list, i);
+
+               if (bit0 ^ bit1) {
+                       u8 index;
+
+                       /* add the appropriate 'paired' entry */
+                       if (!bit0)
+                               index = i;
+                       else
+                               index = i + 1;
+
+                       /* check for room */
+                       if (first_free + 1 < ice_fd_pairs[index].count)
+                               return ICE_ERR_MAX_LIMIT;
+
+                       /* place in extraction sequence */
+                       for (k = 0; k < ice_fd_pairs[index].count; k++) {
+                               es[first_free - k].prot_id =
+                                       ice_fd_pairs[index].prot_id;
+                               es[first_free - k].off =
+                                       ice_fd_pairs[index].off + (k * 2);
+
+                               /* keep track of non-relevant fields */
+                               mask_sel |= 1 << (first_free - k);
+                       }
+
+                       pair_start[index] = first_free;
+                       first_free -= ice_fd_pairs[index].count;
+               }
+       }
+
+       /* fill in the swap array */
+       si = hw->blk[ICE_BLK_FD].es.fvw - 1;
+       do {
+               u8 indexes_used = 1;
+
+               /* assume flat at this index */
+#define ICE_SWAP_VALID 0x80
+               used[si] = si | ICE_SWAP_VALID;
+
+               if (orig_free == ICE_FD_FV_NOT_FOUND || si <= orig_free) {
+                       si -= indexes_used;
+                       continue;
+               }
+
+               /* check for a swap location */
+               for (j = 0; j < ICE_FD_SRC_DST_PAIR_COUNT; j++) {
+                       if (es[si].prot_id == ice_fd_pairs[j].prot_id &&
+                           es[si].off == ice_fd_pairs[j].off) {
+                               u8 idx;
+
+                               /* determine the appropriate matching field */
+                               idx = j + ((j % 2) ? -1 : 1);
+
+                               indexes_used = ice_fd_pairs[idx].count;
+                               for (k = 0; k < indexes_used; k++) {
+                                       used[si - k] = (pair_start[idx] - k) |
+                                               ICE_SWAP_VALID;
+                               }
+
+                               break;
+                       }
+               }
+
+               si -= indexes_used;
+       } while (si >= 0);
+
+       /* for each set of 4 swap indexes, write the appropriate register */
+       for (j = 0; j < hw->blk[ICE_BLK_FD].es.fvw / 4; j++) {
+               u32 raw_entry = 0;
+
+               for (k = 0; k < 4; k++) {
+                       u8 idx;
+
+                       idx = (j * 4) + k;
+                       if (used[idx])
+                               raw_entry |= used[idx] << (k * 8);
+               }
+
+               /* write the appropriate register set, based on HW block */
+               wr32(hw, GLQF_FDSWAP(prof_id, j), raw_entry);
+
+               ice_debug(hw, ICE_DBG_INIT, "swap wr(%d, %d): %x = %x\n",
+                         prof_id, j, GLQF_FDSWAP(prof_id, j), raw_entry);
+       }
+
+       /* update the masks for this profile to be sure we ignore fields that
+        * are not relevant to our match criteria
+        */
+       ice_update_fd_mask(hw, prof_id, mask_sel);
+
+       return ICE_SUCCESS;
+}
+
 /**
  * ice_add_prof - add profile
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
- * @id: profile tracking id
+ * @id: profile tracking ID
  * @ptypes: array of bitmaps indicating ptypes (ICE_FLOW_PTYPE_MAX bits)
  * @es: extraction sequence (length of array is determined by the block)
  *
  * This function registers a profile, which matches a set of PTYPES with a
  * particular extraction sequence. While the hardware profile is allocated
  * it will not be written until the first call to ice_add_flow that specifies
- * the id value used here.
+ * the ID value used here.
  */
 enum ice_status
 ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
@@ -3787,15 +3813,29 @@ ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
        /* search for existing profile */
        status = ice_find_prof_id(hw, blk, es, &prof_id);
        if (status) {
-               /* allocate profile id */
+               /* allocate profile ID */
                status = ice_alloc_prof_id(hw, blk, &prof_id);
                if (status)
                        goto err_ice_add_prof;
+               if (blk == ICE_BLK_FD) {
+                       /* For Flow Director block, the extraction sequence may
+                        * need to be altered in the case where there are paired
+                        * fields that have no match. This is necessary because
+                        * for Flow Director, src and dest fields need to paired
+                        * for filter programming and these values are swapped
+                        * during Tx.
+                        */
+                       status = ice_update_fd_swap(hw, prof_id, es);
+                       if (status)
+                               goto err_ice_add_prof;
+               }
 
                /* and write new es */
                ice_write_es(hw, blk, prof_id, es);
        }
 
+       ice_prof_inc_ref(hw, blk, prof_id);
+
        /* add profile info */
 
        prof = (struct ice_prof_map *)ice_malloc(hw, sizeof(*prof));
@@ -3851,7 +3891,7 @@ err_ice_add_prof:
 
 /**
  * ice_search_prof_id - Search for a profile tracking ID
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @id: profile tracking ID
  *
@@ -3876,7 +3916,7 @@ ice_search_prof_id(struct ice_hw *hw, enum ice_block blk, u64 id)
 
 /**
  * ice_set_prof_context - Set context for a given profile
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @id: profile tracking ID
  * @cntxt: context
@@ -3895,7 +3935,7 @@ ice_set_prof_context(struct ice_hw *hw, enum ice_block blk, u64 id, u64 cntxt)
 
 /**
  * ice_get_prof_context - Get context for a given profile
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @id: profile tracking ID
  * @cntxt: pointer to variable to receive the context
@@ -3914,7 +3954,7 @@ ice_get_prof_context(struct ice_hw *hw, enum ice_block blk, u64 id, u64 *cntxt)
 
 /**
  * ice_vsig_prof_id_count - count profiles in a VSIG
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @vsig: VSIG to remove the profile from
  */
@@ -3933,8 +3973,8 @@ ice_vsig_prof_id_count(struct ice_hw *hw, enum ice_block blk, u16 vsig)
 }
 
 /**
- * ice_rel_tcam_idx - release a tcam index
- * @hw: pointer to the hw struct
+ * ice_rel_tcam_idx - release a TCAM index
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @idx: the index to release
  */
@@ -3947,13 +3987,13 @@ ice_rel_tcam_idx(struct ice_hw *hw, enum ice_block blk, u16 idx)
        u8 nm_msk[ICE_TCAM_KEY_VAL_SZ] = { 0x01, 0x00, 0x00, 0x00, 0x00 };
        enum ice_status status;
 
-       /* write the tcam entry */
+       /* write the TCAM entry */
        status = ice_tcam_write_entry(hw, blk, idx, 0, 0, 0, 0, 0, vl_msk,
                                      dc_msk, nm_msk);
        if (status)
                return status;
 
-       /* release the tcam entry */
+       /* release the TCAM entry */
        status = ice_free_tcam_ent(hw, blk, idx);
 
        return status;
@@ -3961,53 +4001,30 @@ ice_rel_tcam_idx(struct ice_hw *hw, enum ice_block blk, u16 idx)
 
 /**
  * ice_rem_prof_id - remove one profile from a VSIG
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
- * @vsig: VSIG to remove the profile from
  * @prof: pointer to profile structure to remove
- * @chg: pointer to list to record changes
  */
 static enum ice_status
-ice_rem_prof_id(struct ice_hw *hw, enum ice_block blk, u16 vsig,
-               struct ice_vsig_prof *prof, struct LIST_HEAD_TYPE *chg)
+ice_rem_prof_id(struct ice_hw *hw, enum ice_block blk,
+               struct ice_vsig_prof *prof)
 {
        enum ice_status status;
-       struct ice_chs_chg *p;
        u16 i;
 
        for (i = 0; i < prof->tcam_count; i++) {
-               p = (struct ice_chs_chg *)ice_malloc(hw, sizeof(*p));
-               if (!p)
-                       goto err_ice_rem_prof_id;
-
-               p->type = ICE_TCAM_REM;
-               p->vsig = vsig;
-               p->prof_id = prof->tcam[i].prof_id;
-               p->tcam_idx = prof->tcam[i].tcam_idx;
-
-               p->ptg = prof->tcam[i].ptg;
                prof->tcam[i].in_use = false;
-               p->orig_ent = hw->blk[blk].prof.t[p->tcam_idx];
-               status = ice_rel_tcam_idx(hw, blk, p->tcam_idx);
-               if (!status)
-                       status = ice_prof_dec_ref(hw, blk, p->prof_id);
-
-               LIST_ADD(&p->list_entry, chg);
-
+               status = ice_rel_tcam_idx(hw, blk, prof->tcam[i].tcam_idx);
                if (status)
-                       goto err_ice_rem_prof_id;
+                       return ICE_ERR_HW_TABLE;
        }
 
        return ICE_SUCCESS;
-
-err_ice_rem_prof_id:
-       /* caller will clean up the change list */
-       return ICE_ERR_NO_MEMORY;
 }
 
 /**
  * ice_rem_vsig - remove VSIG
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @vsig: the VSIG to remove
  * @chg: the change list
@@ -4025,9 +4042,9 @@ ice_rem_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig,
        LIST_FOR_EACH_ENTRY_SAFE(d, t,
                                 &hw->blk[blk].xlt2.vsig_tbl[idx].prop_lst,
                                 ice_vsig_prof, list) {
-               status = ice_rem_prof_id(hw, blk, vsig, d, chg);
+               status = ice_rem_prof_id(hw, blk, d);
                if (status)
-                       goto err_ice_rem_vsig;
+                       return status;
 
                LIST_DEL(&d->list);
                ice_free(hw, d);
@@ -4035,41 +4052,37 @@ ice_rem_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig,
 
        /* Move all VSIS associated with this VSIG to the default VSIG */
        vsi_cur = hw->blk[blk].xlt2.vsig_tbl[idx].first_vsi;
-       if (!vsi_cur)
-               return ICE_ERR_CFG;
-
-       do {
-               struct ice_vsig_vsi *tmp = vsi_cur->next_vsi;
-               struct ice_chs_chg *p;
-
-               p = (struct ice_chs_chg *)ice_malloc(hw, sizeof(*p));
-               if (!p)
-                       goto err_ice_rem_vsig;
+       /* If the VSIG has at least 1 VSI then iterate through the list
+        * and remove the VSIs before deleting the group.
+        */
+       if (vsi_cur) {
+               do {
+                       struct ice_vsig_vsi *tmp = vsi_cur->next_vsi;
+                       struct ice_chs_chg *p;
 
-               p->type = ICE_VSIG_REM;
-               p->orig_vsig = vsig;
-               p->vsig = ICE_DEFAULT_VSIG;
-               p->vsi = vsi_cur - hw->blk[blk].xlt2.vsis;
+                       p = (struct ice_chs_chg *)ice_malloc(hw, sizeof(*p));
+                       if (!p)
+                               return ICE_ERR_NO_MEMORY;
 
-               LIST_ADD(&p->list_entry, chg);
+                       p->type = ICE_VSIG_REM;
+                       p->orig_vsig = vsig;
+                       p->vsig = ICE_DEFAULT_VSIG;
+                       p->vsi = vsi_cur - hw->blk[blk].xlt2.vsis;
 
-               status = ice_vsig_free(hw, blk, vsig);
-               if (status)
-                       return status;
+                       LIST_ADD(&p->list_entry, chg);
 
-               vsi_cur = tmp;
-       } while (vsi_cur);
+                       vsi_cur = tmp;
+               } while (vsi_cur);
+       }
 
-       return ICE_SUCCESS;
+       status = ice_vsig_free(hw, blk, vsig);
 
-err_ice_rem_vsig:
-       /* the caller will free up the change list */
-       return ICE_ERR_NO_MEMORY;
+       return status;
 }
 
 /**
  * ice_rem_prof_id_vsig - remove a specific profile from a VSIG
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @vsig: VSIG to remove the profile from
  * @hdl: profile handle indicating which profile to remove
@@ -4091,7 +4104,7 @@ ice_rem_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl,
                                /* this is the last profile, remove the VSIG */
                                return ice_rem_vsig(hw, blk, vsig, chg);
 
-                       status = ice_rem_prof_id(hw, blk, vsig, p, chg);
+                       status = ice_rem_prof_id(hw, blk, p);
                        if (!status) {
                                LIST_DEL(&p->list);
                                ice_free(hw, p);
@@ -4105,7 +4118,7 @@ ice_rem_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl,
 
 /**
  * ice_rem_flow_all - remove all flows with a particular profile
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @id: profile tracking ID
  */
@@ -4143,11 +4156,11 @@ err_ice_rem_flow_all:
 
 /**
  * ice_rem_prof - remove profile
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @id: profile tracking ID
  *
- * This will remove the profile specified by the id parameter, which was
+ * This will remove the profile specified by the ID parameter, which was
  * previously created through ice_add_prof. If any existing entries
  * are associated with this profile, they will be removed as well.
  */
@@ -4160,15 +4173,18 @@ enum ice_status ice_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 id)
        if (!pmap)
                return ICE_ERR_DOES_NOT_EXIST;
 
-       status = ice_free_prof_id(hw, blk, pmap->prof_id);
-
+       /* remove all flows with this profile */
+       status = ice_rem_flow_all(hw, blk, pmap->profile_cookie);
        if (status)
                return status;
 
-       /* remove all flows with this profile */
-       status = ice_rem_flow_all(hw, blk, pmap->profile_cookie);
+       /* remove profile */
+       status = ice_free_prof_id(hw, blk, pmap->prof_id);
        if (status)
                return status;
+       /* dereference profile, and possibly remove */
+       ice_prof_dec_ref(hw, blk, pmap->prof_id);
+
        LIST_DEL(&pmap->list);
        ice_free(hw, pmap);
 
@@ -4177,7 +4193,7 @@ enum ice_status ice_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 id)
 
 /**
  * ice_get_prof_ptgs - get ptgs for profile
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @hdl: profile handle
  * @chg: change list
@@ -4190,7 +4206,7 @@ ice_get_prof_ptgs(struct ice_hw *hw, enum ice_block blk, u64 hdl,
        struct ice_chs_chg *p;
        u16 i;
 
-       /* Get the details on the profile specified by the handle id */
+       /* Get the details on the profile specified by the handle ID */
        map = ice_search_prof_id(hw, blk, hdl);
        if (!map)
                return ICE_ERR_DOES_NOT_EXIST;
@@ -4204,7 +4220,7 @@ ice_get_prof_ptgs(struct ice_hw *hw, enum ice_block blk, u64 hdl,
                if (status)
                        goto err_ice_get_prof_ptgs;
 
-               if (add || !hw->blk[blk].es.ref_count[map->prof_id]) {
+               if (add || !hw->blk[blk].es.written[map->prof_id]) {
                        /* add PTG to change list */
                        p = (struct ice_chs_chg *)ice_malloc(hw, sizeof(*p));
                        if (!p)
@@ -4215,9 +4231,11 @@ ice_get_prof_ptgs(struct ice_hw *hw, enum ice_block blk, u64 hdl,
                        p->ptg = ptg;
                        p->add_ptg = add;
 
-                       p->add_prof = !hw->blk[blk].es.ref_count[map->prof_id];
+                       p->add_prof = !hw->blk[blk].es.written[map->prof_id];
                        p->prof_id = map->prof_id;
 
+                       hw->blk[blk].es.written[map->prof_id] = true;
+
                        LIST_ADD(&p->list_entry, chg);
                }
        }
@@ -4231,7 +4249,7 @@ err_ice_get_prof_ptgs:
 
 /**
  * ice_get_profs_vsig - get a copy of the list of profiles from a VSIG
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @vsig: VSIG from which to copy the list
  * @lst: output list
@@ -4256,7 +4274,7 @@ ice_get_profs_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig,
 
                ice_memcpy(p, ent1, sizeof(*p), ICE_NONDMA_TO_NONDMA);
 
-               LIST_ADD(&p->list, lst);
+               LIST_ADD_TAIL(&p->list, lst);
        }
 
        return ICE_SUCCESS;
@@ -4272,7 +4290,7 @@ err_ice_get_profs_vsig:
 
 /**
  * ice_add_prof_to_lst - add profile entry to a list
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @lst: the list to be added to
  * @hdl: profile handle of entry to add
@@ -4298,17 +4316,12 @@ ice_add_prof_to_lst(struct ice_hw *hw, enum ice_block blk,
        p->tcam_count = map->ptype_count;
 
        for (i = 0; i < map->ptype_count; i++) {
-               enum ice_status status;
                u8 ptg;
 
                p->tcam[i].prof_id = map->prof_id;
                p->tcam[i].tcam_idx = ICE_INVALID_TCAM;
 
-               status = ice_ptg_find_ptype(hw, blk, map->ptype[i], &ptg);
-               if (status) {
-                       ice_free(hw, p);
-                       return status;
-               }
+               ice_ptg_find_ptype(hw, blk, map->ptype[i], &ptg);
 
                p->tcam[i].ptg = ptg;
        }
@@ -4320,7 +4333,7 @@ ice_add_prof_to_lst(struct ice_hw *hw, enum ice_block blk,
 
 /**
  * ice_move_vsi - move VSI to another VSIG
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @vsi: the VSI to move
  * @vsig: the VSIG to move the VSI to
@@ -4357,15 +4370,15 @@ ice_move_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 vsig,
 }
 
 /**
- * ice_prof_tcam_ena_dis - add enable or disable tcam change
- * @hw: pointer to the hw struct
+ * ice_prof_tcam_ena_dis - add enable or disable TCAM change
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @enable: true to enable, false to disable
- * @vsig: the vsig of the tcam entry
- * @tcam: pointer the tcam info structure of the tcam to disable
+ * @vsig: the vsig of the TCAM entry
+ * @tcam: pointer the TCAM info structure of the TCAM to disable
  * @chg: the change list
  *
- * This function appends an enable or disable tcam entry in the change log
+ * This function appends an enable or disable TCAM entry in the change log
  */
 static enum ice_status
 ice_prof_tcam_ena_dis(struct ice_hw *hw, enum ice_block blk, bool enable,
@@ -4418,7 +4431,7 @@ err_ice_prof_tcam_ena_dis:
 
 /**
  * ice_adj_prof_priorities - adjust profile based on priorities
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @vsig: the VSIG for which to adjust profile priorities
  * @chg: the change list
@@ -4487,7 +4500,7 @@ ice_adj_prof_priorities(struct ice_hw *hw, enum ice_block blk, u16 vsig,
 
 /**
  * ice_add_prof_id_vsig - add profile to VSIG
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @vsig: the VSIG to which this profile is to be added
  * @hdl: the profile handle indicating the profile to add
@@ -4506,7 +4519,7 @@ ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl,
        struct ice_chs_chg *p;
        u16 i;
 
-       /* Get the details on the profile specified by the handle id */
+       /* Get the details on the profile specified by the handle ID */
        map = ice_search_prof_id(hw, blk, hdl);
        if (!map)
                return ICE_ERR_DOES_NOT_EXIST;
@@ -4524,7 +4537,7 @@ ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl,
        t->prof_id = map->prof_id;
        t->tcam_count = map->ptype_count;
 
-       /* create tcam entries */
+       /* create TCAM entries */
        for (i = 0; i < map->ptype_count; i++) {
                enum ice_status status;
                u16 tcam_idx;
@@ -4543,10 +4556,12 @@ ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl,
                if (!p)
                        goto err_ice_add_prof_id_vsig;
 
-               /* allocate the tcam entry index */
+               /* allocate the TCAM entry index */
                status = ice_alloc_tcam_ent(hw, blk, &tcam_idx);
-               if (status)
+               if (status) {
+                       ice_free(hw, p);
                        goto err_ice_add_prof_id_vsig;
+               }
 
                t->tcam[i].ptg = ptg;
                t->tcam[i].prof_id = map->prof_id;
@@ -4560,7 +4575,7 @@ ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl,
                p->vsig = vsig;
                p->tcam_idx = t->tcam[i].tcam_idx;
 
-               /* write the tcam entry */
+               /* write the TCAM entry */
                status = ice_tcam_write_entry(hw, blk, t->tcam[i].tcam_idx,
                                              t->tcam[i].prof_id,
                                              t->tcam[i].ptg, vsig, 0, 0,
@@ -4568,11 +4583,6 @@ ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl,
                if (status)
                        goto err_ice_add_prof_id_vsig;
 
-               /* this increments the reference count of how many tcam entries
-                * are using this hw profile id
-                */
-               status = ice_prof_inc_ref(hw, blk, t->tcam[i].prof_id);
-
                /* log change */
                LIST_ADD(&p->list_entry, chg);
        }
@@ -4585,12 +4595,13 @@ ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl,
 
 err_ice_add_prof_id_vsig:
        /* let caller clean up the change list */
+       ice_free(hw, t);
        return ICE_ERR_NO_MEMORY;
 }
 
 /**
  * ice_create_prof_id_vsig - add a new VSIG with a single profile
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @vsi: the initial VSI that will be in VSIG
  * @hdl: the profile handle of the profile that will be added to the VSIG
@@ -4609,16 +4620,18 @@ ice_create_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl,
                return ICE_ERR_NO_MEMORY;
 
        new_vsig = ice_vsig_alloc(hw, blk);
-       if (!new_vsig)
-               return ICE_ERR_HW_TABLE;
+       if (!new_vsig) {
+               status = ICE_ERR_HW_TABLE;
+               goto err_ice_create_prof_id_vsig;
+       }
 
        status = ice_move_vsi(hw, blk, vsi, new_vsig, chg);
        if (status)
-               return status;
+               goto err_ice_create_prof_id_vsig;
 
        status = ice_add_prof_id_vsig(hw, blk, new_vsig, hdl, chg);
        if (status)
-               return status;
+               goto err_ice_create_prof_id_vsig;
 
        p->type = ICE_VSIG_ADD;
        p->vsi = vsi;
@@ -4628,11 +4641,16 @@ ice_create_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl,
        LIST_ADD(&p->list_entry, chg);
 
        return ICE_SUCCESS;
+
+err_ice_create_prof_id_vsig:
+       /* let caller clean up the change list */
+       ice_free(hw, p);
+       return status;
 }
 
 /**
  * ice_create_vsig_from_list - create a new VSIG with a list of profiles
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @vsi: the initial VSI that will be in VSIG
  * @lst: the list of profile that will be added to the VSIG
@@ -4666,7 +4684,7 @@ ice_create_vsig_from_lst(struct ice_hw *hw, enum ice_block blk, u16 vsi,
 
 /**
  * ice_find_prof_vsig - find a VSIG with a specific profile handle
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
  * @hdl: the profile handle of the profile to search for
  * @vsig: returns the VSIG with the matching profile
@@ -4697,13 +4715,13 @@ ice_find_prof_vsig(struct ice_hw *hw, enum ice_block blk, u64 hdl, u16 *vsig)
 
 /**
  * ice_add_prof_id_flow - add profile flow
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
- * @vsi: the vsi to enable with the profile specified by id
+ * @vsi: the VSI to enable with the profile specified by ID
  * @hdl: profile handle
  *
  * Calling this function will update the hardware tables to enable the
- * profile indicated by the id parameter for the VSIs specified in the vsi
+ * profile indicated by the ID parameter for the VSIs specified in the VSI
  * array. Once successfully called, the flow will be enabled.
  */
 enum ice_status
@@ -4725,7 +4743,7 @@ ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl)
        if (status)
                return status;
 
-       /* determine if vsi is already part of a VSIG */
+       /* determine if VSI is already part of a VSIG */
        status = ice_vsig_find_vsi(hw, blk, vsi, &vsig);
        if (!status && vsig) {
                bool only_vsi;
@@ -4763,14 +4781,13 @@ ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl)
                /* search for an existing VSIG with an exact charc match */
                status = ice_find_dup_props_vsig(hw, blk, &union_lst, &vsig);
                if (!status) {
-                       /* found an exact match */
-                       /* move vsi to the VSIG that matches */
+                       /* move VSI to the VSIG that matches */
                        status = ice_move_vsi(hw, blk, vsi, vsig, &chg);
                        if (status)
                                goto err_ice_add_prof_id_flow;
 
-                       /* remove original VSIG if we just moved the only VSI
-                        * from it
+                       /* VSI has been moved out of or_vsig. If the or_vsig had
+                        * only that VSI it is now empty and can be removed.
                         */
                        if (only_vsi) {
                                status = ice_rem_vsig(hw, blk, or_vsig, &chg);
@@ -4805,10 +4822,10 @@ ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl)
                }
        } else {
                /* need to find or add a VSIG */
-               /* search for an exising VSIG with an exact charc match */
+               /* search for an existing VSIG with an exact charc match */
                if (ice_find_prof_vsig(hw, blk, hdl, &vsig)) {
                        /* found an exact match */
-                       /* add or move vsi to the VSIG that matches */
+                       /* add or move VSI to the VSIG that matches */
                        status = ice_move_vsi(hw, blk, vsi, vsig, &chg);
                        if (status)
                                goto err_ice_add_prof_id_flow;
@@ -4847,14 +4864,14 @@ err_ice_add_prof_id_flow:
 
 /**
  * ice_add_flow - add flow
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
- * @vsi: array of VSIs to enable with the profile specified by id
- * @count: number of elements in the vsi array
- * @id: profile tracking id
+ * @vsi: array of VSIs to enable with the profile specified by ID
+ * @count: number of elements in the VSI array
+ * @id: profile tracking ID
  *
  * Calling this function will update the hardware tables to enable the
- * profile indicated by the id parameter for the VSIs specified in the vsi
+ * profile indicated by the ID parameter for the VSIs specified in the VSI
  * array. Once successfully called, the flow will be enabled.
  */
 enum ice_status
@@ -4875,7 +4892,7 @@ ice_add_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi[], u8 count,
 
 /**
  * ice_rem_prof_from_list - remove a profile from list
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @lst: list to remove the profile from
  * @hdl: the profile handle indicating the profile to remove
  */
@@ -4897,13 +4914,13 @@ ice_rem_prof_from_list(struct ice_hw *hw, struct LIST_HEAD_TYPE *lst, u64 hdl)
 
 /**
  * ice_rem_prof_id_flow - remove flow
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
- * @vsi: the vsi from which to remove the profile specified by id
+ * @vsi: the VSI from which to remove the profile specified by ID
  * @hdl: profile tracking handle
  *
  * Calling this function will update the hardware tables to remove the
- * profile indicated by the id parameter for the VSIs specified in the vsi
+ * profile indicated by the ID parameter for the VSIs specified in the VSI
  * array. Once successfully called, the flow will be disabled.
  */
 enum ice_status
@@ -4918,7 +4935,7 @@ ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl)
        INIT_LIST_HEAD(&copy);
        INIT_LIST_HEAD(&chg);
 
-       /* determine if vsi is already part of a VSIG */
+       /* determine if VSI is already part of a VSIG */
        status = ice_vsig_find_vsi(hw, blk, vsi, &vsig);
        if (!status && vsig) {
                bool last_profile;
@@ -4976,10 +4993,10 @@ ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl)
                                if (status)
                                        goto err_ice_rem_prof_id_flow;
 
-                       } else if (ice_find_dup_props_vsig(hw, blk, &copy,
-                                                          &vsig)) {
+                       } else if (!ice_find_dup_props_vsig(hw, blk, &copy,
+                                                           &vsig)) {
                                /* found an exact match */
-                               /* add or move vsi to the VSIG that matches */
+                               /* add or move VSI to the VSIG that matches */
                                /* Search for a VSIG with a matching profile
                                 * list
                                 */
@@ -4991,7 +5008,7 @@ ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl)
                        } else {
                                /* since no existing VSIG supports this
                                 * characteristic pattern, we need to create a
-                                * new VSIG and tcam entries
+                                * new VSIG and TCAM entries
                                 */
                                status = ice_create_vsig_from_lst(hw, blk, vsi,
                                                                  &copy, &chg);
@@ -5029,14 +5046,14 @@ err_ice_rem_prof_id_flow:
 
 /**
  * ice_rem_flow - remove flow
- * @hw: pointer to the hw struct
+ * @hw: pointer to the HW struct
  * @blk: hardware block
- * @vsi: array of VSIs from which to remove the profile specified by id
- * @count: number of elements in the vsi array
- * @id: profile tracking id
+ * @vsi: array of VSIs from which to remove the profile specified by ID
+ * @count: number of elements in the VSI array
+ * @id: profile tracking ID
  *
  * The function will remove flows from the specified VSIs that were enabled
- * using ice_add_flow. The id value will indicated which profile will be
+ * using ice_add_flow. The ID value will indicated which profile will be
  * removed. Once successfully called, the flow will be disabled.
  */
 enum ice_status