X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fnet%2Fice%2Fbase%2Fice_flex_pipe.c;h=14e632fab89f0a9fd44ede647f807290804b6a27;hb=5f6bd807691e300b2d8c25c209fb778fa6692d61;hp=493bc4e9b01da58dcab755e8a87bc71c30a08602;hpb=329054ed1df3771df4b59214b5f69b7e6c5b2e8e;p=dpdk.git diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c index 493bc4e9b0..14e632fab8 100644 --- a/drivers/net/ice/base/ice_flex_pipe.c +++ b/drivers/net/ice/base/ice_flex_pipe.c @@ -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(©); 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, ©, - &vsig)) { + } else if (!ice_find_dup_props_vsig(hw, blk, ©, + &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, ©, &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