[PATCH v5 net-next 0/3] lan78xx updates along with Fixed phy Support

2018-04-27 Thread Raghuram Chary J
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

2018-04-27 Thread Raghuram Chary J
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

2018-04-27 Thread Raghuram Chary J
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

2018-04-27 Thread Raghuram Chary J
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

2018-04-28 Thread Raghuram Chary J
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

2018-04-28 Thread Raghuram Chary J
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

2018-04-28 Thread Raghuram Chary J
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

2018-04-28 Thread Raghuram Chary J
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

2018-04-26 Thread Raghuram Chary J
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

2018-04-26 Thread Raghuram Chary J
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

2018-04-26 Thread Raghuram Chary J
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

2018-04-26 Thread Raghuram Chary J
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

2018-04-26 Thread Raghuram Chary J
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

2018-04-26 Thread Raghuram Chary J
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

2018-04-26 Thread Raghuram Chary J
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

2018-04-26 Thread Raghuram Chary J
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

2018-04-26 Thread Raghuram Chary J
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

2018-04-05 Thread Raghuram Chary J
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

2018-04-11 Thread Raghuram Chary J
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

2018-04-11 Thread Raghuram Chary J
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

2018-04-11 Thread Raghuram Chary J
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

2018-04-11 Thread Raghuram Chary J
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

2018-04-11 Thread Raghuram Chary J
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

2018-04-06 Thread Raghuram Chary J
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

2018-04-06 Thread Raghuram Chary J
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

2018-04-06 Thread Raghuram Chary J
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

2018-04-06 Thread Raghuram Chary J
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

2018-04-18 Thread Raghuram Chary J
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

2018-04-20 Thread Raghuram Chary J
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

2018-04-25 Thread Raghuram Chary J
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

2018-04-22 Thread Raghuram Chary J
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)

2018-03-27 Thread Raghuram Chary J
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.

2018-03-23 Thread Raghuram Chary J
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.

2018-03-22 Thread Raghuram Chary J
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

2018-04-25 Thread Raghuram Chary J
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