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

net: dsa: make tag_8021q operations part of the core



Make tag_8021q a more central element of DSA and move the 2 driver
specific operations outside of struct dsa_8021q_context (which is
supposed to hold dynamic data and not really constant function
pointers).

Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d7b1fd52
Loading
Loading
Loading
Loading
+3 −7
Original line number Diff line number Diff line
@@ -231,11 +231,6 @@ static int felix_tag_8021q_vlan_del(struct dsa_switch *ds, int port, u16 vid)
	return 0;
}

static const struct dsa_8021q_ops felix_tag_8021q_ops = {
	.vlan_add	= felix_tag_8021q_vlan_add,
	.vlan_del	= felix_tag_8021q_vlan_del,
};

/* Alternatively to using the NPI functionality, that same hardware MAC
 * connected internally to the enetc or fman DSA master can be configured to
 * use the software-defined tag_8021q frame format. As far as the hardware is
@@ -425,8 +420,7 @@ static int felix_setup_tag_8021q(struct dsa_switch *ds, int cpu)
	ocelot_rmw_rix(ocelot, 0, cpu_flood, ANA_PGID_PGID, PGID_MC);
	ocelot_rmw_rix(ocelot, 0, cpu_flood, ANA_PGID_PGID, PGID_BC);

	err = dsa_tag_8021q_register(ds, &felix_tag_8021q_ops,
				     htons(ETH_P_8021AD));
	err = dsa_tag_8021q_register(ds, htons(ETH_P_8021AD));
	if (err)
		return err;

@@ -1675,6 +1669,8 @@ const struct dsa_switch_ops felix_switch_ops = {
	.port_mrp_del			= felix_mrp_del,
	.port_mrp_add_ring_role		= felix_mrp_add_ring_role,
	.port_mrp_del_ring_role		= felix_mrp_del_ring_role,
	.tag_8021q_vlan_add		= felix_tag_8021q_vlan_add,
	.tag_8021q_vlan_del		= felix_tag_8021q_vlan_del,
};

struct net_device *felix_port_to_netdev(struct ocelot *ocelot, int port)
+3 −7
Original line number Diff line number Diff line
@@ -2543,11 +2543,6 @@ static int sja1105_dsa_8021q_vlan_del(struct dsa_switch *ds, int port, u16 vid)
	return sja1105_build_vlan_table(priv, true);
}

static const struct dsa_8021q_ops sja1105_dsa_8021q_ops = {
	.vlan_add	= sja1105_dsa_8021q_vlan_add,
	.vlan_del	= sja1105_dsa_8021q_vlan_del,
};

/* The programming model for the SJA1105 switch is "all-at-once" via static
 * configuration tables. Some of these can be dynamically modified at runtime,
 * but not the xMII mode parameters table.
@@ -3153,6 +3148,8 @@ static const struct dsa_switch_ops sja1105_switch_ops = {
	.crosschip_bridge_join	= sja1105_crosschip_bridge_join,
	.crosschip_bridge_leave	= sja1105_crosschip_bridge_leave,
	.devlink_info_get	= sja1105_devlink_info_get,
	.tag_8021q_vlan_add	= sja1105_dsa_8021q_vlan_add,
	.tag_8021q_vlan_del	= sja1105_dsa_8021q_vlan_del,
};

static const struct of_device_id sja1105_dt_ids[];
@@ -3296,8 +3293,7 @@ static int sja1105_probe(struct spi_device *spi)
	mutex_init(&priv->ptp_data.lock);
	mutex_init(&priv->mgmt_lock);

	rc = dsa_tag_8021q_register(ds, &sja1105_dsa_8021q_ops,
				    htons(ETH_P_8021Q));
	rc = dsa_tag_8021q_register(ds, htons(ETH_P_8021Q));
	if (rc)
		return rc;

+1 −9
Original line number Diff line number Diff line
@@ -21,22 +21,14 @@ struct dsa_8021q_crosschip_link {
	refcount_t refcount;
};

struct dsa_8021q_ops {
	int (*vlan_add)(struct dsa_switch *ds, int port, u16 vid, u16 flags);
	int (*vlan_del)(struct dsa_switch *ds, int port, u16 vid);
};

struct dsa_8021q_context {
	const struct dsa_8021q_ops *ops;
	struct dsa_switch *ds;
	struct list_head crosschip_links;
	/* EtherType of RX VID, used for filtering on master interface */
	__be16 proto;
};

int dsa_tag_8021q_register(struct dsa_switch *ds,
			   const struct dsa_8021q_ops *ops,
			   __be16 proto);
int dsa_tag_8021q_register(struct dsa_switch *ds, __be16 proto);

void dsa_tag_8021q_unregister(struct dsa_switch *ds);

+7 −0
Original line number Diff line number Diff line
@@ -872,6 +872,13 @@ struct dsa_switch_ops {
					  const struct switchdev_obj_ring_role_mrp *mrp);
	int	(*port_mrp_del_ring_role)(struct dsa_switch *ds, int port,
					  const struct switchdev_obj_ring_role_mrp *mrp);

	/*
	 * tag_8021q operations
	 */
	int	(*tag_8021q_vlan_add)(struct dsa_switch *ds, int port, u16 vid,
				      u16 flags);
	int	(*tag_8021q_vlan_del)(struct dsa_switch *ds, int port, u16 vid);
};

#define DSA_DEVLINK_PARAM_DRIVER(_id, _name, _type, _cmodes)		\
+3 −7
Original line number Diff line number Diff line
@@ -116,13 +116,12 @@ EXPORT_SYMBOL_GPL(vid_is_dsa_8021q);
static int dsa_8021q_vid_apply(struct dsa_switch *ds, int port, u16 vid,
			       u16 flags, bool enabled)
{
	struct dsa_8021q_context *ctx = ds->tag_8021q_ctx;
	struct dsa_port *dp = dsa_to_port(ds, port);

	if (enabled)
		return ctx->ops->vlan_add(ctx->ds, dp->index, vid, flags);
		return ds->ops->tag_8021q_vlan_add(ds, dp->index, vid, flags);

	return ctx->ops->vlan_del(ctx->ds, dp->index, vid);
	return ds->ops->tag_8021q_vlan_del(ds, dp->index, vid);
}

/* RX VLAN tagging (left) and TX VLAN tagging (right) setup shown for a single
@@ -413,9 +412,7 @@ int dsa_8021q_crosschip_bridge_leave(struct dsa_switch *ds, int port,
}
EXPORT_SYMBOL_GPL(dsa_8021q_crosschip_bridge_leave);

int dsa_tag_8021q_register(struct dsa_switch *ds,
			   const struct dsa_8021q_ops *ops,
			   __be16 proto)
int dsa_tag_8021q_register(struct dsa_switch *ds, __be16 proto)
{
	struct dsa_8021q_context *ctx;

@@ -423,7 +420,6 @@ int dsa_tag_8021q_register(struct dsa_switch *ds,
	if (!ctx)
		return -ENOMEM;

	ctx->ops = ops;
	ctx->proto = proto;
	ctx->ds = ds;