提交 6d45408d 编写于 作者: D 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: NDavid S. Miller <davem@davemloft.net>
......@@ -1308,7 +1308,7 @@ int b53_fdb_dump(struct dsa_switch *ds, int port,
}
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;
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)
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_for_each_port(dev, i) {
if (dev->ports[i].bridge_dev != bridge)
if (ds->ports[i].bridge_dev != br)
continue;
/* 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)
}
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 net_device *bridge = dev->ports[port].bridge_dev;
struct b53_vlan *vl = &dev->vlans[0];
s8 cpu_port = ds->dst->cpu_port;
unsigned int i;
......@@ -1367,7 +1365,7 @@ void b53_br_leave(struct dsa_switch *ds, int port)
b53_for_each_port(dev, i) {
/* Don't touch the remaining ports */
if (dev->ports[i].bridge_dev != bridge)
if (ds->ports[i].bridge_dev != br)
continue;
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)
b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan);
dev->ports[port].vlan_ctl_mask = pvlan;
dev->ports[port].bridge_dev = NULL;
if (is5325(dev) || is5365(dev))
pvid = 1;
......@@ -1790,14 +1787,15 @@ struct b53_device *b53_switch_alloc(struct device *base,
struct dsa_switch *ds;
struct b53_device *dev;
ds = devm_kzalloc(base, sizeof(*ds) + sizeof(*dev), GFP_KERNEL);
ds = dsa_switch_alloc(base, DSA_MAX_PORTS);
if (!ds)
return NULL;
dev = (struct b53_device *)(ds + 1);
dev = devm_kzalloc(base, sizeof(*dev), GFP_KERNEL);
if (!dev)
return NULL;
ds->priv = dev;
ds->dev = base;
dev->dev = base;
dev->ds = ds;
......
......@@ -70,7 +70,6 @@ enum {
struct b53_port {
u16 vlan_ctl_mask;
struct net_device *bridge_dev;
};
struct b53_vlan {
......@@ -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);
int b53_get_sset_count(struct dsa_switch *ds);
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_fast_age(struct dsa_switch *ds, int port);
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,
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 net_device *bridge = ds->ports[port].bridge_dev;
u16 output_ports = 0;
int i;
......@@ -1258,7 +1258,7 @@ static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_chip *chip, int port)
} else {
for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
/* 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);
/* 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,
GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
continue;
if (chip->ports[i].bridge_dev ==
chip->ports[port].bridge_dev)
if (ds->ports[i].bridge_dev ==
ds->ports[port].bridge_dev)
break; /* same bridge, check next VLAN */
if (!chip->ports[i].bridge_dev)
if (!ds->ports[i].bridge_dev)
continue;
netdev_warn(ds->ports[port].netdev,
"hardware VLAN %d already used by %s\n",
vlan.vid,
netdev_name(chip->ports[i].bridge_dev));
netdev_name(ds->ports[i].bridge_dev));
err = -EOPNOTSUPP;
goto unlock;
}
......@@ -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,
struct net_device *bridge)
struct net_device *br)
{
struct mv88e6xxx_chip *chip = ds->priv;
int i, err = 0;
mutex_lock(&chip->reg_lock);
/* Assign the bridge and remap each port's VLANTable */
chip->ports[port].bridge_dev = bridge;
/* Remap each port's VLANTable */
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);
if (err)
break;
......@@ -2343,19 +2341,17 @@ static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
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 net_device *bridge = chip->ports[port].bridge_dev;
int i;
mutex_lock(&chip->reg_lock);
/* Unassign the bridge and remap each port's VLANTable */
chip->ports[port].bridge_dev = NULL;
/* Remap each port's VLANTable */
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))
netdev_warn(ds->ports[i].netdev,
"failed to remap\n");
......@@ -4361,11 +4357,10 @@ static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip)
struct device *dev = chip->dev;
struct dsa_switch *ds;
ds = devm_kzalloc(dev, sizeof(*ds), GFP_KERNEL);
ds = dsa_switch_alloc(dev, DSA_MAX_PORTS);
if (!ds)
return -ENOMEM;
ds->dev = dev;
ds->priv = chip;
ds->ops = &mv88e6xxx_switch_ops;
......
......@@ -676,10 +676,6 @@ struct mv88e6xxx_vtu_entry {
struct mv88e6xxx_bus_ops;
struct mv88e6xxx_priv_port {
struct net_device *bridge_dev;
};
struct mv88e6xxx_irq {
u16 masked;
struct irq_chip chip;
......@@ -720,8 +716,6 @@ struct mv88e6xxx_chip {
*/
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
* this from the device tree, and use it before performing
* switch soft reset.
......
......@@ -746,17 +746,14 @@ qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
}
static int
qca8k_port_bridge_join(struct dsa_switch *ds, int port,
struct net_device *bridge)
qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br)
{
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
int port_mask = BIT(QCA8K_CPU_PORT);
int i;
priv->port_sts[port].bridge_dev = bridge;
for (i = 1; i < QCA8K_NUM_PORTS; i++) {
if (priv->port_sts[i].bridge_dev != bridge)
if (ds->ports[i].bridge_dev != br)
continue;
/* Add this port to the portvlan mask of the other ports
* in the bridge
......@@ -775,14 +772,13 @@ qca8k_port_bridge_join(struct dsa_switch *ds, int port,
}
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;
int i;
for (i = 1; i < QCA8K_NUM_PORTS; i++) {
if (priv->port_sts[i].bridge_dev !=
priv->port_sts[port].bridge_dev)
if (ds->ports[i].bridge_dev != br)
continue;
/* Remove this port to the portvlan mask of the other ports
* in the bridge
......@@ -791,7 +787,7 @@ qca8k_port_bridge_leave(struct dsa_switch *ds, int port)
QCA8K_PORT_LOOKUP_CTRL(i),
BIT(port));
}
priv->port_sts[port].bridge_dev = NULL;
/* Set the cpu port to be the only one in the portvlan mask of
* this port
*/
......@@ -954,12 +950,11 @@ qca8k_sw_probe(struct mdio_device *mdiodev)
if (id != QCA8K_ID_QCA8337)
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)
return -ENOMEM;
priv->ds->priv = priv;
priv->ds->dev = &mdiodev->dev;
priv->ds->ops = &qca8k_switch_ops;
mutex_init(&priv->reg_mutex);
dev_set_drvdata(&mdiodev->dev, priv);
......
......@@ -157,7 +157,6 @@ enum qca8k_fdb_cmd {
struct ar8xxx_port_status {
struct ethtool_eee eee;
struct net_device *bridge_dev;
int enabled;
};
......
......@@ -140,10 +140,13 @@ struct dsa_switch_tree {
};
struct dsa_port {
struct dsa_switch *ds;
unsigned int index;
struct net_device *netdev;
struct device_node *dn;
unsigned int ageing_time;
u8 stp_state;
struct net_device *bridge_dev;
};
struct dsa_switch {
......@@ -190,8 +193,11 @@ struct dsa_switch {
u32 cpu_port_mask;
u32 enabled_port_mask;
u32 phys_mii_mask;
struct dsa_port ports[DSA_MAX_PORTS];
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)
......@@ -319,7 +325,8 @@ struct dsa_switch_ops {
int (*set_ageing_time)(struct dsa_switch *ds, unsigned int msecs);
int (*port_bridge_join)(struct dsa_switch *ds, int port,
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,
u8 state);
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)
return dst->rcv != NULL;
}
struct dsa_switch *dsa_switch_alloc(struct device *dev, size_t n);
void dsa_unregister_switch(struct dsa_switch *ds);
int dsa_register_switch(struct dsa_switch *ds, struct device *dev);
#ifdef CONFIG_PM_SLEEP
......
......@@ -145,7 +145,7 @@ static int dsa_cpu_dsa_setups(struct dsa_switch *ds, struct device *dev)
struct dsa_port *dport;
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)))
continue;
......@@ -218,7 +218,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
/*
* Validate supplied switch configuration.
*/
for (i = 0; i < DSA_MAX_PORTS; i++) {
for (i = 0; i < ds->num_ports; i++) {
char *name;
name = cd->port_names[i];
......@@ -242,7 +242,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
valid_name_found = true;
}
if (!valid_name_found && i == DSA_MAX_PORTS)
if (!valid_name_found && i == ds->num_ports)
return -EINVAL;
/* 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)
/*
* 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];
if (!(ds->enabled_port_mask & (1 << i)))
......@@ -347,8 +347,8 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
/*
* Allocate and initialise switch state.
*/
ds = devm_kzalloc(parent, sizeof(*ds), GFP_KERNEL);
if (ds == NULL)
ds = dsa_switch_alloc(parent, DSA_MAX_PORTS);
if (!ds)
return ERR_PTR(-ENOMEM);
ds->dst = dst;
......@@ -356,7 +356,6 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
ds->cd = cd;
ds->ops = ops;
ds->priv = priv;
ds->dev = parent;
ret = dsa_switch_setup_one(ds, parent);
if (ret)
......@@ -378,7 +377,7 @@ static void dsa_switch_destroy(struct dsa_switch *ds)
int port;
/* 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)))
continue;
......@@ -389,7 +388,7 @@ static void dsa_switch_destroy(struct dsa_switch *ds)
}
/* 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)))
continue;
dsa_cpu_dsa_destroy(&ds->ports[port]);
......@@ -409,7 +408,7 @@ int dsa_switch_suspend(struct dsa_switch *ds)
int i, ret = 0;
/* 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))
continue;
......@@ -436,7 +435,7 @@ int dsa_switch_resume(struct dsa_switch *ds)
return ret;
/* 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))
continue;
......
......@@ -98,7 +98,7 @@ static bool dsa_ds_find_port_dn(struct dsa_switch *ds,
{
u32 index;
for (index = 0; index < DSA_MAX_PORTS; index++)
for (index = 0; index < ds->num_ports; index++)
if (ds->ports[index].dn == port)
return true;
return false;
......@@ -159,7 +159,7 @@ static int dsa_ds_complete(struct dsa_switch_tree *dst, struct dsa_switch *ds)
u32 index;
int err;
for (index = 0; index < DSA_MAX_PORTS; index++) {
for (index = 0; index < ds->num_ports; index++) {
port = &ds->ports[index];
if (!dsa_port_is_valid(port))
continue;
......@@ -312,7 +312,7 @@ static int dsa_ds_apply(struct dsa_switch_tree *dst, struct dsa_switch *ds)
return err;
}
for (index = 0; index < DSA_MAX_PORTS; index++) {
for (index = 0; index < ds->num_ports; index++) {
port = &ds->ports[index];
if (!dsa_port_is_valid(port))
continue;
......@@ -344,7 +344,7 @@ static void dsa_ds_unapply(struct dsa_switch_tree *dst, struct dsa_switch *ds)
struct dsa_port *port;
u32 index;
for (index = 0; index < DSA_MAX_PORTS; index++) {
for (index = 0; index < ds->num_ports; index++) {
port = &ds->ports[index];
if (!dsa_port_is_valid(port))
continue;
......@@ -475,7 +475,7 @@ static int dsa_ds_parse(struct dsa_switch_tree *dst, struct dsa_switch *ds)
u32 index;
int err;
for (index = 0; index < DSA_MAX_PORTS; index++) {
for (index = 0; index < ds->num_ports; index++) {
port = &ds->ports[index];
if (!dsa_port_is_valid(port))
continue;
......@@ -529,7 +529,7 @@ static int dsa_parse_ports_dn(struct device_node *ports, struct dsa_switch *ds)
if (err)
return err;
if (reg >= DSA_MAX_PORTS)
if (reg >= ds->num_ports)
return -EINVAL;
ds->ports[reg].dn = port;
......@@ -666,6 +666,28 @@ static int _dsa_register_switch(struct dsa_switch *ds, struct device *dev)
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 err;
......
......@@ -25,12 +25,8 @@ struct dsa_slave_priv {
struct sk_buff * (*xmit)(struct sk_buff *skb,
struct net_device *dev);
/*
* Which switch this port is a part of, and the port index
* for this port.
*/
struct dsa_switch *parent;
u8 port;
/* DSA port data, such as switch, port index, etc. */
struct dsa_port *dp;
/*
* The phylib phy_device pointer for the PHY connected
......@@ -42,7 +38,6 @@ struct dsa_slave_priv {
int old_pause;
int old_duplex;
struct net_device *bridge_dev;
#ifdef CONFIG_NET_POLL_CONTROLLER
struct netpoll *netpoll;
#endif
......
此差异已折叠。
......@@ -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);
brcm_tag[1] = 0;
brcm_tag[2] = 0;
if (p->port == 8)
if (p->dp->index == 8)
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;
......@@ -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;
/* 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;
/* Remove Broadcom tag and update checksum */
......
......@@ -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.
*/
dsa_header = skb->data + 2 * ETH_ALEN;
dsa_header[0] = 0x60 | p->parent->index;
dsa_header[1] = p->port << 3;
dsa_header[0] = 0x60 | p->dp->ds->index;
dsa_header[1] = p->dp->index << 3;
/*
* 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)
* Construct untagged FROM_CPU DSA tag.
*/
dsa_header = skb->data + 2 * ETH_ALEN;
dsa_header[0] = 0x40 | p->parent->index;
dsa_header[1] = p->port << 3;
dsa_header[0] = 0x40 | p->dp->ds->index;
dsa_header[1] = p->dp->index << 3;
dsa_header[2] = 0x00;
dsa_header[3] = 0x00;
}
......@@ -114,7 +114,7 @@ static int dsa_rcv(struct sk_buff *skb, struct net_device *dev,
if (!ds)
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;
/*
......
......@@ -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[2] = 0x00;
edsa_header[3] = 0x00;
edsa_header[4] = 0x60 | p->parent->index;
edsa_header[5] = p->port << 3;
edsa_header[4] = 0x60 | p->dp->ds->index;
edsa_header[5] = p->dp->index << 3;
/*
* 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)
edsa_header[1] = ETH_P_EDSA & 0xff;
edsa_header[2] = 0x00;
edsa_header[3] = 0x00;
edsa_header[4] = 0x40 | p->parent->index;
edsa_header[5] = p->port << 3;
edsa_header[4] = 0x40 | p->dp->ds->index;
edsa_header[5] = p->dp->index << 3;
edsa_header[6] = 0x00;
edsa_header[7] = 0x00;
}
......@@ -127,7 +127,7 @@ static int edsa_rcv(struct sk_buff *skb, struct net_device *dev,
if (!ds)
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;
/*
......
......@@ -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 */
hdr = QCA_HDR_VERSION << QCA_HDR_XMIT_VERSION_S |
QCA_HDR_XMIT_FROM_CPU |
BIT(p->port);
BIT(p->dp->index);
*phdr = htons(hdr);
......
......@@ -50,7 +50,7 @@ static struct sk_buff *trailer_xmit(struct sk_buff *skb, struct net_device *dev)
trailer = skb_put(nskb, 4);
trailer[0] = 0x80;
trailer[1] = 1 << p->port;
trailer[1] = 1 << p->dp->index;
trailer[2] = 0x10;
trailer[3] = 0x00;
......@@ -82,7 +82,7 @@ static int trailer_rcv(struct sk_buff *skb, struct net_device *dev,
goto out_drop;
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;
pskb_trim_rcsum(skb, skb->len - 4);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册