/** * ice_parser_sect_item_get - parse an item from a section * @sect_type: section type * @section: section object * @index: index of the item to get * @offset: dummy as prototype of ice_pkg_enum_entry's last parameter * * Return: a pointer to the item or NULL.
*/ staticvoid *ice_parser_sect_item_get(u32 sect_type, void *section,
u32 index, u32 __maybe_unused *offset)
{
size_t data_off = ICE_SEC_DATA_OFFSET; struct ice_pkg_sect_hdr *hdr;
size_t size;
if (!section) return NULL;
switch (sect_type) { case ICE_SID_RXPARSER_IMEM:
size = ICE_SID_RXPARSER_IMEM_ENTRY_SIZE; break; case ICE_SID_RXPARSER_METADATA_INIT:
size = ICE_SID_RXPARSER_METADATA_INIT_ENTRY_SIZE; break; case ICE_SID_RXPARSER_CAM:
size = ICE_SID_RXPARSER_CAM_ENTRY_SIZE; break; case ICE_SID_RXPARSER_PG_SPILL:
size = ICE_SID_RXPARSER_PG_SPILL_ENTRY_SIZE; break; case ICE_SID_RXPARSER_NOMATCH_CAM:
size = ICE_SID_RXPARSER_NOMATCH_CAM_ENTRY_SIZE; break; case ICE_SID_RXPARSER_NOMATCH_SPILL:
size = ICE_SID_RXPARSER_NOMATCH_SPILL_ENTRY_SIZE; break; case ICE_SID_RXPARSER_BOOST_TCAM:
size = ICE_SID_RXPARSER_BOOST_TCAM_ENTRY_SIZE; break; case ICE_SID_LBL_RXPARSER_TMEM:
data_off = ICE_SEC_LBL_DATA_OFFSET;
size = ICE_SID_LBL_ENTRY_SIZE; break; case ICE_SID_RXPARSER_MARKER_PTYPE:
size = ICE_SID_RXPARSER_MARKER_TYPE_ENTRY_SIZE; break; case ICE_SID_RXPARSER_MARKER_GRP:
size = ICE_SID_RXPARSER_MARKER_GRP_ENTRY_SIZE; break; case ICE_SID_RXPARSER_PROTO_GRP:
size = ICE_SID_RXPARSER_PROTO_GRP_ENTRY_SIZE; break; case ICE_SID_RXPARSER_FLAG_REDIR:
size = ICE_SID_RXPARSER_FLAG_REDIR_ENTRY_SIZE; break; default: return NULL;
}
hdr = section; if (index >= le16_to_cpu(hdr->count)) return NULL;
return section + data_off + index * size;
}
/** * ice_parser_create_table - create an item table from a section * @hw: pointer to the hardware structure * @sect_type: section type * @item_size: item size in bytes * @length: number of items in the table to create * @parse_item: the function to parse the item * @no_offset: ignore header offset, calculate index from 0 * * Return: a pointer to the allocated table or ERR_PTR.
*/ staticvoid *
ice_parser_create_table(struct ice_hw *hw, u32 sect_type,
u32 item_size, u32 length, void (*parse_item)(struct ice_hw *hw, u16 idx, void *item, void *data, int size), bool no_offset)
{ struct ice_pkg_enum state = {}; struct ice_seg *seg = hw->seg; void *table, *data, *item;
u16 idx = 0;
if (!seg) return ERR_PTR(-EINVAL);
table = kzalloc(item_size * length, GFP_KERNEL); if (!table) return ERR_PTR(-ENOMEM);
do {
data = ice_pkg_enum_entry(seg, &state, sect_type, NULL,
ice_parser_sect_item_get);
seg = NULL; if (data) { struct ice_pkg_sect_hdr *hdr = state.sect;
if (!no_offset)
idx = le16_to_cpu(hdr->offset) +
state.entry_idx;
/** * ice_imem_alu_init - parse 96 bits of ALU entry * @alu: pointer to the ALU entry structure * @data: ALU entry data to be parsed * @off: offset of the ALU entry data
*/ staticvoid ice_imem_alu_init(struct ice_alu *alu, u8 *data, u8 off)
{
u64 d64;
u8 idd;
if (hw->debug_mask & ICE_DBG_PARSER)
ice_metainit_dump(hw, mi);
}
/** * ice_metainit_table_get - create a metainit table * @hw: pointer to the hardware structure * * Return: a pointer to the allocated Metadata initialization table.
*/ staticstruct ice_metainit_item *ice_metainit_table_get(struct ice_hw *hw)
{ return ice_parser_create_table(hw, ICE_SID_RXPARSER_METADATA_INIT, sizeof(struct ice_metainit_item),
ICE_METAINIT_TABLE_SIZE,
ice_metainit_parse_item, false);
}
/** * ice_bst_tcam_search - find a TCAM item with specific type * @tcam_table: the TCAM table * @lbl_table: the lbl table to search * @type: the type we need to match against * @start: start searching from this index * * Return: a pointer to the matching BOOST TCAM item or NULL.
*/ struct ice_bst_tcam_item *
ice_bst_tcam_search(struct ice_bst_tcam_item *tcam_table, struct ice_lbl_item *lbl_table, enum ice_lbl_type type, u16 *start)
{
u16 i = *start;
for (; i < ICE_BST_TCAM_TABLE_SIZE; i++) { if (lbl_table[i].type == type) {
*start = i; return &tcam_table[lbl_table[i].idx];
}
}
if (hw->debug_mask & ICE_DBG_PARSER)
ice_pg_nm_cam_dump(hw, ci);
}
/** * ice_pg_cam_table_get - create a parse graph cam table * @hw: pointer to the hardware structure * * Return: a pointer to the allocated Parse Graph CAM table.
*/ staticstruct ice_pg_cam_item *ice_pg_cam_table_get(struct ice_hw *hw)
{ return ice_parser_create_table(hw, ICE_SID_RXPARSER_CAM, sizeof(struct ice_pg_cam_item),
ICE_PG_CAM_TABLE_SIZE,
ice_pg_cam_parse_item, false);
}
/** * ice_pg_sp_cam_table_get - create a parse graph spill cam table * @hw: pointer to the hardware structure * * Return: a pointer to the allocated Parse Graph Spill CAM table.
*/ staticstruct ice_pg_cam_item *ice_pg_sp_cam_table_get(struct ice_hw *hw)
{ return ice_parser_create_table(hw, ICE_SID_RXPARSER_PG_SPILL, sizeof(struct ice_pg_cam_item),
ICE_PG_SP_CAM_TABLE_SIZE,
ice_pg_sp_cam_parse_item, false);
}
/** * ice_pg_nm_cam_table_get - create a parse graph no match cam table * @hw: pointer to the hardware structure * * Return: a pointer to the allocated Parse Graph No Match CAM table.
*/ staticstruct ice_pg_nm_cam_item *ice_pg_nm_cam_table_get(struct ice_hw *hw)
{ return ice_parser_create_table(hw, ICE_SID_RXPARSER_NOMATCH_CAM, sizeof(struct ice_pg_nm_cam_item),
ICE_PG_NM_CAM_TABLE_SIZE,
ice_pg_nm_cam_parse_item, false);
}
/** * ice_pg_nm_sp_cam_table_get - create a parse graph no match spill cam table * @hw: pointer to the hardware structure * * Return: a pointer to the allocated Parse Graph No Match Spill CAM table.
*/ staticstruct ice_pg_nm_cam_item *ice_pg_nm_sp_cam_table_get(struct ice_hw *hw)
{ return ice_parser_create_table(hw, ICE_SID_RXPARSER_NOMATCH_SPILL, sizeof(struct ice_pg_nm_cam_item),
ICE_PG_NM_SP_CAM_TABLE_SIZE,
ice_pg_nm_sp_cam_parse_item, false);
}
/** * ice_pg_cam_match - search parse graph cam table by key * @table: parse graph cam table to search * @size: cam table size * @key: search key * * Return: a pointer to the matching PG CAM item or NULL.
*/ struct ice_pg_cam_item *ice_pg_cam_match(struct ice_pg_cam_item *table, int size, struct ice_pg_cam_key *key)
{ int i;
for (i = 0; i < size; i++) { struct ice_pg_cam_item *item = &table[i];
if (__ice_pg_cam_match(item, key)) return item;
}
return NULL;
}
/** * ice_pg_nm_cam_match - search parse graph no match cam table by key * @table: parse graph no match cam table to search * @size: cam table size * @key: search key * * Return: a pointer to the matching PG No Match CAM item or NULL.
*/ struct ice_pg_nm_cam_item *
ice_pg_nm_cam_match(struct ice_pg_nm_cam_item *table, int size, struct ice_pg_cam_key *key)
{ int i;
for (i = 0; i < size; i++) { struct ice_pg_nm_cam_item *item = &table[i];
if (__ice_pg_nm_cam_match(item, key)) return item;
}
return NULL;
}
/*** Ternary match ***/ /* Perform a ternary match on a 1-byte pattern (@pat) given @key and @key_inv * Rules (per bit): * Key == 0 and Key_inv == 0 : Never match (Don't care) * Key == 0 and Key_inv == 1 : Match on bit == 1 * Key == 1 and Key_inv == 0 : Match on bit == 0 * Key == 1 and Key_inv == 1 : Always match (Don't care) * * Return: true if all bits match, false otherwise.
*/ staticbool ice_ternary_match_byte(u8 key, u8 key_inv, u8 pat)
{
u8 bit_key, bit_key_inv, bit_pat; int i;
for (i = 0; i < BITS_PER_BYTE; i++) {
bit_key = key & BIT(i);
bit_key_inv = key_inv & BIT(i);
bit_pat = pat & BIT(i);
/** * ice_bst_alu_init - parse 96 bits of ALU entry * @alu: pointer to the ALU entry structure * @data: ALU entry data to be parsed * @off: offset of the ALU entry data
*/ staticvoid ice_bst_alu_init(struct ice_alu *alu, u8 *data, u8 off)
{
u64 d64;
u8 idd;
if (hw->debug_mask & ICE_DBG_PARSER)
ice_lbl_dump(hw, lbl_item);
}
/** * ice_bst_lbl_table_get - create a boost label table * @hw: pointer to the hardware structure * * Return: a pointer to the allocated Boost label table.
*/ staticstruct ice_lbl_item *ice_bst_lbl_table_get(struct ice_hw *hw)
{ return ice_parser_create_table(hw, ICE_SID_LBL_RXPARSER_TMEM, sizeof(struct ice_lbl_item),
ICE_BST_TCAM_TABLE_SIZE,
ice_parse_lbl_item, true);
}
/** * ice_bst_tcam_match - match a pattern on the boost tcam table * @tcam_table: boost tcam table to search * @pat: pattern to match * * Return: a pointer to the matching Boost TCAM item or NULL.
*/ struct ice_bst_tcam_item *
ice_bst_tcam_match(struct ice_bst_tcam_item *tcam_table, u8 *pat)
{ int i;
for (i = 0; i < ICE_BST_TCAM_TABLE_SIZE; i++) { struct ice_bst_tcam_item *item = &tcam_table[i];
if (item->hit_idx_grp == 0) continue; if (ice_ternary_match(item->key, item->key_inv, pat,
ICE_BST_TCAM_KEY_SIZE)) return item;
}
return NULL;
}
/*** ICE_SID_RXPARSER_MARKER_PTYPE section ***/ /** * ice_ptype_mk_tcam_dump - dump an ptype marker tcam info * @hw: pointer to the hardware structure * @item: ptype marker tcam to dump
*/ staticvoid ice_ptype_mk_tcam_dump(struct ice_hw *hw, struct ice_ptype_mk_tcam_item *item)
{ struct device *dev = ice_hw_to_dev(hw); int i;
if (hw->debug_mask & ICE_DBG_PARSER)
ice_ptype_mk_tcam_dump(hw,
(struct ice_ptype_mk_tcam_item *)item);
}
/** * ice_ptype_mk_tcam_table_get - create a ptype marker tcam table * @hw: pointer to the hardware structure * * Return: a pointer to the allocated Marker PType TCAM table.
*/ static struct ice_ptype_mk_tcam_item *ice_ptype_mk_tcam_table_get(struct ice_hw *hw)
{ return ice_parser_create_table(hw, ICE_SID_RXPARSER_MARKER_PTYPE, sizeof(struct ice_ptype_mk_tcam_item),
ICE_PTYPE_MK_TCAM_TABLE_SIZE,
ice_parse_ptype_mk_tcam_item, true);
}
/** * ice_ptype_mk_tcam_match - match a pattern on a ptype marker tcam table * @table: ptype marker tcam table to search * @pat: pattern to match * @len: length of the pattern * * Return: a pointer to the matching Marker PType item or NULL.
*/ struct ice_ptype_mk_tcam_item *
ice_ptype_mk_tcam_match(struct ice_ptype_mk_tcam_item *table,
u8 *pat, int len)
{ int i;
for (i = 0; i < ICE_PTYPE_MK_TCAM_TABLE_SIZE; i++) { struct ice_ptype_mk_tcam_item *item = &table[i];
if (ice_ternary_match(item->key, item->key_inv, pat, len)) return item;
}
return NULL;
}
/*** ICE_SID_RXPARSER_MARKER_GRP section ***/ /** * ice_mk_grp_dump - dump an marker group item info * @hw: pointer to the hardware structure * @item: marker group item to dump
*/ staticvoid ice_mk_grp_dump(struct ice_hw *hw, struct ice_mk_grp_item *item)
{ struct device *dev = ice_hw_to_dev(hw); int i;
dev_info(dev, "index = %d\n", item->idx);
dev_info(dev, "markers: "); for (i = 0; i < ICE_MK_COUNT_PER_GRP; i++)
dev_info(dev, "%d ", item->markers[i]);
for (i = 0; i < ICE_MK_COUNT_PER_GRP; i++)
grp->markers[i] = buf[i];
if (hw->debug_mask & ICE_DBG_PARSER)
ice_mk_grp_dump(hw, grp);
}
/** * ice_mk_grp_table_get - create a marker group table * @hw: pointer to the hardware structure * * Return: a pointer to the allocated Marker Group ID table.
*/ staticstruct ice_mk_grp_item *ice_mk_grp_table_get(struct ice_hw *hw)
{ return ice_parser_create_table(hw, ICE_SID_RXPARSER_MARKER_GRP, sizeof(struct ice_mk_grp_item),
ICE_MK_GRP_TABLE_SIZE,
ice_mk_grp_parse_item, false);
}
/** * ice_proto_grp_dump - dump a proto group item info * @hw: pointer to the hardware structure * @item: proto group item to dump
*/ staticvoid ice_proto_grp_dump(struct ice_hw *hw, struct ice_proto_grp_item *item)
{ int i;
/** * ice_proto_off_parse - parse 22 bits of Protocol entry * @po: pointer to the Protocol entry structure * @data: Protocol entry data to be parsed
*/ staticvoid ice_proto_off_parse(struct ice_proto_off *po, u32 data)
{
po->polarity = FIELD_GET(ICE_PO_POL, data);
po->proto_id = FIELD_GET(ICE_PO_PID, data);
po->offset = FIELD_GET(ICE_PO_OFF, data);
}
/** * ice_proto_grp_parse_item - parse 192 bits of Protocol Group Table entry * @hw: pointer to the hardware structure * @idx: index of Protocol Group Table entry * @item: item of Protocol Group Table entry * @data: Protocol Group Table entry data to be parsed * @size: size of Protocol Group Table entry
*/ staticvoid ice_proto_grp_parse_item(struct ice_hw *hw, u16 idx, void *item, void *data, int __maybe_unused size)
{ struct ice_proto_grp_item *grp = item;
u8 *buf = (u8 *)data;
u8 idd, off;
u32 d32; int i;
grp->idx = idx;
for (i = 0; i < ICE_PROTO_COUNT_PER_GRP; i++) {
idd = (ICE_PROTO_GRP_ITEM_SIZE * i) / BITS_PER_BYTE;
off = (ICE_PROTO_GRP_ITEM_SIZE * i) % BITS_PER_BYTE;
d32 = *((u32 *)&buf[idd]) >> off;
ice_proto_off_parse(&grp->po[i], d32);
}
if (hw->debug_mask & ICE_DBG_PARSER)
ice_proto_grp_dump(hw, grp);
}
/** * ice_proto_grp_table_get - create a proto group table * @hw: pointer to the hardware structure * * Return: a pointer to the allocated Protocol Group table.
*/ staticstruct ice_proto_grp_item *ice_proto_grp_table_get(struct ice_hw *hw)
{ return ice_parser_create_table(hw, ICE_SID_RXPARSER_PROTO_GRP, sizeof(struct ice_proto_grp_item),
ICE_PROTO_GRP_TABLE_SIZE,
ice_proto_grp_parse_item, false);
}
/*** ICE_SID_RXPARSER_FLAG_REDIR section ***/ /** * ice_flg_rd_dump - dump a flag redirect item info * @hw: pointer to the hardware structure * @item: flag redirect item to dump
*/ staticvoid ice_flg_rd_dump(struct ice_hw *hw, struct ice_flg_rd_item *item)
{ struct device *dev = ice_hw_to_dev(hw);
/** * ice_flg_rd_parse_item - parse 8 bits of Flag Redirect Table entry * @hw: pointer to the hardware structure * @idx: index of Flag Redirect Table entry * @item: item of Flag Redirect Table entry * @data: Flag Redirect Table entry data to be parsed * @size: size of Flag Redirect Table entry
*/ staticvoid ice_flg_rd_parse_item(struct ice_hw *hw, u16 idx, void *item, void *data, int __maybe_unused size)
{ struct ice_flg_rd_item *rdi = item;
u8 d8 = *(u8 *)data;
if (hw->debug_mask & ICE_DBG_PARSER)
ice_flg_rd_dump(hw, rdi);
}
/** * ice_flg_rd_table_get - create a flag redirect table * @hw: pointer to the hardware structure * * Return: a pointer to the allocated Flags Redirection table.
*/ staticstruct ice_flg_rd_item *ice_flg_rd_table_get(struct ice_hw *hw)
{ return ice_parser_create_table(hw, ICE_SID_RXPARSER_FLAG_REDIR, sizeof(struct ice_flg_rd_item),
ICE_FLG_RD_TABLE_SIZE,
ice_flg_rd_parse_item, false);
}
/** * ice_flg_redirect - redirect a parser flag to packet flag * @table: flag redirect table * @psr_flg: parser flag to redirect * * Return: flag or 0 if @psr_flag = 0.
*/
u64 ice_flg_redirect(struct ice_flg_rd_item *table, u64 psr_flg)
{
u64 flg = 0; int i;
for (i = 0; i < ICE_FLG_RDT_SIZE; i++) { struct ice_flg_rd_item *item = &table[i];
if (!item->expose) continue;
if (psr_flg & BIT(item->intr_flg_id))
flg |= BIT(i);
}
return flg;
}
/*** ICE_SID_XLT_KEY_BUILDER_SW, ICE_SID_XLT_KEY_BUILDER_ACL, * ICE_SID_XLT_KEY_BUILDER_FD and ICE_SID_XLT_KEY_BUILDER_RSS
* sections ***/ staticvoid ice_xlt_kb_entry_dump(struct ice_hw *hw, struct ice_xlt_kb_entry *entry, int idx)
{ struct device *dev = ice_hw_to_dev(hw); int i;
kb->flag15 = *(u64 *)&buf[ICE_XLT_KB_FL15_OFF]; for (i = 0; i < ICE_XLT_KB_TBL_CNT; i++)
ice_kb_entry_init(&kb->entries[i],
&buf[ICE_XLT_KB_TBL_OFF +
i * ICE_XLT_KB_TBL_ENTRY_SIZE]);
if (hw->debug_mask & ICE_DBG_PARSER)
ice_xlt_kb_dump(hw, kb);
}
kb = kzalloc(sizeof(*kb), GFP_KERNEL); if (!kb) return ERR_PTR(-ENOMEM);
data = ice_pkg_enum_section(seg, &state, sect_type); if (!data) {
ice_debug(hw, ICE_DBG_PARSER, "failed to find section type %d.\n",
sect_type);
kfree(kb); return ERR_PTR(-EINVAL);
}
ice_parse_kb_data(hw, kb, data);
return kb;
}
/** * ice_xlt_kb_get_sw - create switch xlt key build * @hw: pointer to the hardware structure * * Return: a pointer to the allocated Key Builder table for Switch.
*/ staticstruct ice_xlt_kb *ice_xlt_kb_get_sw(struct ice_hw *hw)
{ return ice_xlt_kb_get(hw, ICE_SID_XLT_KEY_BUILDER_SW);
}
/** * ice_xlt_kb_get_acl - create acl xlt key build * @hw: pointer to the hardware structure * * Return: a pointer to the allocated Key Builder table for ACL.
*/ staticstruct ice_xlt_kb *ice_xlt_kb_get_acl(struct ice_hw *hw)
{ return ice_xlt_kb_get(hw, ICE_SID_XLT_KEY_BUILDER_ACL);
}
/** * ice_xlt_kb_get_fd - create fdir xlt key build * @hw: pointer to the hardware structure * * Return: a pointer to the allocated Key Builder table for Flow Director.
*/ staticstruct ice_xlt_kb *ice_xlt_kb_get_fd(struct ice_hw *hw)
{ return ice_xlt_kb_get(hw, ICE_SID_XLT_KEY_BUILDER_FD);
}
/** * ice_xlt_kb_get_rss - create rss xlt key build * @hw: pointer to the hardware structure * * Return: a pointer to the allocated Key Builder table for RSS.
*/ staticstruct ice_xlt_kb *ice_xlt_kb_get_rss(struct ice_hw *hw)
{ return ice_xlt_kb_get(hw, ICE_SID_XLT_KEY_BUILDER_RSS);
}
#define ICE_XLT_KB_MASK GENMASK_ULL(5, 0)
/** * ice_xlt_kb_flag_get - aggregate 64 bits packet flag into 16 bits xlt flag * @kb: xlt key build * @pkt_flag: 64 bits packet flag * * Return: XLT flag or 0 if @pkt_flag = 0.
*/
u16 ice_xlt_kb_flag_get(struct ice_xlt_kb *kb, u64 pkt_flag)
{ struct ice_xlt_kb_entry *entry = &kb->entries[0];
u16 flag = 0; int i;
/* check flag 15 */ if (kb->flag15 & pkt_flag)
flag = BIT(ICE_XLT_KB_FLAG0_14_CNT);
/* check flag 0 - 14 */ for (i = 0; i < ICE_XLT_KB_FLAG0_14_CNT; i++) { /* only check first entry */
u16 idx = entry->flg0_14_sel[i] & ICE_XLT_KB_MASK;
if (pkt_flag & BIT(idx))
flag |= (u16)BIT(i);
}
return flag;
}
/*** Parser API ***/ /** * ice_parser_create - create a parser instance * @hw: pointer to the hardware structure * * Return: a pointer to the allocated parser instance or ERR_PTR * in case of error.
*/ struct ice_parser *ice_parser_create(struct ice_hw *hw)
{ struct ice_parser *p; void *err;
p = kzalloc(sizeof(*p), GFP_KERNEL); if (!p) return ERR_PTR(-ENOMEM);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.