Commit 6d45408d authored by David S. Miller's avatar David S. Miller

Merge branch 'dsa-multi-chip-prep'

Vivien Didelot says:

====================
net: dsa: preparatory patches for multi-chip

In order to introduce support for multi-chip configuration, we need to
do a few enhancements. This patchset makes the number of ports in a
switch dynamic (instead of capping to DSA_MAX_PORTS), stores the switch
and index of a port in the dsa_port structure, uses it in the slave
private structure, and exposes the bridge device a port belongs to.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 1f5d492a ddd3a0c8
...@@ -1308,7 +1308,7 @@ int b53_fdb_dump(struct dsa_switch *ds, int port, ...@@ -1308,7 +1308,7 @@ int b53_fdb_dump(struct dsa_switch *ds, int port,
} }
EXPORT_SYMBOL(b53_fdb_dump); EXPORT_SYMBOL(b53_fdb_dump);
int b53_br_join(struct dsa_switch *ds, int port, struct net_device *bridge) int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br)
{ {
struct b53_device *dev = ds->priv; struct b53_device *dev = ds->priv;
s8 cpu_port = ds->dst->cpu_port; s8 cpu_port = ds->dst->cpu_port;
...@@ -1326,11 +1326,10 @@ int b53_br_join(struct dsa_switch *ds, int port, struct net_device *bridge) ...@@ -1326,11 +1326,10 @@ int b53_br_join(struct dsa_switch *ds, int port, struct net_device *bridge)
b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, reg); b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, reg);
} }
dev->ports[port].bridge_dev = bridge;
b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), &pvlan); b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), &pvlan);
b53_for_each_port(dev, i) { b53_for_each_port(dev, i) {
if (dev->ports[i].bridge_dev != bridge) if (ds->ports[i].bridge_dev != br)
continue; continue;
/* Add this local port to the remote port VLAN control /* Add this local port to the remote port VLAN control
...@@ -1354,10 +1353,9 @@ int b53_br_join(struct dsa_switch *ds, int port, struct net_device *bridge) ...@@ -1354,10 +1353,9 @@ int b53_br_join(struct dsa_switch *ds, int port, struct net_device *bridge)
} }
EXPORT_SYMBOL(b53_br_join); EXPORT_SYMBOL(b53_br_join);
void b53_br_leave(struct dsa_switch *ds, int port) void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *br)
{ {
struct b53_device *dev = ds->priv; struct b53_device *dev = ds->priv;
struct net_device *bridge = dev->ports[port].bridge_dev;
struct b53_vlan *vl = &dev->vlans[0]; struct b53_vlan *vl = &dev->vlans[0];
s8 cpu_port = ds->dst->cpu_port; s8 cpu_port = ds->dst->cpu_port;
unsigned int i; unsigned int i;
...@@ -1367,7 +1365,7 @@ void b53_br_leave(struct dsa_switch *ds, int port) ...@@ -1367,7 +1365,7 @@ void b53_br_leave(struct dsa_switch *ds, int port)
b53_for_each_port(dev, i) { b53_for_each_port(dev, i) {
/* Don't touch the remaining ports */ /* Don't touch the remaining ports */
if (dev->ports[i].bridge_dev != bridge) if (ds->ports[i].bridge_dev != br)
continue; continue;
b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), &reg); b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), &reg);
...@@ -1382,7 +1380,6 @@ void b53_br_leave(struct dsa_switch *ds, int port) ...@@ -1382,7 +1380,6 @@ void b53_br_leave(struct dsa_switch *ds, int port)
b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan); b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan);
dev->ports[port].vlan_ctl_mask = pvlan; dev->ports[port].vlan_ctl_mask = pvlan;
dev->ports[port].bridge_dev = NULL;
if (is5325(dev) || is5365(dev)) if (is5325(dev) || is5365(dev))
pvid = 1; pvid = 1;
...@@ -1790,14 +1787,15 @@ struct b53_device *b53_switch_alloc(struct device *base, ...@@ -1790,14 +1787,15 @@ struct b53_device *b53_switch_alloc(struct device *base,
struct dsa_switch *ds; struct dsa_switch *ds;
struct b53_device *dev; struct b53_device *dev;
ds = devm_kzalloc(base, sizeof(*ds) + sizeof(*dev), GFP_KERNEL); ds = dsa_switch_alloc(base, DSA_MAX_PORTS);
if (!ds) if (!ds)
return NULL; return NULL;
dev = (struct b53_device *)(ds + 1); dev = devm_kzalloc(base, sizeof(*dev), GFP_KERNEL);
if (!dev)
return NULL;
ds->priv = dev; ds->priv = dev;
ds->dev = base;
dev->dev = base; dev->dev = base;
dev->ds = ds; dev->ds = ds;
......
...@@ -70,7 +70,6 @@ enum { ...@@ -70,7 +70,6 @@ enum {
struct b53_port { struct b53_port {
u16 vlan_ctl_mask; u16 vlan_ctl_mask;
struct net_device *bridge_dev;
}; };
struct b53_vlan { struct b53_vlan {
...@@ -382,7 +381,7 @@ void b53_get_strings(struct dsa_switch *ds, int port, uint8_t *data); ...@@ -382,7 +381,7 @@ void b53_get_strings(struct dsa_switch *ds, int port, uint8_t *data);
void b53_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data); void b53_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data);
int b53_get_sset_count(struct dsa_switch *ds); int b53_get_sset_count(struct dsa_switch *ds);
int b53_br_join(struct dsa_switch *ds, int port, struct net_device *bridge); int b53_br_join(struct dsa_switch *ds, int port, struct net_device *bridge);
void b53_br_leave(struct dsa_switch *ds, int port); void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *bridge);
void b53_br_set_stp_state(struct dsa_switch *ds, int port, u8 state); void b53_br_set_stp_state(struct dsa_switch *ds, int port, u8 state);
void b53_br_fast_age(struct dsa_switch *ds, int port); void b53_br_fast_age(struct dsa_switch *ds, int port);
int b53_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering); int b53_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering);
......
...@@ -1247,8 +1247,8 @@ static int _mv88e6xxx_atu_remove(struct mv88e6xxx_chip *chip, u16 fid, ...@@ -1247,8 +1247,8 @@ static int _mv88e6xxx_atu_remove(struct mv88e6xxx_chip *chip, u16 fid,
static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_chip *chip, int port) static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_chip *chip, int port)
{ {
struct net_device *bridge = chip->ports[port].bridge_dev;
struct dsa_switch *ds = chip->ds; struct dsa_switch *ds = chip->ds;
struct net_device *bridge = ds->ports[port].bridge_dev;
u16 output_ports = 0; u16 output_ports = 0;
int i; int i;
...@@ -1258,7 +1258,7 @@ static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_chip *chip, int port) ...@@ -1258,7 +1258,7 @@ static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_chip *chip, int port)
} else { } else {
for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
/* allow sending frames to every group member */ /* allow sending frames to every group member */
if (bridge && chip->ports[i].bridge_dev == bridge) if (bridge && ds->ports[i].bridge_dev == bridge)
output_ports |= BIT(i); output_ports |= BIT(i);
/* allow sending frames to CPU port and DSA link(s) */ /* allow sending frames to CPU port and DSA link(s) */
...@@ -1820,17 +1820,17 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port, ...@@ -1820,17 +1820,17 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER) GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
continue; continue;
if (chip->ports[i].bridge_dev == if (ds->ports[i].bridge_dev ==
chip->ports[port].bridge_dev) ds->ports[port].bridge_dev)
break; /* same bridge, check next VLAN */ break; /* same bridge, check next VLAN */
if (!chip->ports[i].bridge_dev) if (!ds->ports[i].bridge_dev)
continue; continue;
netdev_warn(ds->ports[port].netdev, netdev_warn(ds->ports[port].netdev,
"hardware VLAN %d already used by %s\n", "hardware VLAN %d already used by %s\n",
vlan.vid, vlan.vid,
netdev_name(chip->ports[i].bridge_dev)); netdev_name(ds->ports[i].bridge_dev));
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto unlock; goto unlock;
} }
...@@ -2320,18 +2320,16 @@ static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port, ...@@ -2320,18 +2320,16 @@ static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
} }
static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
struct net_device *bridge) struct net_device *br)
{ {
struct mv88e6xxx_chip *chip = ds->priv; struct mv88e6xxx_chip *chip = ds->priv;
int i, err = 0; int i, err = 0;
mutex_lock(&chip->reg_lock); mutex_lock(&chip->reg_lock);
/* Assign the bridge and remap each port's VLANTable */ /* Remap each port's VLANTable */
chip->ports[port].bridge_dev = bridge;
for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
if (chip->ports[i].bridge_dev == bridge) { if (ds->ports[i].bridge_dev == br) {
err = _mv88e6xxx_port_based_vlan_map(chip, i); err = _mv88e6xxx_port_based_vlan_map(chip, i);
if (err) if (err)
break; break;
...@@ -2343,19 +2341,17 @@ static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, ...@@ -2343,19 +2341,17 @@ static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
return err; return err;
} }
static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port) static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port,
struct net_device *br)
{ {
struct mv88e6xxx_chip *chip = ds->priv; struct mv88e6xxx_chip *chip = ds->priv;
struct net_device *bridge = chip->ports[port].bridge_dev;
int i; int i;
mutex_lock(&chip->reg_lock); mutex_lock(&chip->reg_lock);
/* Unassign the bridge and remap each port's VLANTable */ /* Remap each port's VLANTable */
chip->ports[port].bridge_dev = NULL;
for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
if (i == port || chip->ports[i].bridge_dev == bridge) if (i == port || ds->ports[i].bridge_dev == br)
if (_mv88e6xxx_port_based_vlan_map(chip, i)) if (_mv88e6xxx_port_based_vlan_map(chip, i))
netdev_warn(ds->ports[i].netdev, netdev_warn(ds->ports[i].netdev,
"failed to remap\n"); "failed to remap\n");
...@@ -4361,11 +4357,10 @@ static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip) ...@@ -4361,11 +4357,10 @@ static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip)
struct device *dev = chip->dev; struct device *dev = chip->dev;
struct dsa_switch *ds; struct dsa_switch *ds;
ds = devm_kzalloc(dev, sizeof(*ds), GFP_KERNEL); ds = dsa_switch_alloc(dev, DSA_MAX_PORTS);
if (!ds) if (!ds)
return -ENOMEM; return -ENOMEM;
ds->dev = dev;
ds->priv = chip; ds->priv = chip;
ds->ops = &mv88e6xxx_switch_ops; ds->ops = &mv88e6xxx_switch_ops;
......
...@@ -676,10 +676,6 @@ struct mv88e6xxx_vtu_entry { ...@@ -676,10 +676,6 @@ struct mv88e6xxx_vtu_entry {
struct mv88e6xxx_bus_ops; struct mv88e6xxx_bus_ops;
struct mv88e6xxx_priv_port {
struct net_device *bridge_dev;
};
struct mv88e6xxx_irq { struct mv88e6xxx_irq {
u16 masked; u16 masked;
struct irq_chip chip; struct irq_chip chip;
...@@ -720,8 +716,6 @@ struct mv88e6xxx_chip { ...@@ -720,8 +716,6 @@ struct mv88e6xxx_chip {
*/ */
struct mutex stats_mutex; struct mutex stats_mutex;
struct mv88e6xxx_priv_port ports[DSA_MAX_PORTS];
/* A switch may have a GPIO line tied to its reset pin. Parse /* A switch may have a GPIO line tied to its reset pin. Parse
* this from the device tree, and use it before performing * this from the device tree, and use it before performing
* switch soft reset. * switch soft reset.
......
...@@ -746,17 +746,14 @@ qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) ...@@ -746,17 +746,14 @@ qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
} }
static int static int
qca8k_port_bridge_join(struct dsa_switch *ds, int port, qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br)
struct net_device *bridge)
{ {
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
int port_mask = BIT(QCA8K_CPU_PORT); int port_mask = BIT(QCA8K_CPU_PORT);
int i; int i;
priv->port_sts[port].bridge_dev = bridge;
for (i = 1; i < QCA8K_NUM_PORTS; i++) { for (i = 1; i < QCA8K_NUM_PORTS; i++) {
if (priv->port_sts[i].bridge_dev != bridge) if (ds->ports[i].bridge_dev != br)
continue; continue;
/* Add this port to the portvlan mask of the other ports /* Add this port to the portvlan mask of the other ports
* in the bridge * in the bridge
...@@ -775,14 +772,13 @@ qca8k_port_bridge_join(struct dsa_switch *ds, int port, ...@@ -775,14 +772,13 @@ qca8k_port_bridge_join(struct dsa_switch *ds, int port,
} }
static void static void
qca8k_port_bridge_leave(struct dsa_switch *ds, int port) qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br)
{ {
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
int i; int i;
for (i = 1; i < QCA8K_NUM_PORTS; i++) { for (i = 1; i < QCA8K_NUM_PORTS; i++) {
if (priv->port_sts[i].bridge_dev != if (ds->ports[i].bridge_dev != br)
priv->port_sts[port].bridge_dev)
continue; continue;
/* Remove this port to the portvlan mask of the other ports /* Remove this port to the portvlan mask of the other ports
* in the bridge * in the bridge
...@@ -791,7 +787,7 @@ qca8k_port_bridge_leave(struct dsa_switch *ds, int port) ...@@ -791,7 +787,7 @@ qca8k_port_bridge_leave(struct dsa_switch *ds, int port)
QCA8K_PORT_LOOKUP_CTRL(i), QCA8K_PORT_LOOKUP_CTRL(i),
BIT(port)); BIT(port));
} }
priv->port_sts[port].bridge_dev = NULL;
/* Set the cpu port to be the only one in the portvlan mask of /* Set the cpu port to be the only one in the portvlan mask of
* this port * this port
*/ */
...@@ -954,12 +950,11 @@ qca8k_sw_probe(struct mdio_device *mdiodev) ...@@ -954,12 +950,11 @@ qca8k_sw_probe(struct mdio_device *mdiodev)
if (id != QCA8K_ID_QCA8337) if (id != QCA8K_ID_QCA8337)
return -ENODEV; return -ENODEV;
priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL); priv->ds = dsa_switch_alloc(&mdiodev->dev, DSA_MAX_PORTS);
if (!priv->ds) if (!priv->ds)
return -ENOMEM; return -ENOMEM;
priv->ds->priv = priv; priv->ds->priv = priv;
priv->ds->dev = &mdiodev->dev;
priv->ds->ops = &qca8k_switch_ops; priv->ds->ops = &qca8k_switch_ops;
mutex_init(&priv->reg_mutex); mutex_init(&priv->reg_mutex);
dev_set_drvdata(&mdiodev->dev, priv); dev_set_drvdata(&mdiodev->dev, priv);
......
...@@ -157,7 +157,6 @@ enum qca8k_fdb_cmd { ...@@ -157,7 +157,6 @@ enum qca8k_fdb_cmd {
struct ar8xxx_port_status { struct ar8xxx_port_status {
struct ethtool_eee eee; struct ethtool_eee eee;
struct net_device *bridge_dev;
int enabled; int enabled;
}; };
......
...@@ -140,10 +140,13 @@ struct dsa_switch_tree { ...@@ -140,10 +140,13 @@ struct dsa_switch_tree {
}; };
struct dsa_port { struct dsa_port {
struct dsa_switch *ds;
unsigned int index;
struct net_device *netdev; struct net_device *netdev;
struct device_node *dn; struct device_node *dn;
unsigned int ageing_time; unsigned int ageing_time;
u8 stp_state; u8 stp_state;
struct net_device *bridge_dev;
}; };
struct dsa_switch { struct dsa_switch {
...@@ -190,8 +193,11 @@ struct dsa_switch { ...@@ -190,8 +193,11 @@ struct dsa_switch {
u32 cpu_port_mask; u32 cpu_port_mask;
u32 enabled_port_mask; u32 enabled_port_mask;
u32 phys_mii_mask; u32 phys_mii_mask;
struct dsa_port ports[DSA_MAX_PORTS];
struct mii_bus *slave_mii_bus; struct mii_bus *slave_mii_bus;
/* Dynamically allocated ports, keep last */
size_t num_ports;
struct dsa_port ports[];
}; };
static inline bool dsa_is_cpu_port(struct dsa_switch *ds, int p) static inline bool dsa_is_cpu_port(struct dsa_switch *ds, int p)
...@@ -319,7 +325,8 @@ struct dsa_switch_ops { ...@@ -319,7 +325,8 @@ struct dsa_switch_ops {
int (*set_ageing_time)(struct dsa_switch *ds, unsigned int msecs); int (*set_ageing_time)(struct dsa_switch *ds, unsigned int msecs);
int (*port_bridge_join)(struct dsa_switch *ds, int port, int (*port_bridge_join)(struct dsa_switch *ds, int port,
struct net_device *bridge); struct net_device *bridge);
void (*port_bridge_leave)(struct dsa_switch *ds, int port); void (*port_bridge_leave)(struct dsa_switch *ds, int port,
struct net_device *bridge);
void (*port_stp_state_set)(struct dsa_switch *ds, int port, void (*port_stp_state_set)(struct dsa_switch *ds, int port,
u8 state); u8 state);
void (*port_fast_age)(struct dsa_switch *ds, int port); void (*port_fast_age)(struct dsa_switch *ds, int port);
...@@ -386,6 +393,7 @@ static inline bool dsa_uses_tagged_protocol(struct dsa_switch_tree *dst) ...@@ -386,6 +393,7 @@ static inline bool dsa_uses_tagged_protocol(struct dsa_switch_tree *dst)
return dst->rcv != NULL; return dst->rcv != NULL;
} }
struct dsa_switch *dsa_switch_alloc(struct device *dev, size_t n);
void dsa_unregister_switch(struct dsa_switch *ds); void dsa_unregister_switch(struct dsa_switch *ds);
int dsa_register_switch(struct dsa_switch *ds, struct device *dev); int dsa_register_switch(struct dsa_switch *ds, struct device *dev);
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
......
...@@ -145,7 +145,7 @@ static int dsa_cpu_dsa_setups(struct dsa_switch *ds, struct device *dev) ...@@ -145,7 +145,7 @@ static int dsa_cpu_dsa_setups(struct dsa_switch *ds, struct device *dev)
struct dsa_port *dport; struct dsa_port *dport;
int ret, port; int ret, port;
for (port = 0; port < DSA_MAX_PORTS; port++) { for (port = 0; port < ds->num_ports; port++) {
if (!(dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port))) if (!(dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)))
continue; continue;
...@@ -218,7 +218,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent) ...@@ -218,7 +218,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
/* /*
* Validate supplied switch configuration. * Validate supplied switch configuration.
*/ */
for (i = 0; i < DSA_MAX_PORTS; i++) { for (i = 0; i < ds->num_ports; i++) {
char *name; char *name;
name = cd->port_names[i]; name = cd->port_names[i];
...@@ -242,7 +242,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent) ...@@ -242,7 +242,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
valid_name_found = true; valid_name_found = true;
} }
if (!valid_name_found && i == DSA_MAX_PORTS) if (!valid_name_found && i == ds->num_ports)
return -EINVAL; return -EINVAL;
/* Make the built-in MII bus mask match the number of ports, /* Make the built-in MII bus mask match the number of ports,
...@@ -295,7 +295,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent) ...@@ -295,7 +295,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
/* /*
* Create network devices for physical switch ports. * Create network devices for physical switch ports.
*/ */
for (i = 0; i < DSA_MAX_PORTS; i++) { for (i = 0; i < ds->num_ports; i++) {
ds->ports[i].dn = cd->port_dn[i]; ds->ports[i].dn = cd->port_dn[i];
if (!(ds->enabled_port_mask & (1 << i))) if (!(ds->enabled_port_mask & (1 << i)))
...@@ -347,8 +347,8 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index, ...@@ -347,8 +347,8 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
/* /*
* Allocate and initialise switch state. * Allocate and initialise switch state.
*/ */
ds = devm_kzalloc(parent, sizeof(*ds), GFP_KERNEL); ds = dsa_switch_alloc(parent, DSA_MAX_PORTS);
if (ds == NULL) if (!ds)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
ds->dst = dst; ds->dst = dst;
...@@ -356,7 +356,6 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index, ...@@ -356,7 +356,6 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
ds->cd = cd; ds->cd = cd;
ds->ops = ops; ds->ops = ops;
ds->priv = priv; ds->priv = priv;
ds->dev = parent;
ret = dsa_switch_setup_one(ds, parent); ret = dsa_switch_setup_one(ds, parent);
if (ret) if (ret)
...@@ -378,7 +377,7 @@ static void dsa_switch_destroy(struct dsa_switch *ds) ...@@ -378,7 +377,7 @@ static void dsa_switch_destroy(struct dsa_switch *ds)
int port; int port;
/* Destroy network devices for physical switch ports. */ /* Destroy network devices for physical switch ports. */
for (port = 0; port < DSA_MAX_PORTS; port++) { for (port = 0; port < ds->num_ports; port++) {
if (!(ds->enabled_port_mask & (1 << port))) if (!(ds->enabled_port_mask & (1 << port)))
continue; continue;
...@@ -389,7 +388,7 @@ static void dsa_switch_destroy(struct dsa_switch *ds) ...@@ -389,7 +388,7 @@ static void dsa_switch_destroy(struct dsa_switch *ds)
} }
/* Disable configuration of the CPU and DSA ports */ /* Disable configuration of the CPU and DSA ports */
for (port = 0; port < DSA_MAX_PORTS; port++) { for (port = 0; port < ds->num_ports; port++) {
if (!(dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port))) if (!(dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)))
continue; continue;
dsa_cpu_dsa_destroy(&ds->ports[port]); dsa_cpu_dsa_destroy(&ds->ports[port]);
...@@ -409,7 +408,7 @@ int dsa_switch_suspend(struct dsa_switch *ds) ...@@ -409,7 +408,7 @@ int dsa_switch_suspend(struct dsa_switch *ds)
int i, ret = 0; int i, ret = 0;
/* Suspend slave network devices */ /* Suspend slave network devices */
for (i = 0; i < DSA_MAX_PORTS; i++) { for (i = 0; i < ds->num_ports; i++) {
if (!dsa_is_port_initialized(ds, i)) if (!dsa_is_port_initialized(ds, i))
continue; continue;
...@@ -436,7 +435,7 @@ int dsa_switch_resume(struct dsa_switch *ds) ...@@ -436,7 +435,7 @@ int dsa_switch_resume(struct dsa_switch *ds)
return ret; return ret;
/* Resume slave network devices */ /* Resume slave network devices */
for (i = 0; i < DSA_MAX_PORTS; i++) { for (i = 0; i < ds->num_ports; i++) {
if (!dsa_is_port_initialized(ds, i)) if (!dsa_is_port_initialized(ds, i))
continue; continue;
......
...@@ -98,7 +98,7 @@ static bool dsa_ds_find_port_dn(struct dsa_switch *ds, ...@@ -98,7 +98,7 @@ static bool dsa_ds_find_port_dn(struct dsa_switch *ds,
{ {
u32 index; u32 index;
for (index = 0; index < DSA_MAX_PORTS; index++) for (index = 0; index < ds->num_ports; index++)
if (ds->ports[index].dn == port) if (ds->ports[index].dn == port)
return true; return true;
return false; return false;
...@@ -159,7 +159,7 @@ static int dsa_ds_complete(struct dsa_switch_tree *dst, struct dsa_switch *ds) ...@@ -159,7 +159,7 @@ static int dsa_ds_complete(struct dsa_switch_tree *dst, struct dsa_switch *ds)
u32 index; u32 index;
int err; int err;
for (index = 0; index < DSA_MAX_PORTS; index++) { for (index = 0; index < ds->num_ports; index++) {
port = &ds->ports[index]; port = &ds->ports[index];
if (!dsa_port_is_valid(port)) if (!dsa_port_is_valid(port))
continue; continue;
...@@ -312,7 +312,7 @@ static int dsa_ds_apply(struct dsa_switch_tree *dst, struct dsa_switch *ds) ...@@ -312,7 +312,7 @@ static int dsa_ds_apply(struct dsa_switch_tree *dst, struct dsa_switch *ds)
return err; return err;
} }
for (index = 0; index < DSA_MAX_PORTS; index++) { for (index = 0; index < ds->num_ports; index++) {
port = &ds->ports[index]; port = &ds->ports[index];
if (!dsa_port_is_valid(port)) if (!dsa_port_is_valid(port))
continue; continue;
...@@ -344,7 +344,7 @@ static void dsa_ds_unapply(struct dsa_switch_tree *dst, struct dsa_switch *ds) ...@@ -344,7 +344,7 @@ static void dsa_ds_unapply(struct dsa_switch_tree *dst, struct dsa_switch *ds)
struct dsa_port *port; struct dsa_port *port;
u32 index; u32 index;
for (index = 0; index < DSA_MAX_PORTS; index++) { for (index = 0; index < ds->num_ports; index++) {
port = &ds->ports[index]; port = &ds->ports[index];
if (!dsa_port_is_valid(port)) if (!dsa_port_is_valid(port))
continue; continue;
...@@ -475,7 +475,7 @@ static int dsa_ds_parse(struct dsa_switch_tree *dst, struct dsa_switch *ds) ...@@ -475,7 +475,7 @@ static int dsa_ds_parse(struct dsa_switch_tree *dst, struct dsa_switch *ds)
u32 index; u32 index;
int err; int err;
for (index = 0; index < DSA_MAX_PORTS; index++) { for (index = 0; index < ds->num_ports; index++) {
port = &ds->ports[index]; port = &ds->ports[index];
if (!dsa_port_is_valid(port)) if (!dsa_port_is_valid(port))
continue; continue;
...@@ -529,7 +529,7 @@ static int dsa_parse_ports_dn(struct device_node *ports, struct dsa_switch *ds) ...@@ -529,7 +529,7 @@ static int dsa_parse_ports_dn(struct device_node *ports, struct dsa_switch *ds)
if (err) if (err)
return err; return err;
if (reg >= DSA_MAX_PORTS) if (reg >= ds->num_ports)
return -EINVAL; return -EINVAL;
ds->ports[reg].dn = port; ds->ports[reg].dn = port;
...@@ -666,6 +666,28 @@ static int _dsa_register_switch(struct dsa_switch *ds, struct device *dev) ...@@ -666,6 +666,28 @@ static int _dsa_register_switch(struct dsa_switch *ds, struct device *dev)
return err; return err;
} }
struct dsa_switch *dsa_switch_alloc(struct device *dev, size_t n)
{
size_t size = sizeof(struct dsa_switch) + n * sizeof(struct dsa_port);
struct dsa_switch *ds;
int i;
ds = devm_kzalloc(dev, size, GFP_KERNEL);
if (!ds)
return NULL;
ds->dev = dev;
ds->num_ports = n;
for (i = 0; i < ds->num_ports; ++i) {
ds->ports[i].index = i;
ds->ports[i].ds = ds;
}
return ds;
}
EXPORT_SYMBOL_GPL(dsa_switch_alloc);
int dsa_register_switch(struct dsa_switch *ds, struct device *dev) int dsa_register_switch(struct dsa_switch *ds, struct device *dev)
{ {
int err; int err;
......
...@@ -25,12 +25,8 @@ struct dsa_slave_priv { ...@@ -25,12 +25,8 @@ struct dsa_slave_priv {
struct sk_buff * (*xmit)(struct sk_buff *skb, struct sk_buff * (*xmit)(struct sk_buff *skb,
struct net_device *dev); struct net_device *dev);
/* /* DSA port data, such as switch, port index, etc. */
* Which switch this port is a part of, and the port index struct dsa_port *dp;
* for this port.
*/
struct dsa_switch *parent;
u8 port;
/* /*
* The phylib phy_device pointer for the PHY connected * The phylib phy_device pointer for the PHY connected
...@@ -42,7 +38,6 @@ struct dsa_slave_priv { ...@@ -42,7 +38,6 @@ struct dsa_slave_priv {
int old_pause; int old_pause;
int old_duplex; int old_duplex;
struct net_device *bridge_dev;
#ifdef CONFIG_NET_POLL_CONTROLLER #ifdef CONFIG_NET_POLL_CONTROLLER
struct netpoll *netpoll; struct netpoll *netpoll;
#endif #endif
......
...@@ -61,12 +61,12 @@ static int dsa_slave_get_iflink(const struct net_device *dev) ...@@ -61,12 +61,12 @@ static int dsa_slave_get_iflink(const struct net_device *dev)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
return p->parent->dst->master_netdev->ifindex; return p->dp->ds->dst->master_netdev->ifindex;
} }
static inline bool dsa_port_is_bridged(struct dsa_slave_priv *p) static inline bool dsa_port_is_bridged(struct dsa_port *dp)
{ {
return !!p->bridge_dev; return !!dp->bridge_dev;
} }
static void dsa_port_set_stp_state(struct dsa_switch *ds, int port, u8 state) static void dsa_port_set_stp_state(struct dsa_switch *ds, int port, u8 state)
...@@ -96,9 +96,9 @@ static void dsa_port_set_stp_state(struct dsa_switch *ds, int port, u8 state) ...@@ -96,9 +96,9 @@ static void dsa_port_set_stp_state(struct dsa_switch *ds, int port, u8 state)
static int dsa_slave_open(struct net_device *dev) static int dsa_slave_open(struct net_device *dev)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct net_device *master = p->parent->dst->master_netdev; struct net_device *master = p->dp->ds->dst->master_netdev;
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
u8 stp_state = dsa_port_is_bridged(p) ? u8 stp_state = dsa_port_is_bridged(p->dp) ?
BR_STATE_BLOCKING : BR_STATE_FORWARDING; BR_STATE_BLOCKING : BR_STATE_FORWARDING;
int err; int err;
...@@ -123,12 +123,12 @@ static int dsa_slave_open(struct net_device *dev) ...@@ -123,12 +123,12 @@ static int dsa_slave_open(struct net_device *dev)
} }
if (ds->ops->port_enable) { if (ds->ops->port_enable) {
err = ds->ops->port_enable(ds, p->port, p->phy); err = ds->ops->port_enable(ds, p->dp->index, p->phy);
if (err) if (err)
goto clear_promisc; goto clear_promisc;
} }
dsa_port_set_stp_state(ds, p->port, stp_state); dsa_port_set_stp_state(ds, p->dp->index, stp_state);
if (p->phy) if (p->phy)
phy_start(p->phy); phy_start(p->phy);
...@@ -151,8 +151,8 @@ static int dsa_slave_open(struct net_device *dev) ...@@ -151,8 +151,8 @@ static int dsa_slave_open(struct net_device *dev)
static int dsa_slave_close(struct net_device *dev) static int dsa_slave_close(struct net_device *dev)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct net_device *master = p->parent->dst->master_netdev; struct net_device *master = p->dp->ds->dst->master_netdev;
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
if (p->phy) if (p->phy)
phy_stop(p->phy); phy_stop(p->phy);
...@@ -168,9 +168,9 @@ static int dsa_slave_close(struct net_device *dev) ...@@ -168,9 +168,9 @@ static int dsa_slave_close(struct net_device *dev)
dev_uc_del(master, dev->dev_addr); dev_uc_del(master, dev->dev_addr);
if (ds->ops->port_disable) if (ds->ops->port_disable)
ds->ops->port_disable(ds, p->port, p->phy); ds->ops->port_disable(ds, p->dp->index, p->phy);
dsa_port_set_stp_state(ds, p->port, BR_STATE_DISABLED); dsa_port_set_stp_state(ds, p->dp->index, BR_STATE_DISABLED);
return 0; return 0;
} }
...@@ -178,7 +178,7 @@ static int dsa_slave_close(struct net_device *dev) ...@@ -178,7 +178,7 @@ static int dsa_slave_close(struct net_device *dev)
static void dsa_slave_change_rx_flags(struct net_device *dev, int change) static void dsa_slave_change_rx_flags(struct net_device *dev, int change)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct net_device *master = p->parent->dst->master_netdev; struct net_device *master = p->dp->ds->dst->master_netdev;
if (change & IFF_ALLMULTI) if (change & IFF_ALLMULTI)
dev_set_allmulti(master, dev->flags & IFF_ALLMULTI ? 1 : -1); dev_set_allmulti(master, dev->flags & IFF_ALLMULTI ? 1 : -1);
...@@ -189,7 +189,7 @@ static void dsa_slave_change_rx_flags(struct net_device *dev, int change) ...@@ -189,7 +189,7 @@ static void dsa_slave_change_rx_flags(struct net_device *dev, int change)
static void dsa_slave_set_rx_mode(struct net_device *dev) static void dsa_slave_set_rx_mode(struct net_device *dev)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct net_device *master = p->parent->dst->master_netdev; struct net_device *master = p->dp->ds->dst->master_netdev;
dev_mc_sync(master, dev); dev_mc_sync(master, dev);
dev_uc_sync(master, dev); dev_uc_sync(master, dev);
...@@ -198,7 +198,7 @@ static void dsa_slave_set_rx_mode(struct net_device *dev) ...@@ -198,7 +198,7 @@ static void dsa_slave_set_rx_mode(struct net_device *dev)
static int dsa_slave_set_mac_address(struct net_device *dev, void *a) static int dsa_slave_set_mac_address(struct net_device *dev, void *a)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct net_device *master = p->parent->dst->master_netdev; struct net_device *master = p->dp->ds->dst->master_netdev;
struct sockaddr *addr = a; struct sockaddr *addr = a;
int err; int err;
...@@ -228,16 +228,17 @@ static int dsa_slave_port_vlan_add(struct net_device *dev, ...@@ -228,16 +228,17 @@ static int dsa_slave_port_vlan_add(struct net_device *dev,
struct switchdev_trans *trans) struct switchdev_trans *trans)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_port *dp = p->dp;
struct dsa_switch *ds = dp->ds;
if (switchdev_trans_ph_prepare(trans)) { if (switchdev_trans_ph_prepare(trans)) {
if (!ds->ops->port_vlan_prepare || !ds->ops->port_vlan_add) if (!ds->ops->port_vlan_prepare || !ds->ops->port_vlan_add)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return ds->ops->port_vlan_prepare(ds, p->port, vlan, trans); return ds->ops->port_vlan_prepare(ds, dp->index, vlan, trans);
} }
ds->ops->port_vlan_add(ds, p->port, vlan, trans); ds->ops->port_vlan_add(ds, dp->index, vlan, trans);
return 0; return 0;
} }
...@@ -246,12 +247,12 @@ static int dsa_slave_port_vlan_del(struct net_device *dev, ...@@ -246,12 +247,12 @@ static int dsa_slave_port_vlan_del(struct net_device *dev,
const struct switchdev_obj_port_vlan *vlan) const struct switchdev_obj_port_vlan *vlan)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
if (!ds->ops->port_vlan_del) if (!ds->ops->port_vlan_del)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return ds->ops->port_vlan_del(ds, p->port, vlan); return ds->ops->port_vlan_del(ds, p->dp->index, vlan);
} }
static int dsa_slave_port_vlan_dump(struct net_device *dev, static int dsa_slave_port_vlan_dump(struct net_device *dev,
...@@ -259,10 +260,10 @@ static int dsa_slave_port_vlan_dump(struct net_device *dev, ...@@ -259,10 +260,10 @@ static int dsa_slave_port_vlan_dump(struct net_device *dev,
switchdev_obj_dump_cb_t *cb) switchdev_obj_dump_cb_t *cb)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
if (ds->ops->port_vlan_dump) if (ds->ops->port_vlan_dump)
return ds->ops->port_vlan_dump(ds, p->port, vlan, cb); return ds->ops->port_vlan_dump(ds, p->dp->index, vlan, cb);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -272,16 +273,16 @@ static int dsa_slave_port_fdb_add(struct net_device *dev, ...@@ -272,16 +273,16 @@ static int dsa_slave_port_fdb_add(struct net_device *dev,
struct switchdev_trans *trans) struct switchdev_trans *trans)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
if (switchdev_trans_ph_prepare(trans)) { if (switchdev_trans_ph_prepare(trans)) {
if (!ds->ops->port_fdb_prepare || !ds->ops->port_fdb_add) if (!ds->ops->port_fdb_prepare || !ds->ops->port_fdb_add)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return ds->ops->port_fdb_prepare(ds, p->port, fdb, trans); return ds->ops->port_fdb_prepare(ds, p->dp->index, fdb, trans);
} }
ds->ops->port_fdb_add(ds, p->port, fdb, trans); ds->ops->port_fdb_add(ds, p->dp->index, fdb, trans);
return 0; return 0;
} }
...@@ -290,11 +291,11 @@ static int dsa_slave_port_fdb_del(struct net_device *dev, ...@@ -290,11 +291,11 @@ static int dsa_slave_port_fdb_del(struct net_device *dev,
const struct switchdev_obj_port_fdb *fdb) const struct switchdev_obj_port_fdb *fdb)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
int ret = -EOPNOTSUPP; int ret = -EOPNOTSUPP;
if (ds->ops->port_fdb_del) if (ds->ops->port_fdb_del)
ret = ds->ops->port_fdb_del(ds, p->port, fdb); ret = ds->ops->port_fdb_del(ds, p->dp->index, fdb);
return ret; return ret;
} }
...@@ -304,10 +305,10 @@ static int dsa_slave_port_fdb_dump(struct net_device *dev, ...@@ -304,10 +305,10 @@ static int dsa_slave_port_fdb_dump(struct net_device *dev,
switchdev_obj_dump_cb_t *cb) switchdev_obj_dump_cb_t *cb)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
if (ds->ops->port_fdb_dump) if (ds->ops->port_fdb_dump)
return ds->ops->port_fdb_dump(ds, p->port, fdb, cb); return ds->ops->port_fdb_dump(ds, p->dp->index, fdb, cb);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -317,16 +318,16 @@ static int dsa_slave_port_mdb_add(struct net_device *dev, ...@@ -317,16 +318,16 @@ static int dsa_slave_port_mdb_add(struct net_device *dev,
struct switchdev_trans *trans) struct switchdev_trans *trans)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
if (switchdev_trans_ph_prepare(trans)) { if (switchdev_trans_ph_prepare(trans)) {
if (!ds->ops->port_mdb_prepare || !ds->ops->port_mdb_add) if (!ds->ops->port_mdb_prepare || !ds->ops->port_mdb_add)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return ds->ops->port_mdb_prepare(ds, p->port, mdb, trans); return ds->ops->port_mdb_prepare(ds, p->dp->index, mdb, trans);
} }
ds->ops->port_mdb_add(ds, p->port, mdb, trans); ds->ops->port_mdb_add(ds, p->dp->index, mdb, trans);
return 0; return 0;
} }
...@@ -335,10 +336,10 @@ static int dsa_slave_port_mdb_del(struct net_device *dev, ...@@ -335,10 +336,10 @@ static int dsa_slave_port_mdb_del(struct net_device *dev,
const struct switchdev_obj_port_mdb *mdb) const struct switchdev_obj_port_mdb *mdb)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
if (ds->ops->port_mdb_del) if (ds->ops->port_mdb_del)
return ds->ops->port_mdb_del(ds, p->port, mdb); return ds->ops->port_mdb_del(ds, p->dp->index, mdb);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -348,10 +349,10 @@ static int dsa_slave_port_mdb_dump(struct net_device *dev, ...@@ -348,10 +349,10 @@ static int dsa_slave_port_mdb_dump(struct net_device *dev,
switchdev_obj_dump_cb_t *cb) switchdev_obj_dump_cb_t *cb)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
if (ds->ops->port_mdb_dump) if (ds->ops->port_mdb_dump)
return ds->ops->port_mdb_dump(ds, p->port, mdb, cb); return ds->ops->port_mdb_dump(ds, p->dp->index, mdb, cb);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -371,12 +372,12 @@ static int dsa_slave_stp_state_set(struct net_device *dev, ...@@ -371,12 +372,12 @@ static int dsa_slave_stp_state_set(struct net_device *dev,
struct switchdev_trans *trans) struct switchdev_trans *trans)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
if (switchdev_trans_ph_prepare(trans)) if (switchdev_trans_ph_prepare(trans))
return ds->ops->port_stp_state_set ? 0 : -EOPNOTSUPP; return ds->ops->port_stp_state_set ? 0 : -EOPNOTSUPP;
dsa_port_set_stp_state(ds, p->port, attr->u.stp_state); dsa_port_set_stp_state(ds, p->dp->index, attr->u.stp_state);
return 0; return 0;
} }
...@@ -386,14 +387,14 @@ static int dsa_slave_vlan_filtering(struct net_device *dev, ...@@ -386,14 +387,14 @@ static int dsa_slave_vlan_filtering(struct net_device *dev,
struct switchdev_trans *trans) struct switchdev_trans *trans)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
/* bridge skips -EOPNOTSUPP, so skip the prepare phase */ /* bridge skips -EOPNOTSUPP, so skip the prepare phase */
if (switchdev_trans_ph_prepare(trans)) if (switchdev_trans_ph_prepare(trans))
return 0; return 0;
if (ds->ops->port_vlan_filtering) if (ds->ops->port_vlan_filtering)
return ds->ops->port_vlan_filtering(ds, p->port, return ds->ops->port_vlan_filtering(ds, p->dp->index,
attr->u.vlan_filtering); attr->u.vlan_filtering);
return 0; return 0;
...@@ -404,7 +405,7 @@ static int dsa_fastest_ageing_time(struct dsa_switch *ds, ...@@ -404,7 +405,7 @@ static int dsa_fastest_ageing_time(struct dsa_switch *ds,
{ {
int i; int i;
for (i = 0; i < DSA_MAX_PORTS; ++i) { for (i = 0; i < ds->num_ports; ++i) {
struct dsa_port *dp = &ds->ports[i]; struct dsa_port *dp = &ds->ports[i];
if (dp && dp->ageing_time && dp->ageing_time < ageing_time) if (dp && dp->ageing_time && dp->ageing_time < ageing_time)
...@@ -419,7 +420,7 @@ static int dsa_slave_ageing_time(struct net_device *dev, ...@@ -419,7 +420,7 @@ static int dsa_slave_ageing_time(struct net_device *dev,
struct switchdev_trans *trans) struct switchdev_trans *trans)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
unsigned long ageing_jiffies = clock_t_to_jiffies(attr->u.ageing_time); unsigned long ageing_jiffies = clock_t_to_jiffies(attr->u.ageing_time);
unsigned int ageing_time = jiffies_to_msecs(ageing_jiffies); unsigned int ageing_time = jiffies_to_msecs(ageing_jiffies);
...@@ -428,7 +429,7 @@ static int dsa_slave_ageing_time(struct net_device *dev, ...@@ -428,7 +429,7 @@ static int dsa_slave_ageing_time(struct net_device *dev,
return 0; return 0;
/* Keep the fastest ageing time in case of multiple bridges */ /* Keep the fastest ageing time in case of multiple bridges */
ds->ports[p->port].ageing_time = ageing_time; p->dp->ageing_time = ageing_time;
ageing_time = dsa_fastest_ageing_time(ds, ageing_time); ageing_time = dsa_fastest_ageing_time(ds, ageing_time);
if (ds->ops->set_ageing_time) if (ds->ops->set_ageing_time)
...@@ -553,39 +554,39 @@ static int dsa_slave_bridge_port_join(struct net_device *dev, ...@@ -553,39 +554,39 @@ static int dsa_slave_bridge_port_join(struct net_device *dev,
struct net_device *br) struct net_device *br)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
int ret = -EOPNOTSUPP; int ret = -EOPNOTSUPP;
p->bridge_dev = br; p->dp->bridge_dev = br;
if (ds->ops->port_bridge_join) if (ds->ops->port_bridge_join)
ret = ds->ops->port_bridge_join(ds, p->port, br); ret = ds->ops->port_bridge_join(ds, p->dp->index, br);
return ret == -EOPNOTSUPP ? 0 : ret; return ret == -EOPNOTSUPP ? 0 : ret;
} }
static void dsa_slave_bridge_port_leave(struct net_device *dev) static void dsa_slave_bridge_port_leave(struct net_device *dev,
struct net_device *br)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
p->dp->bridge_dev = NULL;
if (ds->ops->port_bridge_leave) if (ds->ops->port_bridge_leave)
ds->ops->port_bridge_leave(ds, p->port); ds->ops->port_bridge_leave(ds, p->dp->index, br);
p->bridge_dev = NULL;
/* Port left the bridge, put in BR_STATE_DISABLED by the bridge layer, /* Port left the bridge, put in BR_STATE_DISABLED by the bridge layer,
* so allow it to be in BR_STATE_FORWARDING to be kept functional * so allow it to be in BR_STATE_FORWARDING to be kept functional
*/ */
dsa_port_set_stp_state(ds, p->port, BR_STATE_FORWARDING); dsa_port_set_stp_state(ds, p->dp->index, BR_STATE_FORWARDING);
} }
static int dsa_slave_port_attr_get(struct net_device *dev, static int dsa_slave_port_attr_get(struct net_device *dev,
struct switchdev_attr *attr) struct switchdev_attr *attr)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
switch (attr->id) { switch (attr->id) {
case SWITCHDEV_ATTR_ID_PORT_PARENT_ID: case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
...@@ -633,7 +634,7 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -633,7 +634,7 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
/* Queue the SKB for transmission on the parent interface, but /* Queue the SKB for transmission on the parent interface, but
* do not modify its EtherType * do not modify its EtherType
*/ */
nskb->dev = p->parent->dst->master_netdev; nskb->dev = p->dp->ds->dst->master_netdev;
dev_queue_xmit(nskb); dev_queue_xmit(nskb);
return NETDEV_TX_OK; return NETDEV_TX_OK;
...@@ -680,10 +681,10 @@ static void dsa_slave_get_drvinfo(struct net_device *dev, ...@@ -680,10 +681,10 @@ static void dsa_slave_get_drvinfo(struct net_device *dev,
static int dsa_slave_get_regs_len(struct net_device *dev) static int dsa_slave_get_regs_len(struct net_device *dev)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
if (ds->ops->get_regs_len) if (ds->ops->get_regs_len)
return ds->ops->get_regs_len(ds, p->port); return ds->ops->get_regs_len(ds, p->dp->index);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -692,10 +693,10 @@ static void ...@@ -692,10 +693,10 @@ static void
dsa_slave_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p) dsa_slave_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
if (ds->ops->get_regs) if (ds->ops->get_regs)
ds->ops->get_regs(ds, p->port, regs, _p); ds->ops->get_regs(ds, p->dp->index, regs, _p);
} }
static int dsa_slave_nway_reset(struct net_device *dev) static int dsa_slave_nway_reset(struct net_device *dev)
...@@ -723,7 +724,7 @@ static u32 dsa_slave_get_link(struct net_device *dev) ...@@ -723,7 +724,7 @@ static u32 dsa_slave_get_link(struct net_device *dev)
static int dsa_slave_get_eeprom_len(struct net_device *dev) static int dsa_slave_get_eeprom_len(struct net_device *dev)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
if (ds->cd && ds->cd->eeprom_len) if (ds->cd && ds->cd->eeprom_len)
return ds->cd->eeprom_len; return ds->cd->eeprom_len;
...@@ -738,7 +739,7 @@ static int dsa_slave_get_eeprom(struct net_device *dev, ...@@ -738,7 +739,7 @@ static int dsa_slave_get_eeprom(struct net_device *dev,
struct ethtool_eeprom *eeprom, u8 *data) struct ethtool_eeprom *eeprom, u8 *data)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
if (ds->ops->get_eeprom) if (ds->ops->get_eeprom)
return ds->ops->get_eeprom(ds, eeprom, data); return ds->ops->get_eeprom(ds, eeprom, data);
...@@ -750,7 +751,7 @@ static int dsa_slave_set_eeprom(struct net_device *dev, ...@@ -750,7 +751,7 @@ static int dsa_slave_set_eeprom(struct net_device *dev,
struct ethtool_eeprom *eeprom, u8 *data) struct ethtool_eeprom *eeprom, u8 *data)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
if (ds->ops->set_eeprom) if (ds->ops->set_eeprom)
return ds->ops->set_eeprom(ds, eeprom, data); return ds->ops->set_eeprom(ds, eeprom, data);
...@@ -762,7 +763,7 @@ static void dsa_slave_get_strings(struct net_device *dev, ...@@ -762,7 +763,7 @@ static void dsa_slave_get_strings(struct net_device *dev,
uint32_t stringset, uint8_t *data) uint32_t stringset, uint8_t *data)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
if (stringset == ETH_SS_STATS) { if (stringset == ETH_SS_STATS) {
int len = ETH_GSTRING_LEN; int len = ETH_GSTRING_LEN;
...@@ -772,7 +773,7 @@ static void dsa_slave_get_strings(struct net_device *dev, ...@@ -772,7 +773,7 @@ static void dsa_slave_get_strings(struct net_device *dev,
strncpy(data + 2 * len, "rx_packets", len); strncpy(data + 2 * len, "rx_packets", len);
strncpy(data + 3 * len, "rx_bytes", len); strncpy(data + 3 * len, "rx_bytes", len);
if (ds->ops->get_strings) if (ds->ops->get_strings)
ds->ops->get_strings(ds, p->port, data + 4 * len); ds->ops->get_strings(ds, p->dp->index, data + 4 * len);
} }
} }
...@@ -853,20 +854,20 @@ static void dsa_slave_get_ethtool_stats(struct net_device *dev, ...@@ -853,20 +854,20 @@ static void dsa_slave_get_ethtool_stats(struct net_device *dev,
uint64_t *data) uint64_t *data)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
data[0] = dev->stats.tx_packets; data[0] = dev->stats.tx_packets;
data[1] = dev->stats.tx_bytes; data[1] = dev->stats.tx_bytes;
data[2] = dev->stats.rx_packets; data[2] = dev->stats.rx_packets;
data[3] = dev->stats.rx_bytes; data[3] = dev->stats.rx_bytes;
if (ds->ops->get_ethtool_stats) if (ds->ops->get_ethtool_stats)
ds->ops->get_ethtool_stats(ds, p->port, data + 4); ds->ops->get_ethtool_stats(ds, p->dp->index, data + 4);
} }
static int dsa_slave_get_sset_count(struct net_device *dev, int sset) static int dsa_slave_get_sset_count(struct net_device *dev, int sset)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
if (sset == ETH_SS_STATS) { if (sset == ETH_SS_STATS) {
int count; int count;
...@@ -884,20 +885,20 @@ static int dsa_slave_get_sset_count(struct net_device *dev, int sset) ...@@ -884,20 +885,20 @@ static int dsa_slave_get_sset_count(struct net_device *dev, int sset)
static void dsa_slave_get_wol(struct net_device *dev, struct ethtool_wolinfo *w) static void dsa_slave_get_wol(struct net_device *dev, struct ethtool_wolinfo *w)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
if (ds->ops->get_wol) if (ds->ops->get_wol)
ds->ops->get_wol(ds, p->port, w); ds->ops->get_wol(ds, p->dp->index, w);
} }
static int dsa_slave_set_wol(struct net_device *dev, struct ethtool_wolinfo *w) static int dsa_slave_set_wol(struct net_device *dev, struct ethtool_wolinfo *w)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
int ret = -EOPNOTSUPP; int ret = -EOPNOTSUPP;
if (ds->ops->set_wol) if (ds->ops->set_wol)
ret = ds->ops->set_wol(ds, p->port, w); ret = ds->ops->set_wol(ds, p->dp->index, w);
return ret; return ret;
} }
...@@ -905,13 +906,13 @@ static int dsa_slave_set_wol(struct net_device *dev, struct ethtool_wolinfo *w) ...@@ -905,13 +906,13 @@ static int dsa_slave_set_wol(struct net_device *dev, struct ethtool_wolinfo *w)
static int dsa_slave_set_eee(struct net_device *dev, struct ethtool_eee *e) static int dsa_slave_set_eee(struct net_device *dev, struct ethtool_eee *e)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
int ret; int ret;
if (!ds->ops->set_eee) if (!ds->ops->set_eee)
return -EOPNOTSUPP; return -EOPNOTSUPP;
ret = ds->ops->set_eee(ds, p->port, p->phy, e); ret = ds->ops->set_eee(ds, p->dp->index, p->phy, e);
if (ret) if (ret)
return ret; return ret;
...@@ -924,13 +925,13 @@ static int dsa_slave_set_eee(struct net_device *dev, struct ethtool_eee *e) ...@@ -924,13 +925,13 @@ static int dsa_slave_set_eee(struct net_device *dev, struct ethtool_eee *e)
static int dsa_slave_get_eee(struct net_device *dev, struct ethtool_eee *e) static int dsa_slave_get_eee(struct net_device *dev, struct ethtool_eee *e)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
int ret; int ret;
if (!ds->ops->get_eee) if (!ds->ops->get_eee)
return -EOPNOTSUPP; return -EOPNOTSUPP;
ret = ds->ops->get_eee(ds, p->port, e); ret = ds->ops->get_eee(ds, p->dp->index, e);
if (ret) if (ret)
return ret; return ret;
...@@ -945,7 +946,7 @@ static int dsa_slave_netpoll_setup(struct net_device *dev, ...@@ -945,7 +946,7 @@ static int dsa_slave_netpoll_setup(struct net_device *dev,
struct netpoll_info *ni) struct netpoll_info *ni)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
struct net_device *master = ds->dst->master_netdev; struct net_device *master = ds->dst->master_netdev;
struct netpoll *netpoll; struct netpoll *netpoll;
int err = 0; int err = 0;
...@@ -988,7 +989,7 @@ static int dsa_slave_get_phys_port_name(struct net_device *dev, ...@@ -988,7 +989,7 @@ static int dsa_slave_get_phys_port_name(struct net_device *dev,
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
if (snprintf(name, len, "p%d", p->port) >= len) if (snprintf(name, len, "p%d", p->dp->index) >= len)
return -EINVAL; return -EINVAL;
return 0; return 0;
...@@ -1059,7 +1060,7 @@ static struct device_type dsa_type = { ...@@ -1059,7 +1060,7 @@ static struct device_type dsa_type = {
static void dsa_slave_adjust_link(struct net_device *dev) static void dsa_slave_adjust_link(struct net_device *dev)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
unsigned int status_changed = 0; unsigned int status_changed = 0;
if (p->old_link != p->phy->link) { if (p->old_link != p->phy->link) {
...@@ -1078,7 +1079,7 @@ static void dsa_slave_adjust_link(struct net_device *dev) ...@@ -1078,7 +1079,7 @@ static void dsa_slave_adjust_link(struct net_device *dev)
} }
if (ds->ops->adjust_link && status_changed) if (ds->ops->adjust_link && status_changed)
ds->ops->adjust_link(ds, p->port, p->phy); ds->ops->adjust_link(ds, p->dp->index, p->phy);
if (status_changed) if (status_changed)
phy_print_status(p->phy); phy_print_status(p->phy);
...@@ -1092,9 +1093,9 @@ static int dsa_slave_fixed_link_update(struct net_device *dev, ...@@ -1092,9 +1093,9 @@ static int dsa_slave_fixed_link_update(struct net_device *dev,
if (dev) { if (dev) {
p = netdev_priv(dev); p = netdev_priv(dev);
ds = p->parent; ds = p->dp->ds;
if (ds->ops->fixed_link_update) if (ds->ops->fixed_link_update)
ds->ops->fixed_link_update(ds, p->port, status); ds->ops->fixed_link_update(ds, p->dp->index, status);
} }
return 0; return 0;
...@@ -1105,7 +1106,7 @@ static int dsa_slave_phy_connect(struct dsa_slave_priv *p, ...@@ -1105,7 +1106,7 @@ static int dsa_slave_phy_connect(struct dsa_slave_priv *p,
struct net_device *slave_dev, struct net_device *slave_dev,
int addr) int addr)
{ {
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
p->phy = mdiobus_get_phy(ds->slave_mii_bus, addr); p->phy = mdiobus_get_phy(ds->slave_mii_bus, addr);
if (!p->phy) { if (!p->phy) {
...@@ -1123,13 +1124,13 @@ static int dsa_slave_phy_connect(struct dsa_slave_priv *p, ...@@ -1123,13 +1124,13 @@ static int dsa_slave_phy_connect(struct dsa_slave_priv *p,
static int dsa_slave_phy_setup(struct dsa_slave_priv *p, static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
struct net_device *slave_dev) struct net_device *slave_dev)
{ {
struct dsa_switch *ds = p->parent; struct dsa_switch *ds = p->dp->ds;
struct device_node *phy_dn, *port_dn; struct device_node *phy_dn, *port_dn;
bool phy_is_fixed = false; bool phy_is_fixed = false;
u32 phy_flags = 0; u32 phy_flags = 0;
int mode, ret; int mode, ret;
port_dn = ds->ports[p->port].dn; port_dn = p->dp->dn;
mode = of_get_phy_mode(port_dn); mode = of_get_phy_mode(port_dn);
if (mode < 0) if (mode < 0)
mode = PHY_INTERFACE_MODE_NA; mode = PHY_INTERFACE_MODE_NA;
...@@ -1150,7 +1151,7 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p, ...@@ -1150,7 +1151,7 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
} }
if (ds->ops->get_phy_flags) if (ds->ops->get_phy_flags)
phy_flags = ds->ops->get_phy_flags(ds, p->port); phy_flags = ds->ops->get_phy_flags(ds, p->dp->index);
if (phy_dn) { if (phy_dn) {
int phy_id = of_mdio_parse_addr(&slave_dev->dev, phy_dn); int phy_id = of_mdio_parse_addr(&slave_dev->dev, phy_dn);
...@@ -1185,9 +1186,10 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p, ...@@ -1185,9 +1186,10 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
* MDIO bus instead * MDIO bus instead
*/ */
if (!p->phy) { if (!p->phy) {
ret = dsa_slave_phy_connect(p, slave_dev, p->port); ret = dsa_slave_phy_connect(p, slave_dev, p->dp->index);
if (ret) { if (ret) {
netdev_err(slave_dev, "failed to connect to port %d: %d\n", p->port, ret); netdev_err(slave_dev, "failed to connect to port %d: %d\n",
p->dp->index, ret);
if (phy_is_fixed) if (phy_is_fixed)
of_phy_deregister_fixed_link(port_dn); of_phy_deregister_fixed_link(port_dn);
return ret; return ret;
...@@ -1275,8 +1277,7 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent, ...@@ -1275,8 +1277,7 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent,
slave_dev->vlan_features = master->vlan_features; slave_dev->vlan_features = master->vlan_features;
p = netdev_priv(slave_dev); p = netdev_priv(slave_dev);
p->parent = ds; p->dp = &ds->ports[port];
p->port = port;
p->xmit = dst->tag_ops->xmit; p->xmit = dst->tag_ops->xmit;
p->old_pause = -1; p->old_pause = -1;
...@@ -1309,10 +1310,9 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent, ...@@ -1309,10 +1310,9 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent,
void dsa_slave_destroy(struct net_device *slave_dev) void dsa_slave_destroy(struct net_device *slave_dev)
{ {
struct dsa_slave_priv *p = netdev_priv(slave_dev); struct dsa_slave_priv *p = netdev_priv(slave_dev);
struct dsa_switch *ds = p->parent;
struct device_node *port_dn; struct device_node *port_dn;
port_dn = ds->ports[p->port].dn; port_dn = p->dp->dn;
netif_carrier_off(slave_dev); netif_carrier_off(slave_dev);
if (p->phy) { if (p->phy) {
...@@ -1343,7 +1343,7 @@ static int dsa_slave_port_upper_event(struct net_device *dev, ...@@ -1343,7 +1343,7 @@ static int dsa_slave_port_upper_event(struct net_device *dev,
if (info->linking) if (info->linking)
err = dsa_slave_bridge_port_join(dev, upper); err = dsa_slave_bridge_port_join(dev, upper);
else else
dsa_slave_bridge_port_leave(dev); dsa_slave_bridge_port_leave(dev, upper);
} }
break; break;
......
...@@ -80,9 +80,9 @@ static struct sk_buff *brcm_tag_xmit(struct sk_buff *skb, struct net_device *dev ...@@ -80,9 +80,9 @@ static struct sk_buff *brcm_tag_xmit(struct sk_buff *skb, struct net_device *dev
((skb->priority << BRCM_IG_TC_SHIFT) & BRCM_IG_TC_MASK); ((skb->priority << BRCM_IG_TC_SHIFT) & BRCM_IG_TC_MASK);
brcm_tag[1] = 0; brcm_tag[1] = 0;
brcm_tag[2] = 0; brcm_tag[2] = 0;
if (p->port == 8) if (p->dp->index == 8)
brcm_tag[2] = BRCM_IG_DSTMAP2_MASK; brcm_tag[2] = BRCM_IG_DSTMAP2_MASK;
brcm_tag[3] = (1 << p->port) & BRCM_IG_DSTMAP1_MASK; brcm_tag[3] = (1 << p->dp->index) & BRCM_IG_DSTMAP1_MASK;
return skb; return skb;
...@@ -128,7 +128,7 @@ static int brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev, ...@@ -128,7 +128,7 @@ static int brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev,
source_port = brcm_tag[3] & BRCM_EG_PID_MASK; source_port = brcm_tag[3] & BRCM_EG_PID_MASK;
/* Validate port against switch setup, either the port is totally */ /* Validate port against switch setup, either the port is totally */
if (source_port >= DSA_MAX_PORTS || !ds->ports[source_port].netdev) if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
goto out_drop; goto out_drop;
/* Remove Broadcom tag and update checksum */ /* Remove Broadcom tag and update checksum */
......
...@@ -33,8 +33,8 @@ static struct sk_buff *dsa_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -33,8 +33,8 @@ static struct sk_buff *dsa_xmit(struct sk_buff *skb, struct net_device *dev)
* Construct tagged FROM_CPU DSA tag from 802.1q tag. * Construct tagged FROM_CPU DSA tag from 802.1q tag.
*/ */
dsa_header = skb->data + 2 * ETH_ALEN; dsa_header = skb->data + 2 * ETH_ALEN;
dsa_header[0] = 0x60 | p->parent->index; dsa_header[0] = 0x60 | p->dp->ds->index;
dsa_header[1] = p->port << 3; dsa_header[1] = p->dp->index << 3;
/* /*
* Move CFI field from byte 2 to byte 1. * Move CFI field from byte 2 to byte 1.
...@@ -54,8 +54,8 @@ static struct sk_buff *dsa_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -54,8 +54,8 @@ static struct sk_buff *dsa_xmit(struct sk_buff *skb, struct net_device *dev)
* Construct untagged FROM_CPU DSA tag. * Construct untagged FROM_CPU DSA tag.
*/ */
dsa_header = skb->data + 2 * ETH_ALEN; dsa_header = skb->data + 2 * ETH_ALEN;
dsa_header[0] = 0x40 | p->parent->index; dsa_header[0] = 0x40 | p->dp->ds->index;
dsa_header[1] = p->port << 3; dsa_header[1] = p->dp->index << 3;
dsa_header[2] = 0x00; dsa_header[2] = 0x00;
dsa_header[3] = 0x00; dsa_header[3] = 0x00;
} }
...@@ -114,7 +114,7 @@ static int dsa_rcv(struct sk_buff *skb, struct net_device *dev, ...@@ -114,7 +114,7 @@ static int dsa_rcv(struct sk_buff *skb, struct net_device *dev,
if (!ds) if (!ds)
goto out_drop; goto out_drop;
if (source_port >= DSA_MAX_PORTS || !ds->ports[source_port].netdev) if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
goto out_drop; goto out_drop;
/* /*
......
...@@ -42,8 +42,8 @@ static struct sk_buff *edsa_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -42,8 +42,8 @@ static struct sk_buff *edsa_xmit(struct sk_buff *skb, struct net_device *dev)
edsa_header[1] = ETH_P_EDSA & 0xff; edsa_header[1] = ETH_P_EDSA & 0xff;
edsa_header[2] = 0x00; edsa_header[2] = 0x00;
edsa_header[3] = 0x00; edsa_header[3] = 0x00;
edsa_header[4] = 0x60 | p->parent->index; edsa_header[4] = 0x60 | p->dp->ds->index;
edsa_header[5] = p->port << 3; edsa_header[5] = p->dp->index << 3;
/* /*
* Move CFI field from byte 6 to byte 5. * Move CFI field from byte 6 to byte 5.
...@@ -67,8 +67,8 @@ static struct sk_buff *edsa_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -67,8 +67,8 @@ static struct sk_buff *edsa_xmit(struct sk_buff *skb, struct net_device *dev)
edsa_header[1] = ETH_P_EDSA & 0xff; edsa_header[1] = ETH_P_EDSA & 0xff;
edsa_header[2] = 0x00; edsa_header[2] = 0x00;
edsa_header[3] = 0x00; edsa_header[3] = 0x00;
edsa_header[4] = 0x40 | p->parent->index; edsa_header[4] = 0x40 | p->dp->ds->index;
edsa_header[5] = p->port << 3; edsa_header[5] = p->dp->index << 3;
edsa_header[6] = 0x00; edsa_header[6] = 0x00;
edsa_header[7] = 0x00; edsa_header[7] = 0x00;
} }
...@@ -127,7 +127,7 @@ static int edsa_rcv(struct sk_buff *skb, struct net_device *dev, ...@@ -127,7 +127,7 @@ static int edsa_rcv(struct sk_buff *skb, struct net_device *dev,
if (!ds) if (!ds)
goto out_drop; goto out_drop;
if (source_port >= DSA_MAX_PORTS || !ds->ports[source_port].netdev) if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
goto out_drop; goto out_drop;
/* /*
......
...@@ -54,7 +54,7 @@ static struct sk_buff *qca_tag_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -54,7 +54,7 @@ static struct sk_buff *qca_tag_xmit(struct sk_buff *skb, struct net_device *dev)
/* Set the version field, and set destination port information */ /* Set the version field, and set destination port information */
hdr = QCA_HDR_VERSION << QCA_HDR_XMIT_VERSION_S | hdr = QCA_HDR_VERSION << QCA_HDR_XMIT_VERSION_S |
QCA_HDR_XMIT_FROM_CPU | QCA_HDR_XMIT_FROM_CPU |
BIT(p->port); BIT(p->dp->index);
*phdr = htons(hdr); *phdr = htons(hdr);
......
...@@ -50,7 +50,7 @@ static struct sk_buff *trailer_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -50,7 +50,7 @@ static struct sk_buff *trailer_xmit(struct sk_buff *skb, struct net_device *dev)
trailer = skb_put(nskb, 4); trailer = skb_put(nskb, 4);
trailer[0] = 0x80; trailer[0] = 0x80;
trailer[1] = 1 << p->port; trailer[1] = 1 << p->dp->index;
trailer[2] = 0x10; trailer[2] = 0x10;
trailer[3] = 0x00; trailer[3] = 0x00;
...@@ -82,7 +82,7 @@ static int trailer_rcv(struct sk_buff *skb, struct net_device *dev, ...@@ -82,7 +82,7 @@ static int trailer_rcv(struct sk_buff *skb, struct net_device *dev,
goto out_drop; goto out_drop;
source_port = trailer[1] & 7; source_port = trailer[1] & 7;
if (source_port >= DSA_MAX_PORTS || !ds->ports[source_port].netdev) if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
goto out_drop; goto out_drop;
pskb_trim_rcsum(skb, skb->len - 4); pskb_trim_rcsum(skb, skb->len - 4);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment