[PATCH net-next] net: phy: aquantia: add PHY ID of AQR106 and AQR107

2016-10-20 Thread shh.xie
From: Shaohui Xie 

The AQR106 and AQR107 can use the existing driver.

Signed-off-by: Shaohui Xie 
---
 drivers/net/phy/aquantia.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
index 09b0b0a..e8ae50e 100644
--- a/drivers/net/phy/aquantia.c
+++ b/drivers/net/phy/aquantia.c
@@ -21,6 +21,8 @@
 #define PHY_ID_AQ1202  0x03a1b445
 #define PHY_ID_AQ2104  0x03a1b460
 #define PHY_ID_AQR105  0x03a1b4a2
+#define PHY_ID_AQR106  0x03a1b4d0
+#define PHY_ID_AQR107  0x03a1b4e0
 #define PHY_ID_AQR405  0x03a1b4b0
 
 #define PHY_AQUANTIA_FEATURES  (SUPPORTED_1baseT_Full | \
@@ -154,6 +156,30 @@ static struct phy_driver aquantia_driver[] = {
.read_status= aquantia_read_status,
 },
 {
+   .phy_id = PHY_ID_AQR106,
+   .phy_id_mask= 0xfff0,
+   .name   = "Aquantia AQR106",
+   .features   = PHY_AQUANTIA_FEATURES,
+   .flags  = PHY_HAS_INTERRUPT,
+   .aneg_done  = aquantia_aneg_done,
+   .config_aneg= aquantia_config_aneg,
+   .config_intr= aquantia_config_intr,
+   .ack_interrupt  = aquantia_ack_interrupt,
+   .read_status= aquantia_read_status,
+},
+{
+   .phy_id = PHY_ID_AQR107,
+   .phy_id_mask= 0xfff0,
+   .name   = "Aquantia AQR107",
+   .features   = PHY_AQUANTIA_FEATURES,
+   .flags  = PHY_HAS_INTERRUPT,
+   .aneg_done  = aquantia_aneg_done,
+   .config_aneg= aquantia_config_aneg,
+   .config_intr= aquantia_config_intr,
+   .ack_interrupt  = aquantia_ack_interrupt,
+   .read_status= aquantia_read_status,
+},
+{
.phy_id = PHY_ID_AQR405,
.phy_id_mask= 0xfff0,
.name   = "Aquantia AQR405",
@@ -173,6 +199,8 @@ static struct mdio_device_id __maybe_unused aquantia_tbl[] 
= {
{ PHY_ID_AQ1202, 0xfff0 },
{ PHY_ID_AQ2104, 0xfff0 },
{ PHY_ID_AQR105, 0xfff0 },
+   { PHY_ID_AQR106, 0xfff0 },
+   { PHY_ID_AQR107, 0xfff0 },
{ PHY_ID_AQR405, 0xfff0 },
{ }
 };
-- 
2.1.0.27.g96db324



[PATCH] net: phylib: fix interrupts re-enablement in phy_start

2016-05-10 Thread shh.xie
From: Shaohui Xie 

If phy was suspended and is starting, current driver always enable
phy's interrupts, if phy works in polling, phy can raise unexpected
interrupt which will not be handled, the interrupt will block system
enter suspend again. So interrupts should only be re-enabled if phy
works in interrupt.

Signed-off-by: Shaohui Xie 
---
 drivers/net/phy/phy.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 6f221c8..baa5ecb 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -871,9 +871,11 @@ void phy_start(struct phy_device *phydev)
break;
case PHY_HALTED:
/* make sure interrupts are re-enabled for the PHY */
-   err = phy_enable_interrupts(phydev);
-   if (err < 0)
-   break;
+   if (phydev->irq != PHY_POLL) {
+   err = phy_enable_interrupts(phydev);
+   if (err < 0)
+   break;
+   }
 
phydev->state = PHY_RESUMING;
do_resume = true;
-- 
2.1.0.27.g96db324



[PATCH] net: phy: adds backplane driver for Freescale's PCS PHY

2015-12-18 Thread shh.xie
From: Shaohui Xie 

Freescale's PCS PHY can support backplane, this patch provides 10GBASE-KR
and 1000BASE-KX support.

Signed-off-by: Shaohui Xie 
---
 drivers/net/phy/Kconfig |7 +
 drivers/net/phy/Makefile|1 +
 drivers/net/phy/fsl_backplane.c | 1201 +++
 3 files changed, 1209 insertions(+)
 create mode 100644 drivers/net/phy/fsl_backplane.c

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 60994a8..ce523ea 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -256,6 +256,13 @@ config MDIO_BCM_IPROC
  This module provides a driver for the MDIO busses found in the
  Broadcom iProc SoC's.
 
+config FSL_BACKPLANE
+   tristate "Support for Backplane on Freescale PCS PHYs"
+   depends on OF_MDIO
+   help
+ This module provides a driver for Backplane on Freescale PCS PHYs,
+ it supports 10GBASE-KR and 1000BASE-KX.
+
 endif # PHYLIB
 
 config MICREL_KS8995MA
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index f31a4e2..fa1fb4d 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -42,3 +42,4 @@ obj-$(CONFIG_MDIO_MOXART) += mdio-moxart.o
 obj-$(CONFIG_MDIO_BCM_UNIMAC)  += mdio-bcm-unimac.o
 obj-$(CONFIG_MICROCHIP_PHY)+= microchip.o
 obj-$(CONFIG_MDIO_BCM_IPROC)   += mdio-bcm-iproc.o
+obj-$(CONFIG_FSL_BACKPLANE)+= fsl_backplane.o
diff --git a/drivers/net/phy/fsl_backplane.c b/drivers/net/phy/fsl_backplane.c
new file mode 100644
index 000..ce0974d
--- /dev/null
+++ b/drivers/net/phy/fsl_backplane.c
@@ -0,0 +1,1201 @@
+/* Freescale backplane driver.
+ *   Author: Shaohui Xie 
+ *
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define FSL_PCS_PHY_ID 0x0083e400
+
+/* Freescale KR PMD registers */
+#define FSL_KR_PMD_CTRL0x96
+#define FSL_KR_PMD_STATUS  0x97
+#define FSL_KR_LP_CU   0x98
+#define FSL_KR_LP_STATUS   0x99
+#define FSL_KR_LD_CU   0x9a
+#define FSL_KR_LD_STATUS   0x9b
+
+/* Freescale KR PMD defines */
+#define PMD_RESET  0x1
+#define PMD_STATUS_SUP_STAT0x4
+#define PMD_STATUS_FRAME_LOCK  0x2
+#define TRAIN_EN   0x3
+#define TRAIN_DISABLE  0x1
+#define RX_STAT0x1
+
+/* Freescale KX PCS mode register */
+#define FSL_PCS_IF_MODE0x8014
+
+/* Freescale KX PCS mode register init value */
+#define IF_MODE_INIT   0x8
+
+/* Freescale KX/KR AN registers */
+#define FSL_AN_AD1 0x11
+#define FSL_AN_BP_STAT 0x30
+
+/* Freescale KX/KR AN registers defines */
+#define AN_CTRL_INIT   0x1200
+#define KX_AN_AD1_INIT 0x25
+#define KR_AN_AD1_INIT 0x85
+#define REMOTE_FAULT   0x10
+#define AN_LNK_UP_MASK 0x4
+#define KR_AN_MASK 0x8
+#define TRAIN_FAIL 0x8
+
+/* C(-1) */
+#define BIN_M1 0
+/* C(1) */
+#define BIN_LONG   1
+#define BIN_M1_SEL 6
+#define BIN_Long_SEL   7
+#define CDR_SEL_MASK   0x0007
+#define BIN_SNAPSHOT_NUM   5
+#define BIN_M1_THRESHOLD   3
+#define BIN_LONG_THRESHOLD 2
+
+#define PRE_COE_MASK   0x03c0
+#define POST_COE_MASK  0x001f
+#define ZERO_COE_MASK  0x3f00
+#define PRE_COE_SHIFT  22
+#define POST_COE_SHIFT 16
+#define ZERO_COE_SHIFT 8
+
+#define PRE_COE_MAX0x0
+#define PRE_COE_MIN0x8
+#define POST_COE_MAX   0x0
+#define POST_COE_MIN   0x10
+#define ZERO_COE_MAX   0x30
+#define ZERO_COE_MIN   0x0
+
+#define TECR0_INIT 0x2420
+#define RATIO_PREQ 0x3
+#define RATIO_PST1Q0xd
+#define RATIO_EQ   0x20
+
+#define GCR0_RESET_MASK0x60
+#define GCR1_REIDL_TH_MASK 0x0070
+#define GCR1_REIDL_EX_SEL_MASK 0x000c
+#define GCR1_REIDL_ET_MAS_MASK 0x4000
+#define TECR0_AMP_RED_MASK 0x003f
+
+#define GCR1_SNP_START_MASK0x0040
+#define RECR1_SNP_DONE_MASK0x0004
+#define TCSR1_SNP_DATA_MASK0xffc0
+#define TCSR1_SNP_DATA_SHIFT   6
+#define TCSR1_EQ_SNPBIN_SIGN_MASK  0x100
+
+#define XGKR_TIMEOUT   1050
+
+#define INCREMENT  1
+#define DECR

[PATCH] [V2] net: fsl: expands dependencies of NET_VENDOR_FREESCALE

2015-11-19 Thread shh.xie
From: Shaohui Xie 

Freescale hosts some ARMv8 based SoCs, and a generic convention
ARCH_LAYERSCAPE is used to cover such SoCs. Adding ARCH_LAYERSCAPE
to dependencies of NET_VENDOR_FREESCALE to support networking on those
SoCs.

The ARCH_LAYERSCAPE is introduced by:
commit: 53a5fde05 arm64: Use generic Layerscape SoC family naming

Signed-off-by: Shaohui Xie 
---
changes in v2:
1. revises commit message to add commit which introduces ARCH_LAYERSCAPE.

 drivers/net/ethernet/freescale/Kconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/Kconfig 
b/drivers/net/ethernet/freescale/Kconfig
index ff76d4e..bee32a9 100644
--- a/drivers/net/ethernet/freescale/Kconfig
+++ b/drivers/net/ethernet/freescale/Kconfig
@@ -7,7 +7,8 @@ config NET_VENDOR_FREESCALE
default y
depends on FSL_SOC || QUICC_ENGINE || CPM1 || CPM2 || PPC_MPC512x || \
   M523x || M527x || M5272 || M528x || M520x || M532x || \
-  ARCH_MXC || ARCH_MXS || (PPC_MPC52xx && PPC_BESTCOMM)
+  ARCH_MXC || ARCH_MXS || (PPC_MPC52xx && PPC_BESTCOMM) || \
+  ARCH_LAYERSCAPE
---help---
  If you have a network (Ethernet) card belonging to this class, say Y.
 
-- 
2.1.0.27.g96db324

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH][v3] net: phy: fix a bug in get_phy_c45_ids

