Commit e42bd4ed authored by Vladimir Oltean's avatar Vladimir Oltean Committed by David S. Miller
Browse files

net: mscc: ocelot: keep traps in a list



When using the ocelot-8021q tagging protocol, the CPU port isn't
configured as an NPI port, but is a regular port. So a "trap to CPU"
operation is actually a "redirect" operation. So DSA needs to set up the
trapping action one way or another, depending on the tagging protocol in
use.

To ease DSA's work of modifying the action, keep all currently installed
traps in a list, so that DSA can live-patch them when the tagging
protocol changes.

Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2960bb14
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -1495,6 +1495,7 @@ int ocelot_trap_add(struct ocelot *ocelot, int port, unsigned long cookie,
		trap->action.cpu_copy_ena = true;
		trap->action.mask_mode = OCELOT_MASK_MODE_PERMIT_DENY;
		trap->action.port_mask = 0;
		list_add_tail(&trap->trap_list, &ocelot->traps);
		new = true;
	}

@@ -1506,8 +1507,10 @@ int ocelot_trap_add(struct ocelot *ocelot, int port, unsigned long cookie,
		err = ocelot_vcap_filter_replace(ocelot, trap);
	if (err) {
		trap->ingress_port_mask &= ~BIT(port);
		if (!trap->ingress_port_mask)
		if (!trap->ingress_port_mask) {
			list_del(&trap->trap_list);
			kfree(trap);
		}
		return err;
	}

@@ -1527,8 +1530,11 @@ int ocelot_trap_del(struct ocelot *ocelot, int port, unsigned long cookie)
		return 0;

	trap->ingress_port_mask &= ~BIT(port);
	if (!trap->ingress_port_mask)
	if (!trap->ingress_port_mask) {
		list_del(&trap->trap_list);

		return ocelot_vcap_filter_del(ocelot, trap);
	}

	return ocelot_vcap_filter_replace(ocelot, trap);
}
+3 −0
Original line number Diff line number Diff line
@@ -279,6 +279,7 @@ static int ocelot_flower_parse_action(struct ocelot *ocelot, int port,
			filter->action.cpu_copy_ena = true;
			filter->action.cpu_qu_num = 0;
			filter->type = OCELOT_VCAP_FILTER_OFFLOAD;
			list_add_tail(&filter->trap_list, &ocelot->traps);
			break;
		case FLOW_ACTION_POLICE:
			if (filter->block_id == PSFP_BLOCK_ID) {
@@ -840,6 +841,8 @@ int ocelot_cls_flower_replace(struct ocelot *ocelot, int port,

	ret = ocelot_flower_parse(ocelot, port, ingress, f, filter);
	if (ret) {
		if (!list_empty(&filter->trap_list))
			list_del(&filter->trap_list);
		kfree(filter);
		return ret;
	}
+1 −0
Original line number Diff line number Diff line
@@ -1401,6 +1401,7 @@ int ocelot_vcap_init(struct ocelot *ocelot)
	}

	INIT_LIST_HEAD(&ocelot->dummy_rules);
	INIT_LIST_HEAD(&ocelot->traps);
	INIT_LIST_HEAD(&ocelot->vcap_pol.pol_list);

	return 0;
+1 −0
Original line number Diff line number Diff line
@@ -689,6 +689,7 @@ struct ocelot {
	u8				base_mac[ETH_ALEN];

	struct list_head		vlans;
	struct list_head		traps;

	/* Switches like VSC9959 have flooding per traffic class */
	int				num_flooding_pgids;
+1 −0
Original line number Diff line number Diff line
@@ -682,6 +682,7 @@ struct ocelot_vcap_id {

struct ocelot_vcap_filter {
	struct list_head list;
	struct list_head trap_list;

	enum ocelot_vcap_filter_type type;
	int block_id;