Commit a6892c96 authored by Dan Nowlin's avatar Dan Nowlin Committed by Jeff Kirsher

ice: Fix for 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.
Signed-off-by: default avatarDan Nowlin <dan.nowlin@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 9d5c5a52
...@@ -3470,6 +3470,24 @@ ice_move_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 vsig, ...@@ -3470,6 +3470,24 @@ ice_move_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 vsig,
return 0; return 0;
} }
/**
* 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 *chg)
{
struct ice_chs_chg *pos, *tmp;
list_for_each_entry_safe(tmp, pos, chg, list_entry)
if (tmp->type == ICE_TCAM_ADD && tmp->tcam_idx == idx) {
list_del(&tmp->list_entry);
devm_kfree(ice_hw_to_dev(hw), tmp);
}
}
/** /**
* ice_prof_tcam_ena_dis - add enable or disable TCAM change * ice_prof_tcam_ena_dis - add enable or disable TCAM change
* @hw: pointer to the HW struct * @hw: pointer to the HW struct
...@@ -3489,14 +3507,19 @@ ice_prof_tcam_ena_dis(struct ice_hw *hw, enum ice_block blk, bool enable, ...@@ -3489,14 +3507,19 @@ ice_prof_tcam_ena_dis(struct ice_hw *hw, enum ice_block blk, bool enable,
enum ice_status status; enum ice_status status;
struct ice_chs_chg *p; struct ice_chs_chg *p;
/* Default: enable means change the low flag bit to don't care */ u8 vl_msk[ICE_TCAM_KEY_VAL_SZ] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
u8 dc_msk[ICE_TCAM_KEY_VAL_SZ] = { 0x01, 0x00, 0x00, 0x00, 0x00 }; 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 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 disabling, free the TCAM */
if (!enable) { 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->tcam_idx = 0;
tcam->in_use = 0; tcam->in_use = 0;
return status; return status;
...@@ -3612,11 +3635,12 @@ ice_adj_prof_priorities(struct ice_hw *hw, enum ice_block blk, u16 vsig, ...@@ -3612,11 +3635,12 @@ ice_adj_prof_priorities(struct ice_hw *hw, enum ice_block blk, u16 vsig,
* @blk: hardware block * @blk: hardware block
* @vsig: the VSIG to which this profile is to be added * @vsig: the VSIG to which this profile is to be added
* @hdl: the profile handle indicating the profile to add * @hdl: the profile handle indicating the profile to add
* @rev: true to add entries to the end of the list
* @chg: the change list * @chg: the change list
*/ */
static enum ice_status static enum ice_status
ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl, ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl,
struct list_head *chg) bool rev, struct list_head *chg)
{ {
/* Masks that ignore flags */ /* Masks that ignore flags */
u8 vl_msk[ICE_TCAM_KEY_VAL_SZ] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; u8 vl_msk[ICE_TCAM_KEY_VAL_SZ] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
...@@ -3625,7 +3649,7 @@ ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl, ...@@ -3625,7 +3649,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_prof_map *map;
struct ice_vsig_prof *t; struct ice_vsig_prof *t;
struct ice_chs_chg *p; struct ice_chs_chg *p;
u16 i; u16 vsig_idx, 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); map = ice_search_prof_id(hw, blk, hdl);
...@@ -3687,8 +3711,13 @@ ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl, ...@@ -3687,8 +3711,13 @@ ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl,
} }
/* add profile to VSIG */ /* add profile to VSIG */
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, list_add(&t->list,
&hw->blk[blk].xlt2.vsig_tbl[(vsig & ICE_VSIG_IDX_M)].prop_lst); &hw->blk[blk].xlt2.vsig_tbl[vsig_idx].prop_lst);
return 0; return 0;
...@@ -3728,7 +3757,7 @@ ice_create_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl, ...@@ -3728,7 +3757,7 @@ ice_create_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl,
if (status) if (status)
goto err_ice_create_prof_id_vsig; 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) if (status)
goto err_ice_create_prof_id_vsig; goto err_ice_create_prof_id_vsig;
...@@ -3753,11 +3782,13 @@ ice_create_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl, ...@@ -3753,11 +3782,13 @@ ice_create_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl,
* @blk: hardware block * @blk: hardware block
* @vsi: the initial VSI that will be in VSIG * @vsi: the initial VSI that will be in VSIG
* @lst: the list of profile that will be added to the VSIG * @lst: the list of profile that will be added to the VSIG
* @new_vsig: return of new VSIG
* @chg: the change list * @chg: the change list
*/ */
static enum ice_status static enum ice_status
ice_create_vsig_from_lst(struct ice_hw *hw, enum ice_block blk, u16 vsi, ice_create_vsig_from_lst(struct ice_hw *hw, enum ice_block blk, u16 vsi,
struct list_head *lst, struct list_head *chg) struct list_head *lst, u16 *new_vsig,
struct list_head *chg)
{ {
struct ice_vsig_prof *t; struct ice_vsig_prof *t;
enum ice_status status; enum ice_status status;
...@@ -3772,12 +3803,15 @@ ice_create_vsig_from_lst(struct ice_hw *hw, enum ice_block blk, u16 vsi, ...@@ -3772,12 +3803,15 @@ ice_create_vsig_from_lst(struct ice_hw *hw, enum ice_block blk, u16 vsi,
return status; return status;
list_for_each_entry(t, lst, list) { list_for_each_entry(t, lst, list) {
/* Reverse the order here since we are copying the list */
status = ice_add_prof_id_vsig(hw, blk, vsig, t->profile_cookie, status = ice_add_prof_id_vsig(hw, blk, vsig, t->profile_cookie,
chg); true, chg);
if (status) if (status)
return status; return status;
} }
*new_vsig = vsig;
return 0; return 0;
} }
...@@ -3899,7 +3933,8 @@ ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl) ...@@ -3899,7 +3933,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 * not sharing entries and we can simply add the new
* profile to the VSIG. * 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) if (status)
goto err_ice_add_prof_id_flow; goto err_ice_add_prof_id_flow;
...@@ -3910,7 +3945,8 @@ ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl) ...@@ -3910,7 +3945,8 @@ ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl)
} else { } else {
/* No match, so we need a new VSIG */ /* No match, so we need a new VSIG */
status = ice_create_vsig_from_lst(hw, blk, vsi, status = ice_create_vsig_from_lst(hw, blk, vsi,
&union_lst, &chg); &union_lst, &vsig,
&chg);
if (status) if (status)
goto err_ice_add_prof_id_flow; goto err_ice_add_prof_id_flow;
...@@ -4076,7 +4112,8 @@ ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl) ...@@ -4076,7 +4112,8 @@ ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl)
* new VSIG and TCAM entries * new VSIG and TCAM entries
*/ */
status = ice_create_vsig_from_lst(hw, blk, vsi, status = ice_create_vsig_from_lst(hw, blk, vsi,
&copy, &chg); &copy, &vsig,
&chg);
if (status) if (status)
goto err_ice_rem_prof_id_flow; goto err_ice_rem_prof_id_flow;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment