[PATCH v5 net-next 0/3] lan78xx updates along with Fixed phy Support
These series of patches handle few modifications in driver and adds support for fixed phy. Raghuram Chary J (3): lan78xx: Lan7801 Support for Fixed PHY lan78xx: Remove DRIVER_VERSION for lan78xx driver lan78xx: Modify error messages drivers/net/usb/Kconfig | 1 + drivers/net/usb/lan78xx.c | 110 -- 2 files changed, 79 insertions(+), 32 deletions(-) -- 2.16.2
[PATCH v5 net-next 1/3] lan78xx: Lan7801 Support for Fixed PHY
Adding Fixed PHY support to the lan78xx driver. Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- v0->v1: * Remove driver version #define * Modify netdev_info to netdev_dbg * Move lan7801 specific to new routine and add switch case * Minor cleanup v1->v2: * Removed fixedphy variable and used phy_is_pseudo_fixed_link() check. v2->v3: * Revert driver version, debug statment changes for separate patch. * Modify lan7801 specific routine with return type struct phy_device. v3->v4: * Modify lan7801 specific routine by removing phydev arg and get phydev. v4->v5: * Patched in latest net-next. * Also handled error condition for fixedphy. --- drivers/net/usb/Kconfig | 1 + drivers/net/usb/lan78xx.c | 104 +- 2 files changed, 77 insertions(+), 28 deletions(-) diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index f28bd74ac275..418b0904cecb 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -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. diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index c59f8afd0d73..81dfd10c3b92 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include #include "lan78xx.h" @@ -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; - } - - 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, "PHY Not Found!! Registering Fixed PHY\n"); + phydev = fixed_phy_register(PHY_POLL, _status, -1, + NULL); + if (IS_ERR(phydev)) { + netdev_err(dev->net, "No PHY/fixed_PHY found\n"); + return NULL; + } + 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 |= 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, 0xfff0, 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, 0xfff0, 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
[PATCH v5 net-next 2/3] lan78xx: Remove DRIVER_VERSION for lan78xx driver
Remove driver version info from the lan78xx driver. Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- drivers/net/usb/lan78xx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 81dfd10c3b92..54f8db887e3d 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -44,7 +44,6 @@ #define DRIVER_AUTHOR "WOOJUNG HUH <woojung@microchip.com>" #define DRIVER_DESC"LAN78XX USB 3.0 Gigabit Ethernet Devices" #define DRIVER_NAME"lan78xx" -#define DRIVER_VERSION "1.0.6" #define TX_TIMEOUT_JIFFIES (5 * HZ) #define THROTTLE_JIFFIES (HZ / 8) @@ -1503,7 +1502,6 @@ static void lan78xx_get_drvinfo(struct net_device *net, struct lan78xx_net *dev = netdev_priv(net); strncpy(info->driver, DRIVER_NAME, sizeof(info->driver)); - strncpy(info->version, DRIVER_VERSION, sizeof(info->version)); usb_make_path(dev->udev, info->bus_info, sizeof(info->bus_info)); } -- 2.16.2
[PATCH v5 net-next 3/3] lan78xx: Modify error messages
Modify the error messages when phy registration fails. Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- drivers/net/usb/lan78xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 54f8db887e3d..4b930c9faa16 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -2100,14 +2100,14 @@ static struct phy_device *lan7801_phy_init(struct lan78xx_net *dev) ret = phy_register_fixup_for_uid(PHY_KSZ9031RNX, 0xfff0, ksz9031rnx_fixup); if (ret < 0) { - netdev_err(dev->net, "fail to register fixup\n"); + netdev_err(dev->net, "fail to register fixup for PHY_KSZ9031RNX\n"); return NULL; } /* external PHY fixup for LAN8835 */ ret = phy_register_fixup_for_uid(PHY_LAN8835, 0xfff0, lan8835_fixup); if (ret < 0) { - netdev_err(dev->net, "fail to register fixup\n"); + netdev_err(dev->net, "fail to register fixup for PHY_LAN8835\n"); return NULL; } /* add more external PHY fixup here if needed */ -- 2.16.2
[PATCH v6 net-next 1/3] lan78xx: Lan7801 Support for Fixed PHY
Adding Fixed PHY support to the lan78xx driver. Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- v0->v1: * Remove driver version #define * Modify netdev_info to netdev_dbg * Move lan7801 specific to new routine and add switch case * Minor cleanup v1->v2: * Removed fixedphy variable and used phy_is_pseudo_fixed_link() check. v2->v3: * Revert driver version, debug statment changes for separate patch. * Modify lan7801 specific routine with return type struct phy_device. v3->v4: * Modify lan7801 specific routine by removing phydev arg and get phydev. v4->v5: * Patched in latest net-next. * Also handled error condition for fixedphy. --- drivers/net/usb/Kconfig | 1 + drivers/net/usb/lan78xx.c | 104 +- 2 files changed, 77 insertions(+), 28 deletions(-) diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index f28bd74ac275..418b0904cecb 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -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. diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index c59f8afd0d73..81dfd10c3b92 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include #include "lan78xx.h" @@ -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; - } - - 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, "PHY Not Found!! Registering Fixed PHY\n"); + phydev = fixed_phy_register(PHY_POLL, _status, -1, + NULL); + if (IS_ERR(phydev)) { + netdev_err(dev->net, "No PHY/fixed_PHY found\n"); + return NULL; + } + 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 |= 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, 0xfff0, 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, 0xfff0, 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
[PATCH v6 net-next 3/3] lan78xx: Modify error messages
Modify the error messages when phy registration fails. Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- v5->v6: * Modified error msg --- drivers/net/usb/lan78xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 54f8db887e3d..91761436709a 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -2100,14 +2100,14 @@ static struct phy_device *lan7801_phy_init(struct lan78xx_net *dev) ret = phy_register_fixup_for_uid(PHY_KSZ9031RNX, 0xfff0, ksz9031rnx_fixup); if (ret < 0) { - netdev_err(dev->net, "fail to register fixup\n"); + netdev_err(dev->net, "Failed to register fixup for PHY_KSZ9031RNX\n"); return NULL; } /* external PHY fixup for LAN8835 */ ret = phy_register_fixup_for_uid(PHY_LAN8835, 0xfff0, lan8835_fixup); if (ret < 0) { - netdev_err(dev->net, "fail to register fixup\n"); + netdev_err(dev->net, "Failed to register fixup for PHY_LAN8835\n"); return NULL; } /* add more external PHY fixup here if needed */ -- 2.16.2
[PATCH v6 net-next 2/3] lan78xx: Remove DRIVER_VERSION for lan78xx driver
Remove driver version info from the lan78xx driver. Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- drivers/net/usb/lan78xx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 81dfd10c3b92..54f8db887e3d 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -44,7 +44,6 @@ #define DRIVER_AUTHOR "WOOJUNG HUH <woojung@microchip.com>" #define DRIVER_DESC"LAN78XX USB 3.0 Gigabit Ethernet Devices" #define DRIVER_NAME"lan78xx" -#define DRIVER_VERSION "1.0.6" #define TX_TIMEOUT_JIFFIES (5 * HZ) #define THROTTLE_JIFFIES (HZ / 8) @@ -1503,7 +1502,6 @@ static void lan78xx_get_drvinfo(struct net_device *net, struct lan78xx_net *dev = netdev_priv(net); strncpy(info->driver, DRIVER_NAME, sizeof(info->driver)); - strncpy(info->version, DRIVER_VERSION, sizeof(info->version)); usb_make_path(dev->udev, info->bus_info, sizeof(info->bus_info)); } -- 2.16.2
[PATCH v6 net-next 0/3] lan78xx updates along with Fixed phy Support
These series of patches handle few modifications in driver and adds support for fixed phy. Raghuram Chary J (3): lan78xx: Lan7801 Support for Fixed PHY lan78xx: Remove DRIVER_VERSION for lan78xx driver lan78xx: Modify error messages drivers/net/usb/Kconfig | 1 + drivers/net/usb/lan78xx.c | 110 -- 2 files changed, 79 insertions(+), 32 deletions(-) -- 2.16.2
[PATCH v3 net-next 3/3] lan78xx: Modify error messages
Modify the error messages when phy registration fails. Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- drivers/net/usb/lan78xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 0bd973516d56..64c741f012aa 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -2039,14 +2039,14 @@ static struct phy_device *lan7801_phy_init(struct phy_device *phydev, ret = phy_register_fixup_for_uid(PHY_KSZ9031RNX, 0xfff0, ksz9031rnx_fixup); if (ret < 0) { - netdev_err(dev->net, "fail to register fixup\n"); + netdev_err(dev->net, "fail to register fixup for PHY_KSZ9031RNX\n"); return NULL; } /* external PHY fixup for LAN8835 */ ret = phy_register_fixup_for_uid(PHY_LAN8835, 0xfff0, lan8835_fixup); if (ret < 0) { - netdev_err(dev->net, "fail to register fixup\n"); + netdev_err(dev->net, "fail to register fixup for PHY_LAN8835\n"); return NULL; } /* add more external PHY fixup here if needed */ -- 2.16.2
[PATCH v3 net-next 0/3] lan78xx updates along with Fixed
These series of patches handle few modifications in driver and adds support for fixed phy. Raghuram Chary J (3): lan78xx: Lan7801 Support for Fixed PHY lan78xx: Remove DRIVER_VERSION for lan78xx driver lan78xx: Modify error messages drivers/net/usb/Kconfig | 1 + drivers/net/usb/lan78xx.c | 109 +++--- 2 files changed, 76 insertions(+), 34 deletions(-) -- 2.16.2
[PATCH v3 net-next 1/3] lan78xx: Lan7801 Support for Fixed PHY
Adding Fixed PHY support to the lan78xx driver. Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- v0->v1: * Remove driver version #define * Modify netdev_info to netdev_dbg * Move lan7801 specific to new routine and add switch case * Minor cleanup v1->v2: * Removed fixedphy variable and used phy_is_pseudo_fixed_link() check. v2->v3: * Revert driver version, debug statment changes for separate patch. * Modify lan7801 specific routine with return type struct phy_device. --- drivers/net/usb/Kconfig | 1 + drivers/net/usb/lan78xx.c | 103 -- 2 files changed, 74 insertions(+), 30 deletions(-) diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index f28bd74ac275..418b0904cecb 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -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. diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 0867f7275852..ef169d73fadc 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include "lan78xx.h" #define DRIVER_AUTHOR "WOOJUNG HUH <woojung@microchip.com>" @@ -2003,52 +2003,90 @@ 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 phy_device *phydev, + struct lan78xx_net *dev) { + u32 buf; int ret; - u32 mii_adv; - struct phy_device *phydev; + struct fixed_phy_status fphy_status = { + .link = 1, + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, + }; - phydev = phy_find_first(dev->mdiobus); if (!phydev) { - netdev_err(dev->net, "no PHY found\n"); - return -EIO; - } - - 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, "PHY Not Found!! Registering Fixed PHY\n"); + phydev = fixed_phy_register(PHY_POLL, _status, -1, + NULL); + if (IS_ERR(phydev)) { + netdev_err(dev->net, "No PHY/fixed_PHY found\n"); + return NULL; + } + 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 |= 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, 0xfff0, 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, 0xfff0, 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
[PATCH v3 net-next 2/3] lan78xx: Remove DRIVER_VERSION for lan78xx driver
Remove driver version info from the lan78xx driver. Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- drivers/net/usb/lan78xx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index ef169d73fadc..0bd973516d56 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -42,7 +42,6 @@ #define DRIVER_AUTHOR "WOOJUNG HUH <woojung@microchip.com>" #define DRIVER_DESC"LAN78XX USB 3.0 Gigabit Ethernet Devices" #define DRIVER_NAME"lan78xx" -#define DRIVER_VERSION "1.0.6" #define TX_TIMEOUT_JIFFIES (5 * HZ) #define THROTTLE_JIFFIES (HZ / 8) @@ -1477,7 +1476,6 @@ static void lan78xx_get_drvinfo(struct net_device *net, struct lan78xx_net *dev = netdev_priv(net); strncpy(info->driver, DRIVER_NAME, sizeof(info->driver)); - strncpy(info->version, DRIVER_VERSION, sizeof(info->version)); usb_make_path(dev->udev, info->bus_info, sizeof(info->bus_info)); } -- 2.16.2
[PATCH v3 net-next] lan78xx: Lan7801 Support for Fixed PHY
Adding Fixed PHY support to the lan78xx driver. Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- v0->v1: * Remove driver version #define * Modify netdev_info to netdev_dbg * Move lan7801 specific to new routine and add switch case * Minor cleanup v1->v2: * Removed fixedphy variable and used phy_is_pseudo_fixed_link() check. v2->v3: * Revert driver version, debug statment changes for separate patch. * Modify lan7801 specific routine with return type struct phy_device. --- drivers/net/usb/Kconfig | 1 + drivers/net/usb/lan78xx.c | 103 -- 2 files changed, 74 insertions(+), 30 deletions(-) diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index f28bd74ac275..418b0904cecb 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -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. diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 0867f7275852..ef169d73fadc 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include "lan78xx.h" #define DRIVER_AUTHOR "WOOJUNG HUH <woojung@microchip.com>" @@ -2003,52 +2003,90 @@ 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 phy_device *phydev, + struct lan78xx_net *dev) { + u32 buf; int ret; - u32 mii_adv; - struct phy_device *phydev; + struct fixed_phy_status fphy_status = { + .link = 1, + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, + }; - phydev = phy_find_first(dev->mdiobus); if (!phydev) { - netdev_err(dev->net, "no PHY found\n"); - return -EIO; - } - - 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, "PHY Not Found!! Registering Fixed PHY\n"); + phydev = fixed_phy_register(PHY_POLL, _status, -1, + NULL); + if (IS_ERR(phydev)) { + netdev_err(dev->net, "No PHY/fixed_PHY found\n"); + return NULL; + } + 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 |= 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, 0xfff0, 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, 0xfff0, 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
[PATCH v4 net-next 2/3] lan78xx: Remove DRIVER_VERSION for lan78xx driver
Remove driver version info from the lan78xx driver. Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- drivers/net/usb/lan78xx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index cb35cfa20ca0..5da5f0e3cd21 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -42,7 +42,6 @@ #define DRIVER_AUTHOR "WOOJUNG HUH <woojung@microchip.com>" #define DRIVER_DESC"LAN78XX USB 3.0 Gigabit Ethernet Devices" #define DRIVER_NAME"lan78xx" -#define DRIVER_VERSION "1.0.6" #define TX_TIMEOUT_JIFFIES (5 * HZ) #define THROTTLE_JIFFIES (HZ / 8) @@ -1477,7 +1476,6 @@ static void lan78xx_get_drvinfo(struct net_device *net, struct lan78xx_net *dev = netdev_priv(net); strncpy(info->driver, DRIVER_NAME, sizeof(info->driver)); - strncpy(info->version, DRIVER_VERSION, sizeof(info->version)); usb_make_path(dev->udev, info->bus_info, sizeof(info->bus_info)); } -- 2.16.2
[PATCH v4 net-next 1/3] lan78xx: Lan7801 Support for Fixed PHY
Adding Fixed PHY support to the lan78xx driver. Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- v0->v1: * Remove driver version #define * Modify netdev_info to netdev_dbg * Move lan7801 specific to new routine and add switch case * Minor cleanup v1->v2: * Removed fixedphy variable and used phy_is_pseudo_fixed_link() check. v2->v3: * Revert driver version, debug statment changes for separate patch. * Modify lan7801 specific routine with return type struct phy_device. v3->v4: * Modify lan7801 specific routine by removing phydev arg and get phydev. --- drivers/net/usb/Kconfig | 1 + drivers/net/usb/lan78xx.c | 100 +- 2 files changed, 73 insertions(+), 28 deletions(-) diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index f28bd74ac275..418b0904cecb 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -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. diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 0867f7275852..cb35cfa20ca0 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include "lan78xx.h" #define DRIVER_AUTHOR "WOOJUNG HUH <woojung@microchip.com>" @@ -2003,52 +2003,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; - } - - 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, "PHY Not Found!! Registering Fixed PHY\n"); + phydev = fixed_phy_register(PHY_POLL, _status, -1, + NULL); + if (IS_ERR(phydev)) { + netdev_err(dev->net, "No PHY/fixed_PHY found\n"); + return NULL; + } + 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 |= 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, 0xfff0, 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, 0xfff0, 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
[PATCH v4 net-next 3/3] lan78xx: Modify error messages
Modify the error messages when phy registration fails. Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- drivers/net/usb/lan78xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 5da5f0e3cd21..525bb4bf1975 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -2040,14 +2040,14 @@ static struct phy_device *lan7801_phy_init(struct lan78xx_net *dev) ret = phy_register_fixup_for_uid(PHY_KSZ9031RNX, 0xfff0, ksz9031rnx_fixup); if (ret < 0) { - netdev_err(dev->net, "fail to register fixup\n"); + netdev_err(dev->net, "fail to register fixup for PHY_KSZ9031RNX\n"); return NULL; } /* external PHY fixup for LAN8835 */ ret = phy_register_fixup_for_uid(PHY_LAN8835, 0xfff0, lan8835_fixup); if (ret < 0) { - netdev_err(dev->net, "fail to register fixup\n"); + netdev_err(dev->net, "fail to register fixup for PHY_LAN8835\n"); return NULL; } /* add more external PHY fixup here if needed */ -- 2.16.2
[PATCH v4 net-next 0/3] lan78xx updates along with Fixed phy Support
These series of patches handle few modifications in driver and adds support for fixed phy. Raghuram Chary J (3): lan78xx: Lan7801 Support for Fixed PHY lan78xx: Remove DRIVER_VERSION for lan78xx driver lan78xx: Modify error messages drivers/net/usb/Kconfig | 1 + drivers/net/usb/lan78xx.c | 106 -- 2 files changed, 75 insertions(+), 32 deletions(-) -- 2.16.2
[PATCH ethtool] ethtool: Add register dump support for MICROCHIP LAN78xx
This patch adds support for Microchip's lan78xx families of USB Ethernet controllers to ethtool's dump registers command. This patch is for use with the lan78xx driver. Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- Makefile.am | 2 +- ethtool.c | 1 + internal.h | 4 +++ lan78xx.c | 87 + 4 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 lan78xx.c diff --git a/Makefile.am b/Makefile.am index edbda57..14f79b6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -14,7 +14,7 @@ ethtool_SOURCES += \ pcnet32.c realtek.c tg3.c marvell.c vioc.c\ smsc911x.c at76c50x-usb.c sfc.c stmmac.c \ sff-common.c sff-common.h sfpid.c sfpdiag.c \ - ixgbevf.c tse.c vmxnet3.c qsfp.c qsfp.h fjes.c + ixgbevf.c tse.c vmxnet3.c qsfp.c qsfp.h fjes.c lan78xx.c endif TESTS = test-cmdline test-features diff --git a/ethtool.c b/ethtool.c index da7421c..3494402 100644 --- a/ethtool.c +++ b/ethtool.c @@ -1160,6 +1160,7 @@ static const struct { { "altera_tse", altera_tse_dump_regs }, { "vmxnet3", vmxnet3_dump_regs }, { "fjes", fjes_dump_regs }, + { "lan78xx", lan78xx_dump_regs }, #endif }; diff --git a/internal.h b/internal.h index 913f4eb..b239dc7 100644 --- a/internal.h +++ b/internal.h @@ -350,4 +350,8 @@ void sff8636_show_all(const __u8 *id, __u32 eeprom_len); /* FUJITSU Extended Socket network device */ int fjes_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* MICROCHIP LAN78XX USB ETHERNET Controller */ +int lan78xx_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + #endif /* ETHTOOL_INTERNAL_H__ */ diff --git a/lan78xx.c b/lan78xx.c new file mode 100644 index 000..bb64e80 --- /dev/null +++ b/lan78xx.c @@ -0,0 +1,87 @@ +#include +#include +#include "internal.h" + +int lan78xx_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs) +{ + unsigned int *lan78xx_reg = (unsigned int *)regs->data; + + fprintf(stdout, "LAN78xx Registers:\n"); + fprintf(stdout, "--\n"); + fprintf(stdout, "ID_REV = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "INT_STS = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "HW_CFG = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "PMT_CTRL = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "E2P_CMD = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "E2P_DATA = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "USB_STATUS = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "VLAN_TYPE= 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "\n"); + + fprintf(stdout, "MAC Registers:\n"); + fprintf(stdout, "--\n"); + fprintf(stdout, "MAC_CR = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "MAC_RX = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "MAC_TX = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "FLOW = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "ERR_STS= 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "MII_ACC= 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "MII_DATA = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "EEE_TX_LPI_REQ_DLY = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "EEE_TW_TX_SYS = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "EEE_TX_LPI_REM_DLY = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "WUCSR = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "\n"); + + fprintf(stdout, "PHY Registers:\n"); + fprintf(stdout, "--\n"); + fprintf(stdout, "Mode Control = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "Mode Status = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "Device identifier1 = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "Device identifier2 = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "Auto-Neg Advertisement = 0x%04X\n", + *lan78xx_reg++); + fprintf(stdout, "Auto-Neg Link Partner Ability = 0x%04X\n", + *lan78xx_reg++); + fprintf(stdout, "Auto-Neg Expansion = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "Auto-Neg Next Page TX = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "Auto-Neg Link Partner Next Page RX = 0x%04X\n", + *lan78xx_reg++); +
[PATCH v1 net 3/3] lan78xx: Lan7801 Support for Fixed PHY
Adding Fixed PHY support to the lan78xx driver. Fixes: 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to 10/100/1000 Ethernet device driver") Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- drivers/net/usb/Kconfig | 1 + drivers/net/usb/lan78xx.c | 42 ++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index f28bd74ac275..418b0904cecb 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -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. diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index cbeec784f8b8..0c87ac1b767f 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include "lan78xx.h" #define DRIVER_AUTHOR "WOOJUNG HUH <woojung@microchip.com>" @@ -426,6 +426,7 @@ struct lan78xx_net { struct statstagestats; struct irq_domain_data domain_data; + struct phy_device *fixedphy; }; /* define external phy id */ @@ -2061,11 +2062,39 @@ static int lan78xx_phy_init(struct lan78xx_net *dev) int ret; u32 mii_adv; struct phy_device *phydev; + struct fixed_phy_status fphy_status = { + .link = 1, + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, + }; phydev = phy_find_first(dev->mdiobus); if (!phydev) { - netdev_err(dev->net, "no PHY found\n"); - return -EIO; + if (dev->chipid == ID_REV_CHIP_ID_7801_) { + u32 buf; + + netdev_info(dev->net, "PHY Not Found!! Registering Fixed PHY\n"); + phydev = fixed_phy_register(PHY_POLL, _status, -1, + NULL); + if (IS_ERR(phydev)) { + netdev_err(dev->net, "No PHY/fixed_PHY found\n"); + return -ENODEV; + } + netdev_info(dev->net, "Registered FIXED PHY\n"); + dev->interface = PHY_INTERFACE_MODE_RGMII; + dev->fixedphy = phydev; + 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 |= HW_CFG_CLK125_EN_; + buf |= HW_CFG_REFCLK25_EN_; + ret = lan78xx_write_reg(dev, HW_CFG, buf); + goto phyinit; + } else { + netdev_err(dev->net, "no PHY found\n"); + return -EIO; + } } if ((dev->chipid == ID_REV_CHIP_ID_7800_) || @@ -2103,7 +2132,7 @@ static int lan78xx_phy_init(struct lan78xx_net *dev) ret = -EIO; goto error; } - +phyinit: /* if phyirq is not set, use polling mode in phylib */ if (dev->domain_data.phyirq > 0) phydev->irq = dev->domain_data.phyirq; @@ -3562,6 +3591,11 @@ static void lan78xx_disconnect(struct usb_interface *intf) udev = interface_to_usbdev(intf); net = dev->net; + + if (dev->fixedphy) { + fixed_phy_unregister(dev->fixedphy); + dev->fixedphy = NULL; + } unregister_netdev(net); cancel_delayed_work_sync(>wq); -- 2.16.2
[PATCH v1 net 2/3] lan78xx: Add support to dump lan78xx registers
In order to dump lan78xx family registers using ethtool, add support at lan78xx driver level. Fixes: 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to 10/100/1000 Ethernet device driver") Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- v0->v1: * Return device regs len if phydev is null. --- drivers/net/usb/lan78xx.c | 54 +++ 1 file changed, 54 insertions(+) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 55a78eb96961..cbeec784f8b8 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -278,6 +278,30 @@ struct lan78xx_statstage64 { u64 eee_tx_lpi_time; }; +u32 lan78xx_regs[] = { + ID_REV, + INT_STS, + HW_CFG, + PMT_CTL, + E2P_CMD, + E2P_DATA, + USB_STATUS, + VLAN_TYPE, + MAC_CR, + MAC_RX, + MAC_TX, + FLOW, + ERR_STS, + MII_ACC, + MII_DATA, + EEE_TX_LPI_REQ_DLY, + EEE_TW_TX_SYS, + EEE_TX_LPI_REM_DLY, + WUCSR +}; + +#define PHY_REG_SIZE (32 * sizeof(u32)) + struct lan78xx_net; struct lan78xx_priv { @@ -1604,6 +1628,34 @@ static int lan78xx_set_pause(struct net_device *net, return ret; } +static int lan78xx_get_regs_len(struct net_device *netdev) +{ + if (!netdev->phydev) + return (sizeof(lan78xx_regs)); + else + return (sizeof(lan78xx_regs) + PHY_REG_SIZE); +} + +static void +lan78xx_get_regs(struct net_device *netdev, struct ethtool_regs *regs, +void *buf) +{ + u32 *data = buf; + int i, j; + struct lan78xx_net *dev = netdev_priv(netdev); + + /* Read Device/MAC registers */ + for (i = 0, j = 0; i < (sizeof(lan78xx_regs) / sizeof(u32)); i++, j++) + lan78xx_read_reg(dev, lan78xx_regs[i], [j]); + + if (!netdev->phydev) + return; + + /* Read PHY registers */ + for (i = 0; i < 32; i++, j++) + data[j] = phy_read(netdev->phydev, i); +} + static const struct ethtool_ops lan78xx_ethtool_ops = { .get_link = lan78xx_get_link, .nway_reset = phy_ethtool_nway_reset, @@ -1624,6 +1676,8 @@ static const struct ethtool_ops lan78xx_ethtool_ops = { .set_pauseparam = lan78xx_set_pause, .get_link_ksettings = lan78xx_get_link_ksettings, .set_link_ksettings = lan78xx_set_link_ksettings, + .get_regs_len = lan78xx_get_regs_len, + .get_regs = lan78xx_get_regs, }; static int lan78xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) -- 2.16.2
[PATCH v1 net 1/3] lan78xx: PHY DSP registers initialization to address EEE link drop issues with long cables
The patch is to configure DSP registers of PHY device to handle Gbe-EEE failures with >40m cable length. Fixes: 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to 10/100/1000 Ethernet device driver") Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- v0->v1: * Use phy_save_page to save current page before switching to TR page. * Use phy_restore_page to restore saved page. * Add read_page and write_page callbacks. * __phy_read, __phy_write to read,write phy registers. * Handle error conditions. --- drivers/net/phy/microchip.c | 178 ++- include/linux/microchipphy.h | 8 ++ 2 files changed, 185 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/microchip.c b/drivers/net/phy/microchip.c index 0f293ef28935..4a8e91922eaa 100644 --- a/drivers/net/phy/microchip.c +++ b/drivers/net/phy/microchip.c @@ -20,6 +20,7 @@ #include #include #include +#include #define DRIVER_AUTHOR "WOOJUNG HUH <woojung@microchip.com>" #define DRIVER_DESC"Microchip LAN88XX PHY driver" @@ -30,6 +31,16 @@ struct lan88xx_priv { __u32 wolopts; }; +static int lan88xx_read_page(struct phy_device *phydev) +{ + return __phy_read(phydev, LAN88XX_EXT_PAGE_ACCESS); +} + +static int lan88xx_write_page(struct phy_device *phydev, int page) +{ + return __phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, page); +} + static int lan88xx_phy_config_intr(struct phy_device *phydev) { int rc; @@ -66,6 +77,150 @@ static int lan88xx_suspend(struct phy_device *phydev) return 0; } +static int lan88xx_TR_reg_set(struct phy_device *phydev, u16 regaddr, + u32 data) +{ + int val, save_page, ret = 0; + u16 buf; + + /* Save current page */ + save_page = phy_save_page(phydev); + if (save_page < 0) { + pr_warn("Failed to get current page\n"); + goto err; + } + + /* Switch to TR page */ + lan88xx_write_page(phydev, LAN88XX_EXT_PAGE_ACCESS_TR); + + ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_LOW_DATA, + (data & 0x)); + if (ret < 0) { + pr_warn("Failed to write TR low data\n"); + goto err; + } + + ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_HIGH_DATA, + (data & 0x00FF) >> 16); + if (ret < 0) { + pr_warn("Failed to write TR high data\n"); + goto err; + } + + /* Config control bits [15:13] of register */ + buf = (regaddr & ~(0x3 << 13));/* Clr [14:13] to write data in reg */ + buf |= 0x8000; /* Set [15] to Packet transmit */ + + ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_CR, buf); + if (ret < 0) { + pr_warn("Failed to write data in reg\n"); + goto err; + } + + usleep_range(1000, 2000);/* Wait for Data to be written */ + val = __phy_read(phydev, LAN88XX_EXT_PAGE_TR_CR); + if (!(val & 0x8000)) + pr_warn("TR Register[0x%X] configuration failed\n", regaddr); +err: + return phy_restore_page(phydev, save_page, ret); +} + +static void lan88xx_config_TR_regs(struct phy_device *phydev) +{ + int err; + + /* Get access to Channel 0x1, Node 0xF , Register 0x01. +* Write 24-bit value 0x12B00A to register. Setting MrvlTrFix1000Kf, +* MrvlTrFix1000Kp, MasterEnableTR bits. +*/ + err = lan88xx_TR_reg_set(phydev, 0x0F82, 0x12B00A); + if (err < 0) + pr_warn("Failed to Set Register[0x0F82]\n"); + + /* Get access to Channel b'10, Node b'1101, Register 0x06. +* Write 24-bit value 0xD2C46F to register. Setting SSTrKf1000Slv, +* SSTrKp1000Mas bits. +*/ + err = lan88xx_TR_reg_set(phydev, 0x168C, 0xD2C46F); + if (err < 0) + pr_warn("Failed to Set Register[0x168C]\n"); + + /* Get access to Channel b'10, Node b', Register 0x11. +* Write 24-bit value 0x620 to register. Setting rem_upd_done_thresh +* bits +*/ + err = lan88xx_TR_reg_set(phydev, 0x17A2, 0x620); + if (err < 0) + pr_warn("Failed to Set Register[0x17A2]\n"); + + /* Get access to Channel b'10, Node b'1101, Register 0x10. +* Write 24-bit value 0xEEFFDD to register. Setting +* eee_TrKp1Long_1000, eee_TrKp2Long_1000, eee_TrKp3Long_1000, +* eee_TrKp1Short_1000,eee_TrKp2Short_1000, eee_TrKp3Short_1000 bits. +*/ + err = lan88xx_TR_reg_set(phydev, 0x16A0, 0xEEFFDD); + if (err < 0) + pr_warn("Failed to Set Register[0x16A0]\n"); + + /* Get access to Channel b'10, Node b'1101, Register 0x13. +* Write 24
[PATCH v1 net 0/3] lan78xx: Fixes and enhancements
These series of patches have fix and enhancements for lan78xx driver. Raghuram Chary J (3): lan78xx: PHY DSP registers initialization to address EEE link drop issues with long cables lan78xx: Add support to dump lan78xx registers lan78xx: Lan7801 Support for Fixed PHY drivers/net/phy/microchip.c | 178 ++- drivers/net/usb/Kconfig | 1 + drivers/net/usb/lan78xx.c| 96 ++- include/linux/microchipphy.h | 8 ++ 4 files changed, 278 insertions(+), 5 deletions(-) -- 2.16.2
[PATCH v2 net] lan78xx: PHY DSP registers initialization to address EEE link drop issues with long cables
The patch is to configure DSP registers of PHY device to handle Gbe-EEE failures with >40m cable length. Fixes: 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to 10/100/1000 Ethernet device driver") Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- v0->v1: * Use phy_save_page to save current page before switching to TR page. * Use phy_restore_page to restore saved page. * Add read_page and write_page callbacks. * __phy_read, __phy_write to read,write phy registers. * Handle error conditions. v1->v2: * Sending the patch to net separately from enhancements. --- drivers/net/phy/microchip.c | 178 ++- include/linux/microchipphy.h | 8 ++ 2 files changed, 185 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/microchip.c b/drivers/net/phy/microchip.c index 0f293ef28935..4a8e91922eaa 100644 --- a/drivers/net/phy/microchip.c +++ b/drivers/net/phy/microchip.c @@ -20,6 +20,7 @@ #include #include #include +#include #define DRIVER_AUTHOR "WOOJUNG HUH <woojung@microchip.com>" #define DRIVER_DESC"Microchip LAN88XX PHY driver" @@ -30,6 +31,16 @@ struct lan88xx_priv { __u32 wolopts; }; +static int lan88xx_read_page(struct phy_device *phydev) +{ + return __phy_read(phydev, LAN88XX_EXT_PAGE_ACCESS); +} + +static int lan88xx_write_page(struct phy_device *phydev, int page) +{ + return __phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, page); +} + static int lan88xx_phy_config_intr(struct phy_device *phydev) { int rc; @@ -66,6 +77,150 @@ static int lan88xx_suspend(struct phy_device *phydev) return 0; } +static int lan88xx_TR_reg_set(struct phy_device *phydev, u16 regaddr, + u32 data) +{ + int val, save_page, ret = 0; + u16 buf; + + /* Save current page */ + save_page = phy_save_page(phydev); + if (save_page < 0) { + pr_warn("Failed to get current page\n"); + goto err; + } + + /* Switch to TR page */ + lan88xx_write_page(phydev, LAN88XX_EXT_PAGE_ACCESS_TR); + + ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_LOW_DATA, + (data & 0x)); + if (ret < 0) { + pr_warn("Failed to write TR low data\n"); + goto err; + } + + ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_HIGH_DATA, + (data & 0x00FF) >> 16); + if (ret < 0) { + pr_warn("Failed to write TR high data\n"); + goto err; + } + + /* Config control bits [15:13] of register */ + buf = (regaddr & ~(0x3 << 13));/* Clr [14:13] to write data in reg */ + buf |= 0x8000; /* Set [15] to Packet transmit */ + + ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_CR, buf); + if (ret < 0) { + pr_warn("Failed to write data in reg\n"); + goto err; + } + + usleep_range(1000, 2000);/* Wait for Data to be written */ + val = __phy_read(phydev, LAN88XX_EXT_PAGE_TR_CR); + if (!(val & 0x8000)) + pr_warn("TR Register[0x%X] configuration failed\n", regaddr); +err: + return phy_restore_page(phydev, save_page, ret); +} + +static void lan88xx_config_TR_regs(struct phy_device *phydev) +{ + int err; + + /* Get access to Channel 0x1, Node 0xF , Register 0x01. +* Write 24-bit value 0x12B00A to register. Setting MrvlTrFix1000Kf, +* MrvlTrFix1000Kp, MasterEnableTR bits. +*/ + err = lan88xx_TR_reg_set(phydev, 0x0F82, 0x12B00A); + if (err < 0) + pr_warn("Failed to Set Register[0x0F82]\n"); + + /* Get access to Channel b'10, Node b'1101, Register 0x06. +* Write 24-bit value 0xD2C46F to register. Setting SSTrKf1000Slv, +* SSTrKp1000Mas bits. +*/ + err = lan88xx_TR_reg_set(phydev, 0x168C, 0xD2C46F); + if (err < 0) + pr_warn("Failed to Set Register[0x168C]\n"); + + /* Get access to Channel b'10, Node b', Register 0x11. +* Write 24-bit value 0x620 to register. Setting rem_upd_done_thresh +* bits +*/ + err = lan88xx_TR_reg_set(phydev, 0x17A2, 0x620); + if (err < 0) + pr_warn("Failed to Set Register[0x17A2]\n"); + + /* Get access to Channel b'10, Node b'1101, Register 0x10. +* Write 24-bit value 0xEEFFDD to register. Setting +* eee_TrKp1Long_1000, eee_TrKp2Long_1000, eee_TrKp3Long_1000, +* eee_TrKp1Short_1000,eee_TrKp2Short_1000, eee_TrKp3Short_1000 bits. +*/ + err = lan88xx_TR_reg_set(phydev, 0x16A0, 0xEEFFDD); + if (err < 0) + pr_warn("Failed to Set Register[0x16A0]\n"); + + /* Get
[PATCH net 1/3] lan78xx: PHY DSP registers initialization to address EEE link drop issues with long cables
The patch is to configure DSP registers of PHY device to handle Gbe-EEE failures with >40m cable length. Fixes: 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to 10/100/1000 Ethernet device driver") Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- drivers/net/phy/microchip.c | 123 ++- include/linux/microchipphy.h | 8 +++ 2 files changed, 130 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/microchip.c b/drivers/net/phy/microchip.c index 0f293ef28935..174ae9808722 100644 --- a/drivers/net/phy/microchip.c +++ b/drivers/net/phy/microchip.c @@ -20,6 +20,7 @@ #include #include #include +#include #define DRIVER_AUTHOR "WOOJUNG HUH <woojung@microchip.com>" #define DRIVER_DESC"Microchip LAN88XX PHY driver" @@ -66,6 +67,107 @@ static int lan88xx_suspend(struct phy_device *phydev) return 0; } +static void lan88xx_TR_reg_set(struct phy_device *phydev, u16 regaddr, + u32 data) +{ + int val; + u16 buf; + + /* Get access to token ring page */ + phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, + LAN88XX_EXT_PAGE_ACCESS_TR); + + phy_write(phydev, LAN88XX_EXT_PAGE_TR_LOW_DATA, (data & 0x)); + phy_write(phydev, LAN88XX_EXT_PAGE_TR_HIGH_DATA, + (data & 0x00FF) >> 16); + + /* Config control bits [15:13] of register */ + buf = (regaddr & ~(0x3 << 13));/* Clr [14:13] to write data in reg */ + buf |= 0x8000; /* Set [15] to Packet transmit */ + + phy_write(phydev, LAN88XX_EXT_PAGE_TR_CR, buf); + + usleep_range(1000, 2000);/* Wait for Data to be written */ + val = phy_read(phydev, LAN88XX_EXT_PAGE_TR_CR); + if (!(val & 0x8000)) + pr_warn("TR Register[0x%X] configuration failed\n", regaddr); + + /* Setting to Main page registers space*/ + phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, LAN88XX_EXT_PAGE_SPACE_0); +} + +static void lan88xx_config_TR_regs(struct phy_device *phydev) +{ + /* Get access to Channel 0x1, Node 0xF , Register 0x01. +* Write 24-bit value 0x12B00A to register. Setting MrvlTrFix1000Kf, +* MrvlTrFix1000Kp, MasterEnableTR bits. +*/ + lan88xx_TR_reg_set(phydev, 0x0F82, 0x12B00A); + + /* Get access to Channel b'10, Node b'1101, Register 0x06. +* Write 24-bit value 0xD2C46F to register. Setting SSTrKf1000Slv, +* SSTrKp1000Mas bits. +*/ + lan88xx_TR_reg_set(phydev, 0x168C, 0xD2C46F); + + /* Get access to Channel b'10, Node b', Register 0x11. +* Write 24-bit value 0x620 to register. Setting rem_upd_done_thresh +* bits +*/ + lan88xx_TR_reg_set(phydev, 0x17A2, 0x620); + + /* Get access to Channel b'10, Node b'1101, Register 0x10. +* Write 24-bit value 0xEEFFDD to register. Setting +* eee_TrKp1Long_1000, eee_TrKp2Long_1000, eee_TrKp3Long_1000, +* eee_TrKp1Short_1000,eee_TrKp2Short_1000, eee_TrKp3Short_1000 bits. +*/ + lan88xx_TR_reg_set(phydev, 0x16A0, 0xEEFFDD); + + /* Get access to Channel b'10, Node b'1101, Register 0x13. +* Write 24-bit value 0x071448 to register. Setting +* slv_lpi_tr_tmr_val1, slv_lpi_tr_tmr_val2 bits. +*/ + lan88xx_TR_reg_set(phydev, 0x16A6, 0x071448); + + /* Get access to Channel b'10, Node b'1101, Register 0x12. +* Write 24-bit value 0x13132F to register. Setting +* slv_sigdet_timer_val1, slv_sigdet_timer_val2 bits. +*/ + lan88xx_TR_reg_set(phydev, 0x16A4, 0x13132F); + + /* Get access to Channel b'10, Node b'1101, Register 0x14. +* Write 24-bit value 0x0 to register. Setting eee_3level_delay, +* eee_TrKf_freeze_delay bits. +*/ + lan88xx_TR_reg_set(phydev, 0x16A8, 0x0); + + /* Get access to Channel b'01, Node b', Register 0x34. +* Write 24-bit value 0x91B06C to register. Setting +* FastMseSearchThreshLong1000, FastMseSearchThreshShort1000, +* FastMseSearchUpdGain1000 bits. +*/ + lan88xx_TR_reg_set(phydev, 0x0FE8, 0x91B06C); + + /* Get access to Channel b'01, Node b', Register 0x3E. +* Write 24-bit value 0xC0A028 to register. Setting +* FastMseKp2ThreshLong1000, FastMseKp2ThreshShort1000, +* FastMseKp2UpdGain1000, FastMseKp2ExitEn1000 bits. +*/ + lan88xx_TR_reg_set(phydev, 0x0FFC, 0xC0A028); + + /* Get access to Channel b'01, Node b', Register 0x35. +* Write 24-bit value 0x041600 to register. Setting +* FastMseSearchPhShNum1000, FastMseSearchClksPerPh1000, +* FastMsePhChangeDelay1000 bits. +*/ + lan88xx_TR_reg_set(phydev, 0x0FEA, 0x041600); + + /* Get access to Channel b'10, Node b'1101, Register 0x03. +* Write 24-bit value
[PATCH net 0/3] lan78xx: Fixes and enhancements
These series of patches have fix and enhancements for lan78xx driver. Raghuram Chary J (3): lan78xx: PHY DSP registers initialization to address EEE link drop issues with long cables lan78xx: Add support to dump lan78xx registers lan78xx: Lan7801 Support for Fixed PHY drivers/net/phy/microchip.c | 123 ++- drivers/net/usb/Kconfig | 1 + drivers/net/usb/lan78xx.c| 93 ++-- include/linux/microchipphy.h | 8 +++ 4 files changed, 220 insertions(+), 5 deletions(-) -- 2.16.2
[PATCH net 2/3] lan78xx: Add support to dump lan78xx registers
In order to dump lan78xx family registers using ethtool, add support at lan78xx driver level. Fixes: 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to 10/100/1000 Ethernet device driver") Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- drivers/net/usb/lan78xx.c | 51 +++ 1 file changed, 51 insertions(+) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 55a78eb96961..e3cc3b504c87 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -278,6 +278,30 @@ struct lan78xx_statstage64 { u64 eee_tx_lpi_time; }; +u32 lan78xx_regs[] = { + ID_REV, + INT_STS, + HW_CFG, + PMT_CTL, + E2P_CMD, + E2P_DATA, + USB_STATUS, + VLAN_TYPE, + MAC_CR, + MAC_RX, + MAC_TX, + FLOW, + ERR_STS, + MII_ACC, + MII_DATA, + EEE_TX_LPI_REQ_DLY, + EEE_TW_TX_SYS, + EEE_TX_LPI_REM_DLY, + WUCSR +}; + +#define PHY_REG_SIZE (32 * sizeof(u32)) + struct lan78xx_net; struct lan78xx_priv { @@ -1604,6 +1628,31 @@ static int lan78xx_set_pause(struct net_device *net, return ret; } +static int lan78xx_get_regs_len(struct net_device *netdev) +{ + return (sizeof(lan78xx_regs) + PHY_REG_SIZE); +} + +static void +lan78xx_get_regs(struct net_device *netdev, struct ethtool_regs *regs, +void *buf) +{ + u32 *data = buf; + int i, j; + struct lan78xx_net *dev = netdev_priv(netdev); + + /* Read Device/MAC registers */ + for (i = 0, j = 0; i < (sizeof(lan78xx_regs) / sizeof(u32)); i++, j++) + lan78xx_read_reg(dev, lan78xx_regs[i], [j]); + + if (!netdev->phydev) + return; + + /* Read PHY registers */ + for (i = 0; i < 32; i++, j++) + data[j] = phy_read(netdev->phydev, i); +} + static const struct ethtool_ops lan78xx_ethtool_ops = { .get_link = lan78xx_get_link, .nway_reset = phy_ethtool_nway_reset, @@ -1624,6 +1673,8 @@ static const struct ethtool_ops lan78xx_ethtool_ops = { .set_pauseparam = lan78xx_set_pause, .get_link_ksettings = lan78xx_get_link_ksettings, .set_link_ksettings = lan78xx_set_link_ksettings, + .get_regs_len = lan78xx_get_regs_len, + .get_regs = lan78xx_get_regs, }; static int lan78xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) -- 2.16.2
[PATCH net 3/3] lan78xx: Lan7801 Support for Fixed PHY
Adding Fixed PHY support to the lan78xx driver. Fixes: 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to 10/100/1000 Ethernet device driver") Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- drivers/net/usb/Kconfig | 1 + drivers/net/usb/lan78xx.c | 42 ++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index f28bd74ac275..418b0904cecb 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -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. diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index e3cc3b504c87..e67b2dabde66 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include "lan78xx.h" #define DRIVER_AUTHOR "WOOJUNG HUH <woojung@microchip.com>" @@ -426,6 +426,7 @@ struct lan78xx_net { struct statstagestats; struct irq_domain_data domain_data; + struct phy_device *fixedphy; }; /* define external phy id */ @@ -2058,11 +2059,39 @@ static int lan78xx_phy_init(struct lan78xx_net *dev) int ret; u32 mii_adv; struct phy_device *phydev; + struct fixed_phy_status fphy_status = { + .link = 1, + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, + }; phydev = phy_find_first(dev->mdiobus); if (!phydev) { - netdev_err(dev->net, "no PHY found\n"); - return -EIO; + if (dev->chipid == ID_REV_CHIP_ID_7801_) { + u32 buf; + + netdev_info(dev->net, "PHY Not Found!! Registering Fixed PHY\n"); + phydev = fixed_phy_register(PHY_POLL, _status, -1, + NULL); + if (IS_ERR(phydev)) { + netdev_err(dev->net, "No PHY/fixed_PHY found\n"); + return -ENODEV; + } + netdev_info(dev->net, "Registered FIXED PHY\n"); + dev->interface = PHY_INTERFACE_MODE_RGMII; + dev->fixedphy = phydev; + 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 |= HW_CFG_CLK125_EN_; + buf |= HW_CFG_REFCLK25_EN_; + ret = lan78xx_write_reg(dev, HW_CFG, buf); + goto phyinit; + } else { + netdev_err(dev->net, "no PHY found\n"); + return -EIO; + } } if ((dev->chipid == ID_REV_CHIP_ID_7800_) || @@ -2100,7 +2129,7 @@ static int lan78xx_phy_init(struct lan78xx_net *dev) ret = -EIO; goto error; } - +phyinit: /* if phyirq is not set, use polling mode in phylib */ if (dev->domain_data.phyirq > 0) phydev->irq = dev->domain_data.phyirq; @@ -3559,6 +3588,11 @@ static void lan78xx_disconnect(struct usb_interface *intf) udev = interface_to_usbdev(intf); net = dev->net; + + if (dev->fixedphy) { + fixed_phy_unregister(dev->fixedphy); + dev->fixedphy = NULL; + } unregister_netdev(net); cancel_delayed_work_sync(>wq); -- 2.16.2
[PATCH net-next] lan78xx: Add support to dump lan78xx registers
In order to dump lan78xx family registers using ethtool, add support at lan78xx driver level. Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- drivers/net/usb/lan78xx.c | 54 +++ 1 file changed, 54 insertions(+) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 0867f7275852..e846698fa32a 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -278,6 +278,30 @@ struct lan78xx_statstage64 { u64 eee_tx_lpi_time; }; +static u32 lan78xx_regs[] = { + ID_REV, + INT_STS, + HW_CFG, + PMT_CTL, + E2P_CMD, + E2P_DATA, + USB_STATUS, + VLAN_TYPE, + MAC_CR, + MAC_RX, + MAC_TX, + FLOW, + ERR_STS, + MII_ACC, + MII_DATA, + EEE_TX_LPI_REQ_DLY, + EEE_TW_TX_SYS, + EEE_TX_LPI_REM_DLY, + WUCSR +}; + +#define PHY_REG_SIZE (32 * sizeof(u32)) + struct lan78xx_net; struct lan78xx_priv { @@ -1605,6 +1629,34 @@ static int lan78xx_set_pause(struct net_device *net, return ret; } +static int lan78xx_get_regs_len(struct net_device *netdev) +{ + if (!netdev->phydev) + return (sizeof(lan78xx_regs)); + else + return (sizeof(lan78xx_regs) + PHY_REG_SIZE); +} + +static void +lan78xx_get_regs(struct net_device *netdev, struct ethtool_regs *regs, +void *buf) +{ + u32 *data = buf; + int i, j; + struct lan78xx_net *dev = netdev_priv(netdev); + + /* Read Device/MAC registers */ + for (i = 0, j = 0; i < (sizeof(lan78xx_regs) / sizeof(u32)); i++, j++) + lan78xx_read_reg(dev, lan78xx_regs[i], [j]); + + if (!netdev->phydev) + return; + + /* Read PHY registers */ + for (i = 0; i < 32; i++, j++) + data[j] = phy_read(netdev->phydev, i); +} + static const struct ethtool_ops lan78xx_ethtool_ops = { .get_link = lan78xx_get_link, .nway_reset = phy_ethtool_nway_reset, @@ -1625,6 +1677,8 @@ static const struct ethtool_ops lan78xx_ethtool_ops = { .set_pauseparam = lan78xx_set_pause, .get_link_ksettings = lan78xx_get_link_ksettings, .set_link_ksettings = lan78xx_set_link_ksettings, + .get_regs_len = lan78xx_get_regs_len, + .get_regs = lan78xx_get_regs, }; static int lan78xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) -- 2.16.2
[PATCH v1 net-next] lan78xx: Add support to dump lan78xx registers
In order to dump lan78xx family registers using ethtool, add support at lan78xx driver level. Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- v0->v1: * Remove one variable in the for loop. --- drivers/net/usb/lan78xx.c | 54 +++ 1 file changed, 54 insertions(+) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 0867f7275852..207a3e18c08f 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -278,6 +278,30 @@ struct lan78xx_statstage64 { u64 eee_tx_lpi_time; }; +static u32 lan78xx_regs[] = { + ID_REV, + INT_STS, + HW_CFG, + PMT_CTL, + E2P_CMD, + E2P_DATA, + USB_STATUS, + VLAN_TYPE, + MAC_CR, + MAC_RX, + MAC_TX, + FLOW, + ERR_STS, + MII_ACC, + MII_DATA, + EEE_TX_LPI_REQ_DLY, + EEE_TW_TX_SYS, + EEE_TX_LPI_REM_DLY, + WUCSR +}; + +#define PHY_REG_SIZE (32 * sizeof(u32)) + struct lan78xx_net; struct lan78xx_priv { @@ -1605,6 +1629,34 @@ static int lan78xx_set_pause(struct net_device *net, return ret; } +static int lan78xx_get_regs_len(struct net_device *netdev) +{ + if (!netdev->phydev) + return (sizeof(lan78xx_regs)); + else + return (sizeof(lan78xx_regs) + PHY_REG_SIZE); +} + +static void +lan78xx_get_regs(struct net_device *netdev, struct ethtool_regs *regs, +void *buf) +{ + u32 *data = buf; + int i, j; + struct lan78xx_net *dev = netdev_priv(netdev); + + /* Read Device/MAC registers */ + for (i = 0; i < (sizeof(lan78xx_regs) / sizeof(u32)); i++) + lan78xx_read_reg(dev, lan78xx_regs[i], [i]); + + if (!netdev->phydev) + return; + + /* Read PHY registers */ + for (j = 0; j < 32; i++, j++) + data[i] = phy_read(netdev->phydev, j); +} + static const struct ethtool_ops lan78xx_ethtool_ops = { .get_link = lan78xx_get_link, .nway_reset = phy_ethtool_nway_reset, @@ -1625,6 +1677,8 @@ static const struct ethtool_ops lan78xx_ethtool_ops = { .set_pauseparam = lan78xx_set_pause, .get_link_ksettings = lan78xx_get_link_ksettings, .set_link_ksettings = lan78xx_set_link_ksettings, + .get_regs_len = lan78xx_get_regs_len, + .get_regs = lan78xx_get_regs, }; static int lan78xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) -- 2.16.2
[PATCH v1 net-next] lan78xx: Lan7801 Support for Fixed PHY
Adding Fixed PHY support to the lan78xx driver. Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- v0->v1: * Remove driver version #define * Modify netdev_info to netdev_dbg * Move lan7801 specific to new routine and add switch case * Minor cleanup --- drivers/net/usb/Kconfig | 1 + drivers/net/usb/lan78xx.c | 113 -- 2 files changed, 79 insertions(+), 35 deletions(-) diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index f28bd74ac275..418b0904cecb 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -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. diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 0867f7275852..47fa34a2d09f 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -36,13 +36,12 @@ #include #include #include -#include +#include #include "lan78xx.h" #define DRIVER_AUTHOR "WOOJUNG HUH <woojung@microchip.com>" #define DRIVER_DESC"LAN78XX USB 3.0 Gigabit Ethernet Devices" #define DRIVER_NAME"lan78xx" -#define DRIVER_VERSION "1.0.6" #define TX_TIMEOUT_JIFFIES (5 * HZ) #define THROTTLE_JIFFIES (HZ / 8) @@ -402,6 +401,7 @@ struct lan78xx_net { struct statstagestats; struct irq_domain_data domain_data; + struct phy_device *fixedphy; }; /* define external phy id */ @@ -1477,7 +1477,6 @@ static void lan78xx_get_drvinfo(struct net_device *net, struct lan78xx_net *dev = netdev_priv(net); strncpy(info->driver, DRIVER_NAME, sizeof(info->driver)); - strncpy(info->version, DRIVER_VERSION, sizeof(info->version)); usb_make_path(dev->udev, info->bus_info, sizeof(info->bus_info)); } @@ -2003,52 +2002,91 @@ static int ksz9031rnx_fixup(struct phy_device *phydev) return 1; } -static int lan78xx_phy_init(struct lan78xx_net *dev) +static int lan7801_phy_init(struct phy_device **phydev, + struct lan78xx_net *dev) { + u32 buf; int ret; - u32 mii_adv; - struct phy_device *phydev; - - phydev = phy_find_first(dev->mdiobus); - if (!phydev) { - netdev_err(dev->net, "no PHY found\n"); - return -EIO; - } - - 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_) { - if (!phydev->drv) { + struct fixed_phy_status fphy_status = { + .link = 1, + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, + }; + + if (!*phydev) { + netdev_dbg(dev->net, "PHY Not Found!! Registering Fixed PHY\n"); + *phydev = fixed_phy_register(PHY_POLL, _status, -1, +NULL); + if (IS_ERR(*phydev)) { + netdev_err(dev->net, "No PHY/fixed_PHY found\n"); + return -ENODEV; + } + netdev_dbg(dev->net, "Registered FIXED PHY\n"); + dev->interface = PHY_INTERFACE_MODE_RGMII; + dev->fixedphy = *phydev; + 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 |= 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; } - dev->interface = PHY_INTERFACE_MODE_RGMII; - /* external PHY fixup for KSZ9031RNX */ ret = phy_register_fixup_for_uid(PHY_KSZ9031RNX, 0xfff0, ksz9031rnx_fixup); if (ret < 0) { - netdev_err(dev->net, "fail to register fixup\n"); + netdev_err(dev->net, "fail to register fixup PHY_KSZ9031RNX\n"); return ret; } /* external PHY fixup for LAN8835 */ ret = phy_register_fixup_for_uid(PHY_LAN8835, 0xf
[PATCH net-next] lan78xx: Lan7801 Support for Fixed PHY
Adding Fixed PHY support to the lan78xx driver. Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- drivers/net/usb/Kconfig | 1 + drivers/net/usb/lan78xx.c | 43 +++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index f28bd74ac275..418b0904cecb 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -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. diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 207a3e18c08f..0d52f37c6cf4 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -36,13 +36,13 @@ #include #include #include -#include +#include #include "lan78xx.h" #define DRIVER_AUTHOR "WOOJUNG HUH <woojung@microchip.com>" #define DRIVER_DESC"LAN78XX USB 3.0 Gigabit Ethernet Devices" #define DRIVER_NAME"lan78xx" -#define DRIVER_VERSION "1.0.6" +#define DRIVER_VERSION "1.0.7" #define TX_TIMEOUT_JIFFIES (5 * HZ) #define THROTTLE_JIFFIES (HZ / 8) @@ -426,6 +426,7 @@ struct lan78xx_net { struct statstagestats; struct irq_domain_data domain_data; + struct phy_device *fixedphy; }; /* define external phy id */ @@ -2062,11 +2063,39 @@ static int lan78xx_phy_init(struct lan78xx_net *dev) int ret; u32 mii_adv; struct phy_device *phydev; + struct fixed_phy_status fphy_status = { + .link = 1, + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, + }; phydev = phy_find_first(dev->mdiobus); if (!phydev) { - netdev_err(dev->net, "no PHY found\n"); - return -EIO; + if (dev->chipid == ID_REV_CHIP_ID_7801_) { + u32 buf; + + netdev_info(dev->net, "PHY Not Found!! Registering Fixed PHY\n"); + phydev = fixed_phy_register(PHY_POLL, _status, -1, + NULL); + if (IS_ERR(phydev)) { + netdev_err(dev->net, "No PHY/fixed_PHY found\n"); + return -ENODEV; + } + netdev_info(dev->net, "Registered FIXED PHY\n"); + dev->interface = PHY_INTERFACE_MODE_RGMII; + dev->fixedphy = phydev; + 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 |= HW_CFG_CLK125_EN_; + buf |= HW_CFG_REFCLK25_EN_; + ret = lan78xx_write_reg(dev, HW_CFG, buf); + goto phyinit; + } else { + netdev_err(dev->net, "no PHY found\n"); + return -EIO; + } } if ((dev->chipid == ID_REV_CHIP_ID_7800_) || @@ -2105,6 +2134,7 @@ static int lan78xx_phy_init(struct lan78xx_net *dev) goto error; } +phyinit: /* if phyirq is not set, use polling mode in phylib */ if (dev->domain_data.phyirq > 0) phydev->irq = dev->domain_data.phyirq; @@ -3555,6 +3585,11 @@ static void lan78xx_disconnect(struct usb_interface *intf) phy_disconnect(net->phydev); + if (dev->fixedphy) { + fixed_phy_unregister(dev->fixedphy); + dev->fixedphy = NULL; + } + unregister_netdev(net); cancel_delayed_work_sync(>wq); -- 2.16.2
[PATCH net] lan78xx: Crash in lan78xx_writ_reg (Workqueue: events lan78xx_deferred_multicast_write)
Description: Crash was reported with syzkaller pointing to lan78xx_write_reg routine. Root-cause: Proper cleanup of workqueues and init/setup routines was not happening in failure conditions. Fix: Handled the error conditions by cleaning up the queues and init/setup routines. Fixes: 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to 10/100/1000 Ethernet device driver") Reported-by: Andrey Konovalov <andreyk...@google.com> Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- drivers/net/usb/lan78xx.c | 23 +-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 60a604cc7647..11176070b345 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -2863,8 +2863,7 @@ static int lan78xx_bind(struct lan78xx_net *dev, struct usb_interface *intf) if (ret < 0) { netdev_warn(dev->net, "lan78xx_setup_irq_domain() failed : %d", ret); - kfree(pdata); - return ret; + goto out1; } dev->net->hard_header_len += TX_OVERHEAD; @@ -2872,14 +2871,32 @@ static int lan78xx_bind(struct lan78xx_net *dev, struct usb_interface *intf) /* Init all registers */ ret = lan78xx_reset(dev); + if (ret) { + netdev_warn(dev->net, "Registers INIT FAILED"); + goto out2; + } ret = lan78xx_mdio_init(dev); + if (ret) { + netdev_warn(dev->net, "MDIO INIT FAILED."); + goto out2; + } dev->net->flags |= IFF_MULTICAST; pdata->wol = WAKE_MAGIC; return ret; + +out2: + lan78xx_remove_irq_domain(dev); + +out1: + netdev_warn(dev->net, "Bind routine FAILED"); + cancel_work_sync(>set_multicast); + cancel_work_sync(>set_vlan); + kfree(pdata); + return ret; } static void lan78xx_unbind(struct lan78xx_net *dev, struct usb_interface *intf) @@ -2891,6 +2908,8 @@ static void lan78xx_unbind(struct lan78xx_net *dev, struct usb_interface *intf) lan78xx_remove_mdio(dev); if (pdata) { + cancel_work_sync(>set_multicast); + cancel_work_sync(>set_vlan); netif_dbg(dev, ifdown, dev->net, "free pdata"); kfree(pdata); pdata = NULL; -- 2.16.2
[PATCH v1 net] lan78xx: Set ASD in MAC_CR when EEE is enabled.
Description: EEE does not work with lan7800 when AutoSpeed is not set. (This can happen when EEPROM is not populated or configured incorrectly) Root-Cause: When EEE is enabled, the mac config register ASD is not set i.e. in default state, causing EEE fail. Fix: Set the register when eeprom is not present. Fixes: 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to 10/100/1000 Ethernet device driver") Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- v0->v1: * Resolved the style related problems. * Removed 1/3 patch count from Subject line. --- drivers/net/usb/lan78xx.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 60a604cc7647..90d176279152 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -2351,6 +2351,7 @@ static int lan78xx_reset(struct lan78xx_net *dev) u32 buf; int ret = 0; unsigned long timeout; + u8 sig; ret = lan78xx_read_reg(dev, HW_CFG, ); buf |= HW_CFG_LRST_; @@ -2450,6 +2451,15 @@ static int lan78xx_reset(struct lan78xx_net *dev) /* LAN7801 only has RGMII mode */ if (dev->chipid == ID_REV_CHIP_ID_7801_) buf &= ~MAC_CR_GMII_EN_; + + if (dev->chipid == ID_REV_CHIP_ID_7800_) { + ret = lan78xx_read_raw_eeprom(dev, 0, 1, ); + if (!ret && sig != EEPROM_INDICATOR) { + /* Implies there is no external eeprom. Set mac speed */ + netdev_info(dev->net, "No External EEPROM. Setting MAC Speed\n"); + buf |= MAC_CR_AUTO_DUPLEX_ | MAC_CR_AUTO_SPEED_; + } + } ret = lan78xx_write_reg(dev, MAC_CR, buf); ret = lan78xx_read_reg(dev, MAC_TX, ); -- 2.16.2
[PATCH net 1/3] lan78xx: Set ASD in MAC_CR when EEE is enabled.
Description: EEE does not work with lan7800 when AutoSpeed is not set. (This can happen when EEPROM is not populated or configured incorrectly) Root-Cause: When EEE is enabled, the mac config register ASD is not set i.e in default state,causing EEE fail. Fix: Set the register when eeprom is not present. Fixes: 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to 10/100/1000 Ethernet device driver") Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- drivers/net/usb/lan78xx.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 11176070b345..e2d26f9c0f6a 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -2351,6 +2351,7 @@ static int lan78xx_reset(struct lan78xx_net *dev) u32 buf; int ret = 0; unsigned long timeout; + u8 sig; ret = lan78xx_read_reg(dev, HW_CFG, ); buf |= HW_CFG_LRST_; @@ -2450,6 +2451,15 @@ static int lan78xx_reset(struct lan78xx_net *dev) /* LAN7801 only has RGMII mode */ if (dev->chipid == ID_REV_CHIP_ID_7801_) buf &= ~MAC_CR_GMII_EN_; + + if(dev->chipid == ID_REV_CHIP_ID_7800_) { + ret = lan78xx_read_raw_eeprom(dev, 0, 1, ); + if ((!ret) && (sig != EEPROM_INDICATOR)) { + /*Implies there is no external eeprom. Set mac speed*/ + netdev_info(dev->net, "No External EEPROM. Setting MAC Speed \n"); + buf |= MAC_CR_AUTO_DUPLEX_ | MAC_CR_AUTO_SPEED_; + } + } ret = lan78xx_write_reg(dev, MAC_CR, buf); ret = lan78xx_read_reg(dev, MAC_TX, ); -- 2.16.2
[PATCH v2 net-next] lan78xx: Lan7801 Support for Fixed PHY
Adding Fixed PHY support to the lan78xx driver. Signed-off-by: Raghuram Chary J <raghuramchary.jallipa...@microchip.com> --- v0->v1: * Remove driver version #define * Modify netdev_info to netdev_dbg * Move lan7801 specific to new routine and add switch case * Minor cleanup v1->v2: * Removed fixedphy variable and used phy_is_pseudo_fixed_link() check. --- drivers/net/usb/Kconfig | 1 + drivers/net/usb/lan78xx.c | 111 +++--- 2 files changed, 77 insertions(+), 35 deletions(-) diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index f28bd74ac275..418b0904cecb 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -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. diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 0867f7275852..48925ed71555 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -36,13 +36,12 @@ #include #include #include -#include +#include #include "lan78xx.h" #define DRIVER_AUTHOR "WOOJUNG HUH <woojung@microchip.com>" #define DRIVER_DESC"LAN78XX USB 3.0 Gigabit Ethernet Devices" #define DRIVER_NAME"lan78xx" -#define DRIVER_VERSION "1.0.6" #define TX_TIMEOUT_JIFFIES (5 * HZ) #define THROTTLE_JIFFIES (HZ / 8) @@ -1477,7 +1476,6 @@ static void lan78xx_get_drvinfo(struct net_device *net, struct lan78xx_net *dev = netdev_priv(net); strncpy(info->driver, DRIVER_NAME, sizeof(info->driver)); - strncpy(info->version, DRIVER_VERSION, sizeof(info->version)); usb_make_path(dev->udev, info->bus_info, sizeof(info->bus_info)); } @@ -2003,52 +2001,90 @@ static int ksz9031rnx_fixup(struct phy_device *phydev) return 1; } -static int lan78xx_phy_init(struct lan78xx_net *dev) +static int lan7801_phy_init(struct phy_device **phydev, + struct lan78xx_net *dev) { + u32 buf; int ret; - u32 mii_adv; - struct phy_device *phydev; - - phydev = phy_find_first(dev->mdiobus); - if (!phydev) { - netdev_err(dev->net, "no PHY found\n"); - return -EIO; - } - - 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_) { - if (!phydev->drv) { + struct fixed_phy_status fphy_status = { + .link = 1, + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, + }; + + if (!*phydev) { + netdev_dbg(dev->net, "PHY Not Found!! Registering Fixed PHY\n"); + *phydev = fixed_phy_register(PHY_POLL, _status, -1, +NULL); + if (IS_ERR(*phydev)) { + netdev_err(dev->net, "No PHY/fixed_PHY found\n"); + return -ENODEV; + } + 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 |= 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; } - dev->interface = PHY_INTERFACE_MODE_RGMII; - /* external PHY fixup for KSZ9031RNX */ ret = phy_register_fixup_for_uid(PHY_KSZ9031RNX, 0xfff0, ksz9031rnx_fixup); if (ret < 0) { - netdev_err(dev->net, "fail to register fixup\n"); + netdev_err(dev->net, "fail to register fixup PHY_KSZ9031RNX\n"); return ret; } /* external PHY fixup for LAN8835 */ ret = phy_register_fixup_for_uid(PHY_LAN8835, 0xfff0, lan8835_fixup); if (ret < 0) { - netdev_err(dev->net, &q