forked from Minki/linux
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:
commit
0486b60a8c
@ -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);
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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 = {
|
||||
|
@ -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,
|
||||
|
@ -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 = ¬ag_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;
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/slab.h>
|
||||
#include "dsa_priv.h"
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/slab.h>
|
||||
#include "dsa_priv.h"
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/slab.h>
|
||||
#include "dsa_priv.h"
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/slab.h>
|
||||
#include "dsa_priv.h"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user