2015-11-02 Thread shh.xie
From: Shaohui Xie 

When probing devices-in-package for a c45 phy, device zero is the last
device to probe, however, if driver reads 0 from device zero,
c45_ids->devices_in_package is set to '0', the loop condition of probing
will be matched again, see codes below:

for (i = 1;i < num_ids && c45_ids->devices_in_package == 0;i++)

driver will run in a dead loop.

This patch restructures the bug and confusing loop, it provides a helper
function get_phy_c45_devs_in_pkg which to read devices-in-package registers
of a MMD, and rewrites the loop with using the helper function.

Signed-off-by: Shaohui Xie 
---
changes in v3:
removed a leading space on the first line of comment of get_phy_c45_devs_in_pkg.

changes in v2:
1. uses a helper function to read devices in package registers of a MMD.

2. rewrites the probing loop with using the helper function.

 drivers/net/phy/phy_device.c | 74 +---
 1 file changed, 49 insertions(+), 25 deletions(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 3833891..8c84b9e 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -205,6 +205,37 @@ struct phy_device *phy_device_create(struct mii_bus *bus, 
int addr, int phy_id,
 }
 EXPORT_SYMBOL(phy_device_create);
 
+/* get_phy_c45_devs_in_pkg - reads a MMD's devices in package registers.
+ * @bus: the target MII bus
+ * @addr: PHY address on the MII bus
+ * @dev_addr: MMD address in the PHY.
+ * @devices_in_package: where to store the devices in package information.
+ *
+ * Description: reads devices in package registers of a MMD at @dev_addr
+ * from PHY at @addr on @bus.
+ *
+ * Returns: 0 on success, -EIO on failure.
+ */
+static int get_phy_c45_devs_in_pkg(struct mii_bus *bus, int addr, int dev_addr,
+  u32 *devices_in_package)
+{
+   int phy_reg, reg_addr;
+
+   reg_addr = MII_ADDR_C45 | dev_addr << 16 | MDIO_DEVS2;
+   phy_reg = mdiobus_read(bus, addr, reg_addr);
+   if (phy_reg < 0)
+   return -EIO;
+   *devices_in_package = (phy_reg & 0x) << 16;
+
+   reg_addr = MII_ADDR_C45 | dev_addr << 16 | MDIO_DEVS1;
+   phy_reg = mdiobus_read(bus, addr, reg_addr);
+   if (phy_reg < 0)
+   return -EIO;
+   *devices_in_package |= (phy_reg & 0x);
+
+   return 0;
+}
+
 /**
  * get_phy_c45_ids - reads the specified addr for its 802.3-c45 IDs.
  * @bus: the target MII bus
@@ -223,38 +254,31 @@ static int get_phy_c45_ids(struct mii_bus *bus, int addr, 
u32 *phy_id,
int phy_reg;
int i, reg_addr;
const int num_ids = ARRAY_SIZE(c45_ids->device_ids);
+   u32 *devs = &c45_ids->devices_in_package;
 
-   /* Find first non-zero Devices In package.  Device
-* zero is reserved, so don't probe it.
+   /* Find first non-zero Devices In package. Device zero is reserved
+* for 802.3 c45 complied PHYs, so don't probe it at first.
 */
-   for (i = 1;
-i < num_ids && c45_ids->devices_in_package == 0;
-i++) {
-retry: reg_addr = MII_ADDR_C45 | i << 16 | MDIO_DEVS2;
-   phy_reg = mdiobus_read(bus, addr, reg_addr);
+   for (i = 1; i < num_ids && *devs == 0; i++) {
+   phy_reg = get_phy_c45_devs_in_pkg(bus, addr, i, devs);
if (phy_reg < 0)
return -EIO;
-   c45_ids->devices_in_package = (phy_reg & 0x) << 16;
 
-   reg_addr = MII_ADDR_C45 | i << 16 | MDIO_DEVS1;
-   phy_reg = mdiobus_read(bus, addr, reg_addr);
-   if (phy_reg < 0)
-   return -EIO;
-   c45_ids->devices_in_package |= (phy_reg & 0x);
-
-   if ((c45_ids->devices_in_package & 0x1fff) == 0x1fff) {
-   if (i) {
-   /*  If mostly Fs, there is no device there,
-*  then let's continue to probe more, as some
-*  10G PHYs have zero Devices In package,
-*  e.g. Cortina CS4315/CS4340 PHY.
-*/
-   i = 0;
-   goto retry;
-   } else {
-   /* no device there, let's get out of here */
+   if ((*devs & 0x1fff) == 0x1fff) {
+   /*  If mostly Fs, there is no device there,
+*  then let's continue to probe more, as some
+*  10G PHYs have zero Devices In package,
+*  e.g. Cortina CS4315/CS4340 PHY.
+*/
+   phy_reg = get_phy_c45_devs_in_pkg(bus, addr, 0, devs);
+   if (phy_reg < 0)
+   return -EIO;
+   /* no device there, let's get out of here */
+  

[PATCH][v2] net: phy: fix a bug in get_phy_c45_ids

2015-11-02 Thread shh.xie
From: Shaohui Xie 

When probing devices-in-package for a c45 phy, device zero is the last
device to probe, however, if driver reads 0 from device zero,
c45_ids->devices_in_package is set to '0', the loop condition of probing
will be matched again, see codes below:

for (i = 1;i < num_ids && c45_ids->devices_in_package == 0;i++)

driver will run in a dead loop.

This patch restructures the bug and confusing loop, it provides a helper
function get_phy_c45_devs_in_pkg which to read devices-in-package registers
of a MMD, and rewrites the loop with using the helper function.

Signed-off-by: Shaohui Xie 
---
changes in v2:
1. uses a helper function to read devices in package registers of a MMD.

2. rewrites the probing loop with using the helper function.

 drivers/net/phy/phy_device.c | 74 +---
 1 file changed, 49 insertions(+), 25 deletions(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 3833891..8c84b9e 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -205,6 +205,37 @@ struct phy_device *phy_device_create(struct mii_bus *bus, 
int addr, int phy_id,
 }
 EXPORT_SYMBOL(phy_device_create);
 
+ /* get_phy_c45_devs_in_pkg - reads a MMD's devices in package registers.
+ * @bus: the target MII bus
+ * @addr: PHY address on the MII bus
+ * @dev_addr: MMD address in the PHY.
+ * @devices_in_package: where to store the devices in package information.
+ *
+ * Description: reads devices in package registers of a MMD at @dev_addr
+ * from PHY at @addr on @bus.
+ *
+ * Returns: 0 on success, -EIO on failure.
+ */
+static int get_phy_c45_devs_in_pkg(struct mii_bus *bus, int addr, int dev_addr,
+  u32 *devices_in_package)
+{
+   int phy_reg, reg_addr;
+
+   reg_addr = MII_ADDR_C45 | dev_addr << 16 | MDIO_DEVS2;
+   phy_reg = mdiobus_read(bus, addr, reg_addr);
+   if (phy_reg < 0)
+   return -EIO;
+   *devices_in_package = (phy_reg & 0x) << 16;
+
+   reg_addr = MII_ADDR_C45 | dev_addr << 16 | MDIO_DEVS1;
+   phy_reg = mdiobus_read(bus, addr, reg_addr);
+   if (phy_reg < 0)
+   return -EIO;
+   *devices_in_package |= (phy_reg & 0x);
+
+   return 0;
+}
+
 /**
  * get_phy_c45_ids - reads the specified addr for its 802.3-c45 IDs.
  * @bus: the target MII bus
@@ -223,38 +254,31 @@ static int get_phy_c45_ids(struct mii_bus *bus, int addr, 
u32 *phy_id,
int phy_reg;
int i, reg_addr;
const int num_ids = ARRAY_SIZE(c45_ids->device_ids);
+   u32 *devs = &c45_ids->devices_in_package;
 
-   /* Find first non-zero Devices In package.  Device
-* zero is reserved, so don't probe it.
+   /* Find first non-zero Devices In package. Device zero is reserved
+* for 802.3 c45 complied PHYs, so don't probe it at first.
 */
-   for (i = 1;
-i < num_ids && c45_ids->devices_in_package == 0;
-i++) {
-retry: reg_addr = MII_ADDR_C45 | i << 16 | MDIO_DEVS2;
-   phy_reg = mdiobus_read(bus, addr, reg_addr);
+   for (i = 1; i < num_ids && *devs == 0; i++) {
+   phy_reg = get_phy_c45_devs_in_pkg(bus, addr, i, devs);
if (phy_reg < 0)
return -EIO;
-   c45_ids->devices_in_package = (phy_reg & 0x) << 16;
 
-   reg_addr = MII_ADDR_C45 | i << 16 | MDIO_DEVS1;
-   phy_reg = mdiobus_read(bus, addr, reg_addr);
-   if (phy_reg < 0)
-   return -EIO;
-   c45_ids->devices_in_package |= (phy_reg & 0x);
-
-   if ((c45_ids->devices_in_package & 0x1fff) == 0x1fff) {
-   if (i) {
-   /*  If mostly Fs, there is no device there,
-*  then let's continue to probe more, as some
-*  10G PHYs have zero Devices In package,
-*  e.g. Cortina CS4315/CS4340 PHY.
-*/
-   i = 0;
-   goto retry;
-   } else {
-   /* no device there, let's get out of here */
+   if ((*devs & 0x1fff) == 0x1fff) {
+   /*  If mostly Fs, there is no device there,
+*  then let's continue to probe more, as some
+*  10G PHYs have zero Devices In package,
+*  e.g. Cortina CS4315/CS4340 PHY.
+*/
+   phy_reg = get_phy_c45_devs_in_pkg(bus, addr, 0, devs);
+   if (phy_reg < 0)
+   return -EIO;
+   /* no device there, let's get out of here */
+   if ((*devs & 0x1fff) == 0x1fff) {
*phy_id = 0xf

[PATCH] net: phy: fix a bug in get_phy_c45_ids

2015-10-29 Thread shh.xie
From: Shaohui Xie 

When probing devices-in-package for a c45 phy, device zero is the last
device to probe, in a rare situation which driver can read a '0' from
the device zero, thus c45_ids->devices_in_package is set to '0', so the
loop condition of probing is matched, see codes below:

for (i = 1;i < num_ids && c45_ids->devices_in_package == 0;i++)

driver will run in a dead loop.

So after probing the device zero, driver should stop the probing loop.

Signed-off-by: Shaohui Xie 
---
 drivers/net/phy/phy_device.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 3833891..065d6d3 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -257,6 +257,10 @@ retry: reg_addr = MII_ADDR_C45 | i << 16 | 
MDIO_DEVS2;
return 0;
}
}
+
+   /* stop probe when device zero was probed. */
+   if (!i)
+   break;
}
 
/* Now probe Device Identifiers for each device present. */
-- 
2.1.0.27.g96db324

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] net: fsl: expands dependencies of NET_VENDOR_FREESCALE

2015-10-26 Thread shh.xie
From: Shaohui Xie 

Freescale hosts some ARMv8 based SoCs, and a generic convention
ARCH_LAYERSCAPE is used to cover such SoCs. Adding ARCH_LAYERSCAPE
to dependencies of NET_VENDOR_FREESCALE to support networking on those
SoCs.

The patch to add ARCH_LAYERSCAPE can be viewed at:
http://www.spinics.net/lists/arm-kernel/msg455583.html

Signed-off-by: Shaohui Xie 
---
 drivers/net/ethernet/freescale/Kconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/Kconfig 
b/drivers/net/ethernet/freescale/Kconfig
index ff76d4e..bee32a9 100644
--- a/drivers/net/ethernet/freescale/Kconfig
+++ b/drivers/net/ethernet/freescale/Kconfig
@@ -7,7 +7,8 @@ config NET_VENDOR_FREESCALE
default y
depends on FSL_SOC || QUICC_ENGINE || CPM1 || CPM2 || PPC_MPC512x || \
   M523x || M527x || M5272 || M528x || M520x || M532x || \
-  ARCH_MXC || ARCH_MXS || (PPC_MPC52xx && PPC_BESTCOMM)
+  ARCH_MXC || ARCH_MXS || (PPC_MPC52xx && PPC_BESTCOMM) || \
+  ARCH_LAYERSCAPE
---help---
  If you have a network (Ethernet) card belonging to this class, say Y.
 
-- 
2.1.0.27.g96db324

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] net: phy: add interrupt support for aquantia phy

2015-08-21 Thread shh.xie
From: Shaohui Xie 

By implementing config_intr & ack_interrupt, now the phy can support
link connect/disconnect interrupt.

Signed-off-by: Shaohui Xie 
---
 drivers/net/phy/aquantia.c | 49 ++
 1 file changed, 49 insertions(+)

diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
index 73d347d..d6111af 100644
--- a/drivers/net/phy/aquantia.c
+++ b/drivers/net/phy/aquantia.c
@@ -44,6 +44,43 @@ static int aquantia_aneg_done(struct phy_device *phydev)
return (reg < 0) ? reg : (reg & BMSR_ANEGCOMPLETE);
 }
 
+static int aquantia_config_intr(struct phy_device *phydev)
+{
+   int err;
+
+   if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
+   err = phy_write_mmd(phydev, MDIO_MMD_AN, 0xd401, 1);
+   if (err < 0)
+   return err;
+
+   err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xff00, 1);
+   if (err < 0)
+   return err;
+
+   err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xff01, 0x1001);
+   } else {
+   err = phy_write_mmd(phydev, MDIO_MMD_AN, 0xd401, 0);
+   if (err < 0)
+   return err;
+
+   err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xff00, 0);
+   if (err < 0)
+   return err;
+
+   err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xff01, 0);
+   }
+
+   return err;
+}
+
+static int aquantia_ack_interrupt(struct phy_device *phydev)
+{
+   int reg;
+
+   reg = phy_read_mmd(phydev, MDIO_MMD_AN, 0xcc01);
+   return (reg < 0) ? reg : 0;
+}
+
 static int aquantia_read_status(struct phy_device *phydev)
 {
int reg;
@@ -85,8 +122,11 @@ static struct phy_driver aquantia_driver[] = {
.phy_id_mask= 0xfff0,
.name   = "Aquantia AQ1202",
.features   = PHY_AQUANTIA_FEATURES,
+   .flags  = PHY_HAS_INTERRUPT,
.aneg_done  = aquantia_aneg_done,
.config_aneg= aquantia_config_aneg,
+   .config_intr= aquantia_config_intr,
+   .ack_interrupt  = aquantia_ack_interrupt,
.read_status= aquantia_read_status,
.driver = { .owner = THIS_MODULE,},
 },
@@ -95,8 +135,11 @@ static struct phy_driver aquantia_driver[] = {
.phy_id_mask= 0xfff0,
.name   = "Aquantia AQ2104",
.features   = PHY_AQUANTIA_FEATURES,
+   .flags  = PHY_HAS_INTERRUPT,
.aneg_done  = aquantia_aneg_done,
.config_aneg= aquantia_config_aneg,
+   .config_intr= aquantia_config_intr,
+   .ack_interrupt  = aquantia_ack_interrupt,
.read_status= aquantia_read_status,
.driver = { .owner = THIS_MODULE,},
 },
@@ -105,8 +148,11 @@ static struct phy_driver aquantia_driver[] = {
.phy_id_mask= 0xfff0,
.name   = "Aquantia AQR105",
.features   = PHY_AQUANTIA_FEATURES,
+   .flags  = PHY_HAS_INTERRUPT,
.aneg_done  = aquantia_aneg_done,
.config_aneg= aquantia_config_aneg,
+   .config_intr= aquantia_config_intr,
+   .ack_interrupt  = aquantia_ack_interrupt,
.read_status= aquantia_read_status,
.driver = { .owner = THIS_MODULE,},
 },
@@ -115,8 +161,11 @@ static struct phy_driver aquantia_driver[] = {
.phy_id_mask= 0xfff0,
.name   = "Aquantia AQR405",
.features   = PHY_AQUANTIA_FEATURES,
+   .flags  = PHY_HAS_INTERRUPT,
.aneg_done  = aquantia_aneg_done,
.config_aneg= aquantia_config_aneg,
+   .config_intr= aquantia_config_intr,
+   .ack_interrupt  = aquantia_ack_interrupt,
.read_status= aquantia_read_status,
.driver = { .owner = THIS_MODULE,},
 },
-- 
2.1.0.27.g96db324

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] net: phy: fix PHY_RUNNING in phy_state_machine

2015-08-13 Thread shh.xie
From: Shaohui Xie 

Currently, if phy state is PHY_RUNNING, we always register a CHANGE
when phy works in polling or interrupt ignored, this will make the
adjust_link being called even the phy link did Not changed.

checking the phy link to make sure the link did changed before we
register a CHANGE, if link did not changed, we do nothing.

Signed-off-by: Shaohui Xie 
---
 drivers/net/phy/phy.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 84b1fba..d972851 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -814,6 +814,7 @@ void phy_state_machine(struct work_struct *work)
bool needs_aneg = false, do_suspend = false;
enum phy_state old_state;
int err = 0;
+   int old_link;
 
mutex_lock(&phydev->lock);
 
@@ -899,11 +900,18 @@ void phy_state_machine(struct work_struct *work)
phydev->adjust_link(phydev->attached_dev);
break;
case PHY_RUNNING:
-   /* Only register a CHANGE if we are
-* polling or ignoring interrupts
+   /* Only register a CHANGE if we are polling or ignoring
+* interrupts and link changed since latest checking.
 */
-   if (!phy_interrupt_is_valid(phydev))
-   phydev->state = PHY_CHANGELINK;
+   if (!phy_interrupt_is_valid(phydev)) {
+   old_link = phydev->link;
+   err = phy_read_status(phydev);
+   if (err)
+   break;
+
+   if (old_link != phydev->link)
+   phydev->state = PHY_CHANGELINK;
+   }
break;
case PHY_CHANGELINK:
err = phy_read_status(phydev);
-- 
2.1.0.27.g96db324

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] net: phy: select copper mode when Marvel 88e1111 in SGMII

2015-08-07 Thread shh.xie
From: Madalin Bucur 

For the Marvel 88e PHY only two SGMII modes are available, both
allowing only SGMII to copper mode (with or without clock). SGMII
to fiber mode is not supported. Make sure the fiber/copper registers
selector bits are cleared for selecting copper mode.

Signed-off-by: Madalin Bucur 
Signed-off-by: Shaohui Xie 
---
 drivers/net/phy/marvell.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 3320a17..e6897b6 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -52,6 +52,7 @@
 #define MII_M1011_PHY_SCR_MDI_X0x0020
 #define MII_M1011_PHY_SCR_AUTO_CROSS   0x0060
 
+#define MII_M1145_PHY_EXT_ADDR_PAGE0x16
 #define MII_M1145_PHY_EXT_SR   0x1b
 #define MII_M1145_PHY_EXT_CR   0x14
 #define MII_M1145_RGMII_RX_DELAY   0x0080
@@ -552,6 +553,16 @@ static int m88e_config_init(struct phy_device *phydev)
err = phy_write(phydev, MII_M_PHY_EXT_SR, temp);
if (err < 0)
return err;
+
+   /* make sure copper is selected */
+   err = phy_read(phydev, MII_M1145_PHY_EXT_ADDR_PAGE);
+   if (err < 0)
+   return err;
+
+   err = phy_write(phydev, MII_M1145_PHY_EXT_ADDR_PAGE,
+   err & (~0xff));
+   if (err < 0)
+   return err;
}
 
