net: dsa: use dsa_to_port helper everywhere

Do not let the drivers access the ds->ports static array directly
while there is a dsa_to_port helper for this purpose.

At the same time, un-const this helper since the SJA1105 driver
assigns the priv member of the returned dsa_port structure.

Signed-off-by: Vivien Didelot <vivien.didelot@gmail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
This commit is contained in:
Vivien Didelot 2019-10-21 16:51:15 -04:00 committed by Jakub Kicinski
parent 88652bf8ce
commit 68bb8ea8ad
12 changed files with 44 additions and 42 deletions

View File

@ -524,7 +524,7 @@ int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy)
if (!dsa_is_user_port(ds, port)) if (!dsa_is_user_port(ds, port))
return 0; return 0;
cpu_port = ds->ports[port].cpu_dp->index; cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
if (dev->ops->irq_enable) if (dev->ops->irq_enable)
ret = dev->ops->irq_enable(dev, port); ret = dev->ops->irq_enable(dev, port);
@ -1629,7 +1629,7 @@ EXPORT_SYMBOL(b53_fdb_dump);
int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br) 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->ports[port].cpu_dp->index; s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
u16 pvlan, reg; u16 pvlan, reg;
unsigned int i; unsigned int i;
@ -1675,7 +1675,7 @@ 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 b53_vlan *vl = &dev->vlans[0]; struct b53_vlan *vl = &dev->vlans[0];
s8 cpu_port = ds->ports[port].cpu_dp->index; s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
unsigned int i; unsigned int i;
u16 pvlan, reg, pvid; u16 pvlan, reg, pvid;

View File

