diff options
author | Gavin Shan <gwshan@linux.vnet.ibm.com> | 2016-07-19 11:54:22 +1000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-07-19 20:49:17 -0700 |
commit | 113ce107afe979902c003900bfaed7878d8a5968 (patch) | |
tree | 3e1165acbab424ee756fc9447848e0bcf2724d2b /drivers/net/ethernet/faraday/ftgmac100.c | |
parent | eb4181849f58f31d8d68762b6d87c6f06b86dbbd (diff) | |
download | lwn-113ce107afe979902c003900bfaed7878d8a5968.tar.gz lwn-113ce107afe979902c003900bfaed7878d8a5968.zip |
net/faraday: Read MAC address from chip
The device is assigned with random MAC address. It isn't reasonable.
An valid MAC address might have been provided by (uboot) firmware by
device-tree or in chip. It's reasonable to use it to maintain consistency.
This uses the MAC address from device-tree or that in the chip if it's
valid. Otherwise, a random MAC address is given as before.
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Acked-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/faraday/ftgmac100.c')
-rw-r--r-- | drivers/net/ethernet/faraday/ftgmac100.c | 69 |
1 files changed, 62 insertions, 7 deletions
diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c index 9b09493b8b75..2c3f6563944a 100644 --- a/drivers/net/ethernet/faraday/ftgmac100.c +++ b/drivers/net/ethernet/faraday/ftgmac100.c @@ -141,6 +141,64 @@ static void ftgmac100_set_mac(struct ftgmac100 *priv, const unsigned char *mac) iowrite32(laddr, priv->base + FTGMAC100_OFFSET_MAC_LADR); } +static void ftgmac100_setup_mac(struct ftgmac100 *priv) +{ + u8 mac[ETH_ALEN]; + unsigned int m; + unsigned int l; + void *addr; + + addr = device_get_mac_address(priv->dev, mac, ETH_ALEN); + if (addr) { + ether_addr_copy(priv->netdev->dev_addr, mac); + dev_info(priv->dev, "Read MAC address %pM from device tree\n", + mac); + return; + } + + m = ioread32(priv->base + FTGMAC100_OFFSET_MAC_MADR); + l = ioread32(priv->base + FTGMAC100_OFFSET_MAC_LADR); + + mac[0] = (m >> 8) & 0xff; + mac[1] = m & 0xff; + mac[2] = (l >> 24) & 0xff; + mac[3] = (l >> 16) & 0xff; + mac[4] = (l >> 8) & 0xff; + mac[5] = l & 0xff; + + if (!is_valid_ether_addr(mac)) { + mac[5] = (m >> 8) & 0xff; + mac[4] = m & 0xff; + mac[3] = (l >> 24) & 0xff; + mac[2] = (l >> 16) & 0xff; + mac[1] = (l >> 8) & 0xff; + mac[0] = l & 0xff; + } + + if (is_valid_ether_addr(mac)) { + ether_addr_copy(priv->netdev->dev_addr, mac); + dev_info(priv->dev, "Read MAC address %pM from chip\n", mac); + } else { + eth_hw_addr_random(priv->netdev); + dev_info(priv->dev, "Generated random MAC address %pM\n", + priv->netdev->dev_addr); + } +} + +static int ftgmac100_set_mac_addr(struct net_device *dev, void *p) +{ + int ret; + + ret = eth_prepare_mac_addr_change(dev, p); + if (ret < 0) + return ret; + + eth_commit_mac_addr_change(dev, p); + ftgmac100_set_mac(netdev_priv(dev), dev->dev_addr); + + return 0; +} + static void ftgmac100_init_hw(struct ftgmac100 *priv) { /* setup ring buffer base registers */ @@ -1141,7 +1199,7 @@ static const struct net_device_ops ftgmac100_netdev_ops = { .ndo_open = ftgmac100_open, .ndo_stop = ftgmac100_stop, .ndo_start_xmit = ftgmac100_hard_start_xmit, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = ftgmac100_set_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = ftgmac100_do_ioctl, }; @@ -1265,6 +1323,9 @@ static int ftgmac100_probe(struct platform_device *pdev) priv->irq = irq; + /* MAC address from chip or random one */ + ftgmac100_setup_mac(priv); + err = ftgmac100_setup_mdio(netdev); if (err) goto err_setup_mdio; @@ -1278,12 +1339,6 @@ static int ftgmac100_probe(struct platform_device *pdev) netdev_info(netdev, "irq %d, mapped at %p\n", priv->irq, priv->base); - if (!is_valid_ether_addr(netdev->dev_addr)) { - eth_hw_addr_random(netdev); - netdev_info(netdev, "generated random MAC address %pM\n", - netdev->dev_addr); - } - return 0; err_register_netdev: |