diff options
Diffstat (limited to 'drivers/net/usb')
-rw-r--r-- | drivers/net/usb/asix.h | 3 | ||||
-rw-r--r-- | drivers/net/usb/asix_devices.c | 18 |
2 files changed, 20 insertions, 1 deletions
diff --git a/drivers/net/usb/asix.h b/drivers/net/usb/asix.h index 072760d76a72..2c81236c6c7c 100644 --- a/drivers/net/usb/asix.h +++ b/drivers/net/usb/asix.h @@ -158,6 +158,8 @@ #define AX_EEPROM_MAGIC 0xdeadbeef #define AX_EEPROM_LEN 0x200 +#define AX_EMBD_PHY_ADDR 0x10 + /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ struct asix_data { u8 multi_filter[AX_MCAST_FILTER_SIZE]; @@ -183,6 +185,7 @@ struct asix_common_private { struct asix_rx_fixup_info rx_fixup_info; struct mii_bus *mdio; struct phy_device *phydev; + struct phy_device *phydev_int; u16 phy_addr; bool embd_phy; u8 chipcode; diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c index fb617eb551bb..38e47a93fb83 100644 --- a/drivers/net/usb/asix_devices.c +++ b/drivers/net/usb/asix_devices.c @@ -679,6 +679,22 @@ static int ax88772_init_phy(struct usbnet *dev) phy_attached_info(priv->phydev); + if (priv->embd_phy) + return 0; + + /* In case main PHY is not the embedded PHY and MAC is RMII clock + * provider, we need to suspend embedded PHY by keeping PLL enabled + * (AX_SWRESET_IPPD == 0). + */ + priv->phydev_int = mdiobus_get_phy(priv->mdio, AX_EMBD_PHY_ADDR); + if (!priv->phydev_int) { + netdev_err(dev->net, "Could not find internal PHY\n"); + return -ENODEV; + } + + priv->phydev_int->mac_managed_pm = 1; + phy_suspend(priv->phydev_int); + return 0; } @@ -734,7 +750,7 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) return ret; priv->phy_addr = ret; - priv->embd_phy = ((priv->phy_addr & 0x1f) == 0x10); + priv->embd_phy = ((priv->phy_addr & 0x1f) == AX_EMBD_PHY_ADDR); ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, 0, 0, 1, &priv->chipcode, 0); |