Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0ba512e authored by Petri Gynther's avatar Petri Gynther Committed by David S. Miller
Browse files

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: default avatarPetri Gynther <pgynther@google.com>
Acked-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c3582a2c
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -62,7 +62,6 @@ config BCM63XX_ENET

config BCMGENET
	tristate "Broadcom GENET internal MAC support"
	depends on OF
	select MII
	select PHYLIB
	select FIXED_PHY if BCMGENET=y
+21 −10
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/phy.h>
#include <linux/platform_data/bcmgenet.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)
{
	struct bcmgenet_platform_data *pd = pdev->dev.platform_data;
	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 net_device *dev;
	const void *macaddr;
@@ -2601,9 +2603,11 @@ static int bcmgenet_probe(struct platform_device *pdev)
		return -ENOMEM;
	}

	if (dn) {
		of_id = of_match_node(bcmgenet_match, dn);
		if (!of_id)
			return -EINVAL;
	}

	priv = netdev_priv(dev);
	priv->irq0 = platform_get_irq(pdev, 0);
@@ -2615,12 +2619,16 @@ static int bcmgenet_probe(struct platform_device *pdev)
		goto err;
	}

	if (dn) {
		macaddr = of_get_mac_address(dn);
		if (!macaddr) {
			dev_err(&pdev->dev, "can't find MAC address\n");
			err = -EINVAL;
			goto err;
		}
	} else {
		macaddr = pd->mac_address;
	}

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	priv->base = devm_ioremap_resource(&pdev->dev, r);
@@ -2659,7 +2667,10 @@ static int bcmgenet_probe(struct platform_device *pdev)

	priv->dev = dev;
	priv->pdev = pdev;
	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");
	if (IS_ERR(priv->clk))
+104 −22
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <linux/of.h>
#include <linux/of_net.h>
#include <linux/of_mdio.h>
#include <linux/platform_data/bcmgenet.h>

#include "bcmgenet.h"

@@ -312,6 +313,16 @@ static int bcmgenet_mii_probe(struct net_device *dev)
	u32 phy_flags;
	int ret;

	/* Communicate the integrated PHY revision */
	phy_flags = priv->gphy_rev;

	/* Initialize link state variables that bcmgenet_mii_setup() uses */
	priv->old_link = -1;
	priv->old_speed = -1;
	priv->old_duplex = -1;
	priv->old_pause = -1;

	if (dn) {
		if (priv->phydev) {
			pr_info("PHY already attached\n");
			return 0;
@@ -328,21 +339,23 @@ static int bcmgenet_mii_probe(struct net_device *dev)
			priv->phy_dn = of_node_get(dn);
		}

	/* Communicate the integrated PHY revision */
	phy_flags = priv->gphy_rev;

	/* Initialize link state variables that bcmgenet_mii_setup() uses */
	priv->old_link = -1;
	priv->old_speed = -1;
	priv->old_duplex = -1;
	priv->old_pause = -1;

		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;

@@ -438,6 +451,75 @@ static int bcmgenet_mii_of_init(struct bcmgenet_priv *priv)
	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)
{
	struct bcmgenet_priv *priv = netdev_priv(dev);
@@ -447,7 +529,7 @@ int bcmgenet_mii_init(struct net_device *dev)
	if (ret)
		return ret;

	ret = bcmgenet_mii_of_init(priv);
	ret = bcmgenet_mii_bus_init(priv);
	if (ret)
		goto out_free;

+18 −0
Original line number Diff line number Diff line
#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