2014-07-31 21:40:38 +00:00
|
|
|
From 103c0bf3ff46486466bc9138d70c25133d516003 Mon Sep 17 00:00:00 2001
|
|
|
|
From: Hauke Mehrtens <hauke@hauke-m.de>
|
|
|
|
Date: Tue, 29 Jul 2014 00:08:01 +0200
|
|
|
|
Subject: [PATCH] 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>
|
|
|
|
---
|
|
|
|
arch/mips/bcm47xx/sprom.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
1 file changed, 48 insertions(+)
|
|
|
|
|
2014-07-05 15:04:50 +00:00
|
|
|
--- a/arch/mips/bcm47xx/sprom.c
|
|
|
|
+++ b/arch/mips/bcm47xx/sprom.c
|
2014-07-31 21:40:38 +00:00
|
|
|
@@ -28,6 +28,8 @@
|
2014-07-05 15:04:50 +00:00
|
|
|
|
|
|
|
#include <bcm47xx.h>
|
|
|
|
#include <bcm47xx_nvram.h>
|
|
|
|
+#include <linux/if_ether.h>
|
2014-07-31 21:40:38 +00:00
|
|
|
+#include <linux/etherdevice.h>
|
2014-07-05 15:04:50 +00:00
|
|
|
|
|
|
|
static void create_key(const char *prefix, const char *postfix,
|
|
|
|
const char *name, char *buf, int len)
|
2014-07-31 21:40:38 +00:00
|
|
|
@@ -631,6 +633,33 @@ static void bcm47xx_fill_sprom_path_r45(
|
2014-07-05 15:04:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
+static bool bcm47xx_is_valid_mac(u8 *mac)
|
|
|
|
+{
|
2014-07-05 19:36:49 +00:00
|
|
|
+ return mac && !(mac[0] == 0x00 && mac[1] == 0x90 && mac[2] == 0x4c);
|
2014-07-05 15:04:50 +00:00
|
|
|
+}
|
|
|
|
+
|
|
|
|
+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;
|
|
|
|
+}
|
|
|
|
+
|
2014-07-05 19:36:49 +00:00
|
|
|
+static int mac_addr_used = 2;
|
2014-07-05 15:04:50 +00:00
|
|
|
+
|
|
|
|
static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom,
|
|
|
|
const char *prefix, bool fallback)
|
|
|
|
{
|
2014-07-31 21:40:38 +00:00
|
|
|
@@ -648,6 +677,25 @@ static void bcm47xx_fill_sprom_ethernet(
|
2014-07-05 15:04:50 +00:00
|
|
|
|
|
|
|
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];
|
2014-07-31 21:40:38 +00:00
|
|
|
+
|
2014-07-05 15:04:50 +00:00
|
|
|
+ nvram_read_macaddr(NULL, "et0macaddr", mac, false);
|
|
|
|
+ if (bcm47xx_is_valid_mac(mac)) {
|
|
|
|
+ int err = bcm47xx_increase_mac_addr(mac, mac_addr_used);
|
2014-07-31 21:40:38 +00:00
|
|
|
+
|
2014-07-05 15:04:50 +00:00
|
|
|
+ if (!err) {
|
|
|
|
+ memcpy(sprom->il0mac, mac, ETH_ALEN);
|
|
|
|
+ mac_addr_used++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
}
|
|
|
|
|
|
|
|
static void bcm47xx_fill_board_data(struct ssb_sprom *sprom, const char *prefix,
|