Commit 451f2c44 authored by Tony Nguyen's avatar Tony Nguyen Committed by Jeff Kirsher

ice: Populate TCAM filter software structures

Store the TCAM entry with the profile data and the VSI group in the
respective SW structures. This will be subsequently used to write out
the tables to hardware.
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: default avatarHenry Tieman <henry.w.tieman@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 31ad4e4e
......@@ -233,6 +233,7 @@ struct ice_aqc_get_sw_cfg_resp {
#define ICE_AQC_RES_TYPE_VSI_LIST_REP 0x03
#define ICE_AQC_RES_TYPE_VSI_LIST_PRUNE 0x04
#define ICE_AQC_RES_TYPE_HASH_PROF_BLDR_PROFID 0x60
#define ICE_AQC_RES_TYPE_HASH_PROF_BLDR_TCAM 0x61
#define ICE_AQC_RES_TYPE_FLAG_SCAN_BOTTOM BIT(12)
#define ICE_AQC_RES_TYPE_FLAG_IGNORE_INDEX BIT(13)
......
......@@ -1572,6 +1572,39 @@ ice_alloc_hw_res(struct ice_hw *hw, u16 type, u16 num, bool btm, u16 *res)
return status;
}
/**
* ice_free_hw_res - free allocated HW resource
* @hw: pointer to the HW struct
* @type: type of resource to free
* @num: number of resources
* @res: pointer to array that contains the resources to free
*/
enum ice_status
ice_free_hw_res(struct ice_hw *hw, u16 type, u16 num, u16 *res)
{
struct ice_aqc_alloc_free_res_elem *buf;
enum ice_status status;
u16 buf_len;
buf_len = struct_size(buf, elem, num - 1);
buf = kzalloc(buf_len, GFP_KERNEL);
if (!buf)
return ICE_ERR_NO_MEMORY;
/* Prepare buffer to free resource. */
buf->num_elems = cpu_to_le16(num);
buf->res_type = cpu_to_le16(type);
memcpy(buf->elem, res, sizeof(buf->elem) * num);
status = ice_aq_alloc_free_res(hw, num, buf, buf_len,
ice_aqc_opc_free_res, NULL);
if (status)
ice_debug(hw, ICE_DBG_SW, "CQ CMD Buffer:\n");
kfree(buf);
return status;
}
/**
* ice_get_num_per_func - determine number of resources per PF
* @hw: pointer to the HW structure
......
......@@ -36,6 +36,8 @@ ice_acquire_res(struct ice_hw *hw, enum ice_aq_res_ids res,
void ice_release_res(struct ice_hw *hw, enum ice_aq_res_ids res);
enum ice_status
ice_alloc_hw_res(struct ice_hw *hw, u16 type, u16 num, bool btm, u16 *res);
enum ice_status
ice_free_hw_res(struct ice_hw *hw, u16 type, u16 num, u16 *res);
enum ice_status ice_init_nvm(struct ice_hw *hw);
enum ice_status
ice_read_sr_buf(struct ice_hw *hw, u16 offset, u16 *words, u16 *data);
......
......@@ -21,6 +21,8 @@
enum ice_status
ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
struct ice_fv_word *es);
enum ice_status
ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buff, u32 len);
enum ice_status
ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len);
......
......@@ -283,6 +283,7 @@ struct ice_ptg_ptype {
u8 ptg;
};
#define ICE_MAX_TCAM_PER_PROFILE 32
#define ICE_MAX_PTG_PER_PROFILE 32
struct ice_prof_map {
......@@ -294,6 +295,23 @@ struct ice_prof_map {
u8 ptg[ICE_MAX_PTG_PER_PROFILE];
};
#define ICE_INVALID_TCAM 0xFFFF
struct ice_tcam_inf {
u16 tcam_idx;
u8 ptg;
u8 prof_id;
u8 in_use;
};
struct ice_vsig_prof {
struct list_head list;
u64 profile_cookie;
u8 prof_id;
u8 tcam_count;
struct ice_tcam_inf tcam[ICE_MAX_TCAM_PER_PROFILE];
};
struct ice_vsig_entry {
struct list_head prop_lst;
struct ice_vsig_vsi *first_vsi;
......@@ -343,6 +361,13 @@ struct ice_xlt2 {
u16 count;
};
/* Profile ID Management */
struct ice_prof_id_key {
__le16 flags;
u8 xlt1;
__le16 xlt2_cdid;
} __packed;
/* Keys are made up of two values, each one-half the size of the key.
* For TCAM, the entire key is 80 bits wide (or 2, 40-bit wide values)
*/
......@@ -385,5 +410,31 @@ struct ice_blk_info {
u8 is_list_init;
};
enum ice_chg_type {
ICE_TCAM_NONE = 0,
ICE_PTG_ES_ADD,
ICE_TCAM_ADD,
ICE_VSIG_ADD,
ICE_VSIG_REM,
ICE_VSI_MOVE,
};
struct ice_chs_chg {
struct list_head list_entry;
enum ice_chg_type type;
u8 add_ptg;
u8 add_vsig;
u8 add_tcam_idx;
u8 add_prof;
u16 ptype;
u8 ptg;
u8 prof_id;
u16 vsi;
u16 vsig;
u16 orig_vsig;
u16 tcam_idx;
};
#define ICE_FLOW_PTYPE_MAX ICE_XLT1_CNT
#endif /* _ICE_FLEX_TYPE_H_ */
......@@ -450,6 +450,38 @@ ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
return status;
}
/**
* ice_flow_assoc_prof - associate a VSI with a flow profile
* @hw: pointer to the hardware structure
* @blk: classification stage
* @prof: pointer to flow profile
* @vsi_handle: software VSI handle
*
* Assumption: the caller has acquired the lock to the profile list
* and the software VSI handle has been validated
*/
static enum ice_status
ice_flow_assoc_prof(struct ice_hw *hw, enum ice_block blk,
struct ice_flow_prof *prof, u16 vsi_handle)
{
enum ice_status status = 0;
if (!test_bit(vsi_handle, prof->vsis)) {
status = ice_add_prof_id_flow(hw, blk,
ice_get_hw_vsi_num(hw,
vsi_handle),
prof->id);
if (!status)
set_bit(vsi_handle, prof->vsis);
else
ice_debug(hw, ICE_DBG_FLOW,
"HW profile add failed, %d\n",
status);
}
return status;
}
/**
* ice_flow_add_prof - Add a flow profile for packet segments and matched fields
* @hw: pointer to the HW struct
......@@ -458,12 +490,13 @@ ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
* @prof_id: unique ID to identify this flow profile
* @segs: array of one or more packet segments that describe the flow
* @segs_cnt: number of packet segments provided
* @prof: stores the returned flow profile added
*/
static enum ice_status
ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
u64 prof_id, struct ice_flow_seg_info *segs, u8 segs_cnt)
u64 prof_id, struct ice_flow_seg_info *segs, u8 segs_cnt,
struct ice_flow_prof **prof)
{
struct ice_flow_prof *prof = NULL;
enum ice_status status;
if (segs_cnt > ICE_FLOW_SEG_MAX)
......@@ -482,9 +515,9 @@ ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
mutex_lock(&hw->fl_profs_locks[blk]);
status = ice_flow_add_prof_sync(hw, blk, dir, prof_id, segs, segs_cnt,
&prof);
prof);
if (!status)
list_add(&prof->l_entry, &hw->fl_profs[blk]);
list_add(&(*prof)->l_entry, &hw->fl_profs[blk]);
mutex_unlock(&hw->fl_profs_locks[blk]);
......@@ -634,6 +667,7 @@ ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u64 hash_fields,
/**
* ice_add_rss_cfg_sync - add an RSS configuration
* @hw: pointer to the hardware structure
* @vsi_handle: software VSI handle
* @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
* @addl_hdrs: protocol header fields
* @segs_cnt: packet segment count
......@@ -641,9 +675,11 @@ ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u64 hash_fields,
* Assumption: lock has already been acquired for RSS list
*/
static enum ice_status
ice_add_rss_cfg_sync(struct ice_hw *hw, u64 hashed_flds, u32 addl_hdrs,
u8 segs_cnt)
ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
u32 addl_hdrs, u8 segs_cnt)
{
const enum ice_block blk = ICE_BLK_RSS;
struct ice_flow_prof *prof = NULL;
struct ice_flow_seg_info *segs;
enum ice_status status;
......@@ -663,11 +699,15 @@ ice_add_rss_cfg_sync(struct ice_hw *hw, u64 hashed_flds, u32 addl_hdrs,
/* Create a new flow profile with generated profile and packet
* segment information.
*/
status = ice_flow_add_prof(hw, ICE_BLK_RSS, ICE_FLOW_RX,
status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX,
ICE_FLOW_GEN_PROFID(hashed_flds,
segs[segs_cnt - 1].hdrs,
segs_cnt),
segs, segs_cnt);
segs, segs_cnt, &prof);
if (status)
goto exit;
status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
exit:
kfree(segs);
......@@ -696,7 +736,7 @@ ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
return ICE_ERR_PARAM;
mutex_lock(&hw->rss_locks);
status = ice_add_rss_cfg_sync(hw, hashed_flds, addl_hdrs,
status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
ICE_RSS_OUTER_HEADERS);
mutex_unlock(&hw->rss_locks);
......@@ -719,7 +759,8 @@ enum ice_status ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
mutex_lock(&hw->rss_locks);
list_for_each_entry(r, &hw->rss_list_head, l_entry) {
if (test_bit(vsi_handle, r->vsis)) {
status = ice_add_rss_cfg_sync(hw, r->hashed_flds,
status = ice_add_rss_cfg_sync(hw, vsi_handle,
r->hashed_flds,
r->packet_hdr,
ICE_RSS_OUTER_HEADERS);
if (status)
......
......@@ -26,6 +26,7 @@ enum ice_status {
ICE_ERR_IN_USE = -16,
ICE_ERR_MAX_LIMIT = -17,
ICE_ERR_RESET_ONGOING = -18,
ICE_ERR_HW_TABLE = -19,
ICE_ERR_NVM_CHECKSUM = -51,
ICE_ERR_BUF_TOO_SHORT = -52,
ICE_ERR_NVM_BLANK_MODE = -53,
......
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