brcm47xx: increase fallback mac addresses by one
[15.05/openwrt.git] / target / linux / brcm47xx / patches-3.10 / 180-generate-mac-address.patch
1 --- a/arch/mips/bcm47xx/sprom.c
2 +++ b/arch/mips/bcm47xx/sprom.c
3 @@ -28,6 +28,7 @@
4  
5  #include <bcm47xx.h>
6  #include <bcm47xx_nvram.h>
7 +#include <linux/if_ether.h>
8  
9  static void create_key(const char *prefix, const char *postfix,
10                        const char *name, char *buf, int len)
11 @@ -631,6 +632,33 @@ static void bcm47xx_fill_sprom_path_r45(
12         }
13  }
14  
15 +static bool bcm47xx_is_valid_mac(u8 *mac)
16 +{
17 +       return mac && !(mac[0] == 0x00 && mac[1] == 0x90 && mac[2] == 0x4c);
18 +}
19 +
20 +static int bcm47xx_increase_mac_addr(u8 *mac, u8 num)
21 +{
22 +       u8 *oui = mac + ETH_ALEN/2 - 1;
23 +       u8 *p = mac + ETH_ALEN - 1;
24 +
25 +       do {
26 +               (*p) += num;
27 +               if (*p > num)
28 +                       break;
29 +               p--;
30 +               num = 1;
31 +       } while (p != oui);
32 +
33 +       if (p == oui) {
34 +               pr_err("unable to fetch mac address\n");
35 +               return -ENOENT;
36 +       }
37 +       return 0;
38 +}
39 +
40 +static int mac_addr_used = 2;
41 +
42  static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom,
43                                         const char *prefix, bool fallback)
44  {
45 @@ -648,6 +676,23 @@ static void bcm47xx_fill_sprom_ethernet(
46  
47         nvram_read_macaddr(prefix, "macaddr", sprom->il0mac, fallback);
48         nvram_read_macaddr(prefix, "il0macaddr", sprom->il0mac, fallback);
49 +
50 +       /* The address prefix 00:90:4C is used by Broadcom in their initial
51 +          configuration. When a mac address with the prefix 00:90:4C is used
52 +          all devices from the same series are sharing the same mac address.
53 +          To prevent mac address collisions we replace them with a mac address
54 +          based on the base address. */
55 +       if (!bcm47xx_is_valid_mac(sprom->il0mac)) {
56 +               u8 mac[6];
57 +               nvram_read_macaddr(NULL, "et0macaddr", mac, false);
58 +               if (bcm47xx_is_valid_mac(mac)) {
59 +                       int err = bcm47xx_increase_mac_addr(mac, mac_addr_used);
60 +                       if (!err) {
61 +                               memcpy(sprom->il0mac, mac, ETH_ALEN);
62 +                               mac_addr_used++;
63 +                       }
64 +               }
65 +       }
66  }
67  
68  static void bcm47xx_fill_board_data(struct ssb_sprom *sprom, const char *prefix,