Skip to content

Commit

Permalink
Merge branch 'net-dsa-Multi-CPU-ground-work'
Browse files Browse the repository at this point in the history
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: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jun 13, 2017
2 parents 38b6ec5 + 3cc9f25 commit b217566
Show file tree
Hide file tree
Showing 12 changed files with 91 additions and 91 deletions.
4 changes: 2 additions & 2 deletions drivers/net/dsa/bcm_sf2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/dsa/mt7530.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
23 changes: 6 additions & 17 deletions include/net/dsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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.
*/
Expand Down
19 changes: 5 additions & 14 deletions net/dsa/dsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand Down
27 changes: 17 additions & 10 deletions net/dsa/dsa2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down
10 changes: 10 additions & 0 deletions net/dsa/dsa_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,14 @@ extern const struct dsa_device_ops qca_netdev_ops;
/* tag_trailer.c */
extern const struct dsa_device_ops trailer_netdev_ops;

static inline struct net_device *dsa_master_netdev(struct dsa_slave_priv *p)
{
return p->dp->cpu_dp->netdev;
}

static inline struct dsa_port *dsa_get_cpu_port(struct dsa_switch_tree *dst)
{
return dst->cpu_dp;
}

#endif
23 changes: 14 additions & 9 deletions net/dsa/legacy.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,12 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
struct dsa_switch_tree *dst = ds->dst;
struct dsa_chip_data *cd = ds->cd;
bool valid_name_found = false;
struct net_device *master;
int index = ds->index;
int i, ret;

master = dst->cpu_dp->netdev;

/*
* Validate supplied switch configuration.
*/
Expand All @@ -116,7 +119,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)

if (!strcmp(name, "cpu")) {
if (dst->cpu_dp) {
netdev_err(dst->master_netdev,
netdev_err(master,
"multiple cpu ports?!\n");
return -EINVAL;
}
Expand All @@ -126,6 +129,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
ds->dsa_port_mask |= 1 << i;
} else {
ds->enabled_port_mask |= 1 << i;
ds->ports[i].cpu_dp = dst->cpu_dp;
}
valid_name_found = true;
}
Expand Down Expand Up @@ -168,7 +172,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
return ret;

if (ops->set_addr) {
ret = ops->set_addr(ds, dst->master_netdev->dev_addr);
ret = ops->set_addr(ds, master->dev_addr);
if (ret < 0)
return ret;
}
Expand All @@ -195,14 +199,14 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)

ret = dsa_slave_create(ds, parent, i, cd->port_names[i]);
if (ret < 0)
netdev_err(dst->master_netdev, "[%d]: can't create dsa slave device for port %d(%s): %d\n",
netdev_err(master, "[%d]: can't create dsa slave device for port %d(%s): %d\n",
index, i, cd->port_names[i], ret);
}

/* Perform configuration of the CPU and DSA ports */
ret = dsa_cpu_dsa_setups(ds, parent);
if (ret < 0)
netdev_err(dst->master_netdev, "[%d] : can't configure CPU and DSA ports\n",
netdev_err(master, "[%d] : can't configure CPU and DSA ports\n",
index);

ret = dsa_cpu_port_ethtool_setup(ds->dst->cpu_dp);
Expand All @@ -217,6 +221,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
struct device *parent, struct device *host_dev)
{
struct dsa_chip_data *cd = dst->pd->chip + index;
struct net_device *master = dst->cpu_dp->netdev;
const struct dsa_switch_ops *ops;
struct dsa_switch *ds;
int ret;
Expand All @@ -228,11 +233,11 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
*/
ops = dsa_switch_probe(parent, host_dev, cd->sw_addr, &name, &priv);
if (!ops) {
netdev_err(dst->master_netdev, "[%d]: could not detect attached switch\n",
netdev_err(master, "[%d]: could not detect attached switch\n",
index);
return ERR_PTR(-EINVAL);
}
netdev_info(dst->master_netdev, "[%d]: detected a %s switch\n",
netdev_info(master, "[%d]: detected a %s switch\n",
index, name);


Expand Down Expand Up @@ -575,7 +580,7 @@ static int dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
unsigned configured = 0;

dst->pd = pd;
dst->master_netdev = dev;
dst->cpu_dp->netdev = dev;

for (i = 0; i < pd->nr_chips; i++) {
struct dsa_switch *ds;
Expand Down Expand Up @@ -671,7 +676,7 @@ static void dsa_remove_dst(struct dsa_switch_tree *dst)
{
int i;

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
Expand All @@ -688,7 +693,7 @@ static void dsa_remove_dst(struct dsa_switch_tree *dst)

dsa_cpu_port_ethtool_restore(dst->cpu_dp);

dev_put(dst->master_netdev);
dev_put(dst->cpu_dp->netdev);
}

static int dsa_remove(struct platform_device *pdev)
Expand Down
Loading

0 comments on commit b217566

Please sign in to comment.