aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--target/linux/ar71xx/base-files/etc/diag.sh3
-rwxr-xr-xtarget/linux/ar71xx/base-files/etc/uci-defaults/02_network1
-rwxr-xr-xtarget/linux/ar71xx/base-files/lib/ar71xx.sh3
-rwxr-xr-xtarget/linux/ar71xx/base-files/lib/upgrade/platform.sh1
-rw-r--r--target/linux/ar71xx/config-3.181
-rw-r--r--target/linux/ar71xx/files/arch/mips/ath79/mach-wap4410n.c285
-rw-r--r--target/linux/ar71xx/generic/profiles/linksys.mk10
-rw-r--r--target/linux/ar71xx/image/Makefile3
8 files changed, 307 insertions, 0 deletions
diff --git a/target/linux/ar71xx/base-files/etc/diag.sh b/target/linux/ar71xx/base-files/etc/diag.sh
index 0bcb273359..ce2b9bad50 100644
--- a/target/linux/ar71xx/base-files/etc/diag.sh
+++ b/target/linux/ar71xx/base-files/etc/diag.sh
@@ -328,6 +328,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 ea19de9087..51095a9a5e 100755
--- a/target/linux/ar71xx/base-files/etc/uci-defaults/02_network
+++ b/target/linux/ar71xx/base-files/etc/uci-defaults/02_network
@@ -341,6 +341,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 9943d6918a..dd13948c40 100755
--- a/target/linux/ar71xx/base-files/lib/ar71xx.sh
+++ b/target/linux/ar71xx/base-files/lib/ar71xx.sh
@@ -880,6 +880,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 37a2e7b0ee..73d8b0d7f6 100755
--- a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh
@@ -233,6 +233,7 @@ platform_check_image() {
nanostation-m-xw | \
rw2458n | \
wpj531 | \
+ wap4410n | \
wndap360 | \
wpj344 | \
wzr-hp-g300nh2 | \
diff --git a/target/linux/ar71xx/config-3.18 b/target/linux/ar71xx/config-3.18
index 0680dd0440..02857d5d2d 100644
--- a/target/linux/ar71xx/config-3.18
+++ b/target/linux/ar71xx/config-3.18
@@ -148,6 +148,7 @@ CONFIG_ATH79_MACH_WPJ531=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 0000000000..f2cf071fc8
--- /dev/null
+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wap4410n.c
@@ -0,0 +1,285 @@
+/*
+ * Cisco WAP4410N board support
+ *
+ * Copyright (C) 2014 Caleb James DeLisle <cjd@cjdns.fr>
+ * Copyright (C) 2015 Ryan A Young <rayoung@utexas.edu>
+ *
+ * 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 <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/nxp_74hc153.h>
+
+#include <asm/mach-ath79/ath79.h>
+
+#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)
+/*
+ * Note that this is different from upgrade.h, in which ENV_SIZE is 0x10000.
+ * This is because the sercomm header is located in the upper end of the root
+ * section instead of the env section, and it must not be overwritten by rootfs.
+ */
+#define ENV_SIZE (0x20000)
+
+#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 bedf3a3d49..0a7a89768b 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 0235287e16..e43d95dd4a 100644
--- a/target/linux/ar71xx/image/Makefile
+++ b/target/linux/ar71xx/image/Makefile
@@ -1254,6 +1254,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))
@@ -2141,6 +2143,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))