mirror of
https://xff.cz/git/u-boot/
synced 2025-09-27 05:21:16 +02:00
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> Reviewed-by: York Sun <york.sun@nxp.com>
This commit is contained in:
committed by
York Sun
parent
b2b877306c
commit
6c2b520a37
@@ -14,15 +14,32 @@
|
|||||||
#include <linux/compat.h>
|
#include <linux/compat.h>
|
||||||
#include <fsl-mc/fsl_dpmac.h>
|
#include <fsl-mc/fsl_dpmac.h>
|
||||||
|
|
||||||
|
#include <fsl-mc/ldpaa_wriop.h>
|
||||||
#include "ldpaa_eth.h"
|
#include "ldpaa_eth.h"
|
||||||
|
|
||||||
#undef CONFIG_PHYLIB
|
#ifdef CONFIG_PHYLIB
|
||||||
static int init_phy(struct eth_device *dev)
|
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
|
#ifdef DEBUG
|
||||||
static void ldpaa_eth_get_dpni_counter(void)
|
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
|
#ifdef DEBUG
|
||||||
struct dpni_link_state link_state;
|
struct dpni_link_state link_state;
|
||||||
#endif
|
#endif
|
||||||
int err;
|
int err = 0;
|
||||||
|
struct mii_dev *bus;
|
||||||
|
phy_interface_t enet_if;
|
||||||
|
|
||||||
if (net_dev->state == ETH_STATE_ACTIVE)
|
if (net_dev->state == ETH_STATE_ACTIVE)
|
||||||
return 0;
|
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");
|
printf("ERROR (DPL is deployed. No device available)\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DPMAC initialization */
|
/* DPMAC initialization */
|
||||||
err = ldpaa_dpmac_setup(priv);
|
err = ldpaa_dpmac_setup(priv);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto err_dpmac_setup;
|
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 */
|
/* DPMAC binding DPNI */
|
||||||
err = ldpaa_dpmac_bind(priv);
|
err = ldpaa_dpmac_bind(priv);
|
||||||
if (err)
|
if (err)
|
||||||
@@ -425,28 +481,24 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
|
|||||||
return err;
|
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);
|
err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
printf("dpni_enable() failed\n");
|
printf("dpni_enable() failed\n");
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
dpmac_link_state.rate = SPEED_1000;
|
dpmac_link_state.rate = priv->phydev->speed;
|
||||||
dpmac_link_state.options = DPMAC_LINK_OPT_AUTONEG;
|
|
||||||
dpmac_link_state.up = 1;
|
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,
|
err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
|
||||||
priv->dpmac_handle, &dpmac_link_state);
|
priv->dpmac_handle, &dpmac_link_state);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
@@ -484,10 +536,7 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
|
|||||||
goto err_qdid;
|
goto err_qdid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!priv->phydev->link)
|
return priv->phydev->link;
|
||||||
printf("%s: No link.\n", priv->phydev->dev->name);
|
|
||||||
|
|
||||||
return priv->phydev->link ? 0 : -1;
|
|
||||||
|
|
||||||
err_qdid:
|
err_qdid:
|
||||||
err_rx_flow:
|
err_rx_flow:
|
||||||
@@ -495,9 +544,10 @@ err_rx_flow:
|
|||||||
err_dpni_bind:
|
err_dpni_bind:
|
||||||
ldpaa_dpbp_free();
|
ldpaa_dpbp_free();
|
||||||
err_dpbp_setup:
|
err_dpbp_setup:
|
||||||
err_dpamc_bind:
|
|
||||||
dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
|
dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
|
||||||
err_dpni_setup:
|
err_dpni_setup:
|
||||||
|
err_dpamc_bind:
|
||||||
|
dpmac_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
|
||||||
err_dpmac_setup:
|
err_dpmac_setup:
|
||||||
return err;
|
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;
|
struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
#ifdef CONFIG_PHYLIB
|
||||||
|
struct mii_dev *bus = wriop_get_mdio(priv->dpmac_id);
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((net_dev->state == ETH_STATE_PASSIVE) ||
|
if ((net_dev->state == ETH_STATE_PASSIVE) ||
|
||||||
(net_dev->state == ETH_STATE_INIT))
|
(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");
|
printf("dpni_disable() failed\n");
|
||||||
|
|
||||||
#ifdef CONFIG_PHYLIB
|
#ifdef CONFIG_PHYLIB
|
||||||
phy_shutdown(priv->phydev);
|
if (priv->phydev && bus != NULL)
|
||||||
|
phy_shutdown(priv->phydev);
|
||||||
|
else
|
||||||
|
free(priv->phydev);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ldpaa_dpbp_free();
|
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->halt = ldpaa_eth_stop;
|
||||||
net_dev->send = ldpaa_eth_tx;
|
net_dev->send = ldpaa_eth_tx;
|
||||||
net_dev->recv = ldpaa_eth_pull_dequeue_rx;
|
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))
|
#ifdef CONFIG_PHYLIB
|
||||||
return 0;
|
err = init_phy(net_dev);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
#endif
|
||||||
|
|
||||||
err = eth_register(net_dev);
|
err = eth_register(net_dev);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
Reference in New Issue
Block a user