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