allow ifconfig ethX to down ethernet link. Ethernet
part of chip is switched to power down more and on
ifconfig up driver does soft reset and restores it's
state.

Signed-off-by: Max Uvarov <muva...@gmail.com>
---
 drivers/net/usb/smsc95xx.c | 34 +++++++++++++++++++++++++++++++++-
 drivers/net/usb/smsc95xx.h |  5 +++++
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 41e283f3eeb9..e72b038cfb79 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -1142,9 +1142,41 @@ static int smsc95xx_reset(struct usbnet *dev)
        return 0;
 }
 
+static int smsc95xx_lan_power_down(struct net_device *net)
+{
+       struct usbnet *dev = netdev_priv(net);
+       struct mii_if_info *mii = &dev->mii;
+       int ret;
+
+       ret = smsc95xx_mdio_read_nopm(net, mii->phy_id, SMSC95XX_PHY_BASIC);
+       if (ret < 0)
+               return ret;
+       ret &= ~SMSC95XX_PHY_BASIC_BIT_AUTONEG; /* disable autoneg */
+       smsc95xx_mdio_write_nopm(net, mii->phy_id, SMSC95XX_PHY_BASIC, ret);
+
+       ret = smsc95xx_mdio_read_nopm(net, mii->phy_id, SMSC95XX_PHY_BASIC);
+       if (ret < 0)
+               return ret;
+       ret |= SMSC95XX_PHY_BASIC_BIT_POWER_DOWN; /* enable power down */
+       smsc95xx_mdio_write_nopm(net, mii->phy_id, SMSC95XX_PHY_BASIC, ret);
+
+       return 0;
+}
+
+static int smsc95xx_stop(struct net_device *net)
+{
+       int ret;
+
+       ret = smsc95xx_lan_power_down(net);
+       if (ret)
+               netdev_err(net, "err switch to power down mode\n");
+
+       return usbnet_stop(net);
+}
+
 static const struct net_device_ops smsc95xx_netdev_ops = {
        .ndo_open               = usbnet_open,
-       .ndo_stop               = usbnet_stop,
+       .ndo_stop               = smsc95xx_stop,
        .ndo_start_xmit         = usbnet_start_xmit,
        .ndo_tx_timeout         = usbnet_tx_timeout,
        .ndo_change_mtu         = usbnet_change_mtu,
diff --git a/drivers/net/usb/smsc95xx.h b/drivers/net/usb/smsc95xx.h
index 526faa0c44e6..547e8053feba 100644
--- a/drivers/net/usb/smsc95xx.h
+++ b/drivers/net/usb/smsc95xx.h
@@ -47,6 +47,11 @@
 #define RX_STS_DB_                     (0x00000004)    /* Dribbling */
 #define RX_STS_CRC_                    (0x00000002)    /* CRC Error */
 
+/* Basic Control Register */
+#define SMSC95XX_PHY_BASIC               (0x0)
+#define SMSC95XX_PHY_BASIC_BIT_AUTONEG   BIT(12)
+#define SMSC95XX_PHY_BASIC_BIT_POWER_DOWN BIT(11)
+
 /* SCSRs */
 #define ID_REV                         (0x00)
 #define ID_REV_CHIP_ID_MASK_           (0xFFFF0000)
-- 
2.17.1

Reply via email to