From patchwork Mon Apr 27 07:27:43 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Caleb James DeLisle X-Patchwork-Id: 464863 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from arrakis.dune.hu (arrakis.dune.hu [78.24.191.176]) (using TLSv1.1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 948731402B6 for ; Mon, 27 Apr 2015 17:29:16 +1000 (AEST) Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id C308D283F5C; Mon, 27 Apr 2015 09:28:00 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on arrakis.dune.hu X-Spam-Level: X-Spam-Status: No, score=-1.5 required=5.0 tests=BAYES_00 autolearn=unavailable version=3.3.2 Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 0DE83280192 for ; Mon, 27 Apr 2015 09:27:51 +0200 (CEST) X-policyd-weight: using cached result; rate: -7.6 Received: from mail.caldana.org (mail.caldana.org [213.136.89.234]) by arrakis.dune.hu (Postfix) with ESMTP for ; Mon, 27 Apr 2015 09:27:50 +0200 (CEST) Received: from mail.caldana.org (localhost.localdomain [127.0.0.1]) by mail.caldana.org (Postfix) with ESMTP id 4F4373555461 for ; Mon, 27 Apr 2015 09:28:53 +0200 (CEST) X-Virus-Scanned: amavisd-new at caldana.org Received: from mail.caldana.org ([127.0.0.1]) by mail.caldana.org (paula.caldana.org [127.0.0.1]) (amavisd-new, port 10024) with LMTP id rC8I5nAzTh5Z for ; Mon, 27 Apr 2015 09:28:51 +0200 (CEST) Received: from [10.241.0.2] (240.92.211.130.bc.googleusercontent.com [130.211.92.240]) by mail.caldana.org (Postfix) with ESMTPSA id E133630FB803 for ; Mon, 27 Apr 2015 09:28:50 +0200 (CEST) Message-ID: <553DE4EF.8070505@cjdns.fr> Date: Mon, 27 Apr 2015 09:27:43 +0200 From: Caleb James DeLisle User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 To: OpenWrt Development List Subject: [OpenWrt-Devel] [PATCH] [RESUBMIT] Support Linksys WAP-4410N X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openwrt-devel-bounces@lists.openwrt.org Sender: "openwrt-devel" I noticed the patch was not applying to the recent master so I reworked it to add a new patch to the patchset against the kernel rather than patching the patch which was ugly (and proved to be brittle). This patch has a checkpatch.pl issue but it's trailing whitespace in the patch which it adds and it's not from me. As stated before, there's no way to locate the new larger kernel where the old one was so upgrading from factory firmware without uart is basically a non-starter but sysupgrade works (*worked, I will write a confirmation email as soon as I have double-checked the rework of the patch but nothing functional was changed.) Finally I didn't send this as a reply because I'm new to mailing patches and paranoid about breaking an inline patch. Thanks, Caleb Signed-off-by: Caleb James DeLisle diff --git a/target/linux/ar71xx/base-files/etc/diag.sh b/target/linux/ar71xx/base-files/etc/diag.sh index d702d45..f268fe4 100644 --- a/target/linux/ar71xx/base-files/etc/diag.sh +++ b/target/linux/ar71xx/base-files/etc/diag.sh @@ -305,6 +305,9 @@ get_status_led() { wrt400n) status_led="wrt400n:blue:wps" ;; + wap4410n) + status_led="wrt4410n:green:power" + ;; wrt160nl) status_led="wrt160nl:blue:wps" ;; diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/02_network b/target/linux/ar71xx/base-files/etc/uci-defaults/02_network index f5c6865..7f163d6 100644 --- a/target/linux/ar71xx/base-files/etc/uci-defaults/02_network +++ b/target/linux/ar71xx/base-files/etc/uci-defaults/02_network @@ -338,6 +338,7 @@ tl-wa901nd-v3 |\ tl-wr703n |\ tube2h |\ wndap360 |\ +wap4410n |\ mynet-rext |\ wp543) ucidef_set_interface_lan "eth0" diff --git a/target/linux/ar71xx/base-files/lib/ar71xx.sh b/target/linux/ar71xx/base-files/lib/ar71xx.sh index 645c5d9..a64a3bd 100755 --- a/target/linux/ar71xx/base-files/lib/ar71xx.sh +++ b/target/linux/ar71xx/base-files/lib/ar71xx.sh @@ -849,6 +849,9 @@ ar71xx_board_detect() { *WRT400N) name="wrt400n" ;; + *WAP4410N) + name="wap4410n" + ;; *"WZR-450HP2") name="wzr-450hp2" ;; diff --git a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh index a8cec91..33d3a58 100755 --- a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh +++ b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh @@ -228,6 +228,7 @@ platform_check_image() { rocket-m-xw | \ nanostation-m-xw | \ rw2458n | \ + wap4410n | \ wndap360 | \ wzr-hp-g300nh2 | \ wzr-hp-g300nh | \ diff --git a/target/linux/ar71xx/config-3.18 b/target/linux/ar71xx/config-3.18 index 36b8bb6..87b8162 100644 --- a/target/linux/ar71xx/config-3.18 +++ b/target/linux/ar71xx/config-3.18 @@ -140,6 +140,7 @@ CONFIG_ATH79_MACH_WPJ344=y CONFIG_ATH79_MACH_WPJ558=y CONFIG_ATH79_MACH_WRT160NL=y CONFIG_ATH79_MACH_WRT400N=y +CONFIG_ATH79_MACH_WAP4410N=y CONFIG_ATH79_MACH_WZR_450HP2=y CONFIG_ATH79_MACH_WZR_HP_AG300H=y CONFIG_ATH79_MACH_WZR_HP_G300NH=y diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wap4410n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wap4410n.c new file mode 100644 index 0000000..15bd12b --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wap4410n.c @@ -0,0 +1,279 @@ +/* + * Cisco WAP4410N board support + * + * Copyright (C) 2014 Caleb James DeLisle + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation, or (at your option) any later version. + */ +#include +#include +#include +#include +#include + +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-usb.h" +#include "dev-wmac.h" +#include "machtypes.h" + +/* -------------- begin flash device -------------- */ + +#define FLASH_BASE 0xbf000000 + +/* where the actual art data is within the art partition. */ +#define ART_DATA_OFFSET 0x1000 + +/* If changed, make sure to change image/Makefile too! */ +#define KERN_SIZE 0x190000 + +/* Flash layout: u-boot/include/upgrade.h in cisco's GPL dump */ +#define FLASH_SIZE (0x800000) +#define BOOT_SIZE (0x40000) +#define NVRAM_SIZE (0x10000) +#define ART_SIZE (0x10000) +#define ENV_SIZE (0x10000) + +#define NODE_INFO_OFFSET (BOOT_SIZE - 0x90) +struct wap4410n_node_info { + /** Serial number written on back of device. */ + char serial_no[16]; + + /** Internal to Sercomm (?), France = { domain: 0x80, country: 0x00 } */ + uint8_t domain; + uint8_t country; + + /** written on the board, eg: 13 */ + uint8_t hw_ver; + + uint8_t zero0[5]; + + /** ASCII numeric digits */ + char wps_pin[8]; + + uint8_t zero1[16]; + + uint8_t mac_addr[6]; + + uint8_t zero2[3]; + + /** 31734572436f4d6d -> "1sErCoMm" does not seem to be checked. */ + char magic_1sErCoMm[8]; + + /** 00010000 (offset 0x41, completely unaligned) */ + uint8_t unknown0[4]; + + /** Used by upslug2 protocol */ + uint8_t hardware_id[32]; + + /** 0000240800008000000000030000200400000008 */ + uint8_t unknown1[20]; + + /** 734572436f4d6d -> "sErCoMm" */ + uint8_t magic_sErCoMm[7]; + + uint8_t zero3[16]; +}; + +#define UPGRADE_INFO_OFFSET 0x7dfff0 +struct wap4410n_upgrade_info { + /** Stock WAP4410: 2408 */ + uint16_t product_id; + + /** Always 8000 */ + uint16_t protocol; + + /** 2007 -> v2.0.7.x */ + uint16_t fw_version; + + /** 90f7 same value as NSLU2 */ + uint16_t unknown0; + + /** bootloader checks this and will "soft brick" if it's not correct. */ + uint8_t eRcOmM[6]; + + uint8_t pad[2]; +}; + +/* + * An instruction in the bootloader which checks that 0x7dfff8 == "eRcOmM" and + * bricks if it's not. + * If this instruction is overwritten with a zero, you get 64k of extra space. + * 2406 0006 1440 000a 8fbc 0020 <-- unpatched + * 2406 0006 0000 0000 8fbc 0020 <-- patched + */ +#define SERCOMM_CHECK_LAST_INSN 0x24060006 +#define SERCOMM_CHECK_INSN_OFFSET 0x19e08 +#define SERCOMM_CHECK_NEXT_INSN 0x8fbc0020 + + +/* Little bit of arithmatic on the flash layout. */ +#define NVRAM_OFFSET BOOT_SIZE +#define KERN_OFFSET (NVRAM_OFFSET + NVRAM_SIZE) +#define ROOT_OFFSET (KERN_OFFSET + KERN_SIZE) +#define ART_OFFSET (FLASH_SIZE - ART_SIZE) +#define ENV_OFFSET (ART_OFFSET - ENV_SIZE) +/* rootfs is whatever is left. */ +#define ROOT_SIZE (ENV_OFFSET - ROOT_OFFSET) + +#define PART(b, s, n, f) { .name = n, .offset = b, .size = s, .mask_flags = f } +static struct mtd_partition wap4410n_flash_partitions[] = { + PART(0x00000000, BOOT_SIZE, "u-boot", MTD_WRITEABLE), + PART(NVRAM_OFFSET, NVRAM_SIZE, "u-boot-env", MTD_WRITEABLE), + PART(KERN_OFFSET, KERN_SIZE, "kernel", 0), + PART(ROOT_OFFSET, ROOT_SIZE, "rootfs", 0), + PART(ENV_OFFSET, ENV_SIZE, "sercomm", MTD_WRITEABLE), + PART(ART_OFFSET, ART_SIZE, "art", MTD_WRITEABLE), + + /* Pseudo-partition over whole upgradable space, used by sysupgrade. */ + PART(KERN_OFFSET, KERN_SIZE + ROOT_SIZE, "firmware", 0) +}; +#undef PART + +static struct physmap_flash_data wap4410n_flash_data = { + .width = 2, + .parts = wap4410n_flash_partitions, + .nr_parts = ARRAY_SIZE(wap4410n_flash_partitions), +}; + +static struct resource wap4410n_flash_resources[] = { + [0] = { + .start = FLASH_BASE, + .end = FLASH_BASE + FLASH_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device wap4410n_flash_device = { + .name = "physmap-flash", + .id = -1, + .resource = wap4410n_flash_resources, + .num_resources = ARRAY_SIZE(wap4410n_flash_resources), + .dev = { .platform_data = &wap4410n_flash_data } +}; + + +static void __init wap4410n_flash_reg(void) +{ + uint32_t *insn = (uint32_t *) (FLASH_BASE + SERCOMM_CHECK_INSN_OFFSET); + int i; + if (SERCOMM_CHECK_LAST_INSN != insn[-1] || + SERCOMM_CHECK_NEXT_INSN != insn[1]) { + printk(KERN_INFO "Unrecognized bootloader, costs 64k storage"); + } else if (insn[0]) { + printk(KERN_INFO "eRcOmM check at %p in uboot, costs 64k storage", + (void *)insn); + } else { + printk(KERN_INFO "eRcOmM check at %p patched, gain 64k storage", + (void *)insn); + wap4410n_flash_partitions[3].size += + wap4410n_flash_partitions[4].size; + wap4410n_flash_data.nr_parts--; + for (i = 4; i < wap4410n_flash_data.nr_parts; i++) { + memcpy(&wap4410n_flash_partitions[i], + &wap4410n_flash_partitions[i + 1], + sizeof(struct mtd_partition)); + } + } + platform_device_register(&wap4410n_flash_device); +} + +/* -------------- end flash device -------------- */ + + +/* -------------------- GPIO -------------------- */ + +#define LED_WIRELESS 0 +#define LED_POWER 1 +#define KEYS_POLL_INTERVAL 20 /* msecs */ +#define KEYS_DEBOUNE_INTERVAL (3 * KEYS_POLL_INTERVAL) + +/* 2 lights are gpio, other 2 are hardwired. */ +static struct gpio_led wap4410n_leds_gpio[] __initdata = { + { + .name = "wrt4410n:green:power", + .gpio = LED_POWER, + .active_low = 1, + }, + { + .name = "wrt4410n:green:wireless", + .gpio = LED_WIRELESS, + .active_low = 1, + }, +}; + +static struct gpio_keys_button wap4410n_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = KEYS_DEBOUNE_INTERVAL, + .gpio = 21, + .active_low = 1, + } +}; + +static void __init wap4410n_gpio_reg(void) +{ + ath79_register_gpio_keys_polled( + -1, + KEYS_POLL_INTERVAL, + ARRAY_SIZE(wap4410n_gpio_keys), + wap4410n_gpio_keys + ); + ath79_register_leds_gpio( + -1, + ARRAY_SIZE(wap4410n_leds_gpio), + wap4410n_leds_gpio + ); +} + +/* -------------------- end GPIO -------------------- */ + +/** Never called, just for build time verification. */ +static void wap4410n_build_verify(void) +{ + BUILD_BUG_ON((KERN_SIZE / 0x10000 * 0x10000) != KERN_SIZE); + BUILD_BUG_ON(sizeof(struct wap4410n_upgrade_info) != 16); + BUILD_BUG_ON(sizeof(struct wap4410n_node_info) != 0x90); +} + +static void __init wap4410n_setup(void) +{ + struct wap4410n_node_info *ni = (struct wap4410n_node_info *) + (FLASH_BASE + NODE_INFO_OFFSET); + uint8_t *art = (uint8_t *) + (FLASH_BASE + FLASH_SIZE - ART_SIZE + ART_DATA_OFFSET); + + ath79_init_mac(ath79_eth0_data.mac_addr, ni->mac_addr, 0); + + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + /* TODO: SPEED_1000 causes a silent failure, testing needed. */ + ath79_eth0_data.speed = SPEED_100; + ath79_eth0_data.duplex = DUPLEX_FULL; + ath79_register_eth(0); + + ath79_register_usb(); + + wap4410n_flash_reg(); + + ath79_register_wmac(art, ni->mac_addr); + + wap4410n_gpio_reg(); + + /* silence compiler warning */ + if (0) + wap4410n_build_verify(); +} + +MIPS_MACHINE( + ATH79_MACH_WAP4410N, + "WAP4410N", + "Linksys WAP4410N", + wap4410n_setup +); diff --git a/target/linux/ar71xx/generic/profiles/linksys.mk b/target/linux/ar71xx/generic/profiles/linksys.mk index bedf3a3..0a7a897 100644 --- a/target/linux/ar71xx/generic/profiles/linksys.mk +++ b/target/linux/ar71xx/generic/profiles/linksys.mk @@ -23,5 +23,15 @@ define Profile/WRT400N/Description Package set optimized for the Linksys WRT400N. endef +define Profile/WAP4410N + NAME:=Linksys WAP4410N + PACKAGES:= +endef + +define Profile/WAP4410N/Description + Package set optimized for the Linksys WAP4410N. +endef + $(eval $(call Profile,WRT160NL)) $(eval $(call Profile,WRT400N)) +$(eval $(call Profile,WAP4410N)) diff --git a/target/linux/ar71xx/image/Makefile b/target/linux/ar71xx/image/Makefile index e4f6c71..cc81a0a 100644 --- a/target/linux/ar71xx/image/Makefile +++ b/target/linux/ar71xx/image/Makefile @@ -538,6 +538,8 @@ define Image/Build/WRT400N fi endef +Image/Build/WAP4410N/buildkernel=$(call MkuImageGzip,$(2),$(3)) +Image/Build/WAP4410N=$(call Sysupgrade/KRuImage,$(1),$(2),1638400,6356992) define Image/Build/CameoAP94/buildkernel $(call MkuImageLzma,$(2),$(3) $(4)) @@ -1551,6 +1553,7 @@ $(eval $(call SingleProfile,WHRHPG300N,64kraw,WHRHPGN,whr-hp-gn,WHR-HP-GN,ttyS0, $(eval $(call SingleProfile,WHRHPG300N,64kraw,WLAEAG300N,wlae-ag300n,WLAE-AG300N,ttyS0,115200,$$(whrhpg300n_mtdlayout),WLAE-AG300N)) $(eval $(call SingleProfile,WRT400N,64k,WRT400N,wrt400n,WRT400N,ttyS0,115200)) +$(eval $(call SingleProfile,WAP4410N,64k,WAP4410N,wap4410n,WAP4410N,ttyS0,115200)) $(eval $(call SingleProfile,WZRHP128K,128kraw,WZRHPG300NH,wzr-hp-g300nh,WZR-HP-G300NH,ttyS0,115200,WZR-HP-G300NH)) $(eval $(call SingleProfile,WZRHP64K,64kraw,WZRHPG300NH2,wzr-hp-g300nh2,WZR-HP-G300NH2,ttyS0,115200,WZR-HP-G300NH2)) diff --git a/target/linux/ar71xx/patches-3.18/904-MIPS-ath79-linksys-wap4410n-support.patch b/target/linux/ar71xx/patches-3.18/904-MIPS-ath79-linksys-wap4410n-support.patch new file mode 100644 index 0000000..a6fd82f --- /dev/null +++ b/target/linux/ar71xx/patches-3.18/904-MIPS-ath79-linksys-wap4410n-support.patch @@ -0,0 +1,38 @@ +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -523,6 +523,15 @@ config ATH79_MACH_WRT400N + select ATH79_DEV_LEDS_GPIO + select ATH79_DEV_M25P80 + ++config ATH79_MACH_WAP4410N ++ bool "Linksys WAP4410N board support" ++ select SOC_AR913X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_USB ++ select ATH79_DEV_WMAC ++ + config ATH79_MACH_R6100 + bool "NETGEAR R6100 board support" + select SOC_AR934X +--- a/arch/mips/ath79/Makefile ++++ b/arch/mips/ath79/Makefile +@@ -149,6 +149,7 @@ obj-$(CONFIG_ATH79_MACH_WPJ344) += mach- + obj-$(CONFIG_ATH79_MACH_WPJ558) += mach-wpj558.o + obj-$(CONFIG_ATH79_MACH_WRT160NL) += mach-wrt160nl.o + obj-$(CONFIG_ATH79_MACH_WRT400N) += mach-wrt400n.o ++obj-$(CONFIG_ATH79_MACH_WAP4410N) += mach-wap4410n.o + obj-$(CONFIG_ATH79_MACH_WZR_HP_G300NH) += mach-wzr-hp-g300nh.o + obj-$(CONFIG_ATH79_MACH_WZR_HP_G300NH2) += mach-wzr-hp-g300nh2.o + obj-$(CONFIG_ATH79_MACH_WZR_HP_AG300H) += mach-wzr-hp-ag300h.o +--- a/arch/mips/ath79/machtypes.h ++++ b/arch/mips/ath79/machtypes.h +@@ -198,6 +198,7 @@ enum ath79_mach_type { + ATH79_MACH_WPJ558, /* Compex WPJ558 */ + ATH79_MACH_WRT160NL, /* Linksys WRT160NL */ + ATH79_MACH_WRT400N, /* Linksys WRT400N */ ++ ATH79_MACH_WAP4410N, /* Linksys WAP4410N */ + ATH79_MACH_WZR_HP_AG300H, /* Buffalo WZR-HP-AG300H */ + ATH79_MACH_WZR_HP_G300NH, /* Buffalo WZR-HP-G300NH */ + ATH79_MACH_WZR_HP_G300NH2, /* Buffalo WZR-HP-G300NH2 */