The commit is incomplete, it does not even build the mach-* file This reverts commit 6e6adcf7a197b1802cb728ddcccf05f890ca0574 SVN-Revision: 46425master
parent
0fc6755f66
commit
d26e8d9439
@ -1,285 +0,0 @@ |
||||
/*
|
||||
* 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 |
||||
); |
Loading…
Reference in new issue