mvebu: backport mainline patches from kernel 3.11
[openwrt/svn-archive/archive.git] / target / linux / mvebu / patches-3.10 / 0020-net-mvneta-read-MAC-address-from-hardware-when-avail.patch
1 From 25d3318a445c4f4360f86bf6d1d1a320d9646bb5 Mon Sep 17 00:00:00 2001
2 From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
3 Date: Tue, 4 Jun 2013 04:52:23 +0000
4 Subject: [PATCH 020/203] net: mvneta: read MAC address from hardware when
5 available
6
7 This patch improves the logic used by the mvneta driver to find a MAC
8 address for a particular interface. Until now, it was only looking at
9 the Device Tree, and if no address was found, was falling back to
10 generating a random MAC address.
11
12 This patch adds the intermediate solution of reading the MAC address
13 from the hardware registers, in case it has been set by the
14 bootloader. So the order is now:
15
16 1) MAC address from the Device Tree
17 2) MAC address from the hardware registers
18 3) Random MAC address
19
20 This requires moving the MAC address initialization a little bit later
21 in the ->probe() code, because it now requires the hardware registers
22 to be remapped.
23
24 Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
25 Cc: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
26 Cc: Joe Perches <joe@perches.com>
27 Signed-off-by: David S. Miller <davem@davemloft.net>
28 ---
29 drivers/net/ethernet/marvell/mvneta.c | 44 ++++++++++++++++++++++++++++-------
30 1 file changed, 35 insertions(+), 9 deletions(-)
31
32 --- a/drivers/net/ethernet/marvell/mvneta.c
33 +++ b/drivers/net/ethernet/marvell/mvneta.c
34 @@ -2260,6 +2260,21 @@ static int mvneta_change_mtu(struct net_
35 return 0;
36 }
37
38 +/* Get mac address */
39 +static void mvneta_get_mac_addr(struct mvneta_port *pp, unsigned char *addr)
40 +{
41 + u32 mac_addr_l, mac_addr_h;
42 +
43 + mac_addr_l = mvreg_read(pp, MVNETA_MAC_ADDR_LOW);
44 + mac_addr_h = mvreg_read(pp, MVNETA_MAC_ADDR_HIGH);
45 + addr[0] = (mac_addr_h >> 24) & 0xFF;
46 + addr[1] = (mac_addr_h >> 16) & 0xFF;
47 + addr[2] = (mac_addr_h >> 8) & 0xFF;
48 + addr[3] = mac_addr_h & 0xFF;
49 + addr[4] = (mac_addr_l >> 8) & 0xFF;
50 + addr[5] = mac_addr_l & 0xFF;
51 +}
52 +
53 /* Handle setting mac address */
54 static int mvneta_set_mac_addr(struct net_device *dev, void *addr)
55 {
56 @@ -2678,7 +2693,9 @@ static int mvneta_probe(struct platform_
57 u32 phy_addr;
58 struct mvneta_port *pp;
59 struct net_device *dev;
60 - const char *mac_addr;
61 + const char *dt_mac_addr;
62 + char hw_mac_addr[ETH_ALEN];
63 + const char *mac_from;
64 int phy_mode;
65 int err;
66
67 @@ -2714,13 +2731,6 @@ static int mvneta_probe(struct platform_
68 goto err_free_irq;
69 }
70
71 - mac_addr = of_get_mac_address(dn);
72 -
73 - if (!mac_addr || !is_valid_ether_addr(mac_addr))
74 - eth_hw_addr_random(dev);
75 - else
76 - memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
77 -
78 dev->tx_queue_len = MVNETA_MAX_TXD;
79 dev->watchdog_timeo = 5 * HZ;
80 dev->netdev_ops = &mvneta_netdev_ops;
81 @@ -2751,6 +2761,21 @@ static int mvneta_probe(struct platform_
82
83 clk_prepare_enable(pp->clk);
84
85 + dt_mac_addr = of_get_mac_address(dn);
86 + if (dt_mac_addr && is_valid_ether_addr(dt_mac_addr)) {
87 + mac_from = "device tree";
88 + memcpy(dev->dev_addr, dt_mac_addr, ETH_ALEN);
89 + } else {
90 + mvneta_get_mac_addr(pp, hw_mac_addr);
91 + if (is_valid_ether_addr(hw_mac_addr)) {
92 + mac_from = "hardware";
93 + memcpy(dev->dev_addr, hw_mac_addr, ETH_ALEN);
94 + } else {
95 + mac_from = "random";
96 + eth_hw_addr_random(dev);
97 + }
98 + }
99 +
100 pp->tx_done_timer.data = (unsigned long)dev;
101
102 pp->tx_ring_size = MVNETA_MAX_TXD;
103 @@ -2783,7 +2808,8 @@ static int mvneta_probe(struct platform_
104 goto err_deinit;
105 }
106
107 - netdev_info(dev, "mac: %pM\n", dev->dev_addr);
108 + netdev_info(dev, "Using %s mac address %pM\n", mac_from,
109 + dev->dev_addr);
110
111 platform_set_drvdata(pdev, pp->dev);
112