if (phydev->interface == PHY_INTERFACE_MODE_RTBI) {
-- 
2.1.0.27.g96db324

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] net: phy: add RealTek RTL8211DN phy id

2015-08-06 Thread shh.xie
From: Shaohui Xie 

RTL8211DN is compatible with RTL8211E.

Signed-off-by: Shaohui Xie 
---
 drivers/net/phy/realtek.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 4535361..43ab691 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -137,6 +137,19 @@ static struct phy_driver realtek_drvs[] = {
.config_intr= &rtl8211b_config_intr,
.driver = { .owner = THIS_MODULE,},
}, {
+   .phy_id = 0x001cc914,
+   .name   = "RTL8211DN Gigabit Ethernet",
+   .phy_id_mask= 0x001f,
+   .features   = PHY_GBIT_FEATURES,
+   .flags  = PHY_HAS_INTERRUPT,
+   .config_aneg= genphy_config_aneg,
+   .read_status= genphy_read_status,
+   .ack_interrupt  = rtl821x_ack_interrupt,
+   .config_intr= rtl8211e_config_intr,
+   .suspend= genphy_suspend,
+   .resume = genphy_resume,
+   .driver = { .owner = THIS_MODULE,},
+   }, {
.phy_id = 0x001cc915,
.name   = "RTL8211E Gigabit Ethernet",
.phy_id_mask= 0x001f,
@@ -170,6 +183,7 @@ module_phy_driver(realtek_drvs);
 
 static struct mdio_device_id __maybe_unused realtek_tbl[] = {
{ 0x001cc912, 0x001f },
+   { 0x001cc914, 0x001f },
{ 0x001cc915, 0x001f },
{ 0x001cc916, 0x001f },
{ }
-- 
2.1.0.27.g96db324

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH][v3] net: phy: add driver for aquantia phy

2015-07-31 Thread shh.xie
From: Shaohui Xie 

This patch added driver to support Aquantia PHYs AQ1202, AQ2104, AQR105,
AQR405, which accessed through clause 45.

Signed-off-by: Shaohui Xie 
---
changes in v3:
removed nop routines.

changes in v2:
addressed Florian's comments.

 drivers/net/phy/Kconfig|   5 ++
 drivers/net/phy/Makefile   |   1 +
 drivers/net/phy/aquantia.c | 152 +
 3 files changed, 158 insertions(+)
 create mode 100644 drivers/net/phy/aquantia.c

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 8ef8191..c07030d 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -14,6 +14,11 @@ if PHYLIB
 
 comment "MII PHY device drivers"
 
+config AQUANTIA_PHY
+tristate "Drivers for the Aquantia PHYs"
+---help---
+  Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
+
 config AT803X_PHY
tristate "Drivers for Atheros AT803X PHYs"
---help---
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 16aac1c..9bb1033 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -3,6 +3,7 @@
 libphy-objs:= phy.o phy_device.o mdio_bus.o
 
 obj-$(CONFIG_PHYLIB)   += libphy.o
+obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o
 obj-$(CONFIG_MARVELL_PHY)  += marvell.o
 obj-$(CONFIG_DAVICOM_PHY)  += davicom.o
 obj-$(CONFIG_CICADA_PHY)   += cicada.o
diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
new file mode 100644
index 000..73d347d
--- /dev/null
+++ b/drivers/net/phy/aquantia.c
@@ -0,0 +1,152 @@
+/*
+ * Driver for Aquantia PHY
+ *
+ * Author: Shaohui Xie 
+ *
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PHY_ID_AQ1202  0x03a1b445
+#define PHY_ID_AQ2104  0x03a1b460
+#define PHY_ID_AQR105  0x03a1b4a2
+#define PHY_ID_AQR405  0x03a1b4b0
+
+#define PHY_AQUANTIA_FEATURES  (SUPPORTED_1baseT_Full | \
+SUPPORTED_1000baseT_Full | \
+SUPPORTED_100baseT_Full | \
+PHY_DEFAULT_FEATURES)
+
+static int aquantia_config_aneg(struct phy_device *phydev)
+{
+   phydev->supported = PHY_AQUANTIA_FEATURES;
+   phydev->advertising = phydev->supported;
+
+   return 0;
+}
+
+static int aquantia_aneg_done(struct phy_device *phydev)
+{
+   int reg;
+
+   reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
+   return (reg < 0) ? reg : (reg & BMSR_ANEGCOMPLETE);
+}
+
+static int aquantia_read_status(struct phy_device *phydev)
+{
+   int reg;
+
+   reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
+   reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
+   if (reg & MDIO_STAT1_LSTATUS)
+   phydev->link = 1;
+   else
+   phydev->link = 0;
+
+   reg = phy_read_mmd(phydev, MDIO_MMD_AN, 0xc800);
+   mdelay(10);
+   reg = phy_read_mmd(phydev, MDIO_MMD_AN, 0xc800);
+
+   switch (reg) {
+   case 0x9:
+   phydev->speed = SPEED_2500;
+   break;
+   case 0x5:
+   phydev->speed = SPEED_1000;
+   break;
+   case 0x3:
+   phydev->speed = SPEED_100;
+   break;
+   case 0x7:
+   default:
+   phydev->speed = SPEED_1;
+   break;
+   }
+   phydev->duplex = DUPLEX_FULL;
+
+   return 0;
+}
+
+static struct phy_driver aquantia_driver[] = {
+{
+   .phy_id = PHY_ID_AQ1202,
+   .phy_id_mask= 0xfff0,
+   .name   = "Aquantia AQ1202",
+   .features   = PHY_AQUANTIA_FEATURES,
+   .aneg_done  = aquantia_aneg_done,
+   .config_aneg= aquantia_config_aneg,
+   .read_status= aquantia_read_status,
+   .driver = { .owner = THIS_MODULE,},
+},
+{
+   .phy_id = PHY_ID_AQ2104,
+   .phy_id_mask= 0xfff0,
+   .name   = "Aquantia AQ2104",
+   .features   = PHY_AQUANTIA_FEATURES,
+   .aneg_done  = aquantia_aneg_done,
+   .config_aneg= aquantia_config_aneg,
+   .read_status= aquantia_read_status,
+   .driver = { .owner = THIS_MODULE,},
+},
+{
+   .phy_id = PHY_ID_AQR105,
+   .phy_id_mask= 0xfff0,
+   .name   = "Aquantia AQR105",
+   .features   = PHY_AQUANTIA_FEATURES,
+   .aneg_done  = aquantia_aneg_done,
+   .config_aneg= aquantia_config_aneg,
+   .read_status= aquantia_read_status,
+   .driver = { .owner = THIS_MODULE,},
+},
+{
+   .phy_id = PHY_ID_AQR405,
+   .phy_id_mask= 0xfff0,
+   .name   = "Aquantia AQR405",
+  

[PATCH][v2] net: phy: add driver for aquantia phy

2015-07-29 Thread shh.xie
From: Shaohui Xie 

This patch added driver to support Aquantia PHYs AQ1202, AQ2104, AQR105,
AQR405, which accessed through clause 45.

Signed-off-by: Shaohui Xie 
---
changes in v2:
addressed Florian's comments.

 drivers/net/phy/Kconfig|   5 ++
 drivers/net/phy/Makefile   |   1 +
 drivers/net/phy/aquantia.c | 170 +
 3 files changed, 176 insertions(+)
 create mode 100644 drivers/net/phy/aquantia.c

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 8ef8191..c07030d 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -14,6 +14,11 @@ if PHYLIB
 
 comment "MII PHY device drivers"
 
+config AQUANTIA_PHY
+tristate "Drivers for the Aquantia PHYs"
+---help---
+  Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
+
 config AT803X_PHY
tristate "Drivers for Atheros AT803X PHYs"
---help---
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 16aac1c..9bb1033 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -3,6 +3,7 @@
 libphy-objs:= phy.o phy_device.o mdio_bus.o
 
 obj-$(CONFIG_PHYLIB)   += libphy.o
+obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o
 obj-$(CONFIG_MARVELL_PHY)  += marvell.o
 obj-$(CONFIG_DAVICOM_PHY)  += davicom.o
 obj-$(CONFIG_CICADA_PHY)   += cicada.o
diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
new file mode 100644
index 000..e57301a
--- /dev/null
+++ b/drivers/net/phy/aquantia.c
@@ -0,0 +1,170 @@
+/*
+ * Driver for Aquantia PHY
+ *
+ * Author: Shaohui Xie 
+ *
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PHY_ID_AQ1202  0x03a1b445
+#define PHY_ID_AQ2104  0x03a1b460
+#define PHY_ID_AQR105  0x03a1b4a2
+#define PHY_ID_AQR405  0x03a1b4b0
+
+#define PHY_AQUANTIA_FEATURES  (SUPPORTED_1baseT_Full | \
+SUPPORTED_1000baseT_Full | \
+SUPPORTED_100baseT_Full | \
+PHY_DEFAULT_FEATURES)
+
+static int aquantia_soft_reset(struct phy_device *phydev)
+{
+   return 0;
+}
+
+static int aquantia_config_init(struct phy_device *phydev)
+{
+   return 0;
+}
+
+static int aquantia_config_aneg(struct phy_device *phydev)
+{
+   phydev->supported = PHY_AQUANTIA_FEATURES;
+   phydev->advertising = phydev->supported;
+
+   return 0;
+}
+
+static int aquantia_aneg_done(struct phy_device *phydev)
+{
+   int reg;
+
+   reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
+   return (reg < 0) ? reg : (reg & BMSR_ANEGCOMPLETE);
+}
+
+static int aquantia_read_status(struct phy_device *phydev)
+{
+   int reg;
+
+   reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
+   reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
+   if (reg & MDIO_STAT1_LSTATUS)
+   phydev->link = 1;
+   else
+   phydev->link = 0;
+
+   reg = phy_read_mmd(phydev, MDIO_MMD_AN, 0xc800);
+   mdelay(10);
+   reg = phy_read_mmd(phydev, MDIO_MMD_AN, 0xc800);
+
+   switch (reg) {
+   case 0x9:
+   phydev->speed = SPEED_2500;
+   break;
+   case 0x5:
+   phydev->speed = SPEED_1000;
+   break;
+   case 0x3:
+   phydev->speed = SPEED_100;
+   break;
+   case 0x7:
+   default:
+   phydev->speed = SPEED_1;
+   break;
+   }
+   phydev->duplex = DUPLEX_FULL;
+
+   return 0;
+}
+
+static struct phy_driver aquantia_driver[] = {
+{
+   .phy_id = PHY_ID_AQ1202,
+   .phy_id_mask= 0xfff0,
+   .name   = "Aquantia AQ1202",
+   .features   = PHY_AQUANTIA_FEATURES,
+   .soft_reset = aquantia_soft_reset,
+   .aneg_done  = aquantia_aneg_done,
+   .config_init= aquantia_config_init,
+   .config_aneg= aquantia_config_aneg,
+   .read_status= aquantia_read_status,
+   .driver = { .owner = THIS_MODULE,},
+},
+{
+   .phy_id = PHY_ID_AQ2104,
+   .phy_id_mask= 0xfff0,
+   .name   = "Aquantia AQ2104",
+   .features   = PHY_AQUANTIA_FEATURES,
+   .soft_reset = aquantia_soft_reset,
+   .aneg_done  = aquantia_aneg_done,
+   .config_init= aquantia_config_init,
+   .config_aneg= aquantia_config_aneg,
+   .read_status= aquantia_read_status,
+   .driver = { .owner = THIS_MODULE,},
+},
+{
+   .phy_id = PHY_ID_AQR105,
+   .phy_id_mask= 0xfff0,
+   .name   = "Aquantia AQR105",
+   .features   = PHY_AQUANTIA_FEATURES,
+   .

[PATCH] net: phy: fix auto negotiation checking for teranetics

2015-07-24 Thread shh.xie
From: Shaohui Xie 

When using fiber port, the phy cannot report it's auto negotiation state,
driver should always report auto negotiation is done when using fiber port.

Signed-off-by: Shaohui Xie 
---
 drivers/net/phy/teranetics.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/teranetics.c b/drivers/net/phy/teranetics.c
index 7dcb5aa..91e1bec 100644
--- a/drivers/net/phy/teranetics.c
+++ b/drivers/net/phy/teranetics.c
@@ -51,8 +51,15 @@ static int teranetics_aneg_done(struct phy_device *phydev)
 {
int reg;
 
-   reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
-   return (reg < 0) ? reg : (reg & BMSR_ANEGCOMPLETE);
+   /* auto negotiation state can only be checked when using copper
+* port, if using fiber port, just lie it's done.
+*/
+   if (!phy_read_mmd(phydev, MDIO_MMD_VEND1, 93)) {
+   reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
+   return (reg < 0) ? reg : (reg & BMSR_ANEGCOMPLETE);
+   }
+
+   return 1;
 }
 
 static int teranetics_config_aneg(struct phy_device *phydev)
