Loading drivers/net/usb/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -111,6 +111,7 @@ config USB_LAN78XX select MII select PHYLIB select MICROCHIP_PHY select FIXED_PHY help This option adds support for Microchip LAN78XX based USB 2 & USB 3 10/100/1000 Ethernet adapters. Loading drivers/net/usb/lan78xx.c +76 −28 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ #include <linux/irq.h> #include <linux/irqchip/chained_irq.h> #include <linux/microchipphy.h> #include <linux/phy.h> #include <linux/phy_fixed.h> #include <linux/of_mdio.h> #include <linux/of_net.h> #include "lan78xx.h" Loading Loading @@ -2063,52 +2063,91 @@ static int ksz9031rnx_fixup(struct phy_device *phydev) return 1; } static int lan78xx_phy_init(struct lan78xx_net *dev) static struct phy_device *lan7801_phy_init(struct lan78xx_net *dev) { u32 buf; int ret; u32 mii_adv; struct fixed_phy_status fphy_status = { .link = 1, .speed = SPEED_1000, .duplex = DUPLEX_FULL, }; struct phy_device *phydev; phydev = phy_find_first(dev->mdiobus); if (!phydev) { netdev_err(dev->net, "no PHY found\n"); return -EIO; netdev_dbg(dev->net, "PHY Not Found!! Registering Fixed PHY\n"); phydev = fixed_phy_register(PHY_POLL, &fphy_status, -1, NULL); if (IS_ERR(phydev)) { netdev_err(dev->net, "No PHY/fixed_PHY found\n"); return NULL; } if ((dev->chipid == ID_REV_CHIP_ID_7800_) || (dev->chipid == ID_REV_CHIP_ID_7850_)) { phydev->is_internal = true; dev->interface = PHY_INTERFACE_MODE_GMII; } else if (dev->chipid == ID_REV_CHIP_ID_7801_) { netdev_dbg(dev->net, "Registered FIXED PHY\n"); dev->interface = PHY_INTERFACE_MODE_RGMII; ret = lan78xx_write_reg(dev, MAC_RGMII_ID, MAC_RGMII_ID_TXC_DELAY_EN_); ret = lan78xx_write_reg(dev, RGMII_TX_BYP_DLL, 0x3D00); ret = lan78xx_read_reg(dev, HW_CFG, &buf); buf |= HW_CFG_CLK125_EN_; buf |= HW_CFG_REFCLK25_EN_; ret = lan78xx_write_reg(dev, HW_CFG, buf); } else { if (!phydev->drv) { netdev_err(dev->net, "no PHY driver found\n"); return -EIO; return NULL; } dev->interface = PHY_INTERFACE_MODE_RGMII; /* external PHY fixup for KSZ9031RNX */ ret = phy_register_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0, ksz9031rnx_fixup); if (ret < 0) { netdev_err(dev->net, "fail to register fixup\n"); return ret; return NULL; } /* external PHY fixup for LAN8835 */ ret = phy_register_fixup_for_uid(PHY_LAN8835, 0xfffffff0, lan8835_fixup); if (ret < 0) { netdev_err(dev->net, "fail to register fixup\n"); return ret; return NULL; } /* add more external PHY fixup here if needed */ phydev->is_internal = false; } else { netdev_err(dev->net, "unknown ID found\n"); ret = -EIO; goto error; } return phydev; } static int lan78xx_phy_init(struct lan78xx_net *dev) { int ret; u32 mii_adv; struct phy_device *phydev; switch (dev->chipid) { case ID_REV_CHIP_ID_7801_: phydev = lan7801_phy_init(dev); if (!phydev) { netdev_err(dev->net, "lan7801: PHY Init Failed"); return -EIO; } break; case ID_REV_CHIP_ID_7800_: case ID_REV_CHIP_ID_7850_: phydev = phy_find_first(dev->mdiobus); if (!phydev) { netdev_err(dev->net, "no PHY found\n"); return -EIO; } phydev->is_internal = true; dev->interface = PHY_INTERFACE_MODE_GMII; break; default: netdev_err(dev->net, "Unknown CHIP ID found\n"); return -EIO; } /* if phyirq is not set, use polling mode in phylib */ Loading @@ -2127,6 +2166,16 @@ static int lan78xx_phy_init(struct lan78xx_net *dev) if (ret) { netdev_err(dev->net, "can't attach PHY to %s\n", dev->mdiobus->id); if (dev->chipid == ID_REV_CHIP_ID_7801_) { if (phy_is_pseudo_fixed_link(phydev)) { fixed_phy_unregister(phydev); } else { phy_unregister_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0); phy_unregister_fixup_for_uid(PHY_LAN8835, 0xfffffff0); } } return -EIO; } Loading Loading @@ -2166,12 +2215,6 @@ static int lan78xx_phy_init(struct lan78xx_net *dev) dev->fc_autoneg = phydev->autoneg; return 0; error: phy_unregister_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0); phy_unregister_fixup_for_uid(PHY_LAN8835, 0xfffffff0); return ret; } static int lan78xx_set_rx_max_frame_length(struct lan78xx_net *dev, int size) Loading Loading @@ -3569,6 +3612,7 @@ static void lan78xx_disconnect(struct usb_interface *intf) struct lan78xx_net *dev; struct usb_device *udev; struct net_device *net; struct phy_device *phydev; dev = usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); Loading @@ -3577,12 +3621,16 @@ static void lan78xx_disconnect(struct usb_interface *intf) udev = interface_to_usbdev(intf); net = dev->net; phydev = net->phydev; phy_unregister_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0); phy_unregister_fixup_for_uid(PHY_LAN8835, 0xfffffff0); phy_disconnect(net->phydev); if (phy_is_pseudo_fixed_link(phydev)) fixed_phy_unregister(phydev); unregister_netdev(net); cancel_delayed_work_sync(&dev->wq); Loading Loading
drivers/net/usb/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -111,6 +111,7 @@ config USB_LAN78XX select MII select PHYLIB select MICROCHIP_PHY select FIXED_PHY help This option adds support for Microchip LAN78XX based USB 2 & USB 3 10/100/1000 Ethernet adapters. Loading
drivers/net/usb/lan78xx.c +76 −28 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ #include <linux/irq.h> #include <linux/irqchip/chained_irq.h> #include <linux/microchipphy.h> #include <linux/phy.h> #include <linux/phy_fixed.h> #include <linux/of_mdio.h> #include <linux/of_net.h> #include "lan78xx.h" Loading Loading @@ -2063,52 +2063,91 @@ static int ksz9031rnx_fixup(struct phy_device *phydev) return 1; } static int lan78xx_phy_init(struct lan78xx_net *dev) static struct phy_device *lan7801_phy_init(struct lan78xx_net *dev) { u32 buf; int ret; u32 mii_adv; struct fixed_phy_status fphy_status = { .link = 1, .speed = SPEED_1000, .duplex = DUPLEX_FULL, }; struct phy_device *phydev; phydev = phy_find_first(dev->mdiobus); if (!phydev) { netdev_err(dev->net, "no PHY found\n"); return -EIO; netdev_dbg(dev->net, "PHY Not Found!! Registering Fixed PHY\n"); phydev = fixed_phy_register(PHY_POLL, &fphy_status, -1, NULL); if (IS_ERR(phydev)) { netdev_err(dev->net, "No PHY/fixed_PHY found\n"); return NULL; } if ((dev->chipid == ID_REV_CHIP_ID_7800_) || (dev->chipid == ID_REV_CHIP_ID_7850_)) { phydev->is_internal = true; dev->interface = PHY_INTERFACE_MODE_GMII; } else if (dev->chipid == ID_REV_CHIP_ID_7801_) { netdev_dbg(dev->net, "Registered FIXED PHY\n"); dev->interface = PHY_INTERFACE_MODE_RGMII; ret = lan78xx_write_reg(dev, MAC_RGMII_ID, MAC_RGMII_ID_TXC_DELAY_EN_); ret = lan78xx_write_reg(dev, RGMII_TX_BYP_DLL, 0x3D00); ret = lan78xx_read_reg(dev, HW_CFG, &buf); buf |= HW_CFG_CLK125_EN_; buf |= HW_CFG_REFCLK25_EN_; ret = lan78xx_write_reg(dev, HW_CFG, buf); } else { if (!phydev->drv) { netdev_err(dev->net, "no PHY driver found\n"); return -EIO; return NULL; } dev->interface = PHY_INTERFACE_MODE_RGMII; /* external PHY fixup for KSZ9031RNX */ ret = phy_register_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0, ksz9031rnx_fixup); if (ret < 0) { netdev_err(dev->net, "fail to register fixup\n"); return ret; return NULL; } /* external PHY fixup for LAN8835 */ ret = phy_register_fixup_for_uid(PHY_LAN8835, 0xfffffff0, lan8835_fixup); if (ret < 0) { netdev_err(dev->net, "fail to register fixup\n"); return ret; return NULL; } /* add more external PHY fixup here if needed */ phydev->is_internal = false; } else { netdev_err(dev->net, "unknown ID found\n"); ret = -EIO; goto error; } return phydev; } static int lan78xx_phy_init(struct lan78xx_net *dev) { int ret; u32 mii_adv; struct phy_device *phydev; switch (dev->chipid) { case ID_REV_CHIP_ID_7801_: phydev = lan7801_phy_init(dev); if (!phydev) { netdev_err(dev->net, "lan7801: PHY Init Failed"); return -EIO; } break; case ID_REV_CHIP_ID_7800_: case ID_REV_CHIP_ID_7850_: phydev = phy_find_first(dev->mdiobus); if (!phydev) { netdev_err(dev->net, "no PHY found\n"); return -EIO; } phydev->is_internal = true; dev->interface = PHY_INTERFACE_MODE_GMII; break; default: netdev_err(dev->net, "Unknown CHIP ID found\n"); return -EIO; } /* if phyirq is not set, use polling mode in phylib */ Loading @@ -2127,6 +2166,16 @@ static int lan78xx_phy_init(struct lan78xx_net *dev) if (ret) { netdev_err(dev->net, "can't attach PHY to %s\n", dev->mdiobus->id); if (dev->chipid == ID_REV_CHIP_ID_7801_) { if (phy_is_pseudo_fixed_link(phydev)) { fixed_phy_unregister(phydev); } else { phy_unregister_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0); phy_unregister_fixup_for_uid(PHY_LAN8835, 0xfffffff0); } } return -EIO; } Loading Loading @@ -2166,12 +2215,6 @@ static int lan78xx_phy_init(struct lan78xx_net *dev) dev->fc_autoneg = phydev->autoneg; return 0; error: phy_unregister_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0); phy_unregister_fixup_for_uid(PHY_LAN8835, 0xfffffff0); return ret; } static int lan78xx_set_rx_max_frame_length(struct lan78xx_net *dev, int size) Loading Loading @@ -3569,6 +3612,7 @@ static void lan78xx_disconnect(struct usb_interface *intf) struct lan78xx_net *dev; struct usb_device *udev; struct net_device *net; struct phy_device *phydev; dev = usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); Loading @@ -3577,12 +3621,16 @@ static void lan78xx_disconnect(struct usb_interface *intf) udev = interface_to_usbdev(intf); net = dev->net; phydev = net->phydev; phy_unregister_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0); phy_unregister_fixup_for_uid(PHY_LAN8835, 0xfffffff0); phy_disconnect(net->phydev); if (phy_is_pseudo_fixed_link(phydev)) fixed_phy_unregister(phydev); unregister_netdev(net); cancel_delayed_work_sync(&dev->wq); Loading