Skip to content

Commit 961d418

Browse files
rogerqdavem330
authored andcommitted
net: ethernet: ti: cpsw_ale: add policer/classifier helpers and setup defaults
The Policer registers in the ALE register space are just shadow registers and use an index field in the policer table control register to read/write to the actual Polier registers. Add helper functions to Read and Write to Policer registers. Also add a helper function to set the thread value to classifier/policer mapping. Any packet that first matches the classifier will be sent to the thread (flow) that is set in the classifier to thread mapping table. If not set then it goes to the default flow. Default behaviour is to have 8 classifiers to map 8 DSCP/PCP priorities to N receive threads (flows). N depends on number of RX channels enabled for the port. As per the standard [1] User prioritie 1 (Background) and 2 (Spare) have lower priority than the user priority 0 (default). User priority 1 being of the lowest priority. [1] IEEE802.1D-2004, IEEE Standard for Local and metropolitan area networks Table G-2 - Traffic type acronyms Table G-3 - Defining traffic types Signed-off-by: Roger Quadros <[email protected]> Reviewed-by: Simon Horman <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent eb41dd7 commit 961d418

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed

drivers/net/ethernet/ti/cpsw_ale.c

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,3 +1627,97 @@ u32 cpsw_ale_get_num_entries(struct cpsw_ale *ale)
16271627
{
16281628
return ale ? ale->params.ale_entries : 0;
16291629
}
1630+
1631+
/* Reads the specified policer index into ALE POLICER registers */
1632+
static void cpsw_ale_policer_read_idx(struct cpsw_ale *ale, u32 idx)
1633+
{
1634+
idx &= ALE_POLICER_TBL_INDEX_MASK;
1635+
writel_relaxed(idx, ale->params.ale_regs + ALE_POLICER_TBL_CTL);
1636+
}
1637+
1638+
/* Writes the ALE POLICER registers into the specified policer index */
1639+
static void cpsw_ale_policer_write_idx(struct cpsw_ale *ale, u32 idx)
1640+
{
1641+
idx &= ALE_POLICER_TBL_INDEX_MASK;
1642+
idx |= ALE_POLICER_TBL_WRITE_ENABLE;
1643+
writel_relaxed(idx, ale->params.ale_regs + ALE_POLICER_TBL_CTL);
1644+
}
1645+
1646+
/* enables/disables the custom thread value for the specified policer index */
1647+
static void cpsw_ale_policer_thread_idx_enable(struct cpsw_ale *ale, u32 idx,
1648+
u32 thread_id, bool enable)
1649+
{
1650+
regmap_field_write(ale->fields[ALE_THREAD_CLASS_INDEX], idx);
1651+
regmap_field_write(ale->fields[ALE_THREAD_VALUE], thread_id);
1652+
regmap_field_write(ale->fields[ALE_THREAD_ENABLE], enable ? 1 : 0);
1653+
}
1654+
1655+
/* Disable all policer entries and thread mappings */
1656+
static void cpsw_ale_policer_reset(struct cpsw_ale *ale)
1657+
{
1658+
int i;
1659+
1660+
for (i = 0; i < ale->params.num_policers ; i++) {
1661+
cpsw_ale_policer_read_idx(ale, i);
1662+
regmap_field_write(ale->fields[POL_PORT_MEN], 0);
1663+
regmap_field_write(ale->fields[POL_PRI_MEN], 0);
1664+
regmap_field_write(ale->fields[POL_OUI_MEN], 0);
1665+
regmap_field_write(ale->fields[POL_DST_MEN], 0);
1666+
regmap_field_write(ale->fields[POL_SRC_MEN], 0);
1667+
regmap_field_write(ale->fields[POL_OVLAN_MEN], 0);
1668+
regmap_field_write(ale->fields[POL_IVLAN_MEN], 0);
1669+
regmap_field_write(ale->fields[POL_ETHERTYPE_MEN], 0);
1670+
regmap_field_write(ale->fields[POL_IPSRC_MEN], 0);
1671+
regmap_field_write(ale->fields[POL_IPDST_MEN], 0);
1672+
regmap_field_write(ale->fields[POL_EN], 0);
1673+
regmap_field_write(ale->fields[POL_RED_DROP_EN], 0);
1674+
regmap_field_write(ale->fields[POL_YELLOW_DROP_EN], 0);
1675+
regmap_field_write(ale->fields[POL_PRIORITY_THREAD_EN], 0);
1676+
1677+
cpsw_ale_policer_thread_idx_enable(ale, i, 0, 0);
1678+
}
1679+
}
1680+
1681+
/* Default classifier is to map 8 user priorities to N receive channels */
1682+
void cpsw_ale_classifier_setup_default(struct cpsw_ale *ale, int num_rx_ch)
1683+
{
1684+
int pri, idx;
1685+
/* IEEE802.1D-2004, Standard for Local and metropolitan area networks
1686+
* Table G-2 - Traffic type acronyms
1687+
* Table G-3 - Defining traffic types
1688+
* User priority values 1 and 2 effectively communicate a lower
1689+
* priority than 0. In the below table 0 is assigned to higher priority
1690+
* thread than 1 and 2 wherever possible.
1691+
* The below table maps which thread the user priority needs to be
1692+
* sent to for a given number of threads (RX channels). Upper threads
1693+
* have higher priority.
1694+
* e.g. if number of threads is 8 then user priority 0 will map to
1695+
* pri_thread_map[8-1][0] i.e. thread 2
1696+
*/
1697+
int pri_thread_map[8][8] = { { 0, 0, 0, 0, 0, 0, 0, 0, },
1698+
{ 0, 0, 0, 0, 1, 1, 1, 1, },
1699+
{ 0, 0, 0, 0, 1, 1, 2, 2, },
1700+
{ 1, 0, 0, 1, 2, 2, 3, 3, },
1701+
{ 1, 0, 0, 1, 2, 3, 4, 4, },
1702+
{ 1, 0, 0, 2, 3, 4, 5, 5, },
1703+
{ 1, 0, 0, 2, 3, 4, 5, 6, },
1704+
{ 2, 0, 1, 3, 4, 5, 6, 7, } };
1705+
1706+
cpsw_ale_policer_reset(ale);
1707+
1708+
/* use first 8 classifiers to map 8 (DSCP/PCP) priorities to channels */
1709+
for (pri = 0; pri < 8; pri++) {
1710+
idx = pri;
1711+
1712+
/* Classifier 'idx' match on priority 'pri' */
1713+
cpsw_ale_policer_read_idx(ale, idx);
1714+
regmap_field_write(ale->fields[POL_PRI_VAL], pri);
1715+
regmap_field_write(ale->fields[POL_PRI_MEN], 1);
1716+
cpsw_ale_policer_write_idx(ale, idx);
1717+
1718+
/* Map Classifier 'idx' to thread provided by the map */
1719+
cpsw_ale_policer_thread_idx_enable(ale, idx,
1720+
pri_thread_map[num_rx_ch - 1][pri],
1721+
1);
1722+
}
1723+
}

drivers/net/ethernet/ti/cpsw_ale.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,5 +193,6 @@ int cpsw_ale_vlan_add_modify(struct cpsw_ale *ale, u16 vid, int port_mask,
193193
int cpsw_ale_vlan_del_modify(struct cpsw_ale *ale, u16 vid, int port_mask);
194194
void cpsw_ale_set_unreg_mcast(struct cpsw_ale *ale, int unreg_mcast_mask,
195195
bool add);
196+
void cpsw_ale_classifier_setup_default(struct cpsw_ale *ale, int num_rx_ch);
196197

197198
#endif

0 commit comments

Comments
 (0)