Merge branch 'dsa-next'

Alexander Duyck says:

====================
DSA Cleanups

This patch series does two things, first it cleans up the tag_protocol and
protocol ops being configured seperately.  Second it addresses the desire
to split DSA away from relying on a MII bus.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2014-09-15 17:24:29 -04:00
commit 0486b60a8c
16 changed files with 113 additions and 86 deletions

View File

@ -499,7 +499,7 @@ void __init orion_ge00_switch_init(struct dsa_platform_data *d, int irq)
d->netdev = &orion_ge00.dev;
for (i = 0; i < d->nr_chips; i++)
d->chip[i].mii_bus = &orion_ge00_shared.dev;
d->chip[i].host_dev = &orion_ge00_shared.dev;
orion_switch_device.dev.platform_data = d;
platform_device_register(&orion_switch_device);

View File

@ -129,7 +129,7 @@ static int bcm_sf2_sw_get_sset_count(struct dsa_switch *ds)
return BCM_SF2_STATS_SIZE;
}
static char *bcm_sf2_sw_probe(struct mii_bus *bus, int sw_addr)
static char *bcm_sf2_sw_probe(struct device *host_dev, int sw_addr)
{
return "Broadcom Starfighter 2";
}

View File

@ -21,7 +21,8 @@
static int reg_read(struct dsa_switch *ds, int addr, int reg)
{
return mdiobus_read(ds->master_mii_bus, ds->pd->sw_addr + addr, reg);
return mdiobus_read(to_mii_bus(ds->master_dev),
ds->pd->sw_addr + addr, reg);
}
#define REG_READ(addr, reg) \
@ -37,8 +38,8 @@ static int reg_read(struct dsa_switch *ds, int addr, int reg)
static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
{
return mdiobus_write(ds->master_mii_bus, ds->pd->sw_addr + addr,
reg, val);
return mdiobus_write(to_mii_bus(ds->master_dev),
ds->pd->sw_addr + addr, reg, val);
}
#define REG_WRITE(addr, reg, val) \
@ -50,10 +51,14 @@ static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
return __ret; \
})
static char *mv88e6060_probe(struct mii_bus *bus, int sw_addr)
static char *mv88e6060_probe(struct device *host_dev, int sw_addr)
{
struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
int ret;
if (bus == NULL)
return NULL;
ret = mdiobus_read(bus, sw_addr + REG_PORT(0), 0x03);
if (ret >= 0) {
ret &= 0xfff0;

View File

@ -17,10 +17,14 @@
#include <net/dsa.h>
#include "mv88e6xxx.h"
static char *mv88e6123_61_65_probe(struct mii_bus *bus, int sw_addr)
static char *mv88e6123_61_65_probe(struct device *host_dev, int sw_addr)
{
struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
int ret;
if (bus == NULL)
return NULL;
ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03);
if (ret >= 0) {
if (ret == 0x1212)

View File

@ -22,10 +22,14 @@
#define ID_6095 0x0950
#define ID_6131 0x1060
static char *mv88e6131_probe(struct mii_bus *bus, int sw_addr)
static char *mv88e6131_probe(struct device *host_dev, int sw_addr)
{
struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
int ret;
if (bus == NULL)
return NULL;
ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03);
if (ret >= 0) {
ret &= 0xfff0;

View File

@ -17,10 +17,14 @@
#include <net/dsa.h>
#include "mv88e6xxx.h"
static char *mv88e6171_probe(struct mii_bus *bus, int sw_addr)
static char *mv88e6171_probe(struct device *host_dev, int sw_addr)
{
struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
int ret;
if (bus == NULL)
return NULL;
ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03);
if (ret >= 0) {
if ((ret & 0xfff0) == 0x1710)

View File

@ -78,7 +78,7 @@ int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg)
int ret;
mutex_lock(&ps->smi_mutex);
ret = __mv88e6xxx_reg_read(ds->master_mii_bus,
ret = __mv88e6xxx_reg_read(to_mii_bus(ds->master_dev),
ds->pd->sw_addr, addr, reg);
mutex_unlock(&ps->smi_mutex);
@ -122,7 +122,7 @@ int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
int ret;
mutex_lock(&ps->smi_mutex);
ret = __mv88e6xxx_reg_write(ds->master_mii_bus,
ret = __mv88e6xxx_reg_write(to_mii_bus(ds->master_dev),
ds->pd->sw_addr, addr, reg, val);
mutex_unlock(&ps->smi_mutex);

View File

@ -1928,13 +1928,6 @@ struct udp_offload {
struct offload_callbacks callbacks;
};
struct dsa_device_ops {
netdev_tx_t (*xmit)(struct sk_buff *skb, struct net_device *dev);
int (*rcv)(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev);
};
/* often modified stats are per cpu, other are shared (netdev->stats) */
struct pcpu_sw_netstats {
u64 rx_packets;

View File

@ -34,7 +34,7 @@ struct dsa_chip_data {
/*
* How to access the switch configuration registers.
*/
struct device *mii_bus;
struct device *host_dev;
int sw_addr;
/* Device tree node pointer for this specific switch chip
@ -77,7 +77,7 @@ struct dsa_platform_data {
struct dsa_chip_data *chip;
};
struct dsa_device_ops;
struct packet_type;
struct dsa_switch_tree {
/*
@ -91,7 +91,10 @@ struct dsa_switch_tree {
* protocol to use.
*/
struct net_device *master_netdev;
const struct dsa_device_ops *ops;
int (*rcv)(struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt,
struct net_device *orig_dev);
enum dsa_tag_protocol tag_protocol;
/*
@ -131,9 +134,9 @@ struct dsa_switch {
struct dsa_switch_driver *drv;
/*
* Reference to mii bus to use.
* Reference to host device to use.
*/
struct mii_bus *master_mii_bus;
struct device *master_dev;
/*
* Slave mii_bus and devices for the individual ports.
@ -175,7 +178,7 @@ struct dsa_switch_driver {
/*
* Probing and setup.
*/
char *(*probe)(struct mii_bus *bus, int sw_addr);
char *(*probe)(struct device *host_dev, int sw_addr);
int (*setup)(struct dsa_switch *ds);
int (*set_addr)(struct dsa_switch *ds, u8 *addr);
@ -210,6 +213,7 @@ struct dsa_switch_driver {
void register_switch_driver(struct dsa_switch_driver *type);
void unregister_switch_driver(struct dsa_switch_driver *type);
struct mii_bus *dsa_host_dev_to_mii_bus(struct device *dev);
static inline void *ds_to_priv(struct dsa_switch *ds)
{
@ -218,7 +222,6 @@ static inline void *ds_to_priv(struct dsa_switch *ds)
static inline bool dsa_uses_tagged_protocol(struct dsa_switch_tree *dst)
{
return dst->tag_protocol != DSA_TAG_PROTO_NONE;
return dst->rcv != NULL;
}
#endif

View File

@ -10,7 +10,6 @@
*/
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/module.h>
@ -44,7 +43,7 @@ void unregister_switch_driver(struct dsa_switch_driver *drv)
EXPORT_SYMBOL_GPL(unregister_switch_driver);
static struct dsa_switch_driver *
dsa_switch_probe(struct mii_bus *bus, int sw_addr, char **_name)
dsa_switch_probe(struct device *host_dev, int sw_addr, char **_name)
{
struct dsa_switch_driver *ret;
struct list_head *list;
@ -59,7 +58,7 @@ dsa_switch_probe(struct mii_bus *bus, int sw_addr, char **_name)
drv = list_entry(list, struct dsa_switch_driver, list);
name = drv->probe(bus, sw_addr);
name = drv->probe(host_dev, sw_addr);
if (name != NULL) {
ret = drv;
break;
@ -76,7 +75,7 @@ dsa_switch_probe(struct mii_bus *bus, int sw_addr, char **_name)
/* basic switch operations **************************************************/
static struct dsa_switch *
dsa_switch_setup(struct dsa_switch_tree *dst, int index,
struct device *parent, struct mii_bus *bus)
struct device *parent, struct device *host_dev)
{
struct dsa_chip_data *pd = dst->pd->chip + index;
struct dsa_switch_driver *drv;
@ -89,7 +88,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
/*
* Probe for switch model.
*/
drv = dsa_switch_probe(bus, pd->sw_addr, &name);
drv = dsa_switch_probe(host_dev, pd->sw_addr, &name);
if (drv == NULL) {
printk(KERN_ERR "%s[%d]: could not detect attached switch\n",
dst->master_netdev->name, index);
@ -110,8 +109,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
ds->index = index;
ds->pd = dst->pd->chip + index;
ds->drv = drv;
ds->master_mii_bus = bus;
ds->master_dev = host_dev;
/*
* Validate supplied switch configuration.
@ -154,9 +152,34 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
* tagging protocol to the preferred tagging format of this
* switch.
*/
if (ds->dst->cpu_switch == index)
ds->dst->tag_protocol = drv->tag_protocol;
if (dst->cpu_switch == index) {
switch (drv->tag_protocol) {
#ifdef CONFIG_NET_DSA_TAG_DSA
case DSA_TAG_PROTO_DSA:
dst->rcv = dsa_netdev_ops.rcv;
break;
#endif
#ifdef CONFIG_NET_DSA_TAG_EDSA
case DSA_TAG_PROTO_EDSA:
dst->rcv = edsa_netdev_ops.rcv;
break;
#endif
#ifdef CONFIG_NET_DSA_TAG_TRAILER
case DSA_TAG_PROTO_TRAILER:
dst->rcv = trailer_netdev_ops.rcv;
break;
#endif
#ifdef CONFIG_NET_DSA_TAG_BRCM
case DSA_TAG_PROTO_BRCM:
dst->rcv = brcm_netdev_ops.rcv;
break;
#endif
default:
break;
}
dst->tag_protocol = drv->tag_protocol;
}
/*
* Do basic register setup.
@ -261,7 +284,7 @@ static struct device *dev_find_class(struct device *parent, char *class)
return device_find_child(parent, class, dev_is_class);
}
static struct mii_bus *dev_to_mii_bus(struct device *dev)
struct mii_bus *dsa_host_dev_to_mii_bus(struct device *dev)
{
struct device *d;
@ -277,6 +300,7 @@ static struct mii_bus *dev_to_mii_bus(struct device *dev)
return NULL;
}
EXPORT_SYMBOL_GPL(dsa_host_dev_to_mii_bus);
static struct net_device *dev_to_net_device(struct device *dev)
{
@ -542,17 +566,9 @@ static int dsa_probe(struct platform_device *pdev)
dst->cpu_port = -1;
for (i = 0; i < pd->nr_chips; i++) {
struct mii_bus *bus;
struct dsa_switch *ds;
bus = dev_to_mii_bus(pd->chip[i].mii_bus);
if (bus == NULL) {
printk(KERN_ERR "%s[%d]: no mii bus found for "
"dsa switch\n", dev->name, i);
continue;
}
ds = dsa_switch_setup(dst, i, &pdev->dev, bus);
ds = dsa_switch_setup(dst, i, &pdev->dev, pd->chip[i].host_dev);
if (IS_ERR(ds)) {
printk(KERN_ERR "%s[%d]: couldn't create dsa switch "
"instance (error %ld)\n", dev->name, i,
@ -626,7 +642,7 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
return 0;
}
return dst->ops->rcv(skb, dev, pt, orig_dev);
return dst->rcv(skb, dev, pt, orig_dev);
}
static struct packet_type dsa_pack_type __read_mostly = {

View File

@ -12,7 +12,13 @@
#define __DSA_PRIV_H
#include <linux/phy.h>
#include <net/dsa.h>
#include <linux/netdevice.h>
struct dsa_device_ops {
netdev_tx_t (*xmit)(struct sk_buff *skb, struct net_device *dev);
int (*rcv)(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev);
};
struct dsa_slave_priv {
/*
@ -20,6 +26,8 @@ struct dsa_slave_priv {
* switch port.
*/
struct net_device *dev;
netdev_tx_t (*xmit)(struct sk_buff *skb,
struct net_device *dev);
/*
* Which switch this port is a part of, and the port index
@ -43,6 +51,7 @@ struct dsa_slave_priv {
extern char dsa_driver_version[];
/* slave.c */
extern const struct dsa_device_ops notag_netdev_ops;
void dsa_slave_mii_bus_init(struct dsa_switch *ds);
struct net_device *dsa_slave_create(struct dsa_switch *ds,
struct device *parent,

View File

@ -9,7 +9,6 @@
*/
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/phy.h>
#include <linux/of_net.h>
@ -45,7 +44,7 @@ void dsa_slave_mii_bus_init(struct dsa_switch *ds)
ds->slave_mii_bus->write = dsa_slave_phy_write;
snprintf(ds->slave_mii_bus->id, MII_BUS_ID_SIZE, "dsa-%d:%.2x",
ds->index, ds->pd->sw_addr);
ds->slave_mii_bus->parent = &ds->master_mii_bus->dev;
ds->slave_mii_bus->parent = ds->master_dev;
}
@ -176,9 +175,8 @@ static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch_tree *dst = p->parent->dst;
return dst->ops->xmit(skb, dev);
return p->xmit(skb, dev);
}
static netdev_tx_t dsa_slave_notag_xmit(struct sk_buff *skb,
@ -325,11 +323,6 @@ static const struct net_device_ops dsa_slave_netdev_ops = {
.ndo_do_ioctl = dsa_slave_ioctl,
};
static const struct dsa_device_ops notag_netdev_ops = {
.xmit = dsa_slave_notag_xmit,
.rcv = NULL,
};
static void dsa_slave_adjust_link(struct net_device *dev)
{
struct dsa_slave_priv *p = netdev_priv(dev);
@ -435,32 +428,6 @@ dsa_slave_create(struct dsa_switch *ds, struct device *parent,
slave_dev->tx_queue_len = 0;
slave_dev->netdev_ops = &dsa_slave_netdev_ops;
switch (ds->dst->tag_protocol) {
#ifdef CONFIG_NET_DSA_TAG_DSA
case DSA_TAG_PROTO_DSA:
ds->dst->ops = &dsa_netdev_ops;
break;
#endif
#ifdef CONFIG_NET_DSA_TAG_EDSA
case DSA_TAG_PROTO_EDSA:
ds->dst->ops = &edsa_netdev_ops;
break;
#endif
#ifdef CONFIG_NET_DSA_TAG_TRAILER
case DSA_TAG_PROTO_TRAILER:
ds->dst->ops = &trailer_netdev_ops;
break;
#endif
#ifdef CONFIG_NET_DSA_TAG_BRCM
case DSA_TAG_PROTO_BRCM:
ds->dst->ops = &brcm_netdev_ops;
break;
#endif
default:
ds->dst->ops = &notag_netdev_ops;
break;
}
SET_NETDEV_DEV(slave_dev, parent);
slave_dev->dev.of_node = ds->pd->port_dn[port];
slave_dev->vlan_features = master->vlan_features;
@ -470,6 +437,32 @@ dsa_slave_create(struct dsa_switch *ds, struct device *parent,
p->parent = ds;
p->port = port;
switch (ds->dst->tag_protocol) {
#ifdef CONFIG_NET_DSA_TAG_DSA
case DSA_TAG_PROTO_DSA:
p->xmit = dsa_netdev_ops.xmit;
break;
#endif
#ifdef CONFIG_NET_DSA_TAG_EDSA
case DSA_TAG_PROTO_EDSA:
p->xmit = edsa_netdev_ops.xmit;
break;
#endif
#ifdef CONFIG_NET_DSA_TAG_TRAILER
case DSA_TAG_PROTO_TRAILER:
p->xmit = trailer_netdev_ops.xmit;
break;
#endif
#ifdef CONFIG_NET_DSA_TAG_BRCM
case DSA_TAG_PROTO_BRCM:
p->xmit = brcm_netdev_ops.xmit;
break;
#endif
default:
p->xmit = dsa_slave_notag_xmit;
break;
}
p->old_pause = -1;
p->old_link = -1;
p->old_duplex = -1;

View File

@ -11,7 +11,6 @@
#include <linux/etherdevice.h>
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/slab.h>
#include "dsa_priv.h"

View File

@ -10,7 +10,6 @@
#include <linux/etherdevice.h>
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/slab.h>
#include "dsa_priv.h"

View File

@ -10,7 +10,6 @@
#include <linux/etherdevice.h>
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/slab.h>
#include "dsa_priv.h"

View File

@ -10,7 +10,6 @@
#include <linux/etherdevice.h>
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/slab.h>
#include "dsa_priv.h"