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