This patch adds support for Huawei E970 wireless gateway devices. It has been tested on an E970 labelled as T-Mobile web'n'walk Box IV. E960/B970 should work too, from what I know it's basically the same hardware.
The device has a Broadcom BCM5354 SoC and a built-in 3G USB modem. It uses a hardware watchdog which needs GPIO-7 to be toggled at least every 1-2 seconds. This patch uses gpio_wdt module (see my previous patch today) to take care of this. Tested and works: 3G wan, wlan+LED, VLAN config, failsafe using reset button, image to be used for upgrade from OEM firmware's web interface Link to the wiki page I've created: <http://wiki.openwrt.org/toh/huawei/e970> Issue: * lzma-loader crashes, so gzipped kernel is used. Presumably due to watchdog reset during kernel decompress. Signed-off-by: Mathias Adam <m.adam--open...@adamis.de> --- diff --git a/package/broadcom-diag/src/diag.c b/package/broadcom-diag/src/diag.c index 997fbe8..362cb73 100644 --- a/package/broadcom-diag/src/diag.c +++ b/package/broadcom-diag/src/diag.c @@ -150,6 +150,9 @@ enum { /* Edimax */ PS1208MFG, + + /* Huawei */ + HUAWEI_E970, }; static void __init bcm4780_init(void) { @@ -1036,6 +1039,16 @@ static struct platform_t __initdata platforms[] = { { .name = "wlan", .gpio = 1 << 0, .polarity = NORMAL }, }, }, + /* Huawei */ + [HUAWEI_E970] = { + .name = "Huawei E970", + .buttons = { + { .name = "reset", .gpio = 1 << 6 }, + }, + .leds = { + { .name = "wlan", .gpio = 1 << 0, .polarity = NORMAL }, + }, + }, }; static struct platform_t __init *platform_detect(void) @@ -1306,6 +1319,9 @@ static struct platform_t __init *platform_detect(void) !strcmp(getvar("status_gpio"), "1")) /* gpio based detection */ return &platforms[PS1208MFG]; + if (!strcmp(boardnum, "0x5347") && !strcmp(boardtype, "0x048e")) /* Huawei E970 */ + return &platforms[HUAWEI_E970]; + /* not found */ return NULL; } diff --git a/target/linux/brcm47xx/config-3.6 b/target/linux/brcm47xx/config-3.6 index 7f1ea7d..93fdeb9 100644 --- a/target/linux/brcm47xx/config-3.6 +++ b/target/linux/brcm47xx/config-3.6 @@ -143,3 +143,4 @@ CONFIG_USB_ARCH_HAS_XHCI=y CONFIG_USB_SUPPORT=y CONFIG_WATCHDOG_CORE=y CONFIG_ZONE_DMA_FLAG=0 +CONFIG_GPIO_WDT=y diff --git a/target/linux/brcm47xx/image/Makefile b/target/linux/brcm47xx/image/Makefile index f45fb56..9a716f4 100644 --- a/target/linux/brcm47xx/image/Makefile +++ b/target/linux/brcm47xx/image/Makefile @@ -13,6 +13,7 @@ endef define Image/Prepare cat $(KDIR)/vmlinux | $(STAGING_DIR_HOST)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $(KDIR)/vmlinux.lzma + gzip -nc9 $(KDIR)/vmlinux > $(KDIR)/vmlinux.gz rm -f $(KDIR)/loader.gz $(MAKE) -C lzma-loader \ BUILD_DIR="$(KDIR)" \ @@ -56,6 +57,12 @@ define Image/Build/Edi $(STAGING_DIR_HOST)/bin/trx2edips $(BIN_DIR)/$(IMG_PREFIX)-$(1).trx $(BIN_DIR)/openwrt-$(2)-$(3).bin endef +define Image/Build/Huawei + dd if=/dev/zero of=$(BIN_DIR)/openwrt-$(2)-$(3)-gz.bin bs=92 count=1 + echo -ne 'HDR0\x08\x00\x00\x00' >> $(BIN_DIR)/openwrt-$(2)-$(3)-gz.bin + cat $(BIN_DIR)/$(IMG_PREFIX)-$(1)-gz.trx >> $(BIN_DIR)/openwrt-$(2)-$(3)-gz.bin +endef + define trxalign/jffs2-128k -a 0x20000 -f $(KDIR)/root.$(1) endef @@ -117,9 +124,13 @@ define Image/Build $(STAGING_DIR_HOST)/bin/trx -o $(BIN_DIR)/$(IMG_PREFIX)-$(1).trx \ -f $(KDIR)/loader.gz -f $(KDIR)/vmlinux.lzma \ $(call trxalign/$(1),$(1)) + $(STAGING_DIR_HOST)/bin/trx -o $(BIN_DIR)/$(IMG_PREFIX)-$(1)-gz.trx \ + -f $(KDIR)/vmlinux.gz \ + $(call trxalign/$(1),$(1)) $(call Image/Build/$(1),$(1)) $(call Image/Build/Motorola,$(1),wr850g,1,$(1)) $(call Image/Build/USR,$(1),usr5461,$(1)) + $(call Image/Build/Huawei,$(1),e970,$(1)) # $(call Image/Build/Chk,$(1),wgr614_v8,U12H072T00_NETGEAR,2,$(patsubst jffs2-%,jffs2,$(1))) # $(call Image/Build/Chk,$(1),wgr614_v9,U12H094T00_NETGEAR,2,$(patsubst jffs2-%,jffs2,$(1))) # $(call Image/Build/Chk,$(1),wndr3300,U12H093T00_NETGEAR,2,$(patsubst jffs2-%,jffs2,$(1))) diff --git a/target/linux/brcm47xx/patches-3.6/830-huawei_e970_support.patch b/target/linux/brcm47xx/patches-3.6/830-huawei_e970_support.patch new file mode 100644 index 0000000..c6c14d1 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.6/830-huawei_e970_support.patch @@ -0,0 +1,174 @@ +--- a/arch/mips/bcm47xx/setup.c ++++ b/arch/mips/bcm47xx/setup.c +@@ -33,6 +33,7 @@ + #include <linux/bcma/bcma_soc.h> + #include <linux/serial.h> + #include <linux/serial_8250.h> ++#include <linux/gpio_wdt.h> + #include <asm/bootinfo.h> + #include <asm/reboot.h> + #include <asm/time.h> +@@ -45,6 +46,29 @@ EXPORT_SYMBOL(bcm47xx_bus); + enum bcm47xx_bus_type bcm47xx_bus_type; + EXPORT_SYMBOL(bcm47xx_bus_type); + ++ ++#define ROUTER_HUAWEI_E970 1 ++ ++static int get_router(void) ++{ ++ char buf[20]; ++ u32 boardnum = 0; ++ u16 boardtype = 0; ++ ++ if (bcm47xx_nvram_getenv("boardnum", buf, sizeof(buf)) >= 0) ++ boardnum = simple_strtoul(buf, NULL, 0); ++ if (bcm47xx_nvram_getenv("boardtype", buf, sizeof(buf)) >= 0) ++ boardtype = simple_strtoul(buf, NULL, 0); ++ ++ if (boardnum == 0x5347 && boardtype == 0x048e) { ++ /* Huawei E970 */ ++ return ROUTER_HUAWEI_E970; ++ } ++ ++ return 0; ++} ++ ++ + static void bcm47xx_machine_restart(char *command) + { + printk(KERN_ALERT "Please stand by while rebooting the system...\n"); +@@ -254,8 +278,24 @@ void __init plat_mem_setup(void) + pm_power_off = bcm47xx_machine_halt; + } + ++static struct gpio_wdt_platform_data gpio_wdt_data = { ++ .gpio = 7, ++ .interval = HZ, ++ .first_interval = HZ/5, ++}; ++ ++static struct platform_device gpio_wdt_device = { ++ .name = "gpio-wdt", ++ .id = 0, ++ .dev = { ++ .platform_data = &gpio_wdt_data, ++ }, ++}; ++ + static int __init bcm47xx_register_bus_complete(void) + { ++ int err = 0; ++ + switch (bcm47xx_bus_type) { + #ifdef CONFIG_BCM47XX_SSB + case BCM47XX_BUS_TYPE_SSB: +@@ -268,6 +308,14 @@ static int __init bcm47xx_register_bus_c + break; + #endif + } +- return 0; ++ ++ /* device-specific initializations */ ++ switch (get_router()) { ++ case ROUTER_HUAWEI_E970: ++ printk(KERN_INFO "bcm47xx: detected Huawei E970 or similar, starting early gpio_wdt timer\n"); ++ err = platform_device_register(&gpio_wdt_device); ++ } ++ ++ return err; + } + device_initcall(bcm47xx_register_bus_complete); +--- a/arch/mips/configs/bcm47xx_defconfig ++++ b/arch/mips/configs/bcm47xx_defconfig +@@ -380,6 +380,7 @@ CONFIG_THERMAL=y + CONFIG_WATCHDOG=y + CONFIG_WATCHDOG_NOWAYOUT=y + CONFIG_BCM47XX_WDT=y ++CONFIG_GPIO_WDT=y + CONFIG_SSB_DRIVER_GIGE=y + CONFIG_DISPLAY_SUPPORT=m + CONFIG_SOUND=m +--- a/drivers/watchdog/bcm47xx_wdt.c ++++ b/drivers/watchdog/bcm47xx_wdt.c +@@ -26,6 +26,7 @@ + #include <linux/watchdog.h> + #include <linux/timer.h> + #include <linux/jiffies.h> ++#include <bcm47xx_nvram.h> + + #define DRV_NAME "bcm47xx_wdt" + +@@ -45,6 +46,29 @@ MODULE_PARM_DESC(nowayout, + "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + ++ ++#define ROUTER_HUAWEI_E970 1 ++ ++static int get_router(void) ++{ ++ char buf[20]; ++ u32 boardnum = 0; ++ u16 boardtype = 0; ++ ++ if (bcm47xx_nvram_getenv("boardnum", buf, sizeof(buf)) >= 0) ++ boardnum = simple_strtoul(buf, NULL, 0); ++ if (bcm47xx_nvram_getenv("boardtype", buf, sizeof(buf)) >= 0) ++ boardtype = simple_strtoul(buf, NULL, 0); ++ ++ if (boardnum == 0x5347 && boardtype == 0x048e) { ++ /* Huawei E970 */ ++ return ROUTER_HUAWEI_E970; ++ } ++ ++ return 0; ++} ++ ++ + static inline struct bcm47xx_wdt *bcm47xx_wdt_get(struct watchdog_device *wdd) + { + return container_of(wdd, struct bcm47xx_wdt, wdd); +@@ -187,6 +211,12 @@ static int __devinit bcm47xx_wdt_probe(s + if (!wdt) + return -ENXIO; + ++ switch (get_router()) { ++ case ROUTER_HUAWEI_E970: ++ dev_info(&pdev->dev, "detected Huawei E970 or similar, not enabling BCM47xx Watchdog Timer\n"); ++ return 0; ++ } ++ + soft = wdt->max_timer_ms < WDT_SOFTTIMER_THRESHOLD * 1000; + + if (soft) { +--- a/drivers/mtd/bcm47xxpart.c ++++ b/drivers/mtd/bcm47xxpart.c +@@ -84,6 +84,7 @@ struct trx_header { + #define ROUTER_NETGEAR_WNR3500L 4 + #define ROUTER_SIMPLETECH_SIMPLESHARE 5 + #define ROUTER_NETGEAR_WNDR3400 6 ++#define ROUTER_HUAWEI_E970 7 + + static int + find_cfe_size(struct mtd_info *mtd) +@@ -404,6 +405,11 @@ static int get_router(void) + return ROUTER_SIMPLETECH_SIMPLESHARE; + } + ++ if (boardnum == 0x5347 && boardtype == 0x048e) { ++ /* Huawei E970 */ ++ return ROUTER_HUAWEI_E970; ++ } ++ + return 0; + } + +@@ -445,6 +451,7 @@ static int parse_bcm47xx_partitions(stru + case ROUTER_NETGEAR_WNDR3300: + case ROUTER_NETGEAR_WNR3500L: + case ROUTER_NETGEAR_WNDR3400: ++ case ROUTER_HUAWEI_E970: + /* Netgear: checksum is @ 0x003AFFF8 for 4M flash or checksum + * is @ 0x007AFFF8 for 8M flash + */ _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel