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: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
2b341f7532
commit
4fa7210802
@ -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,
|
||||
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_policer pol = { 0 };
|
||||
struct flow_action_entry *action;
|
||||
int port = priv->chip_port;
|
||||
int err;
|
||||
|
||||
@ -232,6 +232,58 @@ static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv,
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (priv->tc.police_id && priv->tc.police_id != f->cookie) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Only one policer per port is supported");
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
err = ocelot_policer_validate(&f->rule->action, action, extack);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
pol.rate = (u32)div_u64(action->police.rate_bytes_ps, 1000) * 8;
|
||||
pol.burst = action->police.burst;
|
||||
|
||||
err = ocelot_port_policer_add(ocelot, port, &pol);
|
||||
if (err) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Could not add policer");
|
||||
return err;
|
||||
}
|
||||
|
||||
priv->tc.police_id = f->cookie;
|
||||
priv->tc.offload_cnt++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
if (err) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Could not delete policer");
|
||||
return err;
|
||||
}
|
||||
|
||||
priv->tc.police_id = 0;
|
||||
priv->tc.offload_cnt--;
|
||||
|
||||
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)) {
|
||||
@ -248,47 +300,27 @@ static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv,
|
||||
|
||||
action = &f->rule->action.entries[0];
|
||||
|
||||
if (action->id != FLOW_ACTION_POLICE) {
|
||||
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;
|
||||
}
|
||||
|
||||
if (priv->tc.police_id && priv->tc.police_id != f->cookie) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Only one policer per port is supported");
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
err = ocelot_policer_validate(&f->rule->action, action,
|
||||
extack);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
pol.rate = (u32)div_u64(action->police.rate_bytes_ps, 1000) * 8;
|
||||
pol.burst = action->police.burst;
|
||||
|
||||
err = ocelot_port_policer_add(ocelot, port, &pol);
|
||||
if (err) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Could not add policer");
|
||||
return err;
|
||||
}
|
||||
|
||||
priv->tc.police_id = f->cookie;
|
||||
priv->tc.offload_cnt++;
|
||||
return 0;
|
||||
break;
|
||||
case TC_CLSMATCHALL_DESTROY:
|
||||
if (priv->tc.police_id != f->cookie)
|
||||
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;
|
||||
|
||||
err = ocelot_port_policer_del(ocelot, port);
|
||||
if (err) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Could not delete policer");
|
||||
return err;
|
||||
}
|
||||
priv->tc.police_id = 0;
|
||||
priv->tc.offload_cnt--;
|
||||
return 0;
|
||||
break;
|
||||
case TC_CLSMATCHALL_STATS:
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
|
Loading…
Reference in New Issue
Block a user