summaryrefslogtreecommitdiff
path: root/arch/mips/bcm47xx
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/bcm47xx')
-rw-r--r--arch/mips/bcm47xx/Kconfig5
-rw-r--r--arch/mips/bcm47xx/bcm47xx_private.h3
-rw-r--r--arch/mips/bcm47xx/board.c26
-rw-r--r--arch/mips/bcm47xx/buttons.c38
-rw-r--r--arch/mips/bcm47xx/leds.c92
-rw-r--r--arch/mips/bcm47xx/prom.c68
-rw-r--r--arch/mips/bcm47xx/setup.c7
-rw-r--r--arch/mips/bcm47xx/sprom.c48
8 files changed, 259 insertions, 28 deletions
diff --git a/arch/mips/bcm47xx/Kconfig b/arch/mips/bcm47xx/Kconfig
index 09cb6f7aa3db..fc21d3659fa0 100644
--- a/arch/mips/bcm47xx/Kconfig
+++ b/arch/mips/bcm47xx/Kconfig
@@ -11,8 +11,6 @@ config BCM47XX_SSB
select SSB_DRIVER_PCICORE if PCI
select SSB_PCICORE_HOSTMODE if PCI
select SSB_DRIVER_GPIO
- select GPIOLIB
- select LEDS_GPIO_REGISTER
default y
help
Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support.
@@ -22,6 +20,7 @@ config BCM47XX_SSB
config BCM47XX_BCMA
bool "BCMA Support for Broadcom BCM47XX"
select SYS_HAS_CPU_MIPS32_R2
+ select SYS_SUPPORTS_HIGHMEM
select CPU_MIPSR2_IRQ_VI
select BCMA
select BCMA_HOST_SOC
@@ -29,8 +28,6 @@ config BCM47XX_BCMA
select BCMA_HOST_PCI if PCI
select BCMA_DRIVER_PCI_HOSTMODE if PCI
select BCMA_DRIVER_GPIO
- select GPIOLIB
- select LEDS_GPIO_REGISTER
default y
help
Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.
diff --git a/arch/mips/bcm47xx/bcm47xx_private.h b/arch/mips/bcm47xx/bcm47xx_private.h
index 0194c3b9a729..f1cc9d0495d8 100644
--- a/arch/mips/bcm47xx/bcm47xx_private.h
+++ b/arch/mips/bcm47xx/bcm47xx_private.h
@@ -3,6 +3,9 @@
#include <linux/kernel.h>
+/* prom.c */
+void __init bcm47xx_prom_highmem_init(void);
+
/* buttons.c */
int __init bcm47xx_buttons_register(void);
diff --git a/arch/mips/bcm47xx/board.c b/arch/mips/bcm47xx/board.c
index 44ab1be68c3c..b3ae068ca4fa 100644
--- a/arch/mips/bcm47xx/board.c
+++ b/arch/mips/bcm47xx/board.c
@@ -58,6 +58,7 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_machine_name[] __initconst =
static const
struct bcm47xx_board_type_list1 bcm47xx_board_list_hardware_version[] __initconst = {
{{BCM47XX_BOARD_ASUS_RTN10U, "Asus RT-N10U"}, "RTN10U"},
+ {{BCM47XX_BOARD_ASUS_RTN10D, "Asus RT-N10D"}, "RTN10D"},
{{BCM47XX_BOARD_ASUS_RTN12, "Asus RT-N12"}, "RT-N12"},
{{BCM47XX_BOARD_ASUS_RTN12B1, "Asus RT-N12B1"}, "RTN12B1"},
{{BCM47XX_BOARD_ASUS_RTN12C1, "Asus RT-N12C1"}, "RTN12C1"},
@@ -80,6 +81,14 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_hardware_version[] __initcons
{ {0}, NULL},
};
+/* hardware_version, boardnum */
+static const
+struct bcm47xx_board_type_list2 bcm47xx_board_list_hw_version_num[] __initconst = {
+ {{BCM47XX_BOARD_MICROSOFT_MN700, "Microsoft MN-700"}, "WL500-", "mn700"},
+ {{BCM47XX_BOARD_ASUS_WL500G, "Asus WL500G"}, "WL500-", "asusX"},
+ { {0}, NULL},
+};
+
/* productid */
static const
struct bcm47xx_board_type_list1 bcm47xx_board_list_productid[] __initconst = {
@@ -98,7 +107,7 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_productid[] __initconst = {
/* ModelId */
static const
struct bcm47xx_board_type_list1 bcm47xx_board_list_ModelId[] __initconst = {
- {{BCM47XX_BOARD_DELL_TM2300, "Dell WX-5565"}, "WX-5565"},
+ {{BCM47XX_BOARD_DELL_TM2300, "Dell TrueMobile 2300"}, "WX-5565"},
{{BCM47XX_BOARD_MOTOROLA_WE800G, "Motorola WE800G"}, "WE800G"},
{{BCM47XX_BOARD_MOTOROLA_WR850GP, "Motorola WR850GP"}, "WR850GP"},
{{BCM47XX_BOARD_MOTOROLA_WR850GV2V3, "Motorola WR850G"}, "WR850G"},
@@ -180,9 +189,9 @@ struct bcm47xx_board_type_list3 bcm47xx_board_list_board[] __initconst = {
{{BCM47XX_BOARD_PHICOMM_M1, "Phicomm M1"}, "0x0590", "80", "0x1104"},
{{BCM47XX_BOARD_ZTE_H218N, "ZTE H218N"}, "0x053d", "1234", "0x1305"},
{{BCM47XX_BOARD_NETGEAR_WNR3500L, "Netgear WNR3500L"}, "0x04CF", "3500", "02"},
- {{BCM47XX_BOARD_LINKSYS_WRT54G, "Linksys WRT54G/GS/GL"}, "0x0101", "42", "0x10"},
- {{BCM47XX_BOARD_LINKSYS_WRT54G, "Linksys WRT54G/GS/GL"}, "0x0467", "42", "0x10"},
- {{BCM47XX_BOARD_LINKSYS_WRT54G, "Linksys WRT54G/GS/GL"}, "0x0708", "42", "0x10"},
+ {{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101, "Linksys WRT54G/GS/GL"}, "0x0101", "42", "0x10"},
+ {{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467, "Linksys WRT54G/GS/GL"}, "0x0467", "42", "0x10"},
+ {{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708, "Linksys WRT54G/GS/GL"}, "0x0708", "42", "0x10"},
{ {0}, NULL},
};
@@ -237,6 +246,15 @@ static __init const struct bcm47xx_board_type *bcm47xx_board_get_nvram(void)
}
}
+ if (bcm47xx_nvram_getenv("hardware_version", buf1, sizeof(buf1)) >= 0 &&
+ bcm47xx_nvram_getenv("boardtype", buf2, sizeof(buf2)) >= 0) {
+ for (e2 = bcm47xx_board_list_boot_hw; e2->value1; e2++) {
+ if (!strstarts(buf1, e2->value1) &&
+ !strcmp(buf2, e2->value2))
+ return &e2->board;
+ }
+ }
+
if (bcm47xx_nvram_getenv("productid", buf1, sizeof(buf1)) >= 0) {
for (e1 = bcm47xx_board_list_productid; e1->value1; e1++) {
if (!strcmp(buf1, e1->value1))
diff --git a/arch/mips/bcm47xx/buttons.c b/arch/mips/bcm47xx/buttons.c
index 49a1ce06844b..913182bcafb8 100644
--- a/arch/mips/bcm47xx/buttons.c
+++ b/arch/mips/bcm47xx/buttons.c
@@ -56,6 +56,11 @@ bcm47xx_buttons_asus_wl330ge[] __initconst = {
};
static const struct gpio_keys_button
+bcm47xx_buttons_asus_wl500g[] __initconst = {
+ BCM47XX_GPIO_KEY(6, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
bcm47xx_buttons_asus_wl500gd[] __initconst = {
BCM47XX_GPIO_KEY(6, KEY_RESTART),
};
@@ -265,7 +270,7 @@ bcm47xx_buttons_linksys_wrt54g3gv2[] __initconst = {
};
static const struct gpio_keys_button
-bcm47xx_buttons_linksys_wrt54gsv1[] __initconst = {
+bcm47xx_buttons_linksys_wrt54g_generic[] __initconst = {
BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
BCM47XX_GPIO_KEY(6, KEY_RESTART),
};
@@ -288,6 +293,13 @@ bcm47xx_buttons_linksys_wrtsl54gs[] __initconst = {
BCM47XX_GPIO_KEY(6, KEY_RESTART),
};
+/* Microsoft */
+
+static const struct gpio_keys_button
+bcm47xx_buttons_microsoft_nm700[] __initconst = {
+ BCM47XX_GPIO_KEY(7, KEY_RESTART),
+};
+
/* Motorola */
static const struct gpio_keys_button
@@ -329,6 +341,12 @@ bcm47xx_buttons_netgear_wndr4500v1[] __initconst = {
};
static const struct gpio_keys_button
+bcm47xx_buttons_netgear_wnr3500lv1[] __initconst = {
+ BCM47XX_GPIO_KEY(4, KEY_RESTART),
+ BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON),
+};
+
+static const struct gpio_keys_button
bcm47xx_buttons_netgear_wnr834bv2[] __initconst = {
BCM47XX_GPIO_KEY(6, KEY_RESTART),
};
@@ -395,6 +413,9 @@ int __init bcm47xx_buttons_register(void)
case BCM47XX_BOARD_ASUS_WL330GE:
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl330ge);
break;
+ case BCM47XX_BOARD_ASUS_WL500G:
+ err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500g);
+ break;
case BCM47XX_BOARD_ASUS_WL500GD:
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500gd);
break;
@@ -501,12 +522,14 @@ int __init bcm47xx_buttons_register(void)
case BCM47XX_BOARD_LINKSYS_WRT310NV1:
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt310nv1);
break;
- case BCM47XX_BOARD_LINKSYS_WRT54G:
- err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54gsv1);
- break;
case BCM47XX_BOARD_LINKSYS_WRT54G3GV2:
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54g3gv2);
break;
+ case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101:
+ case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467:
+ case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708:
+ err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54g_generic);
+ break;
case BCM47XX_BOARD_LINKSYS_WRT610NV1:
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt610nv1);
break;
@@ -517,6 +540,10 @@ int __init bcm47xx_buttons_register(void)
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrtsl54gs);
break;
+ case BCM47XX_BOARD_MICROSOFT_MN700:
+ err = bcm47xx_copy_bdata(bcm47xx_buttons_microsoft_nm700);
+ break;
+
case BCM47XX_BOARD_MOTOROLA_WE800G:
err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_we800g);
break;
@@ -536,6 +563,9 @@ int __init bcm47xx_buttons_register(void)
case BCM47XX_BOARD_NETGEAR_WNDR4500V1:
err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr4500v1);
break;
+ case BCM47XX_BOARD_NETGEAR_WNR3500L:
+ err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr3500lv1);
+ break;
case BCM47XX_BOARD_NETGEAR_WNR834BV2:
err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr834bv2);
break;
diff --git a/arch/mips/bcm47xx/leds.c b/arch/mips/bcm47xx/leds.c
index adcb547a91c3..903a656d4119 100644
--- a/arch/mips/bcm47xx/leds.c
+++ b/arch/mips/bcm47xx/leds.c
@@ -35,6 +35,15 @@ bcm47xx_leds_asus_rtn12[] __initconst = {
};
static const struct gpio_led
+bcm47xx_leds_asus_rtn15u[] __initconst = {
+ /* TODO: Add "wlan" LED */
+ BCM47XX_GPIO_LED(3, "blue", "wan", 1, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(4, "blue", "lan", 1, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(6, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+ BCM47XX_GPIO_LED(9, "blue", "usb", 0, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
bcm47xx_leds_asus_rtn16[] __initconst = {
BCM47XX_GPIO_LED(1, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON),
BCM47XX_GPIO_LED(7, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
@@ -42,8 +51,8 @@ bcm47xx_leds_asus_rtn16[] __initconst = {
static const struct gpio_led
bcm47xx_leds_asus_rtn66u[] __initconst = {
- BCM47XX_GPIO_LED(12, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
- BCM47XX_GPIO_LED(15, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(12, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+ BCM47XX_GPIO_LED(15, "blue", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
};
static const struct gpio_led
@@ -64,6 +73,11 @@ bcm47xx_leds_asus_wl330ge[] __initconst = {
};
static const struct gpio_led
+bcm47xx_leds_asus_wl500g[] __initconst = {
+ BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+};
+
+static const struct gpio_led
bcm47xx_leds_asus_wl500gd[] __initconst = {
BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
};
@@ -216,8 +230,8 @@ bcm47xx_leds_linksys_e1000v1[] __initconst = {
static const struct gpio_led
bcm47xx_leds_linksys_e1000v21[] __initconst = {
- BCM47XX_GPIO_LED(5, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
- BCM47XX_GPIO_LED(6, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+ BCM47XX_GPIO_LED(5, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(6, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON),
BCM47XX_GPIO_LED(7, "amber", "wps", 0, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(8, "blue", "wps", 0, LEDS_GPIO_DEFSTATE_OFF),
};
@@ -292,7 +306,7 @@ bcm47xx_leds_linksys_wrt310nv1[] __initconst = {
};
static const struct gpio_led
-bcm47xx_leds_linksys_wrt54gsv1[] __initconst = {
+bcm47xx_leds_linksys_wrt54g_generic[] __initconst = {
BCM47XX_GPIO_LED(0, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
BCM47XX_GPIO_LED(5, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
@@ -306,6 +320,24 @@ bcm47xx_leds_linksys_wrt54g3gv2[] __initconst = {
BCM47XX_GPIO_LED(3, "blue", "3g", 0, LEDS_GPIO_DEFSTATE_OFF),
};
+/* Verified on: WRT54GS V1.0 */
+static const struct gpio_led
+bcm47xx_leds_linksys_wrt54g_type_0101[] __initconst = {
+ BCM47XX_GPIO_LED(0, "green", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
+ BCM47XX_GPIO_LED(7, "green", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+/* Verified on: WRT54GL V1.1 */
+static const struct gpio_led
+bcm47xx_leds_linksys_wrt54g_type_0467[] __initconst = {
+ BCM47XX_GPIO_LED(0, "green", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
+ BCM47XX_GPIO_LED(2, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(3, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(7, "green", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
static const struct gpio_led
bcm47xx_leds_linksys_wrt610nv1[] __initconst = {
BCM47XX_GPIO_LED(0, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
@@ -325,11 +357,17 @@ bcm47xx_leds_linksys_wrt610nv2[] __initconst = {
static const struct gpio_led
bcm47xx_leds_linksys_wrtsl54gs[] __initconst = {
- BCM47XX_GPIO_LED(0, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
- BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
- BCM47XX_GPIO_LED(2, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
- BCM47XX_GPIO_LED(3, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
- BCM47XX_GPIO_LED(7, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(0, "green", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
+ BCM47XX_GPIO_LED(5, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(7, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+/* Microsoft */
+
+static const struct gpio_led
+bcm47xx_leds_microsoft_nm700[] __initconst = {
+ BCM47XX_GPIO_LED(6, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
};
/* Motorola */
@@ -377,6 +415,15 @@ bcm47xx_leds_netgear_wndr4500v1[] __initconst = {
};
static const struct gpio_led
+bcm47xx_leds_netgear_wnr3500lv1[] __initconst = {
+ BCM47XX_GPIO_LED(0, "blue", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(1, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(2, "green", "wan", 1, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(3, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
+ BCM47XX_GPIO_LED(7, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
bcm47xx_leds_netgear_wnr834bv2[] __initconst = {
BCM47XX_GPIO_LED(2, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
BCM47XX_GPIO_LED(3, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF),
@@ -417,6 +464,9 @@ void __init bcm47xx_leds_register(void)
case BCM47XX_BOARD_ASUS_RTN12:
bcm47xx_set_pdata(bcm47xx_leds_asus_rtn12);
break;
+ case BCM47XX_BOARD_ASUS_RTN15U:
+ bcm47xx_set_pdata(bcm47xx_leds_asus_rtn15u);
+ break;
case BCM47XX_BOARD_ASUS_RTN16:
bcm47xx_set_pdata(bcm47xx_leds_asus_rtn16);
break;
@@ -432,6 +482,9 @@ void __init bcm47xx_leds_register(void)
case BCM47XX_BOARD_ASUS_WL330GE:
bcm47xx_set_pdata(bcm47xx_leds_asus_wl330ge);
break;
+ case BCM47XX_BOARD_ASUS_WL500G:
+ bcm47xx_set_pdata(bcm47xx_leds_asus_wl500g);
+ break;
case BCM47XX_BOARD_ASUS_WL500GD:
bcm47xx_set_pdata(bcm47xx_leds_asus_wl500gd);
break;
@@ -538,12 +591,18 @@ void __init bcm47xx_leds_register(void)
case BCM47XX_BOARD_LINKSYS_WRT310NV1:
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt310nv1);
break;
- case BCM47XX_BOARD_LINKSYS_WRT54G:
- bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54gsv1);
- break;
case BCM47XX_BOARD_LINKSYS_WRT54G3GV2:
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g3gv2);
break;
+ case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101:
+ bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g_type_0101);
+ break;
+ case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467:
+ bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g_type_0467);
+ break;
+ case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708:
+ bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g_generic);
+ break;
case BCM47XX_BOARD_LINKSYS_WRT610NV1:
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt610nv1);
break;
@@ -554,6 +613,10 @@ void __init bcm47xx_leds_register(void)
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrtsl54gs);
break;
+ case BCM47XX_BOARD_MICROSOFT_MN700:
+ bcm47xx_set_pdata(bcm47xx_leds_microsoft_nm700);
+ break;
+
case BCM47XX_BOARD_MOTOROLA_WE800G:
bcm47xx_set_pdata(bcm47xx_leds_motorola_we800g);
break;
@@ -570,6 +633,9 @@ void __init bcm47xx_leds_register(void)
case BCM47XX_BOARD_NETGEAR_WNDR4500V1:
bcm47xx_set_pdata(bcm47xx_leds_netgear_wndr4500v1);
break;
+ case BCM47XX_BOARD_NETGEAR_WNR3500L:
+ bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr3500lv1);
+ break;
case BCM47XX_BOARD_NETGEAR_WNR834BV2:
bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr834bv2);
break;
diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c
index 1a03a2f43496..1b170bf5f7f0 100644
--- a/arch/mips/bcm47xx/prom.c
+++ b/arch/mips/bcm47xx/prom.c
@@ -51,6 +51,8 @@ __init void bcm47xx_set_system_type(u16 chip_id)
chip_id);
}
+static unsigned long lowmem __initdata;
+
static __init void prom_init_mem(void)
{
unsigned long mem;
@@ -87,6 +89,7 @@ static __init void prom_init_mem(void)
if (!memcmp(prom_init, prom_init + mem, 32))
break;
}
+ lowmem = mem;
/* Ignoring the last page when ddr size is 128M. Cached
* accesses to last page is causing the processor to prefetch
@@ -95,7 +98,6 @@ static __init void prom_init_mem(void)
*/
if (c->cputype == CPU_74K && (mem == (128 << 20)))
mem -= 0x1000;
-
add_memory_region(0, mem, BOOT_MEM_RAM);
}
@@ -114,3 +116,67 @@ void __init prom_init(void)
void __init prom_free_prom_memory(void)
{
}
+
+#if defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM)
+
+#define EXTVBASE 0xc0000000
+#define ENTRYLO(x) ((pte_val(pfn_pte((x) >> _PFN_SHIFT, PAGE_KERNEL_UNCACHED)) >> 6) | 1)
+
+#include <asm/tlbflush.h>
+
+/* Stripped version of tlb_init, with the call to build_tlb_refill_handler
+ * dropped. Calling it at this stage causes a hang.
+ */
+void __cpuinit early_tlb_init(void)
+{
+ write_c0_pagemask(PM_DEFAULT_MASK);
+ write_c0_wired(0);
+ temp_tlb_entry = current_cpu_data.tlbsize - 1;
+ local_flush_tlb_all();
+}
+
+void __init bcm47xx_prom_highmem_init(void)
+{
+ unsigned long off = (unsigned long)prom_init;
+ unsigned long extmem = 0;
+ bool highmem_region = false;
+
+ if (WARN_ON(bcm47xx_bus_type != BCM47XX_BUS_TYPE_BCMA))
+ return;
+
+ if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706)
+ highmem_region = true;
+
+ if (lowmem != 128 << 20 || !highmem_region)
+ return;
+
+ early_tlb_init();
+
+ /* Add one temporary TLB entry to map SDRAM Region 2.
+ * Physical Virtual
+ * 0x80000000 0xc0000000 (1st: 256MB)
+ * 0x90000000 0xd0000000 (2nd: 256MB)
+ */
+ add_temporary_entry(ENTRYLO(0x80000000),
+ ENTRYLO(0x80000000 + (256 << 20)),
+ EXTVBASE, PM_256M);
+
+ off = EXTVBASE + __pa(off);
+ for (extmem = 128 << 20; extmem < 512 << 20; extmem <<= 1) {
+ if (!memcmp(prom_init, (void *)(off + extmem), 16))
+ break;
+ }
+ extmem -= lowmem;
+
+ early_tlb_init();
+
+ if (!extmem)
+ return;
+
+ pr_warn("Found %lu MiB of extra memory, but highmem is unsupported yet!\n",
+ extmem >> 20);
+
+ /* TODO: Register extra memory */
+}
+
+#endif /* defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM) */
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index 63a4b0e915dc..2b63e7e7d3d3 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -59,12 +59,12 @@ static void bcm47xx_machine_restart(char *command)
switch (bcm47xx_bus_type) {
#ifdef CONFIG_BCM47XX_SSB
case BCM47XX_BUS_TYPE_SSB:
- ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1);
+ ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 3);
break;
#endif
#ifdef CONFIG_BCM47XX_BCMA
case BCM47XX_BUS_TYPE_BCMA:
- bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 1);
+ bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 3);
break;
#endif
}
@@ -218,6 +218,9 @@ void __init plat_mem_setup(void)
bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
bcm47xx_register_bcma();
bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id);
+#ifdef CONFIG_HIGHMEM
+ bcm47xx_prom_highmem_init();
+#endif
#endif
} else {
printk(KERN_INFO "bcm47xx: using ssb bus\n");
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,