diff --git a/patches/0001-generic-platform-mikrotik-add-wlan-lz77-decompress.patch b/patches/0001-generic-platform-mikrotik-add-wlan-lz77-decompress.patch new file mode 100644 index 00000000..a27b2881 --- /dev/null +++ b/patches/0001-generic-platform-mikrotik-add-wlan-lz77-decompress.patch @@ -0,0 +1,700 @@ +From 116211fc6f17f5b6e6ba4c9372cacb1d88333d9f Mon Sep 17 00:00:00 2001 +From: John Thomson +Date: Sat, 24 Jun 2023 09:44:27 +1000 +Subject: [PATCH] generic: platform/mikrotik: add wlan lz77 decompress +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +A number of new (or newly factory flashed) Mikrotik devices are using +LZ77 magic for wlan tag hard_config data. +New devices include the Chateau LTE12 [1], and ax devices [2] +Newly factory flashed devices may include the hap ac3 [3] + +This can be seen in decoded OEM supout [4] dmesg: +"radio data lz77 decompressed from"… + +Investigating an arm RouterOS flash.ko module, and supplied example +hard_config dumps, the format was determined via [5]. + +debug prints can be enabled in a DYNAMIC_DEBUG kernel build via the +kernel cmdline: + + chosen { +- bootargs = "console=ttyS0,115200"; ++ bootargs = "console=ttyS0,115200 dyndbg=\"file: drivers/platform/mikrotik/* +p\""; + }; + +[1]: https://forum.openwrt.org/t/no-wireless-mikrotik-rbd53ig-5hacd2hnd/157763/4 +[2]: https://forum.openwrt.org/t/mikrotik-routeros-v7-x-and-openwrt-sysupgrade/148072/17 +[3]: https://forum.openwrt.org/t/adding-support-for-mikrotik-hap-ax2/133715/47 +[4]: https://github.com/farseeker/go-mikrotik-rif +[5]: https://github.com/john-tho/routeros-wlan-lz77-decode + +Signed-off-by: John Thomson +--- + target/linux/ath79/mikrotik/config-default | 1 + + .../files/drivers/platform/mikrotik/Kconfig | 9 + + .../files/drivers/platform/mikrotik/Makefile | 1 + + .../drivers/platform/mikrotik/rb_hardconfig.c | 67 ++- + .../platform/mikrotik/rb_hardconfig_lz77.c | 430 ++++++++++++++++++ + .../platform/mikrotik/rb_hardconfig_lz77.h | 40 ++ + .../drivers/platform/mikrotik/routerboot.h | 1 + + target/linux/ipq40xx/mikrotik/config-default | 1 + + target/linux/ramips/mt7621/config-5.15 | 1 + + 9 files changed, 550 insertions(+), 1 deletion(-) + create mode 100644 target/linux/generic/files/drivers/platform/mikrotik/rb_hardconfig_lz77.c + create mode 100644 target/linux/generic/files/drivers/platform/mikrotik/rb_hardconfig_lz77.h + +diff --git a/target/linux/ath79/mikrotik/config-default b/target/linux/ath79/mikrotik/config-default +index 67d4ca6edc..072d5afd5e 100644 +--- a/target/linux/ath79/mikrotik/config-default ++++ b/target/linux/ath79/mikrotik/config-default +@@ -12,6 +12,7 @@ CONFIG_MFD_RB4XX_CPLD=y + CONFIG_MIKROTIK=y + CONFIG_MIKROTIK_RB_SYSFS=y + CONFIG_MTD_NAND=y ++CONFIG_MIKROTIK_RB_SYSFS_WLAN_LZ77=y + CONFIG_MTD_NAND_AR934X=y + CONFIG_MTD_NAND_CORE=y + CONFIG_MTD_NAND_ECC=y +diff --git a/target/linux/generic/files/drivers/platform/mikrotik/Kconfig b/target/linux/generic/files/drivers/platform/mikrotik/Kconfig +index 1dc027815a..42918f0a51 100644 +--- a/target/linux/generic/files/drivers/platform/mikrotik/Kconfig ++++ b/target/linux/generic/files/drivers/platform/mikrotik/Kconfig +@@ -15,4 +15,13 @@ config MIKROTIK_RB_SYSFS + help + This driver exposes RouterBoot configuration in sysfs. + ++config MIKROTIK_RB_SYSFS_WLAN_LZ77 ++ tristate "RouterBoot sysfs WLAN BRD LZ77 decode support" ++ depends on MIKROTIK_RB_SYSFS ++ help ++ Include the capability to decode wireless board data from ++ Mikrotik's LZ77 format. This was first seen in 2021. ++ Likely required if device is using RouterBOOT v7 for backup bootloader, ++ or was recently calibrated (example: US radio limits). ++ + endif # MIKROTIK +diff --git a/target/linux/generic/files/drivers/platform/mikrotik/Makefile b/target/linux/generic/files/drivers/platform/mikrotik/Makefile +index a232e1a9e8..e878126c7d 100644 +--- a/target/linux/generic/files/drivers/platform/mikrotik/Makefile ++++ b/target/linux/generic/files/drivers/platform/mikrotik/Makefile +@@ -2,3 +2,4 @@ + # Makefile for MikroTik RouterBoard platform specific drivers + # + obj-$(CONFIG_MIKROTIK_RB_SYSFS) += routerboot.o rb_hardconfig.o rb_softconfig.o ++obj-$(CONFIG_MIKROTIK_RB_SYSFS_WLAN_LZ77) += rb_hardconfig_lz77.o +diff --git a/target/linux/generic/files/drivers/platform/mikrotik/rb_hardconfig.c b/target/linux/generic/files/drivers/platform/mikrotik/rb_hardconfig.c +index bd0469d5e8..83ba74341c 100644 +--- a/target/linux/generic/files/drivers/platform/mikrotik/rb_hardconfig.c ++++ b/target/linux/generic/files/drivers/platform/mikrotik/rb_hardconfig.c +@@ -38,8 +38,9 @@ + #include + + #include "routerboot.h" ++#include "rb_hardconfig_lz77.h" + +-#define RB_HARDCONFIG_VER "0.07" ++#define RB_HARDCONFIG_VER "0.08" + #define RB_HC_PR_PFX "[rb_hardconfig] " + + /* ID values for hardware settings */ +@@ -563,6 +564,63 @@ fail: + return ret; + } + ++static int hc_wlan_data_unpack_lz77(const u16 tag_id, const u8 *inbuf, size_t inlen, ++ void *outbuf, size_t *outlen) ++{ ++ u16 rle_ofs, rle_len; ++ u8 *tempbuf; ++ size_t templen; ++ int ret; ++ ++ /* Temporary buffer same size as the outbuf */ ++ tempbuf = kmalloc(*outlen, GFP_KERNEL); ++ if (!tempbuf) ++ return -ENOMEM; ++ ++ /* LZO-decompress lzo_len bytes of outbuf into the tempbuf */ ++ ret = lz77_mikrotik_wlan_decompress( ++ (const unsigned char *)inbuf, ++ inlen, ++ (unsigned char *)tempbuf, ++ outlen); ++ if (ret < 0) { ++ pr_err(RB_HC_PR_PFX "LZ77: LZ77 decompress fail\n"); ++ goto lz77_fail; ++ } ++ templen = ret; ++ ++ pr_debug(RB_HC_PR_PFX "LZ77: decompressed from %zu to %d\n", ++ inlen, templen); ++ ++ /* skip DRE magic */ ++ tempbuf += 4; ++ templen -= 4; ++ ++ /* Past magic. Look for tag node */ ++ ret = routerboot_tag_find(tempbuf, templen, tag_id, &rle_ofs, &rle_len); ++ if (ret) { ++ pr_debug(RB_HC_PR_PFX "LZ77: no RLE data for id 0x%04x\n", tag_id); ++ goto lz77_fail; ++ } ++ pr_debug(RB_HC_PR_PFX "LZ77: found RLE data for id 0x%04x\n", tag_id); ++ ++ if (rle_len > templen) { ++ pr_err(RB_HC_PR_PFX "LZ77: Invalid RLE data length\n"); ++ ret = -EINVAL; ++ goto lz77_fail; ++ } ++ ++ /* RLE-decode tempbuf back into the outbuf */ ++ ret = routerboot_rle_decode(tempbuf+rle_ofs, rle_len, outbuf, outlen); ++ if (ret) ++ pr_debug(RB_HC_PR_PFX "LZ77: RLE decoding error (%d)\n", ret); ++ ++lz77_fail: ++ kfree(tempbuf); ++ return ret; ++} ++ ++ + static int hc_wlan_data_unpack(const u16 tag_id, const size_t tofs, size_t tlen, + void *outbuf, size_t *outlen) + { +@@ -585,6 +643,13 @@ static int hc_wlan_data_unpack(const u16 tag_id, const size_t tofs, size_t tlen, + tlen -= sizeof(magic); + ret = hc_wlan_data_unpack_lzor(tag_id, lbuf, tlen, outbuf, outlen); + break; ++ case RB_MAGIC_LZ77: ++ /* Skip magic */ ++ lbuf += sizeof(magic); ++ tlen -= sizeof(magic); ++ ret = hc_wlan_data_unpack_lz77(tag_id, lbuf, tlen, outbuf, outlen); ++ break; ++ + case RB_MAGIC_ERD: + /* Skip magic */ + lbuf += sizeof(magic); +diff --git a/target/linux/generic/files/drivers/platform/mikrotik/rb_hardconfig_lz77.c b/target/linux/generic/files/drivers/platform/mikrotik/rb_hardconfig_lz77.c +new file mode 100644 +index 0000000000..2b17050ac0 +--- /dev/null ++++ b/target/linux/generic/files/drivers/platform/mikrotik/rb_hardconfig_lz77.c +@@ -0,0 +1,430 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Copyright (C) 2023 John Thomson ++ */ ++ ++#include ++#include ++#include ++ ++#include "rb_hardconfig_lz77.h" ++ ++#define RB_HC_PR_PFX_LZ77 "[rb_hardconfig][lz77] " ++ ++/** ++ * lz77_mikrotik_wlan_get_bit ++ * ++ * @in: compressed data ++ * @in_offset_bit: bit offset to extract ++ */ ++static unsigned int lz77_mikrotik_wlan_get_bit( ++ const unsigned char *in, ++ unsigned int in_offset_bit) ++{ ++ return ((in[in_offset_bit>>3] >> (in_offset_bit & 7)) & 0x1); ++ ++} ++ ++/** ++ * lz77_mikrotik_wlan_get_byte ++ * ++ * @in: compressed data ++ * @in_offset_bit: bit offset to extract byte ++ */ ++static unsigned char lz77_mikrotik_wlan_get_byte( ++ const unsigned char *in, ++ unsigned int in_offset_bit) ++{ ++ unsigned char buf = 0; ++ int i; ++ ++ /* built a byte from unaligned bits (reversed) */ ++ for (i = 0; i <= 7; ++i) ++ buf += ((in[(in_offset_bit+i)>>3] >> ((in_offset_bit+i) & 7)) & 0x1)<<(7-i); ++ return buf; ++} ++ ++/** ++ * lz77_mikrotik_wlan_decode_count - decode bits at given offset as a count ++ * ++ * @in: compressed data ++ * @in_offset_bit: bit offset where count starts ++ * @shift: left shift operand value of first count bit ++ * @count: initial count ++ * @bits_used: how many bits were consumed by this count ++ * @size: maximum bit count for this counter ++ * ++ * Returns the decoded count ++ */ ++static int lz77_mikrotik_wlan_decode_count( ++ const unsigned char *in, ++ unsigned int in_offset_bit, ++ unsigned int shift, ++ unsigned int count, ++ unsigned int *bits_used, ++ unsigned int size) ++{ ++ unsigned int pos = in_offset_bit; ++ bool up = true; ++ ++ size += pos; ++ *bits_used = 0; ++ pr_debug(RB_HC_PR_PFX_LZ77 "decode_count inbit: %i, start shift:%i, initial count:%i\n", ++ in_offset_bit, shift, count); ++ ++ /* maybe could use find_first_zero_bit to skip count up, ++ * and extract for the count down, ++ * but would need to mask the bits from and to the byte align boundary ++ */ ++ ++ while (true) { ++ if (pos >= size) { ++ pr_err(RB_HC_PR_PFX_LZ77 "max bit index reached before count completed\n"); ++ return -1; ++ } ++ ++ /* if the bit value at offset is set */ ++ if (lz77_mikrotik_wlan_get_bit(in, pos)) ++ count += (1 << shift); ++ ++ /* shift increases until we find an unsed bit */ ++ else if (up) ++ up = false; ++ ++ if (up) ++ ++shift; ++ else { ++ if (!shift) { ++ *bits_used = pos - in_offset_bit + 1; ++ return count; ++ } ++ --shift; ++ } ++ ++ ++pos; ++ } ++ ++ return -1; ++} ++ ++enum lz77_mikrotik_instruction { ++ INSTR_ERROR = -1, ++ INSTR_LITERAL_BYTE = 0, ++ /* a (non aligned) byte follows this instruction, ++ * which is directly copied into output ++ */ ++ INSTR_PREVIOUS_OFFSET = 1, ++ /* this group is a match, with a bytes length defined by ++ * following counter bits, starting at bitshift 0, ++ * less the built-in count of 1 ++ * using the previous offset as source ++ */ ++ INSTR_LONG = 2 ++ /* this group has two counters, ++ * the first counter starts at bitshift 4, ++ * if this counter == 0, this is a non-matching group ++ * the second counter (bytes length) starts at bitshift 4, ++ * less the built-in count of 11+1. ++ * The final match group has this count 0, ++ * and following bits which pad to byte-alignment. ++ * ++ * if this counter > 0, this is a matching group ++ * this first count is the match offset (in bytes) ++ * the second count is the match length (in bytes), ++ * less the built-in count of 2 ++ * these groups can source bytes that are part of this group ++ */ ++}; ++ ++/** ++ * lz77_mikrotik_wlan_decode_instruction ++ * ++ * @in: compressed data ++ * @in_offset_bit: bit offset where instruction starts ++ * @bits_used: how many bits were consumed by this count ++ * ++ * Returns the decoded instruction ++ */ ++static enum lz77_mikrotik_instruction lz77_mikrotik_wlan_decode_instruction( ++ const unsigned char *in, ++ unsigned int in_offset_bit, ++ unsigned int *bits_used) ++{ ++ if (lz77_mikrotik_wlan_get_bit(in, in_offset_bit)) { ++ *bits_used = 2; ++ if (lz77_mikrotik_wlan_get_bit(in, ++in_offset_bit)) ++ return INSTR_LONG; ++ else ++ return INSTR_PREVIOUS_OFFSET; ++ } else { ++ *bits_used = 1; ++ return INSTR_LITERAL_BYTE; ++ } ++ return INSTR_ERROR; ++} ++ ++struct lz77_mk_instr_opcodes { ++ /* group instruction */ ++ enum lz77_mikrotik_instruction instruction; ++ /* if >0, a match group, ++ * which starts at byte output_position - 1*offset ++ */ ++ unsigned int offset; ++ /* how long the match group is, ++ * or how long the (following counter) non-match group is ++ */ ++ unsigned int length; ++ /* how many bits were used for this instruction + op code(s) */ ++ unsigned int bits_used; ++ /* input char */ ++ unsigned char *in; ++ /* offset where this instruction started */ ++ unsigned int in_pos; ++}; ++ ++/** ++ * lz77_mikrotik_wlan_decode_instruction_operators ++ * ++ * @in: compressed data ++ * @in_offset_bit: bit offset where instruction starts ++ * @previous_offset: last used match offset ++ * @opcode: struct to hold instruction & operators ++ * ++ * Returns error code ++ */ ++ ++ ++static int lz77_mikrotik_wlan_decode_instruction_operators( ++ const unsigned char *in, ++ unsigned int in_offset_bit, ++ unsigned int previous_offset, ++ struct lz77_mk_instr_opcodes *opcode) ++{ ++ enum lz77_mikrotik_instruction instruction; ++ unsigned int bit_count = 0; ++ unsigned int bits_used = 0; ++ int offset = 0; ++ int length = 0; ++ ++ instruction = lz77_mikrotik_wlan_decode_instruction( ++ in, in_offset_bit, &bit_count); ++ ++ /* skip bits used by instruction */ ++ bits_used += bit_count; ++ ++ switch (instruction) { ++ case INSTR_LITERAL_BYTE: ++ /* non-matching char */ ++ offset = 0; ++ length = 1; ++ break; ++ ++ case INSTR_PREVIOUS_OFFSET: ++ /* matching group uses previous offset */ ++ offset = previous_offset; ++ ++ length = lz77_mikrotik_wlan_decode_count( ++ in, ++ in_offset_bit + bits_used, ++ 0, 1, &bit_count, ++ LZ77_MK_MAX_COUNT_BIT_LEN); ++ if (length < 0) ++ return -1; ++ /* skip bits used by count */ ++ bits_used += bit_count; ++ break; ++ ++ case INSTR_LONG: ++ offset = lz77_mikrotik_wlan_decode_count( ++ in, ++ in_offset_bit + bits_used, ++ 4, 0, &bit_count, ++ LZ77_MK_MAX_COUNT_BIT_LEN); ++ if (offset < 0) ++ return -1; ++ ++ /* skip bits used by offset count */ ++ bits_used += bit_count; ++ ++ if (offset == 0) { ++ /* non-matching long group */ ++ length = lz77_mikrotik_wlan_decode_count( ++ in, ++ in_offset_bit + bits_used, ++ 4, 12, &bit_count, ++ LZ77_MK_MAX_COUNT_BIT_LEN); ++ if (length < 0) ++ return -1; ++ /* skip bits used by length count */ ++ bits_used += bit_count; ++ } else { ++ /* matching group */ ++ length = lz77_mikrotik_wlan_decode_count( ++ in, ++ in_offset_bit + bits_used, ++ 0, 2, &bit_count, ++ LZ77_MK_MAX_COUNT_BIT_LEN); ++ if (length < 0) ++ return -1; ++ /* skip bits used by length count */ ++ bits_used += bit_count; ++ } ++ ++ break; ++ ++ case INSTR_ERROR: ++ return -1; ++ } ++ ++ opcode->instruction = instruction; ++ opcode->offset = offset; ++ opcode->length = length; ++ opcode->bits_used = bits_used; ++ opcode->in = (unsigned char *) in; ++ opcode->in_pos = in_offset_bit; ++ return 0; ++} ++ ++/** ++ * lz77_mikrotik_wlan_decompress ++ * ++ * @in: compressed data ptr ++ * @in_len: length of compressed data ++ * @out: buffer ptr to decompress into ++ * @out_len: length of decompressed buffer ++ * ++ * Returns length of decompressed data ++ */ ++int lz77_mikrotik_wlan_decompress( ++ const unsigned char *in, ++ size_t in_len, ++ unsigned char *out, ++ size_t *out_len) ++{ ++ unsigned char *output_ptr; ++ unsigned int input_bit = 0; ++ unsigned char * const output_end = out + *out_len; ++ struct lz77_mk_instr_opcodes *opcode; ++ unsigned int match_offset = 0; ++ int rc = 0; ++ unsigned int match_length, partial_count, i; ++ ++ output_ptr = out; ++ ++ if (in_len > LZ77_MK_MAX_ENCODED || ++ (in_len * 8) > UINT_MAX) { ++ pr_err(RB_HC_PR_PFX_LZ77 "input longer than expected\n"); ++ return -1; ++ } ++ ++ opcode = kmalloc(sizeof(struct lz77_mk_instr_opcodes), GFP_KERNEL); ++ if (!opcode) ++ return -ENOMEM; ++ ++ while (true) { ++ if (output_ptr > output_end) { ++ pr_err(RB_HC_PR_PFX_LZ77 "output overrun\n"); ++ goto free_lz77_struct; ++ } ++ if (input_bit > in_len*8) { ++ pr_err(RB_HC_PR_PFX_LZ77 "input overrun\n"); ++ goto free_lz77_struct; ++ } ++ ++ rc = lz77_mikrotik_wlan_decode_instruction_operators( ++ in, input_bit, match_offset, opcode); ++ if (rc < 0) { ++ pr_err(RB_HC_PR_PFX_LZ77 "instruction operands decode error\n"); ++ goto free_lz77_struct; ++ } ++ ++ pr_debug(RB_HC_PR_PFX_LZ77 "inbit:0x%x->outbyte:0x%x", ++ input_bit, output_ptr - out); ++ ++ input_bit += opcode->bits_used; ++ switch (opcode->instruction) { ++ case INSTR_LITERAL_BYTE: ++ pr_debug(" short"); ++ fallthrough; ++ case INSTR_LONG: ++ if (opcode->offset == 0) { ++ /* this is a non-matching group */ ++ pr_debug(" non-match, len: 0x%x\n", ++ opcode->length); ++ /* test end marker */ ++ if (opcode->length == 0xc && ++ ((input_bit + opcode->length*8) > in_len)){ ++ ++ if (!(*(unsigned int *)out == LZ77_MK_EXPECTED_OUT)) { ++ pr_debug(RB_HC_PR_PFX_LZ77 "lz77 decompressed from %zu to %d\n", ++ in_len, output_ptr - out); ++ return (unsigned int)(output_ptr - out); ++ } else { ++ pr_err(RB_HC_PR_PFX_LZ77 "lz77 decompressed: unexpected output\n"); ++ return -1; ++ } ++ } ++ ++ for (i = opcode->length; i > 0; --i) { ++ *output_ptr = lz77_mikrotik_wlan_get_byte(in, input_bit); ++ ++output_ptr; ++ input_bit += 8; ++ } ++ break; ++ } ++ match_offset = opcode->offset; ++ fallthrough; ++ case INSTR_PREVIOUS_OFFSET: ++ match_length = opcode->length; ++ partial_count = 0; ++ ++ pr_debug(" match, offset: 0x%x, len: 0x%x", ++ opcode->offset, match_length); ++ ++ if (opcode->offset == 0) { ++ pr_err(RB_HC_PR_PFX_LZ77 "match group missing opcode->offset\n"); ++ goto free_lz77_struct; ++ } ++ ++ /* overflow */ ++ if ((output_ptr + match_length) > output_end) { ++ pr_err(RB_HC_PR_PFX_LZ77 "match group output overflow\n"); ++ goto free_lz77_struct; ++ } ++ ++ /* underflow */ ++ if ((output_ptr - opcode->offset) < out) { ++ pr_err(RB_HC_PR_PFX_LZ77 "match group offset underflow\n"); ++ goto free_lz77_struct; ++ } ++ ++ while (opcode->offset < match_length) { ++ ++partial_count; ++ memcpy(output_ptr, ++ output_ptr - opcode->offset, ++ opcode->offset); ++ output_ptr += opcode->offset; ++ match_length -= opcode->offset; ++ } ++ memcpy(output_ptr, ++ output_ptr - opcode->offset, ++ match_length); ++ output_ptr += match_length; ++ if (partial_count) ++ pr_debug(" (%d partial memcpy)", partial_count); ++ pr_debug("\n"); ++ ++ break; ++ ++ case INSTR_ERROR: ++ return -1; ++ } ++ } ++ ++ pr_err(RB_HC_PR_PFX_LZ77 "decode loop broken\n"); ++ ++free_lz77_struct: ++ kfree(opcode); ++ ++ return -1; ++} +diff --git a/target/linux/generic/files/drivers/platform/mikrotik/rb_hardconfig_lz77.h b/target/linux/generic/files/drivers/platform/mikrotik/rb_hardconfig_lz77.h +new file mode 100644 +index 0000000000..a9940bfadf +--- /dev/null ++++ b/target/linux/generic/files/drivers/platform/mikrotik/rb_hardconfig_lz77.h +@@ -0,0 +1,40 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/* ++ * Copyright (C) 2023 John Thomson ++ */ ++ ++#ifndef _ROUTERBOOT_LZ77_H_ ++#define _ROUTERBOOT_LZ77_H_ ++ ++#include ++ ++#define LZ77_MK_MAX_ENCODED 0x1000 ++#define LZ77_MK_MAX_DECODED 0x40000 ++ ++/* examples have all decompressed to start with DRE\x00 */ ++#define LZ77_MK_EXPECTED_OUT 0x44524500 ++ ++/* the look behind window ++ * unknown, for long instruction match offsets up to ++ * 6449 have been seen (would need 21 counter bits: 4 to 12 + 11 to 0) ++ * conservative value here: 27 provides offset up to 0x8000 bytes ++ */ ++#define LZ77_MK_MAX_COUNT_BIT_LEN 27 ++ ++#ifdef CONFIG_MIKROTIK_RB_SYSFS_WLAN_LZ77 ++int lz77_mikrotik_wlan_decompress( ++ const unsigned char *in, ++ size_t in_len, ++ unsigned char *out, ++ size_t *out_len); ++#else ++static inline int lz77_mikrotik_wlan_decompress( ++ const unsigned char *in, ++ size_t in_len, ++ unsigned char *out, ++ size_t *out_len) ++{ ++ return -EOPNOTSUPP; ++} ++#endif /* CONFIG_MIKROTIK_RB_SYSFS_WLAN_LZ77 */ ++#endif /* _ROUTERBOOT_LZ77_H_ */ +diff --git a/target/linux/generic/files/drivers/platform/mikrotik/routerboot.h b/target/linux/generic/files/drivers/platform/mikrotik/routerboot.h +index e858a524af..91693d8985 100644 +--- a/target/linux/generic/files/drivers/platform/mikrotik/routerboot.h ++++ b/target/linux/generic/files/drivers/platform/mikrotik/routerboot.h +@@ -16,6 +16,7 @@ + #define RB_MAGIC_SOFT (('S') | ('o' << 8) | ('f' << 16) | ('t' << 24)) + #define RB_MAGIC_LZOR (('L') | ('Z' << 8) | ('O' << 16) | ('R' << 24)) + #define RB_MAGIC_ERD (('E' << 16) | ('R' << 8) | ('D')) ++#define RB_MAGIC_LZ77 (('7') | ('7' << 8) | ('Z' << 16) | ('L' << 24)) + + #define RB_ART_SIZE 0x10000 + +diff --git a/target/linux/ipq40xx/mikrotik/config-default b/target/linux/ipq40xx/mikrotik/config-default +index 1268d2c810..149e02ac1a 100644 +--- a/target/linux/ipq40xx/mikrotik/config-default ++++ b/target/linux/ipq40xx/mikrotik/config-default +@@ -1,5 +1,6 @@ + CONFIG_MIKROTIK=y + CONFIG_MIKROTIK_RB_SYSFS=y ++CONFIG_MIKROTIK_RB_SYSFS_WLAN_LZ77=y + CONFIG_MTD_ROUTERBOOT_PARTS=y + CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y + CONFIG_MTD_SPLIT_MINOR_FW=y +diff --git a/target/linux/ramips/mt7621/config-5.15 b/target/linux/ramips/mt7621/config-5.15 +index 05e4c1ce87..430e0ba328 100644 +--- a/target/linux/ramips/mt7621/config-5.15 ++++ b/target/linux/ramips/mt7621/config-5.15 +@@ -118,6 +118,7 @@ CONFIG_MFD_SYSCON=y + CONFIG_MIGRATION=y + CONFIG_MIKROTIK=y + CONFIG_MIKROTIK_RB_SYSFS=y ++# CONFIG_MIKROTIK_RB_SYSFS_WLAN_LZ77 is not set + CONFIG_MIPS=y + CONFIG_MIPS_ASID_BITS=8 + CONFIG_MIPS_ASID_SHIFT=0 +-- +2.45.2 + diff --git a/profiles/devices/mikrotik_hap-ac3.yml b/profiles/devices/mikrotik_hap-ac3.yml index 75c105e8..16f424df 100644 --- a/profiles/devices/mikrotik_hap-ac3.yml +++ b/profiles/devices/mikrotik_hap-ac3.yml @@ -5,6 +5,7 @@ image_paths: - "ipq40xx/mikrotik/openwrt-ipq40xx-mikrotik-mikrotik_hap-ac3-initramfs-kernel.bin" - "ipq40xx/mikrotik/openwrt-ipq40xx-mikrotik-mikrotik_hap-ac3-squashfs-sysupgrade.bin" supported: true +apply_patches: true private_radio: - radio0 diff --git a/roles/prepare-sources/defaults/main.yml b/roles/prepare-sources/defaults/main.yml index 71668bb8..85fdafad 100644 --- a/roles/prepare-sources/defaults/main.yml +++ b/roles/prepare-sources/defaults/main.yml @@ -1,3 +1,4 @@ repo: https://github.com/openwrt/openwrt version: openwrt-23.05 source_dir: build/ +apply_patches: false \ No newline at end of file diff --git a/roles/prepare-sources/tasks/main.yml b/roles/prepare-sources/tasks/main.yml index de6dca0b..73a1c6ff 100644 --- a/roles/prepare-sources/tasks/main.yml +++ b/roles/prepare-sources/tasks/main.yml @@ -14,6 +14,14 @@ version: "{{version}}" register: source_version +- name: Apply patches + command: git am --no-gpg-sign "{{ item }}" + with_fileglob: + - "patches/*" + args: + chdir: "{{source_dir}}" + when: apply_patches + - name: Update Rust shell: "{{ansible_env.HOME}}/.cargo/bin/rustup default 1.75; {{ansible_env.HOME}}/.cargo/bin/rustup update"