net: bcmgenet: enable driver to work without a device tree
Modify bcmgenet driver so that it can be used on Broadcom 7xxx MIPS-based STB platforms without a device tree. Signed-off-by: Petri Gynther <pgynther@google.com> Acked-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c3582a2c4d
commit
b0ba512e25
|
@ -62,7 +62,6 @@ config BCM63XX_ENET
|
||||||
|
|
||||||
config BCMGENET
|
config BCMGENET
|
||||||
tristate "Broadcom GENET internal MAC support"
|
tristate "Broadcom GENET internal MAC support"
|
||||||
depends on OF
|
|
||||||
select MII
|
select MII
|
||||||
select PHYLIB
|
select PHYLIB
|
||||||
select FIXED_PHY if BCMGENET=y
|
select FIXED_PHY if BCMGENET=y
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include <linux/ip.h>
|
#include <linux/ip.h>
|
||||||
#include <linux/ipv6.h>
|
#include <linux/ipv6.h>
|
||||||
#include <linux/phy.h>
|
#include <linux/phy.h>
|
||||||
|
#include <linux/platform_data/bcmgenet.h>
|
||||||
|
|
||||||
#include <asm/unaligned.h>
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
|
@ -2586,8 +2587,9 @@ static const struct of_device_id bcmgenet_match[] = {
|
||||||
|
|
||||||
static int bcmgenet_probe(struct platform_device *pdev)
|
static int bcmgenet_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
struct bcmgenet_platform_data *pd = pdev->dev.platform_data;
|
||||||
struct device_node *dn = pdev->dev.of_node;
|
struct device_node *dn = pdev->dev.of_node;
|
||||||
const struct of_device_id *of_id;
|
const struct of_device_id *of_id = NULL;
|
||||||
struct bcmgenet_priv *priv;
|
struct bcmgenet_priv *priv;
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
const void *macaddr;
|
const void *macaddr;
|
||||||
|
@ -2601,9 +2603,11 @@ static int bcmgenet_probe(struct platform_device *pdev)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
of_id = of_match_node(bcmgenet_match, dn);
|
if (dn) {
|
||||||
if (!of_id)
|
of_id = of_match_node(bcmgenet_match, dn);
|
||||||
return -EINVAL;
|
if (!of_id)
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
priv = netdev_priv(dev);
|
priv = netdev_priv(dev);
|
||||||
priv->irq0 = platform_get_irq(pdev, 0);
|
priv->irq0 = platform_get_irq(pdev, 0);
|
||||||
|
@ -2615,11 +2619,15 @@ static int bcmgenet_probe(struct platform_device *pdev)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
macaddr = of_get_mac_address(dn);
|
if (dn) {
|
||||||
if (!macaddr) {
|
macaddr = of_get_mac_address(dn);
|
||||||
dev_err(&pdev->dev, "can't find MAC address\n");
|
if (!macaddr) {
|
||||||
err = -EINVAL;
|
dev_err(&pdev->dev, "can't find MAC address\n");
|
||||||
goto err;
|
err = -EINVAL;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
macaddr = pd->mac_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
@ -2659,7 +2667,10 @@ static int bcmgenet_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
priv->dev = dev;
|
priv->dev = dev;
|
||||||
priv->pdev = pdev;
|
priv->pdev = pdev;
|
||||||
priv->version = (enum bcmgenet_version)of_id->data;
|
if (of_id)
|
||||||
|
priv->version = (enum bcmgenet_version)of_id->data;
|
||||||
|
else
|
||||||
|
priv->version = pd->genet_version;
|
||||||
|
|
||||||
priv->clk = devm_clk_get(&priv->pdev->dev, "enet");
|
priv->clk = devm_clk_get(&priv->pdev->dev, "enet");
|
||||||
if (IS_ERR(priv->clk))
|
if (IS_ERR(priv->clk))
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_net.h>
|
#include <linux/of_net.h>
|
||||||
#include <linux/of_mdio.h>
|
#include <linux/of_mdio.h>
|
||||||
|
#include <linux/platform_data/bcmgenet.h>
|
||||||
|
|
||||||
#include "bcmgenet.h"
|
#include "bcmgenet.h"
|
||||||
|
|
||||||
|
@ -312,22 +313,6 @@ static int bcmgenet_mii_probe(struct net_device *dev)
|
||||||
u32 phy_flags;
|
u32 phy_flags;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (priv->phydev) {
|
|
||||||
pr_info("PHY already attached\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* In the case of a fixed PHY, the DT node associated
|
|
||||||
* to the PHY is the Ethernet MAC DT node.
|
|
||||||
*/
|
|
||||||
if (!priv->phy_dn && of_phy_is_fixed_link(dn)) {
|
|
||||||
ret = of_phy_register_fixed_link(dn);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
priv->phy_dn = of_node_get(dn);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Communicate the integrated PHY revision */
|
/* Communicate the integrated PHY revision */
|
||||||
phy_flags = priv->gphy_rev;
|
phy_flags = priv->gphy_rev;
|
||||||
|
|
||||||
|
@ -337,11 +322,39 @@ static int bcmgenet_mii_probe(struct net_device *dev)
|
||||||
priv->old_duplex = -1;
|
priv->old_duplex = -1;
|
||||||
priv->old_pause = -1;
|
priv->old_pause = -1;
|
||||||
|
|
||||||
phydev = of_phy_connect(dev, priv->phy_dn, bcmgenet_mii_setup,
|
if (dn) {
|
||||||
phy_flags, priv->phy_interface);
|
if (priv->phydev) {
|
||||||
if (!phydev) {
|
pr_info("PHY already attached\n");
|
||||||
pr_err("could not attach to PHY\n");
|
return 0;
|
||||||
return -ENODEV;
|
}
|
||||||
|
|
||||||
|
/* In the case of a fixed PHY, the DT node associated
|
||||||
|
* to the PHY is the Ethernet MAC DT node.
|
||||||
|
*/
|
||||||
|
if (!priv->phy_dn && of_phy_is_fixed_link(dn)) {
|
||||||
|
ret = of_phy_register_fixed_link(dn);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
priv->phy_dn = of_node_get(dn);
|
||||||
|
}
|
||||||
|
|
||||||
|
phydev = of_phy_connect(dev, priv->phy_dn, bcmgenet_mii_setup,
|
||||||
|
phy_flags, priv->phy_interface);
|
||||||
|
if (!phydev) {
|
||||||
|
pr_err("could not attach to PHY\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
phydev = priv->phydev;
|
||||||
|
phydev->dev_flags = phy_flags;
|
||||||
|
|
||||||
|
ret = phy_connect_direct(dev, phydev, bcmgenet_mii_setup,
|
||||||
|
priv->phy_interface);
|
||||||
|
if (ret) {
|
||||||
|
pr_err("could not attach to PHY\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->phydev = phydev;
|
priv->phydev = phydev;
|
||||||
|
@ -438,6 +451,75 @@ static int bcmgenet_mii_of_init(struct bcmgenet_priv *priv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv)
|
||||||
|
{
|
||||||
|
struct device *kdev = &priv->pdev->dev;
|
||||||
|
struct bcmgenet_platform_data *pd = kdev->platform_data;
|
||||||
|
struct mii_bus *mdio = priv->mii_bus;
|
||||||
|
struct phy_device *phydev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (pd->phy_interface != PHY_INTERFACE_MODE_MOCA && pd->mdio_enabled) {
|
||||||
|
/*
|
||||||
|
* Internal or external PHY with MDIO access
|
||||||
|
*/
|
||||||
|
if (pd->phy_address >= 0 && pd->phy_address < PHY_MAX_ADDR)
|
||||||
|
mdio->phy_mask = ~(1 << pd->phy_address);
|
||||||
|
else
|
||||||
|
mdio->phy_mask = 0;
|
||||||
|
|
||||||
|
ret = mdiobus_register(mdio);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(kdev, "failed to register MDIO bus\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pd->phy_address >= 0 && pd->phy_address < PHY_MAX_ADDR)
|
||||||
|
phydev = mdio->phy_map[pd->phy_address];
|
||||||
|
else
|
||||||
|
phydev = phy_find_first(mdio);
|
||||||
|
|
||||||
|
if (!phydev) {
|
||||||
|
dev_err(kdev, "failed to register PHY device\n");
|
||||||
|
mdiobus_unregister(mdio);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* MoCA port or no MDIO access.
|
||||||
|
* Use fixed PHY to represent the link layer.
|
||||||
|
*/
|
||||||
|
struct fixed_phy_status fphy_status = {
|
||||||
|
.link = 1,
|
||||||
|
.speed = pd->phy_speed,
|
||||||
|
.duplex = pd->phy_duplex,
|
||||||
|
.pause = 0,
|
||||||
|
.asym_pause = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
phydev = fixed_phy_register(PHY_POLL, &fphy_status, NULL);
|
||||||
|
if (!phydev || IS_ERR(phydev)) {
|
||||||
|
dev_err(kdev, "failed to register fixed PHY device\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->phydev = phydev;
|
||||||
|
priv->phy_interface = pd->phy_interface;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bcmgenet_mii_bus_init(struct bcmgenet_priv *priv)
|
||||||
|
{
|
||||||
|
struct device_node *dn = priv->pdev->dev.of_node;
|
||||||
|
|
||||||
|
if (dn)
|
||||||
|
return bcmgenet_mii_of_init(priv);
|
||||||
|
else
|
||||||
|
return bcmgenet_mii_pd_init(priv);
|
||||||
|
}
|
||||||
|
|
||||||
int bcmgenet_mii_init(struct net_device *dev)
|
int bcmgenet_mii_init(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct bcmgenet_priv *priv = netdev_priv(dev);
|
struct bcmgenet_priv *priv = netdev_priv(dev);
|
||||||
|
@ -447,7 +529,7 @@ int bcmgenet_mii_init(struct net_device *dev)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = bcmgenet_mii_of_init(priv);
|
ret = bcmgenet_mii_bus_init(priv);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
|
|
18
include/linux/platform_data/bcmgenet.h
Normal file
18
include/linux/platform_data/bcmgenet.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef __LINUX_PLATFORM_DATA_BCMGENET_H__
|
||||||
|
#define __LINUX_PLATFORM_DATA_BCMGENET_H__
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/if_ether.h>
|
||||||
|
#include <linux/phy.h>
|
||||||
|
|
||||||
|
struct bcmgenet_platform_data {
|
||||||
|
bool mdio_enabled;
|
||||||
|
phy_interface_t phy_interface;
|
||||||
|
int phy_address;
|
||||||
|
int phy_speed;
|
||||||
|
int phy_duplex;
|
||||||
|
u8 mac_address[ETH_ALEN];
|
||||||
|
int genet_version;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue