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

net: usb/phy: asix: add support for ax88772A/C PHYs

Add support for build-in x88772A/C PHYs

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Oleksij Rempel and committed by
David S. Miller
dde25846 7e88b11a

+74 -1
+73 -1
drivers/net/phy/ax88796b.c
··· 10 10 #include <linux/mii.h> 11 11 #include <linux/phy.h> 12 12 13 + #define PHY_ID_ASIX_AX88772A 0x003b1861 14 + #define PHY_ID_ASIX_AX88772C 0x003b1881 13 15 #define PHY_ID_ASIX_AX88796B 0x003b1841 14 16 15 17 MODULE_DESCRIPTION("Asix PHY driver"); ··· 41 39 return genphy_soft_reset(phydev); 42 40 } 43 41 44 - static struct phy_driver asix_driver[] = { { 42 + /* AX88772A is not working properly with some old switches (NETGEAR EN 108TP): 43 + * after autoneg is done and the link status is reported as active, the MII_LPA 44 + * register is 0. This issue is not reproducible on AX88772C. 45 + */ 46 + static int asix_ax88772a_read_status(struct phy_device *phydev) 47 + { 48 + int ret, val; 49 + 50 + ret = genphy_update_link(phydev); 51 + if (ret) 52 + return ret; 53 + 54 + if (!phydev->link) 55 + return 0; 56 + 57 + /* If MII_LPA is 0, phy_resolve_aneg_linkmode() will fail to resolve 58 + * linkmode so use MII_BMCR as default values. 59 + */ 60 + val = phy_read(phydev, MII_BMCR); 61 + if (val < 0) 62 + return val; 63 + 64 + if (val & BMCR_SPEED100) 65 + phydev->speed = SPEED_100; 66 + else 67 + phydev->speed = SPEED_10; 68 + 69 + if (val & BMCR_FULLDPLX) 70 + phydev->duplex = DUPLEX_FULL; 71 + else 72 + phydev->duplex = DUPLEX_HALF; 73 + 74 + ret = genphy_read_lpa(phydev); 75 + if (ret < 0) 76 + return ret; 77 + 78 + if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) 79 + phy_resolve_aneg_linkmode(phydev); 80 + 81 + return 0; 82 + } 83 + 84 + static void asix_ax88772a_link_change_notify(struct phy_device *phydev) 85 + { 86 + /* Reset PHY, otherwise MII_LPA will provide outdated information. 87 + * This issue is reproducible only with some link partner PHYs 88 + */ 89 + if (phydev->state == PHY_NOLINK && phydev->drv->soft_reset) 90 + phydev->drv->soft_reset(phydev); 91 + } 92 + 93 + static struct phy_driver asix_driver[] = { 94 + { 95 + PHY_ID_MATCH_EXACT(PHY_ID_ASIX_AX88772A), 96 + .name = "Asix Electronics AX88772A", 97 + .flags = PHY_IS_INTERNAL, 98 + .read_status = asix_ax88772a_read_status, 99 + .suspend = genphy_suspend, 100 + .resume = genphy_resume, 101 + .soft_reset = asix_soft_reset, 102 + .link_change_notify = asix_ax88772a_link_change_notify, 103 + }, { 104 + PHY_ID_MATCH_EXACT(PHY_ID_ASIX_AX88772C), 105 + .name = "Asix Electronics AX88772C", 106 + .flags = PHY_IS_INTERNAL, 107 + .suspend = genphy_suspend, 108 + .resume = genphy_resume, 109 + .soft_reset = asix_soft_reset, 110 + }, { 45 111 .phy_id = PHY_ID_ASIX_AX88796B, 46 112 .name = "Asix Electronics AX88796B", 47 113 .phy_id_mask = 0xfffffff0, ··· 120 50 module_phy_driver(asix_driver); 121 51 122 52 static struct mdio_device_id __maybe_unused asix_tbl[] = { 53 + { PHY_ID_MATCH_EXACT(PHY_ID_ASIX_AX88772A) }, 54 + { PHY_ID_MATCH_EXACT(PHY_ID_ASIX_AX88772C) }, 123 55 { PHY_ID_ASIX_AX88796B, 0xfffffff0 }, 124 56 { } 125 57 };
+1
drivers/net/usb/Kconfig
··· 164 164 depends on USB_USBNET 165 165 select CRC32 166 166 select PHYLIB 167 + select AX88796B_PHY 167 168 default y 168 169 help 169 170 This option adds support for ASIX AX88xxx based USB 2.0