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 <hauke@hauke-m.de>

SVN-Revision: 41513
This commit is contained in:
Hauke Mehrtens 2014-07-05 15:04:50 +00:00
parent 163fe41c75
commit 3fff38f93a
2 changed files with 136 additions and 0 deletions

View file

@ -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,

View file

@ -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,