summaryrefslogtreecommitdiff
path: root/arch/mips/bcm47xx/sprom.c
diff options
context:
space:
mode:
authorHauke Mehrtens <hauke@hauke-m.de>2014-07-29 02:08:01 +0400
committerRalf Baechle <ralf@linux-mips.org>2014-07-30 21:25:15 +0400
commit103c0bf3ff46486466bc9138d70c25133d516003 (patch)
tree56f1a2d28257a5a33c4845627e4003301227b41f /arch/mips/bcm47xx/sprom.c
parent316cad5c1d4daee998cd1f83ccdb437f6f20d45c (diff)
downloadlinux-103c0bf3ff46486466bc9138d70c25133d516003.tar.xz
MIPS: BCM47XX: fixup broken MAC addresses in nvram
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. To generate such addresses we take the main mac address from et0macaddr and increase it by two for the first wifi device and by 3 for the second one. This matches the printed mac address on the device. The main mac address increased by one is used as wan address by the vendor code. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> Cc: zajec5@gmail.com Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/7489/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/bcm47xx/sprom.c')
-rw-r--r--arch/mips/bcm47xx/sprom.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c
index da4cdb16844e..41226b68de3d 100644
--- a/arch/mips/bcm47xx/sprom.c
+++ b/arch/mips/bcm47xx/sprom.c
@@ -28,6 +28,8 @@
#include <bcm47xx.h>
#include <bcm47xx_nvram.h>
+#include <linux/if_ether.h>
+#include <linux/etherdevice.h>
static void create_key(const char *prefix, const char *postfix,
const char *name, char *buf, int len)
@@ -631,6 +633,33 @@ static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom,
}
}
+static bool bcm47xx_is_valid_mac(u8 *mac)
+{
+ return mac && !(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 = 2;
+
static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom,
const char *prefix, bool fallback)
{
@@ -648,6 +677,25 @@ static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom,
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) {
+ ether_addr_copy(sprom->il0mac, mac);
+ mac_addr_used++;
+ }
+ }
+ }
}
static void bcm47xx_fill_board_data(struct ssb_sprom *sprom, const char *prefix,