ar71xx: add 64kb bootloader mtd parser for tplinkpart
authorJohn Crispin <john@openwrt.org>
Mon, 17 Aug 2015 06:23:49 +0000 (06:23 +0000)
committerJohn Crispin <john@openwrt.org>
Mon, 17 Aug 2015 06:23:49 +0000 (06:23 +0000)
Signed-off-by: Weijie Gao <hackpascal@gmail.com>
This patch adds flash layout parser for TP-Link firmwares which have a 64kb
bootloader.

This is used for TP-Link TL-WDR6500 v2.

SVN-Revision: 46662

target/linux/ar71xx/files/drivers/mtd/tplinkpart.c

index ab952b63e95be78e1c9390e5e7be136cb01e25d1..ac1efa1c22ed59fb77ef2597585ba6e8021d9e0d 100644 (file)
 
 #define TPLINK_NUM_PARTS       5
 #define TPLINK_HEADER_V1       0x01000000
+#define TPLINK_HEADER_V2       0x02000000
 #define MD5SUM_LEN             16
 
 #define TPLINK_ART_LEN         0x10000
 #define TPLINK_KERNEL_OFFS     0x20000
+#define TPLINK_64K_KERNEL_OFFS 0x10000
 
 struct tplink_fw_header {
        uint32_t        version;        /* header version */
@@ -70,7 +72,7 @@ tplink_read_header(struct mtd_info *mtd, size_t offset)
 
        /* sanity checks */
        t = be32_to_cpu(header->version);
-       if (t != TPLINK_HEADER_V1)
+       if ((t != TPLINK_HEADER_V1) && (t != TPLINK_HEADER_V2))
                goto err_free_header;
 
        t = be32_to_cpu(header->kernel_ofs);
@@ -106,14 +108,14 @@ static int tplink_check_rootfs_magic(struct mtd_info *mtd, size_t offset)
        return 0;
 }
 
-static int tplink_parse_partitions(struct mtd_info *master,
+static int tplink_parse_partitions_offset(struct mtd_info *master,
                                   struct mtd_partition **pparts,
-                                  struct mtd_part_parser_data *data)
+                                  struct mtd_part_parser_data *data,
+                                  size_t offset)
 {
        struct mtd_partition *parts;
        struct tplink_fw_header *header;
        int nr_parts;
-       size_t offset;
        size_t art_offset;
        size_t rootfs_offset;
        size_t squashfs_offset;
@@ -126,8 +128,6 @@ static int tplink_parse_partitions(struct mtd_info *master,
                goto err;
        }
 
-       offset = TPLINK_KERNEL_OFFS;
-
        header = tplink_read_header(master, offset);
        if (!header) {
                pr_notice("%s: no TP-Link header found\n", master->name);
@@ -180,15 +180,38 @@ err:
        return ret;
 }
 
+static int tplink_parse_partitions(struct mtd_info *master,
+                                  struct mtd_partition **pparts,
+                                  struct mtd_part_parser_data *data)
+{
+       return tplink_parse_partitions_offset(master, pparts, data,
+                                             TPLINK_KERNEL_OFFS);
+}
+
+static int tplink_parse_64k_partitions(struct mtd_info *master,
+                                  struct mtd_partition **pparts,
+                                  struct mtd_part_parser_data *data)
+{
+       return tplink_parse_partitions_offset(master, pparts, data,
+                                             TPLINK_64K_KERNEL_OFFS);
+}
+
 static struct mtd_part_parser tplink_parser = {
        .owner          = THIS_MODULE,
        .parse_fn       = tplink_parse_partitions,
        .name           = "tp-link",
 };
 
+static struct mtd_part_parser tplink_64k_parser = {
+       .owner          = THIS_MODULE,
+       .parse_fn       = tplink_parse_64k_partitions,
+       .name           = "tp-link-64k",
+};
+
 static int __init tplink_parser_init(void)
 {
        register_mtd_parser(&tplink_parser);
+       register_mtd_parser(&tplink_64k_parser);
 
        return 0;
 }