* 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.
>
(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.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
@@ -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)
+#define E970_GPIO_WDT_PIN 7
+
+
+static struct {
+ struct timer_list timer;
+ unsigned long interval;
+ unsigned gpio;
+ int gstate;
+} bcm47xx_gpiowdt;
+
+
+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;
+
default:
bcm47xx_parts[3].offset = mtd->size -
roundup(NVRAM_SPACE,
mtd->erasesize);
bcm47xx_parts[3].size = roundup(NVRAM_SPACE,
mtd->erasesize);