net: fec_mpc52xx: Read MAC address from device-tree
Until now, the MPC5200 FEC ethernet driver relied upon the bootloader (U-Boot) to write the MAC address into the ethernet controller registers. The Linux driver should not rely on such a thing. So lets read the MAC address from the DT as it should be done here. The following priority is now used to read the MAC address: 1) First, try OF node MAC address, if not present or invalid, then: 2) Read from MAC address registers, if invalid, then: 3) Log a warning message, and choose a random MAC address. This fixes a problem with a MPC5200 board that uses the SPL U-Boot version without FEC initialization before Linux booting for boot speedup. Additionally a status line is now be printed upon successful driver probing, also displaying this MAC address. Signed-off-by: Stefan Roese <sr@denx.de> Cc: Anatolij Gustschin <agust@denx.de> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
af32de0ecd
commit
db98f08188
@@ -29,6 +29,7 @@
|
|||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/of_mdio.h>
|
#include <linux/of_mdio.h>
|
||||||
|
#include <linux/of_net.h>
|
||||||
#include <linux/of_platform.h>
|
#include <linux/of_platform.h>
|
||||||
|
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
@@ -76,10 +77,6 @@ static void mpc52xx_fec_stop(struct net_device *dev);
|
|||||||
static void mpc52xx_fec_start(struct net_device *dev);
|
static void mpc52xx_fec_start(struct net_device *dev);
|
||||||
static void mpc52xx_fec_reset(struct net_device *dev);
|
static void mpc52xx_fec_reset(struct net_device *dev);
|
||||||
|
|
||||||
static u8 mpc52xx_fec_mac_addr[6];
|
|
||||||
module_param_array_named(mac, mpc52xx_fec_mac_addr, byte, NULL, 0);
|
|
||||||
MODULE_PARM_DESC(mac, "six hex digits, ie. 0x1,0x2,0xc0,0x01,0xba,0xbe");
|
|
||||||
|
|
||||||
#define MPC52xx_MESSAGES_DEFAULT ( NETIF_MSG_DRV | NETIF_MSG_PROBE | \
|
#define MPC52xx_MESSAGES_DEFAULT ( NETIF_MSG_DRV | NETIF_MSG_PROBE | \
|
||||||
NETIF_MSG_LINK | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP)
|
NETIF_MSG_LINK | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP)
|
||||||
static int debug = -1; /* the above default */
|
static int debug = -1; /* the above default */
|
||||||
@@ -110,15 +107,6 @@ static void mpc52xx_fec_set_paddr(struct net_device *dev, u8 *mac)
|
|||||||
out_be32(&fec->paddr2, (*(u16 *)(&mac[4]) << 16) | FEC_PADDR2_TYPE);
|
out_be32(&fec->paddr2, (*(u16 *)(&mac[4]) << 16) | FEC_PADDR2_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mpc52xx_fec_get_paddr(struct net_device *dev, u8 *mac)
|
|
||||||
{
|
|
||||||
struct mpc52xx_fec_priv *priv = netdev_priv(dev);
|
|
||||||
struct mpc52xx_fec __iomem *fec = priv->fec;
|
|
||||||
|
|
||||||
*(u32 *)(&mac[0]) = in_be32(&fec->paddr1);
|
|
||||||
*(u16 *)(&mac[4]) = in_be32(&fec->paddr2) >> 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mpc52xx_fec_set_mac_address(struct net_device *dev, void *addr)
|
static int mpc52xx_fec_set_mac_address(struct net_device *dev, void *addr)
|
||||||
{
|
{
|
||||||
struct sockaddr *sock = addr;
|
struct sockaddr *sock = addr;
|
||||||
@@ -853,6 +841,8 @@ static int mpc52xx_fec_probe(struct platform_device *op)
|
|||||||
struct resource mem;
|
struct resource mem;
|
||||||
const u32 *prop;
|
const u32 *prop;
|
||||||
int prop_size;
|
int prop_size;
|
||||||
|
struct device_node *np = op->dev.of_node;
|
||||||
|
const char *mac_addr;
|
||||||
|
|
||||||
phys_addr_t rx_fifo;
|
phys_addr_t rx_fifo;
|
||||||
phys_addr_t tx_fifo;
|
phys_addr_t tx_fifo;
|
||||||
@@ -866,7 +856,7 @@ static int mpc52xx_fec_probe(struct platform_device *op)
|
|||||||
priv->ndev = ndev;
|
priv->ndev = ndev;
|
||||||
|
|
||||||
/* Reserve FEC control zone */
|
/* Reserve FEC control zone */
|
||||||
rv = of_address_to_resource(op->dev.of_node, 0, &mem);
|
rv = of_address_to_resource(np, 0, &mem);
|
||||||
if (rv) {
|
if (rv) {
|
||||||
printk(KERN_ERR DRIVER_NAME ": "
|
printk(KERN_ERR DRIVER_NAME ": "
|
||||||
"Error while parsing device node resource\n" );
|
"Error while parsing device node resource\n" );
|
||||||
@@ -919,7 +909,7 @@ static int mpc52xx_fec_probe(struct platform_device *op)
|
|||||||
|
|
||||||
/* Get the IRQ we need one by one */
|
/* Get the IRQ we need one by one */
|
||||||
/* Control */
|
/* Control */
|
||||||
ndev->irq = irq_of_parse_and_map(op->dev.of_node, 0);
|
ndev->irq = irq_of_parse_and_map(np, 0);
|
||||||
|
|
||||||
/* RX */
|
/* RX */
|
||||||
priv->r_irq = bcom_get_task_irq(priv->rx_dmatsk);
|
priv->r_irq = bcom_get_task_irq(priv->rx_dmatsk);
|
||||||
@@ -927,11 +917,33 @@ static int mpc52xx_fec_probe(struct platform_device *op)
|
|||||||
/* TX */
|
/* TX */
|
||||||
priv->t_irq = bcom_get_task_irq(priv->tx_dmatsk);
|
priv->t_irq = bcom_get_task_irq(priv->tx_dmatsk);
|
||||||
|
|
||||||
/* MAC address init */
|
/*
|
||||||
if (!is_zero_ether_addr(mpc52xx_fec_mac_addr))
|
* MAC address init:
|
||||||
memcpy(ndev->dev_addr, mpc52xx_fec_mac_addr, 6);
|
*
|
||||||
else
|
* First try to read MAC address from DT
|
||||||
mpc52xx_fec_get_paddr(ndev, ndev->dev_addr);
|
*/
|
||||||
|
mac_addr = of_get_mac_address(np);
|
||||||
|
if (mac_addr) {
|
||||||
|
memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
|
||||||
|
} else {
|
||||||
|
struct mpc52xx_fec __iomem *fec = priv->fec;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the MAC addresse is not provided via DT then read
|
||||||
|
* it back from the controller regs
|
||||||
|
*/
|
||||||
|
*(u32 *)(&ndev->dev_addr[0]) = in_be32(&fec->paddr1);
|
||||||
|
*(u16 *)(&ndev->dev_addr[4]) = in_be32(&fec->paddr2) >> 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if the MAC address is valid, if not get a random one
|
||||||
|
*/
|
||||||
|
if (!is_valid_ether_addr(ndev->dev_addr)) {
|
||||||
|
eth_hw_addr_random(ndev);
|
||||||
|
dev_warn(&ndev->dev, "using random MAC address %pM\n",
|
||||||
|
ndev->dev_addr);
|
||||||
|
}
|
||||||
|
|
||||||
priv->msg_enable = netif_msg_init(debug, MPC52xx_MESSAGES_DEFAULT);
|
priv->msg_enable = netif_msg_init(debug, MPC52xx_MESSAGES_DEFAULT);
|
||||||
|
|
||||||
@@ -942,20 +954,20 @@ static int mpc52xx_fec_probe(struct platform_device *op)
|
|||||||
/* Start with safe defaults for link connection */
|
/* Start with safe defaults for link connection */
|
||||||
priv->speed = 100;
|
priv->speed = 100;
|
||||||
priv->duplex = DUPLEX_HALF;
|
priv->duplex = DUPLEX_HALF;
|
||||||
priv->mdio_speed = ((mpc5xxx_get_bus_frequency(op->dev.of_node) >> 20) / 5) << 1;
|
priv->mdio_speed = ((mpc5xxx_get_bus_frequency(np) >> 20) / 5) << 1;
|
||||||
|
|
||||||
/* The current speed preconfigures the speed of the MII link */
|
/* The current speed preconfigures the speed of the MII link */
|
||||||
prop = of_get_property(op->dev.of_node, "current-speed", &prop_size);
|
prop = of_get_property(np, "current-speed", &prop_size);
|
||||||
if (prop && (prop_size >= sizeof(u32) * 2)) {
|
if (prop && (prop_size >= sizeof(u32) * 2)) {
|
||||||
priv->speed = prop[0];
|
priv->speed = prop[0];
|
||||||
priv->duplex = prop[1] ? DUPLEX_FULL : DUPLEX_HALF;
|
priv->duplex = prop[1] ? DUPLEX_FULL : DUPLEX_HALF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there is a phy handle, then get the PHY node */
|
/* If there is a phy handle, then get the PHY node */
|
||||||
priv->phy_node = of_parse_phandle(op->dev.of_node, "phy-handle", 0);
|
priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
|
||||||
|
|
||||||
/* the 7-wire property means don't use MII mode */
|
/* the 7-wire property means don't use MII mode */
|
||||||
if (of_find_property(op->dev.of_node, "fsl,7-wire-mode", NULL)) {
|
if (of_find_property(np, "fsl,7-wire-mode", NULL)) {
|
||||||
priv->seven_wire_mode = 1;
|
priv->seven_wire_mode = 1;
|
||||||
dev_info(&ndev->dev, "using 7-wire PHY mode\n");
|
dev_info(&ndev->dev, "using 7-wire PHY mode\n");
|
||||||
}
|
}
|
||||||
@@ -970,6 +982,8 @@ static int mpc52xx_fec_probe(struct platform_device *op)
|
|||||||
|
|
||||||
/* We're done ! */
|
/* We're done ! */
|
||||||
dev_set_drvdata(&op->dev, ndev);
|
dev_set_drvdata(&op->dev, ndev);
|
||||||
|
printk(KERN_INFO "%s: %s MAC %pM\n",
|
||||||
|
ndev->name, op->dev.of_node->full_name, ndev->dev_addr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user