diff mbox

[U-Boot,1/2,v2] driver: net: ldpaa_eth: Add support of PHY framework

Message ID 1456313531-14536-1-git-send-email-prabhakar.kushwaha@nxp.com
State Accepted
Delegated to: York Sun
Headers show

Commit Message

Prabhakar Kushwaha Feb. 24, 2016, 11:32 a.m. UTC
This patch integrate DPAA2 ethernet driver existing PHY framework.

Call phy_connect and phy_config as per available DPMAC id defined
in SerDes Protcol.

Signed-off-by: Pratiyush Mohan Srivastava <pratiyush.srivastava@nxp.com>
Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
---
Changes for v2: Incorporated Joe Hershberger's comments

 drivers/net/ldpaa_eth/ldpaa_eth.c | 121 +++++++++++++++++++++++++++-----------
 1 file changed, 87 insertions(+), 34 deletions(-)

Comments

Prabhakar Kushwaha March 8, 2016, 2:36 a.m. UTC | #1
Hi Joe,

I have incorporated your review comments on this patch. 
Please review it and let me know if any other changes are required.

Regards,
Prabhakar


> -----Original Message-----
> From: Prabhakar Kushwaha [mailto:prabhakar.kushwaha@nxp.com]
> Sent: Wednesday, February 24, 2016 5:02 PM
> To: u-boot@lists.denx.de
> Cc: joe.hershberger@gmail.com; york sun <york.sun@nxp.com>; Prabhakar
> Kushwaha <prabhakar.kushwaha@nxp.com>; Pratiyush Srivastava
> <pratiyush.srivastava@nxp.com>
> Subject: [PATCH 1/2][v2] driver: net: ldpaa_eth: Add support of PHY
> framework
> 
> This patch integrate DPAA2 ethernet driver existing PHY framework.
> 
> Call phy_connect and phy_config as per available DPMAC id defined in
> SerDes Protcol.
> 
> Signed-off-by: Pratiyush Mohan Srivastava <pratiyush.srivastava@nxp.com>
> Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
> ---
> Changes for v2: Incorporated Joe Hershberger's comments
> 
>  drivers/net/ldpaa_eth/ldpaa_eth.c | 121
> +++++++++++++++++++++++++++-----------
>  1 file changed, 87 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c
> b/drivers/net/ldpaa_eth/ldpaa_eth.c
> index 7f96883..8a00bc3 100644
> --- a/drivers/net/ldpaa_eth/ldpaa_eth.c
> +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c
> @@ -14,15 +14,32 @@
>  #include <linux/compat.h>
>  #include <fsl-mc/fsl_dpmac.h>
> 
> +#include <fsl-mc/ldpaa_wriop.h>
>  #include "ldpaa_eth.h"
> 
> -#undef CONFIG_PHYLIB
> +#ifdef CONFIG_PHYLIB
>  static int init_phy(struct eth_device *dev)  {
> -	/*TODO for external PHY */
> +	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
> +	struct phy_device *phydev = NULL;
> +	struct mii_dev *bus;
> 
> -	return 0;
> +	bus = wriop_get_mdio(priv->dpmac_id);
> +	if (bus == NULL)
> +		return 0;
> +
> +	phydev = phy_connect(bus, wriop_get_phy_address(priv-
> >dpmac_id),
> +			     dev, wriop_get_enet_if(priv->dpmac_id));
> +	if (!phydev) {
> +		printf("Failed to connect\n");
> +		return -1;
> +	}
> +
> +	priv->phydev = phydev;
> +
> +	return phy_config(phydev);
>  }
> +#endif
> 
>  #ifdef DEBUG
>  static void ldpaa_eth_get_dpni_counter(void) @@ -380,7 +397,9 @@ static
> int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)  #ifdef DEBUG
>  	struct dpni_link_state link_state;
>  #endif
> -	int err;
> +	int err = 0;
> +	struct mii_dev *bus;
> +	phy_interface_t enet_if;
> 
>  	if (net_dev->state == ETH_STATE_ACTIVE)
>  		return 0;
> @@ -394,11 +413,48 @@ static int ldpaa_eth_open(struct eth_device
> *net_dev, bd_t *bd)
>  		printf("ERROR (DPL is deployed. No device available)\n");
>  		return -ENODEV;
>  	}
> +
>  	/* DPMAC initialization */
>  	err = ldpaa_dpmac_setup(priv);
>  	if (err < 0)
>  		goto err_dpmac_setup;
> 
> +#ifdef CONFIG_PHYLIB
> +	if (priv->phydev)
> +		err = phy_startup(priv->phydev);
> +		if (err) {
> +			printf("%s: Could not initialize\n",
> +			       priv->phydev->dev->name);
> +			goto err_dpamc_bind;
> +		}
> +#else
> +	priv->phydev = (struct phy_device *)malloc(sizeof(struct
> phy_device));
> +	memset(priv->phydev, 0, sizeof(struct phy_device));
> +
> +	priv->phydev->speed = SPEED_1000;
> +	priv->phydev->link = 1;
> +	priv->phydev->duplex = DUPLEX_FULL;
> +#endif
> +
> +	bus = wriop_get_mdio(priv->dpmac_id);
> +	enet_if = wriop_get_enet_if(priv->dpmac_id);
> +	if ((bus == NULL) &&
> +	    (enet_if == PHY_INTERFACE_MODE_XGMII)) {
> +		priv->phydev = (struct phy_device *)
> +				malloc(sizeof(struct phy_device));
> +		memset(priv->phydev, 0, sizeof(struct phy_device));
> +
> +		priv->phydev->speed = SPEED_10000;
> +		priv->phydev->link = 1;
> +		priv->phydev->duplex = DUPLEX_FULL;
> +	}
> +
> +	if (!priv->phydev->link) {
> +		printf("%s: No link.\n", priv->phydev->dev->name);
> +		err = -1;
> +		goto err_dpamc_bind;
> +	}
> +
>  	/* DPMAC binding DPNI */
>  	err = ldpaa_dpmac_bind(priv);
>  	if (err)
> @@ -425,28 +481,24 @@ static int ldpaa_eth_open(struct eth_device
> *net_dev, bd_t *bd)
>  		return err;
>  	}
> 
> -#ifdef CONFIG_PHYLIB
> -	/* TODO Check this path */
> -	err = phy_startup(priv->phydev);
> -	if (err) {
> -		printf("%s: Could not initialize\n", priv->phydev->dev-
> >name);
> -		return err;
> -	}
> -#else
> -	priv->phydev->speed = SPEED_1000;
> -	priv->phydev->link = 1;
> -	priv->phydev->duplex = DUPLEX_FULL;
> -#endif
> -
>  	err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni-
> >dpni_handle);
>  	if (err < 0) {
>  		printf("dpni_enable() failed\n");
>  		return err;
>  	}
> 
> -	dpmac_link_state.rate = SPEED_1000;
> -	dpmac_link_state.options = DPMAC_LINK_OPT_AUTONEG;
> -	dpmac_link_state.up = 1;
> +	dpmac_link_state.rate = priv->phydev->speed;
> +
> +	if (priv->phydev->autoneg == AUTONEG_DISABLE)
> +		dpmac_link_state.options &=
> ~DPMAC_LINK_OPT_AUTONEG;
> +	else
> +		dpmac_link_state.options |= DPMAC_LINK_OPT_AUTONEG;
> +
> +	if (priv->phydev->duplex == DUPLEX_HALF)
> +		dpmac_link_state.options |=
> DPMAC_LINK_OPT_HALF_DUPLEX;
> +
> +	dpmac_link_state.up = priv->phydev->link;
> +
>  	err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
>  				  priv->dpmac_handle, &dpmac_link_state);
>  	if (err < 0) {
> @@ -484,10 +536,7 @@ static int ldpaa_eth_open(struct eth_device
> *net_dev, bd_t *bd)
>  		goto err_qdid;
>  	}
> 
> -	if (!priv->phydev->link)
> -		printf("%s: No link.\n", priv->phydev->dev->name);
> -
> -	return priv->phydev->link ? 0 : -1;
> +	return priv->phydev->link;
> 
>  err_qdid:
>  err_rx_flow:
> @@ -495,9 +544,10 @@ err_rx_flow:
>  err_dpni_bind:
>  	ldpaa_dpbp_free();
>  err_dpbp_setup:
> -err_dpamc_bind:
>  	dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni-
> >dpni_handle);
>  err_dpni_setup:
> +err_dpamc_bind:
> +	dpmac_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, priv-
> >dpmac_handle);
>  err_dpmac_setup:
>  	return err;
>  }
> @@ -506,6 +556,9 @@ static void ldpaa_eth_stop(struct eth_device
> *net_dev)  {
>  	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev-
> >priv;
>  	int err = 0;
> +#ifdef CONFIG_PHYLIB
> +	struct mii_dev *bus = wriop_get_mdio(priv->dpmac_id); #endif
> 
>  	if ((net_dev->state == ETH_STATE_PASSIVE) ||
>  	    (net_dev->state == ETH_STATE_INIT)) @@ -531,7 +584,10 @@
> static void ldpaa_eth_stop(struct eth_device *net_dev)
>  		printf("dpni_disable() failed\n");
> 
>  #ifdef CONFIG_PHYLIB
> -	phy_shutdown(priv->phydev);
> +	if (priv->phydev && bus != NULL)
> +		phy_shutdown(priv->phydev);
> +	else
> +		free(priv->phydev);
>  #endif
> 
>  	ldpaa_dpbp_free();
> @@ -914,15 +970,12 @@ static int ldpaa_eth_netdev_init(struct eth_device
> *net_dev,
>  	net_dev->halt = ldpaa_eth_stop;
>  	net_dev->send = ldpaa_eth_tx;
>  	net_dev->recv = ldpaa_eth_pull_dequeue_rx;
> -/*
> -	TODO: PHY MDIO information
> -	priv->bus = info->bus;
> -	priv->phyaddr = info->phy_addr;
> -	priv->enet_if = info->enet_if;
> -*/
> 
> -	if (init_phy(net_dev))
> -		return 0;
> +#ifdef CONFIG_PHYLIB
> +	err = init_phy(net_dev);
> +	if (err < 0)
> +		return err;
> +#endif
> 
>  	err = eth_register(net_dev);
>  	if (err < 0) {
> --
> 1.9.1
>
York Sun March 18, 2016, 4:25 p.m. UTC | #2
On 02/24/2016 03:32 AM, Prabhakar Kushwaha wrote:
> This patch integrate DPAA2 ethernet driver existing PHY framework.
> 
> Call phy_connect and phy_config as per available DPMAC id defined
> in SerDes Protcol.
> 
> Signed-off-by: Pratiyush Mohan Srivastava <pratiyush.srivastava@nxp.com>
> Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
> ---
> Changes for v2: Incorporated Joe Hershberger's comments
> 

Since Joe didn't comment on this version, I presume he is OK with this one.

<snip>

> @@ -914,15 +970,12 @@ static int ldpaa_eth_netdev_init(struct eth_device *net_dev,
>  	net_dev->halt = ldpaa_eth_stop;
>  	net_dev->send = ldpaa_eth_tx;
>  	net_dev->recv = ldpaa_eth_pull_dequeue_rx;
> -/*
> -	TODO: PHY MDIO information
> -	priv->bus = info->bus;
> -	priv->phyaddr = info->phy_addr;
> -	priv->enet_if = info->enet_if;
> -*/
>  
> -	if (init_phy(net_dev))
> -		return 0;
> +#ifdef CONFIG_PHYLIB
> +	err = init_phy(net_dev); 

Extra white space at the end of line. No need to respin. I can fix this when
merging.

> +	if (err < 0)
> +		return err;
> +#endif
>  
>  	err = eth_register(net_dev);
>  	if (err < 0) {
> 

York
York Sun March 22, 2016, 3:43 p.m. UTC | #3
On 02/24/2016 03:32 AM, Prabhakar Kushwaha wrote:
> This patch integrate DPAA2 ethernet driver existing PHY framework.
> 
> Call phy_connect and phy_config as per available DPMAC id defined
> in SerDes Protcol.
> 
> Signed-off-by: Pratiyush Mohan Srivastava <pratiyush.srivastava@nxp.com>
> Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
> ---
> Changes for v2: Incorporated Joe Hershberger's comments
> 
>  drivers/net/ldpaa_eth/ldpaa_eth.c | 121 +++++++++++++++++++++++++++-----------
>  1 file changed, 87 insertions(+), 34 deletions(-)

Applied to u-boot-fsl-qoriq, awaiting upstream.

Thanks.

York
diff mbox

Patch

diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c
index 7f96883..8a00bc3 100644
--- a/drivers/net/ldpaa_eth/ldpaa_eth.c
+++ b/drivers/net/ldpaa_eth/ldpaa_eth.c
@@ -14,15 +14,32 @@ 
 #include <linux/compat.h>
 #include <fsl-mc/fsl_dpmac.h>
 
+#include <fsl-mc/ldpaa_wriop.h>
 #include "ldpaa_eth.h"
 
-#undef CONFIG_PHYLIB
+#ifdef CONFIG_PHYLIB
 static int init_phy(struct eth_device *dev)
 {
-	/*TODO for external PHY */
+	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
+	struct phy_device *phydev = NULL;
+	struct mii_dev *bus;
 
-	return 0;
+	bus = wriop_get_mdio(priv->dpmac_id);
+	if (bus == NULL)
+		return 0;
+
+	phydev = phy_connect(bus, wriop_get_phy_address(priv->dpmac_id),
+			     dev, wriop_get_enet_if(priv->dpmac_id));
+	if (!phydev) {
+		printf("Failed to connect\n");
+		return -1;
+	}
+
+	priv->phydev = phydev;
+
+	return phy_config(phydev);
 }
+#endif
 
 #ifdef DEBUG
 static void ldpaa_eth_get_dpni_counter(void)
@@ -380,7 +397,9 @@  static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
 #ifdef DEBUG
 	struct dpni_link_state link_state;
 #endif
-	int err;
+	int err = 0;
+	struct mii_dev *bus;
+	phy_interface_t enet_if;
 
 	if (net_dev->state == ETH_STATE_ACTIVE)
 		return 0;
@@ -394,11 +413,48 @@  static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
 		printf("ERROR (DPL is deployed. No device available)\n");
 		return -ENODEV;
 	}
+
 	/* DPMAC initialization */
 	err = ldpaa_dpmac_setup(priv);
 	if (err < 0)
 		goto err_dpmac_setup;
 
+#ifdef CONFIG_PHYLIB
+	if (priv->phydev)
+		err = phy_startup(priv->phydev);
+		if (err) {
+			printf("%s: Could not initialize\n",
+			       priv->phydev->dev->name);
+			goto err_dpamc_bind;
+		}
+#else
+	priv->phydev = (struct phy_device *)malloc(sizeof(struct phy_device));
+	memset(priv->phydev, 0, sizeof(struct phy_device));
+
+	priv->phydev->speed = SPEED_1000;
+	priv->phydev->link = 1;
+	priv->phydev->duplex = DUPLEX_FULL;
+#endif
+
+	bus = wriop_get_mdio(priv->dpmac_id);
+	enet_if = wriop_get_enet_if(priv->dpmac_id);
+	if ((bus == NULL) &&
+	    (enet_if == PHY_INTERFACE_MODE_XGMII)) {
+		priv->phydev = (struct phy_device *)
+				malloc(sizeof(struct phy_device));
+		memset(priv->phydev, 0, sizeof(struct phy_device));
+
+		priv->phydev->speed = SPEED_10000;
+		priv->phydev->link = 1;
+		priv->phydev->duplex = DUPLEX_FULL;
+	}
+
+	if (!priv->phydev->link) {
+		printf("%s: No link.\n", priv->phydev->dev->name);
+		err = -1;
+		goto err_dpamc_bind;
+	}
+
 	/* DPMAC binding DPNI */
 	err = ldpaa_dpmac_bind(priv);
 	if (err)
@@ -425,28 +481,24 @@  static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
 		return err;
 	}
 
-#ifdef CONFIG_PHYLIB
-	/* TODO Check this path */
-	err = phy_startup(priv->phydev);
-	if (err) {
-		printf("%s: Could not initialize\n", priv->phydev->dev->name);
-		return err;
-	}
-#else
-	priv->phydev->speed = SPEED_1000;
-	priv->phydev->link = 1;
-	priv->phydev->duplex = DUPLEX_FULL;
-#endif
-
 	err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
 	if (err < 0) {
 		printf("dpni_enable() failed\n");
 		return err;
 	}
 
-	dpmac_link_state.rate = SPEED_1000;
-	dpmac_link_state.options = DPMAC_LINK_OPT_AUTONEG;
-	dpmac_link_state.up = 1;
+	dpmac_link_state.rate = priv->phydev->speed;
+
+	if (priv->phydev->autoneg == AUTONEG_DISABLE)
+		dpmac_link_state.options &= ~DPMAC_LINK_OPT_AUTONEG;
+	else
+		dpmac_link_state.options |= DPMAC_LINK_OPT_AUTONEG;
+
+	if (priv->phydev->duplex == DUPLEX_HALF)
+		dpmac_link_state.options |= DPMAC_LINK_OPT_HALF_DUPLEX;
+
+	dpmac_link_state.up = priv->phydev->link;
+
 	err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
 				  priv->dpmac_handle, &dpmac_link_state);
 	if (err < 0) {
@@ -484,10 +536,7 @@  static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
 		goto err_qdid;
 	}
 
-	if (!priv->phydev->link)
-		printf("%s: No link.\n", priv->phydev->dev->name);
-
-	return priv->phydev->link ? 0 : -1;
+	return priv->phydev->link;
 
 err_qdid:
 err_rx_flow:
@@ -495,9 +544,10 @@  err_rx_flow:
 err_dpni_bind:
 	ldpaa_dpbp_free();
 err_dpbp_setup:
-err_dpamc_bind:
 	dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
 err_dpni_setup:
+err_dpamc_bind:
+	dpmac_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
 err_dpmac_setup:
 	return err;
 }
@@ -506,6 +556,9 @@  static void ldpaa_eth_stop(struct eth_device *net_dev)
 {
 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
 	int err = 0;
+#ifdef CONFIG_PHYLIB
+	struct mii_dev *bus = wriop_get_mdio(priv->dpmac_id);
+#endif
 
 	if ((net_dev->state == ETH_STATE_PASSIVE) ||
 	    (net_dev->state == ETH_STATE_INIT))
@@ -531,7 +584,10 @@  static void ldpaa_eth_stop(struct eth_device *net_dev)
 		printf("dpni_disable() failed\n");
 
 #ifdef CONFIG_PHYLIB
-	phy_shutdown(priv->phydev);
+	if (priv->phydev && bus != NULL)
+		phy_shutdown(priv->phydev);
+	else
+		free(priv->phydev);
 #endif
 
 	ldpaa_dpbp_free();
@@ -914,15 +970,12 @@  static int ldpaa_eth_netdev_init(struct eth_device *net_dev,
 	net_dev->halt = ldpaa_eth_stop;
 	net_dev->send = ldpaa_eth_tx;
 	net_dev->recv = ldpaa_eth_pull_dequeue_rx;
-/*
-	TODO: PHY MDIO information
-	priv->bus = info->bus;
-	priv->phyaddr = info->phy_addr;
-	priv->enet_if = info->enet_if;
-*/
 
-	if (init_phy(net_dev))
-		return 0;
+#ifdef CONFIG_PHYLIB
+	err = init_phy(net_dev); 
+	if (err < 0)
+		return err;
+#endif
 
 	err = eth_register(net_dev);
 	if (err < 0) {