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.bin
where 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

Attachment: huawei-e970-padding
Description: Binary data

_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to