From: Qi Zhang Date: Tue, 12 Nov 2019 13:45:57 +0000 (+0800) Subject: net/ice/base: fix TCAM entry management X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=89a3286f9c59467d68c450a9fc3ab86b9eb64b89;p=dpdk.git net/ice/base: fix TCAM entry management Order intermediate VSIG list correct in order to correctly match existing VSIG lists. When overriding pre-existing TCAM entries, properly delete the existing entry and remove it from the change/update list. Fixes: 51d04e4933e3 ("net/ice/base: add flexible pipeline module") Signed-off-by: Dan Nowlin Signed-off-by: Qi Zhang Tested-by: Zhirun Yan --- diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c index dd098f5291..e8d4bbee40 100644 --- a/drivers/net/ice/base/ice_flex_pipe.c +++ b/drivers/net/ice/base/ice_flex_pipe.c @@ -5002,6 +5002,26 @@ static void ice_set_tcam_flags(u16 mask, u8 dc_mask[ICE_TCAM_KEY_VAL_SZ]) flag_word = (u16 *)dc_mask; *flag_word = ~mask; } + +/** + * ice_rem_chg_tcam_ent - remove a specific tcam entry from change list + * @hw: pointer to the HW struct + * @idx: the index of the tcam entry to remove + * @chg: the list of change structures to search + */ +static void +ice_rem_chg_tcam_ent(struct ice_hw *hw, u16 idx, struct LIST_HEAD_TYPE *chg) +{ + struct ice_chs_chg *pos, *tmp; + + LIST_FOR_EACH_ENTRY_SAFE(tmp, pos, chg, ice_chs_chg, list_entry) { + if (tmp->type == ICE_TCAM_ADD && tmp->tcam_idx == idx) { + LIST_DEL(&tmp->list_entry); + ice_free(hw, tmp); + } + } +} + /** * ice_prof_tcam_ena_dis - add enable or disable TCAM change * @hw: pointer to the HW struct @@ -5021,14 +5041,19 @@ ice_prof_tcam_ena_dis(struct ice_hw *hw, enum ice_block blk, bool enable, enum ice_status status; struct ice_chs_chg *p; - /* Default: enable means change the low flag bit to don't care */ - u8 dc_msk[ICE_TCAM_KEY_VAL_SZ] = { 0x01, 0x00, 0x00, 0x00, 0x00 }; + u8 vl_msk[ICE_TCAM_KEY_VAL_SZ] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + u8 dc_msk[ICE_TCAM_KEY_VAL_SZ] = { 0xFF, 0xFF, 0x00, 0x00, 0x00 }; 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 disabling, free the tcam */ if (!enable) { - status = ice_free_tcam_ent(hw, blk, tcam->tcam_idx); + status = ice_rel_tcam_idx(hw, blk, tcam->tcam_idx); + + /* if we have already created a change for this tcam entry, then + * we need to remove that entry, in order to prevent writing to + * a tcam entry we no longer will have ownership of. + */ + ice_rem_chg_tcam_ent(hw, tcam->tcam_idx, chg); tcam->tcam_idx = 0; tcam->in_use = 0; return status; @@ -5147,11 +5172,12 @@ ice_adj_prof_priorities(struct ice_hw *hw, enum ice_block blk, u16 vsig, * @blk: hardware block * @vsig: the VSIG to which this profile is to be added * @hdl: the profile handle indicating the profile to add + * @rev: true to reverse the additions to the list * @chg: the change list */ static enum ice_status ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl, - struct LIST_HEAD_TYPE *chg) + bool rev, struct LIST_HEAD_TYPE *chg) { /* Masks that ignore flags */ u8 vl_msk[ICE_TCAM_KEY_VAL_SZ] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; @@ -5160,7 +5186,7 @@ ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl, struct ice_prof_map *map; struct ice_vsig_prof *t; struct ice_chs_chg *p; - u16 i; + u16 vsig_idx, i; /* Get the details on the profile specified by the handle ID */ map = ice_search_prof_id(hw, blk, hdl); @@ -5227,8 +5253,13 @@ ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl, } /* add profile to VSIG */ - LIST_ADD(&t->list, - &hw->blk[blk].xlt2.vsig_tbl[(vsig & ICE_VSIG_IDX_M)].prop_lst); + vsig_idx = vsig & ICE_VSIG_IDX_M; + if (rev) + LIST_ADD_TAIL(&t->list, + &hw->blk[blk].xlt2.vsig_tbl[vsig_idx].prop_lst); + else + LIST_ADD(&t->list, + &hw->blk[blk].xlt2.vsig_tbl[vsig_idx].prop_lst); return ICE_SUCCESS; @@ -5268,7 +5299,7 @@ ice_create_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl, if (status) goto err_ice_create_prof_id_vsig; - status = ice_add_prof_id_vsig(hw, blk, new_vsig, hdl, chg); + status = ice_add_prof_id_vsig(hw, blk, new_vsig, hdl, false, chg); if (status) goto err_ice_create_prof_id_vsig; @@ -5297,7 +5328,8 @@ err_ice_create_prof_id_vsig: */ static enum ice_status ice_create_vsig_from_lst(struct ice_hw *hw, enum ice_block blk, u16 vsi, - struct LIST_HEAD_TYPE *lst, struct LIST_HEAD_TYPE *chg) + struct LIST_HEAD_TYPE *lst, u16 *new_vsig, + struct LIST_HEAD_TYPE *chg) { struct ice_vsig_prof *t; enum ice_status status; @@ -5312,12 +5344,15 @@ ice_create_vsig_from_lst(struct ice_hw *hw, enum ice_block blk, u16 vsi, return status; LIST_FOR_EACH_ENTRY(t, lst, ice_vsig_prof, list) { + /* Reverse the order here since we are copying the list */ status = ice_add_prof_id_vsig(hw, blk, vsig, t->profile_cookie, - chg); + true, chg); if (status) return status; } + *new_vsig = vsig; + return ICE_SUCCESS; } @@ -5481,7 +5516,8 @@ ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl) * not sharing entries and we can simply add the new * profile to the VSIG. */ - status = ice_add_prof_id_vsig(hw, blk, vsig, hdl, &chg); + status = ice_add_prof_id_vsig(hw, blk, vsig, hdl, false, + &chg); if (status) goto err_ice_add_prof_id_flow; @@ -5492,7 +5528,8 @@ ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl) } else { /* No match, so we need a new VSIG */ status = ice_create_vsig_from_lst(hw, blk, vsi, - &union_lst, &chg); + &union_lst, &vsig, + &chg); if (status) goto err_ice_add_prof_id_flow; @@ -5664,7 +5701,8 @@ ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl) * new VSIG and TCAM entries */ status = ice_create_vsig_from_lst(hw, blk, vsi, - ©, &chg); + ©, &vsig, + &chg); if (status) goto err_ice_rem_prof_id_flow;