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

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
Loading
Loading
Loading
Loading
+71 −39
Original line number Diff line number Diff line
@@ -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,35 +232,13 @@ static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv,
		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) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Only one policer per port is supported");
		return -EEXIST;
	}

		err = ocelot_policer_validate(&f->rule->action, action,
					      extack);
	err = ocelot_policer_validate(&f->rule->action, action, extack);
	if (err)
		return err;

@@ -275,10 +253,16 @@ static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv,

	priv->tc.police_id = f->cookie;
	priv->tc.offload_cnt++;

	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);
	if (err) {
@@ -286,9 +270,57 @@ static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv,
				   "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)) {
			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:
	default:
		return -EOPNOTSUPP;