Skip to content

Commit

Permalink
net: mvpp2: cls: Support steering to RSS contexts
Browse files Browse the repository at this point in the history
When steering to an RXQ, we can perform an extra RSS step to assign a
queue from an RSS table.

This is done by setting the RSS_EN attribute in the C2 engine. In that
case, the RXQ that is assigned is the global RSS context id, that is
then translated to an RSS table using the RXQ2RSS table.

An example using ethtool to steer to RXQ 2 and 3 would be :

ethtool -X eth0 weight 0 0 1 1 context new

(This would print the allocated context id, let's say it's 1)

ethtool -N eth0 flow-type udp4 dst-port 1234 context 1 loc 0

The hash parameters are the ones that are globally configured for RSS :

ethtool -N eth0 rx-flow-hash udp4 sdfn

When an RSS context is removed while there are active classification
rules using this context, these rules are removed.

Signed-off-by: Maxime Chevallier <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
minimaxwell authored and davem330 committed May 25, 2019
1 parent c561da6 commit 1413477
Showing 1 changed file with 54 additions and 4 deletions.
58 changes: 54 additions & 4 deletions drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1068,7 +1068,7 @@ static int mvpp2_port_c2_tcam_rule_add(struct mvpp2_port *port,
struct flow_action_entry *act;
struct mvpp2_cls_c2_entry c2;
u8 qh, ql, pmap;
int index;
int index, ctx;

memset(&c2, 0, sizeof(c2));

Expand Down Expand Up @@ -1108,14 +1108,36 @@ static int mvpp2_port_c2_tcam_rule_add(struct mvpp2_port *port,
*/
c2.act = MVPP22_CLS_C2_ACT_COLOR(MVPP22_C2_COL_NO_UPD_LOCK);

/* Update RSS status after matching this entry */
if (act->queue.ctx)
c2.attr[2] |= MVPP22_CLS_C2_ATTR2_RSS_EN;

/* Always lock the RSS_EN decision. We might have high prio
* rules steering to an RXQ, and a lower one steering to RSS,
* we don't want the low prio RSS rule overwriting this flag.
*/
c2.act = MVPP22_CLS_C2_ACT_RSS_EN(MVPP22_C2_UPD_LOCK);

/* Mark packet as "forwarded to software", needed for RSS */
c2.act |= MVPP22_CLS_C2_ACT_FWD(MVPP22_C2_FWD_SW_LOCK);

c2.act |= MVPP22_CLS_C2_ACT_QHIGH(MVPP22_C2_UPD_LOCK) |
MVPP22_CLS_C2_ACT_QLOW(MVPP22_C2_UPD_LOCK);

qh = ((act->queue.index + port->first_rxq) >> 3) & MVPP22_CLS_C2_ATTR0_QHIGH_MASK;
ql = (act->queue.index + port->first_rxq) & MVPP22_CLS_C2_ATTR0_QLOW_MASK;
if (act->queue.ctx) {
/* Get the global ctx number */
ctx = mvpp22_rss_ctx(port, act->queue.ctx);
if (ctx < 0)
return -EINVAL;

qh = (ctx >> 3) & MVPP22_CLS_C2_ATTR0_QHIGH_MASK;
ql = ctx & MVPP22_CLS_C2_ATTR0_QLOW_MASK;
} else {
qh = ((act->queue.index + port->first_rxq) >> 3) &
MVPP22_CLS_C2_ATTR0_QHIGH_MASK;
ql = (act->queue.index + port->first_rxq) &
MVPP22_CLS_C2_ATTR0_QLOW_MASK;
}

c2.attr[0] = MVPP22_CLS_C2_ATTR0_QHIGH(qh) |
MVPP22_CLS_C2_ATTR0_QLOW(ql);
Expand Down Expand Up @@ -1235,6 +1257,13 @@ static int mvpp2_cls_rfs_parse_rule(struct mvpp2_rfs_rule *rule)
if (act->id != FLOW_ACTION_QUEUE && act->id != FLOW_ACTION_DROP)
return -EOPNOTSUPP;

/* When both an RSS context and an queue index are set, the index
* is considered as an offset to be added to the indirection table
* entries. We don't support this, so reject this rule.
*/
if (act->queue.ctx && act->queue.index)
return -EOPNOTSUPP;

/* For now, only use the C2 engine which has a HEK size limited to 64
* bits for TCAM matching.
*/
Expand Down Expand Up @@ -1455,11 +1484,32 @@ static struct mvpp2_rss_table *mvpp22_rss_table_get(struct mvpp2 *priv,
int mvpp22_port_rss_ctx_delete(struct mvpp2_port *port, u32 port_ctx)
{
struct mvpp2 *priv = port->priv;
int rss_ctx = mvpp22_rss_ctx(port, port_ctx);
struct ethtool_rxnfc *rxnfc;
int i, rss_ctx, ret;

rss_ctx = mvpp22_rss_ctx(port, port_ctx);

if (rss_ctx < 0 || rss_ctx >= MVPP22_N_RSS_TABLES)
return -EINVAL;

/* Invalidate any active classification rule that use this context */
for (i = 0; i < MVPP2_N_RFS_ENTRIES_PER_FLOW; i++) {
if (!port->rfs_rules[i])
continue;

rxnfc = &port->rfs_rules[i]->rxnfc;
if (!(rxnfc->fs.flow_type & FLOW_RSS) ||
rxnfc->rss_context != port_ctx)
continue;

ret = mvpp2_ethtool_cls_rule_del(port, rxnfc);
if (ret) {
netdev_warn(port->dev,
"couldn't remove classification rule %d associated to this context",
rxnfc->fs.location);
}
}

kfree(priv->rss_tables[rss_ctx]);

priv->rss_tables[rss_ctx] = NULL;
Expand Down

0 comments on commit 1413477

Please sign in to comment.