• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/firmware-utils/src/tplink-safeloader.c

  1 // SPDX-License-Identifier: BSD-2-Clause
  2 /*
  3   Copyright (c) 2014, Matthias Schiffer <mschiffer@universe-factory.net>
  4   All rights reserved.
  5 */
  6 
  7 
  8 /*
  9    tplink-safeloader
 10 
 11    Image generation tool for the TP-LINK SafeLoader as seen on
 12    TP-LINK Pharos devices (CPE210/220/510/520)
 13 */
 14 
 15 
 16 #include <assert.h>
 17 #include <ctype.h>
 18 #include <errno.h>
 19 #include <stdbool.h>
 20 #include <stddef.h>
 21 #include <stdio.h>
 22 #include <stdint.h>
 23 #include <stdlib.h>
 24 #include <string.h>
 25 #include <time.h>
 26 #include <unistd.h>
 27 
 28 #include <arpa/inet.h>
 29 
 30 #include <sys/types.h>
 31 #include <sys/stat.h>
 32 #include <limits.h>
 33 
 34 #include "md5.h"
 35 
 36 
 37 #define ALIGN(x,a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); })
 38 
 39 
 40 #define MAX_PARTITIONS  32
 41 
 42 /** An image partition table entry */
 43 struct image_partition_entry {
 44         const char *name;
 45         size_t size;
 46         uint8_t *data;
 47 };
 48 
 49 /** A flash partition table entry */
 50 struct flash_partition_entry {
 51         const char *name;
 52         uint32_t base;
 53         uint32_t size;
 54 };
 55 
 56 /** Flash partition names table entry */
 57 struct factory_partition_names {
 58         const char *partition_table;
 59         const char *soft_ver;
 60         const char *os_image;
 61         const char *support_list;
 62         const char *file_system;
 63         const char *extra_para;
 64 };
 65 
 66 /** Partition trailing padding definitions
 67  * Values 0x00 to 0xff are reserved to indicate the padding value
 68  * Values from 0x100 are reserved to indicate other behaviour */
 69 enum partition_trail_value {
 70         PART_TRAIL_00   = 0x00,
 71         PART_TRAIL_FF   = 0xff,
 72         PART_TRAIL_MAX  = 0xff,
 73         PART_TRAIL_NONE = 0x100
 74 };
 75 
 76 /** soft-version value overwrite types
 77  * The default (for an uninitialised soft_ver field) is to use the numerical
 78  * version number "0.0.0"
 79  */
 80 enum soft_ver_type {
 81         SOFT_VER_TYPE_NUMERIC = 0,
 82         SOFT_VER_TYPE_TEXT = 1,
 83 };
 84 
 85 /** Firmware layout description */
 86 struct device_info {
 87         const char *id;
 88         const char *vendor;
 89         const char *support_list;
 90         enum partition_trail_value part_trail;
 91         struct {
 92                 enum soft_ver_type type;
 93                 union {
 94                         const char *text;
 95                         uint8_t num[3];
 96                 };
 97         } soft_ver;
 98         uint32_t soft_ver_compat_level;
 99         struct flash_partition_entry partitions[MAX_PARTITIONS+1];
100         const char *first_sysupgrade_partition;
101         const char *last_sysupgrade_partition;
102         struct factory_partition_names partition_names;
103 };
104 
105 #define SOFT_VER_TEXT(_t) {.type = SOFT_VER_TYPE_TEXT, .text = _t}
106 #define SOFT_VER_NUMERIC(_maj, _min, _patch) {  \
107                 .type = SOFT_VER_TYPE_NUMERIC,          \
108                 .num = {_maj, _min, _patch}}
109 #define SOFT_VER_DEFAULT SOFT_VER_NUMERIC(0, 0, 0)
110 
111 struct __attribute__((__packed__)) meta_header {
112         uint32_t length;
113         uint32_t zero;
114 };
115 
116 /** The content of the soft-version structure */
117 struct __attribute__((__packed__)) soft_version {
118         uint8_t pad1;
119         uint8_t version_major;
120         uint8_t version_minor;
121         uint8_t version_patch;
122         uint8_t year_hi;
123         uint8_t year_lo;
124         uint8_t month;
125         uint8_t day;
126         uint32_t rev;
127         uint32_t compat_level;
128 };
129 
130 /*
131  * Safeloader image type
132  *   Safeloader images contain a 0x14 byte preamble with image size (big endian
133  *   UINT32) and md5 checksum (16 bytes).
134  *
135  * SAFEFLOADER_TYPE_DEFAULT
136  *   Standard preamble with size including preamble length, and checksum.
137  *   Header of 0x1000 bytes, contents of which are not specified.
138  *   Payload starts at offset 0x1014.
139  *
140  * SAFELOADER_TYPE_VENDOR
141  *   Standard preamble with size including preamble length, and checksum.
142  *   Header contains up to 0x1000 bytes of vendor data, starting with a big endian
143  *   UINT32 size, followed by that number of bytes containing (text) data.
144  *   Padded with 0xFF. Payload starts at offset 0x1014.
145  *
146  * SAFELOADER_TYPE_CLOUD
147  *   Standard preamble with size including preamble length, and checksum.
148  *   Followed by the 'fw-type:Cloud' string and some (unknown) data.
149  *   Payload starts at offset 0x1014.
150  *
151  * SAFELOADER_TYPE_QNEW
152  *   Reversed order preamble, with (apparent) md5 checksum before the image
153  *   size. The size does not include the preamble length.
154  *   Header starts with 0x3C bytes, starting with the string '?NEW' (format not
155  *   understood). Then another 0x1000 bytes follow, with the data payload
156  *   starting at 0x1050.
157  */
158 enum safeloader_image_type {
159         SAFELOADER_TYPE_DEFAULT,
160         SAFELOADER_TYPE_VENDOR,
161         SAFELOADER_TYPE_CLOUD,
162         SAFELOADER_TYPE_QNEW,
163 };
164 
165 /* Internal representation of safeloader image data */
166 struct safeloader_image_info {
167         enum safeloader_image_type type;
168         size_t payload_offset;
169         struct flash_partition_entry entries[MAX_PARTITIONS];
170 };
171 
172 #define SAFELOADER_PREAMBLE_SIZE        0x14
173 #define SAFELOADER_HEADER_SIZE          0x1000
174 #define SAFELOADER_PAYLOAD_OFFSET       (SAFELOADER_PREAMBLE_SIZE + SAFELOADER_HEADER_SIZE)
175 
176 #define SAFELOADER_QNEW_HEADER_SIZE     0x3C
177 #define SAFELOADER_QNEW_PAYLOAD_OFFSET  \
178         (SAFELOADER_PREAMBLE_SIZE + SAFELOADER_QNEW_HEADER_SIZE + SAFELOADER_HEADER_SIZE)
179 
180 #define SAFELOADER_PAYLOAD_TABLE_SIZE   0x800
181 
182 static const uint8_t jffs2_eof_mark[4] = {0xde, 0xad, 0xc0, 0xde};
183 
184 
185 /**
186    Salt for the MD5 hash
187 
188    Fortunately, TP-LINK seems to use the same salt for most devices which use
189    the new image format.
190 */
191 static const uint8_t md5_salt[16] = {
192         0x7a, 0x2b, 0x15, 0xed,
193         0x9b, 0x98, 0x59, 0x6d,
194         0xe5, 0x04, 0xab, 0x44,
195         0xac, 0x2a, 0x9f, 0x4e,
196 };
197 
198 
199 /** Firmware layout table */
200 static struct device_info boards[] = {
201         /** Firmware layout for the CPE210/220 V1 */
202         {
203                 .id     = "CPE210",
204                 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
205                 .support_list =
206                         "SupportList:\r\n"
207                         "CPE210(TP-LINK|UN|N300-2):1.0\r\n"
208                         "CPE210(TP-LINK|UN|N300-2):1.1\r\n"
209                         "CPE210(TP-LINK|US|N300-2):1.1\r\n"
210                         "CPE210(TP-LINK|EU|N300-2):1.1\r\n"
211                         "CPE220(TP-LINK|UN|N300-2):1.1\r\n"
212                         "CPE220(TP-LINK|US|N300-2):1.1\r\n"
213                         "CPE220(TP-LINK|EU|N300-2):1.1\r\n",
214                 .part_trail = 0xff,
215                 .soft_ver = SOFT_VER_DEFAULT,
216 
217                 .partitions = {
218                         {"fs-uboot", 0x00000, 0x20000},
219                         {"partition-table", 0x20000, 0x02000},
220                         {"default-mac", 0x30000, 0x00020},
221                         {"product-info", 0x31100, 0x00100},
222                         {"signature", 0x32000, 0x00400},
223                         {"firmware", 0x40000, 0x770000},
224                         {"soft-version", 0x7b0000, 0x00100},
225                         {"support-list", 0x7b1000, 0x00400},
226                         {"user-config", 0x7c0000, 0x10000},
227                         {"default-config", 0x7d0000, 0x10000},
228                         {"log", 0x7e0000, 0x10000},
229                         {"radio", 0x7f0000, 0x10000},
230                         {NULL, 0, 0}
231                 },
232 
233                 .first_sysupgrade_partition = "os-image",
234                 .last_sysupgrade_partition = "support-list",
235         },
236 
237         /** Firmware layout for the CPE210 V2 */
238         {
239                 .id     = "CPE210V2",
240                 .vendor = "CPE210(TP-LINK|UN|N300-2|00000000):2.0\r\n",
241                 .support_list =
242                         "SupportList:\r\n"
243                         "CPE210(TP-LINK|EU|N300-2|00000000):2.0\r\n"
244                         "CPE210(TP-LINK|EU|N300-2|45550000):2.0\r\n"
245                         "CPE210(TP-LINK|EU|N300-2|55530000):2.0\r\n"
246                         "CPE210(TP-LINK|UN|N300-2|00000000):2.0\r\n"
247                         "CPE210(TP-LINK|UN|N300-2|45550000):2.0\r\n"
248                         "CPE210(TP-LINK|UN|N300-2|55530000):2.0\r\n"
249                         "CPE210(TP-LINK|US|N300-2|55530000):2.0\r\n"
250                         "CPE210(TP-LINK|UN|N300-2):2.0\r\n"
251                         "CPE210(TP-LINK|EU|N300-2):2.0\r\n"
252                         "CPE210(TP-LINK|US|N300-2):2.0\r\n",
253                 .part_trail = 0xff,
254                 .soft_ver = SOFT_VER_DEFAULT,
255 
256                 .partitions = {
257                         {"fs-uboot", 0x00000, 0x20000},
258                         {"partition-table", 0x20000, 0x02000},
259                         {"default-mac", 0x30000, 0x00020},
260                         {"product-info", 0x31100, 0x00100},
261                         {"device-info", 0x31400, 0x00400},
262                         {"signature", 0x32000, 0x00400},
263                         {"device-id", 0x33000, 0x00100},
264                         {"firmware", 0x40000, 0x770000},
265                         {"soft-version", 0x7b0000, 0x00100},
266                         {"support-list", 0x7b1000, 0x01000},
267                         {"user-config", 0x7c0000, 0x10000},
268                         {"default-config", 0x7d0000, 0x10000},
269                         {"log", 0x7e0000, 0x10000},
270                         {"radio", 0x7f0000, 0x10000},
271                         {NULL, 0, 0}
272                 },
273 
274                 .first_sysupgrade_partition = "os-image",
275                 .last_sysupgrade_partition = "support-list",
276         },
277 
278         /** Firmware layout for the CPE210 V3 */
279         {
280                 .id     = "CPE210V3",
281                 .vendor = "CPE210(TP-LINK|UN|N300-2|00000000):3.0\r\n",
282                 .support_list =
283                         "SupportList:\r\n"
284                         "CPE210(TP-LINK|EU|N300-2|45550000):3.0\r\n"
285                         "CPE210(TP-LINK|UN|N300-2|00000000):3.0\r\n"
286                         "CPE210(TP-LINK|US|N300-2|55530000):3.0\r\n"
287                         "CPE210(TP-LINK|UN|N300-2):3.0\r\n"
288                         "CPE210(TP-LINK|EU|N300-2):3.0\r\n"
289                         "CPE210(TP-LINK|EU|N300-2|45550000):3.1\r\n"
290                         "CPE210(TP-LINK|UN|N300-2|00000000):3.1\r\n"
291                         "CPE210(TP-LINK|US|N300-2|55530000):3.1\r\n"
292                         "CPE210(TP-LINK|EU|N300-2|45550000):3.20\r\n"
293                         "CPE210(TP-LINK|UN|N300-2|00000000):3.20\r\n"
294                         "CPE210(TP-LINK|US|N300-2|55530000):3.20\r\n",
295                 .part_trail = 0xff,
296                 .soft_ver = SOFT_VER_DEFAULT,
297 
298                 .partitions = {
299                         {"fs-uboot", 0x00000, 0x20000},
300                         {"partition-table", 0x20000, 0x01000},
301                         {"default-mac", 0x30000, 0x00020},
302                         {"product-info", 0x31100, 0x00100},
303                         {"device-info", 0x31400, 0x00400},
304                         {"signature", 0x32000, 0x00400},
305                         {"device-id", 0x33000, 0x00100},
306                         {"firmware", 0x40000, 0x770000},
307                         {"soft-version", 0x7b0000, 0x00100},
308                         {"support-list", 0x7b1000, 0x01000},
309                         {"user-config", 0x7c0000, 0x10000},
310                         {"default-config", 0x7d0000, 0x10000},
311                         {"log", 0x7e0000, 0x10000},
312                         {"radio", 0x7f0000, 0x10000},
313                         {NULL, 0, 0}
314                 },
315 
316                 .first_sysupgrade_partition = "os-image",
317                 .last_sysupgrade_partition = "support-list",
318         },
319 
320         /** Firmware layout for the CPE220 V2 */
321         {
322                 .id     = "CPE220V2",
323                 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
324                 .support_list =
325                         "SupportList:\r\n"
326                         "CPE220(TP-LINK|EU|N300-2|00000000):2.0\r\n"
327                         "CPE220(TP-LINK|EU|N300-2|45550000):2.0\r\n"
328                         "CPE220(TP-LINK|EU|N300-2|55530000):2.0\r\n"
329                         "CPE220(TP-LINK|UN|N300-2|00000000):2.0\r\n"
330                         "CPE220(TP-LINK|UN|N300-2|45550000):2.0\r\n"
331                         "CPE220(TP-LINK|UN|N300-2|55530000):2.0\r\n"
332                         "CPE220(TP-LINK|US|N300-2|55530000):2.0\r\n"
333                         "CPE220(TP-LINK|UN|N300-2):2.0\r\n"
334                         "CPE220(TP-LINK|EU|N300-2):2.0\r\n"
335                         "CPE220(TP-LINK|US|N300-2):2.0\r\n",
336                 .part_trail = 0xff,
337                 .soft_ver = SOFT_VER_DEFAULT,
338 
339                 .partitions = {
340                         {"fs-uboot", 0x00000, 0x20000},
341                         {"partition-table", 0x20000, 0x02000},
342                         {"default-mac", 0x30000, 0x00020},
343                         {"product-info", 0x31100, 0x00100},
344                         {"signature", 0x32000, 0x00400},
345                         {"firmware", 0x40000, 0x770000},
346                         {"soft-version", 0x7b0000, 0x00100},
347                         {"support-list", 0x7b1000, 0x00400},
348                         {"user-config", 0x7c0000, 0x10000},
349                         {"default-config", 0x7d0000, 0x10000},
350                         {"log", 0x7e0000, 0x10000},
351                         {"radio", 0x7f0000, 0x10000},
352                         {NULL, 0, 0}
353                 },
354 
355                 .first_sysupgrade_partition = "os-image",
356                 .last_sysupgrade_partition = "support-list",
357         },
358 
359         /** Firmware layout for the CPE220 V3 */
360         {
361                 .id     = "CPE220V3",
362                 .vendor = "CPE220(TP-LINK|UN|N300-2|00000000):3.0\r\n",
363                 .support_list =
364                         "SupportList:\r\n"
365                         "CPE220(TP-LINK|EU|N300-2|00000000):3.0\r\n"
366                         "CPE220(TP-LINK|EU|N300-2|45550000):3.0\r\n"
367                         "CPE220(TP-LINK|EU|N300-2|55530000):3.0\r\n"
368                         "CPE220(TP-LINK|UN|N300-2|00000000):3.0\r\n"
369                         "CPE220(TP-LINK|UN|N300-2|45550000):3.0\r\n"
370                         "CPE220(TP-LINK|UN|N300-2|55530000):3.0\r\n"
371                         "CPE220(TP-LINK|US|N300-2|55530000):3.0\r\n"
372                         "CPE220(TP-LINK|UN|N300-2):3.0\r\n"
373                         "CPE220(TP-LINK|EU|N300-2):3.0\r\n"
374                         "CPE220(TP-LINK|US|N300-2):3.0\r\n",
375                 .part_trail = 0xff,
376                 .soft_ver = SOFT_VER_DEFAULT,
377 
378                 .partitions = {
379                         {"fs-uboot", 0x00000, 0x20000},
380                         {"partition-table", 0x20000, 0x02000},
381                         {"default-mac", 0x30000, 0x00020},
382                         {"product-info", 0x31100, 0x00100},
383                         {"device-info", 0x31400, 0x00400},
384                         {"signature", 0x32000, 0x00400},
385                         {"device-id", 0x33000, 0x00100},
386                         {"firmware", 0x40000, 0x770000},
387                         {"soft-version", 0x7b0000, 0x00100},
388                         {"support-list", 0x7b1000, 0x01000},
389                         {"user-config", 0x7c0000, 0x10000},
390                         {"default-config", 0x7d0000, 0x10000},
391                         {"log", 0x7e0000, 0x10000},
392                         {"radio", 0x7f0000, 0x10000},
393                         {NULL, 0, 0}
394                 },
395 
396                 .first_sysupgrade_partition = "os-image",
397                 .last_sysupgrade_partition = "support-list",
398         },
399 
400         /** Firmware layout for the CPE510/520 V1 */
401         {
402                 .id     = "CPE510",
403                 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
404                 .support_list =
405                         "SupportList:\r\n"
406                         "CPE510(TP-LINK|UN|N300-5):1.0\r\n"
407                         "CPE510(TP-LINK|UN|N300-5):1.1\r\n"
408                         "CPE510(TP-LINK|UN|N300-5):1.1\r\n"
409                         "CPE510(TP-LINK|US|N300-5):1.1\r\n"
410                         "CPE510(TP-LINK|CA|N300-5):1.1\r\n"
411                         "CPE510(TP-LINK|EU|N300-5):1.1\r\n"
412                         "CPE520(TP-LINK|UN|N300-5):1.1\r\n"
413                         "CPE520(TP-LINK|US|N300-5):1.1\r\n"
414                         "CPE520(TP-LINK|EU|N300-5):1.1\r\n",
415                 .part_trail = 0xff,
416                 .soft_ver = SOFT_VER_DEFAULT,
417 
418                 .partitions = {
419                         {"fs-uboot", 0x00000, 0x20000},
420                         {"partition-table", 0x20000, 0x02000},
421                         {"default-mac", 0x30000, 0x00020},
422                         {"product-info", 0x31100, 0x00100},
423                         {"signature", 0x32000, 0x00400},
424                         {"firmware", 0x40000, 0x770000},
425                         {"soft-version", 0x7b0000, 0x00100},
426                         {"support-list", 0x7b1000, 0x00400},
427                         {"user-config", 0x7c0000, 0x10000},
428                         {"default-config", 0x7d0000, 0x10000},
429                         {"log", 0x7e0000, 0x10000},
430                         {"radio", 0x7f0000, 0x10000},
431                         {NULL, 0, 0}
432                 },
433 
434                 .first_sysupgrade_partition = "os-image",
435                 .last_sysupgrade_partition = "support-list",
436         },
437 
438         /** Firmware layout for the CPE510 V2 */
439         {
440                 .id     = "CPE510V2",
441                 .vendor = "CPE510(TP-LINK|UN|N300-5):2.0\r\n",
442                 .support_list =
443                         "SupportList:\r\n"
444                         "CPE510(TP-LINK|EU|N300-5|00000000):2.0\r\n"
445                         "CPE510(TP-LINK|EU|N300-5|45550000):2.0\r\n"
446                         "CPE510(TP-LINK|EU|N300-5|55530000):2.0\r\n"
447                         "CPE510(TP-LINK|UN|N300-5|00000000):2.0\r\n"
448                         "CPE510(TP-LINK|UN|N300-5|45550000):2.0\r\n"
449                         "CPE510(TP-LINK|UN|N300-5|55530000):2.0\r\n"
450                         "CPE510(TP-LINK|US|N300-5|00000000):2.0\r\n"
451                         "CPE510(TP-LINK|US|N300-5|45550000):2.0\r\n"
452                         "CPE510(TP-LINK|US|N300-5|55530000):2.0\r\n"
453                         "CPE510(TP-LINK|UN|N300-5):2.0\r\n"
454                         "CPE510(TP-LINK|EU|N300-5):2.0\r\n"
455                         "CPE510(TP-LINK|US|N300-5):2.0\r\n",
456                 .part_trail = 0xff,
457                 .soft_ver = SOFT_VER_DEFAULT,
458 
459                 .partitions = {
460                         {"fs-uboot", 0x00000, 0x20000},
461                         {"partition-table", 0x20000, 0x02000},
462                         {"default-mac", 0x30000, 0x00020},
463                         {"product-info", 0x31100, 0x00100},
464                         {"signature", 0x32000, 0x00400},
465                         {"firmware", 0x40000, 0x770000},
466                         {"soft-version", 0x7b0000, 0x00100},
467                         {"support-list", 0x7b1000, 0x00400},
468                         {"user-config", 0x7c0000, 0x10000},
469                         {"default-config", 0x7d0000, 0x10000},
470                         {"log", 0x7e0000, 0x10000},
471                         {"radio", 0x7f0000, 0x10000},
472                         {NULL, 0, 0}
473                 },
474 
475                 .first_sysupgrade_partition = "os-image",
476                 .last_sysupgrade_partition = "support-list",
477         },
478 
479         /** Firmware layout for the CPE510 V3 */
480         {
481                 .id     = "CPE510V3",
482                 .vendor = "CPE510(TP-LINK|UN|N300-5):3.0\r\n",
483                 .support_list =
484                         "SupportList:\r\n"
485                         "CPE510(TP-LINK|EU|N300-5|00000000):3.0\r\n"
486                         "CPE510(TP-LINK|EU|N300-5|45550000):3.0\r\n"
487                         "CPE510(TP-LINK|EU|N300-5|55530000):3.0\r\n"
488                         "CPE510(TP-LINK|UN|N300-5|00000000):3.0\r\n"
489                         "CPE510(TP-LINK|UN|N300-5|45550000):3.0\r\n"
490                         "CPE510(TP-LINK|UN|N300-5|55530000):3.0\r\n"
491                         "CPE510(TP-LINK|US|N300-5|00000000):3.0\r\n"
492                         "CPE510(TP-LINK|US|N300-5|45550000):3.0\r\n"
493                         "CPE510(TP-LINK|US|N300-5|55530000):3.0\r\n"
494                         "CPE510(TP-LINK|UN|N300-5):3.0\r\n"
495                         "CPE510(TP-LINK|EU|N300-5):3.0\r\n"
496                         "CPE510(TP-LINK|US|N300-5):3.0\r\n"
497                         "CPE510(TP-LINK|UN|N300-5|00000000):3.20\r\n"
498                         "CPE510(TP-LINK|US|N300-5|55530000):3.20\r\n"
499                         "CPE510(TP-LINK|EU|N300-5|45550000):3.20\r\n",
500                 .part_trail = 0xff,
501                 .soft_ver = SOFT_VER_DEFAULT,
502 
503                 .partitions = {
504                         {"fs-uboot", 0x00000, 0x20000},
505                         {"partition-table", 0x20000, 0x02000},
506                         {"default-mac", 0x30000, 0x00020},
507                         {"product-info", 0x31100, 0x00100},
508                         {"signature", 0x32000, 0x00400},
509                         {"firmware", 0x40000, 0x770000},
510                         {"soft-version", 0x7b0000, 0x00100},
511                         {"support-list", 0x7b1000, 0x00400},
512                         {"user-config", 0x7c0000, 0x10000},
513                         {"default-config", 0x7d0000, 0x10000},
514                         {"log", 0x7e0000, 0x10000},
515                         {"radio", 0x7f0000, 0x10000},
516                         {NULL, 0, 0}
517                 },
518 
519                 .first_sysupgrade_partition = "os-image",
520                 .last_sysupgrade_partition = "support-list",
521         },
522 
523         /** Firmware layout for the CPE605V1 */
524         {
525                 .id     = "CPE605V1",
526                 .vendor = "CPE605(TP-LINK|UN|N150-5):1.0\r\n",
527                 .support_list =
528                         "SupportList:\r\n"
529                         "CPE605(TP-LINK|UN|N150-5|00000000):1.0\r\n"
530                         "CPE605(TP-LINK|EU|N150-5|45550000):1.0\r\n"
531                         "CPE605(TP-LINK|US|N150-5|55530000):1.0\r\n",
532                 .part_trail = 0x00,
533                 .soft_ver = SOFT_VER_DEFAULT,
534 
535                 .partitions = {
536                         {"fs-uboot", 0x00000, 0x20000},
537                         {"partition-table", 0x20000, 0x02000},
538                         {"default-mac", 0x30000, 0x00020},
539                         {"serial-number", 0x30100, 0x00020},
540                         {"product-info", 0x31100, 0x00100},
541                         {"device-info", 0x31400, 0x00400},
542                         {"signature", 0x32000, 0x00400},
543                         {"device-id", 0x33000, 0x00100},
544                         {"firmware", 0x40000, 0x770000},
545                         {"soft-version", 0x7b0000, 0x00100},
546                         {"support-list", 0x7b1000, 0x01000},
547                         {"user-config", 0x7c0000, 0x10000},
548                         {"default-config", 0x7d0000, 0x10000},
549                         {"log", 0x7e0000, 0x10000},
550                         {"radio", 0x7f0000, 0x10000},
551                         {NULL, 0, 0}
552                 },
553 
554                 .first_sysupgrade_partition = "os-image",
555                 .last_sysupgrade_partition = "support-list",
556         },
557 
558         /** Firmware layout for the CPE610V1 */
559         {
560                 .id     = "CPE610V1",
561                 .vendor = "CPE610(TP-LINK|UN|N300-5|00000000):1.0\r\n",
562                 .support_list =
563                         "SupportList:\r\n"
564                         "CPE610(TP-LINK|EU|N300-5|00000000):1.0\r\n"
565                         "CPE610(TP-LINK|EU|N300-5|45550000):1.0\r\n"
566                         "CPE610(TP-LINK|EU|N300-5|55530000):1.0\r\n"
567                         "CPE610(TP-LINK|UN|N300-5|00000000):1.0\r\n"
568                         "CPE610(TP-LINK|UN|N300-5|45550000):1.0\r\n"
569                         "CPE610(TP-LINK|UN|N300-5|55530000):1.0\r\n"
570                         "CPE610(TP-LINK|US|N300-5|55530000):1.0\r\n"
571                         "CPE610(TP-LINK|UN|N300-5):1.0\r\n"
572                         "CPE610(TP-LINK|EU|N300-5):1.0\r\n"
573                         "CPE610(TP-LINK|US|N300-5):1.0\r\n",
574                 .part_trail = 0xff,
575                 .soft_ver = SOFT_VER_DEFAULT,
576 
577                 .partitions = {
578                         {"fs-uboot", 0x00000, 0x20000},
579                         {"partition-table", 0x20000, 0x02000},
580                         {"default-mac", 0x30000, 0x00020},
581                         {"product-info", 0x31100, 0x00100},
582                         {"signature", 0x32000, 0x00400},
583                         {"firmware", 0x40000, 0x770000},
584                         {"soft-version", 0x7b0000, 0x00100},
585                         {"support-list", 0x7b1000, 0x00400},
586                         {"user-config", 0x7c0000, 0x10000},
587                         {"default-config", 0x7d0000, 0x10000},
588                         {"log", 0x7e0000, 0x10000},
589                         {"radio", 0x7f0000, 0x10000},
590                         {NULL, 0, 0}
591                 },
592 
593                 .first_sysupgrade_partition = "os-image",
594                 .last_sysupgrade_partition = "support-list",
595         },
596 
597         /** Firmware layout for the CPE610V2 */
598         {
599                 .id     = "CPE610V2",
600                 .vendor = "CPE610(TP-LINK|UN|N300-5|00000000):2.0\r\n",
601                 .support_list =
602                         "SupportList:\r\n"
603                         "CPE610(TP-LINK|EU|N300-5|00000000):2.0\r\n"
604                         "CPE610(TP-LINK|EU|N300-5|45550000):2.0\r\n"
605                         "CPE610(TP-LINK|EU|N300-5|55530000):2.0\r\n"
606                         "CPE610(TP-LINK|UN|N300-5|00000000):2.0\r\n"
607                         "CPE610(TP-LINK|UN|N300-5|45550000):2.0\r\n"
608                         "CPE610(TP-LINK|UN|N300-5|55530000):2.0\r\n"
609                         "CPE610(TP-LINK|US|N300-5|55530000):2.0\r\n"
610                         "CPE610(TP-LINK|UN|N300-5):2.0\r\n"
611                         "CPE610(TP-LINK|EU|N300-5):2.0\r\n"
612                         "CPE610(TP-LINK|US|N300-5):2.0\r\n",
613                 .part_trail = 0xff,
614                 .soft_ver = SOFT_VER_DEFAULT,
615 
616                 .partitions = {
617                         {"fs-uboot", 0x00000, 0x20000},
618                         {"partition-table", 0x20000, 0x02000},
619                         {"default-mac", 0x30000, 0x00020},
620                         {"product-info", 0x31100, 0x00100},
621                         {"signature", 0x32000, 0x00400},
622                         {"firmware", 0x40000, 0x770000},
623                         {"soft-version", 0x7b0000, 0x00100},
624                         {"support-list", 0x7b1000, 0x00400},
625                         {"user-config", 0x7c0000, 0x10000},
626                         {"default-config", 0x7d0000, 0x10000},
627                         {"log", 0x7e0000, 0x10000},
628                         {"radio", 0x7f0000, 0x10000},
629                         {NULL, 0, 0}
630                 },
631 
632                 .first_sysupgrade_partition = "os-image",
633                 .last_sysupgrade_partition = "support-list",
634         },
635         /** Firmware layout for the CPE710 V1 */
636         {
637                 .id     = "CPE710V1",
638                 .vendor = "CPE710(TP-LINK|UN|AC866-5|00000000):1.0\r\n",
639                 .support_list =
640                         "SupportList:\r\n"
641                         "CPE710(TP-LINK|UN|AC866-5|00000000):1.0\r\n"
642                         "CPE710(TP-LINK|EU|AC866-5|45550000):1.0\r\n"
643                         "CPE710(TP-LINK|US|AC866-5|55530000):1.0\r\n"
644                         "CPE710(TP-LINK|UN|AC866-5):1.0\r\n"
645                         "CPE710(TP-LINK|EU|AC866-5):1.0\r\n"
646                         "CPE710(TP-LINK|US|AC866-5):1.0\r\n",
647                 .part_trail = 0xff,
648                 .soft_ver = SOFT_VER_DEFAULT,
649 
650                 .partitions = {
651                         {"fs-uboot", 0x00000, 0x50000},
652                         {"partition-table", 0x50000, 0x02000},
653                         {"default-mac", 0x60000, 0x00020},
654                         {"serial-number", 0x60100, 0x00020},
655                         {"product-info", 0x61100, 0x00100},
656                         {"device-info", 0x61400, 0x00400},
657                         {"signature", 0x62000, 0x00400},
658                         {"device-id", 0x63000, 0x00100},
659                         {"firmware", 0x70000, 0xf40000},
660                         {"soft-version", 0xfb0000, 0x00100},
661                         {"support-list", 0xfb1000, 0x01000},
662                         {"user-config", 0xfc0000, 0x10000},
663                         {"default-config", 0xfd0000, 0x10000},
664                         {"log", 0xfe0000, 0x10000},
665                         {"radio", 0xff0000, 0x10000},
666                         {NULL, 0, 0}
667                 },
668 
669                 .first_sysupgrade_partition = "os-image",
670                 .last_sysupgrade_partition = "support-list",
671         },
672 
673         {
674                 .id     = "WBS210",
675                 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
676                 .support_list =
677                         "SupportList:\r\n"
678                         "WBS210(TP-LINK|UN|N300-2):1.20\r\n"
679                         "WBS210(TP-LINK|US|N300-2):1.20\r\n"
680                         "WBS210(TP-LINK|EU|N300-2):1.20\r\n",
681                 .part_trail = 0xff,
682                 .soft_ver = SOFT_VER_DEFAULT,
683 
684                 .partitions = {
685                         {"fs-uboot", 0x00000, 0x20000},
686                         {"partition-table", 0x20000, 0x02000},
687                         {"default-mac", 0x30000, 0x00020},
688                         {"product-info", 0x31100, 0x00100},
689                         {"signature", 0x32000, 0x00400},
690                         {"firmware", 0x40000, 0x770000},
691                         {"soft-version", 0x7b0000, 0x00100},
692                         {"support-list", 0x7b1000, 0x00400},
693                         {"user-config", 0x7c0000, 0x10000},
694                         {"default-config", 0x7d0000, 0x10000},
695                         {"log", 0x7e0000, 0x10000},
696                         {"radio", 0x7f0000, 0x10000},
697                         {NULL, 0, 0}
698                 },
699 
700                 .first_sysupgrade_partition = "os-image",
701                 .last_sysupgrade_partition = "support-list",
702         },
703 
704         {
705                 .id     = "WBS210V2",
706                 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
707                 .support_list =
708                         "SupportList:\r\n"
709                         "WBS210(TP-LINK|UN|N300-2|00000000):2.0\r\n"
710                         "WBS210(TP-LINK|US|N300-2|55530000):2.0\r\n"
711                         "WBS210(TP-LINK|EU|N300-2|45550000):2.0\r\n",
712                 .part_trail = 0xff,
713                 .soft_ver = SOFT_VER_DEFAULT,
714 
715                 .partitions = {
716                         {"fs-uboot", 0x00000, 0x20000},
717                         {"partition-table", 0x20000, 0x02000},
718                         {"default-mac", 0x30000, 0x00020},
719                         {"product-info", 0x31100, 0x00100},
720                         {"signature", 0x32000, 0x00400},
721                         {"firmware", 0x40000, 0x770000},
722                         {"soft-version", 0x7b0000, 0x00100},
723                         {"support-list", 0x7b1000, 0x00400},
724                         {"user-config", 0x7c0000, 0x10000},
725                         {"default-config", 0x7d0000, 0x10000},
726                         {"log", 0x7e0000, 0x10000},
727                         {"radio", 0x7f0000, 0x10000},
728                         {NULL, 0, 0}
729                 },
730 
731                 .first_sysupgrade_partition = "os-image",
732                 .last_sysupgrade_partition = "support-list",
733         },
734 
735         {
736                 .id     = "WBS510",
737                 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
738                 .support_list =
739                         "SupportList:\r\n"
740                         "WBS510(TP-LINK|UN|N300-5):1.20\r\n"
741                         "WBS510(TP-LINK|US|N300-5):1.20\r\n"
742                         "WBS510(TP-LINK|EU|N300-5):1.20\r\n"
743                         "WBS510(TP-LINK|CA|N300-5):1.20\r\n",
744                 .part_trail = 0xff,
745                 .soft_ver = SOFT_VER_DEFAULT,
746 
747                 .partitions = {
748                         {"fs-uboot", 0x00000, 0x20000},
749                         {"partition-table", 0x20000, 0x02000},
750                         {"default-mac", 0x30000, 0x00020},
751                         {"product-info", 0x31100, 0x00100},
752                         {"signature", 0x32000, 0x00400},
753                         {"firmware", 0x40000, 0x770000},
754                         {"soft-version", 0x7b0000, 0x00100},
755                         {"support-list", 0x7b1000, 0x00400},
756                         {"user-config", 0x7c0000, 0x10000},
757                         {"default-config", 0x7d0000, 0x10000},
758                         {"log", 0x7e0000, 0x10000},
759                         {"radio", 0x7f0000, 0x10000},
760                         {NULL, 0, 0}
761                 },
762 
763                 .first_sysupgrade_partition = "os-image",
764                 .last_sysupgrade_partition = "support-list",
765         },
766 
767         {
768                 .id     = "WBS510V2",
769                 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
770                 .support_list =
771                         "SupportList:\r\n"
772                         "WBS510(TP-LINK|UN|N300-5|00000000):2.0\r\n"
773                         "WBS510(TP-LINK|US|N300-5|55530000):2.0\r\n"
774                         "WBS510(TP-LINK|EU|N300-5|45550000):2.0\r\n"
775                         "WBS510(TP-LINK|CA|N300-5|43410000):2.0\r\n",
776                 .part_trail = 0xff,
777                 .soft_ver = SOFT_VER_DEFAULT,
778 
779                 .partitions = {
780                         {"fs-uboot", 0x00000, 0x20000},
781                         {"partition-table", 0x20000, 0x02000},
782                         {"default-mac", 0x30000, 0x00020},
783                         {"product-info", 0x31100, 0x00100},
784                         {"signature", 0x32000, 0x00400},
785                         {"firmware", 0x40000, 0x770000},
786                         {"soft-version", 0x7b0000, 0x00100},
787                         {"support-list", 0x7b1000, 0x00400},
788                         {"user-config", 0x7c0000, 0x10000},
789                         {"default-config", 0x7d0000, 0x10000},
790                         {"log", 0x7e0000, 0x10000},
791                         {"radio", 0x7f0000, 0x10000},
792                         {NULL, 0, 0}
793                 },
794 
795                 .first_sysupgrade_partition = "os-image",
796                 .last_sysupgrade_partition = "support-list",
797         },
798 
799         /** Firmware layout for the AD7200 */
800         {
801                 .id = "AD7200",
802                 .vendor = "",
803                 .support_list =
804                         "SupportList:\r\n"
805                         "{product_name:AD7200,product_ver:1.0.0,special_id:00000000}\r\n",
806                 .part_trail = 0x00,
807                 .soft_ver = SOFT_VER_DEFAULT,
808 
809                 .partitions = {
810                         {"SBL1", 0x00000, 0x20000},
811                         {"MIBIB", 0x20000, 0x20000},
812                         {"SBL2", 0x40000, 0x20000},
813                         {"SBL3", 0x60000, 0x30000},
814                         {"DDRCONFIG", 0x90000, 0x10000},
815                         {"SSD", 0xa0000, 0x10000},
816                         {"TZ", 0xb0000, 0x30000},
817                         {"RPM", 0xe0000, 0x20000},
818                         {"fs-uboot", 0x100000, 0x70000},
819                         {"uboot-env", 0x170000, 0x40000},
820                         {"radio", 0x1b0000, 0x40000},
821                         {"os-image", 0x1f0000, 0x400000},
822                         {"file-system", 0x5f0000, 0x1900000},
823                         {"default-mac", 0x1ef0000, 0x00200},
824                         {"pin", 0x1ef0200, 0x00200},
825                         {"device-id", 0x1ef0400, 0x00200},
826                         {"product-info", 0x1ef0600, 0x0fa00},
827                         {"partition-table", 0x1f00000, 0x10000},
828                         {"soft-version", 0x1f10000, 0x10000},
829                         {"support-list", 0x1f20000, 0x10000},
830                         {"profile", 0x1f30000, 0x10000},
831                         {"default-config", 0x1f40000, 0x10000},
832                         {"user-config", 0x1f50000, 0x40000},
833                         {"qos-db", 0x1f90000, 0x40000},
834                         {"usb-config", 0x1fd0000, 0x10000},
835                         {"log", 0x1fe0000, 0x20000},
836                         {NULL, 0, 0}
837                 },
838 
839                 .first_sysupgrade_partition = "os-image",
840                 .last_sysupgrade_partition = "file-system"
841         },
842 
843         /** Firmware layout for the C2600 */
844         {
845                 .id     = "C2600",
846                 .vendor = "",
847                 .support_list =
848                         "SupportList:\r\n"
849                         "{product_name:Archer C2600,product_ver:1.0.0,special_id:00000000}\r\n",
850                 .part_trail = 0x00,
851                 .soft_ver = SOFT_VER_DEFAULT,
852 
853                 /**
854                     We use a bigger os-image partition than the stock images (and thus
855                     smaller file-system), as our kernel doesn't fit in the stock firmware's
856                     2 MB os-image since kernel 4.14.
857                 */
858                 .partitions = {
859                         {"SBL1", 0x00000, 0x20000},
860                         {"MIBIB", 0x20000, 0x20000},
861                         {"SBL2", 0x40000, 0x20000},
862                         {"SBL3", 0x60000, 0x30000},
863                         {"DDRCONFIG", 0x90000, 0x10000},
864                         {"SSD", 0xa0000, 0x10000},
865                         {"TZ", 0xb0000, 0x30000},
866                         {"RPM", 0xe0000, 0x20000},
867                         {"fs-uboot", 0x100000, 0x70000},
868                         {"uboot-env", 0x170000, 0x40000},
869                         {"radio", 0x1b0000, 0x40000},
870                         {"os-image", 0x1f0000, 0x400000}, /* Stock: base 0x1f0000 size 0x200000 */
871                         {"file-system", 0x5f0000, 0x1900000}, /* Stock: base 0x3f0000 size 0x1b00000 */
872                         {"default-mac", 0x1ef0000, 0x00200},
873                         {"pin", 0x1ef0200, 0x00200},
874                         {"product-info", 0x1ef0400, 0x0fc00},
875                         {"partition-table", 0x1f00000, 0x10000},
876                         {"soft-version", 0x1f10000, 0x10000},
877                         {"support-list", 0x1f20000, 0x10000},
878                         {"profile", 0x1f30000, 0x10000},
879                         {"default-config", 0x1f40000, 0x10000},
880                         {"user-config", 0x1f50000, 0x40000},
881                         {"qos-db", 0x1f90000, 0x40000},
882                         {"usb-config", 0x1fd0000, 0x10000},
883                         {"log", 0x1fe0000, 0x20000},
884                         {NULL, 0, 0}
885                 },
886 
887                 .first_sysupgrade_partition = "os-image",
888                 .last_sysupgrade_partition = "file-system"
889         },
890 
891         /** Firmware layout for the A7-V5 */
892         {
893                 .id     = "ARCHER-A7-V5",
894                 .support_list =
895                         "SupportList:\n"
896                         "{product_name:Archer A7,product_ver:5.0.0,special_id:45550000}\n"
897                         "{product_name:Archer A7,product_ver:5.0.0,special_id:55530000}\n"
898                         "{product_name:Archer A7,product_ver:5.0.0,special_id:43410000}\n"
899                         "{product_name:Archer A7,product_ver:5.0.0,special_id:4A500000}\n"
900                         "{product_name:Archer A7,product_ver:5.0.0,special_id:54570000}\n"
901                         "{product_name:Archer A7,product_ver:5.0.0,special_id:52550000}\n",
902                 .part_trail = 0x00,
903                 .soft_ver = SOFT_VER_TEXT("soft_ver:7.0.0\n"),
904 
905                 /* We're using a dynamic kernel/rootfs split here */
906                 .partitions = {
907                         {"factory-boot", 0x00000, 0x20000},
908                         {"fs-uboot", 0x20000, 0x20000},
909                         {"firmware", 0x40000, 0xec0000},        /* Stock: name os-image base 0x40000 size 0x120000 */
910                                                                 /* Stock: name file-system base 0x160000 size 0xda0000 */
911                         {"default-mac", 0xf40000, 0x00200},
912                         {"pin", 0xf40200, 0x00200},
913                         {"device-id", 0xf40400, 0x00100},
914                         {"product-info", 0xf40500, 0x0fb00},
915                         {"soft-version", 0xf50000, 0x00100},
916                         {"extra-para", 0xf51000, 0x01000},
917                         {"support-list", 0xf52000, 0x0a000},
918                         {"profile", 0xf5c000, 0x04000},
919                         {"default-config", 0xf60000, 0x10000},
920                         {"user-config", 0xf70000, 0x40000},
921                         {"certificate", 0xfb0000, 0x10000},
922                         {"partition-table", 0xfc0000, 0x10000},
923                         {"log", 0xfd0000, 0x20000},
924                         {"radio", 0xff0000, 0x10000},
925                         {NULL, 0, 0}
926                 },
927 
928                 .first_sysupgrade_partition = "os-image",
929                 .last_sysupgrade_partition = "file-system",
930         },
931 
932         /** Firmware layout for the Archer A9 v6 */
933         {
934                 .id     = "ARCHER-A9-V6",
935                 .support_list =
936                         "SupportList:\n"
937                         "{product_name:Archer A9,product_ver:6.0,special_id:55530000}\n"
938                         "{product_name:Archer A9,product_ver:6.0,special_id:45550000}\n"
939                         "{product_name:Archer A9,product_ver:6.0,special_id:52550000}\n"
940                         "{product_name:Archer A9,product_ver:6.0,special_id:4A500000}\n"
941                         "{product_name:Archer C90,product_ver:6.0,special_id:55530000}\n",
942                 .part_trail = 0x00,
943                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.1.0\n"),
944 
945                 /* We're using a dynamic kernel/rootfs split here */
946                 .partitions = {
947                         {"factory-boot", 0x00000, 0x20000},
948                         {"fs-uboot", 0x20000, 0x20000},
949                         {"partition-table", 0x40000, 0x10000},
950                         {"radio", 0x50000, 0x10000},
951                         {"default-mac", 0x60000, 0x00200},
952                         {"pin", 0x60200, 0x00200},
953                         {"device-id", 0x60400, 0x00100},
954                         {"product-info", 0x60500, 0x0fb00},
955                         {"soft-version", 0x70000, 0x01000},
956                         {"extra-para", 0x71000, 0x01000},
957                         {"support-list", 0x72000, 0x0a000},
958                         {"profile", 0x7c000, 0x04000},
959                         {"user-config", 0x80000, 0x10000},
960                         {"ap-config", 0x90000, 0x10000},
961                         {"apdef-config", 0xa0000, 0x10000},
962                         {"router-config", 0xb0000, 0x10000},
963                         {"firmware", 0xc0000, 0xf00000},        /* Stock: name os-image base 0xc0000 size 0x120000 */
964                                                                 /* Stock: name file-system base 0x1e0000 size 0xde0000 */
965                         {"log", 0xfc0000, 0x20000},
966                         {"certificate", 0xfe0000, 0x10000},
967                         {"default-config", 0xff0000, 0x10000},
968                         {NULL, 0, 0}
969                 },
970 
971                 .first_sysupgrade_partition = "os-image",
972                 .last_sysupgrade_partition = "file-system",
973         },
974 
975         /** Firmware layout for the Archer AX23 v1 */
976         {
977                 .id     = "ARCHER-AX23-V1",
978                 .vendor = "",
979                 .support_list =
980                         "SupportList:\n"
981                         "{product_name:Archer AX23,product_ver:1.0,special_id:45550000}\n"
982                         "{product_name:Archer AX23,product_ver:1.0,special_id:4A500000}\n"
983                         "{product_name:Archer AX23,product_ver:1.0,special_id:4B520000}\n"
984                         "{product_name:Archer AX23,product_ver:1.0,special_id:52550000}\n"
985                         "{product_name:Archer AX23,product_ver:1.0.0,special_id:43410000}\n"
986                         "{product_name:Archer AX23,product_ver:1.0.0,special_id:54570000}\n"
987                         "{product_name:Archer AX23,product_ver:1.0.0,special_id:55530000}\n"
988                         "{product_name:Archer AX23,product_ver:1.20,special_id:45550000}\n"
989                         "{product_name:Archer AX23,product_ver:1.20,special_id:4A500000}\n"
990                         "{product_name:Archer AX23,product_ver:1.20,special_id:52550000}\n"
991                         "{product_name:Archer AX23,product_ver:1.20,special_id:55530000}\n"
992                         "{product_name:Archer AX1800,product_ver:1.20,special_id:45550000}\n"
993                         "{product_name:Archer AX1800,product_ver:1.20,special_id:52550000}\n",
994                 .part_trail = 0x00,
995                 .soft_ver = SOFT_VER_TEXT("soft_ver:3.0.3\n"),
996 
997                 .partitions = {
998                         {"fs-uboot", 0x00000, 0x40000},
999                         {"firmware", 0x40000, 0xf60000},
1000                         {"default-mac", 0xfa0000, 0x00200},
1001                         {"pin", 0xfa0200, 0x00100},
1002                         {"device-id", 0xfa0300, 0x00100},
1003                         {"product-info", 0xfa0400, 0x0fc00},
1004                         {"default-config", 0xfb0000, 0x08000},
1005                         {"ap-def-config", 0xfb8000, 0x08000},
1006                         {"user-config", 0xfc0000, 0x0a000},
1007                         {"ag-config", 0xfca000, 0x04000},
1008                         {"certificate", 0xfce000, 0x02000},
1009                         {"ap-config", 0xfd0000, 0x06000},
1010                         {"router-config", 0xfd6000, 0x06000},
1011                         {"favicon", 0xfdc000, 0x02000},
1012                         {"logo", 0xfde000, 0x02000},
1013                         {"partition-table", 0xfe0000, 0x00800},
1014                         {"soft-version", 0xfe0800, 0x00100},
1015                         {"support-list", 0xfe0900, 0x00400},
1016                         {"profile", 0xfe0d00, 0x03000},
1017                         {"extra-para", 0xfe3d00, 0x00100},
1018                         {"radio", 0xff0000, 0x10000},
1019                         {NULL, 0, 0}
1020                 },
1021                 .first_sysupgrade_partition = "os-image",
1022                 .last_sysupgrade_partition = "file-system",
1023         },
1024         /** Firmware layout for the C2v3 */
1025         {
1026                 .id     = "ARCHER-C2-V3",
1027                 .support_list =
1028                         "SupportList:\n"
1029                         "{product_name:ArcherC2,product_ver:3.0.0,special_id:00000000}\n"
1030                         "{product_name:ArcherC2,product_ver:3.0.0,special_id:55530000}\n"
1031                         "{product_name:ArcherC2,product_ver:3.0.0,special_id:45550000}\n",
1032                 .part_trail = 0x00,
1033                 .soft_ver = SOFT_VER_TEXT("soft_ver:3.0.1\n"),
1034 
1035                 /** We're using a dynamic kernel/rootfs split here */
1036 
1037                 .partitions = {
1038                         {"factory-boot", 0x00000, 0x20000},
1039                         {"fs-uboot", 0x20000, 0x10000},
1040                         {"firmware", 0x30000, 0x7a0000},
1041                         {"user-config", 0x7d0000, 0x04000},
1042                         {"default-mac", 0x7e0000, 0x00100},
1043                         {"device-id", 0x7e0100, 0x00100},
1044                         {"extra-para", 0x7e0200, 0x00100},
1045                         {"pin", 0x7e0300, 0x00100},
1046                         {"support-list", 0x7e0400, 0x00400},
1047                         {"soft-version", 0x7e0800, 0x00400},
1048                         {"product-info", 0x7e0c00, 0x01400},
1049                         {"partition-table", 0x7e2000, 0x01000},
1050                         {"profile", 0x7e3000, 0x01000},
1051                         {"default-config", 0x7e4000, 0x04000},
1052                         {"merge-config", 0x7ec000, 0x02000},
1053                         {"qos-db", 0x7ee000, 0x02000},
1054                         {"radio", 0x7f0000, 0x10000},
1055                         {NULL, 0, 0}
1056                 },
1057 
1058                 .first_sysupgrade_partition = "os-image",
1059                 .last_sysupgrade_partition = "file-system",
1060         },
1061 
1062         /** Firmware layout for the C25v1 */
1063         {
1064                 .id     = "ARCHER-C25-V1",
1065                 .support_list =
1066                         "SupportList:\n"
1067                         "{product_name:ArcherC25,product_ver:1.0.0,special_id:00000000}\n"
1068                         "{product_name:ArcherC25,product_ver:1.0.0,special_id:55530000}\n"
1069                         "{product_name:ArcherC25,product_ver:1.0.0,special_id:45550000}\n",
1070                 .part_trail = 0x00,
1071                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
1072 
1073                 /* We're using a dynamic kernel/rootfs split here */
1074                 .partitions = {
1075                         {"factory-boot", 0x00000, 0x20000},
1076                         {"fs-uboot", 0x20000, 0x10000},
1077                         {"firmware", 0x30000, 0x7a0000},        /* Stock: name os-image base 0x30000 size 0x100000 */
1078                                                                 /* Stock: name file-system base 0x130000 size 0x6a0000 */
1079                         {"user-config", 0x7d0000, 0x04000},
1080                         {"default-mac", 0x7e0000, 0x00100},
1081                         {"device-id", 0x7e0100, 0x00100},
1082                         {"extra-para", 0x7e0200, 0x00100},
1083                         {"pin", 0x7e0300, 0x00100},
1084                         {"support-list", 0x7e0400, 0x00400},
1085                         {"soft-version", 0x7e0800, 0x00400},
1086                         {"product-info", 0x7e0c00, 0x01400},
1087                         {"partition-table", 0x7e2000, 0x01000},
1088                         {"profile", 0x7e3000, 0x01000},
1089                         {"default-config", 0x7e4000, 0x04000},
1090                         {"merge-config", 0x7ec000, 0x02000},
1091                         {"qos-db", 0x7ee000, 0x02000},
1092                         {"radio", 0x7f0000, 0x10000},
1093                         {NULL, 0, 0}
1094                 },
1095 
1096                 .first_sysupgrade_partition = "os-image",
1097                 .last_sysupgrade_partition = "file-system",
1098         },
1099 
1100         /** Firmware layout for the C58v1 */
1101         {
1102                 .id     = "ARCHER-C58-V1",
1103                 .vendor = "",
1104                 .support_list =
1105                         "SupportList:\r\n"
1106                         "{product_name:Archer C58,product_ver:1.0.0,special_id:00000000}\r\n"
1107                         "{product_name:Archer C58,product_ver:1.0.0,special_id:45550000}\r\n"
1108                         "{product_name:Archer C58,product_ver:1.0.0,special_id:55530000}\r\n",
1109                 .part_trail = 0x00,
1110                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
1111 
1112                 .partitions = {
1113                         {"fs-uboot", 0x00000, 0x10000},
1114                         {"default-mac", 0x10000, 0x00200},
1115                         {"pin", 0x10200, 0x00200},
1116                         {"product-info", 0x10400, 0x00100},
1117                         {"partition-table", 0x10500, 0x00800},
1118                         {"soft-version", 0x11300, 0x00200},
1119                         {"support-list", 0x11500, 0x00100},
1120                         {"device-id", 0x11600, 0x00100},
1121                         {"profile", 0x11700, 0x03900},
1122                         {"default-config", 0x15000, 0x04000},
1123                         {"user-config", 0x19000, 0x04000},
1124                         {"firmware", 0x20000, 0x7c8000},
1125                         {"certyficate", 0x7e8000, 0x08000},
1126                         {"radio", 0x7f0000, 0x10000},
1127                         {NULL, 0, 0}
1128                 },
1129 
1130                 .first_sysupgrade_partition = "os-image",
1131                 .last_sysupgrade_partition = "file-system",
1132         },
1133 
1134         /** Firmware layout for the C59v1 */
1135         {
1136                 .id     = "ARCHER-C59-V1",
1137                 .vendor = "",
1138                 .support_list =
1139                         "SupportList:\r\n"
1140                         "{product_name:Archer C59,product_ver:1.0.0,special_id:00000000}\r\n"
1141                         "{product_name:Archer C59,product_ver:1.0.0,special_id:43410000}\r\n"
1142                         "{product_name:Archer C59,product_ver:1.0.0,special_id:45550000}\r\n"
1143                         "{product_name:Archer C59,product_ver:1.0.0,special_id:52550000}\r\n"
1144                         "{product_name:Archer C59,product_ver:1.0.0,special_id:55530000}\r\n",
1145                 .part_trail = 0x00,
1146                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
1147 
1148                 /* We're using a dynamic kernel/rootfs split here */
1149                 .partitions = {
1150                         {"fs-uboot", 0x00000, 0x10000},
1151                         {"default-mac", 0x10000, 0x00200},
1152                         {"pin", 0x10200, 0x00200},
1153                         {"device-id", 0x10400, 0x00100},
1154                         {"product-info", 0x10500, 0x0fb00},
1155                         {"firmware", 0x20000, 0xe30000},
1156                         {"partition-table", 0xe50000, 0x10000},
1157                         {"soft-version", 0xe60000, 0x10000},
1158                         {"support-list", 0xe70000, 0x10000},
1159                         {"profile", 0xe80000, 0x10000},
1160                         {"default-config", 0xe90000, 0x10000},
1161                         {"user-config", 0xea0000, 0x40000},
1162                         {"usb-config", 0xee0000, 0x10000},
1163                         {"certificate", 0xef0000, 0x10000},
1164                         {"qos-db", 0xf00000, 0x40000},
1165                         {"log", 0xfe0000, 0x10000},
1166                         {"radio", 0xff0000, 0x10000},
1167                         {NULL, 0, 0}
1168                 },
1169 
1170                 .first_sysupgrade_partition = "os-image",
1171                 .last_sysupgrade_partition = "file-system",
1172         },
1173 
1174         /** Firmware layout for the C59v2 */
1175         {
1176                 .id     = "ARCHER-C59-V2",
1177                 .vendor = "",
1178                 .support_list =
1179                         "SupportList:\r\n"
1180                         "{product_name:Archer C59,product_ver:2.0.0,special_id:00000000}\r\n"
1181                         "{product_name:Archer C59,product_ver:2.0.0,special_id:43410000}\r\n"
1182                         "{product_name:Archer C59,product_ver:2.0.0,special_id:45550000}\r\n"
1183                         "{product_name:Archer C59,product_ver:2.0.0,special_id:55530000}\r\n",
1184                 .part_trail = 0x00,
1185                 .soft_ver = SOFT_VER_TEXT("soft_ver:2.0.0 Build 20161206 rel.7303\n"),
1186 
1187                 /** We're using a dynamic kernel/rootfs split here */
1188                 .partitions = {
1189                         {"factory-boot", 0x00000, 0x20000},
1190                         {"fs-uboot", 0x20000, 0x10000},
1191                         {"default-mac", 0x30000, 0x00200},
1192                         {"pin", 0x30200, 0x00200},
1193                         {"device-id", 0x30400, 0x00100},
1194                         {"product-info", 0x30500, 0x0fb00},
1195                         {"firmware", 0x40000, 0xe10000},
1196                         {"partition-table", 0xe50000, 0x10000},
1197                         {"soft-version", 0xe60000, 0x10000},
1198                         {"support-list", 0xe70000, 0x10000},
1199                         {"profile", 0xe80000, 0x10000},
1200                         {"default-config", 0xe90000, 0x10000},
1201                         {"user-config", 0xea0000, 0x40000},
1202                         {"usb-config", 0xee0000, 0x10000},
1203                         {"certificate", 0xef0000, 0x10000},
1204                         {"extra-para", 0xf00000, 0x10000},
1205                         {"qos-db", 0xf10000, 0x30000},
1206                         {"log", 0xfe0000, 0x10000},
1207                         {"radio", 0xff0000, 0x10000},
1208                         {NULL, 0, 0}
1209                 },
1210 
1211                 .first_sysupgrade_partition = "os-image",
1212                 .last_sysupgrade_partition = "file-system",
1213         },
1214 
1215         /** Firmware layout for the Archer C6 v2 (EU/RU/JP) */
1216         {
1217                 .id     = "ARCHER-C6-V2",
1218                 .vendor = "",
1219                 .support_list =
1220                         "SupportList:\r\n"
1221                         "{product_name:Archer A6,product_ver:2.0.0,special_id:45550000}\r\n"
1222                         "{product_name:Archer A6,product_ver:2.0.0,special_id:52550000}\r\n"
1223                         "{product_name:Archer C6,product_ver:2.0.0,special_id:45550000}\r\n"
1224                         "{product_name:Archer C6,product_ver:2.0.0,special_id:52550000}\r\n"
1225                         "{product_name:Archer C6,product_ver:2.0.0,special_id:4A500000}\r\n",
1226                 .part_trail = 0x00,
1227                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.9.1\n"),
1228 
1229                 .partitions = {
1230                         {"fs-uboot", 0x00000, 0x20000},
1231                         {"default-mac", 0x20000, 0x00200},
1232                         {"pin", 0x20200, 0x00100},
1233                         {"product-info", 0x20300, 0x00200},
1234                         {"device-id", 0x20500, 0x0fb00},
1235                         {"firmware", 0x30000, 0x7a9400},
1236                         {"soft-version", 0x7d9400, 0x00100},
1237                         {"extra-para", 0x7d9500, 0x00100},
1238                         {"support-list", 0x7d9600, 0x00200},
1239                         {"profile", 0x7d9800, 0x03000},
1240                         {"default-config", 0x7dc800, 0x03000},
1241                         {"partition-table", 0x7df800, 0x00800},
1242                         {"user-config", 0x7e0000, 0x0c000},
1243                         {"certificate", 0x7ec000, 0x04000},
1244                         {"radio", 0x7f0000, 0x10000},
1245                         {NULL, 0, 0}
1246                 },
1247 
1248                 .first_sysupgrade_partition = "os-image",
1249                 .last_sysupgrade_partition = "file-system",
1250         },
1251 
1252         /** Firmware layout for the Archer C6 v2 (US) and A6 v2 (US/TW) */
1253         {
1254                 .id     = "ARCHER-C6-V2-US",
1255                 .vendor = "",
1256                 .support_list =
1257                         "SupportList:\n"
1258                         "{product_name:Archer A6,product_ver:2.0.0,special_id:55530000}\n"
1259                         "{product_name:Archer A6,product_ver:2.0.0,special_id:54570000}\n"
1260                         "{product_name:Archer C6,product_ver:2.0.0,special_id:55530000}\n",
1261                 .part_trail = 0x00,
1262                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.9.1\n"),
1263 
1264                 .partitions = {
1265                         {"factory-boot", 0x00000, 0x20000},
1266                         {"default-mac", 0x20000, 0x00200},
1267                         {"pin", 0x20200, 0x00100},
1268                         {"product-info", 0x20300, 0x00200},
1269                         {"device-id", 0x20500, 0x0fb00},
1270                         {"fs-uboot", 0x30000, 0x20000},
1271                         {"firmware", 0x50000, 0xf89400},
1272                         {"soft-version", 0xfd9400, 0x00100},
1273                         {"extra-para", 0xfd9500, 0x00100},
1274                         {"support-list", 0xfd9600, 0x00200},
1275                         {"profile", 0xfd9800, 0x03000},
1276                         {"default-config", 0xfdc800, 0x03000},
1277                         {"partition-table", 0xfdf800, 0x00800},
1278                         {"user-config", 0xfe0000, 0x0c000},
1279                         {"certificate", 0xfec000, 0x04000},
1280                         {"radio", 0xff0000, 0x10000},
1281                         {NULL, 0, 0}
1282                 },
1283                 .first_sysupgrade_partition = "os-image",
1284                 .last_sysupgrade_partition = "file-system",
1285         },
1286         /** Firmware layout for the Archer C6 v3 */
1287         {
1288                 .id     = "ARCHER-C6-V3",
1289                 .vendor = "",
1290                 .support_list =
1291                         "SupportList:\n"
1292                         "{product_name:Archer C6,product_ver:3.20,special_id:55530000}"
1293                         "{product_name:Archer C6,product_ver:3.20,special_id:45550000}"
1294                         "{product_name:Archer C6,product_ver:3.20,special_id:52550000}"
1295                         "{product_name:Archer C6,product_ver:3.20,special_id:4A500000}"
1296                         "{product_name:Archer C6,product_ver:3.20,special_id:4B520000}"
1297                         "{product_name:Archer C6,product_ver:3.0.0,special_id:42520000}",
1298                 .part_trail = 0x00,
1299                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.9\n"),
1300 
1301                 .partitions = {
1302                         {"fs-uboot", 0x00000, 0x40000},
1303                         {"firmware", 0x40000, 0xf60000},
1304                         {"default-mac", 0xfa0000, 0x00200},
1305                         {"pin", 0xfa0200, 0x00100},
1306                         {"device-id", 0xfa0300, 0x00100},
1307                         {"product-info", 0xfa0400, 0x0fc00},
1308                         {"default-config", 0xfb0000, 0x08000},
1309                         {"ap-def-config", 0xfb8000, 0x08000},
1310                         {"user-config", 0xfc0000, 0x0a000},
1311                         {"ag-config", 0xfca000, 0x04000},
1312                         {"certificate", 0xfce000, 0x02000},
1313                         {"ap-config", 0xfd0000, 0x06000},
1314                         {"router-config", 0xfd6000, 0x06000},
1315                         {"favicon", 0xfdc000, 0x02000},
1316                         {"logo", 0xfde000, 0x02000},
1317                         {"partition-table", 0xfe0000, 0x00800},
1318                         {"soft-version", 0xfe0800, 0x00100},
1319                         {"support-list", 0xfe0900, 0x00200},
1320                         {"profile", 0xfe0b00, 0x03000},
1321                         {"extra-para", 0xfe3b00, 0x00100},
1322                         {"radio", 0xff0000, 0x10000},
1323                         {NULL, 0, 0}
1324                 },
1325                 .first_sysupgrade_partition = "os-image",
1326                 .last_sysupgrade_partition = "file-system",
1327         },
1328         /** Firmware layout for the Archer A6 v3  */
1329         {
1330                 .id     = "ARCHER-A6-V3",
1331                 .vendor = "",
1332                 .support_list =
1333                         "SupportList:\n"
1334                         "{product_name:Archer A6,product_ver:3.0.0,special_id:43410000}\n"
1335                         "{product_name:Archer A6,product_ver:3.0.0,special_id:55530000}\n"
1336                         "{product_name:Archer A6,product_ver:3.0.0,special_id:54570000}\n"
1337                         "{product_name:Archer A6,product_ver:3.0.0,special_id:4A500000}\n"
1338                         "{product_name:Archer A6,product_ver:3.20,special_id:45550000}\n"
1339                         "{product_name:Archer A6,product_ver:3.20,special_id:52550000}\n",
1340                 .part_trail = 0x00,
1341                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.5\n"),
1342 
1343                 .partitions = {
1344                         {"fs-uboot", 0x00000, 0x40000},
1345                         {"firmware", 0x40000, 0xf60000},
1346                         {"default-mac", 0xfa0000, 0x00200},
1347                         {"pin", 0xfa0200, 0x00100},
1348                         {"device-id", 0xfa0300, 0x00100},
1349                         {"product-info", 0xfa0400, 0x0fc00},
1350                         {"default-config", 0xfb0000, 0x08000},
1351                         {"ap-def-config", 0xfb8000, 0x08000},
1352                         {"user-config", 0xfc0000, 0x0a000},
1353                         {"ag-config", 0xfca000, 0x04000},
1354                         {"certificate", 0xfce000, 0x02000},
1355                         {"ap-config", 0xfd0000, 0x06000},
1356                         {"router-config", 0xfd6000, 0x06000},
1357                         {"favicon", 0xfdc000, 0x02000},
1358                         {"logo", 0xfde000, 0x02000},
1359                         {"partition-table", 0xfe0000, 0x00800},
1360                         {"soft-version", 0xfe0800, 0x00100},
1361                         {"support-list", 0xfe0900, 0x00200},
1362                         {"profile", 0xfe0b00, 0x03000},
1363                         {"extra-para", 0xfe3b00, 0x00100},
1364                         {"radio", 0xff0000, 0x10000},
1365                         {NULL, 0, 0}
1366                 },
1367                 .first_sysupgrade_partition = "os-image",
1368                 .last_sysupgrade_partition = "file-system",
1369         },
1370         /** Firmware layout for the Archer C6U v1 */
1371         {
1372                 .id     = "ARCHER-C6U-V1",
1373                 .vendor = "",
1374                 .support_list =
1375                         "SupportList:\n"
1376                         "{product_name:Archer C6U,product_ver:1.0.0,special_id:45550000}\n"
1377                         "{product_name:Archer C6U,product_ver:1.0.0,special_id:52550000}\n",
1378                 .part_trail = 0x00,
1379                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.2\n"),
1380 
1381                 .partitions = {
1382                         {"fs-uboot", 0x00000, 0x40000},
1383                         {"firmware", 0x40000, 0xf60000},
1384                         {"default-mac", 0xfa0000, 0x00200},
1385                         {"pin", 0xfa0200, 0x00100},
1386                         {"device-id", 0xfa0300, 0x00100},
1387                         {"product-info", 0xfa0400, 0x0fc00},
1388                         {"default-config", 0xfb0000, 0x08000},
1389                         {"ap-def-config", 0xfb8000, 0x08000},
1390                         {"user-config", 0xfc0000, 0x0c000},
1391                         {"certificate", 0xfcc000, 0x04000},
1392                         {"ap-config", 0xfd0000, 0x08000},
1393                         {"router-config", 0xfd8000, 0x08000},
1394                         {"partition-table", 0xfe0000, 0x00800},
1395                         {"soft-version", 0xfe0800, 0x00100},
1396                         {"support-list", 0xfe0900, 0x00200},
1397                         {"profile", 0xfe0b00, 0x03000},
1398                         {"extra-para", 0xfe3b00, 0x00100},
1399                         {"radio", 0xff0000, 0x10000},
1400                         {NULL, 0, 0}
1401                 },
1402                 .first_sysupgrade_partition = "os-image",
1403                 .last_sysupgrade_partition = "file-system",
1404         },
1405         /** Firmware layout for the C60v1 */
1406         {
1407                 .id     = "ARCHER-C60-V1",
1408                 .vendor = "",
1409                 .support_list =
1410                         "SupportList:\r\n"
1411                         "{product_name:Archer C60,product_ver:1.0.0,special_id:00000000}\r\n"
1412                         "{product_name:Archer C60,product_ver:1.0.0,special_id:43410000}\r\n"
1413                         "{product_name:Archer C60,product_ver:1.0.0,special_id:45550000}\r\n"
1414                         "{product_name:Archer C60,product_ver:1.0.0,special_id:55530000}\r\n",
1415                 .part_trail = 0x00,
1416                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
1417 
1418                 .partitions = {
1419                         {"fs-uboot", 0x00000, 0x10000},
1420                         {"default-mac", 0x10000, 0x00200},
1421                         {"pin", 0x10200, 0x00200},
1422                         {"product-info", 0x10400, 0x00100},
1423                         {"partition-table", 0x10500, 0x00800},
1424                         {"soft-version", 0x11300, 0x00200},
1425                         {"support-list", 0x11500, 0x00100},
1426                         {"device-id", 0x11600, 0x00100},
1427                         {"profile", 0x11700, 0x03900},
1428                         {"default-config", 0x15000, 0x04000},
1429                         {"user-config", 0x19000, 0x04000},
1430                         {"firmware", 0x20000, 0x7c8000},
1431                         {"certyficate", 0x7e8000, 0x08000},
1432                         {"radio", 0x7f0000, 0x10000},
1433                         {NULL, 0, 0}
1434                 },
1435 
1436                 .first_sysupgrade_partition = "os-image",
1437                 .last_sysupgrade_partition = "file-system",
1438         },
1439 
1440         /** Firmware layout for the C60v2 */
1441         {
1442                 .id     = "ARCHER-C60-V2",
1443                 .vendor = "",
1444                 .support_list =
1445                         "SupportList:\r\n"
1446                         "{product_name:Archer C60,product_ver:2.0.0,special_id:42520000}\r\n"
1447                         "{product_name:Archer C60,product_ver:2.0.0,special_id:43410000}\r\n"
1448                         "{product_name:Archer C60,product_ver:2.0.0,special_id:45550000}\r\n"
1449                         "{product_name:Archer C60,product_ver:2.0.0,special_id:55530000}\r\n",
1450                 .part_trail = 0x00,
1451                 .soft_ver = SOFT_VER_TEXT("soft_ver:2.0.0\n"),
1452 
1453                 .partitions = {
1454                         {"factory-boot", 0x00000, 0x1fb00},
1455                         {"default-mac", 0x1fb00, 0x00200},
1456                         {"pin", 0x1fd00, 0x00100},
1457                         {"product-info", 0x1fe00, 0x00100},
1458                         {"device-id", 0x1ff00, 0x00100},
1459                         {"fs-uboot", 0x20000, 0x10000},
1460                         {"firmware", 0x30000, 0x7a0000},
1461                         {"soft-version", 0x7d9500, 0x00100},
1462                         {"support-list", 0x7d9600, 0x00100},
1463                         {"extra-para", 0x7d9700, 0x00100},
1464                         {"profile", 0x7d9800, 0x03000},
1465                         {"default-config", 0x7dc800, 0x03000},
1466                         {"partition-table", 0x7df800, 0x00800},
1467                         {"user-config", 0x7e0000, 0x0c000},
1468                         {"certificate", 0x7ec000, 0x04000},
1469                         {"radio", 0x7f0000, 0x10000},
1470                         {NULL, 0, 0}
1471                 },
1472 
1473                 .first_sysupgrade_partition = "os-image",
1474                 .last_sysupgrade_partition = "file-system",
1475         },
1476 
1477         /** Firmware layout for the C60v3 */
1478         {
1479                 .id     = "ARCHER-C60-V3",
1480                 .vendor = "",
1481                 .support_list =
1482                         "SupportList:\r\n"
1483                         "{product_name:Archer C60,product_ver:3.0.0,special_id:42520000}\r\n"
1484                         "{product_name:Archer C60,product_ver:3.0.0,special_id:43410000}\r\n"
1485                         "{product_name:Archer C60,product_ver:3.0.0,special_id:45550000}\r\n"
1486                         "{product_name:Archer C60,product_ver:3.0.0,special_id:55530000}\r\n",
1487                 .part_trail = 0x00,
1488                 .soft_ver = SOFT_VER_TEXT("soft_ver:3.0.0\n"),
1489 
1490                 .partitions = {
1491                         {"factory-boot", 0x00000, 0x1fb00},
1492                         {"default-mac", 0x1fb00, 0x00200},
1493                         {"pin", 0x1fd00, 0x00100},
1494                         {"product-info", 0x1fe00, 0x00100},
1495                         {"device-id", 0x1ff00, 0x00100},
1496                         {"fs-uboot", 0x20000, 0x10000},
1497                         {"firmware", 0x30000, 0x7a0000},
1498                         {"soft-version", 0x7d9500, 0x00100},
1499                         {"support-list", 0x7d9600, 0x00100},
1500                         {"extra-para", 0x7d9700, 0x00100},
1501                         {"profile", 0x7d9800, 0x03000},
1502                         {"default-config", 0x7dc800, 0x03000},
1503                         {"partition-table", 0x7df800, 0x00800},
1504                         {"user-config", 0x7e0000, 0x0c000},
1505                         {"certificate", 0x7ec000, 0x04000},
1506                         {"radio", 0x7f0000, 0x10000},
1507                         {NULL, 0, 0}
1508                 },
1509 
1510                 .first_sysupgrade_partition = "os-image",
1511                 .last_sysupgrade_partition = "file-system",
1512         },
1513 
1514         /** Firmware layout for the C5 */
1515         {
1516                 .id     = "ARCHER-C5-V2",
1517                 .vendor = "",
1518                 .support_list =
1519                         "SupportList:\r\n"
1520                         "{product_name:ArcherC5,product_ver:2.0.0,special_id:00000000}\r\n"
1521                         "{product_name:ArcherC5,product_ver:2.0.0,special_id:55530000}\r\n"
1522                         "{product_name:ArcherC5,product_ver:2.0.0,special_id:4A500000}\r\n", /* JP version */
1523                 .part_trail = 0x00,
1524                 .soft_ver = SOFT_VER_DEFAULT,
1525 
1526                 .partitions = {
1527                         {"fs-uboot", 0x00000, 0x40000},
1528                         {"os-image", 0x40000, 0x200000},
1529                         {"file-system", 0x240000, 0xc00000},
1530                         {"default-mac", 0xe40000, 0x00200},
1531                         {"pin", 0xe40200, 0x00200},
1532                         {"product-info", 0xe40400, 0x00200},
1533                         {"partition-table", 0xe50000, 0x10000},
1534                         {"soft-version", 0xe60000, 0x00200},
1535                         {"support-list", 0xe61000, 0x0f000},
1536                         {"profile", 0xe70000, 0x10000},
1537                         {"default-config", 0xe80000, 0x10000},
1538                         {"user-config", 0xe90000, 0x50000},
1539                         {"log", 0xee0000, 0x100000},
1540                         {"radio_bk", 0xfe0000, 0x10000},
1541                         {"radio", 0xff0000, 0x10000},
1542                         {NULL, 0, 0}
1543                 },
1544 
1545                 .first_sysupgrade_partition = "os-image",
1546                 .last_sysupgrade_partition = "file-system"
1547         },
1548 
1549         /** Firmware layout for the C7 */
1550         {
1551                 .id     = "ARCHER-C7-V4",
1552                 .support_list =
1553                         "SupportList:\n"
1554                         "{product_name:Archer C7,product_ver:4.0.0,special_id:00000000}\n"
1555                         "{product_name:Archer C7,product_ver:4.0.0,special_id:41550000}\n"
1556                         "{product_name:Archer C7,product_ver:4.0.0,special_id:45550000}\n"
1557                         "{product_name:Archer C7,product_ver:4.0.0,special_id:4B520000}\n"
1558                         "{product_name:Archer C7,product_ver:4.0.0,special_id:42520000}\n"
1559                         "{product_name:Archer C7,product_ver:4.0.0,special_id:4A500000}\n"
1560                         "{product_name:Archer C7,product_ver:4.0.0,special_id:52550000}\n"
1561                         "{product_name:Archer C7,product_ver:4.0.0,special_id:54570000}\n"
1562                         "{product_name:Archer C7,product_ver:4.0.0,special_id:55530000}\n"
1563                         "{product_name:Archer C7,product_ver:4.0.0,special_id:43410000}\n",
1564                 .part_trail = 0x00,
1565                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
1566 
1567                 /* We're using a dynamic kernel/rootfs split here */
1568                 .partitions = {
1569                         {"factory-boot", 0x00000, 0x20000},
1570                         {"fs-uboot", 0x20000, 0x20000},
1571                         {"firmware", 0x40000, 0xEC0000},        /* Stock: name os-image base 0x40000 size 0x120000 */
1572                                                                 /* Stock: name file-system base 0x160000 size 0xda0000 */
1573                         {"default-mac", 0xf00000, 0x00200},
1574                         {"pin", 0xf00200, 0x00200},
1575                         {"device-id", 0xf00400, 0x00100},
1576                         {"product-info", 0xf00500, 0x0fb00},
1577                         {"soft-version", 0xf10000, 0x00100},
1578                         {"extra-para", 0xf11000, 0x01000},
1579                         {"support-list", 0xf12000, 0x0a000},
1580                         {"profile", 0xf1c000, 0x04000},
1581                         {"default-config", 0xf20000, 0x10000},
1582                         {"user-config", 0xf30000, 0x40000},
1583                         {"qos-db", 0xf70000, 0x40000},
1584                         {"certificate", 0xfb0000, 0x10000},
1585                         {"partition-table", 0xfc0000, 0x10000},
1586                         {"log", 0xfd0000, 0x20000},
1587                         {"radio", 0xff0000, 0x10000},
1588                         {NULL, 0, 0}
1589                 },
1590 
1591                 .first_sysupgrade_partition = "os-image",
1592                 .last_sysupgrade_partition = "file-system",
1593         },
1594 
1595         /** Firmware layout for the C7 v5*/
1596         {
1597                 .id     = "ARCHER-C7-V5",
1598                 .support_list =
1599                         "SupportList:\n"
1600                         "{product_name:Archer C7,product_ver:5.0.0,special_id:00000000}\n"
1601                         "{product_name:Archer C7,product_ver:5.0.0,special_id:45550000}\n"
1602                         "{product_name:Archer C7,product_ver:5.0.0,special_id:55530000}\n"
1603                         "{product_name:Archer C7,product_ver:5.0.0,special_id:43410000}\n"
1604                         "{product_name:Archer C7,product_ver:5.0.0,special_id:4A500000}\n"
1605                         "{product_name:Archer C7,product_ver:5.0.0,special_id:54570000}\n"
1606                         "{product_name:Archer C7,product_ver:5.0.0,special_id:52550000}\n"
1607                         "{product_name:Archer C7,product_ver:5.0.0,special_id:4B520000}\n",
1608 
1609                 .part_trail = 0x00,
1610                 .soft_ver = SOFT_VER_TEXT("soft_ver:7.0.0\n"),
1611 
1612                 /* We're using a dynamic kernel/rootfs split here */
1613                 .partitions = {
1614                         {"factory-boot",    0x00000,  0x20000},
1615                         {"fs-uboot",        0x20000,  0x20000},
1616                         {"partition-table", 0x40000,  0x10000},
1617                         {"radio",           0x50000,  0x10000},
1618                         {"default-mac",     0x60000,  0x00200},
1619                         {"pin",             0x60200,  0x00200},
1620                         {"device-id",       0x60400,  0x00100},
1621                         {"product-info",    0x60500,  0x0fb00},
1622                         {"soft-version",    0x70000,  0x01000},
1623                         {"extra-para",      0x71000,  0x01000},
1624                         {"support-list",    0x72000,  0x0a000},
1625                         {"profile",         0x7c000,  0x04000},
1626                         {"user-config",     0x80000,  0x40000},
1627 
1628 
1629                         {"firmware",        0xc0000,  0xf00000},        /* Stock: name os-image base 0xc0000  size 0x120000 */
1630                                                                         /* Stock: name file-system base 0x1e0000 size 0xde0000 */
1631 
1632                         {"log",             0xfc0000, 0x20000},
1633                         {"certificate",     0xfe0000, 0x10000},
1634                         {"default-config",  0xff0000, 0x10000},
1635                         {NULL, 0, 0}
1636 
1637                 },
1638 
1639                 .first_sysupgrade_partition = "os-image",
1640                 .last_sysupgrade_partition = "file-system",
1641         },
1642 
1643         /** Firmware layout for the C9 */
1644         {
1645                 .id     = "ARCHERC9",
1646                 .vendor = "",
1647                 .support_list =
1648                         "SupportList:\n"
1649                         "{product_name:ArcherC9,"
1650                         "product_ver:1.0.0,"
1651                         "special_id:00000000}\n",
1652                 .part_trail = 0x00,
1653                 .soft_ver = SOFT_VER_DEFAULT,
1654 
1655                 .partitions = {
1656                         {"fs-uboot", 0x00000, 0x40000},
1657                         {"os-image", 0x40000, 0x200000},
1658                         {"file-system", 0x240000, 0xc00000},
1659                         {"default-mac", 0xe40000, 0x00200},
1660                         {"pin", 0xe40200, 0x00200},
1661                         {"product-info", 0xe40400, 0x00200},
1662                         {"partition-table", 0xe50000, 0x10000},
1663                         {"soft-version", 0xe60000, 0x00200},
1664                         {"support-list", 0xe61000, 0x0f000},
1665                         {"profile", 0xe70000, 0x10000},
1666                         {"default-config", 0xe80000, 0x10000},
1667                         {"user-config", 0xe90000, 0x50000},
1668                         {"log", 0xee0000, 0x100000},
1669                         {"radio_bk", 0xfe0000, 0x10000},
1670                         {"radio", 0xff0000, 0x10000},
1671                         {NULL, 0, 0}
1672                 },
1673 
1674                 .first_sysupgrade_partition = "os-image",
1675                 .last_sysupgrade_partition = "file-system"
1676         },
1677 
1678         /** Firmware layout for the Deco M4R v1 and v2 */
1679         {
1680                 .id     = "DECO-M4R-V1",
1681                 .vendor = "",
1682                 .support_list =
1683                         "SupportList:\n"
1684                         "{product_name:M4R,product_ver:1.0.0,special_id:55530000}\n"
1685                         "{product_name:M4R,product_ver:1.0.0,special_id:45550000}\n"
1686                         "{product_name:M4R,product_ver:1.0.0,special_id:43410000}\n"
1687                         "{product_name:M4R,product_ver:1.0.0,special_id:4A500000}\n"
1688                         "{product_name:M4R,product_ver:1.0.0,special_id:41550000}\n"
1689                         "{product_name:M4R,product_ver:1.0.0,special_id:4B520000}\n"
1690                         "{product_name:M4R,product_ver:1.0.0,special_id:49440000}\n"
1691                         "{product_name:M4R,product_ver:2.0.0,special_id:55530000}\n"
1692                         "{product_name:M4R,product_ver:2.0.0,special_id:45550000}\n"
1693                         "{product_name:M4R,product_ver:2.0.0,special_id:43410000}\n"
1694                         "{product_name:M4R,product_ver:2.0.0,special_id:4A500000}\n"
1695                         "{product_name:M4R,product_ver:2.0.0,special_id:41550000}\n"
1696                         "{product_name:M4R,product_ver:2.0.0,special_id:4B520000}\n"
1697                         "{product_name:M4R,product_ver:2.0.0,special_id:54570000}\n"
1698                         "{product_name:M4R,product_ver:2.0.0,special_id:42340000}\n"
1699                         "{product_name:M4R,product_ver:2.0.0,special_id:49440000}\n",
1700                 .part_trail = 0x00,
1701                 .soft_ver = SOFT_VER_DEFAULT,
1702 
1703                 .partitions = {
1704                         {"fs-uboot", 0x00000, 0x80000},
1705                         {"firmware", 0x80000, 0xe00000},
1706                         {"product-info", 0xe80000, 0x05000},
1707                         {"default-mac", 0xe85000, 0x01000},
1708                         {"device-id", 0xe86000, 0x01000},
1709                         {"support-list", 0xe87000, 0x10000},
1710                         {"user-config", 0xea7000, 0x10000},
1711                         {"device-config", 0xeb7000, 0x10000},
1712                         {"group-info", 0xec7000, 0x10000},
1713                         {"partition-table", 0xed7000, 0x02000},
1714                         {"soft-version", 0xed9000, 0x10000},
1715                         {"profile", 0xee9000, 0x10000},
1716                         {"default-config", 0xef9000, 0x10000},
1717                         {"url-sig", 0xfe0000, 0x10000},
1718                         {"radio", 0xff0000, 0x10000},
1719                         {NULL, 0, 0}
1720                 },
1721                 .first_sysupgrade_partition = "os-image",
1722                 .last_sysupgrade_partition = "file-system",
1723         },
1724 
1725         /** Firmware layout for the Deco M4R v4 */
1726         {
1727                 .id     = "DECO-M4R-V4",
1728                 .vendor = "",
1729                 .support_list =
1730                         "SupportList:\n"
1731                         "{product_name:M4R,product_ver:4.0.0,special_id:55530000}\n"
1732                         "{product_name:M4R,product_ver:4.0.0,special_id:45550000}\n"
1733                         "{product_name:M4R,product_ver:4.0.0,special_id:4A500000}\n"
1734                         "{product_name:M4R,product_ver:4.0.0,special_id:42340000}\n"
1735                         "{product_name:M4R,product_ver:4.0.0,special_id:5A470000}\n",
1736                 .part_trail = 0x00,
1737                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
1738 
1739                 .partitions = {
1740                         {"fs-uboot", 0x00000, 0x40000},
1741                         {"firmware", 0x40000, 0xf60000},
1742                         {"default-mac", 0xfa0000, 0x00300},
1743                         {"device-id", 0xfa0300, 0x00100},
1744                         {"product-info", 0xfa0400, 0x0fc00},
1745                         {"group-info", 0xfb0000, 0x04000},
1746                         {"user-config", 0xfb4000, 0x0c000},
1747                         {"device-config", 0xfc0000, 0x10000},
1748                         {"default-config", 0xfd0000, 0x10000},
1749                         {"partition-table", 0xfe0000, 0x00800},
1750                         {"soft-version", 0xfe0800, 0x00100},
1751                         {"support-list", 0xfe0900, 0x00200},
1752                         {"profile", 0xfe0b00, 0x03000},
1753                         {"extra-para", 0xfe3b00, 0x00100},
1754                         {"radio", 0xff0000, 0x10000},
1755                         {NULL, 0, 0}
1756                 },
1757                 .first_sysupgrade_partition = "os-image",
1758                 .last_sysupgrade_partition = "file-system",
1759         },
1760 
1761         /** Firmware layout for the Deco M5 */
1762         {
1763                 .id = "DECO-M5",
1764                 .vendor = "",
1765                 .support_list =
1766                         "SupportList:\n"
1767                         "{product_name:M5,product_ver:1.0.0,special_id:55530000}\n"
1768                         "{product_name:M5,product_ver:1.0.0,special_id:45550000}\n"
1769                         "{product_name:M5,product_ver:1.0.0,special_id:43410000}\n"
1770                         "{product_name:M5,product_ver:1.0.0,special_id:4A500000}\n"
1771                         "{product_name:M5,product_ver:1.0.0,special_id:41550000}\n"
1772                         "{product_name:M5,product_ver:1.0.0,special_id:4B520000}\n"
1773                         "{product_name:M5,product_ver:1.0.0,special_id:49440000}\n"
1774                         "{product_name:M5,product_ver:3.0.0,special_id:55530000}\n"
1775                         "{product_name:M5,product_ver:3.0.0,special_id:45550000}\n"
1776                         "{product_name:M5,product_ver:3.0.0,special_id:43410000}\n"
1777                         "{product_name:M5,product_ver:3.0.0,special_id:4A500000}\n"
1778                         "{product_name:M5,product_ver:3.0.0,special_id:41550000}\n"
1779                         "{product_name:M5,product_ver:3.0.0,special_id:4B520000}\n"
1780                         "{product_name:M5,product_ver:3.0.0,special_id:49440000}\n"
1781                         "{product_name:M5,product_ver:3.0.0,special_id:53570000}\n"
1782                         "{product_name:M5,product_ver:3.0.0,special_id:42340000}\n"
1783                         "{product_name:M5,product_ver:3.0.0,special_id:54570000}\n"
1784                         "{product_name:M5,product_ver:3.2.0,special_id:55530000}\n"
1785                         "{product_name:M5,product_ver:3.2.0,special_id:45550000}\n"
1786                         "{product_name:M5,product_ver:3.2.0,special_id:43410000}\n"
1787                         "{product_name:M5,product_ver:3.2.0,special_id:4A500000}\n"
1788                         "{product_name:M5,product_ver:3.2.0,special_id:41550000}\n"
1789                         "{product_name:M5,product_ver:3.2.0,special_id:4B520000}\n"
1790                         "{product_name:M5,product_ver:3.2.0,special_id:49440000}\n"
1791                         "{product_name:M5,product_ver:3.2.0,special_id:53570000}\n"
1792                         "{product_name:M5,product_ver:3.2.0,special_id:42340000}\n"
1793                         "{product_name:M5,product_ver:3.2.0,special_id:54570000}\n",
1794                 .part_trail = 0x00,
1795                 .soft_ver = SOFT_VER_DEFAULT,
1796 
1797                 .partitions = {
1798                         {"SBL1", 0x00000, 0x30000},
1799                         {"boot-config_0", 0x30000, 0x10000},
1800                         {"MIBIB", 0x40000, 0x10000},
1801                         {"boot-config_1", 0x50000, 0x10000},
1802                         {"QSEE", 0x60000, 0x60000},
1803                         {"CDT", 0xc0000, 0x10000},
1804                         {"DDRPARAMS", 0xd0000, 0x10000},
1805                         {"uboot-env", 0xe0000, 0x10000},
1806                         {"fs-uboot@0", 0xf0000, 0x80000},
1807                         {"radio", 0x170000, 0x0fff0},
1808                         {"bluetooth-XTAL", 0x17fff0, 0x00010},
1809                         {"default-mac", 0x180000, 0x01000},
1810                         {"device-id", 0x182000, 0x01000},
1811                         {"product-info", 0x183000, 0x05000},
1812                         {"support-list", 0x190000, 0x10000},
1813                         {"user-config", 0x200000, 0x10000},
1814                         {"device-config", 0x210000, 0x10000},
1815                         {"group-info", 0x220000, 0x10000},
1816                         {"partition-table@0", 0x230000, 0x02000},
1817                         {"os-image@0", 0x240000, 0x300000},
1818                         {"file-system@0", 0x540000, 0x790000},
1819                         {"soft-version@0", 0xcd0000, 0x10000},
1820                         {"profile@0", 0xce0000, 0x10000},
1821                         {"default-config@0", 0xcf0000, 0x10000},
1822                         {"partition-table@1", 0xd00000, 0x02000},
1823                         {"fs-uboot@1", 0xd10000, 0x80000},
1824                         {"os-image@1", 0xd90000, 0x400000},
1825                         {"file-system@1", 0x1190000, 0xc40000},
1826                         {"soft-version@1", 0x1dd0000, 0x10000},
1827                         {"profile@1", 0x1de0000, 0x10000},
1828                         {"default-config@1", 0x1df0000, 0x10000},
1829                         {"tm-sig", 0x1e00000, 0x200000},
1830                         {NULL, 0, 0}
1831                 },
1832 
1833                 .partition_names.partition_table = "partition-table@1",
1834                 .partition_names.soft_ver = "soft-version@1",
1835                 .partition_names.os_image = "os-image@1",
1836                 .partition_names.file_system = "file-system@1",
1837 
1838                 .first_sysupgrade_partition = "os-image@1",
1839                 .last_sysupgrade_partition = "file-system@1"
1840         },
1841 
1842         /** Firmware layout for the Deco S4 v2 */
1843         {
1844                 .id     = "DECO-S4-V2",
1845                 .vendor = "",
1846                 .support_list =
1847                         "SupportList:\n"
1848                         "{product_name:S4,product_ver:1.0.0,special_id:55530000}\n"
1849                         "{product_name:S4,product_ver:1.0.0,special_id:45550000}\n"
1850                         "{product_name:S4,product_ver:1.0.0,special_id:43410000}\n"
1851                         "{product_name:S4,product_ver:1.0.0,special_id:4A500000}\n"
1852                         "{product_name:S4,product_ver:1.0.0,special_id:41550000}\n"
1853                         "{product_name:S4,product_ver:1.0.0,special_id:4B520000}\n"
1854                         "{product_name:S4,product_ver:2.0.0,special_id:55530000}\n"
1855                         "{product_name:S4,product_ver:2.0.0,special_id:45550000}\n"
1856                         "{product_name:S4,product_ver:2.0.0,special_id:43410000}\n"
1857                         "{product_name:S4,product_ver:2.0.0,special_id:4A500000}\n"
1858                         "{product_name:S4,product_ver:2.0.0,special_id:41550000}\n"
1859                         "{product_name:S4,product_ver:2.0.0,special_id:4B520000}\n",
1860                 .part_trail = 0x00,
1861                 .soft_ver = SOFT_VER_DEFAULT,
1862 
1863                 .partitions = {
1864                         {"fs-uboot", 0x00000, 0x80000},
1865                         {"product-info", 0x80000, 0x05000},
1866                         {"default-mac", 0x85000, 0x01000},
1867                         {"device-id", 0x86000, 0x01000},
1868                         {"support-list", 0x87000, 0x10000},
1869                         {"user-config", 0xa7000, 0x10000},
1870                         {"device-config", 0xb7000, 0x10000},
1871                         {"group-info", 0xc7000, 0x10000},
1872                         {"partition-table", 0xd7000, 0x02000},
1873                         {"soft-version", 0xd9000, 0x10000},
1874                         {"profile", 0xe9000, 0x10000},
1875                         {"default-config", 0xf9000, 0x10000},
1876                         {"url-sig", 0x1e0000, 0x10000},
1877                         {"radio", 0x1f0000, 0x10000},
1878                         {"firmware", 0x200000, 0xe00000},
1879                         {NULL, 0, 0}
1880                 },
1881                 .first_sysupgrade_partition = "os-image",
1882                 .last_sysupgrade_partition = "file-system",
1883         },
1884 
1885         /** Firmware layout for the EAP120 */
1886         {
1887                 .id     = "EAP120",
1888                 .vendor = "EAP120(TP-LINK|UN|N300-2):1.0\r\n",
1889                 .support_list =
1890                         "SupportList:\r\n"
1891                         "EAP120(TP-LINK|UN|N300-2):1.0\r\n",
1892                 .part_trail = 0xff,
1893                 .soft_ver = SOFT_VER_DEFAULT,
1894 
1895                 .partitions = {
1896                         {"fs-uboot", 0x00000, 0x20000},
1897                         {"partition-table", 0x20000, 0x02000},
1898                         {"default-mac", 0x30000, 0x00020},
1899                         {"support-list", 0x31000, 0x00100},
1900                         {"product-info", 0x31100, 0x00100},
1901                         {"soft-version", 0x32000, 0x00100},
1902                         {"os-image", 0x40000, 0x180000},
1903                         {"file-system", 0x1c0000, 0x600000},
1904                         {"user-config", 0x7c0000, 0x10000},
1905                         {"backup-config", 0x7d0000, 0x10000},
1906                         {"log", 0x7e0000, 0x10000},
1907                         {"radio", 0x7f0000, 0x10000},
1908                         {NULL, 0, 0}
1909                 },
1910 
1911                 .first_sysupgrade_partition = "os-image",
1912                 .last_sysupgrade_partition = "file-system"
1913         },
1914 
1915         /** Firmware layout for the EAP225-Outdoor v1 */
1916         {
1917                 .id     = "EAP225-OUTDOOR-V1",
1918                 .support_list =
1919                         "SupportList:\r\n"
1920                         "EAP225-Outdoor(TP-Link|UN|AC1200-D):1.0\r\n",
1921                 .part_trail = PART_TRAIL_NONE,
1922                 .soft_ver = SOFT_VER_DEFAULT,
1923                 .soft_ver_compat_level = 2,
1924 
1925                 .partitions = {
1926                         {"fs-uboot", 0x00000, 0x20000},
1927                         {"partition-table", 0x20000, 0x02000},
1928                         {"default-mac", 0x30000, 0x01000},
1929                         {"support-list", 0x31000, 0x00100},
1930                         {"product-info", 0x31100, 0x00400},
1931                         {"soft-version", 0x32000, 0x00100},
1932                         {"firmware", 0x40000, 0xd80000},
1933                         {"user-config", 0xdc0000, 0x30000},
1934                         {"mutil-log", 0xf30000, 0x80000},
1935                         {"oops", 0xfb0000, 0x40000},
1936                         {"radio", 0xff0000, 0x10000},
1937                         {NULL, 0, 0}
1938                 },
1939 
1940                 .first_sysupgrade_partition = "os-image",
1941                 .last_sysupgrade_partition = "file-system"
1942         },
1943 
1944         /** Firmware layout for the EAP225 v1 */
1945         {
1946                 .id     = "EAP225-V1",
1947                 .support_list =
1948                         "SupportList:\r\n"
1949                         "EAP225(TP-LINK|UN|AC1200-D):1.0\r\n",
1950                 .part_trail = PART_TRAIL_NONE,
1951                 .soft_ver = SOFT_VER_DEFAULT,
1952 
1953                 .partitions = {
1954                         {"fs-uboot", 0x00000, 0x20000},
1955                         {"partition-table", 0x20000, 0x02000},
1956                         {"default-mac", 0x30000, 0x01000},
1957                         {"support-list", 0x31000, 0x00100},
1958                         {"product-info", 0x31100, 0x00400},
1959                         {"soft-version", 0x32000, 0x00100},
1960                         {"firmware", 0x40000, 0xd80000},
1961                         {"user-config", 0xdc0000, 0x30000},
1962                         {"radio", 0xff0000, 0x10000},
1963                         {NULL, 0, 0}
1964                 },
1965 
1966                 .first_sysupgrade_partition = "os-image",
1967                 .last_sysupgrade_partition = "file-system"
1968         },
1969 
1970         /** Firmware layout for the EAP225 v3
1971          * Also compatible with:
1972          *   - EAP225 v3.20
1973          *   - EAP225 v4
1974          *   - EAP225-Outdoor v1
1975          *   - EAP225-Outdoor v3
1976          *   */
1977         {
1978                 .id     = "EAP225-V3",
1979                 .support_list =
1980                         "SupportList:\r\n"
1981                         "EAP225(TP-Link|UN|AC1350-D):3.0\r\n"
1982                         "EAP225(TP-Link|UN|AC1350-D):3.20\r\n"
1983                         "EAP225(TP-Link|UN|AC1350-D):4.0 CA\r\n"
1984                         "EAP225-Outdoor(TP-Link|UN|AC1200-D):1.0\r\n"
1985                         "EAP225-Outdoor(TP-Link|UN|AC1200-D):3.0 CA,JP\r\n",
1986                 .part_trail = PART_TRAIL_NONE,
1987                 .soft_ver = SOFT_VER_DEFAULT,
1988                 .soft_ver_compat_level = 2,
1989 
1990                 .partitions = {
1991                         {"fs-uboot", 0x00000, 0x20000},
1992                         {"partition-table", 0x20000, 0x02000},
1993                         {"default-mac", 0x30000, 0x01000},
1994                         {"support-list", 0x31000, 0x00100},
1995                         {"product-info", 0x31100, 0x00400},
1996                         {"soft-version", 0x32000, 0x00100},
1997                         {"firmware", 0x40000, 0xd80000},
1998                         {"user-config", 0xdc0000, 0x30000},
1999                         {"mutil-log", 0xf30000, 0x80000},
2000                         {"oops", 0xfb0000, 0x40000},
2001                         {"radio", 0xff0000, 0x10000},
2002                         {NULL, 0, 0}
2003                 },
2004 
2005                 .first_sysupgrade_partition = "os-image",
2006                 .last_sysupgrade_partition = "file-system"
2007         },
2008 
2009         /** Firmware layout for the EAP225-Wall v2 */
2010         {
2011                 .id     = "EAP225-WALL-V2",
2012                 .support_list =
2013                         "SupportList:\r\n"
2014                         "EAP225-Wall(TP-Link|UN|AC1200-D):2.0\r\n",
2015                 .part_trail = PART_TRAIL_NONE,
2016                 .soft_ver = SOFT_VER_DEFAULT,
2017                 .soft_ver_compat_level = 1,
2018 
2019                 .partitions = {
2020                         {"fs-uboot", 0x00000, 0x20000},
2021                         {"partition-table", 0x20000, 0x02000},
2022                         {"default-mac", 0x30000, 0x01000},
2023                         {"support-list", 0x31000, 0x00100},
2024                         {"product-info", 0x31100, 0x00400},
2025                         {"soft-version", 0x32000, 0x00100},
2026                         {"firmware", 0x40000, 0xd80000},
2027                         {"user-config", 0xdc0000, 0x30000},
2028                         {"mutil-log", 0xf30000, 0x80000},
2029                         {"oops", 0xfb0000, 0x40000},
2030                         {"radio", 0xff0000, 0x10000},
2031                         {NULL, 0, 0}
2032                 },
2033 
2034                 .first_sysupgrade_partition = "os-image",
2035                 .last_sysupgrade_partition = "file-system"
2036         },
2037 
2038         /** Firmware layout for the EAP235-Wall v1 */
2039         {
2040                 .id     = "EAP235-WALL-V1",
2041                 .support_list =
2042                         "SupportList:\r\n"
2043                         "EAP235-Wall(TP-Link|UN|AC1200-D):1.0\r\n",
2044                 .part_trail = PART_TRAIL_NONE,
2045                 .soft_ver = SOFT_VER_NUMERIC(3, 0, 0),
2046                 .soft_ver_compat_level = 1,
2047 
2048                 .partitions = {
2049                         {"fs-uboot", 0x00000, 0x80000},
2050                         {"partition-table", 0x80000, 0x02000},
2051                         {"default-mac", 0x90000, 0x01000},
2052                         {"support-list", 0x91000, 0x00100},
2053                         {"product-info", 0x91100, 0x00400},
2054                         {"soft-version", 0x92000, 0x00100},
2055                         {"firmware", 0xa0000, 0xd20000},
2056                         {"user-config", 0xdc0000, 0x30000},
2057                         {"mutil-log", 0xf30000, 0x80000},
2058                         {"oops", 0xfb0000, 0x40000},
2059                         {"radio", 0xff0000, 0x10000},
2060                         {NULL, 0, 0}
2061                 },
2062 
2063                 .first_sysupgrade_partition = "os-image",
2064                 .last_sysupgrade_partition = "file-system"
2065         },
2066 
2067         /** Firmware layout for the EAP245 v1 */
2068         {
2069                 .id     = "EAP245-V1",
2070                 .support_list =
2071                         "SupportList:\r\n"
2072                         "EAP245(TP-LINK|UN|AC1750-D):1.0\r\n",
2073                 .part_trail = PART_TRAIL_NONE,
2074                 .soft_ver = SOFT_VER_DEFAULT,
2075 
2076                 .partitions = {
2077                         {"fs-uboot", 0x00000, 0x20000},
2078                         {"partition-table", 0x20000, 0x02000},
2079                         {"default-mac", 0x30000, 0x01000},
2080                         {"support-list", 0x31000, 0x00100},
2081                         {"product-info", 0x31100, 0x00400},
2082                         {"soft-version", 0x32000, 0x00100},
2083                         {"firmware", 0x40000, 0xd80000},
2084                         {"user-config", 0xdc0000, 0x30000},
2085                         {"radio", 0xff0000, 0x10000},
2086                         {NULL, 0, 0}
2087                 },
2088 
2089                 .first_sysupgrade_partition = "os-image",
2090                 .last_sysupgrade_partition = "file-system"
2091         },
2092 
2093         /** Firmware layout for the EAP245 v3 */
2094         {
2095                 .id     = "EAP245-V3",
2096                 .support_list =
2097                         "SupportList:\r\n"
2098                         "EAP245(TP-Link|UN|AC1750-D):3.0\r\n"
2099                         "EAP265 HD(TP-Link|UN|AC1750-D):1.0",
2100                 .part_trail = PART_TRAIL_NONE,
2101                 .soft_ver = SOFT_VER_DEFAULT,
2102                 .soft_ver_compat_level = 1,
2103 
2104                 /** Firmware partition with dynamic kernel/rootfs split */
2105                 .partitions = {
2106                         {"factroy-boot", 0x00000, 0x40000},
2107                         {"fs-uboot", 0x40000, 0x40000},
2108                         {"partition-table", 0x80000, 0x10000},
2109                         {"default-mac", 0x90000, 0x01000},
2110                         {"support-list", 0x91000, 0x00100},
2111                         {"product-info", 0x91100, 0x00400},
2112                         {"soft-version", 0x92000, 0x00100},
2113                         {"radio", 0xa0000, 0x10000},
2114                         {"extra-para", 0xb0000, 0x10000},
2115                         {"firmware", 0xc0000, 0xe40000},
2116                         {"config", 0xf00000, 0x30000},
2117                         {"mutil-log", 0xf30000, 0x80000},
2118                         {"oops", 0xfb0000, 0x40000},
2119                         {NULL, 0, 0}
2120                 },
2121 
2122                 .first_sysupgrade_partition = "os-image",
2123                 .last_sysupgrade_partition = "file-system"
2124         },
2125 
2126         /** Firmware layout for the EAP610 v3/EAP613 v1 */
2127         {
2128                 .id = "EAP610-V3",
2129                 .soft_ver = SOFT_VER_DEFAULT,
2130                 .soft_ver_compat_level = 1,
2131                 .support_list =
2132                         "SupportList:\r\n"
2133                         "EAP610(TP-Link|UN|AX1800-D):3.0\r\n"
2134                         "EAP610(TP-Link|JP|AX1800-D):3.0\r\n"
2135                         "EAP610(TP-Link|EG|AX1800-D):3.0\r\n"
2136                         "EAP610(TP-Link|CA|AX1800-D):3.0\r\n"
2137                         "EAP613(TP-Link|UN|AX1800-D):1.0 JP\r\n",
2138                 .part_trail = PART_TRAIL_NONE,
2139 
2140                 .partitions = {
2141                         {"fs-uboot", 0x00000, 0x80000},
2142                         {"partition-table", 0x80000, 0x02000},
2143                         {"default-mac", 0x90000, 0x01000},
2144                         {"support-list", 0x91000, 0x00100},
2145                         {"product-info", 0x91100, 0x00400},
2146                         {"soft-version", 0x92000, 0x00100},
2147                         {"firmware", 0xa0000, 0xcf0000},
2148                         {"user-config", 0xd90000, 0x60000},
2149                         {"mutil-log", 0xf30000, 0x80000},
2150                         {"oops", 0xfb0000, 0x40000},
2151                         {"radio", 0xff0000, 0x10000},
2152                         {NULL, 0, 0}
2153                 },
2154 
2155                 .first_sysupgrade_partition = "os-image",
2156                 .last_sysupgrade_partition = "file-system"
2157         },
2158 
2159         /** Firmware layout for the EAP615-Wall v1 */
2160         {
2161                 .id = "EAP615-WALL-V1",
2162                 .soft_ver = SOFT_VER_DEFAULT,
2163                 .soft_ver_compat_level = 2,
2164                 .support_list =
2165                         "SupportList:\r\n"
2166                         "EAP615-Wall(TP-Link|UN|AX1800-D):1.0\r\n"
2167                         "EAP615-Wall(TP-Link|CA|AX1800-D):1.0\r\n"
2168                         "EAP615-Wall(TP-Link|JP|AX1800-D):1.0\r\n",
2169                 .part_trail = PART_TRAIL_NONE,
2170 
2171                 .partitions = {
2172                         {"fs-uboot", 0x00000, 0x80000},
2173                         {"partition-table", 0x80000, 0x02000},
2174                         {"default-mac", 0x90000, 0x01000},
2175                         {"support-list", 0x91000, 0x00100},
2176                         {"product-info", 0x91100, 0x00400},
2177                         {"soft-version", 0x92000, 0x00100},
2178                         {"firmware", 0xa0000, 0xcf0000},
2179                         {"user-config", 0xd90000, 0x60000},
2180                         {"mutil-log", 0xf30000, 0x80000},
2181                         {"oops", 0xfb0000, 0x40000},
2182                         {"radio", 0xff0000, 0x10000},
2183                         {NULL, 0, 0}
2184                 },
2185 
2186                 .first_sysupgrade_partition = "os-image",
2187                 .last_sysupgrade_partition = "file-system"
2188         },
2189 
2190         /** Firmware layout for the TL-WA1201 v2 */
2191         {
2192                 .id     = "TL-WA1201-V2",
2193                 .vendor = "",
2194                 .support_list =
2195                         "SupportList:\n"
2196                         "{product_name:TL-WA1201,product_ver:2.0.0,special_id:45550000}\n"
2197                         "{product_name:TL-WA1201,product_ver:2.0.0,special_id:55530000}\n",
2198                 .part_trail = 0x00,
2199                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.1 Build 20200709 rel.66244\n"),
2200 
2201                 .partitions = {
2202                         {"fs-uboot", 0x00000, 0x20000},
2203                         {"default-mac", 0x20000, 0x00200},
2204                         {"pin", 0x20200, 0x00100},
2205                         {"product-info", 0x20300, 0x00200},
2206                         {"device-id", 0x20500, 0x0fb00},
2207                         {"firmware", 0x30000, 0xce0000},
2208                         {"portal-logo", 0xd10000, 0x20000},
2209                         {"portal-back", 0xd30000, 0x200000},
2210                         {"soft-version", 0xf30000, 0x00200},
2211                         {"extra-para", 0xf30200, 0x00200},
2212                         {"support-list", 0xf30400, 0x00200},
2213                         {"profile", 0xf30600, 0x0fa00},
2214                         {"apdef-config", 0xf40000, 0x10000},
2215                         {"ap-config", 0xf50000, 0x10000},
2216                         {"redef-config", 0xf60000, 0x10000},
2217                         {"re-config", 0xf70000, 0x10000},
2218                         {"multidef-config", 0xf80000, 0x10000},
2219                         {"multi-config", 0xf90000, 0x10000},
2220                         {"clientdef-config", 0xfa0000, 0x10000},
2221                         {"client-config", 0xfb0000, 0x10000},
2222                         {"partition-table", 0xfc0000, 0x10000},
2223                         {"user-config", 0xfd0000, 0x10000},
2224                         {"certificate", 0xfe0000, 0x10000},
2225                         {"radio", 0xff0000, 0x10000},
2226                         {NULL, 0, 0}
2227                 },
2228                 .first_sysupgrade_partition = "os-image",
2229                 .last_sysupgrade_partition = "file-system",
2230         },
2231 
2232         /** Firmware layout for the TL-WA850RE v2 */
2233         {
2234                 .id     = "TLWA850REV2",
2235                 .vendor = "",
2236                 .support_list =
2237                         "SupportList:\n"
2238                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55530000}\n"
2239                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:00000000}\n"
2240                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55534100}\n"
2241                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:45550000}\n"
2242                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4B520000}\n"
2243                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:42520000}\n"
2244                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4A500000}\n"
2245                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:43410000}\n"
2246                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:41550000}\n"
2247                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:52550000}\n",
2248                 .part_trail = 0x00,
2249                 .soft_ver = SOFT_VER_DEFAULT,
2250 
2251                 /**
2252                    576KB were moved from file-system to os-image
2253                    in comparison to the stock image
2254                 */
2255                 .partitions = {
2256                         {"fs-uboot", 0x00000, 0x20000},
2257                         {"firmware", 0x20000, 0x390000},
2258                         {"partition-table", 0x3b0000, 0x02000},
2259                         {"default-mac", 0x3c0000, 0x00020},
2260                         {"pin", 0x3c0100, 0x00020},
2261                         {"product-info", 0x3c1000, 0x01000},
2262                         {"soft-version", 0x3c2000, 0x00100},
2263                         {"support-list", 0x3c3000, 0x01000},
2264                         {"profile", 0x3c4000, 0x08000},
2265                         {"user-config", 0x3d0000, 0x10000},
2266                         {"default-config", 0x3e0000, 0x10000},
2267                         {"radio", 0x3f0000, 0x10000},
2268                         {NULL, 0, 0}
2269                 },
2270 
2271                 .first_sysupgrade_partition = "os-image",
2272                 .last_sysupgrade_partition = "file-system"
2273         },
2274 
2275         /** Firmware layout for the TL-WA855RE v1 */
2276         {
2277                 .id     = "TLWA855REV1",
2278                 .vendor = "",
2279                 .support_list =
2280                         "SupportList:\n"
2281                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:00000000}\n"
2282                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:55530000}\n"
2283                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:45550000}\n"
2284                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4B520000}\n"
2285                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:42520000}\n"
2286                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4A500000}\n"
2287                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:43410000}\n"
2288                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:41550000}\n"
2289                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:52550000}\n",
2290                 .part_trail = 0x00,
2291                 .soft_ver = SOFT_VER_DEFAULT,
2292 
2293                 .partitions = {
2294                         {"fs-uboot", 0x00000, 0x20000},
2295                         {"os-image", 0x20000, 0x150000},
2296                         {"file-system", 0x170000, 0x240000},
2297                         {"partition-table", 0x3b0000, 0x02000},
2298                         {"default-mac", 0x3c0000, 0x00020},
2299                         {"pin", 0x3c0100, 0x00020},
2300                         {"product-info", 0x3c1000, 0x01000},
2301                         {"soft-version", 0x3c2000, 0x00100},
2302                         {"support-list", 0x3c3000, 0x01000},
2303                         {"profile", 0x3c4000, 0x08000},
2304                         {"user-config", 0x3d0000, 0x10000},
2305                         {"default-config", 0x3e0000, 0x10000},
2306                         {"radio", 0x3f0000, 0x10000},
2307                         {NULL, 0, 0}
2308                 },
2309 
2310                 .first_sysupgrade_partition = "os-image",
2311                 .last_sysupgrade_partition = "file-system"
2312         },
2313 
2314         /** Firmware layout for the TL-WPA8630P v2 (EU)*/
2315         {
2316                 .id     = "TL-WPA8630P-V2.0-EU",
2317                 .vendor = "",
2318                 .support_list =
2319                         "SupportList:\n"
2320                         "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:45550000}\n",
2321                 .part_trail = 0x00,
2322                 .soft_ver = SOFT_VER_DEFAULT,
2323 
2324                 .partitions = {
2325                         {"factory-uboot", 0x00000, 0x20000},
2326                         {"fs-uboot", 0x20000, 0x20000},
2327                         {"firmware", 0x40000, 0x5e0000},
2328                         {"partition-table", 0x620000, 0x02000},
2329                         {"default-mac", 0x630000, 0x00020},
2330                         {"pin", 0x630100, 0x00020},
2331                         {"device-id", 0x630200, 0x00030},
2332                         {"product-info", 0x631100, 0x01000},
2333                         {"extra-para", 0x632100, 0x01000},
2334                         {"soft-version", 0x640000, 0x01000},
2335                         {"support-list", 0x641000, 0x01000},
2336                         {"profile", 0x642000, 0x08000},
2337                         {"user-config", 0x650000, 0x10000},
2338                         {"default-config", 0x660000, 0x10000},
2339                         {"default-nvm", 0x670000, 0xc0000},
2340                         {"default-pib", 0x730000, 0x40000},
2341                         {"radio", 0x7f0000, 0x10000},
2342                         {NULL, 0, 0}
2343                 },
2344 
2345                 .first_sysupgrade_partition = "os-image",
2346                 .last_sysupgrade_partition = "file-system"
2347         },
2348 
2349         /** Firmware layout for the TL-WPA8630P v2 (INT)*/
2350         {
2351                 .id     = "TL-WPA8630P-V2-INT",
2352                 .vendor = "",
2353                 .support_list =
2354                         "SupportList:\n"
2355                         "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:41550000}\n"
2356                         "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:44450000}\n"
2357                         "{product_name:TL-WPA8630P,product_ver:2.1.0,special_id:41550000}\n",
2358                 .part_trail = 0x00,
2359                 .soft_ver = SOFT_VER_DEFAULT,
2360 
2361                 .partitions = {
2362                         {"factory-uboot", 0x00000, 0x20000},
2363                         {"fs-uboot", 0x20000, 0x20000},
2364                         {"firmware", 0x40000, 0x5e0000},
2365                         {"partition-table", 0x620000, 0x02000},
2366                         {"extra-para", 0x632100, 0x01000},
2367                         {"soft-version", 0x640000, 0x01000},
2368                         {"support-list", 0x641000, 0x01000},
2369                         {"profile", 0x642000, 0x08000},
2370                         {"user-config", 0x650000, 0x10000},
2371                         {"default-config", 0x660000, 0x10000},
2372                         {"default-nvm", 0x670000, 0xc0000},
2373                         {"default-pib", 0x730000, 0x40000},
2374                         {"default-mac", 0x7e0000, 0x00020},
2375                         {"pin", 0x7e0100, 0x00020},
2376                         {"device-id", 0x7e0200, 0x00030},
2377                         {"product-info", 0x7e1100, 0x01000},
2378                         {"radio", 0x7f0000, 0x10000},
2379                         {NULL, 0, 0}
2380                 },
2381 
2382                 .first_sysupgrade_partition = "os-image",
2383                 .last_sysupgrade_partition = "file-system"
2384         },
2385 
2386         /** Firmware layout for the TL-WPA8630P v2.1 (EU)*/
2387         {
2388                 .id     = "TL-WPA8630P-V2.1-EU",
2389                 .vendor = "",
2390                 .support_list =
2391                         "SupportList:\n"
2392                         "{product_name:TL-WPA8630P,product_ver:2.1.0,special_id:45550000}\n",
2393                 .part_trail = 0x00,
2394                 .soft_ver = SOFT_VER_DEFAULT,
2395 
2396                 .partitions = {
2397                         {"factory-uboot", 0x00000, 0x20000},
2398                         {"fs-uboot", 0x20000, 0x20000},
2399                         {"firmware", 0x40000, 0x5e0000},
2400                         {"extra-para", 0x680000, 0x01000},
2401                         {"product-info", 0x690000, 0x01000},
2402                         {"partition-table", 0x6a0000, 0x02000},
2403                         {"soft-version", 0x6b0000, 0x01000},
2404                         {"support-list", 0x6b1000, 0x01000},
2405                         {"profile", 0x6b2000, 0x08000},
2406                         {"user-config", 0x6c0000, 0x10000},
2407                         {"default-config", 0x6d0000, 0x10000},
2408                         {"default-nvm", 0x6e0000, 0xc0000},
2409                         {"default-pib", 0x7a0000, 0x40000},
2410                         {"default-mac", 0x7e0000, 0x00020},
2411                         {"pin", 0x7e0100, 0x00020},
2412                         {"device-id", 0x7e0200, 0x00030},
2413                         {"radio", 0x7f0000, 0x10000},
2414                         {NULL, 0, 0}
2415                 },
2416 
2417                 .first_sysupgrade_partition = "os-image",
2418                 .last_sysupgrade_partition = "file-system"
2419         },
2420 
2421         /** Firmware layout for the TL-WPA8631P v3 */
2422         {
2423                 .id     = "TL-WPA8631P-V3",
2424                 .vendor = "",
2425                 .support_list =
2426                         "SupportList:\n"
2427                         "{product_name:TL-WPA8631P,product_ver:3.0.0,special_id:41550000}\n"
2428                         "{product_name:TL-WPA8631P,product_ver:3.0.0,special_id:45550000}\n"
2429                         "{product_name:TL-WPA8631P,product_ver:3.0.0,special_id:55530000}\n"
2430                         "{product_name:TL-WPA8631P,product_ver:4.0.0,special_id:41550000}\n"
2431                         "{product_name:TL-WPA8631P,product_ver:4.0.0,special_id:45550000}\n"
2432                         "{product_name:TL-WPA8631P,product_ver:4.0.0,special_id:55530000}\n"
2433                         "{product_name:TL-WPA8635P,product_ver:3.0.0,special_id:46520000}\n",
2434                 .part_trail = 0x00,
2435                 .soft_ver = SOFT_VER_DEFAULT,
2436 
2437                 .partitions = {
2438                         {"fs-uboot", 0x00000, 0x20000},
2439                         {"firmware", 0x20000, 0x710000},
2440                         {"partition-table", 0x730000, 0x02000},
2441                         {"default-mac", 0x732000, 0x00020},
2442                         {"pin", 0x732100, 0x00020},
2443                         {"device-id", 0x732200, 0x00030},
2444                         {"default-region", 0x732300, 0x00010},
2445                         {"product-info", 0x732400, 0x00200},
2446                         {"extra-para", 0x732600, 0x00200},
2447                         {"soft-version", 0x732800, 0x00100},
2448                         {"support-list", 0x732900, 0x00200},
2449                         {"profile", 0x732b00, 0x00100},
2450                         {"default-config", 0x732c00, 0x00800},
2451                         {"plc-type", 0x733400, 0x00020},
2452                         {"default-pib", 0x733500, 0x06000},
2453                         {"user-config", 0x740000, 0x10000},
2454                         {"plc-pib", 0x750000, 0x10000},
2455                         {"plc-nvm", 0x760000, 0x90000},
2456                         {"radio", 0x7f0000, 0x10000},
2457                         {NULL, 0, 0}
2458                 },
2459 
2460                 .first_sysupgrade_partition = "os-image",
2461                 .last_sysupgrade_partition = "file-system"
2462         },
2463 
2464         /** Firmware layout for the TL-WR1043 v5 */
2465         {
2466                 .id     = "TLWR1043NV5",
2467                 .vendor = "",
2468                 .support_list =
2469                         "SupportList:\n"
2470                         "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:45550000}\n"
2471                         "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:55530000}\n",
2472                 .part_trail = 0x00,
2473                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
2474                 .partitions = {
2475                         {"factory-boot", 0x00000, 0x20000},
2476                         {"fs-uboot", 0x20000, 0x20000},
2477                         {"firmware", 0x40000, 0xec0000},
2478                         {"default-mac", 0xf00000, 0x00200},
2479                         {"pin", 0xf00200, 0x00200},
2480                         {"device-id", 0xf00400, 0x00100},
2481                         {"product-info", 0xf00500, 0x0fb00},
2482                         {"soft-version", 0xf10000, 0x01000},
2483                         {"extra-para", 0xf11000, 0x01000},
2484                         {"support-list", 0xf12000, 0x0a000},
2485                         {"profile", 0xf1c000, 0x04000},
2486                         {"default-config", 0xf20000, 0x10000},
2487                         {"user-config", 0xf30000, 0x40000},
2488                         {"qos-db", 0xf70000, 0x40000},
2489                         {"certificate", 0xfb0000, 0x10000},
2490                         {"partition-table", 0xfc0000, 0x10000},
2491                         {"log", 0xfd0000, 0x20000},
2492                         {"radio", 0xff0000, 0x10000},
2493                         {NULL, 0, 0}
2494                 },
2495                 .first_sysupgrade_partition = "os-image",
2496                 .last_sysupgrade_partition = "file-system"
2497         },
2498 
2499         /** Firmware layout for the TL-WR1043 v4 */
2500         {
2501                 .id     = "TLWR1043NDV4",
2502                 .vendor = "",
2503                 .support_list =
2504                         "SupportList:\n"
2505                         "{product_name:TL-WR1043ND,product_ver:4.0.0,special_id:45550000}\n",
2506                 .part_trail = 0x00,
2507                 .soft_ver = SOFT_VER_DEFAULT,
2508 
2509                 /* We're using a dynamic kernel/rootfs split here */
2510                 .partitions = {
2511                         {"fs-uboot", 0x00000, 0x20000},
2512                         {"firmware", 0x20000, 0xf30000},
2513                         {"default-mac", 0xf50000, 0x00200},
2514                         {"pin", 0xf50200, 0x00200},
2515                         {"product-info", 0xf50400, 0x0fc00},
2516                         {"soft-version", 0xf60000, 0x0b000},
2517                         {"support-list", 0xf6b000, 0x04000},
2518                         {"profile", 0xf70000, 0x04000},
2519                         {"default-config", 0xf74000, 0x0b000},
2520                         {"user-config", 0xf80000, 0x40000},
2521                         {"partition-table", 0xfc0000, 0x10000},
2522                         {"log", 0xfd0000, 0x20000},
2523                         {"radio", 0xff0000, 0x10000},
2524                         {NULL, 0, 0}
2525                 },
2526 
2527                 .first_sysupgrade_partition = "os-image",
2528                 .last_sysupgrade_partition = "file-system"
2529         },
2530 
2531         /** Firmware layout for the TL-WR902AC v1 */
2532         {
2533                 .id     = "TL-WR902AC-V1",
2534                 .vendor = "",
2535                 .support_list =
2536                         "SupportList:\n"
2537                         "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:45550000}\n"
2538                         "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:55530000}\n",
2539                 .part_trail = 0x00,
2540                 .soft_ver = SOFT_VER_DEFAULT,
2541 
2542                 /**
2543                    384KB were moved from file-system to os-image
2544                    in comparison to the stock image
2545                 */
2546                 .partitions = {
2547                         {"fs-uboot", 0x00000, 0x20000},
2548                         {"firmware", 0x20000, 0x730000},
2549                         {"default-mac", 0x750000, 0x00200},
2550                         {"pin", 0x750200, 0x00200},
2551                         {"product-info", 0x750400, 0x0fc00},
2552                         {"soft-version", 0x760000, 0x0b000},
2553                         {"support-list", 0x76b000, 0x04000},
2554                         {"profile", 0x770000, 0x04000},
2555                         {"default-config", 0x774000, 0x0b000},
2556                         {"user-config", 0x780000, 0x40000},
2557                         {"partition-table", 0x7c0000, 0x10000},
2558                         {"log", 0x7d0000, 0x20000},
2559                         {"radio", 0x7f0000, 0x10000},
2560                         {NULL, 0, 0}
2561                 },
2562 
2563                 .first_sysupgrade_partition = "os-image",
2564                 .last_sysupgrade_partition = "file-system",
2565         },
2566 
2567         /** Firmware layout for the TL-WR941HP v1 */
2568         {
2569                 .id     = "TL-WR941HP-V1",
2570                 .vendor = "",
2571                 .support_list =
2572                         "SupportList:\n"
2573                         "{product_name:TL-WR941HP,product_ver:1.0.0,special_id:00000000}\n",
2574                 .part_trail = 0x00,
2575                 .soft_ver = SOFT_VER_DEFAULT,
2576 
2577                 .partitions = {
2578                         {"fs-uboot", 0x00000, 0x20000},
2579                         {"firmware", 0x20000, 0x730000},
2580                         {"default-mac", 0x750000, 0x00200},
2581                         {"pin", 0x750200, 0x00200},
2582                         {"product-info", 0x750400, 0x0fc00},
2583                         {"soft-version", 0x760000, 0x0b000},
2584                         {"support-list", 0x76b000, 0x04000},
2585                         {"profile", 0x770000, 0x04000},
2586                         {"default-config", 0x774000, 0x0b000},
2587                         {"user-config", 0x780000, 0x40000},
2588                         {"partition-table", 0x7c0000, 0x10000},
2589                         {"log", 0x7d0000, 0x20000},
2590                         {"radio", 0x7f0000, 0x10000},
2591                         {NULL, 0, 0}
2592                 },
2593 
2594                 .first_sysupgrade_partition = "os-image",
2595                 .last_sysupgrade_partition = "file-system",
2596         },
2597 
2598         /** Firmware layout for the TL-WR942N V1 */
2599         {
2600                 .id     = "TLWR942NV1",
2601                 .vendor = "",
2602                 .support_list =
2603                         "SupportList:\r\n"
2604                         "{product_name:TL-WR942N,product_ver:1.0.0,special_id:00000000}\r\n"
2605                         "{product_name:TL-WR942N,product_ver:1.0.0,special_id:52550000}\r\n",
2606                 .part_trail = 0x00,
2607                 .soft_ver = SOFT_VER_DEFAULT,
2608 
2609                 .partitions = {
2610                         {"fs-uboot", 0x00000, 0x20000},
2611                         {"firmware", 0x20000, 0xe20000},
2612                         {"default-mac", 0xe40000, 0x00200},
2613                         {"pin", 0xe40200, 0x00200},
2614                         {"product-info", 0xe40400, 0x0fc00},
2615                         {"partition-table", 0xe50000, 0x10000},
2616                         {"soft-version", 0xe60000, 0x10000},
2617                         {"support-list", 0xe70000, 0x10000},
2618                         {"profile", 0xe80000, 0x10000},
2619                         {"default-config", 0xe90000, 0x10000},
2620                         {"user-config", 0xea0000, 0x40000},
2621                         {"qos-db", 0xee0000, 0x40000},
2622                         {"certificate", 0xf20000, 0x10000},
2623                         {"usb-config", 0xfb0000, 0x10000},
2624                         {"log", 0xfc0000, 0x20000},
2625                         {"radio-bk", 0xfe0000, 0x10000},
2626                         {"radio", 0xff0000, 0x10000},
2627                         {NULL, 0, 0}
2628                 },
2629 
2630                 .first_sysupgrade_partition = "os-image",
2631                 .last_sysupgrade_partition = "file-system",
2632         },
2633 
2634   /** Firmware layout for the RE200 v2 */
2635         {
2636                 .id     = "RE200-V2",
2637                 .vendor = "",
2638                 .support_list =
2639                         "SupportList:\n"
2640                         "{product_name:RE200,product_ver:2.0.0,special_id:00000000}\n"
2641                         "{product_name:RE200,product_ver:2.0.0,special_id:41520000}\n"
2642                         "{product_name:RE200,product_ver:2.0.0,special_id:41550000}\n"
2643                         "{product_name:RE200,product_ver:2.0.0,special_id:42520000}\n"
2644                         "{product_name:RE200,product_ver:2.0.0,special_id:43410000}\n"
2645                         "{product_name:RE200,product_ver:2.0.0,special_id:45530000}\n"
2646                         "{product_name:RE200,product_ver:2.0.0,special_id:45550000}\n"
2647                         "{product_name:RE200,product_ver:2.0.0,special_id:49440000}\n"
2648                         "{product_name:RE200,product_ver:2.0.0,special_id:4a500000}\n"
2649                         "{product_name:RE200,product_ver:2.0.0,special_id:4b520000}\n"
2650                         "{product_name:RE200,product_ver:2.0.0,special_id:52550000}\n"
2651                         "{product_name:RE200,product_ver:2.0.0,special_id:54570000}\n"
2652                         "{product_name:RE200,product_ver:2.0.0,special_id:55530000}\n",
2653                 .part_trail = 0x00,
2654                 .soft_ver = SOFT_VER_DEFAULT,
2655 
2656                 .partitions = {
2657                         {"fs-uboot", 0x00000, 0x20000},
2658                         {"firmware", 0x20000, 0x7a0000},
2659                         {"partition-table", 0x7c0000, 0x02000},
2660                         {"default-mac", 0x7c2000, 0x00020},
2661                         {"pin", 0x7c2100, 0x00020},
2662                         {"product-info", 0x7c3100, 0x01000},
2663                         {"soft-version", 0x7c4200, 0x01000},
2664                         {"support-list", 0x7c5200, 0x01000},
2665                         {"profile", 0x7c6200, 0x08000},
2666                         {"config-info", 0x7ce200, 0x00400},
2667                         {"user-config", 0x7d0000, 0x10000},
2668                         {"default-config", 0x7e0000, 0x10000},
2669                         {"radio", 0x7f0000, 0x10000},
2670                         {NULL, 0, 0}
2671                 },
2672 
2673                 .first_sysupgrade_partition = "os-image",
2674                 .last_sysupgrade_partition = "file-system"
2675         },
2676 
2677   /** Firmware layout for the RE200 v3 */
2678         {
2679                 .id     = "RE200-V3",
2680                 .vendor = "",
2681                 .support_list =
2682                         "SupportList:\n"
2683                         "{product_name:RE200,product_ver:3.0.0,special_id:00000000}\n"
2684                         "{product_name:RE200,product_ver:3.0.0,special_id:41520000}\n"
2685                         "{product_name:RE200,product_ver:3.0.0,special_id:41550000}\n"
2686                         "{product_name:RE200,product_ver:3.0.0,special_id:42520000}\n"
2687                         "{product_name:RE200,product_ver:3.0.0,special_id:43410000}\n"
2688                         "{product_name:RE200,product_ver:3.0.0,special_id:45470000}\n"
2689                         "{product_name:RE200,product_ver:3.0.0,special_id:45530000}\n"
2690                         "{product_name:RE200,product_ver:3.0.0,special_id:45550000}\n"
2691                         "{product_name:RE200,product_ver:3.0.0,special_id:49440000}\n"
2692                         "{product_name:RE200,product_ver:3.0.0,special_id:4A500000}\n"
2693                         "{product_name:RE200,product_ver:3.0.0,special_id:4B520000}\n"
2694                         "{product_name:RE200,product_ver:3.0.0,special_id:52550000}\n"
2695                         "{product_name:RE200,product_ver:3.0.0,special_id:54570000}\n"
2696                         "{product_name:RE200,product_ver:3.0.0,special_id:55530000}\n",
2697                 .part_trail = 0x00,
2698                 .soft_ver = SOFT_VER_DEFAULT,
2699 
2700                 .partitions = {
2701                         {"fs-uboot", 0x00000, 0x20000},
2702                         {"firmware", 0x20000, 0x7a0000},
2703                         {"partition-table", 0x7c0000, 0x02000},
2704                         {"default-mac", 0x7c2000, 0x00020},
2705                         {"pin", 0x7c2100, 0x00020},
2706                         {"product-info", 0x7c3100, 0x01000},
2707                         {"soft-version", 0x7c4200, 0x01000},
2708                         {"support-list", 0x7c5200, 0x01000},
2709                         {"profile", 0x7c6200, 0x08000},
2710                         {"config-info", 0x7ce200, 0x00400},
2711                         {"user-config", 0x7d0000, 0x10000},
2712                         {"default-config", 0x7e0000, 0x10000},
2713                         {"radio", 0x7f0000, 0x10000},
2714                         {NULL, 0, 0}
2715                 },
2716 
2717                 .first_sysupgrade_partition = "os-image",
2718                 .last_sysupgrade_partition = "file-system"
2719         },
2720 
2721   /** Firmware layout for the RE200 v4 */
2722         {
2723                 .id     = "RE200-V4",
2724                 .vendor = "",
2725                 .support_list =
2726                         "SupportList:\n"
2727                         "{product_name:RE200,product_ver:4.0.0,special_id:00000000}\n"
2728                         "{product_name:RE200,product_ver:4.0.0,special_id:45550000}\n"
2729                         "{product_name:RE200,product_ver:4.0.0,special_id:4A500000}\n"
2730                         "{product_name:RE200,product_ver:4.0.0,special_id:4B520000}\n"
2731                         "{product_name:RE200,product_ver:4.0.0,special_id:43410000}\n"
2732                         "{product_name:RE200,product_ver:4.0.0,special_id:41550000}\n"
2733                         "{product_name:RE200,product_ver:4.0.0,special_id:42520000}\n"
2734                         "{product_name:RE200,product_ver:4.0.0,special_id:55530000}\n"
2735                         "{product_name:RE200,product_ver:4.0.0,special_id:41520000}\n"
2736                         "{product_name:RE200,product_ver:4.0.0,special_id:52550000}\n"
2737                         "{product_name:RE200,product_ver:4.0.0,special_id:54570000}\n"
2738                         "{product_name:RE200,product_ver:4.0.0,special_id:45530000}\n"
2739                         "{product_name:RE200,product_ver:4.0.0,special_id:49440000}\n"
2740                         "{product_name:RE200,product_ver:4.0.0,special_id:45470000}\n",
2741                 .part_trail = 0x00,
2742                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.1.0\n"),
2743 
2744                 .partitions = {
2745                         {"fs-uboot", 0x00000, 0x20000},
2746                         {"firmware", 0x20000, 0x7a0000},
2747                         {"partition-table", 0x7c0000, 0x02000},
2748                         {"default-mac", 0x7c2000, 0x00020},
2749                         {"pin", 0x7c2100, 0x00020},
2750                         {"product-info", 0x7c3100, 0x01000},
2751                         {"soft-version", 0x7c4200, 0x01000},
2752                         {"support-list", 0x7c5200, 0x01000},
2753                         {"profile", 0x7c6200, 0x08000},
2754                         {"config-info", 0x7ce200, 0x00400},
2755                         {"user-config", 0x7d0000, 0x10000},
2756                         {"default-config", 0x7e0000, 0x10000},
2757                         {"radio", 0x7f0000, 0x10000},
2758                         {NULL, 0, 0}
2759                 },
2760 
2761                 .first_sysupgrade_partition = "os-image",
2762                 .last_sysupgrade_partition = "file-system"
2763         },
2764 
2765         /** Firmware layout for the RE205 v3 */
2766         {
2767                 .id     = "RE205-V3",
2768                 .vendor = "",
2769                 .support_list =
2770                         "SupportList:\n"
2771                         "{product_name:RE205,product_ver:3.0.0,special_id:00000000}\n"
2772                         "{product_name:RE205,product_ver:3.0.0,special_id:45550000}\n"
2773                         "{product_name:RE205,product_ver:3.0.0,special_id:4A500000}\n"
2774                         "{product_name:RE205,product_ver:3.0.0,special_id:4B520000}\n"
2775                         "{product_name:RE205,product_ver:3.0.0,special_id:43410000}\n"
2776                         "{product_name:RE205,product_ver:3.0.0,special_id:41550000}\n"
2777                         "{product_name:RE205,product_ver:3.0.0,special_id:42520000}\n"
2778                         "{product_name:RE205,product_ver:3.0.0,special_id:55530000}\n"
2779                         "{product_name:RE205,product_ver:3.0.0,special_id:41520000}\n"
2780                         "{product_name:RE205,product_ver:3.0.0,special_id:52550000}\n"
2781                         "{product_name:RE205,product_ver:3.0.0,special_id:54570000}\n"
2782                         "{product_name:RE205,product_ver:3.0.0,special_id:45530000}\n"
2783                         "{product_name:RE205,product_ver:3.0.0,special_id:45470000}\n",
2784                 .part_trail = 0x00,
2785                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.1.0\n"),
2786 
2787                 .partitions = {
2788                         {"fs-uboot", 0x00000, 0x20000},
2789                         {"firmware", 0x20000, 0x7a0000},
2790                         {"partition-table", 0x7c0000, 0x02000},
2791                         {"default-mac", 0x7c2000, 0x00020},
2792                         {"pin", 0x7c2100, 0x00020},
2793                         {"product-info", 0x7c3100, 0x01000},
2794                         {"soft-version", 0x7c4200, 0x01000},
2795                         {"support-list", 0x7c5200, 0x01000},
2796                         {"profile", 0x7c6200, 0x08000},
2797                         {"config-info", 0x7ce200, 0x00400},
2798                         {"user-config", 0x7d0000, 0x10000},
2799                         {"default-config", 0x7e0000, 0x10000},
2800                         {"radio", 0x7f0000, 0x10000},
2801                         {NULL, 0, 0}
2802                 },
2803 
2804                 .first_sysupgrade_partition = "os-image",
2805                 .last_sysupgrade_partition = "file-system"
2806         },
2807 
2808         /** Firmware layout for the RE220 v2 */
2809         {
2810                 .id     = "RE220-V2",
2811                 .vendor = "",
2812                 .support_list =
2813                         "SupportList:\n"
2814                         "{product_name:RE220,product_ver:2.0.0,special_id:00000000}\n"
2815                         "{product_name:RE220,product_ver:2.0.0,special_id:41520000}\n"
2816                         "{product_name:RE220,product_ver:2.0.0,special_id:41550000}\n"
2817                         "{product_name:RE220,product_ver:2.0.0,special_id:42520000}\n"
2818                         "{product_name:RE220,product_ver:2.0.0,special_id:43410000}\n"
2819                         "{product_name:RE220,product_ver:2.0.0,special_id:45530000}\n"
2820                         "{product_name:RE220,product_ver:2.0.0,special_id:45550000}\n"
2821                         "{product_name:RE220,product_ver:2.0.0,special_id:49440000}\n"
2822                         "{product_name:RE220,product_ver:2.0.0,special_id:4a500000}\n"
2823                         "{product_name:RE220,product_ver:2.0.0,special_id:4b520000}\n"
2824                         "{product_name:RE220,product_ver:2.0.0,special_id:52550000}\n"
2825                         "{product_name:RE220,product_ver:2.0.0,special_id:54570000}\n"
2826                         "{product_name:RE220,product_ver:2.0.0,special_id:55530000}\n",
2827                 .part_trail = 0x00,
2828                 .soft_ver = SOFT_VER_DEFAULT,
2829 
2830                 .partitions = {
2831                         {"fs-uboot", 0x00000, 0x20000},
2832                         {"firmware", 0x20000, 0x7a0000},
2833                         {"partition-table", 0x7c0000, 0x02000},
2834                         {"default-mac", 0x7c2000, 0x00020},
2835                         {"pin", 0x7c2100, 0x00020},
2836                         {"product-info", 0x7c3100, 0x01000},
2837                         {"soft-version", 0x7c4200, 0x01000},
2838                         {"support-list", 0x7c5200, 0x01000},
2839                         {"profile", 0x7c6200, 0x08000},
2840                         {"config-info", 0x7ce200, 0x00400},
2841                         {"user-config", 0x7d0000, 0x10000},
2842                         {"default-config", 0x7e0000, 0x10000},
2843                         {"radio", 0x7f0000, 0x10000},
2844                         {NULL, 0, 0}
2845                 },
2846 
2847                 .first_sysupgrade_partition = "os-image",
2848                 .last_sysupgrade_partition = "file-system"
2849         },
2850 
2851   /** Firmware layout for the RE305 v1 */
2852         {
2853                 .id     = "RE305-V1",
2854                 .vendor = "",
2855                 .support_list =
2856                         "SupportList:\n"
2857                         "{product_name:RE305,product_ver:1.0.0,special_id:45550000}\n"
2858                         "{product_name:RE305,product_ver:1.0.0,special_id:55530000}\n"
2859                         "{product_name:RE305,product_ver:1.0.0,special_id:4a500000}\n"
2860                         "{product_name:RE305,product_ver:1.0.0,special_id:42520000}\n"
2861                         "{product_name:RE305,product_ver:1.0.0,special_id:4b520000}\n"
2862                         "{product_name:RE305,product_ver:1.0.0,special_id:41550000}\n"
2863                         "{product_name:RE305,product_ver:1.0.0,special_id:43410000}\n",
2864                 .part_trail = 0x00,
2865                 .soft_ver = SOFT_VER_DEFAULT,
2866 
2867                 .partitions = {
2868                         {"fs-uboot", 0x00000, 0x20000},
2869                         {"firmware", 0x20000, 0x5e0000},
2870                         {"partition-table", 0x600000, 0x02000},
2871                         {"default-mac", 0x610000, 0x00020},
2872                         {"pin", 0x610100, 0x00020},
2873                         {"product-info", 0x611100, 0x01000},
2874                         {"soft-version", 0x620000, 0x01000},
2875                         {"support-list", 0x621000, 0x01000},
2876                         {"profile", 0x622000, 0x08000},
2877                         {"user-config", 0x630000, 0x10000},
2878                         {"default-config", 0x640000, 0x10000},
2879                         {"radio", 0x7f0000, 0x10000},
2880                         {NULL, 0, 0}
2881                 },
2882 
2883                 .first_sysupgrade_partition = "os-image",
2884                 .last_sysupgrade_partition = "file-system"
2885         },
2886 
2887         /** Firmware layout for the RE305 v3 */
2888         {
2889                 .id     = "RE305-V3",
2890                 .vendor = "",
2891                 .support_list =
2892                         "SupportList:\n"
2893                         "{product_name:RE305,product_ver:3.0.0,special_id:00000000}\n"
2894                         "{product_name:RE305,product_ver:3.0.0,special_id:45550000}\n"
2895                         "{product_name:RE305,product_ver:3.0.0,special_id:4A500000}\n"
2896                         "{product_name:RE305,product_ver:3.0.0,special_id:4B520000}\n"
2897                         "{product_name:RE305,product_ver:3.0.0,special_id:41550000}\n"
2898                         "{product_name:RE305,product_ver:3.0.0,special_id:42520000}\n"
2899                         "{product_name:RE305,product_ver:3.0.0,special_id:55530000}\n"
2900                         "{product_name:RE305,product_ver:3.0.0,special_id:45530000}\n"
2901                         "{product_name:RE305,product_ver:3.0.0,special_id:41530000}\n"
2902                         "{product_name:RE305,product_ver:3.0.0,special_id:43410000}\n"
2903                         "{product_name:RE305,product_ver:3.0.0,special_id:52550000}\n",
2904                 .part_trail = 0x00,
2905                 .soft_ver = SOFT_VER_TEXT("soft_ver:2.0.0\n"),
2906 
2907                 .partitions = {
2908                         {"fs-uboot", 0x00000, 0x20000},
2909                         {"firmware", 0x20000, 0x7a0000},
2910                         {"partition-table", 0x7c0000, 0x02000},
2911                         {"default-mac", 0x7c2000, 0x00020},
2912                         {"pin", 0x7c2100, 0x00020},
2913                         {"product-info", 0x7c3100, 0x01000},
2914                         {"soft-version", 0x7c4200, 0x01000},
2915                         {"support-list", 0x7c5200, 0x01000},
2916                         {"profile", 0x7c6200, 0x08000},
2917                         {"config-info", 0x7ce200, 0x00400},
2918                         {"user-config", 0x7d0000, 0x10000},
2919                         {"default-config", 0x7e0000, 0x10000},
2920                         {"radio", 0x7f0000, 0x10000},
2921                         {NULL, 0, 0}
2922                 },
2923 
2924                 .first_sysupgrade_partition = "os-image",
2925                 .last_sysupgrade_partition = "file-system"
2926         },
2927 
2928         /** Firmware layout for the RE350 v1 */
2929         {
2930                 .id     = "RE350-V1",
2931                 .vendor = "",
2932                 .support_list =
2933                         "SupportList:\n"
2934                         "{product_name:RE350,product_ver:1.0.0,special_id:45550000}\n"
2935                         "{product_name:RE350,product_ver:1.0.0,special_id:00000000}\n"
2936                         "{product_name:RE350,product_ver:1.0.0,special_id:41550000}\n"
2937                         "{product_name:RE350,product_ver:1.0.0,special_id:55530000}\n"
2938                         "{product_name:RE350,product_ver:1.0.0,special_id:43410000}\n"
2939                         "{product_name:RE350,product_ver:1.0.0,special_id:4b520000}\n"
2940                         "{product_name:RE350,product_ver:1.0.0,special_id:4a500000}\n",
2941                 .part_trail = 0x00,
2942                 .soft_ver = SOFT_VER_DEFAULT,
2943 
2944                 /** We're using a dynamic kernel/rootfs split here */
2945                 .partitions = {
2946                         {"fs-uboot", 0x00000, 0x20000},
2947                         {"firmware", 0x20000, 0x5e0000},
2948                         {"partition-table", 0x600000, 0x02000},
2949                         {"default-mac", 0x610000, 0x00020},
2950                         {"pin", 0x610100, 0x00020},
2951                         {"product-info", 0x611100, 0x01000},
2952                         {"soft-version", 0x620000, 0x01000},
2953                         {"support-list", 0x621000, 0x01000},
2954                         {"profile", 0x622000, 0x08000},
2955                         {"user-config", 0x630000, 0x10000},
2956                         {"default-config", 0x640000, 0x10000},
2957                         {"radio", 0x7f0000, 0x10000},
2958                         {NULL, 0, 0}
2959                 },
2960 
2961                 .first_sysupgrade_partition = "os-image",
2962                 .last_sysupgrade_partition = "file-system"
2963         },
2964 
2965         /** Firmware layout for the RE350K v1 */
2966         {
2967                 .id     = "RE350K-V1",
2968                 .vendor = "",
2969                 .support_list =
2970                         "SupportList:\n"
2971                         "{product_name:RE350K,product_ver:1.0.0,special_id:00000000,product_region:US}\n",
2972                 .part_trail = 0x00,
2973                 .soft_ver = SOFT_VER_DEFAULT,
2974 
2975                 /** We're using a dynamic kernel/rootfs split here */
2976                 .partitions = {
2977                         {"fs-uboot", 0x00000, 0x20000},
2978                         {"firmware", 0x20000, 0xd70000},
2979                         {"partition-table", 0xd90000, 0x02000},
2980                         {"default-mac", 0xda0000, 0x00020},
2981                         {"pin", 0xda0100, 0x00020},
2982                         {"product-info", 0xda1100, 0x01000},
2983                         {"soft-version", 0xdb0000, 0x01000},
2984                         {"support-list", 0xdb1000, 0x01000},
2985                         {"profile", 0xdb2000, 0x08000},
2986                         {"user-config", 0xdc0000, 0x10000},
2987                         {"default-config", 0xdd0000, 0x10000},
2988                         {"device-id", 0xde0000, 0x00108},
2989                         {"radio", 0xff0000, 0x10000},
2990                         {NULL, 0, 0}
2991                 },
2992 
2993                 .first_sysupgrade_partition = "os-image",
2994                 .last_sysupgrade_partition = "file-system"
2995         },
2996 
2997         /** Firmware layout for the RE355 */
2998         {
2999                 .id     = "RE355",
3000                 .vendor = "",
3001                 .support_list =
3002                         "SupportList:\r\n"
3003                         "{product_name:RE355,product_ver:1.0.0,special_id:00000000}\r\n"
3004                         "{product_name:RE355,product_ver:1.0.0,special_id:55530000}\r\n"
3005                         "{product_name:RE355,product_ver:1.0.0,special_id:45550000}\r\n"
3006                         "{product_name:RE355,product_ver:1.0.0,special_id:4A500000}\r\n"
3007                         "{product_name:RE355,product_ver:1.0.0,special_id:43410000}\r\n"
3008                         "{product_name:RE355,product_ver:1.0.0,special_id:41550000}\r\n"
3009                         "{product_name:RE355,product_ver:1.0.0,special_id:4B520000}\r\n"
3010                         "{product_name:RE355,product_ver:1.0.0,special_id:55534100}\r\n",
3011                 .part_trail = 0x00,
3012                 .soft_ver = SOFT_VER_DEFAULT,
3013 
3014                 /* We're using a dynamic kernel/rootfs split here */
3015                 .partitions = {
3016                         {"fs-uboot", 0x00000, 0x20000},
3017                         {"firmware", 0x20000, 0x5e0000},
3018                         {"partition-table", 0x600000, 0x02000},
3019                         {"default-mac", 0x610000, 0x00020},
3020                         {"pin", 0x610100, 0x00020},
3021                         {"product-info", 0x611100, 0x01000},
3022                         {"soft-version", 0x620000, 0x01000},
3023                         {"support-list", 0x621000, 0x01000},
3024                         {"profile", 0x622000, 0x08000},
3025                         {"user-config", 0x630000, 0x10000},
3026                         {"default-config", 0x640000, 0x10000},
3027                         {"radio", 0x7f0000, 0x10000},
3028                         {NULL, 0, 0}
3029                 },
3030 
3031                 .first_sysupgrade_partition = "os-image",
3032                 .last_sysupgrade_partition = "file-system"
3033         },
3034 
3035         /** Firmware layout for the RE365 v1 */
3036         {
3037                 .id     = "RE365",
3038                 .vendor = "",
3039                 .support_list =
3040                         "SupportList:\r\n"
3041                         "{product_name:RE365,product_ver:1.0.0,special_id:45550000}\r\n"
3042                         "{product_name:RE365,product_ver:1.0.0,special_id:55530000}\r\n"
3043                         "{product_name:RE365,product_ver:1.0.0,special_id:4a500000}\r\n"
3044                         "{product_name:RE365,product_ver:1.0.0,special_id:42520000}\r\n"
3045                         "{product_name:RE365,product_ver:1.0.0,special_id:4b520000}\r\n"
3046                         "{product_name:RE365,product_ver:1.0.0,special_id:41550000}\r\n"
3047                         "{product_name:RE365,product_ver:1.0.0,special_id:43410000}\r\n"
3048                         "{product_name:RE365,product_ver:1.0.0,special_id:54570000}\r\n"
3049                         "{product_name:RE365,product_ver:1.0.0,special_id:41530000}\r\n",
3050                 .part_trail = 0x00,
3051                 .soft_ver = SOFT_VER_DEFAULT,
3052 
3053                 .partitions = {
3054                         {"fs-uboot", 0x00000, 0x20000},
3055                         {"firmware", 0x20000, 0x5e0000},
3056                         {"partition-table", 0x600000, 0x02000},
3057                         {"default-mac", 0x610000, 0x00020},
3058                         {"pin", 0x610100, 0x00020},
3059                         {"product-info", 0x611100, 0x01000},
3060                         {"soft-version", 0x620000, 0x01000},
3061                         {"support-list", 0x621000, 0x01000},
3062                         {"profile", 0x622000, 0x08000},
3063                         {"user-config", 0x630000, 0x10000},
3064                         {"default-config", 0x640000, 0x10000},
3065                         {"radio", 0x7f0000, 0x10000},
3066                         {NULL, 0, 0}
3067                 },
3068 
3069                 .first_sysupgrade_partition = "os-image",
3070                 .last_sysupgrade_partition = "file-system"
3071         },
3072 
3073         /** Firmware layout for the RE450 */
3074         {
3075                 .id     = "RE450",
3076                 .vendor = "",
3077                 .support_list =
3078                         "SupportList:\r\n"
3079                         "{product_name:RE450,product_ver:1.0.0,special_id:00000000}\r\n"
3080                         "{product_name:RE450,product_ver:1.0.0,special_id:55530000}\r\n"
3081                         "{product_name:RE450,product_ver:1.0.0,special_id:45550000}\r\n"
3082                         "{product_name:RE450,product_ver:1.0.0,special_id:4A500000}\r\n"
3083                         "{product_name:RE450,product_ver:1.0.0,special_id:43410000}\r\n"
3084                         "{product_name:RE450,product_ver:1.0.0,special_id:41550000}\r\n"
3085                         "{product_name:RE450,product_ver:1.0.0,special_id:4B520000}\r\n"
3086                         "{product_name:RE450,product_ver:1.0.0,special_id:55534100}\r\n",
3087                 .part_trail = 0x00,
3088                 .soft_ver = SOFT_VER_DEFAULT,
3089 
3090                 /** We're using a dynamic kernel/rootfs split here */
3091                 .partitions = {
3092                         {"fs-uboot", 0x00000, 0x20000},
3093                         {"firmware", 0x20000, 0x5e0000},
3094                         {"partition-table", 0x600000, 0x02000},
3095                         {"default-mac", 0x610000, 0x00020},
3096                         {"pin", 0x610100, 0x00020},
3097                         {"product-info", 0x611100, 0x01000},
3098                         {"soft-version", 0x620000, 0x01000},
3099                         {"support-list", 0x621000, 0x01000},
3100                         {"profile", 0x622000, 0x08000},
3101                         {"user-config", 0x630000, 0x10000},
3102                         {"default-config", 0x640000, 0x10000},
3103                         {"radio", 0x7f0000, 0x10000},
3104                         {NULL, 0, 0}
3105                 },
3106 
3107                 .first_sysupgrade_partition = "os-image",
3108                 .last_sysupgrade_partition = "file-system"
3109         },
3110 
3111         /** Firmware layout for the RE450 v2 */
3112         {
3113                 .id     = "RE450-V2",
3114                 .vendor = "",
3115                 .support_list =
3116                         "SupportList:\r\n"
3117                         "{product_name:RE450,product_ver:2.0.0,special_id:00000000}\r\n"
3118                         "{product_name:RE450,product_ver:2.0.0,special_id:55530000}\r\n"
3119                         "{product_name:RE450,product_ver:2.0.0,special_id:45550000}\r\n"
3120                         "{product_name:RE450,product_ver:2.0.0,special_id:4A500000}\r\n"
3121                         "{product_name:RE450,product_ver:2.0.0,special_id:43410000}\r\n"
3122                         "{product_name:RE450,product_ver:2.0.0,special_id:41550000}\r\n"
3123                         "{product_name:RE450,product_ver:2.0.0,special_id:41530000}\r\n"
3124                         "{product_name:RE450,product_ver:2.0.0,special_id:4B520000}\r\n"
3125                         "{product_name:RE450,product_ver:2.0.0,special_id:42520000}\r\n",
3126                 .part_trail = 0x00,
3127                 .soft_ver = SOFT_VER_DEFAULT,
3128 
3129                 /* We're using a dynamic kernel/rootfs split here */
3130                 .partitions = {
3131                         {"fs-uboot", 0x00000, 0x20000},
3132                         {"firmware", 0x20000, 0x5e0000},
3133                         {"partition-table", 0x600000, 0x02000},
3134                         {"default-mac", 0x610000, 0x00020},
3135                         {"pin", 0x610100, 0x00020},
3136                         {"product-info", 0x611100, 0x01000},
3137                         {"soft-version", 0x620000, 0x01000},
3138                         {"support-list", 0x621000, 0x01000},
3139                         {"profile", 0x622000, 0x08000},
3140                         {"user-config", 0x630000, 0x10000},
3141                         {"default-config", 0x640000, 0x10000},
3142                         {"radio", 0x7f0000, 0x10000},
3143                         {NULL, 0, 0}
3144                 },
3145 
3146                 .first_sysupgrade_partition = "os-image",
3147                 .last_sysupgrade_partition = "file-system"
3148         },
3149 
3150         /** Firmware layout for the RE450 v3 */
3151         {
3152                 .id     = "RE450-V3",
3153                 .vendor = "",
3154                 .support_list =
3155                         "SupportList:\r\n"
3156                         "{product_name:RE450,product_ver:3.0.0,special_id:00000000}\r\n"
3157                         "{product_name:RE450,product_ver:3.0.0,special_id:55530000}\r\n"
3158                         "{product_name:RE450,product_ver:3.0.0,special_id:45550000}\r\n"
3159                         "{product_name:RE450,product_ver:3.0.0,special_id:4A500000}\r\n"
3160                         "{product_name:RE450,product_ver:3.0.0,special_id:43410000}\r\n"
3161                         "{product_name:RE450,product_ver:3.0.0,special_id:41550000}\r\n"
3162                         "{product_name:RE450,product_ver:3.0.0,special_id:41530000}\r\n"
3163                         "{product_name:RE450,product_ver:3.0.0,special_id:4B520000}\r\n"
3164                         "{product_name:RE450,product_ver:3.0.0,special_id:42520000}\r\n",
3165                 .part_trail = 0x00,
3166                 .soft_ver = SOFT_VER_DEFAULT,
3167 
3168                 /* We're using a dynamic kernel/rootfs split here */
3169                 .partitions = {
3170                         {"fs-uboot", 0x00000, 0x20000},
3171                         {"default-mac", 0x20000, 0x00020},
3172                         {"pin", 0x20020, 0x00020},
3173                         {"product-info", 0x21000, 0x01000},
3174                         {"partition-table", 0x22000, 0x02000},
3175                         {"soft-version", 0x24000, 0x01000},
3176                         {"support-list", 0x25000, 0x01000},
3177                         {"profile", 0x26000, 0x08000},
3178                         {"user-config", 0x2e000, 0x10000},
3179                         {"default-config", 0x3e000, 0x10000},
3180                         {"config-info", 0x4e000, 0x00400},
3181                         {"firmware", 0x50000, 0x7a0000},
3182                         {"radio", 0x7f0000, 0x10000},
3183                         {NULL, 0, 0}
3184                 },
3185 
3186                 .first_sysupgrade_partition = "os-image",
3187                 .last_sysupgrade_partition = "file-system"
3188         },
3189 
3190         /** Firmware layout for the RE455 v1 */
3191         {
3192                 .id     = "RE455-V1",
3193                 .vendor = "",
3194                 .support_list =
3195                         "SupportList:\r\n"
3196                         "{product_name:RE455,product_ver:1.0.0,special_id:00000000}\r\n"
3197                         "{product_name:RE455,product_ver:1.0.0,special_id:55530000}\r\n"
3198                         "{product_name:RE455,product_ver:1.0.0,special_id:45550000}\r\n"
3199                         "{product_name:RE455,product_ver:1.0.0,special_id:4A500000}\r\n"
3200                         "{product_name:RE455,product_ver:1.0.0,special_id:43410000}\r\n"
3201                         "{product_name:RE455,product_ver:1.0.0,special_id:41550000}\r\n"
3202                         "{product_name:RE455,product_ver:1.0.0,special_id:41530000}\r\n"
3203                         "{product_name:RE455,product_ver:1.0.0,special_id:4B520000}\r\n"
3204                         "{product_name:RE455,product_ver:1.0.0,special_id:42520000}\r\n",
3205                 .part_trail = 0x00,
3206                 .soft_ver = SOFT_VER_DEFAULT,
3207 
3208                 /* We're using a dynamic kernel/rootfs split here */
3209                 .partitions = {
3210                         {"fs-uboot", 0x00000, 0x20000},
3211                         {"default-mac", 0x20000, 0x00020},
3212                         {"pin", 0x20020, 0x00020},
3213                         {"product-info", 0x21000, 0x01000},
3214                         {"partition-table", 0x22000, 0x02000},
3215                         {"soft-version", 0x24000, 0x01000},
3216                         {"support-list", 0x25000, 0x01000},
3217                         {"profile", 0x26000, 0x08000},
3218                         {"user-config", 0x2e000, 0x10000},
3219                         {"default-config", 0x3e000, 0x10000},
3220                         {"config-info", 0x4e000, 0x00400},
3221                         {"firmware", 0x50000, 0x7a0000},
3222                         {"radio", 0x7f0000, 0x10000},
3223                         {NULL, 0, 0}
3224                 },
3225 
3226                 .first_sysupgrade_partition = "os-image",
3227                 .last_sysupgrade_partition = "file-system"
3228         },
3229 
3230         /** Firmware layout for the RE500 */
3231         {
3232                 .id     = "RE500-V1",
3233                 .vendor = "",
3234                 .support_list =
3235                         "SupportList:\r\n"
3236                         "{product_name:RE500,product_ver:1.0.0,special_id:00000000}\r\n"
3237                         "{product_name:RE500,product_ver:1.0.0,special_id:55530000}\r\n"
3238                         "{product_name:RE500,product_ver:1.0.0,special_id:45550000}\r\n"
3239                         "{product_name:RE500,product_ver:1.0.0,special_id:4A500000}\r\n"
3240                         "{product_name:RE500,product_ver:1.0.0,special_id:43410000}\r\n"
3241                         "{product_name:RE500,product_ver:1.0.0,special_id:41550000}\r\n"
3242                         "{product_name:RE500,product_ver:1.0.0,special_id:41530000}\r\n",
3243                 .part_trail = 0x00,
3244                 .soft_ver = SOFT_VER_DEFAULT,
3245 
3246                 /* We're using a dynamic kernel/rootfs split here */
3247                 .partitions = {
3248                         {"fs-uboot", 0x00000, 0x20000},
3249                         {"firmware", 0x20000, 0xde0000},
3250                         {"partition-table", 0xe00000, 0x02000},
3251                         {"default-mac", 0xe10000, 0x00020},
3252                         {"pin", 0xe10100, 0x00020},
3253                         {"product-info", 0xe11100, 0x01000},
3254                         {"soft-version", 0xe20000, 0x01000},
3255                         {"support-list", 0xe21000, 0x01000},
3256                         {"profile", 0xe22000, 0x08000},
3257                         {"user-config", 0xe30000, 0x10000},
3258                         {"default-config", 0xe40000, 0x10000},
3259                         {"radio", 0xff0000, 0x10000},
3260                         {NULL, 0, 0}
3261                 },
3262 
3263                 .first_sysupgrade_partition = "os-image",
3264                 .last_sysupgrade_partition = "file-system"
3265         },
3266 
3267         /** Firmware layout for the RE650 */
3268         {
3269                 .id     = "RE650-V1",
3270                 .vendor = "",
3271                 .support_list =
3272                         "SupportList:\r\n"
3273                         "{product_name:RE650,product_ver:1.0.0,special_id:00000000}\r\n"
3274                         "{product_name:RE650,product_ver:1.0.0,special_id:55530000}\r\n"
3275                         "{product_name:RE650,product_ver:1.0.0,special_id:45550000}\r\n"
3276                         "{product_name:RE650,product_ver:1.0.0,special_id:4A500000}\r\n"
3277                         "{product_name:RE650,product_ver:1.0.0,special_id:43410000}\r\n"
3278                         "{product_name:RE650,product_ver:1.0.0,special_id:41550000}\r\n"
3279                         "{product_name:RE650,product_ver:1.0.0,special_id:41530000}\r\n",
3280                 .part_trail = 0x00,
3281                 .soft_ver = SOFT_VER_DEFAULT,
3282 
3283                 /* We're using a dynamic kernel/rootfs split here */
3284                 .partitions = {
3285                         {"fs-uboot", 0x00000, 0x20000},
3286                         {"firmware", 0x20000, 0xde0000},
3287                         {"partition-table", 0xe00000, 0x02000},
3288                         {"default-mac", 0xe10000, 0x00020},
3289                         {"pin", 0xe10100, 0x00020},
3290                         {"product-info", 0xe11100, 0x01000},
3291                         {"soft-version", 0xe20000, 0x01000},
3292                         {"support-list", 0xe21000, 0x01000},
3293                         {"profile", 0xe22000, 0x08000},
3294                         {"user-config", 0xe30000, 0x10000},
3295                         {"default-config", 0xe40000, 0x10000},
3296                         {"radio", 0xff0000, 0x10000},
3297                         {NULL, 0, 0}
3298                 },
3299 
3300                 .first_sysupgrade_partition = "os-image",
3301                 .last_sysupgrade_partition = "file-system"
3302         },
3303         /** Firmware layout for the RE650 V2 (8MB Flash)*/
3304         {
3305                 .id     = "RE650-V2",
3306                 .vendor = "",
3307                 .support_list =
3308                         "SupportList:\n"
3309                         "{product_name:RE650,product_ver:2.0.0,special_id:00000000}\n"
3310                         "{product_name:RE650,product_ver:2.0.0,special_id:45550000}\n"
3311                         "{product_name:RE650,product_ver:2.0.0,special_id:4A500000}\n"
3312                         "{product_name:RE650,product_ver:2.0.0,special_id:41550000}\n"
3313                         "{product_name:RE650,product_ver:2.0.0,special_id:43410000}\n"
3314                         "{product_name:RE650,product_ver:2.0.0,special_id:41530000}\n"
3315                         "{product_name:RE650,product_ver:2.0.0,special_id:55530000}\n",
3316                 .part_trail = 0x00,
3317                 /* For RE650 v2, soft ver is required, otherwise OEM install doesn't work */
3318                 .soft_ver = SOFT_VER_TEXT("soft_ver:2.0.0\n"),
3319 
3320                 /* We're using a dynamic kernel/rootfs split here */
3321                 .partitions = {
3322                         {"fs-uboot", 0x00000, 0x20000},
3323                         {"firmware", 0x20000, 0x7a0000},
3324                         {"partition-table", 0x7c0000, 0x02000},
3325                         {"default-mac", 0x7c2000, 0x00020},
3326                         {"pin", 0x7c2100, 0x00020},
3327                         {"product-info", 0x7c3100, 0x01000},
3328                         {"soft-version", 0x7c4200, 0x01000},
3329                         {"support-list", 0x7c5200, 0x01000},
3330                         {"profile", 0x7c6200, 0x08000},
3331                         {"config-info", 0x7ce200, 0x00400},
3332                         {"user-config", 0x7d0000, 0x10000},
3333                         {"default-config", 0x7e0000, 0x10000},
3334                         {"radio", 0x7f0000, 0x10000},
3335                         {NULL, 0, 0}
3336                 },
3337 
3338                 .first_sysupgrade_partition = "os-image",
3339                 .last_sysupgrade_partition = "file-system"
3340         },
3341 
3342         /** Firmware layout for the Mercusys MR70X */
3343         {
3344                 .id     = "MR70X",
3345                 .vendor = "",
3346                 .support_list =
3347                         "SupportList:\n"
3348                         "{product_name:MR70X,product_ver:1.0.0,special_id:45550000}\n"
3349                         "{product_name:MR70X,product_ver:1.0.0,special_id:4A500000}\n"
3350                         "{product_name:MR70X,product_ver:1.0.0,special_id:55530000}\n",
3351                 .part_trail = 0x00,
3352                 .soft_ver = SOFT_VER_DEFAULT,
3353 
3354                 .partitions = {
3355                         {"fs-uboot", 0x00000, 0x40000},
3356                         {"firmware", 0x40000, 0xf60000},
3357                         {"default-mac", 0xfa0000, 0x00200},
3358                         {"pin", 0xfa0200, 0x00100},
3359                         {"device-id", 0xfa0300, 0x00100},
3360                         {"product-info", 0xfa0400, 0x0fc00},
3361                         {"default-config", 0xfb0000, 0x08000},
3362                         {"ap-def-config", 0xfb8000, 0x08000},
3363                         {"user-config", 0xfc0000, 0x0a000},
3364                         {"ag-config", 0xfca000, 0x04000},
3365                         {"certificate", 0xfce000, 0x02000},
3366                         {"ap-config", 0xfd0000, 0x06000},
3367                         {"router-config", 0xfd6000, 0x06000},
3368                         {"favicon", 0xfdc000, 0x02000},
3369                         {"logo", 0xfde000, 0x02000},
3370                         {"partition-table", 0xfe0000, 0x00800},
3371                         {"soft-version", 0xfe0800, 0x00100},
3372                         {"support-list", 0xfe0900, 0x00200},
3373                         {"profile", 0xfe0b00, 0x03000},
3374                         {"extra-para", 0xfe3b00, 0x00100},
3375                         {"radio", 0xff0000, 0x10000},
3376                         {NULL, 0, 0}
3377                 },
3378 
3379                 .first_sysupgrade_partition = "os-image",
3380                 .last_sysupgrade_partition = "file-system"
3381         },
3382 
3383         {}
3384 };
3385 
3386 #define error(_ret, _errno, _str, ...)                          \
3387         do {                                                    \
3388                 fprintf(stderr, _str ": %s\n", ## __VA_ARGS__,  \
3389                         strerror(_errno));                      \
3390                 if (_ret)                                       \
3391                         exit(_ret);                             \
3392         } while (0)
3393 
3394 
3395 /** Stores a uint32 as big endian */
3396 static inline void put32(uint8_t *buf, uint32_t val) {
3397         buf[0] = val >> 24;
3398         buf[1] = val >> 16;
3399         buf[2] = val >> 8;
3400         buf[3] = val;
3401 }
3402 
3403 static inline bool meta_partition_should_pad(enum partition_trail_value pv)
3404 {
3405         return (pv >= 0) && (pv <= PART_TRAIL_MAX);
3406 }
3407 
3408 /** Allocate a padded meta partition with a correctly initialised header
3409  * If the `data` pointer is NULL, then the required space is only allocated,
3410  * otherwise `data_len` bytes will be copied from `data` into the partition
3411  * entry. */
3412 static struct image_partition_entry init_meta_partition_entry(
3413         const char *name, const void *data, uint32_t data_len,
3414         enum partition_trail_value pad_value)
3415 {
3416         uint32_t total_len = sizeof(struct meta_header) + data_len;
3417         if (meta_partition_should_pad(pad_value))
3418                 total_len += 1;
3419 
3420         struct image_partition_entry entry = {
3421                 .name = name,
3422                 .size = total_len,
3423                 .data = malloc(total_len)
3424         };
3425         if (!entry.data)
3426                 error(1, errno, "failed to allocate meta partition entry");
3427 
3428         struct meta_header *header = (struct meta_header *)entry.data;
3429         header->length = htonl(data_len);
3430         header->zero = 0;
3431 
3432         if (data)
3433                 memcpy(entry.data+sizeof(*header), data, data_len);
3434 
3435         if (meta_partition_should_pad(pad_value))
3436                 entry.data[total_len - 1] = (uint8_t) pad_value;
3437 
3438         return entry;
3439 }
3440 
3441 /** Allocates a new image partition */
3442 static struct image_partition_entry alloc_image_partition(const char *name, size_t len) {
3443         struct image_partition_entry entry = {name, len, malloc(len)};
3444         if (!entry.data)
3445                 error(1, errno, "malloc");
3446 
3447         return entry;
3448 }
3449 
3450 /** Sets up default partition names whenever custom names aren't specified */
3451 static void set_partition_names(struct device_info *info)
3452 {
3453         if (!info->partition_names.partition_table)
3454                 info->partition_names.partition_table = "partition-table";
3455         if (!info->partition_names.soft_ver)
3456                 info->partition_names.soft_ver = "soft-version";
3457         if (!info->partition_names.os_image)
3458                 info->partition_names.os_image = "os-image";
3459         if (!info->partition_names.support_list)
3460                 info->partition_names.support_list = "support-list";
3461         if (!info->partition_names.file_system)
3462                 info->partition_names.file_system = "file-system";
3463         if (!info->partition_names.extra_para)
3464                 info->partition_names.extra_para = "extra-para";
3465 }
3466 
3467 /** Frees an image partition */
3468 static void free_image_partition(struct image_partition_entry *entry)
3469 {
3470         void *data = entry->data;
3471 
3472         entry->name = NULL;
3473         entry->size = 0;
3474         entry->data = NULL;
3475 
3476         free(data);
3477 }
3478 
3479 static time_t source_date_epoch = -1;
3480 static void set_source_date_epoch() {
3481         char *env = getenv("SOURCE_DATE_EPOCH");
3482         char *endptr = env;
3483         errno = 0;
3484         if (env && *env) {
3485                 source_date_epoch = strtoull(env, &endptr, 10);
3486                 if (errno || (endptr && *endptr != '\0')) {
3487                         fprintf(stderr, "Invalid SOURCE_DATE_EPOCH");
3488                         exit(1);
3489                 }
3490         }
3491 }
3492 
3493 /** Generates the partition-table partition */
3494 static struct image_partition_entry make_partition_table(const struct device_info *p)
3495 {
3496         struct image_partition_entry entry = alloc_image_partition(p->partition_names.partition_table, SAFELOADER_PAYLOAD_TABLE_SIZE);
3497 
3498         char *s = (char *)entry.data, *end = (char *)(s+entry.size);
3499 
3500         *(s++) = 0x00;
3501         *(s++) = 0x04;
3502         *(s++) = 0x00;
3503         *(s++) = 0x00;
3504 
3505         size_t i;
3506         for (i = 0; p->partitions[i].name; i++) {
3507                 size_t len = end-s;
3508                 size_t w = snprintf(s, len, "partition %s base 0x%05x size 0x%05x\n",
3509                         p->partitions[i].name, p->partitions[i].base, p->partitions[i].size);
3510 
3511                 if (w > len-1)
3512                         error(1, 0, "flash partition table overflow?");
3513 
3514                 s += w;
3515         }
3516 
3517         s++;
3518 
3519         memset(s, 0xff, end-s);
3520 
3521         return entry;
3522 }
3523 
3524 
3525 /** Generates a binary-coded decimal representation of an integer in the range [0, 99] */
3526 static inline uint8_t bcd(uint8_t v) {
3527         return 0x10 * (v/10) + v%10;
3528 }
3529 
3530 
3531 /** Generates the soft-version partition */
3532 static struct image_partition_entry make_soft_version(const struct device_info *info, uint32_t rev)
3533 {
3534         /** If an info string is provided, use this instead of
3535          * the structured data, and include the null-termination */
3536         if (info->soft_ver.type == SOFT_VER_TYPE_TEXT) {
3537                 uint32_t len = strlen(info->soft_ver.text) + 1;
3538                 return init_meta_partition_entry(info->partition_names.soft_ver,
3539                         info->soft_ver.text, len, info->part_trail);
3540         }
3541 
3542         time_t t;
3543 
3544         if (source_date_epoch != -1)
3545                 t = source_date_epoch;
3546         else if (time(&t) == (time_t)(-1))
3547                 error(1, errno, "time");
3548 
3549         struct tm *tm = gmtime(&t);
3550 
3551         struct soft_version s = {
3552                 .pad1 = 0xff,
3553 
3554                 .version_major = info->soft_ver.num[0],
3555                 .version_minor = info->soft_ver.num[1],
3556                 .version_patch = info->soft_ver.num[2],
3557 
3558                 .year_hi = bcd((1900+tm->tm_year)/100),
3559                 .year_lo = bcd(tm->tm_year%100),
3560                 .month = bcd(tm->tm_mon+1),
3561                 .day = bcd(tm->tm_mday),
3562                 .rev = htonl(rev),
3563 
3564                 .compat_level = htonl(info->soft_ver_compat_level)
3565         };
3566 
3567         if (info->soft_ver_compat_level == 0)
3568                 return init_meta_partition_entry(info->partition_names.soft_ver, &s,
3569                         (uint8_t *)(&s.compat_level) - (uint8_t *)(&s),
3570                         info->part_trail);
3571         else
3572                 return init_meta_partition_entry(info->partition_names.soft_ver, &s,
3573                         sizeof(s), info->part_trail);
3574 }
3575 
3576 /** Generates the support-list partition */
3577 static struct image_partition_entry make_support_list(
3578         const struct device_info *info)
3579 {
3580         uint32_t len = strlen(info->support_list);
3581         return init_meta_partition_entry(info->partition_names.support_list, info->support_list,
3582                 len, info->part_trail);
3583 }
3584 
3585 /** Partition with extra-para data */
3586 static struct image_partition_entry make_extra_para(
3587         const struct device_info *info, const uint8_t *extra_para, size_t len)
3588 {
3589         return init_meta_partition_entry(info->partition_names.extra_para, extra_para, len,
3590                 info->part_trail);
3591 }
3592 
3593 /** Creates a new image partition with an arbitrary name from a file */
3594 static struct image_partition_entry read_file(const char *part_name, const char *filename, bool add_jffs2_eof, struct flash_partition_entry *file_system_partition) {
3595         struct stat statbuf;
3596 
3597         if (stat(filename, &statbuf) < 0)
3598                 error(1, errno, "unable to stat file `%s'", filename);
3599 
3600         size_t len = statbuf.st_size;
3601 
3602         if (add_jffs2_eof) {
3603                 if (file_system_partition)
3604                         len = ALIGN(len + file_system_partition->base, 0x10000) + sizeof(jffs2_eof_mark) - file_system_partition->base;
3605                 else
3606                         len = ALIGN(len, 0x10000) + sizeof(jffs2_eof_mark);
3607         }
3608 
3609         struct image_partition_entry entry = alloc_image_partition(part_name, len);
3610 
3611         FILE *file = fopen(filename, "rb");
3612         if (!file)
3613                 error(1, errno, "unable to open file `%s'", filename);
3614 
3615         if (fread(entry.data, statbuf.st_size, 1, file) != 1)
3616                 error(1, errno, "unable to read file `%s'", filename);
3617 
3618         if (add_jffs2_eof) {
3619                 uint8_t *eof = entry.data + statbuf.st_size, *end = entry.data+entry.size;
3620 
3621                 memset(eof, 0xff, end - eof - sizeof(jffs2_eof_mark));
3622                 memcpy(end - sizeof(jffs2_eof_mark), jffs2_eof_mark, sizeof(jffs2_eof_mark));
3623         }
3624 
3625         fclose(file);
3626 
3627         return entry;
3628 }
3629 
3630 /**
3631    Copies a list of image partitions into an image buffer and generates the image partition table while doing so
3632 
3633    Example image partition table:
3634 
3635      fwup-ptn partition-table base 0x00800 size 0x00800
3636      fwup-ptn os-image base 0x01000 size 0x113b45
3637      fwup-ptn file-system base 0x114b45 size 0x1d0004
3638      fwup-ptn support-list base 0x2e4b49 size 0x000d1
3639 
3640    Each line of the partition table is terminated with the bytes 09 0d 0a ("\t\r\n"),
3641    the end of the partition table is marked with a zero byte.
3642 
3643    The firmware image must contain at least the partition-table and support-list partitions
3644    to be accepted. There aren't any alignment constraints for the image partitions.
3645 
3646    The partition-table partition contains the actual flash layout; partitions
3647    from the image partition table are mapped to the corresponding flash partitions during
3648    the firmware upgrade. The support-list partition contains a list of devices supported by
3649    the firmware image.
3650 
3651    The base offsets in the firmware partition table are relative to the end
3652    of the vendor information block, so the partition-table partition will
3653    actually start at offset 0x1814 of the image.
3654 
3655    I think partition-table must be the first partition in the firmware image.
3656 */
3657 static void put_partitions(uint8_t *buffer, const struct flash_partition_entry *flash_parts, const struct image_partition_entry *parts) {
3658         size_t i, j;
3659         char *image_pt = (char *)buffer, *end = image_pt + SAFELOADER_PAYLOAD_TABLE_SIZE;
3660 
3661         size_t base = SAFELOADER_PAYLOAD_TABLE_SIZE;
3662         for (i = 0; parts[i].name; i++) {
3663                 for (j = 0; flash_parts[j].name; j++) {
3664                         if (!strcmp(flash_parts[j].name, parts[i].name)) {
3665                                 if (parts[i].size > flash_parts[j].size)
3666                                         error(1, 0, "%s partition too big (more than %u bytes)", flash_parts[j].name, (unsigned)flash_parts[j].size);
3667                                 break;
3668                         }
3669                 }
3670 
3671                 assert(flash_parts[j].name);
3672 
3673                 memcpy(buffer + base, parts[i].data, parts[i].size);
3674 
3675                 size_t len = end-image_pt;
3676                 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);
3677 
3678                 if (w > len-1)
3679                         error(1, 0, "image partition table overflow?");
3680 
3681                 image_pt += w;
3682 
3683                 base += parts[i].size;
3684         }
3685 }
3686 
3687 /** Generates and writes the image MD5 checksum */
3688 static void put_md5(uint8_t *md5, uint8_t *buffer, unsigned int len) {
3689         MD5_CTX ctx;
3690 
3691         MD5_Init(&ctx);
3692         MD5_Update(&ctx, md5_salt, (unsigned int)sizeof(md5_salt));
3693         MD5_Update(&ctx, buffer, len);
3694         MD5_Final(md5, &ctx);
3695 }
3696 
3697 
3698 /**
3699    Generates the firmware image in factory format
3700 
3701    Image format:
3702 
3703      Bytes (hex)  Usage
3704      -----------  -----
3705      0000-0003    Image size (4 bytes, big endian)
3706      0004-0013    MD5 hash (hash of a 16 byte salt and the image data starting with byte 0x14)
3707      0014-0017    Vendor information length (without padding) (4 bytes, big endian)
3708      0018-1013    Vendor information (4092 bytes, padded with 0xff; there seem to be older
3709                   (VxWorks-based) TP-LINK devices which use a smaller vendor information block)
3710      1014-1813    Image partition table (2048 bytes, padded with 0xff)
3711      1814-xxxx    Firmware partitions
3712 */
3713 static void * generate_factory_image(struct device_info *info, const struct image_partition_entry *parts, size_t *len) {
3714         *len = SAFELOADER_PAYLOAD_OFFSET + SAFELOADER_PAYLOAD_TABLE_SIZE;
3715 
3716         size_t i;
3717         for (i = 0; parts[i].name; i++)
3718                 *len += parts[i].size;
3719 
3720         uint8_t *image = malloc(*len);
3721         if (!image)
3722                 error(1, errno, "malloc");
3723 
3724         memset(image, 0xff, *len);
3725         put32(image, *len);
3726 
3727         if (info->vendor) {
3728                 size_t vendor_len = strlen(info->vendor);
3729                 put32(image + SAFELOADER_PREAMBLE_SIZE, vendor_len);
3730                 memcpy(image + SAFELOADER_PREAMBLE_SIZE + 0x4, info->vendor, vendor_len);
3731         }
3732 
3733         put_partitions(image + SAFELOADER_PAYLOAD_OFFSET, info->partitions, parts);
3734         put_md5(image + 0x04, image + SAFELOADER_PREAMBLE_SIZE, *len - SAFELOADER_PREAMBLE_SIZE);
3735 
3736         return image;
3737 }
3738 
3739 /**
3740    Generates the firmware image in sysupgrade format
3741 
3742    This makes some assumptions about the provided flash and image partition tables and
3743    should be generalized when TP-LINK starts building its safeloader into hardware with
3744    different flash layouts.
3745 */
3746 static void * generate_sysupgrade_image(struct device_info *info, const struct image_partition_entry *image_parts, size_t *len) {
3747         size_t i, j;
3748         size_t flash_first_partition_index = 0;
3749         size_t flash_last_partition_index = 0;
3750         const struct flash_partition_entry *flash_first_partition = NULL;
3751         const struct flash_partition_entry *flash_last_partition = NULL;
3752         const struct image_partition_entry *image_last_partition = NULL;
3753 
3754         /** Find first and last partitions */
3755         for (i = 0; info->partitions[i].name; i++) {
3756                 if (!strcmp(info->partitions[i].name, info->first_sysupgrade_partition)) {
3757                         flash_first_partition = &info->partitions[i];
3758                         flash_first_partition_index = i;
3759                 } else if (!strcmp(info->partitions[i].name, info->last_sysupgrade_partition)) {
3760                         flash_last_partition = &info->partitions[i];
3761                         flash_last_partition_index = i;
3762                 }
3763         }
3764 
3765         assert(flash_first_partition && flash_last_partition);
3766         assert(flash_first_partition_index < flash_last_partition_index);
3767 
3768         /** Find last partition from image to calculate needed size */
3769         for (i = 0; image_parts[i].name; i++) {
3770                 if (!strcmp(image_parts[i].name, info->last_sysupgrade_partition)) {
3771                         image_last_partition = &image_parts[i];
3772                         break;
3773                 }
3774         }
3775 
3776         assert(image_last_partition);
3777 
3778         *len = flash_last_partition->base - flash_first_partition->base + image_last_partition->size;
3779 
3780         uint8_t *image = malloc(*len);
3781         if (!image)
3782                 error(1, errno, "malloc");
3783 
3784         memset(image, 0xff, *len);
3785 
3786         for (i = flash_first_partition_index; i <= flash_last_partition_index; i++) {
3787                 for (j = 0; image_parts[j].name; j++) {
3788                         if (!strcmp(info->partitions[i].name, image_parts[j].name)) {
3789                                 if (image_parts[j].size > info->partitions[i].size)
3790                                         error(1, 0, "%s partition too big (more than %u bytes)", info->partitions[i].name, (unsigned)info->partitions[i].size);
3791                                 memcpy(image + info->partitions[i].base - flash_first_partition->base, image_parts[j].data, image_parts[j].size);
3792                                 break;
3793                         }
3794 
3795                         assert(image_parts[j].name);
3796                 }
3797         }
3798 
3799         return image;
3800 }
3801 
3802 /** Generates an image according to a given layout and writes it to a file */
3803 static void build_image(const char *output,
3804                 const char *kernel_image,
3805                 const char *rootfs_image,
3806                 uint32_t rev,
3807                 bool add_jffs2_eof,
3808                 bool sysupgrade,
3809                 struct device_info *info) {
3810 
3811         size_t i;
3812 
3813         struct image_partition_entry parts[7] = {};
3814 
3815         struct flash_partition_entry *firmware_partition = NULL;
3816         struct flash_partition_entry *os_image_partition = NULL;
3817         struct flash_partition_entry *file_system_partition = NULL;
3818         size_t firmware_partition_index = 0;
3819 
3820         set_partition_names(info);
3821 
3822         for (i = 0; info->partitions[i].name; i++) {
3823                 if (!strcmp(info->partitions[i].name, "firmware"))
3824                 {
3825                         firmware_partition = &info->partitions[i];
3826                         firmware_partition_index = i;
3827                 }
3828         }
3829 
3830         if (firmware_partition)
3831         {
3832                 os_image_partition = &info->partitions[firmware_partition_index];
3833                 file_system_partition = &info->partitions[firmware_partition_index + 1];
3834 
3835                 struct stat kernel;
3836                 if (stat(kernel_image, &kernel) < 0)
3837                         error(1, errno, "unable to stat file `%s'", kernel_image);
3838 
3839                 if (kernel.st_size > firmware_partition->size)
3840                         error(1, 0, "kernel overflowed firmware partition\n");
3841 
3842                 for (i = MAX_PARTITIONS-1; i >= firmware_partition_index + 1; i--)
3843                         info->partitions[i+1] = info->partitions[i];
3844 
3845                 file_system_partition->name = info->partition_names.file_system;
3846 
3847                 file_system_partition->base = firmware_partition->base + kernel.st_size;
3848 
3849                 /* Align partition start to erase blocks for factory images only */
3850                 if (!sysupgrade)
3851                         file_system_partition->base = ALIGN(firmware_partition->base + kernel.st_size, 0x10000);
3852 
3853                 file_system_partition->size = firmware_partition->size - file_system_partition->base;
3854 
3855                 os_image_partition->name = info->partition_names.os_image;
3856 
3857                 os_image_partition->size = kernel.st_size;
3858         }
3859 
3860         parts[0] = make_partition_table(info);
3861         parts[1] = make_soft_version(info, rev);
3862         parts[2] = make_support_list(info);
3863         parts[3] = read_file(info->partition_names.os_image, kernel_image, false, NULL);
3864         parts[4] = read_file(info->partition_names.file_system, rootfs_image, add_jffs2_eof, file_system_partition);
3865 
3866 
3867         /* Some devices need the extra-para partition to accept the firmware */
3868         if (strcasecmp(info->id, "ARCHER-A6-V3") == 0 ||
3869             strcasecmp(info->id, "ARCHER-A7-V5") == 0 ||
3870             strcasecmp(info->id, "ARCHER-A9-V6") == 0 ||
3871             strcasecmp(info->id, "ARCHER-AX23-V1") == 0 ||
3872             strcasecmp(info->id, "ARCHER-C2-V3") == 0 ||
3873             strcasecmp(info->id, "ARCHER-C7-V4") == 0 ||
3874             strcasecmp(info->id, "ARCHER-C7-V5") == 0 ||
3875             strcasecmp(info->id, "ARCHER-C25-V1") == 0 ||
3876             strcasecmp(info->id, "ARCHER-C59-V2") == 0 ||
3877             strcasecmp(info->id, "ARCHER-C60-V2") == 0 ||
3878             strcasecmp(info->id, "ARCHER-C60-V3") == 0 ||
3879             strcasecmp(info->id, "ARCHER-C6U-V1") == 0 ||
3880             strcasecmp(info->id, "ARCHER-C6-V3") == 0 ||
3881             strcasecmp(info->id, "DECO-M4R-V4") == 0 ||
3882             strcasecmp(info->id, "MR70X") == 0 ||
3883             strcasecmp(info->id, "TLWR1043NV5") == 0) {
3884                 const uint8_t extra_para[2] = {0x01, 0x00};
3885                 parts[5] = make_extra_para(info, extra_para,
3886                         sizeof(extra_para));
3887         } else if (strcasecmp(info->id, "ARCHER-C6-V2") == 0 ||
3888                    strcasecmp(info->id, "TL-WA1201-V2") == 0) {
3889                 const uint8_t extra_para[2] = {0x00, 0x01};
3890                 parts[5] = make_extra_para(info, extra_para,
3891                         sizeof(extra_para));
3892         } else if (strcasecmp(info->id, "ARCHER-C6-V2-US") == 0 ||
3893                    strcasecmp(info->id, "EAP245-V3") == 0) {
3894                 const uint8_t extra_para[2] = {0x01, 0x01};
3895                 parts[5] = make_extra_para(info, extra_para,
3896                         sizeof(extra_para));
3897         }
3898 
3899         size_t len;
3900         void *image;
3901         if (sysupgrade)
3902                 image = generate_sysupgrade_image(info, parts, &len);
3903         else
3904                 image = generate_factory_image(info, parts, &len);
3905 
3906         FILE *file = fopen(output, "wb");
3907         if (!file)
3908                 error(1, errno, "unable to open output file");
3909 
3910         if (fwrite(image, len, 1, file) != 1)
3911                 error(1, 0, "unable to write output file");
3912 
3913         fclose(file);
3914 
3915         free(image);
3916 
3917         for (i = 0; parts[i].name; i++)
3918                 free_image_partition(&parts[i]);
3919 }
3920 
3921 /** Usage output */
3922 static void usage(const char *argv0) {
3923         fprintf(stderr,
3924                 "Usage: %s [OPTIONS...]\n"
3925                 "\n"
3926                 "Options:\n"
3927                 "  -h              show this help\n"
3928                 "\n"
3929                 "Info about an image:\n"
3930                 "  -i <file>       input file to read from\n"
3931                 "Create a new image:\n"
3932                 "  -B <board>      create image for the board specified with <board>\n"
3933                 "  -k <file>       read kernel image from the file <file>\n"
3934                 "  -r <file>       read rootfs image from the file <file>\n"
3935                 "  -o <file>       write output to the file <file>\n"
3936                 "  -V <rev>        sets the revision number to <rev>\n"
3937                 "  -j              add jffs2 end-of-filesystem markers\n"
3938                 "  -S              create sysupgrade instead of factory image\n"
3939                 "Extract an old image:\n"
3940                 "  -x <file>       extract all oem firmware partition\n"
3941                 "  -d <dir>        destination to extract the firmware partition\n"
3942                 "  -z <file>       convert an oem firmware into a sysupgade file. Use -o for output file\n",
3943                 argv0
3944         );
3945 };
3946 
3947 
3948 static struct device_info *find_board(const char *id)
3949 {
3950         struct device_info *board = NULL;
3951 
3952         for (board = boards; board->id != NULL; board++)
3953                 if (strcasecmp(id, board->id) == 0)
3954                         return board;
3955 
3956         return NULL;
3957 }
3958 
3959 static int add_flash_partition(
3960                 struct flash_partition_entry *part_list,
3961                 size_t max_entries,
3962                 const char *name,
3963                 unsigned long base,
3964                 unsigned long size)
3965 {
3966         size_t ptr;
3967         /* check if the list has a free entry */
3968         for (ptr = 0; ptr < max_entries; ptr++, part_list++) {
3969                 if (part_list->name == NULL &&
3970                                 part_list->base == 0 &&
3971                                 part_list->size == 0)
3972                         break;
3973         }
3974 
3975         if (ptr == max_entries) {
3976                 error(1, 0, "No free flash part entry available.");
3977         }
3978 
3979         part_list->name = calloc(1, strlen(name) + 1);
3980         if (!part_list->name) {
3981                 error(1, 0, "Unable to allocate memory");
3982         }
3983 
3984         memcpy((char *)part_list->name, name, strlen(name));
3985         part_list->base = base;
3986         part_list->size = size;
3987 
3988         return 0;
3989 }
3990 
3991 /** read the partition table into struct flash_partition_entry */
3992 enum PARTITION_TABLE_TYPE {
3993         PARTITION_TABLE_FWUP,
3994         PARTITION_TABLE_FLASH,
3995 };
3996 
3997 static int read_partition_table(
3998                 FILE *file, long offset,
3999                 struct flash_partition_entry *entries, size_t max_entries,
4000                 int type)
4001 {
4002         char buf[SAFELOADER_PAYLOAD_TABLE_SIZE];
4003         char *ptr, *end;
4004         const char *parthdr = NULL;
4005         const char *fwuphdr = "fwup-ptn";
4006         const char *flashhdr = "partition";
4007 
4008         /* TODO: search for the partition table */
4009 
4010         switch(type) {
4011         case PARTITION_TABLE_FWUP:
4012                 parthdr = fwuphdr;
4013                 break;
4014         case PARTITION_TABLE_FLASH:
4015                 parthdr = flashhdr;
4016                 break;
4017         default:
4018                 error(1, 0, "Invalid partition table");
4019         }
4020 
4021         if (fseek(file, offset, SEEK_SET) < 0)
4022                 error(1, errno, "Can not seek in the firmware");
4023 
4024         if (fread(buf, sizeof(buf), 1, file) != 1)
4025                 error(1, errno, "Can not read fwup-ptn from the firmware");
4026 
4027         buf[sizeof(buf) - 1] = '\0';
4028 
4029         /* look for the partition header */
4030         if (memcmp(buf, parthdr, strlen(parthdr)) != 0) {
4031                 fprintf(stderr, "DEBUG: can not find fwuphdr\n");
4032                 return 1;
4033         }
4034 
4035         ptr = buf;
4036         end = buf + sizeof(buf);
4037         while ((ptr + strlen(parthdr)) < end &&
4038                         memcmp(ptr, parthdr, strlen(parthdr)) == 0) {
4039                 char *end_part;
4040                 char *end_element;
4041 
4042                 char name[32] = { 0 };
4043                 int name_len = 0;
4044                 unsigned long base = 0;
4045                 unsigned long size = 0;
4046 
4047                 end_part = memchr(ptr, '\n', (end - ptr));
4048                 if (end_part == NULL) {
4049                         /* in theory this should never happen, because a partition always ends with 0x09, 0x0D, 0x0A */
4050                         break;
4051                 }
4052 
4053                 for (int i = 0; i <= 4; i++) {
4054                         if (end_part <= ptr)
4055                                 break;
4056 
4057                         end_element = memchr(ptr, 0x20, (end_part - ptr));
4058                         if (end_element == NULL) {
4059                                 error(1, errno, "Ignoring the rest of the partition entries.");
4060                                 break;
4061                         }
4062 
4063                         switch (i) {
4064                                 /* partition header */
4065                                 case 0:
4066                                         ptr = end_element + 1;
4067                                         continue;
4068                                 /* name */
4069                                 case 1:
4070                                         name_len = (end_element - ptr) > 31 ? 31 : (end_element - ptr);
4071                                         strncpy(name, ptr, name_len);
4072                                         name[name_len] = '\0';
4073                                         ptr = end_element + 1;
4074                                         continue;
4075 
4076                                 /* string "base" */
4077                                 case 2:
4078                                         ptr = end_element + 1;
4079                                         continue;
4080 
4081                                 /* actual base */
4082                                 case 3:
4083                                         base = strtoul(ptr, NULL, 16);
4084                                         ptr = end_element + 1;
4085                                         continue;
4086 
4087                                 /* string "size" */
4088                                 case 4:
4089                                         ptr = end_element + 1;
4090                                         /* actual size. The last element doesn't have a sepeartor */
4091                                         size = strtoul(ptr, NULL, 16);
4092                                         /* the part ends with 0x09, 0x0d, 0x0a */
4093                                         ptr = end_part + 1;
4094                                         add_flash_partition(entries, max_entries, name, base, size);
4095                                         continue;
4096                         }
4097                 }
4098         }
4099 
4100         return 0;
4101 }
4102 
4103 static void safeloader_read_partition(FILE *input_file, size_t payload_offset,
4104                                       struct flash_partition_entry *entry,
4105                                       struct image_partition_entry *part)
4106 {
4107         size_t part_size = entry->size;
4108         void *part_data = malloc(part_size);
4109 
4110         if (fseek(input_file, payload_offset, SEEK_SET))
4111                 error(1, errno, "Failed to seek to partition data");
4112 
4113         if (!part_data)
4114                 error(1, ENOMEM, "Failed to allocate partition data");
4115 
4116         if (fread(part_data, 1, part_size, input_file) < part_size)
4117                 error(1, errno, "Failed to read partition data");
4118 
4119         part->data = part_data;
4120         part->size = part_size;
4121         part->name = entry->name;
4122 }
4123 
4124 static void safeloader_parse_image(FILE *input_file, struct safeloader_image_info *image)
4125 {
4126         static const char *HEADER_ID_CLOUD = "fw-type:Cloud";
4127         static const char *HEADER_ID_QNEW = "?NEW";
4128 
4129         char buf[64];
4130 
4131         if (!input_file)
4132                 return;
4133 
4134         fseek(input_file, SAFELOADER_PREAMBLE_SIZE, SEEK_SET);
4135 
4136         if (fread(buf, sizeof(buf), 1, input_file) != 1)
4137                 error(1, errno, "Can not read image header");
4138 
4139         if (memcmp(HEADER_ID_QNEW, &buf[0], strlen(HEADER_ID_QNEW)) == 0)
4140                 image->type = SAFELOADER_TYPE_QNEW;
4141         else if (memcmp(HEADER_ID_CLOUD, &buf[0], strlen(HEADER_ID_CLOUD)) == 0)
4142                 image->type = SAFELOADER_TYPE_CLOUD;
4143         else if (ntohl(*((uint32_t *) &buf[0])) <= SAFELOADER_HEADER_SIZE)
4144                 image->type = SAFELOADER_TYPE_VENDOR;
4145         else
4146                 image->type = SAFELOADER_TYPE_DEFAULT;
4147 
4148         switch (image->type) {
4149         case SAFELOADER_TYPE_DEFAULT:
4150         case SAFELOADER_TYPE_VENDOR:
4151         case SAFELOADER_TYPE_CLOUD:
4152                 image->payload_offset = SAFELOADER_PAYLOAD_OFFSET;
4153                 break;
4154         case SAFELOADER_TYPE_QNEW:
4155                 image->payload_offset = SAFELOADER_QNEW_PAYLOAD_OFFSET;
4156                 break;
4157         }
4158 
4159         /* Parse image partition table */
4160         read_partition_table(input_file, image->payload_offset, &image->entries[0],
4161                              MAX_PARTITIONS, PARTITION_TABLE_FWUP);
4162 }
4163 
4164 static void write_partition(
4165                 FILE *input_file,
4166                 size_t firmware_offset,
4167                 struct flash_partition_entry *entry,
4168                 FILE *output_file)
4169 {
4170         char buf[4096];
4171         size_t offset;
4172 
4173         fseek(input_file, entry->base + firmware_offset, SEEK_SET);
4174 
4175         for (offset = 0; sizeof(buf) + offset <= entry->size; offset += sizeof(buf)) {
4176                 if (fread(buf, sizeof(buf), 1, input_file) != 1)
4177                         error(1, errno, "Can not read partition from input_file");
4178 
4179                 if (fwrite(buf, sizeof(buf), 1, output_file) != 1)
4180                         error(1, errno, "Can not write partition to output_file");
4181         }
4182         /* write last chunk smaller than buffer */
4183         if (offset < entry->size) {
4184                 offset = entry->size - offset;
4185                 if (fread(buf, offset, 1, input_file) != 1)
4186                         error(1, errno, "Can not read partition from input_file");
4187                 if (fwrite(buf, offset, 1, output_file) != 1)
4188                         error(1, errno, "Can not write partition to output_file");
4189         }
4190 }
4191 
4192 static int extract_firmware_partition(FILE *input_file, size_t firmware_offset, struct flash_partition_entry *entry, const char *output_directory)
4193 {
4194         FILE *output_file;
4195         char output[PATH_MAX];
4196 
4197         snprintf(output, PATH_MAX, "%s/%s", output_directory, entry->name);
4198         output_file = fopen(output, "wb+");
4199         if (output_file == NULL) {
4200                 error(1, errno, "Can not open output file %s", output);
4201         }
4202 
4203         write_partition(input_file, firmware_offset, entry, output_file);
4204 
4205         fclose(output_file);
4206 
4207         return 0;
4208 }
4209 
4210 /** extract all partitions from the firmware file */
4211 static int extract_firmware(const char *input, const char *output_directory)
4212 {
4213         struct safeloader_image_info info = {};
4214         struct stat statbuf;
4215         FILE *input_file;
4216 
4217         /* check input file */
4218         if (stat(input, &statbuf)) {
4219                 error(1, errno, "Can not read input firmware %s", input);
4220         }
4221 
4222         /* check if output directory exists */
4223         if (stat(output_directory, &statbuf)) {
4224                 error(1, errno, "Failed to stat output directory %s", output_directory);
4225         }
4226 
4227         if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
4228                 error(1, errno, "Given output directory is not a directory %s", output_directory);
4229         }
4230 
4231         input_file = fopen(input, "rb");
4232         safeloader_parse_image(input_file, &info);
4233 
4234         for (size_t i = 0; i < MAX_PARTITIONS && info.entries[i].name; i++)
4235                 extract_firmware_partition(input_file, info.payload_offset, &info.entries[i], output_directory);
4236 
4237         return 0;
4238 }
4239 
4240 static struct flash_partition_entry *find_partition(
4241                 struct flash_partition_entry *entries, size_t max_entries,
4242                 const char *name, const char *error_msg)
4243 {
4244         for (size_t i = 0; i < max_entries; i++, entries++) {
4245                 if (strcmp(entries->name, name) == 0)
4246                         return entries;
4247         }
4248 
4249         if (error_msg) {
4250                 error(1, 0, "%s", error_msg);
4251         }
4252 
4253         return NULL;
4254 }
4255 
4256 static int firmware_info(const char *input)
4257 {
4258         struct safeloader_image_info info = {};
4259         struct image_partition_entry part = {};
4260         struct flash_partition_entry *e;
4261         FILE *input_file;
4262 
4263         input_file = fopen(input, "rb");
4264 
4265         safeloader_parse_image(input_file, &info);
4266 
4267         if (info.type == SAFELOADER_TYPE_VENDOR) {
4268                 char buf[SAFELOADER_HEADER_SIZE] = {};
4269                 uint32_t vendor_size;
4270 
4271                 fseek(input_file, SAFELOADER_PREAMBLE_SIZE, SEEK_SET);
4272                 fread(&vendor_size, sizeof(uint32_t), 1, input_file);
4273 
4274                 vendor_size = ntohl(vendor_size);
4275                 fread(buf, vendor_size, 1, input_file);
4276 
4277                 printf("Firmware vendor string:\n");
4278                 fwrite(buf, strnlen(buf, vendor_size), 1, stdout);
4279                 printf("\n");
4280         }
4281 
4282         printf("Firmware image partitions:\n");
4283         printf("%-8s %-8s %s\n", "base", "size", "name");
4284 
4285         e = &info.entries[0];
4286         for (unsigned int i = 0; i < MAX_PARTITIONS && e->name; i++, e++)
4287                 printf("%08x %08x %s\n", e->base, e->size, e->name);
4288 
4289         e = find_partition(&info.entries[0], MAX_PARTITIONS, "soft-version", NULL);
4290         if (e) {
4291                 struct soft_version *s;
4292                 unsigned int ascii_len;
4293                 const uint8_t *buf;
4294                 size_t data_len;
4295                 bool isstr;
4296 
4297                 safeloader_read_partition(input_file, info.payload_offset + e->base, e, &part);
4298                 data_len = ntohl(((struct meta_header *) part.data)->length);
4299                 buf = part.data + sizeof(struct meta_header);
4300 
4301                 /* Check for (null-terminated) string */
4302                 ascii_len = 0;
4303                 while (ascii_len < data_len && isascii(buf[ascii_len]))
4304                         ascii_len++;
4305 
4306                 isstr = ascii_len == data_len;
4307 
4308                 printf("\n[Software version]\n");
4309                 if (isstr) {
4310                         fwrite(buf, strnlen((const char *) buf, data_len), 1, stdout);
4311                         putchar('\n');
4312                 } else if (data_len >= offsetof(struct soft_version, rev)) {
4313                         s = (struct soft_version *) buf;
4314 
4315                         printf("Version: %d.%d.%d\n", s->version_major, s->version_minor, s->version_patch);
4316                         printf("Date: %02x%02x-%02x-%02x\n", s->year_hi, s->year_lo, s->month, s->day);
4317                         printf("Revision: %d\n", ntohl(s->rev));
4318 
4319                         if (data_len >= offsetof(struct soft_version, compat_level)) {
4320                                 printf("Compatibility level: %d\n", ntohl(s->compat_level));
4321                         }
4322                 } else {
4323                         printf("Failed to parse data\n");
4324                 }
4325 
4326                 free_image_partition(&part);
4327         }
4328 
4329         e = find_partition(&info.entries[0], MAX_PARTITIONS, "support-list", NULL);
4330         if (e) {
4331                 size_t data_len;
4332 
4333                 safeloader_read_partition(input_file, info.payload_offset + e->base, e, &part);
4334                 data_len = ntohl(((struct meta_header *) part.data)->length);
4335 
4336                 printf("\n[Support list]\n");
4337                 fwrite(part.data + sizeof(struct meta_header), data_len, 1, stdout);
4338                 printf("\n");
4339 
4340                 free_image_partition(&part);
4341         }
4342 
4343         e = find_partition(&info.entries[0], MAX_PARTITIONS, "partition-table", NULL);
4344         if (e) {
4345                 size_t flash_table_offset = info.payload_offset + e->base + 4;
4346                 struct flash_partition_entry parts[MAX_PARTITIONS] = {};
4347 
4348                 if (read_partition_table(input_file, flash_table_offset, parts, MAX_PARTITIONS, PARTITION_TABLE_FLASH))
4349                         error(1, 0, "Error can not read the partition table (partition)");
4350 
4351                 printf("\n[Partition table]\n");
4352                 printf("%-8s %-8s %s\n", "base", "size", "name");
4353 
4354                 e = &parts[0];
4355                 for (unsigned int i = 0; i < MAX_PARTITIONS && e->name; i++, e++)
4356                         printf("%08x %08x %s\n", e->base, e->size, e->name);
4357         }
4358 
4359         fclose(input_file);
4360 
4361         return 0;
4362 }
4363 
4364 static void write_ff(FILE *output_file, size_t size)
4365 {
4366         char buf[4096];
4367         size_t offset;
4368 
4369         memset(buf, 0xff, sizeof(buf));
4370 
4371         for (offset = 0; offset + sizeof(buf) < size ; offset += sizeof(buf)) {
4372                 if (fwrite(buf, sizeof(buf), 1, output_file) != 1)
4373                         error(1, errno, "Can not write 0xff to output_file");
4374         }
4375 
4376         /* write last chunk smaller than buffer */
4377         if (offset < size) {
4378                 offset = size - offset;
4379                 if (fwrite(buf, offset, 1, output_file) != 1)
4380                         error(1, errno, "Can not write partition to output_file");
4381         }
4382 }
4383 
4384 static void convert_firmware(const char *input, const char *output)
4385 {
4386         struct flash_partition_entry flash[MAX_PARTITIONS] = {};
4387         struct flash_partition_entry *fwup_partition_table;
4388         struct flash_partition_entry *flash_file_system;
4389         struct flash_partition_entry *fwup_file_system;
4390         struct flash_partition_entry *flash_os_image;
4391         struct flash_partition_entry *fwup_os_image;
4392         struct safeloader_image_info info = {};
4393         size_t flash_table_offset;
4394         struct stat statbuf;
4395         FILE *output_file;
4396         FILE *input_file;
4397 
4398         /* check input file */
4399         if (stat(input, &statbuf)) {
4400                 error(1, errno, "Can not read input firmware %s", input);
4401         }
4402 
4403         input_file = fopen(input, "rb");
4404         if (!input_file)
4405                 error(1, 0, "Can not open input firmware %s", input);
4406 
4407         output_file = fopen(output, "wb");
4408         if (!output_file)
4409                 error(1, 0, "Can not open output firmware %s", output);
4410 
4411         input_file = fopen(input, "rb");
4412         safeloader_parse_image(input_file, &info);
4413 
4414         fwup_os_image = find_partition(info.entries, MAX_PARTITIONS,
4415                         "os-image", "Error can not find os-image partition (fwup)");
4416         fwup_file_system = find_partition(info.entries, MAX_PARTITIONS,
4417                         "file-system", "Error can not find file-system partition (fwup)");
4418         fwup_partition_table = find_partition(info.entries, MAX_PARTITIONS,
4419                         "partition-table", "Error can not find partition-table partition");
4420 
4421         /* the flash partition table has a 0x00000004 magic haeder */
4422         flash_table_offset = info.payload_offset + fwup_partition_table->base + 4;
4423         if (read_partition_table(input_file, flash_table_offset, flash, MAX_PARTITIONS, PARTITION_TABLE_FLASH) != 0)
4424                 error(1, 0, "Error can not read the partition table (flash)");
4425 
4426         flash_os_image = find_partition(flash, MAX_PARTITIONS,
4427                         "os-image", "Error can not find os-image partition (flash)");
4428         flash_file_system = find_partition(flash, MAX_PARTITIONS,
4429                         "file-system", "Error can not find file-system partition (flash)");
4430 
4431         /* write os_image to 0x0 */
4432         write_partition(input_file, info.payload_offset, fwup_os_image, output_file);
4433         write_ff(output_file, flash_os_image->size - fwup_os_image->size);
4434 
4435         /* write file-system behind os_image */
4436         fseek(output_file, flash_file_system->base - flash_os_image->base, SEEK_SET);
4437         write_partition(input_file, info.payload_offset, fwup_file_system, output_file);
4438 
4439         fclose(output_file);
4440         fclose(input_file);
4441 }
4442 
4443 int main(int argc, char *argv[]) {
4444         const char *info_image = NULL, *board = NULL, *kernel_image = NULL, *rootfs_image = NULL, *output = NULL;
4445         const char *extract_image = NULL, *output_directory = NULL, *convert_image = NULL;
4446         bool add_jffs2_eof = false, sysupgrade = false;
4447         unsigned rev = 0;
4448         struct device_info *info;
4449         set_source_date_epoch();
4450 
4451         while (true) {
4452                 int c;
4453 
4454                 c = getopt(argc, argv, "i:B:k:r:o:V:jSh:x:d:z:");
4455                 if (c == -1)
4456                         break;
4457 
4458                 switch (c) {
4459                 case 'i':
4460                         info_image = optarg;
4461                         break;
4462 
4463                 case 'B':
4464                         board = optarg;
4465                         break;
4466 
4467                 case 'k':
4468                         kernel_image = optarg;
4469                         break;
4470 
4471                 case 'r':
4472                         rootfs_image = optarg;
4473                         break;
4474 
4475                 case 'o':
4476                         output = optarg;
4477                         break;
4478 
4479                 case 'V':
4480                         sscanf(optarg, "r%u", &rev);
4481                         break;
4482 
4483                 case 'j':
4484                         add_jffs2_eof = true;
4485                         break;
4486 
4487                 case 'S':
4488                         sysupgrade = true;
4489                         break;
4490 
4491                 case 'h':
4492                         usage(argv[0]);
4493                         return 0;
4494 
4495                 case 'd':
4496                         output_directory = optarg;
4497                         break;
4498 
4499                 case 'x':
4500                         extract_image = optarg;
4501                         break;
4502 
4503                 case 'z':
4504                         convert_image = optarg;
4505                         break;
4506 
4507                 default:
4508                         usage(argv[0]);
4509                         return 1;
4510                 }
4511         }
4512 
4513         if (info_image) {
4514                 firmware_info(info_image);
4515         } else if (extract_image || output_directory) {
4516                 if (!extract_image)
4517                         error(1, 0, "No factory/oem image given via -x <file>. Output directory is only valid with -x");
4518                 if (!output_directory)
4519                         error(1, 0, "Can not extract an image without output directory. Use -d <dir>");
4520                 extract_firmware(extract_image, output_directory);
4521         } else if (convert_image) {
4522                 if (!output)
4523                         error(1, 0, "Can not convert a factory/oem image into sysupgrade image without output file. Use -o <file>");
4524                 convert_firmware(convert_image, output);
4525         } else {
4526                 if (!board)
4527                         error(1, 0, "no board has been specified");
4528                 if (!kernel_image)
4529                         error(1, 0, "no kernel image has been specified");
4530                 if (!rootfs_image)
4531                         error(1, 0, "no rootfs image has been specified");
4532                 if (!output)
4533                         error(1, 0, "no output filename has been specified");
4534 
4535                 info = find_board(board);
4536 
4537                 if (info == NULL)
4538                         error(1, 0, "unsupported board %s", board);
4539 
4540                 build_image(output, kernel_image, rootfs_image, rev, add_jffs2_eof, sysupgrade, info);
4541         }
4542 
4543         return 0;
4544 }
4545 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt