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:
		@@ -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,
 | 
			
		||||
@@ -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,
 | 
			
		||||
		Reference in New Issue
	
	Block a user