@ -662,7 +662,7 @@ static void bcm_sf2_sw_fixed_state(struct dsa_switch *ds, int port,
* state machine and make it go in PHY_FORCING state instead. * state machine and make it go in PHY_FORCING state instead.
*/ */
if (!status->link) if (!status->link)
netif_carrier_off(ds->ports[port].slave); netif_carrier_off(dsa_to_port(ds, port)->slave);
status->duplex = DUPLEX_FULL; status->duplex = DUPLEX_FULL;
} else { } else {
status->link = true; status->link = true;
@ -728,7 +728,7 @@ static int bcm_sf2_sw_resume(struct dsa_switch *ds)
static void bcm_sf2_sw_get_wol(struct dsa_switch *ds, int port, static void bcm_sf2_sw_get_wol(struct dsa_switch *ds, int port,
struct ethtool_wolinfo *wol) struct ethtool_wolinfo *wol)
{ {
struct net_device *p = ds->ports[port].cpu_dp->master; struct net_device *p = dsa_to_port(ds, port)->cpu_dp->master;
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
struct ethtool_wolinfo pwol = { }; struct ethtool_wolinfo pwol = { };
@ -752,9 +752,9 @@ static void bcm_sf2_sw_get_wol(struct dsa_switch *ds, int port,
static int bcm_sf2_sw_set_wol(struct dsa_switch *ds, int port, static int bcm_sf2_sw_set_wol(struct dsa_switch *ds, int port,
struct ethtool_wolinfo *wol) struct ethtool_wolinfo *wol)
{ {
struct net_device *p = ds->ports[port].cpu_dp->master; struct net_device *p = dsa_to_port(ds, port)->cpu_dp->master;
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
s8 cpu_port = ds->ports[port].cpu_dp->index; s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
struct ethtool_wolinfo pwol = { }; struct ethtool_wolinfo pwol = { };
if (p->ethtool_ops->get_wol) if (p->ethtool_ops->get_wol)

View File

@ -821,7 +821,7 @@ static int bcm_sf2_cfp_rule_insert(struct dsa_switch *ds, int port,
struct ethtool_rx_flow_spec *fs) struct ethtool_rx_flow_spec *fs)
{ {
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
s8 cpu_port = ds->ports[port].cpu_dp->index; s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
__u64 ring_cookie = fs->ring_cookie; __u64 ring_cookie = fs->ring_cookie;
unsigned int queue_num, port_num; unsigned int queue_num, port_num;
int ret; int ret;
@ -1049,7 +1049,7 @@ static int bcm_sf2_cfp_rule_get_all(struct bcm_sf2_priv *priv,
int bcm_sf2_get_rxnfc(struct dsa_switch *ds, int port, int bcm_sf2_get_rxnfc(struct dsa_switch *ds, int port,
struct ethtool_rxnfc *nfc, u32 *rule_locs) struct ethtool_rxnfc *nfc, u32 *rule_locs)
{ {
struct net_device *p = ds->ports[port].cpu_dp->master; struct net_device *p = dsa_to_port(ds, port)->cpu_dp->master;
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
int ret = 0; int ret = 0;
@ -1092,7 +1092,7 @@ int bcm_sf2_get_rxnfc(struct dsa_switch *ds, int port,
int bcm_sf2_set_rxnfc(struct dsa_switch *ds, int port, int bcm_sf2_set_rxnfc(struct dsa_switch *ds, int port,
struct ethtool_rxnfc *nfc) struct ethtool_rxnfc *nfc)
{ {
struct net_device *p = ds->ports[port].cpu_dp->master; struct net_device *p = dsa_to_port(ds, port)->cpu_dp->master;
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
int ret = 0; int ret = 0;

View File

@ -862,7 +862,7 @@ mt7530_port_set_vlan_unaware(struct dsa_switch *ds, int port)
for (i = 0; i < MT7530_NUM_PORTS; i++) { for (i = 0; i < MT7530_NUM_PORTS; i++) {
if (dsa_is_user_port(ds, i) && if (dsa_is_user_port(ds, i) &&
dsa_port_is_vlan_filtering(&ds->ports[i])) { dsa_port_is_vlan_filtering(dsa_to_port(ds, i))) {
all_user_ports_removed = false; all_user_ports_removed = false;
break; break;
} }
@ -922,7 +922,7 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
* other port is still a VLAN-aware port. * other port is still a VLAN-aware port.
*/ */
if (dsa_is_user_port(ds, i) && i != port && if (dsa_is_user_port(ds, i) && i != port &&
!dsa_port_is_vlan_filtering(&ds->ports[i])) { !dsa_port_is_vlan_filtering(dsa_to_port(ds, i))) {
if (dsa_to_port(ds, i)->bridge_dev != bridge) if (dsa_to_port(ds, i)->bridge_dev != bridge)
continue; continue;
if (priv->ports[i].enable) if (priv->ports[i].enable)
@ -1165,7 +1165,7 @@ mt7530_port_vlan_add(struct dsa_switch *ds, int port,
/* The port is kept as VLAN-unaware if bridge with vlan_filtering not /* The port is kept as VLAN-unaware if bridge with vlan_filtering not
* being set. * being set.
*/ */
if (!dsa_port_is_vlan_filtering(&ds->ports[port])) if (!dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
return; return;
mutex_lock(&priv->reg_mutex); mutex_lock(&priv->reg_mutex);
@ -1196,7 +1196,7 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port,
/* The port is kept as VLAN-unaware if bridge with vlan_filtering not /* The port is kept as VLAN-unaware if bridge with vlan_filtering not
* being set. * being set.
*/ */
if (!dsa_port_is_vlan_filtering(&ds->ports[port])) if (!dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
return 0; return 0;
mutex_lock(&priv->reg_mutex); mutex_lock(&priv->reg_mutex);
@ -1252,7 +1252,7 @@ mt7530_setup(struct dsa_switch *ds)
* controller also is the container for two GMACs nodes representing * controller also is the container for two GMACs nodes representing
* as two netdev instances. * as two netdev instances.
*/ */
dn = ds->ports[MT7530_CPU_PORT].master->dev.of_node->parent; dn = dsa_to_port(ds, MT7530_CPU_PORT)->master->dev.of_node->parent;
if (priv->id == ID_MT7530) { if (priv->id == ID_MT7530) {
priv->ethernet = syscon_node_to_regmap(dn); priv->ethernet = syscon_node_to_regmap(dn);
@ -1340,7 +1340,7 @@ mt7530_setup(struct dsa_switch *ds)
if (!dsa_is_unused_port(ds, 5)) { if (!dsa_is_unused_port(ds, 5)) {
priv->p5_intf_sel = P5_INTF_SEL_GMAC5; priv->p5_intf_sel = P5_INTF_SEL_GMAC5;
interface = of_get_phy_mode(ds->ports[5].dn); interface = of_get_phy_mode(dsa_to_port(ds, 5)->dn);
} else { } else {
/* Scan the ethernet nodes. look for GMAC1, lookup used phy */ /* Scan the ethernet nodes. look for GMAC1, lookup used phy */
for_each_child_of_node(dn, mac_np) { for_each_child_of_node(dn, mac_np) {

View File

@ -1075,7 +1075,7 @@ static u16 mv88e6xxx_port_vlan(struct mv88e6xxx_chip *chip, int dev, int 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))
return mv88e6xxx_port_mask(chip); return mv88e6xxx_port_mask(chip);
br = ds->ports[port].bridge_dev; br = dsa_to_port(ds, port)->bridge_dev;
pvlan = 0; pvlan = 0;
/* Frames from user ports can egress any local DSA links and CPU ports, /* Frames from user ports can egress any local DSA links and CPU ports,
@ -1402,7 +1402,7 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
if (dsa_is_dsa_port(ds, i) || dsa_is_cpu_port(ds, i)) if (dsa_is_dsa_port(ds, i) || dsa_is_cpu_port(ds, i))
continue; continue;
if (!ds->ports[i].slave) if (!dsa_to_port(ds, i)->slave)
continue; continue;
if (vlan.member[i] == if (vlan.member[i] ==
@ -1410,7 +1410,7 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
continue; continue;
if (dsa_to_port(ds, i)->bridge_dev == if (dsa_to_port(ds, i)->bridge_dev ==
ds->ports[port].bridge_dev) dsa_to_port(ds, port)->bridge_dev)
break; /* same bridge, check next VLAN */ break; /* same bridge, check next VLAN */
if (!dsa_to_port(ds, i)->bridge_dev) if (!dsa_to_port(ds, i)->bridge_dev)
@ -2042,7 +2042,7 @@ static int mv88e6xxx_bridge_map(struct mv88e6xxx_chip *chip,
/* Remap the Port VLAN of each local bridge group member */ /* Remap the Port VLAN of each local bridge group member */
for (port = 0; port < mv88e6xxx_num_ports(chip); ++port) { for (port = 0; port < mv88e6xxx_num_ports(chip); ++port) {
if (chip->ds->ports[port].bridge_dev == br) { if (dsa_to_port(chip->ds, port)->bridge_dev == br) {
err = mv88e6xxx_port_vlan_map(chip, port); err = mv88e6xxx_port_vlan_map(chip, port);
if (err) if (err)
return err; return err;
@ -2059,7 +2059,7 @@ static int mv88e6xxx_bridge_map(struct mv88e6xxx_chip *chip,
break; break;
for (port = 0; port < ds->num_ports; ++port) { for (port = 0; port < ds->num_ports; ++port) {
if (ds->ports[port].bridge_dev == br) { if (dsa_to_port(ds, port)->bridge_dev == br) {
err = mv88e6xxx_pvt_map(chip, dev, port); err = mv88e6xxx_pvt_map(chip, dev, port);
if (err) if (err)
return err; return err;

View File

@ -661,7 +661,7 @@ qca8k_setup(struct dsa_switch *ds)
return ret; return ret;
/* Initialize CPU port pad mode (xMII type, delays...) */ /* Initialize CPU port pad mode (xMII type, delays...) */
phy_mode = of_get_phy_mode(ds->ports[QCA8K_CPU_PORT].dn); phy_mode = of_get_phy_mode(dsa_to_port(ds, QCA8K_CPU_PORT)->dn);
if (phy_mode < 0) { if (phy_mode < 0) {
pr_err("Can't find phy-mode for master device\n"); pr_err("Can't find phy-mode for master device\n");
return phy_mode; return phy_mode;

View File

@ -1058,7 +1058,7 @@ int sja1105pqrs_fdb_add(struct dsa_switch *ds, int port,
l2_lookup.vlanid = vid; l2_lookup.vlanid = vid;
l2_lookup.iotag = SJA1105_S_TAG; l2_lookup.iotag = SJA1105_S_TAG;
l2_lookup.mask_macaddr = GENMASK_ULL(ETH_ALEN * 8 - 1, 0); l2_lookup.mask_macaddr = GENMASK_ULL(ETH_ALEN * 8 - 1, 0);
if (dsa_port_is_vlan_filtering(&ds->ports[port])) { if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port))) {
l2_lookup.mask_vlanid = VLAN_VID_MASK; l2_lookup.mask_vlanid = VLAN_VID_MASK;
l2_lookup.mask_iotag = BIT(0); l2_lookup.mask_iotag = BIT(0);
} else { } else {
@ -1121,7 +1121,7 @@ int sja1105pqrs_fdb_del(struct dsa_switch *ds, int port,
l2_lookup.vlanid = vid; l2_lookup.vlanid = vid;
l2_lookup.iotag = SJA1105_S_TAG; l2_lookup.iotag = SJA1105_S_TAG;
l2_lookup.mask_macaddr = GENMASK_ULL(ETH_ALEN * 8 - 1, 0); l2_lookup.mask_macaddr = GENMASK_ULL(ETH_ALEN * 8 - 1, 0);
if (dsa_port_is_vlan_filtering(&ds->ports[port])) { if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port))) {
l2_lookup.mask_vlanid = VLAN_VID_MASK; l2_lookup.mask_vlanid = VLAN_VID_MASK;
l2_lookup.mask_iotag = BIT(0); l2_lookup.mask_iotag = BIT(0);
} else { } else {
@ -1167,7 +1167,7 @@ static int sja1105_fdb_add(struct dsa_switch *ds, int port,
* for what gets printed in 'bridge fdb show'. In the case of zero, * for what gets printed in 'bridge fdb show'. In the case of zero,
* no VID gets printed at all. * no VID gets printed at all.
*/ */
if (!dsa_port_is_vlan_filtering(&ds->ports[port])) if (!dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
vid = 0; vid = 0;
return priv->info->fdb_add_cmd(ds, port, addr, vid); return priv->info->fdb_add_cmd(ds, port, addr, vid);
@ -1178,7 +1178,7 @@ static int sja1105_fdb_del(struct dsa_switch *ds, int port,
{ {
struct sja1105_private *priv = ds->priv; struct sja1105_private *priv = ds->priv;
if (!dsa_port_is_vlan_filtering(&ds->ports[port])) if (!dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
vid = 0; vid = 0;
return priv->info->fdb_del_cmd(ds, port, addr, vid); return priv->info->fdb_del_cmd(ds, port, addr, vid);
@ -1217,7 +1217,7 @@ static int sja1105_fdb_dump(struct dsa_switch *ds, int port,
u64_to_ether_addr(l2_lookup.macaddr, macaddr); u64_to_ether_addr(l2_lookup.macaddr, macaddr);
/* We need to hide the dsa_8021q VLANs from the user. */ /* We need to hide the dsa_8021q VLANs from the user. */
if (!dsa_port_is_vlan_filtering(&ds->ports[port])) if (!dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
l2_lookup.vlanid = 0; l2_lookup.vlanid = 0;
cb(macaddr, l2_lookup.vlanid, l2_lookup.lockeds, data); cb(macaddr, l2_lookup.vlanid, l2_lookup.lockeds, data);
} }
@ -1704,7 +1704,7 @@ static int sja1105_port_enable(struct dsa_switch *ds, int port,
if (!dsa_is_user_port(ds, port)) if (!dsa_is_user_port(ds, port))
return 0; return 0;
slave = ds->ports[port].slave; slave = dsa_to_port(ds, port)->slave;
slave->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER; slave->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
@ -1736,7 +1736,7 @@ static int sja1105_mgmt_xmit(struct dsa_switch *ds, int port, int slot,
} }
/* Transfer skb to the host port. */ /* Transfer skb to the host port. */
dsa_enqueue_skb(skb, ds->ports[port].slave); dsa_enqueue_skb(skb, dsa_to_port(ds, port)->slave);
/* Wait until the switch has processed the frame */ /* Wait until the switch has processed the frame */
do { do {
@ -2061,8 +2061,8 @@ static int sja1105_probe(struct spi_device *spi)
for (i = 0; i < SJA1105_NUM_PORTS; i++) { for (i = 0; i < SJA1105_NUM_PORTS; i++) {
struct sja1105_port *sp = &priv->ports[i]; struct sja1105_port *sp = &priv->ports[i];
ds->ports[i].priv = sp; dsa_to_port(ds, i)->priv = sp;
sp->dp = &ds->ports[i]; sp->dp = dsa_to_port(ds, i);
sp->data = tagger_data; sp->data = tagger_data;
} }
mutex_init(&priv->ptp_data.lock); mutex_init(&priv->ptp_data.lock);

View File

@ -278,7 +278,7 @@ struct dsa_switch {
struct dsa_port ports[]; struct dsa_port ports[];
}; };
static inline const struct dsa_port *dsa_to_port(struct dsa_switch *ds, int p) static inline struct dsa_port *dsa_to_port(struct dsa_switch *ds, int p)
{ {
return &ds->ports[p]; return &ds->ports[p];
} }

View File

@ -246,7 +246,9 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static bool dsa_is_port_initialized(struct dsa_switch *ds, int p) static bool dsa_is_port_initialized(struct dsa_switch *ds, int p)
{ {
return dsa_is_user_port(ds, p) && ds->ports[p].slave; const struct dsa_port *dp = dsa_to_port(ds, p);
return dp->type == DSA_PORT_TYPE_USER && dp->slave;
} }
int dsa_switch_suspend(struct dsa_switch *ds) int dsa_switch_suspend(struct dsa_switch *ds)
@ -258,7 +260,7 @@ int dsa_switch_suspend(struct dsa_switch *ds)
if (!dsa_is_port_initialized(ds, i)) if (!dsa_is_port_initialized(ds, i))
continue; continue;
ret = dsa_slave_suspend(ds->ports[i].slave); ret = dsa_slave_suspend(dsa_to_port(ds, i)->slave);
if (ret) if (ret)
return ret; return ret;
} }
@ -285,7 +287,7 @@ int dsa_switch_resume(struct dsa_switch *ds)
if (!dsa_is_port_initialized(ds, i)) if (!dsa_is_port_initialized(ds, i))
continue; continue;
ret = dsa_slave_resume(ds->ports[i].slave); ret = dsa_slave_resume(dsa_to_port(ds, i)->slave);
if (ret) if (ret)
return ret; return ret;
} }

View File

@ -708,7 +708,7 @@ static int dsa_switch_parse_ports_of(struct dsa_switch *ds,
goto out_put_node; goto out_put_node;
} }
dp = &ds->ports[reg]; dp = dsa_to_port(ds, reg);
err = dsa_port_parse_of(dp, port); err = dsa_port_parse_of(dp, port);
if (err) if (err)
@ -787,7 +787,7 @@ static int dsa_switch_parse_ports(struct dsa_switch *ds,
for (i = 0; i < DSA_MAX_PORTS; i++) { for (i = 0; i < DSA_MAX_PORTS; i++) {
name = cd->port_names[i]; name = cd->port_names[i];
dev = cd->netdev[i]; dev = cd->netdev[i];
dp = &ds->ports[i]; dp = dsa_to_port(ds, i);
if (!name) if (!name)
continue; continue;

View File

@ -20,7 +20,7 @@ static unsigned int dsa_switch_fastest_ageing_time(struct dsa_switch *ds,
int i; int i;
for (i = 0; i < ds->num_ports; ++i) { for (i = 0; i < ds->num_ports; ++i) {
struct dsa_port *dp = &ds->ports[i]; struct dsa_port *dp = dsa_to_port(ds, i);
if (dp->ageing_time && dp->ageing_time < ageing_time) if (dp->ageing_time && dp->ageing_time < ageing_time)
ageing_time = dp->ageing_time; ageing_time = dp->ageing_time;
@ -98,7 +98,7 @@ static int dsa_switch_bridge_leave(struct dsa_switch *ds,
if (unset_vlan_filtering) { if (unset_vlan_filtering) {
struct switchdev_trans trans = {0}; struct switchdev_trans trans = {0};
err = dsa_port_vlan_filtering(&ds->ports[info->port], err = dsa_port_vlan_filtering(dsa_to_port(ds, info->port),
false, &trans); false, &trans);
if (err && err != EOPNOTSUPP) if (err && err != EOPNOTSUPP)
return err; return err;

View File

@ -103,7 +103,7 @@ static int dsa_8021q_restore_pvid(struct dsa_switch *ds, int port)
if (!dsa_is_user_port(ds, port)) if (!dsa_is_user_port(ds, port))
return 0; return 0;
slave = ds->ports[port].slave; slave = dsa_to_port(ds, port)->slave;
err = br_vlan_get_pvid(slave, &pvid); err = br_vlan_get_pvid(slave, &pvid);
if (err < 0) if (err < 0)
@ -118,7 +118,7 @@ static int dsa_8021q_restore_pvid(struct dsa_switch *ds, int port)
return err; return err;
} }
return dsa_port_vid_add(&ds->ports[port], pvid, vinfo.flags); return dsa_port_vid_add(dsa_to_port(ds, port), pvid, vinfo.flags);
} }
/* If @enabled is true, installs @vid with @flags into the switch port's HW /* If @enabled is true, installs @vid with @flags into the switch port's HW
@ -130,7 +130,7 @@ static int dsa_8021q_restore_pvid(struct dsa_switch *ds, int port)
static int dsa_8021q_vid_apply(struct dsa_switch *ds, int port, u16 vid, static int dsa_8021q_vid_apply(struct dsa_switch *ds, int port, u16 vid,
u16 flags, bool enabled) u16 flags, bool enabled)
{ {
struct dsa_port *dp = &ds->ports[port]; struct dsa_port *dp = dsa_to_port(ds, port);
struct bridge_vlan_info vinfo; struct bridge_vlan_info vinfo;
int err; int err;