Hi Mathias,

sorry for answering so late. I haven't seen this patch since 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.
> 
> (kernel patch below)
> 
> Signed-off-by: Mathias Adam <[email protected]>
> 
> ---
> 
> 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

> +     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?
> +#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 {.."
> +
> +
> +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.
>               default:
>                       bcm47xx_parts[3].offset = mtd->size - 
> roundup(NVRAM_SPACE, mtd->erasesize);
>                       bcm47xx_parts[3].size   = roundup(NVRAM_SPACE, 
> mtd->erasesize);

Hauke
_______________________________________________
openwrt-devel mailing list
[email protected]
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to