|
@@ -62,6 +62,7 @@ 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->parent->dst->master_netdev;
|
|
|
|
+ struct dsa_switch *ds = p->parent;
|
|
int err;
|
|
int err;
|
|
|
|
|
|
if (!(master->flags & IFF_UP))
|
|
if (!(master->flags & IFF_UP))
|
|
@@ -84,11 +85,20 @@ static int dsa_slave_open(struct net_device *dev)
|
|
goto clear_allmulti;
|
|
goto clear_allmulti;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (ds->drv->port_enable) {
|
|
|
|
+ err = ds->drv->port_enable(ds, p->port, p->phy);
|
|
|
|
+ if (err)
|
|
|
|
+ goto clear_promisc;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (p->phy)
|
|
if (p->phy)
|
|
phy_start(p->phy);
|
|
phy_start(p->phy);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
|
|
+clear_promisc:
|
|
|
|
+ if (dev->flags & IFF_PROMISC)
|
|
|
|
+ dev_set_promiscuity(master, 0);
|
|
clear_allmulti:
|
|
clear_allmulti:
|
|
if (dev->flags & IFF_ALLMULTI)
|
|
if (dev->flags & IFF_ALLMULTI)
|
|
dev_set_allmulti(master, -1);
|
|
dev_set_allmulti(master, -1);
|
|
@@ -103,6 +113,7 @@ 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->parent->dst->master_netdev;
|
|
|
|
+ struct dsa_switch *ds = p->parent;
|
|
|
|
|
|
if (p->phy)
|
|
if (p->phy)
|
|
phy_stop(p->phy);
|
|
phy_stop(p->phy);
|
|
@@ -117,6 +128,9 @@ static int dsa_slave_close(struct net_device *dev)
|
|
if (!ether_addr_equal(dev->dev_addr, master->dev_addr))
|
|
if (!ether_addr_equal(dev->dev_addr, master->dev_addr))
|
|
dev_uc_del(master, dev->dev_addr);
|
|
dev_uc_del(master, dev->dev_addr);
|
|
|
|
|
|
|
|
+ if (ds->drv->port_disable)
|
|
|
|
+ ds->drv->port_disable(ds, p->port, p->phy);
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|