Skip to content

Commit

Permalink
net: lpc_eth: parse phy nodes from device tree
Browse files Browse the repository at this point in the history
When connected to a micrel phy, phy_find_first doesn't work properly
because the first phy found is on address 0, the broadcast address but, the
first thing the phy driver is doing is disabling this broadcast address.
The phy is then available only on address 1 but the mdio driver doesn't
know about it.

Instead, register the mdio bus using of_mdiobus_register and try to find
the phy description in device tree before falling back to phy_find_first.

This ultimately also allows to describe the interrupt the phy is connected
to.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Alexandre Belloni authored and David S. Miller committed Oct 18, 2019
1 parent 2c69dae commit 3503bf0
Showing 1 changed file with 20 additions and 8 deletions.
28 changes: 20 additions & 8 deletions drivers/net/ethernet/nxp/lpc_eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/etherdevice.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
Expand Down Expand Up @@ -391,6 +392,7 @@ struct rx_status_t {
struct netdata_local {
struct platform_device *pdev;
struct net_device *ndev;
struct device_node *phy_node;
spinlock_t lock;
void __iomem *net_base;
u32 msg_enable;
Expand Down Expand Up @@ -749,22 +751,26 @@ static void lpc_handle_link_change(struct net_device *ndev)
static int lpc_mii_probe(struct net_device *ndev)
{
struct netdata_local *pldat = netdev_priv(ndev);
struct phy_device *phydev = phy_find_first(pldat->mii_bus);

if (!phydev) {
netdev_err(ndev, "no PHY found\n");
return -ENODEV;
}
struct phy_device *phydev;

/* Attach to the PHY */
if (lpc_phy_interface_mode(&pldat->pdev->dev) == PHY_INTERFACE_MODE_MII)
netdev_info(ndev, "using MII interface\n");
else
netdev_info(ndev, "using RMII interface\n");

if (pldat->phy_node)
phydev = of_phy_find_device(pldat->phy_node);
else
phydev = phy_find_first(pldat->mii_bus);
if (!phydev) {
netdev_err(ndev, "no PHY found\n");
return -ENODEV;
}

phydev = phy_connect(ndev, phydev_name(phydev),
&lpc_handle_link_change,
lpc_phy_interface_mode(&pldat->pdev->dev));

if (IS_ERR(phydev)) {
netdev_err(ndev, "Could not attach to PHY\n");
return PTR_ERR(phydev);
Expand All @@ -783,6 +789,7 @@ static int lpc_mii_probe(struct net_device *ndev)

static int lpc_mii_init(struct netdata_local *pldat)
{
struct device_node *node;
int err = -ENXIO;

pldat->mii_bus = mdiobus_alloc();
Expand Down Expand Up @@ -812,7 +819,10 @@ static int lpc_mii_init(struct netdata_local *pldat)

platform_set_drvdata(pldat->pdev, pldat->mii_bus);

if (mdiobus_register(pldat->mii_bus))
node = of_get_child_by_name(pldat->pdev->dev.of_node, "mdio");
err = of_mdiobus_register(pldat->mii_bus, node);
of_node_put(node);
if (err)
goto err_out_unregister_bus;

if (lpc_mii_probe(pldat->ndev) != 0)
Expand Down Expand Up @@ -1345,6 +1355,8 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
netdev_dbg(ndev, "DMA buffer V address :0x%p\n",
pldat->dma_buff_base_v);

pldat->phy_node = of_parse_phandle(np, "phy-handle", 0);

/* Get MAC address from current HW setting (POR state is all zeros) */
__lpc_get_mac(pldat, ndev->dev_addr);

Expand Down

0 comments on commit 3503bf0

Please sign in to comment.