diff mbox

net/fsl: Add mEMAC MDIO support to XGMAC MDIO

Message ID 1420364162-13109-1-git-send-email-shh.xie@gmail.com
State Accepted, archived
Delegated to: David Miller
Headers show

Commit Message

shaohui xie Jan. 4, 2015, 9:36 a.m. UTC
From: Andy Fleming <afleming@gmail.com>

The Freescale mEMAC supports operating at 10/100/1000/10G, and
its associated MDIO controller is likewise capable of operating
both Clause 22 and Clause 45 MDIO buses. It is nearly identical
to the MDIO controller on the XGMAC, so we just modify that
driver.

Portions of this driver developed by:

Sandeep Singh <sandeep@freescale.com>
Roy Zang <tie-fei.zang@freescale.com>

Signed-off-by: Andy Fleming <afleming@gmail.com>
Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
---
 drivers/net/ethernet/freescale/Kconfig      |  3 +-
 drivers/net/ethernet/freescale/xgmac_mdio.c | 64 ++++++++++++++++++++++++-----
 2 files changed, 55 insertions(+), 12 deletions(-)

Comments

David Miller Jan. 6, 2015, 10:18 p.m. UTC | #1
From: <shh.xie@gmail.com>
Date: Sun, 4 Jan 2015 17:36:02 +0800

> From: Andy Fleming <afleming@gmail.com>
> 
> The Freescale mEMAC supports operating at 10/100/1000/10G, and
> its associated MDIO controller is likewise capable of operating
> both Clause 22 and Clause 45 MDIO buses. It is nearly identical
> to the MDIO controller on the XGMAC, so we just modify that
> driver.
> 
> Portions of this driver developed by:
> 
> Sandeep Singh <sandeep@freescale.com>
> Roy Zang <tie-fei.zang@freescale.com>
> 
> Signed-off-by: Andy Fleming <afleming@gmail.com>
> Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>

Applied, thanks.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Emil Medve Jan. 9, 2015, 8:11 p.m. UTC | #2
Hello Shao-Hui,


