From db98f081888cbdd995c7c4cfd407781da35e33ba Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 12 Feb 2013 03:05:38 +0000 Subject: [PATCH] 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 Cc: Anatolij Gustschin Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec_mpc52xx.c | 62 ++++++++++++-------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec_mpc52xx.c b/drivers/net/ethernet/freescale/fec_mpc52xx.c index 817d081d2cd8..7f91b0c5c264 100644 --- a/drivers/net/ethernet/freescale/fec_mpc52xx.c +++ b/drivers/net/ethernet/freescale/fec_mpc52xx.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -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_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 | \ NETIF_MSG_LINK | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP) 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); } -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) { struct sockaddr *sock = addr; @@ -853,6 +841,8 @@ static int mpc52xx_fec_probe(struct platform_device *op) struct resource mem; const u32 *prop; int prop_size; + struct device_node *np = op->dev.of_node; + const char *mac_addr; phys_addr_t rx_fifo; phys_addr_t tx_fifo; @@ -866,7 +856,7 @@ static int mpc52xx_fec_probe(struct platform_device *op) priv->ndev = ndev; /* 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) { printk(KERN_ERR DRIVER_NAME ": " "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 */ /* Control */ - ndev->irq = irq_of_parse_and_map(op->dev.of_node, 0); + ndev->irq = irq_of_parse_and_map(np, 0); /* RX */ priv->r_irq = bcom_get_task_irq(priv->rx_dmatsk); @@ -927,11 +917,33 @@ static int mpc52xx_fec_probe(struct platform_device *op) /* TX */ priv->t_irq = bcom_get_task_irq(priv->tx_dmatsk); - /* MAC address init */ - if (!is_zero_ether_addr(mpc52xx_fec_mac_addr)) - memcpy(ndev->dev_addr, mpc52xx_fec_mac_addr, 6); - else - mpc52xx_fec_get_paddr(ndev, ndev->dev_addr); + /* + * MAC address init: + * + * First try to read MAC address from DT + */ + 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); @@ -942,20 +954,20 @@ static int mpc52xx_fec_probe(struct platform_device *op) /* Start with safe defaults for link connection */ priv->speed = 100; 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 */ - 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)) { priv->speed = prop[0]; priv->duplex = prop[1] ? DUPLEX_FULL : DUPLEX_HALF; } /* 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 */ - 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; 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 ! */ 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; -- 2.30.2