add chaos_calmer branch
[15.05/openwrt.git] / package / kernel / broadcom-wl / patches / 120-fixup-mac-addresses.patch
1 --- a/driver/nvram_stub.c
2 +++ b/driver/nvram_stub.c
3 @@ -5,6 +5,7 @@
4  #include <siutils.h>
5  #include <bcmendian.h>
6  #include <bcmnvram.h>
7 +#include <proto/ethernet.h>
8  
9  #ifdef BCMDBG_ERR
10  #define NVR_MSG(x) printf x
11 @@ -24,6 +25,7 @@ typedef struct _vars {
12  static vars_t *vars = NULL;
13  static int nvram_init_done = 0;
14  extern char *nvram_buf[];
15 +static void fixup_mac_addr(vars_t *new);
16  
17  int
18  BCMATTACHFN(nvram_init)(void *si)
19 @@ -55,6 +57,7 @@ BCMATTACHFN(nvram_init)(void *si)
20         vars = new;
21  
22         bcopy((char *)(&nvh[1]), new->vars, nvs);
23 +       fixup_mac_addr(new);
24         return 0;
25  }
26  
27 @@ -164,3 +167,65 @@ nvram_getall(char *buf, int count)
28         *buf = '\0';
29         return 0;
30  }
31 +
32 +static bool nvram_is_valid_mac(struct ether_addr *mac)
33 +{
34 +       return mac && !(mac->octet[0] == 0x00 && mac->octet[1] == 0x90 && mac->octet[2] == 0x4c);
35 +}
36 +
37 +static int nvram_increase_mac_addr(struct ether_addr *mac, u8 num)
38 +{
39 +       u8 *oui = mac->octet + ETHER_ADDR_LEN/2 - 1;
40 +       u8 *p = mac->octet + ETHER_ADDR_LEN - 1;
41 +
42 +       do {
43 +               (*p) += num;
44 +               if (*p > num)
45 +                       break;
46 +               p--;
47 +               num = 1;
48 +       } while (p != oui);
49 +
50 +       if (p == oui) {
51 +               pr_err("unable to fetch mac address\n");
52 +               return -ENOENT;
53 +       }
54 +       return 0;
55 +}
56 +
57 +static void nvram_change_mac_addr(vars_t *new, struct ether_addr *valid, const char *name)
58 +{
59 +       char *macaddr_c;
60 +       struct ether_addr macaddr;
61 +
62 +       macaddr_c = findvar(new->vars, new->vars + new->size, name);
63 +       if (!macaddr_c)
64 +               return;
65 +
66 +       bcm_ether_atoe(macaddr_c, &macaddr);
67 +       if (nvram_is_valid_mac(&macaddr))
68 +               return;
69 +       nvram_increase_mac_addr(valid, 1);
70 +       bcm_ether_ntoa(valid, macaddr_c);
71 +}
72 +
73 +static void fixup_mac_addr(vars_t *new)
74 +{
75 +       char *macaddr_base_c;
76 +       struct ether_addr macaddr_base;
77 +
78 +       macaddr_base_c = findvar(new->vars, new->vars + new->size, "et0macaddr");
79 +       if (!macaddr_base_c)
80 +               return;
81 +
82 +       bcm_ether_atoe(macaddr_base_c, &macaddr_base);
83 +       if (!nvram_is_valid_mac(&macaddr_base))
84 +               return;
85 +
86 +       /* jump over the first free address so it can be used for wan */
87 +       nvram_increase_mac_addr(&macaddr_base, 1);
88 +       nvram_change_mac_addr(new, &macaddr_base, "sb/1/macaddr");
89 +       nvram_change_mac_addr(new, &macaddr_base, "pci/1/1/macaddr");
90 +       nvram_change_mac_addr(new, &macaddr_base, "pci/1/2/macaddr");
91 +       nvram_change_mac_addr(new, &macaddr_base, "pci/2/1/macaddr");
92 +}