Skip to content

Commit

Permalink
net: fec: Support phys probed from devicetree and fixed-link
Browse files Browse the repository at this point in the history
This adds support for specifying the phy to be used with the fec in the
devicetree using the standard phy-handle property and also supports
fixed-link.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
ukleinek authored and davem330 committed Aug 11, 2014
1 parent 200d7db commit 407066f
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 22 deletions.
29 changes: 28 additions & 1 deletion Documentation/devicetree/bindings/net/fsl-fec.txt
Expand Up @@ -12,7 +12,14 @@ Optional properties:
only if property "phy-reset-gpios" is available. Missing the property
will have the duration be 1 millisecond. Numbers greater than 1000 are
invalid and 1 millisecond will be used instead.
- phy-supply: regulator that powers the Ethernet PHY.
- phy-supply : regulator that powers the Ethernet PHY.
- phy-handle : phandle to the PHY device connected to this device.
- fixed-link : Assume a fixed link. See fixed-link.txt in the same directory.
Use instead of phy-handle.

Optional subnodes:
- mdio : specifies the mdio bus in the FEC, used as a container for phy nodes
according to phy.txt in the same directory

Example:

Expand All @@ -25,3 +32,23 @@ ethernet@83fec000 {
local-mac-address = [00 04 9F 01 1B B9];
phy-supply = <&reg_fec_supply>;
};

Example with phy specified:

ethernet@83fec000 {
compatible = "fsl,imx51-fec", "fsl,imx27-fec";
reg = <0x83fec000 0x4000>;
interrupts = <87>;
phy-mode = "mii";
phy-reset-gpios = <&gpio2 14 0>; /* GPIO2_14 */
local-mac-address = [00 04 9F 01 1B B9];
phy-supply = <&reg_fec_supply>;
phy-handle = <&ethphy>;
mdio {
ethphy: ethernet-phy@6 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <6>;
max-speed = <100>;
};
};
};
1 change: 1 addition & 0 deletions drivers/net/ethernet/freescale/fec.h
Expand Up @@ -310,6 +310,7 @@ struct fec_enet_private {
int mii_timeout;
uint phy_speed;
phy_interface_t phy_interface;
struct device_node *phy_node;
int link;
int full_duplex;
int speed;
Expand Down
76 changes: 55 additions & 21 deletions drivers/net/ethernet/freescale/fec_main.c
Expand Up @@ -52,6 +52,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include <linux/regulator/consumer.h>
#include <linux/if_vlan.h>
Expand Down Expand Up @@ -1648,29 +1649,37 @@ static int fec_enet_mii_probe(struct net_device *ndev)

fep->phy_dev = NULL;

/* check for attached phy */
for (phy_id = 0; (phy_id < PHY_MAX_ADDR); phy_id++) {
if ((fep->mii_bus->phy_mask & (1 << phy_id)))
continue;
if (fep->mii_bus->phy_map[phy_id] == NULL)
continue;
if (fep->mii_bus->phy_map[phy_id]->phy_id == 0)
continue;
if (dev_id--)
continue;
strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE);
break;
}
if (fep->phy_node) {
phy_dev = of_phy_connect(ndev, fep->phy_node,
&fec_enet_adjust_link, 0,
fep->phy_interface);
} else {
/* check for attached phy */
for (phy_id = 0; (phy_id < PHY_MAX_ADDR); phy_id++) {
if ((fep->mii_bus->phy_mask & (1 << phy_id)))
continue;
if (fep->mii_bus->phy_map[phy_id] == NULL)
continue;
if (fep->mii_bus->phy_map[phy_id]->phy_id == 0)
continue;
if (dev_id--)
continue;
strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE);
break;
}

if (phy_id >= PHY_MAX_ADDR) {
netdev_info(ndev, "no PHY, assuming direct connection to switch\n");
strncpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE);
phy_id = 0;
if (phy_id >= PHY_MAX_ADDR) {
netdev_info(ndev, "no PHY, assuming direct connection to switch\n");
strncpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE);
phy_id = 0;
}

snprintf(phy_name, sizeof(phy_name),
PHY_ID_FMT, mdio_bus_id, phy_id);
phy_dev = phy_connect(ndev, phy_name, &fec_enet_adjust_link,
fep->phy_interface);
}

snprintf(phy_name, sizeof(phy_name), PHY_ID_FMT, mdio_bus_id, phy_id);
phy_dev = phy_connect(ndev, phy_name, &fec_enet_adjust_link,
fep->phy_interface);
if (IS_ERR(phy_dev)) {
netdev_err(ndev, "could not attach to PHY\n");
return PTR_ERR(phy_dev);
Expand Down Expand Up @@ -1707,6 +1716,7 @@ static int fec_enet_mii_init(struct platform_device *pdev)
struct fec_enet_private *fep = netdev_priv(ndev);
const struct platform_device_id *id_entry =
platform_get_device_id(fep->pdev);
struct device_node *node;
int err = -ENXIO, i;

/*
Expand Down Expand Up @@ -1774,7 +1784,15 @@ static int fec_enet_mii_init(struct platform_device *pdev)
for (i = 0; i < PHY_MAX_ADDR; i++)
fep->mii_bus->irq[i] = PHY_POLL;

if (mdiobus_register(fep->mii_bus))
node = of_get_child_by_name(pdev->dev.of_node, "mdio");
if (node) {
err = of_mdiobus_register(fep->mii_bus, node);
of_node_put(node);
} else {
err = mdiobus_register(fep->mii_bus);
}

if (err)
goto err_out_free_mdio_irq;

mii_cnt++;
Expand Down Expand Up @@ -2527,6 +2545,7 @@ fec_probe(struct platform_device *pdev)
struct resource *r;
const struct of_device_id *of_id;
static int dev_id;
struct device_node *np = pdev->dev.of_node, *phy_node;

of_id = of_match_device(fec_dt_ids, &pdev->dev);
if (of_id)
Expand Down Expand Up @@ -2566,6 +2585,18 @@ fec_probe(struct platform_device *pdev)

platform_set_drvdata(pdev, ndev);

phy_node = of_parse_phandle(np, "phy-handle", 0);
if (!phy_node && of_phy_is_fixed_link(np)) {
ret = of_phy_register_fixed_link(np);
if (ret < 0) {
dev_err(&pdev->dev,
"broken fixed-link specification\n");
goto failed_phy;
}
phy_node = of_node_get(np);
}
fep->phy_node = phy_node;

ret = of_get_phy_mode(pdev->dev.of_node);
if (ret < 0) {
pdata = dev_get_platdata(&pdev->dev);
Expand Down Expand Up @@ -2670,6 +2701,8 @@ fec_probe(struct platform_device *pdev)
failed_regulator:
fec_enet_clk_enable(ndev, false);
failed_clk:
failed_phy:
of_node_put(phy_node);
failed_ioremap:
free_netdev(ndev);

Expand All @@ -2691,6 +2724,7 @@ fec_drv_remove(struct platform_device *pdev)
if (fep->ptp_clock)
ptp_clock_unregister(fep->ptp_clock);
fec_enet_clk_enable(ndev, false);
of_node_put(fep->phy_node);
free_netdev(ndev);

return 0;
Expand Down

0 comments on commit 407066f

Please sign in to comment.