Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: usb: asix: suspend embedded PHY if external is used

In case external PHY is used, we need to take care of embedded PHY.
Since there are no methods to disable this PHY from the MAC side and
keeping RMII reference clock, we need to suspend it.

This patch will reduce electrical noise (PHY is continuing to send FLPs)
and power consumption by 0,22W.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Oleksij Rempel and committed by
David S. Miller
4d17d43d d5f3c81c

+20 -1
+3
drivers/net/usb/asix.h
··· 158 158 #define AX_EEPROM_MAGIC 0xdeadbeef 159 159 #define AX_EEPROM_LEN 0x200 160 160 161 + #define AX_EMBD_PHY_ADDR 0x10 162 + 161 163 /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ 162 164 struct asix_data { 163 165 u8 multi_filter[AX_MCAST_FILTER_SIZE]; ··· 185 183 struct asix_rx_fixup_info rx_fixup_info; 186 184 struct mii_bus *mdio; 187 185 struct phy_device *phydev; 186 + struct phy_device *phydev_int; 188 187 u16 phy_addr; 189 188 bool embd_phy; 190 189 u8 chipcode;
+17 -1
drivers/net/usb/asix_devices.c
··· 679 679 680 680 phy_attached_info(priv->phydev); 681 681 682 + if (priv->embd_phy) 683 + return 0; 684 + 685 + /* In case main PHY is not the embedded PHY and MAC is RMII clock 686 + * provider, we need to suspend embedded PHY by keeping PLL enabled 687 + * (AX_SWRESET_IPPD == 0). 688 + */ 689 + priv->phydev_int = mdiobus_get_phy(priv->mdio, AX_EMBD_PHY_ADDR); 690 + if (!priv->phydev_int) { 691 + netdev_err(dev->net, "Could not find internal PHY\n"); 692 + return -ENODEV; 693 + } 694 + 695 + priv->phydev_int->mac_managed_pm = 1; 696 + phy_suspend(priv->phydev_int); 697 + 682 698 return 0; 683 699 } 684 700 ··· 750 734 return ret; 751 735 752 736 priv->phy_addr = ret; 753 - priv->embd_phy = ((priv->phy_addr & 0x1f) == 0x10); 737 + priv->embd_phy = ((priv->phy_addr & 0x1f) == AX_EMBD_PHY_ADDR); 754 738 755 739 ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, 0, 0, 1, 756 740 &priv->chipcode, 0);