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
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 */
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);
es->ref_count = (u16 *)
ice_calloc(hw, es->count, sizeof(*es->ref_count));
+ es->written = (u8 *)
+ ice_calloc(hw, es->count, sizeof(*es->written));
+
if (!es->ref_count)
goto err;
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));
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)
- status = ice_prof_dec_ref(hw, blk,
- prof->tcam[i].prof_id);
-
if (status)
return ICE_ERR_HW_TABLE;
}
status = ice_rem_flow_all(hw, blk, pmap->profile_cookie);
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);
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)
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);
}
}
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);
}