Skip to content

Commit 450052a

Browse files
DanNowlinanguy11
authored andcommitted
ice: manage profiles and field vectors
Implement functions to manage profiles and field vectors in hardware. In hardware, there are up to 256 profiles and each of these profiles can have 48 field vector words. Each field vector word is described by protocol id and offset in the packet. To add a new recipe all used profiles need to be searched. If the profile contains all required protocol ids and offsets from the recipe it can be used. The driver has to add this profile to recipe association to tell hardware that newly added recipe is going to be associated with this profile. The amount of used profiles depend on the package. To avoid searching across not used profile, max profile id value is calculated at init flow. The profile is considered as unused when all field vector words in the profile are invalid (protocol id 0xff and offset 0x1ff). Profiles are read from the package section ICE_SID_FLD_VEC_SW. Empty field vector words can be used for recipe results. Store all unused field vector words in prof_res_bm. It is a 256 elements array (max number of profiles) each element is a 48 bit bitmap (max number of field vector words). For now, support only non-tunnel profiles type. Co-developed-by: Grishma Kotecha <grishma.kotecha@intel.com> Signed-off-by: Grishma Kotecha <grishma.kotecha@intel.com> Signed-off-by: Dan Nowlin <dan.nowlin@intel.com> Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com> Tested-by: Sandeep Penigalapati <sandeep.penigalapati@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
1 parent 7715ec3 commit 450052a

File tree

5 files changed

+268
-1
lines changed

5 files changed

+268
-1
lines changed

drivers/net/ethernet/intel/ice/ice_flex_pipe.c

Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,6 +1329,86 @@ ice_chk_pkg_compat(struct ice_hw *hw, struct ice_pkg_hdr *ospkg,
13291329
return status;
13301330
}
13311331

1332+
/**
1333+
* ice_sw_fv_handler
1334+
* @sect_type: section type
1335+
* @section: pointer to section
1336+
* @index: index of the field vector entry to be returned
1337+
* @offset: ptr to variable that receives the offset in the field vector table
1338+
*
1339+
* This is a callback function that can be passed to ice_pkg_enum_entry.
1340+
* This function treats the given section as of type ice_sw_fv_section and
1341+
* enumerates offset field. "offset" is an index into the field vector table.
1342+
*/
1343+
static void *
1344+
ice_sw_fv_handler(u32 sect_type, void *section, u32 index, u32 *offset)
1345+
{
1346+
struct ice_sw_fv_section *fv_section = section;
1347+
1348+
if (!section || sect_type != ICE_SID_FLD_VEC_SW)
1349+
return NULL;
1350+
if (index >= le16_to_cpu(fv_section->count))
1351+
return NULL;
1352+
if (offset)
1353+
/* "index" passed in to this function is relative to a given
1354+
* 4k block. To get to the true index into the field vector
1355+
* table need to add the relative index to the base_offset
1356+
* field of this section
1357+
*/
1358+
*offset = le16_to_cpu(fv_section->base_offset) + index;
1359+
return fv_section->fv + index;
1360+
}
1361+
1362+
/**
1363+
* ice_get_prof_index_max - get the max profile index for used profile
1364+
* @hw: pointer to the HW struct
1365+
*
1366+
* Calling this function will get the max profile index for used profile
1367+
* and store the index number in struct ice_switch_info *switch_info
1368+
* in HW for following use.
1369+
*/
1370+
static enum ice_status ice_get_prof_index_max(struct ice_hw *hw)
1371+
{
1372+
u16 prof_index = 0, j, max_prof_index = 0;
1373+
struct ice_pkg_enum state;
1374+
struct ice_seg *ice_seg;
1375+
bool flag = false;
1376+
struct ice_fv *fv;
1377+
u32 offset;
1378+
1379+
memset(&state, 0, sizeof(state));
1380+
1381+
if (!hw->seg)
1382+
return ICE_ERR_PARAM;
1383+
1384+
ice_seg = hw->seg;
1385+
1386+
do {
1387+
fv = ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,
1388+
&offset, ice_sw_fv_handler);
1389+
if (!fv)
1390+
break;
1391+
ice_seg = NULL;
1392+
1393+
/* in the profile that not be used, the prot_id is set to 0xff
1394+
* and the off is set to 0x1ff for all the field vectors.
1395+
*/
1396+
for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)
1397+
if (fv->ew[j].prot_id != ICE_PROT_INVALID ||
1398+
fv->ew[j].off != ICE_FV_OFFSET_INVAL)
1399+
flag = true;
1400+
if (flag && prof_index > max_prof_index)
1401+
max_prof_index = prof_index;
1402+
1403+
prof_index++;
1404+
flag = false;
1405+
} while (fv);
1406+
1407+
hw->switch_info->max_used_prof_index = max_prof_index;
1408+
1409+
return 0;
1410+
}
1411+
13321412
/**
13331413
* ice_init_pkg - initialize/download package
13341414
* @hw: pointer to the hardware structure
@@ -1408,6 +1488,7 @@ enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buf, u32 len)
14081488
*/
14091489
ice_init_pkg_regs(hw);
14101490
ice_fill_blk_tbls(hw);
1491+
ice_get_prof_index_max(hw);
14111492
} else {
14121493
ice_debug(hw, ICE_DBG_INIT, "package load failed, %d\n",
14131494
status);
@@ -1484,6 +1565,167 @@ static struct ice_buf_build *ice_pkg_buf_alloc(struct ice_hw *hw)
14841565
return bld;
14851566
}
14861567

