aboutsummaryrefslogtreecommitdiffstats
path: root/target
diff options
context:
space:
mode:
Diffstat (limited to 'target')
-rw-r--r--target/linux/brcm47xx/patches-3.10/180-generate-mac-address.patch68
-rw-r--r--target/linux/brcm47xx/patches-3.14/180-generate-mac-address.patch68
2 files changed, 136 insertions, 0 deletions
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 <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,
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 <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,