net/ice/base: replace alloc-followed-by-copy with memdup
[dpdk.git] / drivers / net / ice / base / ice_flex_pipe.c
index 29888df..76c26fd 100644 (file)
@@ -808,7 +808,6 @@ ice_aq_download_pkg(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf,
        return status;
 }
 
-
 /**
  * ice_aq_update_pkg
  * @hw: pointer to the hardware structure
@@ -961,9 +960,19 @@ ice_dwnld_cfg_bufs(struct ice_hw *hw, struct ice_buf *bufs, u32 count)
        if (LE32_TO_CPU(bh->section_entry[0].type) & ICE_METADATA_BUF)
                return ICE_SUCCESS;
 
+       /* reset pkg_dwnld_status in case this function is called in the
+        * reset/rebuild flow
+        */
+       hw->pkg_dwnld_status = ICE_AQ_RC_OK;
+
        status = ice_acquire_global_cfg_lock(hw, ICE_RES_WRITE);
-       if (status)
+       if (status) {
+               if (status == ICE_ERR_AQ_NO_WORK)
+                       hw->pkg_dwnld_status = ICE_AQ_RC_EEXIST;
+               else
+                       hw->pkg_dwnld_status = hw->adminq.sq_last_status;
                return status;
+       }
 
        for (i = 0; i < count; i++) {
                bool last = ((i + 1) == count);
@@ -986,6 +995,9 @@ ice_dwnld_cfg_bufs(struct ice_hw *hw, struct ice_buf *bufs, u32 count)
 
                status = ice_aq_download_pkg(hw, bh, ICE_PKG_BUF_SIZE, last,
                                             &offset, &info, NULL);
+
+               /* Save AQ status from download package */
+               hw->pkg_dwnld_status = hw->adminq.sq_last_status;
                if (status) {
                        ice_debug(hw, ICE_DBG_PKG,
                                  "Pkg download failed: err %d off %d inf %d\n",
@@ -1167,7 +1179,6 @@ init_pkg_free_alloc:
        return status;
 }
 
-
 /**
  * ice_verify_pkg - verify package
  * @pkg: pointer to the package buffer
@@ -1492,11 +1503,84 @@ ice_sw_fv_handler(u32 sect_type, void *section, u32 index, u32 *offset)
        return fv_section->fv + index;
 }
 
+/**
+ * ice_get_sw_prof_type - determine switch profile type
+ * @hw: pointer to the HW structure
+ * @fv: pointer to the switch field vector
+ */
+static enum ice_prof_type
+ice_get_sw_prof_type(struct ice_hw *hw, struct ice_fv *fv)
+{
+       u16 i;
+
+       for (i = 0; i < hw->blk[ICE_BLK_SW].es.fvw; i++) {
+               /* UDP tunnel will have UDP_OF protocol ID and VNI offset */
+               if (fv->ew[i].prot_id == (u8)ICE_PROT_UDP_OF &&
+                   fv->ew[i].off == ICE_VNI_OFFSET)
+                       return ICE_PROF_TUN_UDP;
+
+               /* GRE tunnel will have GRE protocol */
+               if (fv->ew[i].prot_id == (u8)ICE_PROT_GRE_OF)
+                       return ICE_PROF_TUN_GRE;
+
+               /* PPPOE tunnel will have PPPOE protocol */
+               if (fv->ew[i].prot_id == (u8)ICE_PROT_PPPOE)
+                       return ICE_PROF_TUN_PPPOE;
+       }
+
+       return ICE_PROF_NON_TUN;
+}
+
+/**
+ * ice_get_sw_fv_bitmap - Get switch field vector bitmap based on profile type
+ * @hw: pointer to hardware structure
+ * @type: type of profiles requested
+ * @bm: pointer to memory for returning the bitmap of field vectors
+ */
+void
+ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type type,
+                    ice_bitmap_t *bm)
+{
+       struct ice_pkg_enum state;
+       struct ice_seg *ice_seg;
+       struct ice_fv *fv;
+
+       if (type == ICE_PROF_ALL) {
+               u16 i;
+
+               for (i = 0; i < ICE_MAX_NUM_PROFILES; i++)
+                       ice_set_bit(i, bm);
+               return;
+       }
+
+       ice_zero_bitmap(bm, ICE_MAX_NUM_PROFILES);
+
+       ice_seg = hw->seg;
+       do {
+               enum ice_prof_type prof_type;
+               u32 offset;
+
+               fv = (struct ice_fv *)
+                       ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,
+                                          &offset, ice_sw_fv_handler);
+               ice_seg = NULL;
+
+               if (fv) {
+                       /* Determine field vector type */
+                       prof_type = ice_get_sw_prof_type(hw, fv);
+
+                       if (type & prof_type)
+                               ice_set_bit((u16)offset, bm);
+               }
+       } while (fv);
+}
+
 /**
  * ice_get_sw_fv_list
  * @hw: pointer to the HW structure
  * @prot_ids: field vector to search for with a given protocol ID
  * @ids_cnt: lookup/protocol count
+ * @bm: bitmap of field vectors to consider
  * @fv_list: Head of a list
  *
  * Finds all the field vector entries from switch block that contain
@@ -1508,7 +1592,7 @@ ice_sw_fv_handler(u32 sect_type, void *section, u32 index, u32 *offset)
  */
 enum ice_status
 ice_get_sw_fv_list(struct ice_hw *hw, u16 *prot_ids, u8 ids_cnt,
-                  struct LIST_HEAD_TYPE *fv_list)
+                  ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list)
 {
        struct ice_sw_fv_list_entry *fvl;
        struct ice_sw_fv_list_entry *tmp;
@@ -1527,8 +1611,17 @@ ice_get_sw_fv_list(struct ice_hw *hw, u16 *prot_ids, u8 ids_cnt,
                fv = (struct ice_fv *)
                        ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,
                                           &offset, ice_sw_fv_handler);
+               if (!fv)
+                       break;
+               ice_seg = NULL;
 
-               for (i = 0; i < ids_cnt && fv; i++) {
+               /* If field vector is not in the bitmap list, then skip this
+                * profile.
+                */
+               if (!ice_is_bit_set(bm, (u16)offset))
+                       continue;
+
+               for (i = 0; i < ids_cnt; i++) {
                        int j;
 
                        /* This code assumes that if a switch field vector line
@@ -1552,7 +1645,6 @@ ice_get_sw_fv_list(struct ice_hw *hw, u16 *prot_ids, u8 ids_cnt,
                                break;
                        }
                }
-               ice_seg = NULL;
        } while (fv);
        if (LIST_EMPTY(fv_list))
                return ICE_ERR_CFG;
@@ -1779,6 +1871,28 @@ ice_find_free_tunnel_entry(struct ice_hw *hw, enum ice_tunnel_type type,
        return false;
 }
 
+/**
+ * ice_get_tunnel_port - retrieve an open tunnel port
+ * @hw: pointer to the HW structure
+ * @type: tunnel type (TNL_ALL will return any open port)
+ * @port: returns open port
+ */
+bool
+ice_get_open_tunnel_port(struct ice_hw *hw, enum ice_tunnel_type type,
+                        u16 *port)
+{
+       u16 i;
+
+       for (i = 0; i < hw->tnl.count && i < ICE_TUNNEL_MAX_ENTRIES; i++)
+               if (hw->tnl.tbl[i].valid && hw->tnl.tbl[i].in_use &&
+                   (type == TNL_ALL || hw->tnl.tbl[i].type == type)) {
+                       *port = hw->tnl.tbl[i].port;
+                       return true;
+               }
+
+       return false;
+}
+
 /**
  * ice_create_tunnel
  * @hw: pointer to the HW structure
@@ -1805,7 +1919,7 @@ ice_create_tunnel(struct ice_hw *hw, enum ice_tunnel_type type, u16 port)
        if (!bld)
                return ICE_ERR_NO_MEMORY;
 
-       /* allocate 2 sections, one for RX parser, one for TX parser */
+       /* allocate 2 sections, one for Rx parser, one for Tx parser */
        if (ice_pkg_buf_reserve_section(bld, 2))
                goto ice_create_tunnel_err;
 
@@ -1835,7 +1949,7 @@ ice_create_tunnel(struct ice_hw *hw, enum ice_tunnel_type type, u16 port)
                    offsetof(struct ice_boost_key_value, hv_dst_port_key),
                    sizeof(sect_rx->tcam[0].key.key.hv_dst_port_key));
 
-       /* exact copy of entry to TX section entry */
+       /* exact copy of entry to Tx section entry */
        ice_memcpy(sect_tx->tcam, sect_rx->tcam, sizeof(*sect_tx->tcam),
                   ICE_NONDMA_TO_NONDMA);
 
@@ -1886,7 +2000,7 @@ enum ice_status ice_destroy_tunnel(struct ice_hw *hw, u16 port, bool all)
        if (!bld)
                return ICE_ERR_NO_MEMORY;
 
-       /* allocate 2 sections, one for RX parser, one for TX parser */
+       /* allocate 2 sections, one for Rx parser, one for Tx parser */
        if (ice_pkg_buf_reserve_section(bld, 2))
                goto ice_destroy_tunnel_err;
 
@@ -1904,8 +2018,8 @@ enum ice_status ice_destroy_tunnel(struct ice_hw *hw, u16 port, bool all)
                goto ice_destroy_tunnel_err;
        sect_tx->count = CPU_TO_LE16(1);
 
-       /* copy original boost entry to update package buffer, one copy to RX
-        * section, another copy to the TX section
+       /* copy original boost entry to update package buffer, one copy to Rx
+        * section, another copy to the Tx section
         */
        for (i = 0; i < hw->tnl.count && i < ICE_TUNNEL_MAX_ENTRIES; i++)
                if (hw->tnl.tbl[i].valid && hw->tnl.tbl[i].in_use &&
@@ -1968,7 +2082,6 @@ ice_find_prot_off(struct ice_hw *hw, enum ice_block blk, u8 prof, u8 fv_idx,
 
 /* PTG Management */
 
-
 /**
  * ice_ptg_find_ptype - Search for packet type group using packet type (ptype)
  * @hw: pointer to the hardware structure
@@ -2005,30 +2118,6 @@ void ice_ptg_alloc_val(struct ice_hw *hw, enum ice_block blk, u8 ptg)
        hw->blk[blk].xlt1.ptg_tbl[ptg].in_use = true;
 }
 
-/**
- * ice_ptg_alloc - Find a free entry and allocates a new packet type group ID
- * @hw: pointer to the hardware structure
- * @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
- * have a non-zero ID value; which means a 0 return value indicates an error.
- */
-static u8 ice_ptg_alloc(struct ice_hw *hw, enum ice_block blk)
-{
-       u16 i;
-
-       /* Skip the default PTG of 0 */
-       for (i = 1; i < ICE_MAX_PTGS; i++)
-               if (!hw->blk[blk].xlt1.ptg_tbl[i].in_use) {
-                       /* found a free PTG ID */
-                       ice_ptg_alloc_val(hw, blk, i);
-                       return (u8)i;
-               }
-
-       return 0;
-}
-
 /**
  * ice_ptg_remove_ptype - Removes ptype from a particular packet type group
  * @hw: pointer to the hardware structure
@@ -2222,7 +2311,6 @@ ice_match_prop_lst(struct LIST_HEAD_TYPE *list1, struct LIST_HEAD_TYPE *list2)
 
 /* VSIG Management */
 
-
 /**
  * ice_vsig_find_vsi - find a VSIG that contains a specified VSI
  * @hw: pointer to the hardware structure
@@ -2826,7 +2914,7 @@ ice_write_prof_mask_reg(struct ice_hw *hw, enum ice_block blk, u16 mask_idx,
  * ice_write_prof_mask_enable_res - write profile mask enable register
  * @hw: pointer to the HW struct
  * @blk: hardware block
- * @prof_id: profile id
+ * @prof_id: profile ID
  * @enable_mask: enable mask
  */
 static void
@@ -3002,7 +3090,7 @@ exit_ice_free_prof_mask:
  * ice_free_prof_masks - free all profile masks for a profile
  * @hw: pointer to the HW struct
  * @blk: hardware block
- * @prof_id: profile id
+ * @prof_id: profile ID
  */
 static enum ice_status
 ice_free_prof_masks(struct ice_hw *hw, enum ice_block blk, u16 prof_id)
@@ -3064,7 +3152,7 @@ void ice_shutdown_all_prof_masks(struct ice_hw *hw)
  * ice_update_prof_masking - set registers according to masking
  * @hw: pointer to the HW struct
  * @blk: hardware block
- * @prof_id: profile id
+ * @prof_id: profile ID
  * @es: field vector
  * @masks: masks
  */
@@ -3284,7 +3372,7 @@ static void ice_fill_tbl(struct ice_hw *hw, enum ice_block block_id, u32 sid)
        void *sect;
 
        /* 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
+        * ice_pkg_enum_section() will fail. In this case the HW tables will
         * not be filled and return success.
         */
        if (!hw->seg) {
@@ -3376,7 +3464,7 @@ static void ice_fill_tbl(struct ice_hw *hw, enum ice_block block_id, u32 sid)
                        return;
 
                /* if the sum of section size and offset exceed destination size
-                * then we are out of bounds of the Hw table size for that PF.
+                * then we are out of bounds of the HW table size for that PF.
                 * Changing section length to fill the remaining table space
                 * of that PF.
                 */
@@ -3395,7 +3483,7 @@ static void ice_fill_tbl(struct ice_hw *hw, enum ice_block block_id, u32 sid)
  *
  * Reads the current package contents and populates the driver
  * database with the data iteratively for all advanced feature
- * blocks. Assume that the Hw tables have been allocated.
+ * blocks. Assume that the HW tables have been allocated.
  */
 void ice_fill_blk_tbls(struct ice_hw *hw)
 {
@@ -3767,43 +3855,6 @@ ice_vsig_get_ref(struct ice_hw *hw, enum ice_block blk, u16 vsig, u16 *refs)
        return ICE_SUCCESS;
 }
 
-/**
- * ice_get_ptg - get or allocate a ptg for a ptype
- * @hw: pointer to the hardware structure
- * @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
- */
-static enum ice_status
-ice_get_ptg(struct ice_hw *hw, enum ice_block blk, u16 ptype, u8 *ptg,
-           bool *add)
-{
-       enum ice_status status;
-
-       *ptg = ICE_DEFAULT_PTG;
-       *add = false;
-
-       status = ice_ptg_find_ptype(hw, blk, ptype, ptg);
-       if (status)
-               return status;
-
-       if (*ptg == ICE_DEFAULT_PTG) {
-               /* need to allocate a PTG, and add ptype to it */
-               *ptg = ice_ptg_alloc(hw, blk);
-               if (*ptg == ICE_DEFAULT_PTG)
-                       return ICE_ERR_HW_TABLE;
-
-               status = ice_ptg_add_mv_ptype(hw, blk, ptype, *ptg);
-               if (status)
-                       return ICE_ERR_HW_TABLE;
-
-               *add = true;
-       }
-
-       return ICE_SUCCESS;
-};
-
 /**
  * ice_has_prof_vsig - check to see if VSIG has a specific profile
  * @hw: pointer to the hardware structure
@@ -4200,7 +4251,7 @@ ice_update_fd_swap(struct ice_hw *hw, u16 prof_id, struct ice_fv_word *es)
                                index = i + 1;
 
                        /* check for room */
-                       if (first_free + 1 < ice_fd_pairs[index].count)
+                       if (first_free + 1 < (s8)ice_fd_pairs[index].count)
                                return ICE_ERR_MAX_LIMIT;
 
                        /* place in extraction sequence */
@@ -4210,6 +4261,9 @@ ice_update_fd_swap(struct ice_hw *hw, u16 prof_id, struct ice_fv_word *es)
                                es[first_free - k].off =
                                        ice_fd_pairs[index].off + (k * 2);
 
+                               if (k > first_free)
+                                       return ICE_ERR_OUT_OF_RANGE;
+
                                /* keep track of non-relevant fields */
                                mask_sel |= 1 << (first_free - k);
                        }
@@ -4301,11 +4355,14 @@ ice_add_prof_with_mask(struct ice_hw *hw, enum ice_block blk, u64 id,
                       u8 ptypes[], struct ice_fv_word *es, u16 *masks)
 {
        u32 bytes = DIVIDE_AND_ROUND_UP(ICE_FLOW_PTYPE_MAX, BITS_PER_BYTE);
+       ice_declare_bitmap(ptgs_used, ICE_XLT1_CNT);
        struct ice_prof_map *prof;
        enum ice_status status;
        u32 byte = 0;
        u8 prof_id;
 
+       ice_zero_bitmap(ptgs_used, ICE_XLT1_CNT);
+
        ice_acquire_lock(&hw->blk[blk].es.prof_map_lock);
 
        /* search for existing profile */
@@ -4345,11 +4402,11 @@ ice_add_prof_with_mask(struct ice_hw *hw, enum ice_block blk, u64 id,
 
        prof->profile_cookie = id;
        prof->prof_id = prof_id;
-       prof->ptype_count = 0;
+       prof->ptg_cnt = 0;
        prof->context = 0;
 
        /* build list of ptgs */
-       while (bytes && prof->ptype_count < ICE_MAX_PTYPE_PER_PROFILE) {
+       while (bytes && prof->ptg_cnt < ICE_MAX_PTG_PER_PROFILE) {
                u32 bit;
 
                if (!ptypes[byte]) {
@@ -4361,16 +4418,27 @@ ice_add_prof_with_mask(struct ice_hw *hw, enum ice_block blk, u64 id,
                for (bit = 0; bit < 8; bit++) {
                        if (ptypes[byte] & BIT(bit)) {
                                u16 ptype;
+                               u8 ptg;
                                u8 m;
 
                                ptype = byte * BITS_PER_BYTE + bit;
-                               if (ptype < ICE_FLOW_PTYPE_MAX) {
-                                       prof->ptype[prof->ptype_count] = ptype;
 
-                                       if (++prof->ptype_count >=
-                                               ICE_MAX_PTYPE_PER_PROFILE)
-                                               break;
-                               }
+                               /* The package should place all ptypes in a
+                                * non-zero PTG, so the following call should
+                                * never fail.
+                                */
+                               if (ice_ptg_find_ptype(hw, blk, ptype, &ptg))
+                                       continue;
+
+                               /* If PTG is already added, skip and continue */
+                               if (ice_is_bit_set(ptgs_used, ptg))
+                                       continue;
+
+                               ice_set_bit(ptg, ptgs_used);
+                               prof->ptg[prof->ptg_cnt] = ptg;
+
+                               if (++prof->ptg_cnt >= ICE_MAX_PTG_PER_PROFILE)
+                                       break;
 
                                /* nothing left in byte, then exit */
                                m = ~((1 << (bit + 1)) - 1);
@@ -4399,7 +4467,7 @@ err_ice_add_prof:
  * @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
+ * This function registers a profile, which matches a set of PTGs 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.
@@ -4409,11 +4477,14 @@ ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
             struct ice_fv_word *es)
 {
        u32 bytes = DIVIDE_AND_ROUND_UP(ICE_FLOW_PTYPE_MAX, BITS_PER_BYTE);
+       ice_declare_bitmap(ptgs_used, ICE_XLT1_CNT);
        struct ice_prof_map *prof;
        enum ice_status status;
        u32 byte = 0;
        u8 prof_id;
 
+       ice_zero_bitmap(ptgs_used, ICE_XLT1_CNT);
+
        ice_acquire_lock(&hw->blk[blk].es.prof_map_lock);
 
        /* search for existing profile */
@@ -4450,11 +4521,11 @@ ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 
        prof->profile_cookie = id;
        prof->prof_id = prof_id;
-       prof->ptype_count = 0;
+       prof->ptg_cnt = 0;
        prof->context = 0;
 
        /* build list of ptgs */
-       while (bytes && prof->ptype_count < ICE_MAX_PTYPE_PER_PROFILE) {
+       while (bytes && prof->ptg_cnt < ICE_MAX_PTG_PER_PROFILE) {
                u32 bit;
 
                if (!ptypes[byte]) {
@@ -4464,18 +4535,29 @@ ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
                }
                /* Examine 8 bits per byte */
                for (bit = 0; bit < 8; bit++) {
-                       if (ptypes[byte] & 1 << bit) {
+                       if (ptypes[byte] & BIT(bit)) {
                                u16 ptype;
+                               u8 ptg;
                                u8 m;
 
                                ptype = byte * BITS_PER_BYTE + bit;
-                               if (ptype < ICE_FLOW_PTYPE_MAX) {
-                                       prof->ptype[prof->ptype_count] = ptype;
 
-                                       if (++prof->ptype_count >=
-                                               ICE_MAX_PTYPE_PER_PROFILE)
-                                               break;
-                               }
+                               /* The package should place all ptypes in a
+                                * non-zero PTG, so the following call should
+                                * never fail.
+                                */
+                               if (ice_ptg_find_ptype(hw, blk, ptype, &ptg))
+                                       continue;
+
+                               /* If PTG is already added, skip and continue */
+                               if (ice_is_bit_set(ptgs_used, ptg))
+                                       continue;
+
+                               ice_set_bit(ptg, ptgs_used);
+                               prof->ptg[prof->ptg_cnt] = ptg;
+
+                               if (++prof->ptg_cnt >= ICE_MAX_PTG_PER_PROFILE)
+                                       break;
 
                                /* nothing left in byte, then exit */
                                m = ~((1 << (bit + 1)) - 1);
@@ -4603,10 +4685,13 @@ ice_rem_prof_id(struct ice_hw *hw, enum ice_block blk,
        u16 i;
 
        for (i = 0; i < prof->tcam_count; i++) {
-               prof->tcam[i].in_use = false;
-               status = ice_rel_tcam_idx(hw, blk, prof->tcam[i].tcam_idx);
-               if (status)
-                       return ICE_ERR_HW_TABLE;
+               if (prof->tcam[i].in_use) {
+                       prof->tcam[i].in_use = false;
+                       status = ice_rel_tcam_idx(hw, blk,
+                                                 prof->tcam[i].tcam_idx);
+                       if (status)
+                               return ICE_ERR_HW_TABLE;
+               }
        }
 
        return ICE_SUCCESS;
@@ -4786,15 +4871,15 @@ err_ice_rem_prof:
 }
 
 /**
- * ice_get_prof_ptgs - get ptgs for profile
+ * ice_get_prof - get profile
  * @hw: pointer to the HW struct
  * @blk: hardware block
  * @hdl: profile handle
  * @chg: change list
  */
 static enum ice_status
-ice_get_prof_ptgs(struct ice_hw *hw, enum ice_block blk, u64 hdl,
-                 struct LIST_HEAD_TYPE *chg)
+ice_get_prof(struct ice_hw *hw, enum ice_block blk, u64 hdl,
+            struct LIST_HEAD_TYPE *chg)
 {
        struct ice_prof_map *map;
        struct ice_chs_chg *p;
@@ -4805,27 +4890,19 @@ ice_get_prof_ptgs(struct ice_hw *hw, enum ice_block blk, u64 hdl,
        if (!map)
                return ICE_ERR_DOES_NOT_EXIST;
 
-       for (i = 0; i < map->ptype_count; i++) {
-               enum ice_status status;
-               bool add;
-               u8 ptg;
-
-               status = ice_get_ptg(hw, blk, map->ptype[i], &ptg, &add);
-               if (status)
-                       goto err_ice_get_prof_ptgs;
-
-               if (add || !hw->blk[blk].es.written[map->prof_id]) {
-                       /* add PTG to change list */
+       for (i = 0; i < map->ptg_cnt; i++) {
+               if (!hw->blk[blk].es.written[map->prof_id]) {
+                       /* add ES to change list */
                        p = (struct ice_chs_chg *)ice_malloc(hw, sizeof(*p));
                        if (!p)
-                               goto err_ice_get_prof_ptgs;
+                               goto err_ice_get_prof;
 
                        p->type = ICE_PTG_ES_ADD;
-                       p->ptype = map->ptype[i];
-                       p->ptg = ptg;
-                       p->add_ptg = add;
+                       p->ptype = 0;
+                       p->ptg = map->ptg[i];
+                       p->add_ptg = 0;
 
-                       p->add_prof = !hw->blk[blk].es.written[map->prof_id];
+                       p->add_prof = 1;
                        p->prof_id = map->prof_id;
 
                        hw->blk[blk].es.written[map->prof_id] = true;
@@ -4836,7 +4913,7 @@ ice_get_prof_ptgs(struct ice_hw *hw, enum ice_block blk, u64 hdl,
 
        return ICE_SUCCESS;
 
-err_ice_get_prof_ptgs:
+err_ice_get_prof:
        /* let caller clean up the change list */
        return ICE_ERR_NO_MEMORY;
 }
@@ -4862,12 +4939,11 @@ ice_get_profs_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig,
                struct ice_vsig_prof *p;
 
                /* copy to the input list */
-               p = (struct ice_vsig_prof *)ice_malloc(hw, sizeof(*p));
+               p = (struct ice_vsig_prof *)ice_memdup(hw, ent1, sizeof(*p),
+                                                      ICE_NONDMA_TO_NONDMA);
                if (!p)
                        goto err_ice_get_profs_vsig;
 
-               ice_memcpy(p, ent1, sizeof(*p), ICE_NONDMA_TO_NONDMA);
-
                LIST_ADD_TAIL(&p->list, lst);
        }
 
@@ -4907,18 +4983,12 @@ ice_add_prof_to_lst(struct ice_hw *hw, enum ice_block blk,
 
        p->profile_cookie = map->profile_cookie;
        p->prof_id = map->prof_id;
-       p->tcam_count = map->ptype_count;
-
-       for (i = 0; i < map->ptype_count; i++) {
-               u8 ptg;
+       p->tcam_count = map->ptg_cnt;
 
+       for (i = 0; i < map->ptg_cnt; i++) {
                p->tcam[i].prof_id = map->prof_id;
                p->tcam[i].tcam_idx = ICE_INVALID_TCAM;
-
-               if (ice_ptg_find_ptype(hw, blk, map->ptype[i], &ptg))
-                       return ICE_ERR_CFG;
-
-               p->tcam[i].ptg = ptg;
+               p->tcam[i].ptg = map->ptg[i];
        }
 
        LIST_ADD(&p->list, lst);
@@ -4989,12 +5059,19 @@ ice_prof_tcam_ena_dis(struct ice_hw *hw, enum ice_block blk, bool enable,
        u8 nm_msk[ICE_TCAM_KEY_VAL_SZ] = { 0x00, 0x00, 0x00, 0x00, 0x00 };
        u8 vl_msk[ICE_TCAM_KEY_VAL_SZ] = { 0x01, 0x00, 0x00, 0x00, 0x00 };
 
-       /* If disabled, change the low flag bit to never match */
+       /* if disabling, free the tcam */
        if (!enable) {
-               dc_msk[0] = 0x00;
-               nm_msk[0] = 0x01;
+               status = ice_free_tcam_ent(hw, blk, tcam->tcam_idx);
+               tcam->tcam_idx = 0;
+               tcam->in_use = 0;
+               return status;
        }
 
+       /* for re-enabling, reallocate a tcam */
+       status = ice_alloc_tcam_ent(hw, blk, &tcam->tcam_idx);
+       if (status)
+               return status;
+
        /* add TCAM to change list */
        p = (struct ice_chs_chg *)ice_malloc(hw, sizeof(*p));
        if (!p)
@@ -5006,7 +5083,7 @@ ice_prof_tcam_ena_dis(struct ice_hw *hw, enum ice_block blk, bool enable,
        if (status)
                goto err_ice_prof_tcam_ena_dis;
 
-       tcam->in_use = enable;
+       tcam->in_use = 1;
 
        p->type = ICE_TCAM_ADD;
        p->add_tcam_idx = true;
@@ -5131,21 +5208,12 @@ ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl,
 
        t->profile_cookie = map->profile_cookie;
        t->prof_id = map->prof_id;
-       t->tcam_count = map->ptype_count;
+       t->tcam_count = map->ptg_cnt;
 
        /* create TCAM entries */
-       for (i = 0; i < map->ptype_count; i++) {
+       for (i = 0; i < map->ptg_cnt; i++) {
                enum ice_status status;
                u16 tcam_idx;
-               bool add;
-               u8 ptg;
-
-               /* If properly sequenced, we should never have to allocate new
-                * PTGs
-                */
-               status = ice_get_ptg(hw, blk, map->ptype[i], &ptg, &add);
-               if (status)
-                       goto err_ice_add_prof_id_vsig;
 
                /* add TCAM to change list */
                p = (struct ice_chs_chg *)ice_malloc(hw, sizeof(*p));
@@ -5159,7 +5227,7 @@ ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl,
                        goto err_ice_add_prof_id_vsig;
                }
 
-               t->tcam[i].ptg = ptg;
+               t->tcam[i].ptg = map->ptg[i];
                t->tcam[i].prof_id = map->prof_id;
                t->tcam[i].tcam_idx = tcam_idx;
                t->tcam[i].in_use = true;
@@ -5376,7 +5444,8 @@ ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl)
        INIT_LIST_HEAD(&chrs);
        INIT_LIST_HEAD(&chg);
 
-       status = ice_get_prof_ptgs(hw, blk, hdl, &chg);
+       /* Get profile */
+       status = ice_get_prof(hw, blk, hdl, &chg);
        if (status)
                return status;