1568+
/**
1569+
* ice_get_sw_fv_bitmap - Get switch field vector bitmap based on profile type
1570+
* @hw: pointer to hardware structure
1571+
* @req_profs: type of profiles requested
1572+
* @bm: pointer to memory for returning the bitmap of field vectors
1573+
*/
1574+
void
1575+
ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type req_profs,
1576+
unsigned long *bm)
1577+
{
1578+
struct ice_pkg_enum state;
1579+
struct ice_seg *ice_seg;
1580+
struct ice_fv *fv;
1581+
1582+
if (req_profs == ICE_PROF_ALL) {
1583+
bitmap_set(bm, 0, ICE_MAX_NUM_PROFILES);
1584+
return;
1585+
}
1586+
1587+
memset(&state, 0, sizeof(state));
1588+
bitmap_zero(bm, ICE_MAX_NUM_PROFILES);
1589+
ice_seg = hw->seg;
1590+
do {
1591+
u32 offset;
1592+
1593+
fv = ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,
1594+
&offset, ice_sw_fv_handler);
1595+
ice_seg = NULL;
1596+
1597+
if (fv) {
1598+
if (req_profs & ICE_PROF_NON_TUN)
1599+
set_bit((u16)offset, bm);
1600+
}
1601+
} while (fv);
1602+
}
1603+
1604+
/**
1605+
* ice_get_sw_fv_list
1606+
* @hw: pointer to the HW structure
1607+
* @prot_ids: field vector to search for with a given protocol ID
1608+
* @ids_cnt: lookup/protocol count
1609+
* @bm: bitmap of field vectors to consider
1610+
* @fv_list: Head of a list
1611+
*
1612+
* Finds all the field vector entries from switch block that contain
1613+
* a given protocol ID and returns a list of structures of type
1614+
* "ice_sw_fv_list_entry". Every structure in the list has a field vector
1615+
* definition and profile ID information
1616+
* NOTE: The caller of the function is responsible for freeing the memory
1617+
* allocated for every list entry.
1618+
*/
1619+
enum ice_status
1620+
ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt,
1621+
unsigned long *bm, struct list_head *fv_list)
1622+
{
1623+
struct ice_sw_fv_list_entry *fvl;
1624+
struct ice_sw_fv_list_entry *tmp;
1625+
struct ice_pkg_enum state;
1626+
struct ice_seg *ice_seg;
1627+
struct ice_fv *fv;
1628+
u32 offset;
1629+
1630+
memset(&state, 0, sizeof(state));
1631+
1632+
if (!ids_cnt || !hw->seg)
1633+
return ICE_ERR_PARAM;
1634+
1635+
ice_seg = hw->seg;
1636+
do {
1637+
u16 i;
1638+
1639+
fv = ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,
1640+
&offset, ice_sw_fv_handler);
1641+
if (!fv)
1642+
break;
1643+
ice_seg = NULL;
1644+
1645+
/* If field vector is not in the bitmap list, then skip this
1646+
* profile.
1647+
*/
1648+
if (!test_bit((u16)offset, bm))
1649+
continue;
1650+
1651+
for (i = 0; i < ids_cnt; i++) {
1652+
int j;
1653+
1654+
/* This code assumes that if a switch field vector line
1655+
* has a matching protocol, then this line will contain
1656+
* the entries necessary to represent every field in
1657+
* that protocol header.
1658+
*/
1659+
for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)
1660+
if (fv->ew[j].prot_id == prot_ids[i])
1661+
break;
1662+
if (j >= hw->blk[ICE_BLK_SW].es.fvw)
1663+
break;
1664+
if (i + 1 == ids_cnt) {
1665+
fvl = devm_kzalloc(ice_hw_to_dev(hw),
1666+
sizeof(*fvl), GFP_KERNEL);
1667+
if (!fvl)
1668+
goto err;
1669+
fvl->fv_ptr = fv;
1670+
fvl->profile_id = offset;
1671+
list_add(&fvl->list_entry, fv_list);
1672+
break;
1673+
}
1674+
}
1675+
} while (fv);
1676+
if (list_empty(fv_list))
1677+
return ICE_ERR_CFG;
1678+
return 0;
1679+
1680+
err:
1681+
list_for_each_entry_safe(fvl, tmp, fv_list, list_entry) {
1682+
list_del(&fvl->list_entry);
1683+
devm_kfree(ice_hw_to_dev(hw), fvl);
1684+
}
1685+
1686+
return ICE_ERR_NO_MEMORY;
1687+
}
1688+
1689+
/**
1690+
* ice_init_prof_result_bm - Initialize the profile result index bitmap
1691+
* @hw: pointer to hardware structure
1692+
*/
1693+
void ice_init_prof_result_bm(struct ice_hw *hw)
1694+
{
1695+
struct ice_pkg_enum state;
1696+
struct ice_seg *ice_seg;
1697+
struct ice_fv *fv;
1698+
1699+
memset(&state, 0, sizeof(state));
1700+
1701+
if (!hw->seg)
1702+
return;
1703+
1704+
ice_seg = hw->seg;
1705+
do {
1706+
u32 off;
1707+
u16 i;
1708+
1709+
fv = ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,
1710+
&off, ice_sw_fv_handler);
1711+
ice_seg = NULL;
1712+
if (!fv)
1713+
break;
1714+
1715+
bitmap_zero(hw->switch_info->prof_res_bm[off],
1716+
ICE_MAX_FV_WORDS);
1717+
1718+
/* Determine empty field vector indices, these can be
1719+
* used for recipe results. Skip index 0, since it is
1720+
* always used for Switch ID.
1721+
*/
1722+
for (i = 1; i < ICE_MAX_FV_WORDS; i++)
1723+
if (fv->ew[i].prot_id == ICE_PROT_INVALID &&
1724+
fv->ew[i].off == ICE_FV_OFFSET_INVAL)
1725+
set_bit(i, hw->switch_info->prof_res_bm[off]);
1726+
} while (fv);
1727+
}
1728+
14871729
/**
14881730
* ice_pkg_buf_free
14891731
* @hw: pointer to the HW structure

drivers/net/ethernet/intel/ice/ice_flex_pipe.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@
1818

1919
#define ICE_PKG_CNT 4
2020

21+
void
22+
ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type type,
23+
unsigned long *bm);
24+
void
25+
ice_init_prof_result_bm(struct ice_hw *hw);
26+
enum ice_status
27+
ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt,
28+
unsigned long *bm, struct list_head *fv_list);
2129
bool
2230
ice_get_open_tunnel_port(struct ice_hw *hw, u16 *port);
2331
int ice_udp_tunnel_set_port(struct net_device *netdev, unsigned int table,

drivers/net/ethernet/intel/ice/ice_flex_type.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ struct ice_fv_word {
1313
u8 resvrd;
1414
} __packed;
1515

16+
#define ICE_MAX_NUM_PROFILES 256
17+
1618
#define ICE_MAX_FV_WORDS 48
1719
struct ice_fv {
1820
struct ice_fv_word ew[ICE_MAX_FV_WORDS];
@@ -279,6 +281,12 @@ struct ice_sw_fv_section {
279281
struct ice_fv fv[];
280282
};
281283

284+
struct ice_sw_fv_list_entry {
285+
struct list_head list_entry;
286+
u32 profile_id;
287+
struct ice_fv *fv_ptr;
288+
};
289+
282290
/* The BOOST TCAM stores the match packet header in reverse order, meaning
283291
* the fields are reversed; in addition, this means that the normally big endian
284292
* fields of the packet are now little endian.
@@ -603,4 +611,9 @@ struct ice_chs_chg {
603611
};
604612

605613
#define ICE_FLOW_PTYPE_MAX ICE_XLT1_CNT
614+
615+
enum ice_prof_type {
616+
ICE_PROF_NON_TUN = 0x1,
617+
ICE_PROF_ALL = 0xFF,
618+
};
606619
#endif /* _ICE_FLEX_TYPE_H_ */

drivers/net/ethernet/intel/ice/ice_switch.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,11 @@ enum ice_status ice_init_def_sw_recp(struct ice_hw *hw)
5959
if (!recps)
6060
return ICE_ERR_NO_MEMORY;
6161

62-
for (i = 0; i < ICE_SW_LKUP_LAST; i++) {
62+
for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
6363
recps[i].root_rid = i;
6464
INIT_LIST_HEAD(&recps[i].filt_rules);
6565
INIT_LIST_HEAD(&recps[i].filt_replay_rules);
66+
INIT_LIST_HEAD(&recps[i].rg_list);
6667
mutex_init(&recps[i].filt_rule_lock);
6768
}
6869

drivers/net/ethernet/intel/ice/ice_type.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,9 @@ struct ice_port_info {
677677
struct ice_switch_info {
678678
struct list_head vsi_list_map_head;
679679
struct ice_sw_recipe *recp_list;
680+
u16 max_used_prof_index;
681+
682+
DECLARE_BITMAP(prof_res_bm[ICE_MAX_NUM_PROFILES], ICE_MAX_FV_WORDS);
680683
};
681684

682685
/* FW logging configuration */

0 commit comments

Comments
 (0)