On 01/04/2015 03:36 AM, shh.xie@gmail.com wrote:
> From: Andy Fleming <afleming@gmail.com>
> 
> The Freescale mEMAC supports operating at 10/100/1000/10G, and
> its associated MDIO controller is likewise capable of operating
> both Clause 22 and Clause 45 MDIO buses. It is nearly identical
> to the MDIO controller on the XGMAC, so we just modify that
> driver.
> 
> Portions of this driver developed by:
> 
> Sandeep Singh <sandeep@freescale.com>
> Roy Zang <tie-fei.zang@freescale.com>
> 
> Signed-off-by: Andy Fleming <afleming@gmail.com>
> Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
> ---
>  drivers/net/ethernet/freescale/Kconfig      |  3 +-
>  drivers/net/ethernet/freescale/xgmac_mdio.c | 64 ++++++++++++++++++++++++-----
>  2 files changed, 55 insertions(+), 12 deletions(-)
> 
> 	...
> 
> diff --git a/drivers/net/ethernet/freescale/xgmac_mdio.c b/drivers/net/ethernet/freescale/xgmac_mdio.c
> index a352445..e0fc3d1 100644
> --- a/drivers/net/ethernet/freescale/xgmac_mdio.c
> +++ b/drivers/net/ethernet/freescale/xgmac_mdio.c
> 
> 	...
> 
> @@ -123,21 +144,39 @@ static int xgmac_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 val
>  static int xgmac_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
>  {
>  	struct tgec_mdio_controller __iomem *regs = bus->priv;
> -	uint16_t dev_addr = regnum >> 16;
> +	uint16_t dev_addr;
> +	uint32_t mdio_stat;
>  	uint32_t mdio_ctl;
>  	uint16_t value;
>  	int ret;
>  
> +	mdio_stat = in_be32(&regs->mdio_stat);
> +	if (regnum & MII_ADDR_C45) {
> +		dev_addr = (regnum >> 16) & 0x1f;
> +		mdio_stat |= MDIO_STAT_ENC;
> +	} else {
> +		dev_addr = regnum & 0x1f;
> +		mdio_stat = ~MDIO_STAT_ENC;

Shouldn't this be 'mdio_stat &= ~MDIO_STAT_ENC'?


Cheers,
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
shaohui xie Jan. 12, 2015, 3:13 a.m. UTC | #3
Hello Emil,

> -----Original Message-----
> From: Emil Medve [mailto:Emilian.Medve@Freescale.com]
> Sent: Saturday, January 10, 2015 4:12 AM
> To: shh.xie@gmail.com; netdev@vger.kernel.org; davem@davemloft.net
> Cc: Andy Fleming; Xie Shaohui-B21989
> Subject: Re: [PATCH] net/fsl: Add mEMAC MDIO support to XGMAC MDIO
> 
> Hello Shao-Hui,
> 
> 
> On 01/04/2015 03:36 AM, shh.xie@gmail.com wrote:
> > From: Andy Fleming <afleming@gmail.com>
> >
> > The Freescale mEMAC supports operating at 10/100/1000/10G, and its
> > associated MDIO controller is likewise capable of operating both
> > Clause 22 and Clause 45 MDIO buses. It is nearly identical to the MDIO
> > controller on the XGMAC, so we just modify that driver.
> >
> > Portions of this driver developed by:
> >
> > Sandeep Singh <sandeep@freescale.com>
> > Roy Zang <tie-fei.zang@freescale.com>
> >
> > Signed-off-by: Andy Fleming <afleming@gmail.com>
> > Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
> > ---
> >  drivers/net/ethernet/freescale/Kconfig      |  3 +-
> >  drivers/net/ethernet/freescale/xgmac_mdio.c | 64
> > ++++++++++++++++++++++++-----
> >  2 files changed, 55 insertions(+), 12 deletions(-)
> >
> > 	...
> >
> > diff --git a/drivers/net/ethernet/freescale/xgmac_mdio.c
> > b/drivers/net/ethernet/freescale/xgmac_mdio.c
> > index a352445..e0fc3d1 100644
> > --- a/drivers/net/ethernet/freescale/xgmac_mdio.c
> > +++ b/drivers/net/ethernet/freescale/xgmac_mdio.c
> >
> > 	...
> >
> > @@ -123,21 +144,39 @@ static int xgmac_mdio_write(struct mii_bus *bus,
> > int phy_id, int regnum, u16 val  static int xgmac_mdio_read(struct
> > mii_bus *bus, int phy_id, int regnum)  {
> >  	struct tgec_mdio_controller __iomem *regs = bus->priv;
> > -	uint16_t dev_addr = regnum >> 16;
> > +	uint16_t dev_addr;
> > +	uint32_t mdio_stat;
> >  	uint32_t mdio_ctl;
> >  	uint16_t value;
> >  	int ret;
> >
> > +	mdio_stat = in_be32(&regs->mdio_stat);
> > +	if (regnum & MII_ADDR_C45) {
> > +		dev_addr = (regnum >> 16) & 0x1f;
> > +		mdio_stat |= MDIO_STAT_ENC;
> > +	} else {
> > +		dev_addr = regnum & 0x1f;
> > +		mdio_stat = ~MDIO_STAT_ENC;
> 
> Shouldn't this be 'mdio_stat &= ~MDIO_STAT_ENC'?
[S.H] You are right! should be "mdio_stat &= ~MDIO_STAT_ENC".
We have this bug for a long time!

I'll post a patch to fix it.

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

Patch

diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig
index 2703083..ba84c4a 100644
--- a/drivers/net/ethernet/freescale/Kconfig
+++ b/drivers/net/ethernet/freescale/Kconfig
@@ -69,7 +69,8 @@  config FSL_XGMAC_MDIO
 	select PHYLIB
 	select OF_MDIO
 	---help---
-	  This driver supports the MDIO bus on the Fman 10G Ethernet MACs.
+	  This driver supports the MDIO bus on the Fman 10G Ethernet MACs, and
+	  on the FMan mEMAC (which supports both Clauses 22 and 45)
 
 config UCC_GETH
 	tristate "Freescale QE Gigabit Ethernet"
diff --git a/drivers/net/ethernet/freescale/xgmac_mdio.c b/drivers/net/ethernet/freescale/xgmac_mdio.c
index a352445..e0fc3d1 100644
--- a/drivers/net/ethernet/freescale/xgmac_mdio.c
+++ b/drivers/net/ethernet/freescale/xgmac_mdio.c
@@ -32,6 +32,7 @@  struct tgec_mdio_controller {
 	__be32	mdio_addr;	/* MDIO address */
 } __packed;
 
+#define MDIO_STAT_ENC		BIT(6)
 #define MDIO_STAT_CLKDIV(x)	(((x>>1) & 0xff) << 8)
 #define MDIO_STAT_BSY		(1 << 0)
 #define MDIO_STAT_RD_ER		(1 << 1)
@@ -91,20 +92,40 @@  static int xgmac_wait_until_done(struct device *dev,
 static int xgmac_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value)
 {
 	struct tgec_mdio_controller __iomem *regs = bus->priv;
-	uint16_t dev_addr = regnum >> 16;
+	uint16_t dev_addr;
+	u32 mdio_ctl, mdio_stat;
 	int ret;
 
-	/* Set the port and dev addr */
-	out_be32(&regs->mdio_ctl,
-		 MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr));
+	mdio_stat = in_be32(&regs->mdio_stat);
+	if (regnum & MII_ADDR_C45) {
+		/* Clause 45 (ie 10G) */
+		dev_addr = (regnum >> 16) & 0x1f;
+		mdio_stat |= MDIO_STAT_ENC;
+	} else {
+		/* Clause 22 (ie 1G) */
+		dev_addr = regnum & 0x1f;
+		mdio_stat &= ~MDIO_STAT_ENC;
+	}
 
-	/* Set the register address */
-	out_be32(&regs->mdio_addr, regnum & 0xffff);
+	out_be32(&regs->mdio_stat, mdio_stat);
 
 	ret = xgmac_wait_until_free(&bus->dev, regs);
 	if (ret)
 		return ret;
 
+	/* Set the port and dev addr */
+	mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr);
+	out_be32(&regs->mdio_ctl, mdio_ctl);
+
+	/* Set the register address */
+	if (regnum & MII_ADDR_C45) {
+		out_be32(&regs->mdio_addr, regnum & 0xffff);
+
+		ret = xgmac_wait_until_free(&bus->dev, regs);
+		if (ret)
+			return ret;
+	}
+
 	/* Write the value to the register */
 	out_be32(&regs->mdio_data, MDIO_DATA(value));
 
@@ -123,21 +144,39 @@  static int xgmac_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 val
 static int xgmac_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
 {
 	struct tgec_mdio_controller __iomem *regs = bus->priv;
-	uint16_t dev_addr = regnum >> 16;
+	uint16_t dev_addr;
+	uint32_t mdio_stat;
 	uint32_t mdio_ctl;
 	uint16_t value;
 	int ret;
 
+	mdio_stat = in_be32(&regs->mdio_stat);
+	if (regnum & MII_ADDR_C45) {
+		dev_addr = (regnum >> 16) & 0x1f;
+		mdio_stat |= MDIO_STAT_ENC;
+	} else {
+		dev_addr = regnum & 0x1f;
+		mdio_stat = ~MDIO_STAT_ENC;
+	}
+
+	out_be32(&regs->mdio_stat, mdio_stat);
+
+	ret = xgmac_wait_until_free(&bus->dev, regs);
+	if (ret)
+		return ret;
+
 	/* Set the Port and Device Addrs */
 	mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr);
 	out_be32(&regs->mdio_ctl, mdio_ctl);
 
 	/* Set the register address */
-	out_be32(&regs->mdio_addr, regnum & 0xffff);
+	if (regnum & MII_ADDR_C45) {
+		out_be32(&regs->mdio_addr, regnum & 0xffff);
 
-	ret = xgmac_wait_until_free(&bus->dev, regs);
-	if (ret)
-		return ret;
+		ret = xgmac_wait_until_free(&bus->dev, regs);
+		if (ret)
+			return ret;
+	}
 
 	/* Initiate the read */
 	out_be32(&regs->mdio_ctl, mdio_ctl | MDIO_CTL_READ);
@@ -224,6 +263,9 @@  static struct of_device_id xgmac_mdio_match[] = {
 	{
 		.compatible = "fsl,fman-xmdio",
 	},
+	{
+		.compatible = "fsl,fman-memac-mdio",
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, xgmac_mdio_match);