-- 
2.1.0.27.g96db324

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] phylib: add driver for aquantia phy

2015-07-23 Thread shh.xie
From: Shaohui Xie 

This patch added driver to support Aquantia PHYs AQ1202, AQ2104, AQR105,
AQR405, which accessed through clause 45.

Signed-off-by: Shaohui Xie 
---
 drivers/net/phy/Kconfig|   5 ++
 drivers/net/phy/Makefile   |   1 +
 drivers/net/phy/aquantia.c | 157 +
 3 files changed, 163 insertions(+)
 create mode 100644 drivers/net/phy/aquantia.c

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index d6aff87..839b84c 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -14,6 +14,11 @@ if PHYLIB
 
 comment "MII PHY device drivers"
 
+config AQUANTIA_PHY
+tristate "Drivers for the Aquantia PHYs"
+---help---
+  Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
+
 config AT803X_PHY
tristate "Drivers for Atheros AT803X PHYs"
---help---
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 16aac1c..9bb1033 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -3,6 +3,7 @@
 libphy-objs:= phy.o phy_device.o mdio_bus.o
 
 obj-$(CONFIG_PHYLIB)   += libphy.o
+obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o
 obj-$(CONFIG_MARVELL_PHY)  += marvell.o
 obj-$(CONFIG_DAVICOM_PHY)  += davicom.o
 obj-$(CONFIG_CICADA_PHY)   += cicada.o
diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
new file mode 100644
index 000..cb848f95
--- /dev/null
+++ b/drivers/net/phy/aquantia.c
@@ -0,0 +1,157 @@
+/*
+ * Driver for Aquantia PHY
+ *
+ * Author: Shaohui Xie 
+ *
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PHY_ID_AQ1202  0x03a1b445
+#define PHY_ID_AQ2104  0x03a1b460
+#define PHY_ID_AQR105  0x03a1b4a2
+#define PHY_ID_AQR405  0x03a1b4b0
+
+static int aquantia_soft_reset(struct phy_device *phydev)
+{
+   return 0;
+}
+
+static int aquantia_config_init(struct phy_device *phydev)
+{
+   return 0;
+}
+
+static int aquantia_config_aneg(struct phy_device *phydev)
+{
+   phydev->supported = SUPPORTED_1baseT_Full | PHY_GBIT_FEATURES;
+   phydev->advertising = phydev->supported;
+
+   return 0;
+}
+
+static int aquantia_aneg_done(struct phy_device *phydev)
+{
+   int reg;
+
+   reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
+   return (reg < 0) ? reg : (reg & BMSR_ANEGCOMPLETE);
+}
+
+static int aquantia_read_status(struct phy_device *phydev)
+{
+   int reg;
+
+   phydev->speed = SPEED_1;
+   phydev->duplex = DUPLEX_FULL;
+
+   reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
+   reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
+   if (reg & MDIO_STAT1_LSTATUS)
+   phydev->link = 1;
+   else
+   phydev->link = 0;
+
+   reg = phy_read_mmd(phydev, MDIO_MMD_AN, 0xc800);
+   mdelay(10);
+   reg = phy_read_mmd(phydev, MDIO_MMD_AN, 0xc800);
+   if (reg == 0x9)
+   phydev->speed = SPEED_2500;
+   else if (reg == 0x5)
+   phydev->speed = SPEED_1000;
+   else if (reg == 0x3)
+   phydev->speed = SPEED_100;
+
+   return 0;
+}
+
+static struct phy_driver aquantia_driver[] = {
+{
+   .phy_id = PHY_ID_AQ1202,
+   .phy_id_mask= 0xfff0,
+   .name   = "Aquantia AQ1202",
+   .features   = PHY_GBIT_FEATURES,
+   .soft_reset = aquantia_soft_reset,
+   .aneg_done  = aquantia_aneg_done,
+   .config_init= aquantia_config_init,
+   .config_aneg= aquantia_config_aneg,
+   .read_status= aquantia_read_status,
+   .driver = { .owner = THIS_MODULE,},
+},
+{
+   .phy_id = PHY_ID_AQ2104,
+   .phy_id_mask= 0xfff0,
+   .name   = "Aquantia AQ2104",
+   .features   = PHY_GBIT_FEATURES,
+   .soft_reset = aquantia_soft_reset,
+   .aneg_done  = aquantia_aneg_done,
+   .config_init= aquantia_config_init,
+   .config_aneg= aquantia_config_aneg,
+   .read_status= aquantia_read_status,
+   .driver = { .owner = THIS_MODULE,},
+},
+{
+   .phy_id = PHY_ID_AQR105,
+   .phy_id_mask= 0xfff0,
+   .name   = "Aquantia AQR105",
+   .features   = PHY_GBIT_FEATURES,
+   .soft_reset = aquantia_soft_reset,
+   .aneg_done  = aquantia_aneg_done,
+   .config_init= aquantia_config_init,
+   .config_aneg= aquantia_config_aneg,
+   .read_status= aquantia_read_status,
+   .driver = { .owner = THIS_MODULE,},
+},
+{
+   .phy_id = PHY_ID_AQR405,
+   .phy_id_mask= 0xfff0,
+   .name   = "Aquantia AQR405",
+

[PATCH] net/mdio: fix mdio_bus_match for c45 PHY

2015-07-17 Thread shh.xie
From: Shaohui Xie 

We store c45 PHY's id information in c45_ids, so it should be used to
check the matching between PHY driver and PHY device for c45 PHY.

Signed-off-by: Shaohui Xie 
---
 drivers/net/phy/mdio_bus.c | 19 +--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 095ef3f..46a14cb 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -421,6 +421,8 @@ static int mdio_bus_match(struct device *dev, struct 
device_driver *drv)
 {
struct phy_device *phydev = to_phy_device(dev);
struct phy_driver *phydrv = to_phy_driver(drv);
+   const int num_ids = ARRAY_SIZE(phydev->c45_ids.device_ids);
+   int i;
 
if (of_driver_match_device(dev, drv))
return 1;
@@ -428,8 +430,21 @@ static int mdio_bus_match(struct device *dev, struct 
device_driver *drv)
if (phydrv->match_phy_device)
return phydrv->match_phy_device(phydev);
 
-   return (phydrv->phy_id & phydrv->phy_id_mask) ==
-   (phydev->phy_id & phydrv->phy_id_mask);
+   if (phydev->is_c45) {
+   for (i = 1; i < num_ids; i++) {
+   if (!(phydev->c45_ids.devices_in_package & (1 << i)))
+   continue;
+
+   if ((phydrv->phy_id & phydrv->phy_id_mask) ==
+   (phydev->c45_ids.device_ids[i] &
+phydrv->phy_id_mask))
+   return 1;
+   }
+   return 0;
+   } else {
+   return (phydrv->phy_id & phydrv->phy_id_mask) ==
+   (phydev->phy_id & phydrv->phy_id_mask);
+   }
 }
 
 #ifdef CONFIG_PM
-- 
2.1.0.27.g96db324

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] phylib: add driver for Teranetics TN2020

2015-07-16 Thread shh.xie
From: Shaohui Xie 

Teranetics TN2020 is compliant with IEEE 802.3an 10 Gigabit.

Signed-off-by: Shaohui Xie 
---
 drivers/net/phy/Kconfig  |   5 ++
 drivers/net/phy/Makefile |   1 +
 drivers/net/phy/teranetics.c | 128 +++
 3 files changed, 134 insertions(+)
 create mode 100644 drivers/net/phy/teranetics.c

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index cf18940..a8225c5 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -54,6 +54,11 @@ config VITESSE_PHY
 ---help---
   Currently supports the vsc8244
 
+config TERANETICS_PHY
+tristate "Drivers for the Teranetics PHYs"
+---help---
+  Currently supports the Teranetics TN2020
+
 config SMSC_PHY
tristate "Drivers for SMSC PHYs"
---help---
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index fcc25a0..16aac1c 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_CICADA_PHY)+= cicada.o
 obj-$(CONFIG_LXT_PHY)  += lxt.o
 obj-$(CONFIG_QSEMI_PHY)+= qsemi.o
 obj-$(CONFIG_SMSC_PHY) += smsc.o
+obj-$(CONFIG_TERANETICS_PHY)   += teranetics.o
 obj-$(CONFIG_VITESSE_PHY)  += vitesse.o
 obj-$(CONFIG_BROADCOM_PHY) += broadcom.o
 obj-$(CONFIG_BCM63XX_PHY)  += bcm63xx.o
diff --git a/drivers/net/phy/teranetics.c b/drivers/net/phy/teranetics.c
new file mode 100644
index 000..7dcb5aa
--- /dev/null
+++ b/drivers/net/phy/teranetics.c
@@ -0,0 +1,128 @@
+/*
+ * Driver for Teranetics PHY
+ *
+ * Author: Shaohui Xie 
+ *
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+MODULE_DESCRIPTION("Teranetics PHY driver");
+MODULE_AUTHOR("Shaohui Xie ");
+MODULE_LICENSE("GPL v2");
+
+#define PHY_ID_TN2020  0x00a19410
+#define MDIO_PHYXS_LNSTAT_SYNC00x0001
+#define MDIO_PHYXS_LNSTAT_SYNC10x0002
+#define MDIO_PHYXS_LNSTAT_SYNC20x0004
+#define MDIO_PHYXS_LNSTAT_SYNC30x0008
+#define MDIO_PHYXS_LNSTAT_ALIGN 0x1000
+
+#define MDIO_PHYXS_LANE_READY  (MDIO_PHYXS_LNSTAT_SYNC0 | \
+   MDIO_PHYXS_LNSTAT_SYNC1 | \
+   MDIO_PHYXS_LNSTAT_SYNC2 | \
+   MDIO_PHYXS_LNSTAT_SYNC3 | \
+   MDIO_PHYXS_LNSTAT_ALIGN)
+
+static int teranetics_config_init(struct phy_device *phydev)
+{
+   phydev->supported = SUPPORTED_1baseT_Full;
+   phydev->advertising = SUPPORTED_1baseT_Full;
+
+   return 0;
+}
+
+static int teranetics_soft_reset(struct phy_device *phydev)
+{
+   return 0;
+}
+
+static int teranetics_aneg_done(struct phy_device *phydev)
+{
+   int reg;
+
+   reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
+   return (reg < 0) ? reg : (reg & BMSR_ANEGCOMPLETE);
+}
+
+static int teranetics_config_aneg(struct phy_device *phydev)
+{
+   return 0;
+}
+
+static int teranetics_read_status(struct phy_device *phydev)
+{
+   int reg;
+
+   phydev->link = 1;
+
+   phydev->speed = SPEED_1;
+   phydev->duplex = DUPLEX_FULL;
+
+   if (!phy_read_mmd(phydev, MDIO_MMD_VEND1, 93)) {
+   reg = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_LNSTAT);
+   if (reg < 0 ||
+   !((reg & MDIO_PHYXS_LANE_READY) == MDIO_PHYXS_LANE_READY)) {
+   phydev->link = 0;
+   return 0;
+   }
+
+   reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
+   if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS))
+   phydev->link = 0;
+   }
+
+   return 0;
+}
+
+static int teranetics_match_phy_device(struct phy_device *phydev)
+{
+   return phydev->c45_ids.device_ids[3] == PHY_ID_TN2020;
+}
+
+static struct phy_driver teranetics_driver[] = {
+{
+   .phy_id = PHY_ID_TN2020,
+   .phy_id_mask= 0x,
+   .name   = "Teranetics TN2020",
+   .soft_reset = teranetics_soft_reset,
+   .aneg_done  = teranetics_aneg_done,
+   .config_init= teranetics_config_init,
+   .config_aneg= teranetics_config_aneg,
+   .read_status= teranetics_read_status,
+   .match_phy_device = teranetics_match_phy_device,
+   .driver = { .owner = THIS_MODULE,},
+},
+};
+
+static int __init teranetics_init(void)
+{
+   return phy_drivers_register(teranetics_driver,
+   ARRAY_SIZE(teranetics_driver));
+}
+
+static void __exit teranetics_exit(void)
+{
+   return phy_drivers_unregister(teranetics_driver,
+ ARRAY_SIZE(teranetics_driver));
+}
+
+module_init(teranetics_init

[PATCH] net/phy: Add Vitesse 8641 phy ID

2015-06-25 Thread shh.xie
From: Shaohui Xie 

Vitesse VSC8641 is compatible with Vitesse 82xx

Signed-off-by: Shaohui Xie 
---
 drivers/net/phy/vitesse.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c
index 76cad71..17cad18 100644
--- a/drivers/net/phy/vitesse.c
+++ b/drivers/net/phy/vitesse.c
@@ -66,6 +66,7 @@
 #define PHY_ID_VSC8244 0x000fc6c0
 #define PHY_ID_VSC8514 0x00070670
 #define PHY_ID_VSC8574 0x000704a0
+#define PHY_ID_VSC8641 0x00070431
 #define PHY_ID_VSC8662 0x00070660
 #define PHY_ID_VSC8221 0x000fc550
 #define PHY_ID_VSC8211 0x000fc4b0
@@ -272,6 +273,18 @@ static struct phy_driver vsc82xx_driver[] = {
.config_intr= &vsc82xx_config_intr,
.driver = { .owner = THIS_MODULE,},
 }, {
+   .phy_id = PHY_ID_VSC8641,
+   .name   = "Vitesse VSC8641",
+   .phy_id_mask= 0x0000,
+   .features   = PHY_GBIT_FEATURES,
+   .flags  = PHY_HAS_INTERRUPT,
+   .config_init= &vsc824x_config_init,
+   .config_aneg= &vsc82x4_config_aneg,
+   .read_status= &genphy_read_status,
+   .ack_interrupt  = &vsc824x_ack_interrupt,
+   .config_intr= &vsc82xx_config_intr,
+   .driver = { .owner = THIS_MODULE,},
+}, {
.phy_id = PHY_ID_VSC8662,
.name   = "Vitesse VSC8662",
.phy_id_mask= 0x0000,
@@ -318,6 +331,7 @@ static struct mdio_device_id __maybe_unused vitesse_tbl[] = 
{
{ PHY_ID_VSC8244, 0x000fffc0 },
{ PHY_ID_VSC8514, 0x0000 },
{ PHY_ID_VSC8574, 0x0000 },
+   { PHY_ID_VSC8641, 0x0000 },
{ PHY_ID_VSC8662, 0x0000 },
{ PHY_ID_VSC8221, 0x0000 },
{ PHY_ID_VSC8211, 0x0000 },
-- 
1.8.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html