Hi Hauke, Am 25.04.2012 23:43, schrieb Hauke Mehrtens:
Hi Mathias,sorry for answering so late. I haven't seen this patch since now.
don't worry. Thanks for picking it up now.
On 12/17/2011 09:46 PM, Mathias Adam wrote: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. For reference, it has already been addressed in this open ticket: <https://dev.openwrt.org/ticket/2711> The device has a hardware watchdog which needs GPIO-7 to be toggled at least every 1-2 seconds. Therefore a timer is being setup early in the boot process in order to take care of this (see arch/mips/bcm47xx/time.c). 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> Issues: * lzma-loader crashes, so gzipped kernel is used. Presumably due to watchdog reset during kernel decompress. * b43 wireless driver crashes after loading firmware, use proprietary module (wl) instead. Perhaps due to watchdog, too.
In fact it's not only the driver crashing but the whole system doing an immediate reboot.
(kernel patch below) Signed-off-by: Mathias Adam<m.adam--open...@adamis.de> --- Index: target/linux/brcm47xx/image/Makefile =================================================================== --- target/linux/brcm47xx/image/Makefile (Revision 29557) +++ target/linux/brcm47xx/image/Makefile (Arbeitskopie) @@ -13,6 +13,7 @@ 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)" \ @@ -51,6 +52,11 @@ $(STAGING_DIR_HOST)/bin/trx2edips $(BIN_DIR)/$(IMG_PREFIX)-$(1).trx $(BIN_DIR)/openwrt-$(2)-$(3).bin endef +define Image/Build/Huawei + cp ./huawei-e970-padding $(BIN_DIR)/openwrt-$(2)-$(3)-gz.binwhere is huawei-e970-padding ? cp: cannot stat `./huawei-e970-padding': No such file or directory
my mistake. As it's binary it wasn't included in the patch. I attach it to this mail. The patch expects it to be in: target/linux/brcm47xx/image/
+ 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 @@ -107,9 +113,13 @@ $(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),wnr834b_v2,U12H081T00_NETGEAR,2,$(patsubst jffs2-%,jffs2,$(1))) # $(call Image/Build/Chk,$(1),wndr3400_v1,U12H155T00_NETGEAR,2,$(patsubst jffs2-%,jffs2,$(1))) # $(call Image/Build/Chk,$(1),wgr614_v8,U12H072T00_NETGEAR,2,$(patsubst jffs2-%,jffs2,$(1))) Index: package/broadcom-diag/src/diag.c =================================================================== --- package/broadcom-diag/src/diag.c (Revision 29557) +++ package/broadcom-diag/src/diag.c (Arbeitskopie) @@ -142,6 +142,9 @@ /* Edimax */ PS1208MFG, + + /* Huawei */ + HUAWEI_E970, }; static void __init bcm4780_init(void) { @@ -921,6 +924,16 @@ { .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) @@ -1155,6 +1168,9 @@ !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; } --- following patch has to be applied to kernel (3.0): diff -Nur a/arch/mips/bcm47xx/time.c b/arch/mips/bcm47xx/time.c --- a/arch/mips/bcm47xx/time.c 2011-11-29 16:51:22.000000000 +0100 +++ b/arch/mips/bcm47xx/time.c 2011-12-17 18:13:32.000000000 +0100 @@ -25,9 +25,75 @@ #include<linux/init.h> #include<linux/ssb/ssb.h> +#include<linux/gpio.h> #include<asm/time.h> +#include<asm/mach-bcm47xx/nvram.h> #include<bcm47xx.h> +#define ROUTER_HUAWEI_E970 1 + +#define E970_GPIO_WDT_INTERVAL (HZ / 5)isn't that a little bit often? if you say it has to trigger this GPIO every 2 second when not run the timer every second or every 0.5 seconds?
yes, 1 second or even more should be okay. I increased the frequency when I found that the b43 driver seems to trigger the watchdog (see above). However, as it didn't help there anyway, I'll try to increase the interval.
+#define E970_GPIO_WDT_PIN 7 + + +static struct { + struct timer_list timer; + unsigned long interval; + unsigned gpio; + int gstate; +} bcm47xx_gpiowdt;Please do not use an anonymous struct and use "struct bcm47xx_gpiowdt {.."
ok.
+ + +static void bcm47xx_gpiowdt_timer_tick(unsigned long unused) +{ + bcm47xx_gpiowdt.gstate = !bcm47xx_gpiowdt.gstate; + gpio_set_value(bcm47xx_gpiowdt.gpio, bcm47xx_gpiowdt.gstate); + + mod_timer(&bcm47xx_gpiowdt.timer, jiffies + bcm47xx_gpiowdt.interval); +} + +static void bcm47xx_gpiowdt_setup(unsigned long interval, unsigned gpio) +{ + int ret; + + bcm47xx_gpiowdt.interval = interval; + bcm47xx_gpiowdt.gpio = gpio; + bcm47xx_gpiowdt.gstate = 1; + + ret = gpio_request(bcm47xx_gpiowdt.gpio, "bcm47xx-gpio-wdt"); + if (ret< 0) { + printk(KERN_INFO "bcm47xx: failed to request gpio\n"); + return; + } + ret = gpio_direction_output(bcm47xx_gpiowdt.gpio, bcm47xx_gpiowdt.gstate); + if (ret< 0) { + printk(KERN_INFO "bcm47xx: failed to set gpio as output\n"); + return; + } + + setup_timer(&bcm47xx_gpiowdt.timer, bcm47xx_gpiowdt_timer_tick, 0L); + bcm47xx_gpiowdt_timer_tick(0); +} + +static int get_router(void) +{ + char buf[20]; + u32 boardnum = 0; + u16 boardtype = 0; + + if (nvram_getenv("boardnum", buf, sizeof(buf))>= 0) + boardnum = simple_strtoul(buf, NULL, 0); + if (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; +} + void __init plat_time_init(void) { unsigned long hz = 0; @@ -57,4 +123,11 @@ /* Set MIPS counter frequency for fixed_rate_gettimeoffset() */ mips_hpt_frequency = hz; + + /* device-specific initializations */ + switch (get_router()) { + case ROUTER_HUAWEI_E970: + printk(KERN_INFO "bcm47xx: detected Huawei E970, starting gpio watchdog pet timer\n"); + bcm47xx_gpiowdt_setup(E970_GPIO_WDT_INTERVAL, E970_GPIO_WDT_PIN); + } } diff -Nur a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c --- a/drivers/mtd/bcm47xxpart.c 2011-11-29 16:51:24.000000000 +0100 +++ b/drivers/mtd/bcm47xxpart.c 2011-12-14 01:30:36.000000000 +0100 @@ -84,6 +84,7 @@ #define ROUTER_NETGEAR_WNR3500L 4 #define ROUTER_SIMPLETECH_SIMPLESHARE 5 #define ROUTER_NETGEAR_WNDR3400 6 +#define ROUTER_HUAWEI_E970 7 static struct mtd_partition bcm47xx_parts[] = { { name: "cfe", offset:0, size:0, mask_flags:MTD_WRITEABLE, }, @@ -414,6 +415,11 @@ return ROUTER_SIMPLETECH_SIMPLESHARE; } + if (boardnum == 0x5347&& boardtype == 0x048e) { + /* Huawei E970 */ + return ROUTER_HUAWEI_E970; + } + return 0; } @@ -476,6 +482,19 @@ bcm47xx_parts[4].size = roundup(NVRAM_SPACE, mtd->erasesize); break; + case ROUTER_HUAWEI_E970: + pr_notice("Setting up Huawei E970 factory nvram partition\n"); + custom_data_size = mtd->erasesize; + + bcm47xx_parts[3].offset = mtd->size - roundup(NVRAM_SPACE, mtd->erasesize); + bcm47xx_parts[3].size = roundup(NVRAM_SPACE, mtd->erasesize); + + /* Place factory nvram into a partition */ + bcm47xx_parts[4].name = "factory"; + bcm47xx_parts[4].offset = bcm47xx_parts[3].offset - custom_data_size; + bcm47xx_parts[4].size = custom_data_size; + break; +Why don't you take the case for the Netager devices? It uses the same code, except that the partition is named different, but OpenWrt ignores that partition anyway.
Sure, should be ok to use the Netgear case.I don't remember why I doubled the code there, perhaps I just copied and modified the simpletech case and didn't notice that Netgear's essentially the same :-)
default: bcm47xx_parts[3].offset = mtd->size - roundup(NVRAM_SPACE, mtd->erasesize); bcm47xx_parts[3].size = roundup(NVRAM_SPACE, mtd->erasesize);Hauke
I'll prepare a modified patch (and rebase it to current trunk). Could take a couple of days though.
Regards, Mathias
huawei-e970-padding
Description: Binary data
_______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel