From a833dd512dd958e68cc2e71bca39cb2a945fc549 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 5 Jul 2014 15:04:50 +0000 Subject: [PATCH] brcm47xx: do not use mac addresses with 00:90:4C prefix, prevent mac address collisions. 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 SVN-Revision: 41513 --- .../180-generate-mac-address.patch | 68 +++++++++++++++++++ .../180-generate-mac-address.patch | 68 +++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 target/linux/brcm47xx/patches-3.10/180-generate-mac-address.patch create mode 100644 target/linux/brcm47xx/patches-3.14/180-generate-mac-address.patch 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 index 0000000000..58112ce7f1 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.10/180-generate-mac-address.patch @@ -0,0 +1,68 @@ +--- a/arch/mips/bcm47xx/sprom.c ++++ b/arch/mips/bcm47xx/sprom.c +@@ -28,6 +28,7 @@ + + #include + #include ++#include + + 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 index 0000000000..58112ce7f1 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.14/180-generate-mac-address.patch @@ -0,0 +1,68 @@ +--- a/arch/mips/bcm47xx/sprom.c ++++ b/arch/mips/bcm47xx/sprom.c +@@ -28,6 +28,7 @@ + + #include + #include ++#include + + 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, -- 2.30.2