Skip to content

Commit

Permalink
Merge branch 'net-microchip-vcap-rules'
Browse files Browse the repository at this point in the history
Steen Hegelund says:

====================
net: microchip: Add support for two classes of VCAP rules

This adds support for two classes of VCAP rules:

- Permanent rules (added e.g. for PTP support)
- TC user rules (added by the TC userspace tool)

For this to work the VCAP Loopups must be enabled from boot, so that the
"internal" clients like PTP can add rules that are always active.

When the TC tool add a flower filter the VCAP rule corresponding to this
filter will be disabled (kept in memory) until a TC matchall filter creates
a link from chain 0 to the chain (lookup) where the flower filter was
added.

When the flower filter is enabled it will be written to the appropriate
VCAP lookup and become active in HW.

Likewise the flower filter will be disabled if there is no link from chain
0 to the chain of the filter (lookup), and when that happens the
corresponding VCAP rule will be read from the VCAP instance and stored in
memory until it is deleted or enabled again.

Version History:
================
v4      Removed a leftover 'Fixes' tag from v2.  No functional changes.

v3      Removed the change that allowed rules to always be added in the
        LAN996x even though the lookups are not enabled (Horatiu Vultur).
        This was sent separately to net instead.

        Removed the 'Fixes' tags due to the patch sent to net by Horatiu
        Vultur.

        Added a check for validity of the chain source when enabling a
        lookup.

v2      Adding a missing goto exit in vcap_add_rule (Dan Carpenter).
        Added missing checks for error returns in vcap_enable_rule.

v1      Initial version
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jan 16, 2023
2 parents ce870af + 18a15c7 commit 87b08a8
Show file tree
Hide file tree
Showing 16 changed files with 699 additions and 347 deletions.
10 changes: 3 additions & 7 deletions drivers/net/ethernet/microchip/lan966x/lan966x_goto.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
#include "vcap_api_client.h"

