Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b217566a authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-dsa-Multi-CPU-ground-work'



Florian Fainelli says:

====================
net: dsa: Multi-CPU ground work (v4)

This patch series prepares the ground for adding mutliple CPU port support to
DSA, and starts by removing redundant pieces of information such as
master_netdev which is cpu_dp->ethernet. Finally drivers are moved away from
directly accessing ds->dst->cpu_dp and use appropriate helper functions.

Note that if you have Device Tree blobs/platform configurations that are
currently listing multiple CPU ports, the proposed behavior in
dsa_ds_get_cpu_dp() will be to return the last bit set in ds->cpu_port_mask.

Future plans include:
- making dst->cpu_dp a flexible data structure (array, list, you name it)
- having the ability for drivers to return a default/preferred CPU port (if
  necessary)

Changes in v4:

- fixed build warning with NETPOLL enabled

Changes in v3:

- removed the last patch since it causes problems with bcm_sf2/b53 in a
  dual-CPU case (root cause known, proper fix underway)

- removed dsa_ds_get_cpu_dp()

Changes in v2:

- added Reviewed-by tags
- assign port->cpu_dp earlier before ops->setup() has run
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 38b6ec50 3cc9f257
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -806,7 +806,7 @@ static int bcm_sf2_sw_resume(struct dsa_switch *ds)
static void bcm_sf2_sw_get_wol(struct dsa_switch *ds, int port,
			       struct ethtool_wolinfo *wol)
{
	struct net_device *p = ds->dst[ds->index].master_netdev;
	struct net_device *p = ds->dst[ds->index].cpu_dp->netdev;
	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
	struct ethtool_wolinfo pwol;

@@ -829,7 +829,7 @@ static void bcm_sf2_sw_get_wol(struct dsa_switch *ds, int port,
static int bcm_sf2_sw_set_wol(struct dsa_switch *ds, int port,
			      struct ethtool_wolinfo *wol)
{
	struct net_device *p = ds->dst[ds->index].master_netdev;
	struct net_device *p = ds->dst[ds->index].cpu_dp->netdev;
	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
	s8 cpu_port = ds->dst->cpu_dp->index;
	struct ethtool_wolinfo pwol;
+2 −2
Original line number Diff line number Diff line
@@ -912,11 +912,11 @@ mt7530_setup(struct dsa_switch *ds)
	struct device_node *dn;
	struct mt7530_dummy_poll p;

	/* The parent node of master_netdev which holds the common system
	/* The parent node of cpu_dp->netdev which holds the common system
	 * controller also is the container for two GMACs nodes representing
	 * as two netdev instances.
	 */
	dn = ds->master_netdev->dev.of_node->parent;
	dn = ds->dst->cpu_dp->netdev->dev.of_node->parent;
	priv->ethernet = syscon_node_to_regmap(dn);
	if (IS_ERR(priv->ethernet))
		return PTR_ERR(priv->ethernet);
+6 −17
Original line number Diff line number Diff line
@@ -122,24 +122,12 @@ struct dsa_switch_tree {
	 */
	struct dsa_platform_data	*pd;

	/*
	 * Reference to network device to use, and which tagging
	 * protocol to use.
	 */
	struct net_device	*master_netdev;

	/* Copy of tag_ops->rcv for faster access in hot path */
	struct sk_buff *	(*rcv)(struct sk_buff *skb,
				       struct net_device *dev,
				       struct packet_type *pt,
				       struct net_device *orig_dev);

	/*
	 * Original copy of the master netdev ethtool_ops
	 */
	struct ethtool_ops	master_ethtool_ops;
	const struct ethtool_ops *master_orig_ethtool_ops;

	/*
	 * The switch port to which the CPU is attached.
	 */
@@ -183,12 +171,18 @@ struct dsa_port {
	struct dsa_switch	*ds;
	unsigned int		index;
	const char		*name;
	struct dsa_port		*cpu_dp;
	struct net_device	*netdev;
	struct device_node	*dn;
	unsigned int		ageing_time;
	u8			stp_state;
	struct net_device	*bridge_dev;
	struct devlink_port	devlink_port;
	/*
	 * Original copy of the master netdev ethtool_ops
	 */
	struct ethtool_ops	ethtool_ops;
	const struct ethtool_ops *orig_ethtool_ops;
};

struct dsa_switch {
@@ -226,11 +220,6 @@ struct dsa_switch {
	 */
	s8		rtable[DSA_MAX_SWITCHES];

	/*
	 * The lower device this switch uses to talk to the host
	 */
	struct net_device *master_netdev;

	/*
	 * Slave mii_bus and devices for the individual ports.
	 */
+5 −14
Original line number Diff line number Diff line
@@ -118,18 +118,16 @@ int dsa_cpu_port_ethtool_setup(struct dsa_port *cpu_dp)
	struct net_device *master;
	struct ethtool_ops *cpu_ops;

	master = ds->dst->master_netdev;
	if (ds->master_netdev)
		master = ds->master_netdev;
	master = cpu_dp->netdev;

	cpu_ops = devm_kzalloc(ds->dev, sizeof(*cpu_ops), GFP_KERNEL);
	if (!cpu_ops)
		return -ENOMEM;

	memcpy(&ds->dst->master_ethtool_ops, master->ethtool_ops,
	memcpy(&cpu_dp->ethtool_ops, master->ethtool_ops,
	       sizeof(struct ethtool_ops));
	ds->dst->master_orig_ethtool_ops = master->ethtool_ops;
	memcpy(cpu_ops, &ds->dst->master_ethtool_ops,
	cpu_dp->orig_ethtool_ops = master->ethtool_ops;
	memcpy(cpu_ops, &cpu_dp->ethtool_ops,
	       sizeof(struct ethtool_ops));
	dsa_cpu_port_ethtool_init(cpu_ops);
	master->ethtool_ops = cpu_ops;
@@ -139,14 +137,7 @@ int dsa_cpu_port_ethtool_setup(struct dsa_port *cpu_dp)

void dsa_cpu_port_ethtool_restore(struct dsa_port *cpu_dp)
{
	struct dsa_switch *ds = cpu_dp->ds;
	struct net_device *master;

	master = ds->dst->master_netdev;
	if (ds->master_netdev)
		master = ds->master_netdev;

	master->ethtool_ops = ds->dst->master_orig_ethtool_ops;
	cpu_dp->netdev->ethtool_ops = cpu_dp->orig_ethtool_ops;
}

void dsa_cpu_dsa_destroy(struct dsa_port *port)
+17 −10
Original line number Diff line number Diff line
@@ -337,7 +337,7 @@ static int dsa_ds_apply(struct dsa_switch_tree *dst, struct dsa_switch *ds)
		return err;

	if (ds->ops->set_addr) {
		err = ds->ops->set_addr(ds, dst->master_netdev->dev_addr);
		err = ds->ops->set_addr(ds, dst->cpu_dp->netdev->dev_addr);
		if (err < 0)
			return err;
	}
@@ -444,7 +444,7 @@ static int dsa_dst_apply(struct dsa_switch_tree *dst)
	 * sent to the tag format's receive function.
	 */
	wmb();
	dst->master_netdev->dsa_ptr = dst;
	dst->cpu_dp->netdev->dsa_ptr = dst;
	dst->applied = true;

	return 0;
@@ -458,7 +458,7 @@ static void dsa_dst_unapply(struct dsa_switch_tree *dst)
	if (!dst->applied)
		return;

	dst->master_netdev->dsa_ptr = NULL;
	dst->cpu_dp->netdev->dsa_ptr = NULL;

	/* If we used a tagging format that doesn't have an ethertype
	 * field, make sure that all packets from this point get sent
@@ -490,6 +490,8 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 index,
	enum dsa_tag_protocol tag_protocol;
	struct net_device *ethernet_dev;
	struct device_node *ethernet;
	struct dsa_port *p;
	unsigned int i;

	if (port->dn) {
		ethernet = of_parse_phandle(port->dn, "ethernet", 0);
@@ -504,14 +506,19 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 index,
	if (!ethernet_dev)
		return -EPROBE_DEFER;

	if (!ds->master_netdev)
		ds->master_netdev = ethernet_dev;
	if (!dst->cpu_dp) {
		dst->cpu_dp = port;
		dst->cpu_dp->netdev = ethernet_dev;

	if (!dst->master_netdev)
		dst->master_netdev = ethernet_dev;
		for (i = 0; i < ds->num_ports; i++) {
			p = &ds->ports[i];
			if (!dsa_port_is_valid(p) ||
			    i == index)
				continue;

	if (!dst->cpu_dp)
		dst->cpu_dp = port;
			p->cpu_dp = port;
		}
	}

	tag_protocol = ds->ops->get_tag_protocol(ds);
	dst->tag_ops = dsa_resolve_tag_protocol(tag_protocol);
@@ -578,7 +585,7 @@ static int dsa_dst_parse(struct dsa_switch_tree *dst)
			return err;
	}

	if (!dst->master_netdev) {
	if (!dst->cpu_dp->netdev) {
		pr_warn("Tree has no master device\n");
		return -EINVAL;
	}
Loading