brcm47xx: do not use mac addresses with 00:90:4C prefix, prevent mac address collisions.
authorhauke <hauke@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Sat, 5 Jul 2014 15:04:50 +0000 (15:04 +0000)
committerhauke <hauke@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Sat, 5 Jul 2014 15:04:50 +0000 (15:04 +0000)
The address prefix 00:90:4C is used by Broadcom in their initial
configuration. When a mac address with the prefix 00:90:4C is used
all devices from the same series are sharing the same mac address.
To prevent mac address collisions we replace them with a mac address
based on the base address.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@41513 3c298f89-4303-0410-b956-a3cf2f4a3e73

target/linux/brcm47xx/patches-3.10/180-generate-mac-address.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.14/180-generate-mac-address.patch [new file with mode: 0644]

diff --git a/target/linux/brcm47xx/patches-3.10/180-generate-mac-address.patch b/target/linux/brcm47xx/patches-3.10/180-generate-mac-address.patch
new file mode 100644 (file)
index 0000000..58112ce
--- /dev/null
@@ -0,0 +1,68 @@
+--- a/arch/mips/bcm47xx/sprom.c
++++ b/arch/mips/bcm47xx/sprom.c
+@@ -28,6 +28,7 @@
+ #include <bcm47xx.h>
+ #include <bcm47xx_nvram.h>
++#include <linux/if_ether.h>
+ static void create_key(const char *prefix, const char *postfix,
+                      const char *name, char *buf, int len)
+@@ -631,6 +632,33 @@ static void bcm47xx_fill_sprom_path_r45(
+       }
+ }
++static bool bcm47xx_is_valid_mac(u8 *mac)
++{
++      return !(mac[0] == 0x00 && mac[1] == 0x90 && mac[2] == 0x4c);
++}
++
++static int bcm47xx_increase_mac_addr(u8 *mac, u8 num)
++{
++      u8 *oui = mac + ETH_ALEN/2 - 1;
++      u8 *p = mac + ETH_ALEN - 1;
++
++      do {
++              (*p) += num;
++              if (*p > num)
++                      break;
++              p--;
++              num = 1;
++      } while (p != oui);
++
++      if (p == oui) {
++              pr_err("unable to fetch mac address\n");
++              return -ENOENT;
++      }
++      return 0;
++}
++
++static int mac_addr_used = 1;
++
+ static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom,
+                                       const char *prefix, bool fallback)
+ {
+@@ -648,6 +676,23 @@ static void bcm47xx_fill_sprom_ethernet(
+       nvram_read_macaddr(prefix, "macaddr", sprom->il0mac, fallback);
+       nvram_read_macaddr(prefix, "il0macaddr", sprom->il0mac, fallback);
++
++      /* The address prefix 00:90:4C is used by Broadcom in their initial
++         configuration. When a mac address with the prefix 00:90:4C is used
++         all devices from the same series are sharing the same mac address.
++         To prevent mac address collisions we replace them with a mac address
++         based on the base address. */
++      if (!bcm47xx_is_valid_mac(sprom->il0mac)) {
++              u8 mac[6];
++              nvram_read_macaddr(NULL, "et0macaddr", mac, false);
++              if (bcm47xx_is_valid_mac(mac)) {
++                      int err = bcm47xx_increase_mac_addr(mac, mac_addr_used);
++                      if (!err) {
++                              memcpy(sprom->il0mac, mac, ETH_ALEN);
++                              mac_addr_used++;
++                      }
++              }
++      }
+ }
+ static void bcm47xx_fill_board_data(struct ssb_sprom *sprom, const char *prefix,
diff --git a/target/linux/brcm47xx/patches-3.14/180-generate-mac-address.patch b/target/linux/brcm47xx/patches-3.14/180-generate-mac-address.patch
new file mode 100644 (file)
index 0000000..58112ce
--- /dev/null
@@ -0,0 +1,68 @@
+--- a/arch/mips/bcm47xx/sprom.c
++++ b/arch/mips/bcm47xx/sprom.c
+@@ -28,6 +28,7 @@
+ #include <bcm47xx.h>
+ #include <bcm47xx_nvram.h>
++#include <linux/if_ether.h>
+ static void create_key(const char *prefix, const char *postfix,
+                      const char *name, char *buf, int len)
+@@ -631,6 +632,33 @@ static void bcm47xx_fill_sprom_path_r45(
+       }
+ }
++static bool bcm47xx_is_valid_mac(u8 *mac)
++{
++      return !(mac[0] == 0x00 && mac[1] == 0x90 && mac[2] == 0x4c);
++}
++
++static int bcm47xx_increase_mac_addr(u8 *mac, u8 num)
++{
++      u8 *oui = mac + ETH_ALEN/2 - 1;
++      u8 *p = mac + ETH_ALEN - 1;
++
++      do {
++              (*p) += num;
++              if (*p > num)
++                      break;
++              p--;
++              num = 1;
++      } while (p != oui);
++
++      if (p == oui) {
++              pr_err("unable to fetch mac address\n");
++              return -ENOENT;
++      }
++      return 0;
++}
++
++static int mac_addr_used = 1;
++
+ static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom,
+                                       const char *prefix, bool fallback)
+ {
+@@ -648,6 +676,23 @@ static void bcm47xx_fill_sprom_ethernet(
+       nvram_read_macaddr(prefix, "macaddr", sprom->il0mac, fallback);
+       nvram_read_macaddr(prefix, "il0macaddr", sprom->il0mac, fallback);
++
++      /* The address prefix 00:90:4C is used by Broadcom in their initial
++         configuration. When a mac address with the prefix 00:90:4C is used
++         all devices from the same series are sharing the same mac address.
++         To prevent mac address collisions we replace them with a mac address
++         based on the base address. */
++      if (!bcm47xx_is_valid_mac(sprom->il0mac)) {
++              u8 mac[6];
++              nvram_read_macaddr(NULL, "et0macaddr", mac, false);
++              if (bcm47xx_is_valid_mac(mac)) {
++                      int err = bcm47xx_increase_mac_addr(mac, mac_addr_used);
++                      if (!err) {
++                              memcpy(sprom->il0mac, mac, ETH_ALEN);
++                              mac_addr_used++;
++                      }
++              }
++      }
+ }
+ static void bcm47xx_fill_board_data(struct ssb_sprom *sprom, const char *prefix,