int lan966x_goto_port_add(struct lan966x_port *port,
struct flow_action_entry *act,
int from_cid, int to_cid,
unsigned long goto_id,
struct netlink_ext_ack *extack)
{
struct lan966x *lan966x = port->lan966x;
int err;

err = vcap_enable_lookups(lan966x->vcap_ctrl, port->dev,
act->chain_index, goto_id,
from_cid, to_cid, goto_id,
true);
if (err == -EFAULT) {
NL_SET_ERR_MSG_MOD(extack, "Unsupported goto chain");
Expand All @@ -29,8 +29,6 @@ int lan966x_goto_port_add(struct lan966x_port *port,
return err;
}

port->tc.goto_id = goto_id;

return 0;
}

Expand All @@ -41,14 +39,12 @@ int lan966x_goto_port_del(struct lan966x_port *port,
struct lan966x *lan966x = port->lan966x;
int err;

err = vcap_enable_lookups(lan966x->vcap_ctrl, port->dev, 0,
err = vcap_enable_lookups(lan966x->vcap_ctrl, port->dev, 0, 0,
goto_id, false);
if (err) {
NL_SET_ERR_MSG_MOD(extack, "Could not disable VCAP lookups");
return err;
}

port->tc.goto_id = 0;

return 0;
}
3 changes: 1 addition & 2 deletions drivers/net/ethernet/microchip/lan966x/lan966x_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,6 @@ struct lan966x_port_tc {
unsigned long police_id;
unsigned long ingress_mirror_id;
unsigned long egress_mirror_id;
unsigned long goto_id;
struct flow_stats police_stat;
struct flow_stats mirror_stat;
};
Expand Down Expand Up @@ -607,7 +606,7 @@ int lan966x_tc_flower(struct lan966x_port *port,
struct flow_cls_offload *f);

int lan966x_goto_port_add(struct lan966x_port *port,
struct flow_action_entry *act,
int from_cid, int to_cid,
unsigned long goto_id,
struct netlink_ext_ack *extack);
int lan966x_goto_port_del(struct lan966x_port *port,
Expand Down
30 changes: 16 additions & 14 deletions drivers/net/ethernet/microchip/lan966x/lan966x_tc_flower.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ static int lan966x_tc_flower_use_dissectors(struct flow_cls_offload *f,
}

static int lan966x_tc_flower_action_check(struct vcap_control *vctrl,
struct flow_cls_offload *fco,
struct vcap_admin *admin)
struct net_device *dev,
struct flow_cls_offload *fco)
{
struct flow_rule *rule = flow_cls_offload_flow_rule(fco);
struct flow_action_entry *actent, *last_actent = NULL;
Expand All @@ -109,21 +109,23 @@ static int lan966x_tc_flower_action_check(struct vcap_control *vctrl,
last_actent = actent; /* Save last action for later check */
}

/* Check that last action is a goto */
if (last_actent->id != FLOW_ACTION_GOTO) {
/* Check that last action is a goto
* The last chain/lookup does not need to have goto action
*/
if (last_actent->id == FLOW_ACTION_GOTO) {
/* Check if the destination chain is in one of the VCAPs */
if (!vcap_is_next_lookup(vctrl, fco->common.chain_index,
last_actent->chain_index)) {
NL_SET_ERR_MSG_MOD(fco->common.extack,
"Invalid goto chain");
return -EINVAL;
}
} else if (!vcap_is_last_chain(vctrl, fco->common.chain_index)) {
NL_SET_ERR_MSG_MOD(fco->common.extack,
"Last action must be 'goto'");
return -EINVAL;
}

/* Check if the goto chain is in the next lookup */
if (!vcap_is_next_lookup(vctrl, fco->common.chain_index,
last_actent->chain_index)) {
NL_SET_ERR_MSG_MOD(fco->common.extack,
"Invalid goto chain");
return -EINVAL;
}

/* Catch unsupported combinations of actions */
if (action_mask & BIT(FLOW_ACTION_TRAP) &&
action_mask & BIT(FLOW_ACTION_ACCEPT)) {
Expand All @@ -145,8 +147,8 @@ static int lan966x_tc_flower_add(struct lan966x_port *port,
struct vcap_rule *vrule;
int err, idx;

err = lan966x_tc_flower_action_check(port->lan966x->vcap_ctrl, f,
admin);
err = lan966x_tc_flower_action_check(port->lan966x->vcap_ctrl,
port->dev, f);
if (err)
return err;

Expand Down
16 changes: 3 additions & 13 deletions drivers/net/ethernet/microchip/lan966x/lan966x_tc_matchall.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ static int lan966x_tc_matchall_add(struct lan966x_port *port,
return lan966x_mirror_port_add(port, act, f->cookie,
ingress, f->common.extack);
case FLOW_ACTION_GOTO:
return lan966x_goto_port_add(port, act, f->cookie,
return lan966x_goto_port_add(port, f->common.chain_index,
act->chain_index, f->cookie,
f->common.extack);
default:
NL_SET_ERR_MSG_MOD(f->common.extack,
Expand All @@ -46,13 +47,8 @@ static int lan966x_tc_matchall_del(struct lan966x_port *port,
f->cookie == port->tc.egress_mirror_id) {
return lan966x_mirror_port_del(port, ingress,
f->common.extack);
} else if (f->cookie == port->tc.goto_id) {
return lan966x_goto_port_del(port, f->cookie,
f->common.extack);
} else {
NL_SET_ERR_MSG_MOD(f->common.extack,
"Unsupported action");
return -EOPNOTSUPP;
return lan966x_goto_port_del(port, f->cookie, f->common.extack);
}

return 0;
Expand Down Expand Up @@ -80,12 +76,6 @@ int lan966x_tc_matchall(struct lan966x_port *port,
struct tc_cls_matchall_offload *f,
bool ingress)
{
if (!tc_cls_can_offload_and_chain0(port->dev, &f->common)) {
NL_SET_ERR_MSG_MOD(f->common.extack,
"Only chain zero is supported");
return -EOPNOTSUPP;
}

switch (f->command) {
case TC_CLSMATCHALL_REPLACE:
return lan966x_tc_matchall_add(port, f, ingress);
Expand Down
21 changes: 6 additions & 15 deletions drivers/net/ethernet/microchip/lan966x/lan966x_vcap_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,20 +390,6 @@ static int lan966x_vcap_port_info(struct net_device *dev,
return 0;
}

static int lan966x_vcap_enable(struct net_device *dev,
struct vcap_admin *admin,
bool enable)
{
struct lan966x_port *port = netdev_priv(dev);
struct lan966x *lan966x = port->lan966x;

lan_rmw(ANA_VCAP_S2_CFG_ENA_SET(enable),
ANA_VCAP_S2_CFG_ENA,
lan966x, ANA_VCAP_S2_CFG(port->chip_port));

return 0;
}

static struct vcap_operations lan966x_vcap_ops = {
.validate_keyset = lan966x_vcap_validate_keyset,
.add_default_fields = lan966x_vcap_add_default_fields,
Expand All @@ -414,7 +400,6 @@ static struct vcap_operations lan966x_vcap_ops = {
.update = lan966x_vcap_update,
.move = lan966x_vcap_move,
.port_info = lan966x_vcap_port_info,
.enable = lan966x_vcap_enable,
};

static void lan966x_vcap_admin_free(struct vcap_admin *admin)
Expand Down Expand Up @@ -521,6 +506,12 @@ int lan966x_vcap_init(struct lan966x *lan966x)
list_add_tail(&admin->list, &ctrl->list);
}

for (int p = 0; p < lan966x->num_phys_ports; ++p)
if (lan966x->ports[p])
lan_rmw(ANA_VCAP_S2_CFG_ENA_SET(true),
ANA_VCAP_S2_CFG_ENA, lan966x,
ANA_VCAP_S2_CFG(lan966x->ports[p]->chip_port));

lan966x->vcap_ctrl = ctrl;

return 0;
Expand Down
28 changes: 15 additions & 13 deletions drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
Original file line number Diff line number Diff line change
Expand Up @@ -573,8 +573,8 @@ static int sparx5_tc_use_dissectors(struct flow_cls_offload *fco,
}

static int sparx5_tc_flower_action_check(struct vcap_control *vctrl,
struct flow_cls_offload *fco,
struct vcap_admin *admin)
struct net_device *ndev,
struct flow_cls_offload *fco)
{
struct flow_rule *rule = flow_cls_offload_flow_rule(fco);
struct flow_action_entry *actent, *last_actent = NULL;
Expand All @@ -600,21 +600,23 @@ static int sparx5_tc_flower_action_check(struct vcap_control *vctrl,
last_actent = actent; /* Save last action for later check */
}

/* Check that last action is a goto */
if (last_actent->id != FLOW_ACTION_GOTO) {
/* Check if last action is a goto
* The last chain/lookup does not need to have a goto action
*/
if (last_actent->id == FLOW_ACTION_GOTO) {
/* Check if the destination chain is in one of the VCAPs */
if (!vcap_is_next_lookup(vctrl, fco->common.chain_index,
last_actent->chain_index)) {
NL_SET_ERR_MSG_MOD(fco->common.extack,
"Invalid goto chain");
return -EINVAL;
}
} else if (!vcap_is_last_chain(vctrl, fco->common.chain_index)) {
NL_SET_ERR_MSG_MOD(fco->common.extack,
"Last action must be 'goto'");
return -EINVAL;
}

/* Check if the goto chain is in the next lookup */
if (!vcap_is_next_lookup(vctrl, fco->common.chain_index,
last_actent->chain_index)) {
NL_SET_ERR_MSG_MOD(fco->common.extack,
"Invalid goto chain");
return -EINVAL;
}

/* Catch unsupported combinations of actions */
if (action_mask & BIT(FLOW_ACTION_TRAP) &&
action_mask & BIT(FLOW_ACTION_ACCEPT)) {
Expand Down Expand Up @@ -833,7 +835,7 @@ static int sparx5_tc_flower_replace(struct net_device *ndev,

vctrl = port->sparx5->vcap_ctrl;

err = sparx5_tc_flower_action_check(vctrl, fco, admin);
err = sparx5_tc_flower_action_check(vctrl, ndev, fco);
if (err)
return err;

Expand Down
16 changes: 8 additions & 8 deletions drivers/net/ethernet/microchip/sparx5/sparx5_tc_matchall.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ static int sparx5_tc_matchall_replace(struct net_device *ndev,
switch (action->id) {
case FLOW_ACTION_GOTO:
err = vcap_enable_lookups(sparx5->vcap_ctrl, ndev,
tmo->common.chain_index,
action->chain_index, tmo->cookie,
true);
if (err == -EFAULT) {
Expand All @@ -43,6 +44,11 @@ static int sparx5_tc_matchall_replace(struct net_device *ndev,
"VCAP already enabled");
return -EOPNOTSUPP;
}
if (err == -EADDRNOTAVAIL) {
NL_SET_ERR_MSG_MOD(tmo->common.extack,
"Already matching this chain");
return -EOPNOTSUPP;
}
if (err) {
NL_SET_ERR_MSG_MOD(tmo->common.extack,
"Could not enable VCAP lookups");
Expand All @@ -66,8 +72,8 @@ static int sparx5_tc_matchall_destroy(struct net_device *ndev,

sparx5 = port->sparx5;
if (!tmo->rule && tmo->cookie) {
err = vcap_enable_lookups(sparx5->vcap_ctrl, ndev, 0,
tmo->cookie, false);
err = vcap_enable_lookups(sparx5->vcap_ctrl, ndev,
0, 0, tmo->cookie, false);
if (err)
return err;
return 0;
Expand All @@ -80,12 +86,6 @@ int sparx5_tc_matchall(struct net_device *ndev,
struct tc_cls_matchall_offload *tmo,
bool ingress)
{
if (!tc_cls_can_offload_and_chain0(ndev, &tmo->common)) {
NL_SET_ERR_MSG_MOD(tmo->common.extack,
"Only chain zero is supported");
return -EOPNOTSUPP;
}

switch (tmo->command) {
case TC_CLSMATCHALL_REPLACE:
return sparx5_tc_matchall_replace(ndev, tmo, ingress);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ static void sparx5_vcap_port_keys(struct sparx5 *sparx5,
/* Get lookup state */
value = spx5_rd(sparx5, ANA_ACL_VCAP_S2_CFG(port->portno));
out->prf(out->dst, "\n state: ");
if (ANA_ACL_VCAP_S2_CFG_SEC_ENA_GET(value))
if (ANA_ACL_VCAP_S2_CFG_SEC_ENA_GET(value) & BIT(lookup))
out->prf(out->dst, "on");
else
out->prf(out->dst, "off");
Expand Down
29 changes: 6 additions & 23 deletions drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -510,28 +510,6 @@ static void sparx5_vcap_move(struct net_device *ndev, struct vcap_admin *admin,
sparx5_vcap_wait_super_update(sparx5);
}

/* Enable all lookups in the VCAP instance */
static int sparx5_vcap_enable(struct net_device *ndev,
struct vcap_admin *admin,
bool enable)
{
struct sparx5_port *port = netdev_priv(ndev);
struct sparx5 *sparx5;
int portno;

sparx5 = port->sparx5;
portno = port->portno;

/* For now we only consider IS2 */
if (enable)
spx5_wr(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0xf), sparx5,
ANA_ACL_VCAP_S2_CFG(portno));
else
spx5_wr(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0), sparx5,
ANA_ACL_VCAP_S2_CFG(portno));
return 0;
}

/* API callback operations: only IS2 is supported for now */
static struct vcap_operations sparx5_vcap_ops = {
.validate_keyset = sparx5_vcap_validate_keyset,
Expand All @@ -543,7 +521,6 @@ static struct vcap_operations sparx5_vcap_ops = {
.update = sparx5_vcap_update,
.move = sparx5_vcap_move,
.port_info = sparx5_port_info,
.enable = sparx5_vcap_enable,
};

/* Enable lookups per port and set the keyset generation: only IS2 for now */
Expand All @@ -568,6 +545,12 @@ static void sparx5_vcap_port_key_selection(struct sparx5 *sparx5,
ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
}
}
/* IS2 lookups are in bit 0:3 */
for (portno = 0; portno < SPX5_PORTS; ++portno)
spx5_rmw(ANA_ACL_VCAP_S2_CFG_SEC_ENA_SET(0xf),
ANA_ACL_VCAP_S2_CFG_SEC_ENA,
sparx5,
ANA_ACL_VCAP_S2_CFG(portno));
}

/* Disable lookups per port and set the keyset generation: only IS2 for now */
Expand Down
Loading

0 comments on commit 87b08a8

Please sign in to comment.