Add support for TP-LINK CPE210/220/510/520
This commit is contained in:
parent
6f14837b91
commit
ab729ed307
@ -0,0 +1,570 @@
|
|||||||
|
From: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
|
Date: Wed, 26 Nov 2014 19:57:39 +0100
|
||||||
|
Subject: firmware-utils: add new tool tplink-safeloader for the new TP-LINK Pharos devices (CPE210/220/510/520)
|
||||||
|
|
||||||
|
The new TP-LINK Pharos series uses a new bootloader, the "TP-LINK Safeloader".
|
||||||
|
It uses an advanced firmware image format, containing an image partition table
|
||||||
|
and a flash partition table (and image partitions are mapped to the
|
||||||
|
corresponding flash partitions). The exact image format is documented in the
|
||||||
|
source code.
|
||||||
|
|
||||||
|
Furthermore, the bootloader expects the kernel image as an ELF executable.
|
||||||
|
|
||||||
|
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
|
|
||||||
|
diff --git a/tools/firmware-utils/Makefile b/tools/firmware-utils/Makefile
|
||||||
|
index 4bb53cb..3f9eb56 100644
|
||||||
|
--- a/tools/firmware-utils/Makefile
|
||||||
|
+++ b/tools/firmware-utils/Makefile
|
||||||
|
@@ -41,6 +41,7 @@ define Host/Compile
|
||||||
|
$(call cc,mkplanexfw sha1)
|
||||||
|
$(call cc,mktplinkfw md5)
|
||||||
|
$(call cc,mktplinkfw2 md5)
|
||||||
|
+ $(call cc,tplink-safeloader md5, -Wall)
|
||||||
|
$(call cc,pc1crypt)
|
||||||
|
$(call cc,osbridge-crc)
|
||||||
|
$(call cc,wrt400n cyg_crc32)
|
||||||
|
diff --git a/tools/firmware-utils/src/tplink-safeloader.c b/tools/firmware-utils/src/tplink-safeloader.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..23d703f
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tools/firmware-utils/src/tplink-safeloader.c
|
||||||
|
@@ -0,0 +1,538 @@
|
||||||
|
+/*
|
||||||
|
+ Copyright (c) 2014, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
|
+ All rights reserved.
|
||||||
|
+
|
||||||
|
+ Redistribution and use in source and binary forms, with or without
|
||||||
|
+ modification, are permitted provided that the following conditions are met:
|
||||||
|
+
|
||||||
|
+ 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
+ this list of conditions and the following disclaimer.
|
||||||
|
+ 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
+ this list of conditions and the following disclaimer in the documentation
|
||||||
|
+ and/or other materials provided with the distribution.
|
||||||
|
+
|
||||||
|
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
+*/
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ tplink-safeloader
|
||||||
|
+
|
||||||
|
+ Image generation tool for the TP-LINK SafeLoader as seen on
|
||||||
|
+ TP-LINK Pharos devices (CPE210/220/510/520)
|
||||||
|
+*/
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+#include <assert.h>
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <error.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <stdint.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <time.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+
|
||||||
|
+#include <arpa/inet.h>
|
||||||
|
+
|
||||||
|
+#include <sys/types.h>
|
||||||
|
+#include <sys/stat.h>
|
||||||
|
+
|
||||||
|
+#include "md5.h"
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+#define ALIGN(x,a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); })
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/** An image partition table entry */
|
||||||
|
+struct image_partition_entry {
|
||||||
|
+ const char *name;
|
||||||
|
+ size_t size;
|
||||||
|
+ uint8_t *data;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/** A flash partition table entry */
|
||||||
|
+struct flash_partition_entry {
|
||||||
|
+ const char *name;
|
||||||
|
+ uint32_t base;
|
||||||
|
+ uint32_t size;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/** The content of the soft-version structure */
|
||||||
|
+struct __attribute__((__packed__)) soft_version {
|
||||||
|
+ uint32_t magic;
|
||||||
|
+ uint32_t zero;
|
||||||
|
+ uint8_t pad1;
|
||||||
|
+ uint8_t version_major;
|
||||||
|
+ uint8_t version_minor;
|
||||||
|
+ uint8_t version_patch;
|
||||||
|
+ uint8_t year_hi;
|
||||||
|
+ uint8_t year_lo;
|
||||||
|
+ uint8_t month;
|
||||||
|
+ uint8_t day;
|
||||||
|
+ uint32_t rev;
|
||||||
|
+ uint8_t pad2;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static const uint8_t jffs2_eof_mark[4] = {0xde, 0xad, 0xc0, 0xde};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ Salt for the MD5 hash
|
||||||
|
+
|
||||||
|
+ Fortunately, TP-LINK seems to use the same salt for most devices which use
|
||||||
|
+ the new image format.
|
||||||
|
+*/
|
||||||
|
+static const uint8_t md5_salt[16] = {
|
||||||
|
+ 0x7a, 0x2b, 0x15, 0xed,
|
||||||
|
+ 0x9b, 0x98, 0x59, 0x6d,
|
||||||
|
+ 0xe5, 0x04, 0xab, 0x44,
|
||||||
|
+ 0xac, 0x2a, 0x9f, 0x4e,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/** Vendor information for CPE210/220/510/520 */
|
||||||
|
+static const unsigned char cpe510_vendor[] = "\x00\x00\x00\x1f""CPE510(TP-LINK|UN|N300-5):1.0\r\n";
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ The flash partition table for CPE210/220/510/520;
|
||||||
|
+ it is the same as the one used by the stock images.
|
||||||
|
+*/
|
||||||
|
+static const struct flash_partition_entry cpe510_partitions[] = {
|
||||||
|
+ {"fs-uboot", 0x00000, 0x20000},
|
||||||
|
+ {"partition-table", 0x20000, 0x02000},
|
||||||
|
+ {"default-mac", 0x30000, 0x00020},
|
||||||
|
+ {"product-info", 0x31100, 0x00100},
|
||||||
|
+ {"signature", 0x32000, 0x00400},
|
||||||
|
+ {"os-image", 0x40000, 0x170000},
|
||||||
|
+ {"soft-version", 0x1b0000, 0x00100},
|
||||||
|
+ {"support-list", 0x1b1000, 0x00400},
|
||||||
|
+ {"file-system", 0x1c0000, 0x600000},
|
||||||
|
+ {"user-config", 0x7c0000, 0x10000},
|
||||||
|
+ {"default-config", 0x7d0000, 0x10000},
|
||||||
|
+ {"log", 0x7e0000, 0x10000},
|
||||||
|
+ {"radio", 0x7f0000, 0x10000},
|
||||||
|
+ {NULL, 0, 0}
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ The support list for CPE210/220/510/520
|
||||||
|
+
|
||||||
|
+ The stock images also contain strings for two more devices: BS510 and BS210.
|
||||||
|
+ At the moment, there exists no public information about these devices.
|
||||||
|
+*/
|
||||||
|
+static const unsigned char cpe510_support_list[] =
|
||||||
|
+ "\x00\x00\x00\xc8\x00\x00\x00\x00"
|
||||||
|
+ "SupportList:\r\n"
|
||||||
|
+ "CPE510(TP-LINK|UN|N300-5):1.0\r\n"
|
||||||
|
+ "CPE520(TP-LINK|UN|N300-5):1.0\r\n"
|
||||||
|
+ "CPE210(TP-LINK|UN|N300-2):1.0\r\n"
|
||||||
|
+ "CPE220(TP-LINK|UN|N300-2):1.0\r\n"
|
||||||
|
+ "\r\n\xff";
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/** Allocates a new image partition */
|
||||||
|
+struct image_partition_entry alloc_image_partition(const char *name, size_t len) {
|
||||||
|
+ struct image_partition_entry entry = {name, len, malloc(len)};
|
||||||
|
+ if (!entry.data)
|
||||||
|
+ error(1, errno, "malloc");
|
||||||
|
+
|
||||||
|
+ return entry;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/** Frees an image partition */
|
||||||
|
+void free_image_partition(struct image_partition_entry entry) {
|
||||||
|
+ free(entry.data);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/** Generates the partition-table partition */
|
||||||
|
+struct image_partition_entry make_partition_table(const struct flash_partition_entry *p) {
|
||||||
|
+ struct image_partition_entry entry = alloc_image_partition("partition-table", 0x800);
|
||||||
|
+
|
||||||
|
+ char *s = (char *)entry.data, *end = (char *)(s+entry.size);
|
||||||
|
+
|
||||||
|
+ *(s++) = 0x00;
|
||||||
|
+ *(s++) = 0x04;
|
||||||
|
+ *(s++) = 0x00;
|
||||||
|
+ *(s++) = 0x00;
|
||||||
|
+
|
||||||
|
+ size_t i;
|
||||||
|
+ for (i = 0; p[i].name; i++) {
|
||||||
|
+ size_t len = end-s;
|
||||||
|
+ size_t w = snprintf(s, len, "partition %s base 0x%05x size 0x%05x\n", p[i].name, p[i].base, p[i].size);
|
||||||
|
+
|
||||||
|
+ if (w > len-1)
|
||||||
|
+ error(1, 0, "flash partition table overflow?");
|
||||||
|
+
|
||||||
|
+ s += w;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ s++;
|
||||||
|
+
|
||||||
|
+ memset(s, 0xff, end-s);
|
||||||
|
+
|
||||||
|
+ return entry;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/** Generates a binary-coded decimal representation of an integer in the range [0, 99] */
|
||||||
|
+static inline uint8_t bcd(uint8_t v) {
|
||||||
|
+ return 0x10 * (v/10) + v%10;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/** Generates the soft-version partition */
|
||||||
|
+struct image_partition_entry make_soft_version(uint32_t rev) {
|
||||||
|
+ struct image_partition_entry entry = alloc_image_partition("soft-version", sizeof(struct soft_version));
|
||||||
|
+ struct soft_version *s = (struct soft_version *)entry.data;
|
||||||
|
+
|
||||||
|
+ time_t t;
|
||||||
|
+ if (time(&t) == (time_t)(-1))
|
||||||
|
+ error(1, errno, "time");
|
||||||
|
+
|
||||||
|
+ struct tm *tm = localtime(&t);
|
||||||
|
+
|
||||||
|
+ s->magic = htonl(0x0000000c);
|
||||||
|
+ s->zero = 0;
|
||||||
|
+ s->pad1 = 0xff;
|
||||||
|
+
|
||||||
|
+ s->version_major = 0;
|
||||||
|
+ s->version_minor = 0;
|
||||||
|
+ s->version_patch = 0;
|
||||||
|
+
|
||||||
|
+ s->year_hi = bcd((1900+tm->tm_year)/100);
|
||||||
|
+ s->year_lo = bcd(tm->tm_year%100);
|
||||||
|
+ s->month = bcd(tm->tm_mon+1);
|
||||||
|
+ s->day = bcd(tm->tm_mday);
|
||||||
|
+ s->rev = htonl(rev);
|
||||||
|
+
|
||||||
|
+ s->pad2 = 0xff;
|
||||||
|
+
|
||||||
|
+ return entry;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/** Generates the support-list partition */
|
||||||
|
+struct image_partition_entry make_support_list(const unsigned char *support_list, size_t len) {
|
||||||
|
+ struct image_partition_entry entry = alloc_image_partition("support-list", len);
|
||||||
|
+ memcpy(entry.data, support_list, len);
|
||||||
|
+ return entry;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/** Creates a new image partition with an arbitrary name from a file */
|
||||||
|
+struct image_partition_entry read_file(const char *part_name, const char *filename, bool add_jffs2_eof) {
|
||||||
|
+ struct stat statbuf;
|
||||||
|
+
|
||||||
|
+ if (stat(filename, &statbuf) < 0)
|
||||||
|
+ error(1, errno, "unable to stat file `%s'", filename);
|
||||||
|
+
|
||||||
|
+ size_t len = statbuf.st_size;
|
||||||
|
+
|
||||||
|
+ if (add_jffs2_eof)
|
||||||
|
+ len = ALIGN(len, 0x10000) + sizeof(jffs2_eof_mark);
|
||||||
|
+
|
||||||
|
+ struct image_partition_entry entry = alloc_image_partition(part_name, len);
|
||||||
|
+
|
||||||
|
+ FILE *file = fopen(filename, "rb");
|
||||||
|
+ if (!file)
|
||||||
|
+ error(1, errno, "unable to open file `%s'", filename);
|
||||||
|
+
|
||||||
|
+ if (fread(entry.data, statbuf.st_size, 1, file) != 1)
|
||||||
|
+ error(1, errno, "unable to read file `%s'", filename);
|
||||||
|
+
|
||||||
|
+ if (add_jffs2_eof) {
|
||||||
|
+ uint8_t *eof = entry.data + statbuf.st_size, *end = entry.data+entry.size;
|
||||||
|
+
|
||||||
|
+ memset(eof, 0xff, end - eof - sizeof(jffs2_eof_mark));
|
||||||
|
+ memcpy(end - sizeof(jffs2_eof_mark), jffs2_eof_mark, sizeof(jffs2_eof_mark));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ fclose(file);
|
||||||
|
+
|
||||||
|
+ return entry;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ Copies a list of image partitions into an image buffer and generates the image partition table while doing so
|
||||||
|
+
|
||||||
|
+ Example image partition table:
|
||||||
|
+
|
||||||
|
+ fwup-ptn partition-table base 0x00800 size 0x00800
|
||||||
|
+ fwup-ptn os-image base 0x01000 size 0x113b45
|
||||||
|
+ fwup-ptn file-system base 0x114b45 size 0x1d0004
|
||||||
|
+ fwup-ptn support-list base 0x2e4b49 size 0x000d1
|
||||||
|
+
|
||||||
|
+ Each line of the partition table is terminated with the bytes 09 0d 0a ("\t\r\n"),
|
||||||
|
+ the end of the partition table is marked with a zero byte.
|
||||||
|
+
|
||||||
|
+ The firmware image must contain at least the partition-table and support-list partitions
|
||||||
|
+ to be accepted. There aren't any alignment constraints for the image partitions.
|
||||||
|
+
|
||||||
|
+ The partition-table partition contains the actual flash layout; partitions
|
||||||
|
+ from the image partition table are mapped to the corresponding flash partitions during
|
||||||
|
+ the firmware upgrade. The support-list partition contains a list of devices supported by
|
||||||
|
+ the firmware image.
|
||||||
|
+
|
||||||
|
+ The base offsets in the firmware partition table are relative to the end
|
||||||
|
+ of the vendor information block, so the partition-table partition will
|
||||||
|
+ actually start at offset 0x1814 of the image.
|
||||||
|
+
|
||||||
|
+ I think partition-table must be the first partition in the firmware image.
|
||||||
|
+*/
|
||||||
|
+void put_partitions(uint8_t *buffer, const struct image_partition_entry *parts) {
|
||||||
|
+ size_t i;
|
||||||
|
+ char *image_pt = (char *)buffer, *end = image_pt + 0x800;
|
||||||
|
+
|
||||||
|
+ size_t base = 0x800;
|
||||||
|
+ for (i = 0; parts[i].name; i++) {
|
||||||
|
+ memcpy(buffer + base, parts[i].data, parts[i].size);
|
||||||
|
+
|
||||||
|
+ size_t len = end-image_pt;
|
||||||
|
+ size_t w = snprintf(image_pt, len, "fwup-ptn %s base 0x%05x size 0x%05x\t\r\n", parts[i].name, (unsigned)base, (unsigned)parts[i].size);
|
||||||
|
+
|
||||||
|
+ if (w > len-1)
|
||||||
|
+ error(1, 0, "image partition table overflow?");
|
||||||
|
+
|
||||||
|
+ image_pt += w;
|
||||||
|
+
|
||||||
|
+ base += parts[i].size;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ image_pt++;
|
||||||
|
+
|
||||||
|
+ memset(image_pt, 0xff, end-image_pt);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/** Generates and writes the image MD5 checksum */
|
||||||
|
+void put_md5(uint8_t *md5, uint8_t *buffer, unsigned int len) {
|
||||||
|
+ MD5_CTX ctx;
|
||||||
|
+
|
||||||
|
+ MD5_Init(&ctx);
|
||||||
|
+ MD5_Update(&ctx, md5_salt, (unsigned int)sizeof(md5_salt));
|
||||||
|
+ MD5_Update(&ctx, buffer, len);
|
||||||
|
+ MD5_Final(md5, &ctx);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ Generates the firmware image in factory format
|
||||||
|
+
|
||||||
|
+ Image format:
|
||||||
|
+
|
||||||
|
+ Bytes (hex) Usage
|
||||||
|
+ ----------- -----
|
||||||
|
+ 0000-0003 Image size (4 bytes, big endian)
|
||||||
|
+ 0004-0013 MD5 hash (hash of a 16 byte salt and the image data starting with byte 0x14)
|
||||||
|
+ 0014-1013 Vendor information (4096 bytes, padded with 0xff; there seem to be older
|
||||||
|
+ (VxWorks-based) TP-LINK devices which use a smaller vendor information block)
|
||||||
|
+ 1014-1813 Image partition table (2048 bytes, padded with 0xff)
|
||||||
|
+ 1814-xxxx Firmware partitions
|
||||||
|
+*/
|
||||||
|
+void * generate_factory_image(const unsigned char *vendor, size_t vendor_len, const struct image_partition_entry *parts, size_t *len) {
|
||||||
|
+ *len = 0x1814;
|
||||||
|
+
|
||||||
|
+ size_t i;
|
||||||
|
+ for (i = 0; parts[i].name; i++)
|
||||||
|
+ *len += parts[i].size;
|
||||||
|
+
|
||||||
|
+ uint8_t *image = malloc(*len);
|
||||||
|
+ if (!image)
|
||||||
|
+ error(1, errno, "malloc");
|
||||||
|
+
|
||||||
|
+ image[0] = *len >> 24;
|
||||||
|
+ image[1] = *len >> 16;
|
||||||
|
+ image[2] = *len >> 8;
|
||||||
|
+ image[3] = *len;
|
||||||
|
+
|
||||||
|
+ memcpy(image+0x14, vendor, vendor_len);
|
||||||
|
+ memset(image+0x14+vendor_len, 0xff, 4096-vendor_len);
|
||||||
|
+
|
||||||
|
+ put_partitions(image + 0x1014, parts);
|
||||||
|
+ put_md5(image+0x04, image+0x14, *len-0x14);
|
||||||
|
+
|
||||||
|
+ return image;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ Generates the firmware image in sysupgrade format
|
||||||
|
+
|
||||||
|
+ This makes some assumptions about the provided flash and image partition tables and
|
||||||
|
+ should be generalized when TP-LINK starts building its safeloader into hardware with
|
||||||
|
+ different flash layouts.
|
||||||
|
+*/
|
||||||
|
+void * generate_sysupgrade_image(const struct flash_partition_entry *flash_parts, const struct image_partition_entry *image_parts, size_t *len) {
|
||||||
|
+ const struct flash_partition_entry *flash_os_image = &flash_parts[5];
|
||||||
|
+ const struct flash_partition_entry *flash_soft_version = &flash_parts[6];
|
||||||
|
+ const struct flash_partition_entry *flash_support_list = &flash_parts[7];
|
||||||
|
+ const struct flash_partition_entry *flash_file_system = &flash_parts[8];
|
||||||
|
+
|
||||||
|
+ const struct image_partition_entry *image_os_image = &image_parts[3];
|
||||||
|
+ const struct image_partition_entry *image_soft_version = &image_parts[1];
|
||||||
|
+ const struct image_partition_entry *image_support_list = &image_parts[2];
|
||||||
|
+ const struct image_partition_entry *image_file_system = &image_parts[4];
|
||||||
|
+
|
||||||
|
+ assert(strcmp(flash_os_image->name, "os-image") == 0);
|
||||||
|
+ assert(strcmp(flash_soft_version->name, "soft-version") == 0);
|
||||||
|
+ assert(strcmp(flash_support_list->name, "support-list") == 0);
|
||||||
|
+ assert(strcmp(flash_file_system->name, "file-system") == 0);
|
||||||
|
+
|
||||||
|
+ assert(strcmp(image_os_image->name, "os-image") == 0);
|
||||||
|
+ assert(strcmp(image_soft_version->name, "soft-version") == 0);
|
||||||
|
+ assert(strcmp(image_support_list->name, "support-list") == 0);
|
||||||
|
+ assert(strcmp(image_file_system->name, "file-system") == 0);
|
||||||
|
+
|
||||||
|
+ if (image_os_image->size > flash_os_image->size)
|
||||||
|
+ error(1, 0, "kernel image too big (more than %u bytes)", (unsigned)flash_os_image->size);
|
||||||
|
+ if (image_file_system->size > flash_file_system->size)
|
||||||
|
+ error(1, 0, "rootfs image too big (more than %u bytes)", (unsigned)flash_file_system->size);
|
||||||
|
+
|
||||||
|
+ *len = flash_file_system->base - flash_os_image->base + image_file_system->size;
|
||||||
|
+
|
||||||
|
+ uint8_t *image = malloc(*len);
|
||||||
|
+ if (!image)
|
||||||
|
+ error(1, errno, "malloc");
|
||||||
|
+
|
||||||
|
+ memset(image, 0xff, *len);
|
||||||
|
+
|
||||||
|
+ memcpy(image, image_os_image->data, image_os_image->size);
|
||||||
|
+ memcpy(image + flash_soft_version->base - flash_os_image->base, image_soft_version->data, image_soft_version->size);
|
||||||
|
+ memcpy(image + flash_support_list->base - flash_os_image->base, image_support_list->data, image_support_list->size);
|
||||||
|
+ memcpy(image + flash_file_system->base - flash_os_image->base, image_file_system->data, image_file_system->size);
|
||||||
|
+
|
||||||
|
+ return image;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/** Generates an image for CPE210/220/510/520 and writes it to a file */
|
||||||
|
+static void do_cpe510(const char *output, const char *kernel_image, const char *rootfs_image, uint32_t rev, bool add_jffs2_eof, bool sysupgrade) {
|
||||||
|
+ struct image_partition_entry parts[6] = {};
|
||||||
|
+
|
||||||
|
+ parts[0] = make_partition_table(cpe510_partitions);
|
||||||
|
+ parts[1] = make_soft_version(rev);
|
||||||
|
+ parts[2] = make_support_list(cpe510_support_list, sizeof(cpe510_support_list)-1);
|
||||||
|
+ parts[3] = read_file("os-image", kernel_image, false);
|
||||||
|
+ parts[4] = read_file("file-system", rootfs_image, add_jffs2_eof);
|
||||||
|
+
|
||||||
|
+ size_t len;
|
||||||
|
+ void *image;
|
||||||
|
+ if (sysupgrade)
|
||||||
|
+ image = generate_sysupgrade_image(cpe510_partitions, parts, &len);
|
||||||
|
+ else
|
||||||
|
+ image = generate_factory_image(cpe510_vendor, sizeof(cpe510_vendor)-1, parts, &len);
|
||||||
|
+
|
||||||
|
+ FILE *file = fopen(output, "wb");
|
||||||
|
+ if (!file)
|
||||||
|
+ error(1, errno, "unable to open output file");
|
||||||
|
+
|
||||||
|
+ if (fwrite(image, len, 1, file) != 1)
|
||||||
|
+ error(1, 0, "unable to write output file");
|
||||||
|
+
|
||||||
|
+ fclose(file);
|
||||||
|
+
|
||||||
|
+ free(image);
|
||||||
|
+
|
||||||
|
+ size_t i;
|
||||||
|
+ for (i = 0; parts[i].name; i++)
|
||||||
|
+ free_image_partition(parts[i]);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/** Usage output */
|
||||||
|
+void usage(const char *argv0) {
|
||||||
|
+ fprintf(stderr,
|
||||||
|
+ "Usage: %s [OPTIONS...]\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "Options:\n"
|
||||||
|
+ " -B <board> create image for the board specified with <board>\n"
|
||||||
|
+ " -k <file> read kernel image from the file <file>\n"
|
||||||
|
+ " -r <file> read rootfs image from the file <file>\n"
|
||||||
|
+ " -o <file> write output to the file <file>\n"
|
||||||
|
+ " -V <rev> sets the revision number to <rev>\n"
|
||||||
|
+ " -j add jffs2 end-of-filesystem markers\n"
|
||||||
|
+ " -S create sysupgrade instead of factory image\n"
|
||||||
|
+ " -h show this help\n",
|
||||||
|
+ argv0
|
||||||
|
+ );
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+int main(int argc, char *argv[]) {
|
||||||
|
+ const char *board = NULL, *kernel_image = NULL, *rootfs_image = NULL, *output = NULL;
|
||||||
|
+ bool add_jffs2_eof = false, sysupgrade = false;
|
||||||
|
+ unsigned rev = 0;
|
||||||
|
+
|
||||||
|
+ while (true) {
|
||||||
|
+ int c;
|
||||||
|
+
|
||||||
|
+ c = getopt(argc, argv, "B:k:r:o:V:jSh");
|
||||||
|
+ if (c == -1)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ switch (c) {
|
||||||
|
+ case 'B':
|
||||||
|
+ board = optarg;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case 'k':
|
||||||
|
+ kernel_image = optarg;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case 'r':
|
||||||
|
+ rootfs_image = optarg;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case 'o':
|
||||||
|
+ output = optarg;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case 'V':
|
||||||
|
+ sscanf(optarg, "r%u", &rev);
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case 'j':
|
||||||
|
+ add_jffs2_eof = true;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case 'S':
|
||||||
|
+ sysupgrade = true;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case 'h':
|
||||||
|
+ usage(argv[0]);
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ default:
|
||||||
|
+ usage(argv[0]);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!board)
|
||||||
|
+ error(1, 0, "no board has been specified");
|
||||||
|
+ if (!kernel_image)
|
||||||
|
+ error(1, 0, "no kernel image has been specified");
|
||||||
|
+ if (!rootfs_image)
|
||||||
|
+ error(1, 0, "no rootfs image has been specified");
|
||||||
|
+ if (!output)
|
||||||
|
+ error(1, 0, "no output filename has been specified");
|
||||||
|
+
|
||||||
|
+ if (strcmp(board, "CPE510") == 0)
|
||||||
|
+ do_cpe510(output, kernel_image, rootfs_image, rev, add_jffs2_eof, sysupgrade);
|
||||||
|
+ else
|
||||||
|
+ error(1, 0, "unsupported board %s", board);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
@ -0,0 +1,471 @@
|
|||||||
|
From: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
|
Date: Wed, 26 Nov 2014 19:57:50 +0100
|
||||||
|
Subject: ar71xx: add support for TP-LINK CPE210/220/510/520
|
||||||
|
|
||||||
|
This adds support for the TP-LINK CPE210/220/510/520 (Pharos series). These
|
||||||
|
devices are very similar to the Ubiquiti NanoStations, but with better specs:
|
||||||
|
faster CPU, more RAM, 2x2 MIMO.
|
||||||
|
|
||||||
|
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
|
|
||||||
|
diff --git a/target/linux/ar71xx/base-files/etc/diag.sh b/target/linux/ar71xx/base-files/etc/diag.sh
|
||||||
|
index 1864b11..4b510dd 100755
|
||||||
|
--- a/target/linux/ar71xx/base-files/etc/diag.sh
|
||||||
|
+++ b/target/linux/ar71xx/base-files/etc/diag.sh
|
||||||
|
@@ -43,6 +43,9 @@ get_status_led() {
|
||||||
|
cap4200ag)
|
||||||
|
status_led="senao:green:pwr"
|
||||||
|
;;
|
||||||
|
+ cpe510)
|
||||||
|
+ status_led="tp-link:green:link4"
|
||||||
|
+ ;;
|
||||||
|
db120)
|
||||||
|
status_led="db120:green:status"
|
||||||
|
;;
|
||||||
|
diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds b/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds
|
||||||
|
index d3b766d..fb8df40 100755
|
||||||
|
--- a/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds
|
||||||
|
+++ b/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds
|
||||||
|
@@ -61,6 +61,16 @@ carambola2)
|
||||||
|
ucidef_set_led_wlan "wlan" "WLAN" "carambola2:green:wlan" "phy0tpt"
|
||||||
|
;;
|
||||||
|
|
||||||
|
+cpe510)
|
||||||
|
+ ucidef_set_led_switch "lan0" "LAN0" "tp-link:green:lan0" "switch0" "0x20"
|
||||||
|
+ ucidef_set_led_switch "lan1" "LAN1" "tp-link:green:lan1" "switch0" "0x10"
|
||||||
|
+ ucidef_set_rssimon "wlan0" "40000" "1"
|
||||||
|
+ ucidef_set_led_rssi "rssilow" "RSSILOW" "tp-link:green:link1" "wlan0" "1" "100" "0" "13"
|
||||||
|
+ ucidef_set_led_rssi "rssimediumlow" "RSSIMEDIUMLOW" "tp-link:green:link2" "wlan0" "26" "100" "-25" "13"
|
||||||
|
+ ucidef_set_led_rssi "rssimediumhigh" "RSSIMEDIUMHIGH" "tp-link:green:link3" "wlan0" "51" "100" "-50" "13"
|
||||||
|
+ ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "tp-link:green:link4" "wlan0" "76" "100" "-75" "13"
|
||||||
|
+ ;;
|
||||||
|
+
|
||||||
|
db120)
|
||||||
|
ucidef_set_led_usbdev "usb" "USB" "db120:green:usb" "1-1"
|
||||||
|
;;
|
||||||
|
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 c5cfd67..a9f00fa 100755
|
||||||
|
--- a/target/linux/ar71xx/base-files/etc/uci-defaults/02_network
|
||||||
|
+++ b/target/linux/ar71xx/base-files/etc/uci-defaults/02_network
|
||||||
|
@@ -62,6 +62,13 @@ tl-wdr4900-v2)
|
||||||
|
ucidef_add_switch_vlan "switch0" "2" "1 6"
|
||||||
|
;;
|
||||||
|
|
||||||
|
+cpe510)
|
||||||
|
+ ucidef_set_interfaces_lan_wan "eth0.1" "eth0.2"
|
||||||
|
+ ucidef_add_switch "switch0" "1" "1"
|
||||||
|
+ ucidef_add_switch_vlan "switch0" "1" "0t 5"
|
||||||
|
+ ucidef_add_switch_vlan "switch0" "2" "0t 4"
|
||||||
|
+ ;;
|
||||||
|
+
|
||||||
|
db120 |\
|
||||||
|
rb-2011l | \
|
||||||
|
rb-2011uas |\
|
||||||
|
diff --git a/target/linux/ar71xx/base-files/lib/ar71xx.sh b/target/linux/ar71xx/base-files/lib/ar71xx.sh
|
||||||
|
index 5aceaee..0b0a8d6 100755
|
||||||
|
--- a/target/linux/ar71xx/base-files/lib/ar71xx.sh
|
||||||
|
+++ b/target/linux/ar71xx/base-files/lib/ar71xx.sh
|
||||||
|
@@ -229,6 +229,39 @@ tplink_board_detect() {
|
||||||
|
AR71XX_MODEL="$model $hwver"
|
||||||
|
}
|
||||||
|
|
||||||
|
+tplink_pharos_get_model_string() {
|
||||||
|
+ local part
|
||||||
|
+ part=$(find_mtd_part 'product-info')
|
||||||
|
+ [ -z "$part" ] && return 1
|
||||||
|
+
|
||||||
|
+ # The returned string will end with \r\n, but we don't remove it here
|
||||||
|
+ # to simplify matching against it in the sysupgrade image check
|
||||||
|
+ dd if=$part bs=1 skip=4360 2>/dev/null | head -n 1
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+tplink_pharos_board_detect() {
|
||||||
|
+ local model_string="$(tplink_pharos_get_model_string | tr -d '\r')"
|
||||||
|
+ local oIFS="$IFS"; IFS=":"; set -- $model_string; IFS="$oIFS"
|
||||||
|
+ local model
|
||||||
|
+
|
||||||
|
+ case "$1" in
|
||||||
|
+ 'CPE210(TP-LINK|UN|N300-2)')
|
||||||
|
+ model='TP-Link CPE210'
|
||||||
|
+ ;;
|
||||||
|
+ 'CPE220(TP-LINK|UN|N300-2)')
|
||||||
|
+ model='TP-Link CPE220'
|
||||||
|
+ ;;
|
||||||
|
+ 'CPE510(TP-LINK|UN|N300-5)')
|
||||||
|
+ model='TP-Link CPE510'
|
||||||
|
+ ;;
|
||||||
|
+ 'CPE520(TP-LINK|UN|N300-5)')
|
||||||
|
+ model='TP-Link CPE520'
|
||||||
|
+ ;;
|
||||||
|
+ esac
|
||||||
|
+
|
||||||
|
+ [ -n "$model" ] && AR71XX_MODEL="$model v$2"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
ar71xx_board_detect() {
|
||||||
|
local machine
|
||||||
|
local name
|
||||||
|
@@ -302,6 +335,10 @@ ar71xx_board_detect() {
|
||||||
|
*CAP4200AG)
|
||||||
|
name="cap4200ag"
|
||||||
|
;;
|
||||||
|
+ *"CPE210/220/510/520")
|
||||||
|
+ name="cpe510"
|
||||||
|
+ tplink_pharos_board_detect
|
||||||
|
+ ;;
|
||||||
|
*"DB120 reference board")
|
||||||
|
name="db120"
|
||||||
|
;;
|
||||||
|
@@ -751,11 +788,8 @@ ar71xx_board_detect() {
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
- case "$machine" in
|
||||||
|
- *TL-WR* | *TL-WA* | *TL-MR* | *TL-WD* | *Archer*)
|
||||||
|
+ [ -z "$AR71XX_MODEL" ] && [ "${machine:0:8}" = 'TP-LINK ' ] && \
|
||||||
|
tplink_board_detect "$machine"
|
||||||
|
- ;;
|
||||||
|
- esac
|
||||||
|
|
||||||
|
[ -z "$name" ] && name="unknown"
|
||||||
|
|
||||||
|
diff --git a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh
|
||||||
|
index 846954c..15e998c 100755
|
||||||
|
--- a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh
|
||||||
|
+++ b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh
|
||||||
|
@@ -70,6 +70,33 @@ tplink_get_image_boot_size() {
|
||||||
|
get_image "$@" | dd bs=4 count=1 skip=37 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"'
|
||||||
|
}
|
||||||
|
|
||||||
|
+tplink_pharos_check_image() {
|
||||||
|
+ local magic_long="$(get_magic_long "$1")"
|
||||||
|
+ [ "$magic_long" != "7f454c46" ] && {
|
||||||
|
+ echo "Invalid image magic '$magic_long'"
|
||||||
|
+ return 1
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ local model_string="$(tplink_pharos_get_model_string)"
|
||||||
|
+ local line
|
||||||
|
+
|
||||||
|
+ # Here $1 is given to dd directly instead of get_image as otherwise the skip
|
||||||
|
+ # will take almost a second (as dd can't seek then)
|
||||||
|
+ #
|
||||||
|
+ # This will fail if the image isn't local, but that's fine: as the
|
||||||
|
+ # read loop won't be executed at all, it will return true, so the image
|
||||||
|
+ # is accepted (loading the first 1.5M of a remote image for this check seems
|
||||||
|
+ # a bit extreme)
|
||||||
|
+ dd if="$1" bs=1 skip=1511432 count=1024 2>/dev/null | while read line; do
|
||||||
|
+ [ "$line" == "$model_string" ] && break
|
||||||
|
+ done || {
|
||||||
|
+ echo "Unsupported image (model not in support-list)"
|
||||||
|
+ return 1
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
seama_get_type_magic() {
|
||||||
|
get_image "$@" | dd bs=1 count=4 skip=53 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"'
|
||||||
|
}
|
||||||
|
@@ -214,6 +241,11 @@ platform_check_image() {
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
+ cpe510)
|
||||||
|
+ tplink_pharos_check_image "$1" && return 0
|
||||||
|
+ return 1
|
||||||
|
+ ;;
|
||||||
|
+
|
||||||
|
dir-825-b1 | \
|
||||||
|
tew-673gru)
|
||||||
|
dir825b_check_image "$1" && return 0
|
||||||
|
diff --git a/target/linux/ar71xx/config-3.10 b/target/linux/ar71xx/config-3.10
|
||||||
|
index 9a8378a..2f05ec6 100644
|
||||||
|
--- a/target/linux/ar71xx/config-3.10
|
||||||
|
+++ b/target/linux/ar71xx/config-3.10
|
||||||
|
@@ -39,6 +39,7 @@ CONFIG_ATH79_MACH_AW_NR580=y
|
||||||
|
CONFIG_ATH79_MACH_BHU_BXU2000N2_A=y
|
||||||
|
CONFIG_ATH79_MACH_CAP4200AG=y
|
||||||
|
CONFIG_ATH79_MACH_CARAMBOLA2=y
|
||||||
|
+CONFIG_ATH79_MACH_CPE510=y
|
||||||
|
CONFIG_ATH79_MACH_DB120=y
|
||||||
|
CONFIG_ATH79_MACH_DIR_505_A1=y
|
||||||
|
CONFIG_ATH79_MACH_DIR_600_A1=y
|
||||||
|
diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-cpe510.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-cpe510.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..8bf5c0f
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-cpe510.c
|
||||||
|
@@ -0,0 +1,107 @@
|
||||||
|
+/*
|
||||||
|
+ * TP-LINK CPE210/220/510/520 board support
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 2014 Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
|
+ *
|
||||||
|
+ * 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.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/gpio.h>
|
||||||
|
+#include <linux/platform_device.h>
|
||||||
|
+
|
||||||
|
+#include <asm/mach-ath79/ath79.h>
|
||||||
|
+#include <asm/mach-ath79/ar71xx_regs.h>
|
||||||
|
+
|
||||||
|
+#include "common.h"
|
||||||
|
+#include "dev-eth.h"
|
||||||
|
+#include "dev-gpio-buttons.h"
|
||||||
|
+#include "dev-leds-gpio.h"
|
||||||
|
+#include "dev-m25p80.h"
|
||||||
|
+#include "dev-wmac.h"
|
||||||
|
+#include "machtypes.h"
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+#define CPE510_GPIO_LED_LAN0 11
|
||||||
|
+#define CPE510_GPIO_LED_LAN1 12
|
||||||
|
+#define CPE510_GPIO_LED_L1 13
|
||||||
|
+#define CPE510_GPIO_LED_L2 14
|
||||||
|
+#define CPE510_GPIO_LED_L3 15
|
||||||
|
+#define CPE510_GPIO_LED_L4 16
|
||||||
|
+
|
||||||
|
+#define CPE510_GPIO_BTN_RESET 4
|
||||||
|
+
|
||||||
|
+#define CPE510_KEYS_POLL_INTERVAL 20 /* msecs */
|
||||||
|
+#define CPE510_KEYS_DEBOUNCE_INTERVAL (3 * CPE510_KEYS_POLL_INTERVAL)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static struct gpio_led cpe510_leds_gpio[] __initdata = {
|
||||||
|
+ {
|
||||||
|
+ .name = "tp-link:green:lan0",
|
||||||
|
+ .gpio = CPE510_GPIO_LED_LAN0,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .name = "tp-link:green:lan1",
|
||||||
|
+ .gpio = CPE510_GPIO_LED_LAN1,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .name = "tp-link:green:link1",
|
||||||
|
+ .gpio = CPE510_GPIO_LED_L1,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .name = "tp-link:green:link2",
|
||||||
|
+ .gpio = CPE510_GPIO_LED_L2,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .name = "tp-link:green:link3",
|
||||||
|
+ .gpio = CPE510_GPIO_LED_L3,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .name = "tp-link:green:link4",
|
||||||
|
+ .gpio = CPE510_GPIO_LED_L4,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct gpio_keys_button cpe510_gpio_keys[] __initdata = {
|
||||||
|
+ {
|
||||||
|
+ .desc = "Reset button",
|
||||||
|
+ .type = EV_KEY,
|
||||||
|
+ .code = KEY_RESTART,
|
||||||
|
+ .debounce_interval = CPE510_KEYS_DEBOUNCE_INTERVAL,
|
||||||
|
+ .gpio = CPE510_GPIO_BTN_RESET,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static void __init cpe510_setup(void)
|
||||||
|
+{
|
||||||
|
+ u8 *mac = (u8 *) KSEG1ADDR(0x1f830008);
|
||||||
|
+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
|
||||||
|
+
|
||||||
|
+ /* Disable JTAG, enabling GPIOs 0-3 */
|
||||||
|
+ /* Configure OBS4 line, for GPIO 4*/
|
||||||
|
+ ath79_gpio_function_setup(AR934X_GPIO_FUNC_JTAG_DISABLE,
|
||||||
|
+ AR934X_GPIO_FUNC_CLK_OBS4_EN);
|
||||||
|
+
|
||||||
|
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cpe510_leds_gpio),
|
||||||
|
+ cpe510_leds_gpio);
|
||||||
|
+
|
||||||
|
+ ath79_register_gpio_keys_polled(1, CPE510_KEYS_POLL_INTERVAL,
|
||||||
|
+ ARRAY_SIZE(cpe510_gpio_keys),
|
||||||
|
+ cpe510_gpio_keys);
|
||||||
|
+
|
||||||
|
+ ath79_register_m25p80(NULL);
|
||||||
|
+
|
||||||
|
+ ath79_register_mdio(1, 0);
|
||||||
|
+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0);
|
||||||
|
+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII;
|
||||||
|
+ ath79_register_eth(1);
|
||||||
|
+
|
||||||
|
+ ath79_register_wmac(ee, mac);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+MIPS_MACHINE(ATH79_MACH_CPE510, "CPE510", "TP-LINK CPE210/220/510/520",
|
||||||
|
+ cpe510_setup);
|
||||||
|
diff --git a/target/linux/ar71xx/generic/profiles/tp-link.mk b/target/linux/ar71xx/generic/profiles/tp-link.mk
|
||||||
|
index 78333be..a9d170c 100644
|
||||||
|
--- a/target/linux/ar71xx/generic/profiles/tp-link.mk
|
||||||
|
+++ b/target/linux/ar71xx/generic/profiles/tp-link.mk
|
||||||
|
@@ -16,6 +16,17 @@ endef
|
||||||
|
$(eval $(call Profile,ARCHERC7))
|
||||||
|
|
||||||
|
|
||||||
|
+define Profile/CPE510
|
||||||
|
+ NAME:=TP-LINK CPE210/220/510/520
|
||||||
|
+ PACKAGES:=rssileds
|
||||||
|
+endef
|
||||||
|
+
|
||||||
|
+define Profile/CPE510/Description
|
||||||
|
+ Package set optimized for the TP-LINK CPE210/220/510/520.
|
||||||
|
+endef
|
||||||
|
+$(eval $(call Profile,CPE510))
|
||||||
|
+
|
||||||
|
+
|
||||||
|
define Profile/TLMR10U
|
||||||
|
NAME:=TP-LINK TL-MR10U
|
||||||
|
PACKAGES:=kmod-usb-core kmod-usb2
|
||||||
|
diff --git a/target/linux/ar71xx/image/Makefile b/target/linux/ar71xx/image/Makefile
|
||||||
|
index 683c238..5ff7f35 100644
|
||||||
|
--- a/target/linux/ar71xx/image/Makefile
|
||||||
|
+++ b/target/linux/ar71xx/image/Makefile
|
||||||
|
@@ -261,6 +261,7 @@ cameo_ap121_mtdlayout_8M=mtdparts=spi0.0:64k(u-boot)ro,64k(art)ro,64k(mac)ro,64k
|
||||||
|
cameo_db120_mtdlayout=mtdparts=spi0.0:64k(uboot)ro,64k(nvram)ro,15936k(firmware),192k(lang)ro,64k(mac)ro,64k(art)ro
|
||||||
|
cameo_db120_mtdlayout_8M=mtdparts=spi0.0:64k(uboot)ro,64k(nvram)ro,7872k(firmware),128k(lang)ro,64k(art)ro
|
||||||
|
cap4200ag_mtdlayout=mtdparts=spi0.0:256k(u-boot),64k(u-boot-env),320k(custom)ro,1536k(kernel),12096k(rootfs),2048k(failsafe),64k(art),13632k@0xa0000(firmware)
|
||||||
|
+cpe510_mtdlayout=mtdparts=spi0.0:128k(u-boot)ro,64k(pation-table)ro,64k(product-info)ro,1536k(kernel),6144k(rootfs),192k(config)ro,64k(ART)ro,7680k@0x40000(firmware)
|
||||||
|
eap300v2_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env),320k(custom),13632k(firmware),2048k(failsafe),64k(art)ro
|
||||||
|
db120_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,6336k(rootfs),1408k(kernel),64k(nvram),64k(art)ro,7744k@0x50000(firmware)
|
||||||
|
cameo_ap94_mtdlayout=mtdparts=spi0.0:256k(uboot)ro,64k(config)ro,6208k(firmware),64k(caldata)ro,1600k(unknown)ro,64k@0x7f0000(caldata_copy)
|
||||||
|
@@ -811,6 +812,32 @@ define Image/Build/TPLINK-LZMA/initramfs
|
||||||
|
endef
|
||||||
|
|
||||||
|
|
||||||
|
+Image/Build/TPLINK-SAFELOADER/buildkernel=$(call PatchKernelLzma,$(2),$(3) $(4))
|
||||||
|
+
|
||||||
|
+define Image/Build/TPLINK-SAFELOADER
|
||||||
|
+ -rm -rf $(KDIR)/lzma-loader
|
||||||
|
+ $(LOADER_MAKE) LOADER=loader-$(2).elf\
|
||||||
|
+ LZMA_TEXT_START=0x80a00000 LOADADDR=0x80060000 \
|
||||||
|
+ LOADER_DATA="$(KDIR_TMP)/vmlinux-$(2).bin.lzma" BOARD="$(2)" \
|
||||||
|
+ compile loader.elf
|
||||||
|
+
|
||||||
|
+ -$(STAGING_DIR_HOST)/bin/tplink-safeloader \
|
||||||
|
+ -B $(5) \
|
||||||
|
+ -k $(KDIR)/loader-$(2).elf \
|
||||||
|
+ -r $(KDIR)/root.$(1) \
|
||||||
|
+ -V $(REVISION) \
|
||||||
|
+ -j \
|
||||||
|
+ -o $(call factoryname,$(1),$(2))
|
||||||
|
+ -$(STAGING_DIR_HOST)/bin/tplink-safeloader \
|
||||||
|
+ -B $(5) \
|
||||||
|
+ -k $(KDIR)/loader-$(2).elf \
|
||||||
|
+ -r $(KDIR)/root.$(1) \
|
||||||
|
+ -V $(REVISION) \
|
||||||
|
+ -j -S \
|
||||||
|
+ -o $(call sysupname,$(1),$(2))
|
||||||
|
+endef
|
||||||
|
+
|
||||||
|
+
|
||||||
|
define Image/Build/CyberTAN
|
||||||
|
echo -n '' > $(KDIR_TMP)/empty.bin
|
||||||
|
$(STAGING_DIR_HOST)/bin/trx -o $(KDIR)/image.tmp \
|
||||||
|
@@ -1226,6 +1253,8 @@ $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,TLWDR4310V1,tl-wdr4310-v1,TL-WDR4
|
||||||
|
$(eval $(call SingleProfile,TPLINK-LZMA,64kraw,TLWDR4900V2,tl-wdr4900-v2,TL-WDR4900-v2,ttyS0,115200,0x49000002,1,8Mlzma))
|
||||||
|
$(eval $(call SingleProfile,TPLINK-LZMA,64kraw,MW4530RV1,mw4530r-v1,TL-WDR4300,ttyS0,115200,0x45300001,1,8Mlzma))
|
||||||
|
|
||||||
|
+$(eval $(call SingleProfile,TPLINK-SAFELOADER,64kraw,CPE510,cpe210-220-510-520,CPE510,ttyS0,115200,$$(cpe510_mtdlayout),CPE510))
|
||||||
|
+
|
||||||
|
$(eval $(call SingleProfile,TPLINK-LZMA,64kraw,SMART-300,smart-300,SMART-300,ttyS0,115200,0x93410001,1,8Mlzma))
|
||||||
|
|
||||||
|
$(eval $(call SingleProfile,TPLINK-LZMA,64kraw,OOLITE,oolite,GS-OOLITE,ttyATH0,115200,0x3C000101,1,16Mlzma))
|
||||||
|
diff --git a/target/linux/ar71xx/patches-3.10/610-MIPS-ath79-openwrt-machines.patch b/target/linux/ar71xx/patches-3.10/610-MIPS-ath79-openwrt-machines.patch
|
||||||
|
index 3669f26..516d52d 100644
|
||||||
|
--- a/target/linux/ar71xx/patches-3.10/610-MIPS-ath79-openwrt-machines.patch
|
||||||
|
+++ b/target/linux/ar71xx/patches-3.10/610-MIPS-ath79-openwrt-machines.patch
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
--- a/arch/mips/ath79/machtypes.h
|
||||||
|
+++ b/arch/mips/ath79/machtypes.h
|
||||||
|
-@@ -16,22 +16,144 @@
|
||||||
|
+@@ -16,22 +16,145 @@
|
||||||
|
|
||||||
|
enum ath79_mach_type {
|
||||||
|
ATH79_MACH_GENERIC = 0,
|
||||||
|
@@ -24,6 +24,7 @@
|
||||||
|
+ ATH79_MACH_BHU_BXU2000N2_A1, /* BHU BXU2000n-2 A1 */
|
||||||
|
+ ATH79_MACH_CAP4200AG, /* Senao CAP4200AG */
|
||||||
|
+ ATH79_MACH_CARAMBOLA2, /* 8devices Carambola2 */
|
||||||
|
++ ATH79_MACH_CPE510, /* TP-LINK CPE510 */
|
||||||
|
ATH79_MACH_DB120, /* Atheros DB120 reference board */
|
||||||
|
ATH79_MACH_PB44, /* Atheros PB44 reference board */
|
||||||
|
+ ATH79_MACH_DIR_505_A1, /* D-Link DIR-505 rev. A1 */
|
||||||
|
@@ -209,7 +210,7 @@
|
||||||
|
config ATH79_MACH_AP121
|
||||||
|
bool "Atheros AP121 reference board"
|
||||||
|
select SOC_AR933X
|
||||||
|
-@@ -9,64 +64,736 @@ config ATH79_MACH_AP121
|
||||||
|
+@@ -9,64 +64,745 @@ config ATH79_MACH_AP121
|
||||||
|
select ATH79_DEV_GPIO_BUTTONS
|
||||||
|
select ATH79_DEV_LEDS_GPIO
|
||||||
|
select ATH79_DEV_M25P80
|
||||||
|
@@ -709,6 +710,15 @@
|
||||||
|
|
||||||
|
-config ATH79_MACH_AP81
|
||||||
|
- bool "Atheros AP81 reference board"
|
||||||
|
++config ATH79_MACH_CPE510
|
||||||
|
++ bool "TP-LINK CPE510 support"
|
||||||
|
++ select SOC_AR934X
|
||||||
|
++ select ATH79_DEV_ETH
|
||||||
|
++ select ATH79_DEV_GPIO_BUTTONS
|
||||||
|
++ select ATH79_DEV_LEDS_GPIO
|
||||||
|
++ select ATH79_DEV_M25P80
|
||||||
|
++ select ATH79_DEV_WMAC
|
||||||
|
++
|
||||||
|
+config ATH79_MACH_TL_MR11U
|
||||||
|
+ bool "TP-LINK TL-MR11U/TL-MR3040 support"
|
||||||
|
+ select SOC_AR933X
|
||||||
|
@@ -972,7 +982,7 @@
|
||||||
|
|
||||||
|
config ATH79_MACH_UBNT_XM
|
||||||
|
bool "Ubiquiti Networks XM/UniFi boards"
|
||||||
|
-@@ -83,6 +810,65 @@ config ATH79_MACH_UBNT_XM
|
||||||
|
+@@ -83,6 +819,65 @@ config ATH79_MACH_UBNT_XM
|
||||||
|
Say 'Y' here if you want your kernel to support the
|
||||||
|
Ubiquiti Networks XM (rev 1.0) board.
|
||||||
|
|
||||||
|
@@ -1038,7 +1048,7 @@
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
config SOC_AR71XX
|
||||||
|
-@@ -132,7 +918,10 @@ config ATH79_DEV_DSA
|
||||||
|
+@@ -132,7 +927,10 @@ config ATH79_DEV_DSA
|
||||||
|
config ATH79_DEV_ETH
|
||||||
|
def_bool n
|
||||||
|
|
||||||
|
@@ -1050,7 +1060,7 @@
|
||||||
|
def_bool n
|
||||||
|
|
||||||
|
config ATH79_DEV_GPIO_BUTTONS
|
||||||
|
-@@ -164,4 +953,7 @@ config ATH79_PCI_ATH9K_FIXUP
|
||||||
|
+@@ -164,4 +962,7 @@ config ATH79_PCI_ATH9K_FIXUP
|
||||||
|
config ATH79_ROUTERBOOT
|
||||||
|
def_bool n
|
||||||
|
|
||||||
|
@@ -1060,7 +1070,7 @@
|
||||||
|
endif
|
||||||
|
--- a/arch/mips/ath79/Makefile
|
||||||
|
+++ b/arch/mips/ath79/Makefile
|
||||||
|
-@@ -38,9 +38,90 @@ obj-$(CONFIG_ATH79_ROUTERBOOT) += route
|
||||||
|
+@@ -38,9 +38,91 @@ obj-$(CONFIG_ATH79_ROUTERBOOT) += route
|
||||||
|
#
|
||||||
|
# Machines
|
||||||
|
#
|
||||||
|
@@ -1079,6 +1089,7 @@
|
||||||
|
+obj-$(CONFIG_ATH79_MACH_AW_NR580) += mach-aw-nr580.o
|
||||||
|
+obj-$(CONFIG_ATH79_MACH_BHU_BXU2000N2_A)+= mach-bhu-bxu2000n2-a.o
|
||||||
|
+obj-$(CONFIG_ATH79_MACH_CAP4200AG) += mach-cap4200ag.o
|
||||||
|
++obj-$(CONFIG_ATH79_MACH_CPE510) += mach-cpe510.o
|
||||||
|
obj-$(CONFIG_ATH79_MACH_DB120) += mach-db120.o
|
||||||
|
+obj-$(CONFIG_ATH79_MACH_DIR_505_A1) += mach-dir-505-a1.o
|
||||||
|
+obj-$(CONFIG_ATH79_MACH_DIR_600_A1) += mach-dir-600-a1.o
|
@ -68,6 +68,7 @@ CONFIG_ATH79_MACH_AP136=y
|
|||||||
CONFIG_ATH79_MACH_AP81=y
|
CONFIG_ATH79_MACH_AP81=y
|
||||||
CONFIG_ATH79_MACH_AP83=y
|
CONFIG_ATH79_MACH_AP83=y
|
||||||
CONFIG_ATH79_MACH_AP96=y
|
CONFIG_ATH79_MACH_AP96=y
|
||||||
|
CONFIG_ATH79_MACH_CPE510=y
|
||||||
CONFIG_ATH79_MACH_DB120=y
|
CONFIG_ATH79_MACH_DB120=y
|
||||||
CONFIG_ATH79_MACH_PB42=y
|
CONFIG_ATH79_MACH_PB42=y
|
||||||
CONFIG_ATH79_MACH_PB44=y
|
CONFIG_ATH79_MACH_PB44=y
|
||||||
|
@ -2,6 +2,13 @@
|
|||||||
|
|
||||||
## TP-Link
|
## TP-Link
|
||||||
|
|
||||||
|
# CPE210/220/510/520
|
||||||
|
$(eval $(call GluonProfile,CPE510,rssileds))
|
||||||
|
$(eval $(call GluonModel,CPE510,cpe210-220-510-520-squashfs,tp-link-cpe210-v1.0))
|
||||||
|
$(eval $(call GluonModel,CPE510,cpe210-220-510-520-squashfs,tp-link-cpe220-v1.0))
|
||||||
|
$(eval $(call GluonModel,CPE510,cpe210-220-510-520-squashfs,tp-link-cpe510-v1.0))
|
||||||
|
$(eval $(call GluonModel,CPE510,cpe210-220-510-520-squashfs,tp-link-cpe520-v1.0))
|
||||||
|
|
||||||
# TL-WR703N v1
|
# TL-WR703N v1
|
||||||
$(eval $(call GluonProfile,TLWR703))
|
$(eval $(call GluonProfile,TLWR703))
|
||||||
$(eval $(call GluonModel,TLWR703,tl-wr703n-v1-squashfs,tp-link-tl-wr703n-v1))
|
$(eval $(call GluonModel,TLWR703,tl-wr703n-v1-squashfs,tp-link-tl-wr703n-v1))
|
||||||
|
Loading…
Reference in New Issue
Block a user