Commit 4fa72108 authored by Vladimir Oltean's avatar Vladimir Oltean Committed by Jakub Kicinski

net: mscc: ocelot: refactor policer work out of ocelot_setup_tc_cls_matchall

In preparation for adding port mirroring support to the ocelot driver,
the dispatching function ocelot_setup_tc_cls_matchall() must be free of
action-specific code. Move port policer creation and deletion to
separate functions.
Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 2b341f75
...@@ -216,14 +216,14 @@ int ocelot_setup_tc_cls_flower(struct ocelot_port_private *priv, ...@@ -216,14 +216,14 @@ int ocelot_setup_tc_cls_flower(struct ocelot_port_private *priv,
} }
} }
static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv, static int ocelot_setup_tc_cls_matchall_police(struct ocelot_port_private *priv,
struct tc_cls_matchall_offload *f, struct tc_cls_matchall_offload *f,
bool ingress) bool ingress,
struct netlink_ext_ack *extack)
{ {
struct netlink_ext_ack *extack = f->common.extack; struct flow_action_entry *action = &f->rule->action.entries[0];
struct ocelot *ocelot = priv->port.ocelot; struct ocelot *ocelot = priv->port.ocelot;
struct ocelot_policer pol = { 0 }; struct ocelot_policer pol = { 0 };
struct flow_action_entry *action;
int port = priv->chip_port; int port = priv->chip_port;
int err; int err;
...@@ -232,35 +232,13 @@ static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv, ...@@ -232,35 +232,13 @@ static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
switch (f->command) {
case TC_CLSMATCHALL_REPLACE:
if (!flow_offload_has_one_action(&f->rule->action)) {
NL_SET_ERR_MSG_MOD(extack,
"Only one action is supported");
return -EOPNOTSUPP;
}
if (priv->tc.block_shared) {
NL_SET_ERR_MSG_MOD(extack,
"Rate limit is not supported on shared blocks");
return -EOPNOTSUPP;
}
action = &f->rule->action.entries[0];
if (action->id != FLOW_ACTION_POLICE) {
NL_SET_ERR_MSG_MOD(extack, "Unsupported action");
return -EOPNOTSUPP;
}
if (priv->tc.police_id && priv->tc.police_id != f->cookie) { if (priv->tc.police_id && priv->tc.police_id != f->cookie) {
NL_SET_ERR_MSG_MOD(extack, NL_SET_ERR_MSG_MOD(extack,
"Only one policer per port is supported"); "Only one policer per port is supported");
return -EEXIST; return -EEXIST;
} }
err = ocelot_policer_validate(&f->rule->action, action, err = ocelot_policer_validate(&f->rule->action, action, extack);
extack);
if (err) if (err)
return err; return err;
...@@ -275,10 +253,16 @@ static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv, ...@@ -275,10 +253,16 @@ static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv,
priv->tc.police_id = f->cookie; priv->tc.police_id = f->cookie;
priv->tc.offload_cnt++; priv->tc.offload_cnt++;
return 0; return 0;
case TC_CLSMATCHALL_DESTROY: }
if (priv->tc.police_id != f->cookie)
return -ENOENT; static int ocelot_del_tc_cls_matchall_police(struct ocelot_port_private *priv,
struct netlink_ext_ack *extack)
{
struct ocelot *ocelot = priv->port.ocelot;
int port = priv->chip_port;
int err;
err = ocelot_port_policer_del(ocelot, port); err = ocelot_port_policer_del(ocelot, port);
if (err) { if (err) {
...@@ -286,9 +270,57 @@ static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv, ...@@ -286,9 +270,57 @@ static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv,
"Could not delete policer"); "Could not delete policer");
return err; return err;
} }
priv->tc.police_id = 0; priv->tc.police_id = 0;
priv->tc.offload_cnt--; priv->tc.offload_cnt--;
return 0; return 0;
}
static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv,
struct tc_cls_matchall_offload *f,
bool ingress)
{
struct netlink_ext_ack *extack = f->common.extack;
struct flow_action_entry *action;
switch (f->command) {
case TC_CLSMATCHALL_REPLACE:
if (!flow_offload_has_one_action(&f->rule->action)) {
NL_SET_ERR_MSG_MOD(extack,
"Only one action is supported");
return -EOPNOTSUPP;
}
if (priv->tc.block_shared) {
NL_SET_ERR_MSG_MOD(extack,
"Rate limit is not supported on shared blocks");
return -EOPNOTSUPP;
}
action = &f->rule->action.entries[0];
switch (action->id) {
case FLOW_ACTION_POLICE:
return ocelot_setup_tc_cls_matchall_police(priv, f,
ingress,
extack);
break;
default:
NL_SET_ERR_MSG_MOD(extack, "Unsupported action");
return -EOPNOTSUPP;
}
break;
case TC_CLSMATCHALL_DESTROY:
action = &f->rule->action.entries[0];
if (f->cookie == priv->tc.police_id)
return ocelot_del_tc_cls_matchall_police(priv, extack);
else
return -ENOENT;
break;
case TC_CLSMATCHALL_STATS: case TC_CLSMATCHALL_STATS:
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment