You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
272 lines
7.7 KiB
Diff
272 lines
7.7 KiB
Diff
From dff5fdd84a9ace2d9b8b56659c0855542829148a Mon Sep 17 00:00:00 2001
|
|
From: Calvin Johnson <calvin.johnson@nxp.com>
|
|
Date: Fri, 23 Nov 2018 23:58:28 +0530
|
|
Subject: [PATCH] staging: fsl_ppfe/eth: support single interface
|
|
initialization
|
|
|
|
- arrange members of struct mii_bus in sequence matching phy.h
|
|
- if mdio node is defined, use of_mdiobus_register to register
|
|
child nodes (phy devices) available on the mdio bus.
|
|
- remove of_phy_register_fixed_link from pfe_phy_init as it is being
|
|
handled in pfe_get_gemac_if_properties
|
|
- remove mdio enabled check
|
|
- skip phy init, if no PHY or fixed-link
|
|
|
|
Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
|
|
---
|
|
drivers/staging/fsl_ppfe/pfe_eth.c | 110 +++++++++++++-----------
|
|
drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c | 4 +
|
|
2 files changed, 66 insertions(+), 48 deletions(-)
|
|
|
|
--- a/drivers/staging/fsl_ppfe/pfe_eth.c
|
|
+++ b/drivers/staging/fsl_ppfe/pfe_eth.c
|
|
@@ -47,6 +47,7 @@
|
|
|
|
#define LS1012A_REV_1_0 0x87040010
|
|
|
|
+bool pfe_use_old_dts_phy;
|
|
bool pfe_errata_a010897;
|
|
|
|
static void *cbus_emac_base[3];
|
|
@@ -950,7 +951,8 @@ static int pfe_eth_mdio_init(struct pfe_
|
|
struct ls1012a_mdio_platform_data *minfo)
|
|
{
|
|
struct mii_bus *bus;
|
|
- int rc, ii;
|
|
+ struct device_node *mdio_node;
|
|
+ int rc = 0, ii;
|
|
struct phy_device *phydev;
|
|
|
|
netif_info(priv, drv, priv->ndev, "%s\n", __func__);
|
|
@@ -964,25 +966,30 @@ static int pfe_eth_mdio_init(struct pfe_
|
|
}
|
|
|
|
bus->name = "ls1012a MDIO Bus";
|
|
+ snprintf(bus->id, MII_BUS_ID_SIZE, "ls1012a-%x", priv->id);
|
|
+
|
|
+ bus->priv = priv;
|
|
bus->read = &pfe_eth_mdio_read;
|
|
bus->write = &pfe_eth_mdio_write;
|
|
bus->reset = &pfe_eth_mdio_reset;
|
|
- snprintf(bus->id, MII_BUS_ID_SIZE, "ls1012a-%x", priv->id);
|
|
- bus->priv = priv;
|
|
-
|
|
+ bus->parent = priv->pfe->dev;
|
|
bus->phy_mask = minfo->phy_mask;
|
|
- priv->mdc_div = minfo->mdc_div;
|
|
+ bus->irq[0] = minfo->irq[0];
|
|
|
|
+ priv->mdc_div = minfo->mdc_div;
|
|
if (!priv->mdc_div)
|
|
priv->mdc_div = 64;
|
|
-
|
|
- bus->irq[0] = minfo->irq[0];
|
|
-
|
|
- bus->parent = priv->pfe->dev;
|
|
-
|
|
netif_info(priv, drv, priv->ndev, "%s: mdc_div: %d, phy_mask: %x\n",
|
|
__func__, priv->mdc_div, bus->phy_mask);
|
|
- rc = mdiobus_register(bus);
|
|
+
|
|
+ mdio_node = of_get_child_by_name(priv->pfe->dev->of_node, "mdio");
|
|
+ if (mdio_node) {
|
|
+ rc = of_mdiobus_register(bus, mdio_node);
|
|
+ of_node_put(mdio_node);
|
|
+ } else {
|
|
+ rc = mdiobus_register(bus);
|
|
+ }
|
|
+
|
|
if (rc) {
|
|
netdev_err(priv->ndev, "mdiobus_register(%s) failed\n",
|
|
bus->name);
|
|
@@ -995,7 +1002,6 @@ static int pfe_eth_mdio_init(struct pfe_
|
|
* 3rd argument as true and then register the phy device
|
|
* via phy_device_register()
|
|
*/
|
|
-
|
|
if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII) {
|
|
for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) {
|
|
phydev = get_phy_device(priv->mii_bus,
|
|
@@ -1268,8 +1274,6 @@ static int pfe_phy_init(struct net_devic
|
|
char phy_id[MII_BUS_ID_SIZE + 3];
|
|
char bus_id[MII_BUS_ID_SIZE];
|
|
phy_interface_t interface;
|
|
- struct device_node *phy_node;
|
|
- int rc;
|
|
|
|
priv->oldlink = 0;
|
|
priv->oldspeed = 0;
|
|
@@ -1278,7 +1282,6 @@ static int pfe_phy_init(struct net_devic
|
|
snprintf(bus_id, MII_BUS_ID_SIZE, "ls1012a-%d", 0);
|
|
snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
|
|
priv->einfo->phy_id);
|
|
-
|
|
netif_info(priv, drv, ndev, "%s: %s\n", __func__, phy_id);
|
|
interface = priv->einfo->mii_config;
|
|
if ((interface == PHY_INTERFACE_MODE_SGMII) ||
|
|
@@ -1301,23 +1304,22 @@ static int pfe_phy_init(struct net_devic
|
|
priv->oldduplex = -1;
|
|
pr_info("%s interface %x\n", __func__, interface);
|
|
|
|
- if (of_phy_is_fixed_link(priv->phy_node)) {
|
|
- rc = of_phy_register_fixed_link(priv->phy_node);
|
|
- if (rc)
|
|
- return rc;
|
|
- phy_node = of_node_get(priv->phy_node);
|
|
- phydev = of_phy_connect(ndev, phy_node, pfe_eth_adjust_link, 0,
|
|
+ if (priv->phy_node) {
|
|
+ phydev = of_phy_connect(ndev, priv->phy_node,
|
|
+ pfe_eth_adjust_link, 0,
|
|
priv->einfo->mii_config);
|
|
- of_node_put(phy_node);
|
|
+ if (!(phydev)) {
|
|
+ netdev_err(ndev, "Unable to connect to phy\n");
|
|
+ return -ENODEV;
|
|
+ }
|
|
|
|
} else {
|
|
phydev = phy_connect(ndev, phy_id,
|
|
&pfe_eth_adjust_link, interface);
|
|
- }
|
|
-
|
|
- if (IS_ERR(phydev)) {
|
|
- netdev_err(ndev, "phy_connect() failed\n");
|
|
- return PTR_ERR(phydev);
|
|
+ if (IS_ERR(phydev)) {
|
|
+ netdev_err(ndev, "Unable to connect to phy\n");
|
|
+ return PTR_ERR(phydev);
|
|
+ }
|
|
}
|
|
|
|
priv->phydev = phydev;
|
|
@@ -2411,13 +2413,10 @@ static int pfe_eth_init_one(struct pfe *
|
|
memcpy(ndev->dev_addr, einfo[id].mac_addr, ETH_ALEN);
|
|
|
|
/* Initialize mdio */
|
|
- if (minfo[id].enabled) {
|
|
- err = pfe_eth_mdio_init(priv, &minfo[id]);
|
|
- if (err) {
|
|
- netdev_err(ndev, "%s: pfe_eth_mdio_init() failed\n",
|
|
- __func__);
|
|
- goto err2;
|
|
- }
|
|
+ err = pfe_eth_mdio_init(priv, &minfo[id]);
|
|
+ if (err) {
|
|
+ netdev_err(ndev, "%s: pfe_eth_mdio_init() failed\n", __func__);
|
|
+ goto err1;
|
|
}
|
|
|
|
if (us)
|
|
@@ -2462,22 +2461,26 @@ static int pfe_eth_init_one(struct pfe *
|
|
HIF_RX_POLL_WEIGHT - 16);
|
|
|
|
err = register_netdev(ndev);
|
|
-
|
|
if (err) {
|
|
netdev_err(ndev, "register_netdev() failed\n");
|
|
- goto err3;
|
|
+ goto err2;
|
|
+ }
|
|
+
|
|
+ if ((!(pfe_use_old_dts_phy) && !(priv->phy_node)) ||
|
|
+ ((pfe_use_old_dts_phy) &&
|
|
+ (priv->einfo->phy_flags & GEMAC_NO_PHY))) {
|
|
+ pr_info("%s: No PHY or fixed-link\n", __func__);
|
|
+ goto skip_phy_init;
|
|
}
|
|
|
|
phy_init:
|
|
device_init_wakeup(&ndev->dev, WAKE_MAGIC);
|
|
|
|
- if (!(priv->einfo->phy_flags & GEMAC_NO_PHY)) {
|
|
- err = pfe_phy_init(ndev);
|
|
- if (err) {
|
|
- netdev_err(ndev, "%s: pfe_phy_init() failed\n",
|
|
- __func__);
|
|
- goto err4;
|
|
- }
|
|
+ err = pfe_phy_init(ndev);
|
|
+ if (err) {
|
|
+ netdev_err(ndev, "%s: pfe_phy_init() failed\n",
|
|
+ __func__);
|
|
+ goto err3;
|
|
}
|
|
|
|
if (us) {
|
|
@@ -2488,6 +2491,7 @@ phy_init:
|
|
|
|
netif_carrier_on(ndev);
|
|
|
|
+skip_phy_init:
|
|
/* Create all the sysfs files */
|
|
if (pfe_eth_sysfs_init(ndev))
|
|
goto err4;
|
|
@@ -2496,13 +2500,16 @@ phy_init:
|
|
__func__, priv->EMAC_baseaddr);
|
|
|
|
return 0;
|
|
+
|
|
err4:
|
|
+ pfe_phy_exit(priv->ndev);
|
|
+err3:
|
|
if (us)
|
|
- goto err3;
|
|
+ goto err2;
|
|
unregister_netdev(ndev);
|
|
-err3:
|
|
- pfe_eth_mdio_exit(priv->mii_bus);
|
|
err2:
|
|
+ pfe_eth_mdio_exit(priv->mii_bus);
|
|
+err1:
|
|
free_netdev(priv->ndev);
|
|
err0:
|
|
return err;
|
|
@@ -2553,9 +2560,16 @@ static void pfe_eth_exit_one(struct pfe_
|
|
if (!us)
|
|
pfe_eth_sysfs_exit(priv->ndev);
|
|
|
|
- if (!(priv->einfo->phy_flags & GEMAC_NO_PHY))
|
|
- pfe_phy_exit(priv->ndev);
|
|
+ if ((!(pfe_use_old_dts_phy) && !(priv->phy_node)) ||
|
|
+ ((pfe_use_old_dts_phy) &&
|
|
+ (priv->einfo->phy_flags & GEMAC_NO_PHY))) {
|
|
+ pr_info("%s: No PHY or fixed-link\n", __func__);
|
|
+ goto skip_phy_exit;
|
|
+ }
|
|
+
|
|
+ pfe_phy_exit(priv->ndev);
|
|
|
|
+skip_phy_exit:
|
|
if (!us)
|
|
unregister_netdev(priv->ndev);
|
|
|
|
--- a/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c
|
|
+++ b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c
|
|
@@ -18,6 +18,7 @@
|
|
|
|
#include "pfe_mod.h"
|
|
|
|
+extern bool pfe_use_old_dts_phy;
|
|
struct ls1012a_pfe_platform_data pfe_platform_data;
|
|
|
|
static int pfe_get_gemac_if_properties(struct device_node *parent, int port, int
|
|
@@ -64,8 +65,10 @@ static int pfe_get_gemac_if_properties(s
|
|
phy_node = of_parse_phandle(gem, "phy-handle", 0);
|
|
pdata->ls1012a_eth_pdata[port].phy_node = phy_node;
|
|
if (phy_node) {
|
|
+ pfe_use_old_dts_phy = false;
|
|
goto process_phynode;
|
|
} else if (of_phy_is_fixed_link(gem)) {
|
|
+ pfe_use_old_dts_phy = false;
|
|
if (of_phy_register_fixed_link(gem) < 0) {
|
|
pr_err("broken fixed-link specification\n");
|
|
goto err;
|
|
@@ -73,6 +76,7 @@ static int pfe_get_gemac_if_properties(s
|
|
phy_node = of_node_get(gem);
|
|
pdata->ls1012a_eth_pdata[port].phy_node = phy_node;
|
|
} else if (of_get_property(gem, "fsl,pfe-phy-if-flags", &size)) {
|
|
+ pfe_use_old_dts_phy = true;
|
|
/* Use old dts properties for phy handling */
|
|
addr = of_get_property(gem, "fsl,pfe-phy-if-flags", &size);
|
|
pdata->ls1012a_eth_pdata[port].phy_flags = be32_to_cpup(addr);
|