Merge Official Source

This commit is contained in:
AmadeusGhost 2020-05-09 11:15:20 +08:00
commit 004c7f9944
216 changed files with 2099 additions and 1490 deletions

View File

@ -12,7 +12,7 @@ include $(INCLUDE_DIR)/version.mk
include $(INCLUDE_DIR)/feeds.mk
PKG_NAME:=base-files
PKG_RELEASE:=218
PKG_RELEASE:=220
PKG_FLAGS:=nonshared
PKG_FILE_DEPENDS:=$(PLATFORM_DIR)/ $(GENERIC_PLATFORM_DIR)/base-files/

View File

@ -60,15 +60,36 @@ caldata_from_file() {
local source=$1
local offset=$(($2))
local count=$(($3))
local target=$4
dd if=$source of=/lib/firmware/$FIRMWARE iflag=skip_bytes bs=$count skip=$offset count=1 2>/dev/null || \
[ -n "$target" ] || target=/lib/firmware/$FIRMWARE
dd if=$source of=$target iflag=skip_bytes bs=$count skip=$offset count=1 2>/dev/null || \
caldata_die "failed to extract calibration data from $source"
}
caldata_sysfsload_from_file() {
local source=$1
local offset=$(($2))
local count=$(($3))
# test extract to /dev/null first
dd if=$source of=/dev/null iflag=skip_bytes bs=$count skip=$offset count=1 2>/dev/null || \
caldata_die "failed to extract calibration data from $source"
# can't fail now
echo 1 > /sys/$DEVPATH/loading
dd if=$source of=/sys/$DEVPATH/data iflag=skip_bytes bs=$count skip=$offset count=1 2>/dev/null
echo 0 > /sys/$DEVPATH/loading
}
caldata_valid() {
local expected="$1"
local target=$2
magic=$(hexdump -v -n 2 -e '1/1 "%02x"' /lib/firmware/$FIRMWARE)
[ -n "$target" ] || target=/lib/firmware/$FIRMWARE
magic=$(hexdump -v -n 2 -e '1/1 "%02x"' $target)
[ "$magic" = "$expected" ]
return $?
}
@ -77,6 +98,7 @@ caldata_patch_chksum() {
local mac=$1
local mac_offset=$(($2))
local chksum_offset=$(($3))
local target=$4
local xor_mac
local xor_fw_mac
local xor_fw_chksum
@ -91,38 +113,44 @@ caldata_patch_chksum() {
xor_fw_chksum=$(xor $xor_fw_chksum $xor_fw_mac $xor_mac)
printf "%b" "\x${xor_fw_chksum:0:2}\x${xor_fw_chksum:2:2}" | \
dd of=/lib/firmware/$FIRMWARE conv=notrunc bs=1 seek=$chksum_offset count=2
dd of=$target conv=notrunc bs=1 seek=$chksum_offset count=2
}
caldata_patch_mac() {
local mac=$1
local mac_offset=$(($2))
local chksum_offset=$3
local target=$4
[ -z "$mac" -o -z "$mac_offset" ] && return
[ -n "$chksum_offset" ] && caldata_patch_chksum "$mac" "$mac_offset" "$chksum_offset"
[ -n "$target" ] || target=/lib/firmware/$FIRMWARE
macaddr_2bin $mac | dd of=/lib/firmware/$FIRMWARE conv=notrunc oflag=seek_bytes bs=6 seek=$mac_offset count=1 || \
[ -n "$chksum_offset" ] && caldata_patch_chksum "$mac" "$mac_offset" "$chksum_offset" "$target"
macaddr_2bin $mac | dd of=$target conv=notrunc oflag=seek_bytes bs=6 seek=$mac_offset count=1 || \
caldata_die "failed to write MAC address to eeprom file"
}
ath9k_patch_mac() {
local mac=$1
local target=$2
caldata_patch_mac "$mac" 0x2
caldata_patch_mac "$mac" 0x2 "" "$target"
}
ath9k_patch_mac_crc() {
local mac=$1
local mac_offset=$2
local chksum_offset=$((mac_offset - 10))
local target=$4
caldata_patch_mac "$mac" "$mac_offset" "$chksum_offset"
caldata_patch_mac "$mac" "$mac_offset" "$chksum_offset" "$target"
}
ath10k_patch_mac() {
local mac=$1
local target=$2
caldata_patch_mac "$mac" 0x6 0x2
caldata_patch_mac "$mac" 0x6 0x2 "$target"
}

View File

@ -103,11 +103,11 @@ get_magic_long() {
}
get_magic_gpt() {
(get_image "$@" | dd bs=8 count=1 skip=64) 2>/dev/null
(get_image "$@" | dd bs=8 count=1 skip=64) 2>/dev/null
}
get_magic_vfat() {
(get_image "$@" | dd bs=1 count=3 skip=54) 2>/dev/null
(get_image "$@" | dd bs=1 count=3 skip=54) 2>/dev/null
}
part_magic_efi() {

View File

@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=lldpd
PKG_VERSION:=1.0.5
PKG_RELEASE:=1
PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://media.luffy.cx/files/lldpd

View File

@ -5,7 +5,7 @@ config lldpd config
option enable_edp 1
option agentxsocket /var/run/agentx.sock
option lldp_class 4
option lldp_location "2:FR:6:Commercial Rd:3:Roseville:19:4"
@ -13,6 +13,8 @@ config lldpd config
#option lldp_description "OpenWrt System"
#option lldp_hostname "Modified Hostname"
#option lldp_mgmt_ip "!192.168.1.1"
# interfaces to listen on
list interface "loopback"
list interface "lan"

View File

@ -42,11 +42,15 @@ write_lldpd_conf()
fi
done
local lldp_mgmt_ip
config_get lldp_mgmt_ip 'config' 'lldp_mgmt_ip'
# Clear out the config file first
echo -n > "$LLDPD_CONF"
[ -n "$ifnames" ] && echo "configure system interface pattern" "$ifnames" >> "$LLDPD_CONF"
[ -n "$lldp_description" ] && echo "configure system description" "\"$lldp_description\"" >> "$LLDPD_CONF"
[ -n "$lldp_hostname" ] && echo "configure system hostname" "\"$lldp_hostname\"" >> "$LLDPD_CONF"
[ -n "$lldp_mgmt_ip" ] && echo "configure system ip management pattern" "\"$lldp_mgmt_ip\"" >> "$LLDPD_CONF"
# Since lldpd's sysconfdir is /tmp, we'll symlink /etc/lldpd.d to /tmp/$LLDPD_CONFS_DIR
[ -e $LLDPD_CONFS_DIR ] || ln -s /etc/lldpd.d $LLDPD_CONFS_DIR
@ -103,6 +107,8 @@ reload_service() {
unconfigure lldp custom-tlv
unconfigure system interface pattern
unconfigure system description
unconfigure system hostname
unconfigure system ip management pattern
EOF
# Rewrite lldpd.conf
# If something changed it should be included by the lldpcli call

View File

@ -1,38 +0,0 @@
#
# Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
# Copyright (C) 2018 Chris Schimp <silverchris@gmail.com>
# Copyright (C) 2019 Robert Marko <robimarko@gmail.com>
# Copyright (C) 2019 Roger Pueyo Centelles <roger.pueyo@guifi.net>
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=rbextract
PKG_RELEASE:=3
CMAKE_INSTALL:=1
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
define Package/rbextract
SECTION:=utils
CATEGORY:=Utilities
SUBMENU:=Boot Loaders
TITLE:=RouterBOOT ART Extractor
DEPENDS:=@TARGET_ath79 +liblzo
endef
define Package/rbextract/description
This utility is for extracting the WLAN radio calibration data from Mikrotik
Routerboards.
endef
define Package/rbextract/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/rbextract $(1)/usr/sbin/
endef
$(eval $(call BuildPackage,rbextract))

View File

@ -1,14 +0,0 @@
cmake_minimum_required(VERSION 2.6)
PROJECT(rbextract C)
ADD_DEFINITIONS(-Wall --std=gnu99 -Wmissing-declarations)
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
FIND_PATH(lzo_include_dir lzo/lzo1x.h)
INCLUDE_DIRECTORIES(${lzo_include_dir})
ADD_EXECUTABLE(rbextract rbextract.c rle.c)
TARGET_LINK_LIBRARIES(rbextract lzo2)
INSTALL(TARGETS rbextract RUNTIME DESTINATION sbin)

View File

@ -1,497 +0,0 @@
/*
* RouterBoot helper routines
*
* Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org>
* Copyright (C) 2018 Chris Schimp <silverchris@gmail.com>
* Copyright (C) 2019 Robert Marko <robimarko@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*/
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <endian.h>
#include <arpa/inet.h>
#include <lzo/lzo1x.h>
#include "rle.h"
#include "routerboot.h"
inline uint32_t
get_u32(const void *buf)
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
return *(uint32_t *)buf;
#elif __BYTE_ORDER == __BIG_ENDIAN
const uint8_t *p = buf;
return ((uint32_t) p[3] + ((uint32_t) p[2] << 8) +
((uint32_t) p[1] << 16) + ((uint32_t) p[0] << 24));
#else
#error "Unknown byte order!"
#endif
}
int
routerboot_find_tag(uint8_t *buf, unsigned int buflen, uint16_t tag_id,
uint8_t **tag_data, uint16_t *tag_len)
{
uint16_t id;
uint16_t len;
uint32_t magic;
bool align = false;
int ret;
if (buflen < 4)
return 1;
magic = get_u32(buf);
switch (magic) {
case RB_MAGIC_LZOR:
buf += 4;
buflen -= 4;
break;
case RB_MAGIC_ERD:
align = true;
/* fall trough */
case RB_MAGIC_HARD:
/* skip magic value */
buf += 4;
buflen -= 4;
break;
case RB_MAGIC_SOFT:
if (buflen < 8)
return 1;
/* skip magic and CRC value */
buf += 8;
buflen -= 8;
break;
default:
return 1;
}
ret = 1;
while (buflen > 4){
uint32_t id_and_len = get_u32(buf);
buf += 4;
buflen -= 4;
id = id_and_len & 0xFFFF;
len = id_and_len >> 16;
if (align)
len += (4 - len % 4) % 4;
if (id == RB_ID_TERMINATOR) {
break;
}
if (buflen < len)
break;
if (id == tag_id) {
*tag_len = len;
*tag_data = buf;
ret = 0;
break;
}
buf += len;
buflen -= len;
}
return ret;
}
inline int
rb_find_hard_cfg_tag(uint16_t tag_id, uint8_t **tag_data, uint16_t *tag_len)
{
if (!rb_hardconfig ||
!rb_hardconfig_len)
return 1;
return routerboot_find_tag(rb_hardconfig,
rb_hardconfig_len,
tag_id, tag_data, tag_len);
}
const uint8_t *
rb_get_board_product_code(void)
{
uint16_t tag_len;
uint8_t *tag;
int err;
err = rb_find_hard_cfg_tag(RB_ID_BOARD_PRODUCT_CODE, &tag, &tag_len);
if (err)
return NULL;
return tag;
}
uint32_t
rb_get_board_mac(void)
{
uint16_t tag_len;
uint8_t *tag;
int err;
err = rb_find_hard_cfg_tag(RB_ID_MAC_ADDRESS_PACK, &tag, &tag_len);
if (err)
return 0;
return htonl(get_u32(tag));
}
const uint8_t *
rb_get_board_serial(void)
{
uint16_t tag_len;
uint8_t *tag;
int err;
err = rb_find_hard_cfg_tag(RB_ID_SERIAL_NUMBER, &tag, &tag_len);
if (err)
return NULL;
return tag;
}
const uint8_t *
rb_get_board_identifier(void)
{
uint16_t tag_len;
uint8_t *tag;
int err;
err = rb_find_hard_cfg_tag(RB_ID_BOARD_IDENTIFIER, &tag, &tag_len);
if (err)
return NULL;
return tag;
}
const uint8_t *
rb_get_board_name(void)
{
uint16_t tag_len;
uint8_t *tag;
int err;
err = rb_find_hard_cfg_tag(RB_ID_BOARD_NAME, &tag, &tag_len);
if (err)
return NULL;
return tag;
}
const uint8_t *
rb_get_factory_booter_version(void)
{
uint16_t tag_len;
uint8_t *tag;
int err;
err = rb_find_hard_cfg_tag(RB_ID_BIOS_VERSION, &tag, &tag_len);
if (err)
return NULL;
return tag;
}
uint32_t
rb_get_flash_info(void)
{
uint16_t tag_len;
uint8_t *tag;
int err;
err = rb_find_hard_cfg_tag(RB_ID_FLASH_INFO, &tag, &tag_len);
if (err)
return 0;
return htonl(get_u32(tag));
}
uint32_t
rb_get_hw_options(void)
{
uint16_t tag_len;
uint8_t *tag;
int err;
err = rb_find_hard_cfg_tag(RB_ID_HW_OPTIONS, &tag, &tag_len);
if (err)
return 0;
return htonl(get_u32(tag));
}
uint8_t *
__rb_get_wlan_data(void)
{
uint16_t tag_len;
uint8_t *tag;
uint16_t erd_tag_len;
uint8_t *erd_tag;
uint8_t *buf_lzo_in;
uint8_t *buf_lzo_out;
uint8_t *buf_rle_out;
int err;
uint32_t magic;
uint32_t erd_magic;
uint32_t erd_offset;
size_t lzo_out_len;
err = rb_find_hard_cfg_tag(RB_ID_WLAN_DATA, &tag, &tag_len);
if (err) {
printf("no calibration data found\n");
goto err;
}
buf_lzo_in = malloc(RB_ART_SIZE);
if (buf_lzo_in == NULL) {
printf("no memory for calibration data\n");
goto err;
}
buf_rle_out = malloc(RB_ART_SIZE);
if (buf_rle_out == NULL) {
printf("no memory for calibration data\n");
goto err_free_lzo_out;
}
buf_lzo_out = malloc(RB_ART_SIZE);
if (buf_lzo_out == NULL) {
printf("no memory for calibration data\n");
goto err_free_lzo_in;
}
magic = get_u32(tag);
if (magic == RB_MAGIC_LZOR) {
tag += 4;
tag_len -= 4;
if (tag_len + sizeof(lzo_prefix) > RB_ART_SIZE) {
printf("Calibration data too large\n");
goto err_free_lzo_in;
}
printf("Copying fixed LZO prefix (size: %d)\n", sizeof(lzo_prefix));
memcpy(buf_lzo_in, lzo_prefix, sizeof(lzo_prefix));
printf("Copying input data (size: %d)\n", tag_len);
memcpy(buf_lzo_in + sizeof(lzo_prefix), tag, tag_len);
printf("Decompressing with LZO\n");
lzo_out_len = RB_ART_SIZE;
err = lzo1x_decompress_safe(buf_lzo_in, tag_len + sizeof(lzo_prefix),
buf_lzo_out, &lzo_out_len, NULL);
/* For some reason, I get this "input not consumed" error
* even though the output is correct, so ignore it. */
if (err && err != LZO_E_INPUT_NOT_CONSUMED) {
printf("unable to decompress calibration data: %d\n",
err);
goto err_free_lzo_out;
}
printf("Looking for ERD data in decompressed output\n");
erd_magic = 0;
for (erd_offset = 0; erd_offset < lzo_out_len; erd_offset++) {
erd_magic = get_u32(buf_lzo_out + erd_offset);
if (erd_magic == RB_MAGIC_ERD)
break;
}
if (erd_magic != RB_MAGIC_ERD) {
printf("no ERD data found\n");
goto err_free_lzo_out;
}
printf("Found ERD magic at offset %d\n", erd_offset);
err = routerboot_find_tag(buf_lzo_out + erd_offset,
lzo_out_len - erd_offset,
0x1, &erd_tag, &erd_tag_len);
if (err) {
printf("No ERD chunk found\n");
goto err_free_lzo_out;
}
printf("Decompress ERD data with RLE\n");
err = rle_decode(erd_tag, erd_tag_len, buf_rle_out, RB_ART_SIZE,
NULL, NULL);
if (err) {
printf("unable to decode ERD data\n");
goto err_free_rle_out;
}
}
/* Older ath79-based boards directly show the RB_MAGIC_ERD bytes followed by
the LZO-compressed calibration data with no RLE */
else if (magic == RB_MAGIC_ERD) {
if (tag_len > RB_ART_SIZE) {
printf("Calibration data too large\n");
goto err_free_lzo_in;
}
err = routerboot_find_tag(tag, tag_len,
0x1, &buf_lzo_in, &erd_tag_len);
if (err) {
printf("No ERD chunk found\n");
goto err_free_lzo_out;
}
printf("Decompressing with LZO\n");
lzo_out_len = RB_ART_SIZE;
err = lzo1x_decompress_safe(buf_lzo_in, tag_len,
buf_lzo_out, &lzo_out_len, NULL);
/* For some reason, I get this "input not consumed" error
* even though the output is correct, so ignore it. */
if (err && err != LZO_E_INPUT_NOT_CONSUMED) {
printf("unable to decompress calibration data: %d\n",
err);
goto err_free_lzo_out;
}
buf_rle_out = buf_lzo_out;
}
/* Even older ath79-base boards directly have RLE-encoded calibration data,
without any LZO compresion nor showing RB_MAGIC_ERD bytes */
else {
printf("Decode calibration data with RLE\n");
err = rle_decode(tag, tag_len, buf_rle_out, RB_ART_SIZE,
NULL, NULL);
if (err) {
printf("unable to decode ERD data\n");
goto err_free_rle_out;
}
}
return buf_rle_out;
err_free_rle_out:
free(buf_rle_out);
err_free_lzo_out:
free(buf_lzo_out);
err_free_lzo_in:
free(buf_lzo_in);
err:
return NULL;
}
int
main(int argc, char **argv)
{
FILE *infile;
FILE *outfile;
uint8_t *buf;
uint32_t magic;
uint32_t i;
if(argc < 2){
printf("Not enough arguments\n");
printf("Use -h for help\n");
exit(1);
}
if(strcmp(argv[1], "-h") == 0){
printf("This program can extract various data from MikroTik devices hard_config partition\n");
printf("Usage: rbextract <options> <hard_config_location> <output_file> (Optional)\n");
printf("Options:\n");
printf("-a Prints all possible info\n");
printf("-n Prints board name\n");
printf("-p Prints board product code\n");
printf("-i Prints board identifier\n");
printf("-s Prints board serial number\n");
printf("-m Prints board MAC\n");
printf("-o Prints board HW options\n");
printf("-r Prints board RouterBoot factory version\n");
printf("-f Prints board flash identifier\n");
printf("-e Extract board radio calibration\n");
printf("hard_config_location: Path to hard_config partiton\n");
printf("output_file: Path to where caldata will be output\n");
} else {
infile = fopen(argv[2], "r");
if(infile == NULL){
printf("Cant open given path\n");
return 1;
}
fseek(infile, 0L, SEEK_END);
rb_hardconfig_len = ftell(infile);
fseek(infile, 0L, SEEK_SET);
rb_hardconfig = (uint8_t*)calloc(rb_hardconfig_len, sizeof(uint8_t));
if(rb_hardconfig == NULL)
return 1;
fread(rb_hardconfig, sizeof(uint8_t), rb_hardconfig_len, infile);
fclose(infile);
magic = get_u32(rb_hardconfig);
if(magic != RB_MAGIC_HARD){
printf("Routerboot Hard Config not found\n");
exit(1);
}
if(strcmp(argv[1], "-a") == 0){
printf("Board name: %s\n", rb_get_board_name());
printf("Board product code: %s\n", rb_get_board_product_code());
printf("Board identifier: %s\n", rb_get_board_identifier());
printf("Board serial: %s\n", rb_get_board_serial());
printf("Board MAC: %X\n", rb_get_board_mac());
printf("HW Options %x\n", rb_get_hw_options());
printf("Factory RouterBoot version: %s\n", rb_get_factory_booter_version());
printf("Flash identifier: %x\n", rb_get_flash_info());
} else if(strcmp(argv[1], "-n") == 0){
printf("%s\n", rb_get_board_name());
} else if(strcmp(argv[1], "-p") == 0){
printf("%s\n", rb_get_board_product_code());
} else if(strcmp(argv[1], "-i") == 0){
printf("%s\n", rb_get_board_identifier());
} else if(strcmp(argv[1], "-s") == 0){
printf("%s\n", rb_get_board_serial());
} else if(strcmp(argv[1], "-m") == 0){
printf("%x\n", rb_get_board_mac());
} else if(strcmp(argv[1], "-o") == 0){
printf("%x\n", rb_get_hw_options());
} else if(strcmp(argv[1], "-r") == 0){
printf("%s\n", rb_get_factory_booter_version());
} else if(strcmp(argv[1], "-f") == 0){
printf("%x\n", rb_get_flash_info());
} else if(strcmp(argv[1], "-e") == 0){
buf = __rb_get_wlan_data();
if (buf == NULL) {
printf("Could not extract calibration data\n");
return 1;
}
if(argv[3] == NULL){
printf("Missing output file argument\n");
return 1;
}
outfile = fopen(argv[3], "wb");
if(outfile == NULL){
printf("Cant open given path\n");
return 1;
}
/* Write 65536 bytes of caldata */
for(i = 0; i<RB_ART_SIZE; i++){
fwrite(&buf[i], sizeof(uint8_t), sizeof(uint8_t), outfile);
}
fclose(outfile);
}
}
exit(0);
}

View File

@ -1,80 +0,0 @@
/*
* RLE decoding routine
*
* Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*/
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <sys/types.h>
#include "rle.h"
int rle_decode(const unsigned char *src, size_t srclen,
unsigned char *dst, size_t dstlen,
size_t *src_done, size_t *dst_done)
{
size_t srcpos, dstpos;
int ret;
srcpos = 0;
dstpos = 0;
ret = 1;
/* sanity checks */
if (!src || !srclen || !dst || !dstlen)
goto out;
while (1) {
signed char count;
if (srcpos >= srclen)
break;
count = (signed char) src[srcpos++];
if (count == 0) {
ret = 0;
break;
}
if (count > 0) {
unsigned char c;
if (srcpos >= srclen)
break;
c = src[srcpos++];
while (count--) {
if (dstpos >= dstlen)
break;
dst[dstpos++] = c;
}
} else {
count *= -1;
while (count--) {
if (srcpos >= srclen)
break;
if (dstpos >= dstlen)
break;
dst[dstpos++] = src[srcpos++];
}
}
}
out:
if (src_done)
*src_done = srcpos;
if (dst_done)
*dst_done = dstpos;
return ret;
}

View File

@ -1,8 +0,0 @@
#ifndef _RLE_H_
#define _RLE_H_
int rle_decode(const unsigned char *src, size_t srclen,
unsigned char *dst, size_t dstlen,
size_t *src_done, size_t *dst_done);
#endif /* _RLE_H_ */

View File

@ -1,258 +0,0 @@
/*
* RouterBoot/RBextract definitions
*
* Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org>
* Copyright (C) 2019 Robert Marko <robimarko@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*/
#ifndef _RBEXTRACT_H
#define _RBEXTRACT_H
/* Used on some newer boards (ipq40xx). This fixed data is concatenated
with data extracted from the hard_config partition, then decompressed
with LZO. There may also be a second decoding step with RLE. */
uint8_t lzo_prefix[] = {
0x00, 0x05, 0x4c, 0x4c, 0x44, 0x00, 0x34, 0xfe,
0xfe, 0x34, 0x11, 0x3c, 0x1e, 0x3c, 0x2e, 0x3c,
0x4c, 0x34, 0x00, 0x52, 0x62, 0x92, 0xa2, 0xb2,
0xc3, 0x2a, 0x14, 0x00, 0x00, 0x05, 0xfe, 0x6a,
0x3c, 0x16, 0x32, 0x16, 0x11, 0x1e, 0x12, 0x46,
0x32, 0x46, 0x11, 0x4e, 0x12, 0x36, 0x32, 0x36,
0x11, 0x3e, 0x12, 0x5a, 0x9a, 0x64, 0x00, 0x04,
0xfe, 0x10, 0x3c, 0x00, 0x01, 0x00, 0x00, 0x28,
0x0c, 0x00, 0x0f, 0xfe, 0x14, 0x00, 0x24, 0x24,
0x23, 0x24, 0x24, 0x23, 0x25, 0x22, 0x21, 0x21,
0x23, 0x22, 0x21, 0x22, 0x21, 0x2d, 0x38, 0x00,
0x0c, 0x25, 0x25, 0x24, 0x25, 0x25, 0x24, 0x23,
0x22, 0x21, 0x20, 0x23, 0x21, 0x21, 0x22, 0x21,
0x2d, 0x38, 0x00, 0x28, 0xb0, 0x00, 0x00, 0x22,
0x00, 0x00, 0xc0, 0xfe, 0x03, 0x00, 0xc0, 0x00,
0x62, 0xff, 0x62, 0xff, 0xfe, 0x06, 0x00, 0xbb,
0xff, 0xba, 0xff, 0xfe, 0x08, 0x00, 0x9e, 0xff,
0xfe, 0x0a, 0x00, 0x53, 0xff, 0xfe, 0x02, 0x00,
0x20, 0xff, 0xb1, 0xfe, 0xfe, 0xb2, 0xfe, 0xfe,
0xed, 0xfe, 0xfe, 0xfe, 0x04, 0x00, 0x3a, 0xff,
0x3a, 0xff, 0xde, 0xfd, 0x5f, 0x04, 0x33, 0xff,
0x4c, 0x74, 0x03, 0x05, 0x05, 0xff, 0x6d, 0xfe,
0xfe, 0x6d, 0xfe, 0xfe, 0xaf, 0x08, 0x63, 0xff,
0x64, 0x6f, 0x08, 0xac, 0xff, 0xbf, 0x6d, 0x08,
0x7a, 0x6d, 0x08, 0x96, 0x74, 0x04, 0x00, 0x08,
0x79, 0xff, 0xda, 0xfe, 0xfe, 0xdb, 0xfe, 0xfe,
0x56, 0xff, 0xfe, 0x04, 0x00, 0x5e, 0xff, 0x5e,
0xff, 0x6c, 0xfe, 0xfe, 0xfe, 0x06, 0x00, 0x41,
0xff, 0x7f, 0x74, 0x03, 0x00, 0x11, 0x44, 0xff,
0xa9, 0xfe, 0xfe, 0xa9, 0xfe, 0xfe, 0xa5, 0x8f,
0x01, 0x00, 0x08, 0x01, 0x01, 0x02, 0x04, 0x08,
0x02, 0x04, 0x08, 0x08, 0x01, 0x01, 0xfe, 0x22,
0x00, 0x4c, 0x60, 0x64, 0x8c, 0x90, 0xd0, 0xd4,
0xd8, 0x5c, 0x10, 0x09, 0xd8, 0xff, 0xb0, 0xff,
0x00, 0x00, 0xba, 0xff, 0x14, 0x00, 0xba, 0xff,
0x64, 0x00, 0x00, 0x08, 0xfe, 0x06, 0x00, 0x74,
0xff, 0x42, 0xff, 0xce, 0xff, 0x60, 0xff, 0x0a,
0x00, 0xb4, 0x00, 0xa0, 0x00, 0xa0, 0xfe, 0x07,
0x00, 0x0a, 0x00, 0xb0, 0xff, 0x96, 0x4d, 0x00,
0x56, 0x57, 0x18, 0xa6, 0xff, 0x92, 0x70, 0x11,
0x00, 0x12, 0x90, 0x90, 0x76, 0x5a, 0x54, 0x54,
0x4c, 0x46, 0x38, 0x00, 0x10, 0x10, 0x08, 0xfe,
0x05, 0x00, 0x38, 0x29, 0x25, 0x23, 0x22, 0x22,
0x1f, 0x00, 0x00, 0x00, 0xf6, 0xe1, 0xdd, 0xf8,
0xfe, 0x00, 0xfe, 0x15, 0x00, 0x00, 0xd0, 0x02,
0x74, 0x02, 0x08, 0xf8, 0xe5, 0xde, 0x02, 0x04,
0x04, 0xfd, 0x00, 0x00, 0x00, 0x07, 0x50, 0x2d,
0x01, 0x90, 0x90, 0x76, 0x60, 0xb0, 0x07, 0x07,
0x0c, 0x0c, 0x04, 0xfe, 0x05, 0x00, 0x66, 0x66,
0x5a, 0x56, 0xbc, 0x01, 0x06, 0xfc, 0xfc, 0xf1,
0xfe, 0x07, 0x00, 0x24, 0x95, 0x70, 0x64, 0x18,
0x06, 0x2c, 0xff, 0xb5, 0xfe, 0xfe, 0xb5, 0xfe,
0xfe, 0xe2, 0x8c, 0x24, 0x02, 0x2f, 0xff, 0x2f,
0xff, 0xb4, 0x78, 0x02, 0x05, 0x73, 0xff, 0xed,
0xfe, 0xfe, 0x4f, 0xff, 0x36, 0x74, 0x1e, 0x09,
0x4f, 0xff, 0x50, 0xff, 0xfe, 0x16, 0x00, 0x70,
0xac, 0x70, 0x8e, 0xac, 0x40, 0x0e, 0x01, 0x70,
0x7f, 0x8e, 0xac, 0x6c, 0x00, 0x0b, 0xfe, 0x02,
0x00, 0xfe, 0x0a, 0x2c, 0x2a, 0x2a, 0x28, 0x26,
0x1e, 0x1e, 0xfe, 0x02, 0x20, 0x65, 0x20, 0x00,
0x00, 0x05, 0x12, 0x00, 0x11, 0x1e, 0x11, 0x11,
0x41, 0x1e, 0x41, 0x11, 0x31, 0x1e, 0x31, 0x11,
0x70, 0x75, 0x7a, 0x7f, 0x84, 0x89, 0x8e, 0x93,
0x98, 0x30, 0x20, 0x00, 0x02, 0x00, 0xfe, 0x06,
0x3c, 0xbc, 0x32, 0x0c, 0x00, 0x00, 0x2a, 0x12,
0x1e, 0x12, 0x2e, 0x12, 0xcc, 0x12, 0x11, 0x1a,
0x1e, 0x1a, 0x2e, 0x1a, 0x4c, 0x10, 0x1e, 0x10,
0x11, 0x18, 0x1e, 0x42, 0x1e, 0x42, 0x2e, 0x42,
0xcc, 0x42, 0x11, 0x4a, 0x1e, 0x4a, 0x2e, 0x4a,
0x4c, 0x40, 0x1e, 0x40, 0x11, 0x48, 0x1e, 0x32,
0x1e, 0x32, 0x2e, 0x32, 0xcc, 0x32, 0x11, 0x3a,
0x1e, 0x3a, 0x2e, 0x3a, 0x4c, 0x30, 0x1e, 0x30,
0x11, 0x38, 0x1e, 0x27, 0x9a, 0x01, 0x9d, 0xa2,
0x2f, 0x28, 0x00, 0x00, 0x46, 0xde, 0xc4, 0xbf,
0xa6, 0x9d, 0x81, 0x7b, 0x5c, 0x61, 0x40, 0xc7,
0xc0, 0xae, 0xa9, 0x8c, 0x83, 0x6a, 0x62, 0x50,
0x3e, 0xce, 0xc2, 0xae, 0xa3, 0x8c, 0x7b, 0x6a,
0x5a, 0x50, 0x35, 0xd7, 0xc2, 0xb7, 0xa4, 0x95,
0x7e, 0x72, 0x5a, 0x59, 0x37, 0xfe, 0x02, 0xf8,
0x8c, 0x95, 0x90, 0x8f, 0x00, 0xd7, 0xc0, 0xb7,
0xa2, 0x95, 0x7b, 0x72, 0x56, 0x59, 0x32, 0xc7,
0xc3, 0xae, 0xad, 0x8c, 0x85, 0x6a, 0x63, 0x50,
0x3e, 0xce, 0xc3, 0xae, 0xa4, 0x8c, 0x7c, 0x6a,
0x59, 0x50, 0x34, 0xd7, 0xc2, 0xb7, 0xa5, 0x95,
0x7e, 0x72, 0x59, 0x59, 0x36, 0xfc, 0x05, 0x00,
0x02, 0xce, 0xc5, 0xae, 0xa5, 0x95, 0x83, 0x72,
0x5c, 0x59, 0x36, 0xbf, 0xc6, 0xa5, 0xab, 0x8c,
0x8c, 0x6a, 0x67, 0x50, 0x41, 0x64, 0x07, 0x00,
0x02, 0x95, 0x8c, 0x72, 0x65, 0x59, 0x3f, 0xce,
0xc7, 0xae, 0xa8, 0x95, 0x86, 0x72, 0x5f, 0x59,
0x39, 0xfe, 0x02, 0xf8, 0x8b, 0x7c, 0x0b, 0x09,
0xb7, 0xc2, 0x9d, 0xa4, 0x83, 0x85, 0x6a, 0x6b,
0x50, 0x44, 0xb7, 0xc1, 0x64, 0x01, 0x00, 0x06,
0x61, 0x5d, 0x48, 0x3d, 0xae, 0xc4, 0x9d, 0xad,
0x7b, 0x85, 0x61, 0x66, 0x48, 0x46, 0xae, 0xc3,
0x95, 0xa3, 0x72, 0x7c, 0x59, 0x56, 0x38, 0x31,
0x7c, 0x0b, 0x00, 0x0c, 0x96, 0x91, 0x8f, 0x00,
0xb7, 0xc0, 0xa5, 0xab, 0x8c, 0x8a, 0x6a, 0x64,
0x50, 0x3c, 0xb7, 0xc0, 0x9d, 0xa0, 0x83, 0x80,
0x6a, 0x64, 0x50, 0x3d, 0xb7, 0xc5, 0x9d, 0xa5,
0x83, 0x87, 0x6c, 0x08, 0x07, 0xae, 0xc0, 0x9d,
0xa8, 0x83, 0x88, 0x6a, 0x6d, 0x50, 0x46, 0xfc,
0x05, 0x00, 0x16, 0xbf, 0xc0, 0xa5, 0xa2, 0x8c,
0x7f, 0x6a, 0x57, 0x50, 0x2f, 0xb7, 0xc7, 0xa5,
0xb1, 0x8c, 0x8e, 0x72, 0x6d, 0x59, 0x45, 0xbf,
0xc6, 0xa5, 0xa8, 0x8c, 0x87, 0x6a, 0x5f, 0x50,
0x37, 0xbf, 0xc2, 0xa5, 0xa4, 0x8c, 0x83, 0x6a,
0x5c, 0x50, 0x34, 0xbc, 0x05, 0x00, 0x0e, 0x90,
0x00, 0xc7, 0xc2, 0xae, 0xaa, 0x95, 0x82, 0x7b,
0x60, 0x61, 0x3f, 0xb7, 0xc6, 0xa5, 0xb1, 0x8c,
0x8d, 0x72, 0x6b, 0x61, 0x51, 0xbf, 0xc4, 0xa5,
0xa5, 0x8c, 0x82, 0x72, 0x61, 0x59, 0x39, 0x6c,
0x26, 0x03, 0x95, 0x82, 0x7b, 0x61, 0x61, 0x40,
0xfc, 0x05, 0x00, 0x00, 0x7e, 0xd7, 0xc3, 0xb7,
0xa8, 0x9d, 0x80, 0x83, 0x5d, 0x6a, 0x3f, 0xbf,
0xc7, 0xa5, 0xa8, 0x8c, 0x84, 0x72, 0x60, 0x61,
0x46, 0xbf, 0xc2, 0xae, 0xb0, 0x9d, 0x92, 0x83,
0x6f, 0x6a, 0x50, 0xd7, 0xc3, 0xb7, 0xa7, 0x9d,
0x80, 0x83, 0x5e, 0x6a, 0x40, 0xfe, 0x02, 0xf8,
0x8d, 0x96, 0x90, 0x90, 0xfe, 0x05, 0x00, 0x8a,
0xc4, 0x63, 0xb8, 0x3c, 0xa6, 0x29, 0x97, 0x16,
0x81, 0x84, 0xb7, 0x5b, 0xa9, 0x33, 0x94, 0x1e,
0x83, 0x11, 0x70, 0xb8, 0xc2, 0x70, 0xb1, 0x4d,
0xa3, 0x2a, 0x8d, 0x1b, 0x7b, 0xa8, 0xbc, 0x68,
0xab, 0x47, 0x9d, 0x27, 0x87, 0x18, 0x75, 0xae,
0xc6, 0x7d, 0xbb, 0x4d, 0xaa, 0x1c, 0x84, 0x11,
0x72, 0xa3, 0xbb, 0x6e, 0xad, 0x3c, 0x97, 0x24,
0x85, 0x16, 0x71, 0x80, 0xb2, 0x57, 0xa4, 0x30,
0x8e, 0x1c, 0x7c, 0x10, 0x68, 0xbb, 0xbd, 0x75,
0xac, 0x4f, 0x9e, 0x2b, 0x87, 0x1a, 0x76, 0x96,
0xc5, 0x5e, 0xb5, 0x3e, 0xa5, 0x1f, 0x8c, 0x12,
0x7a, 0xc1, 0xc6, 0x42, 0x9f, 0x27, 0x8c, 0x16,
0x77, 0x0f, 0x67, 0x9d, 0xbc, 0x68, 0xad, 0x36,
0x95, 0x20, 0x83, 0x11, 0x6d, 0x9b, 0xb8, 0x67,
0xa8, 0x34, 0x90, 0x1f, 0x7c, 0x10, 0x67, 0x9e,
0xc9, 0x6a, 0xbb, 0x37, 0xa4, 0x20, 0x90, 0x11,
0x7b, 0xc6, 0xc8, 0x47, 0xa4, 0x2a, 0x90, 0x18,
0x7b, 0x10, 0x6c, 0xae, 0xc4, 0x5d, 0xad, 0x37,
0x9a, 0x1f, 0x85, 0x13, 0x75, 0x70, 0xad, 0x42,
0x99, 0x25, 0x84, 0x17, 0x74, 0x0b, 0x56, 0x87,
0xc8, 0x57, 0xb8, 0x2b, 0x9e, 0x19, 0x8a, 0x0d,
0x74, 0xa7, 0xc8, 0x6e, 0xb9, 0x36, 0xa0, 0x1f,
0x8b, 0x11, 0x75, 0x94, 0xbe, 0x4b, 0xa5, 0x2a,
0x92, 0x18, 0x7c, 0x0f, 0x6b, 0xaf, 0xc0, 0x58,
0xa8, 0x34, 0x94, 0x1d, 0x7d, 0x12, 0x6d, 0x82,
0xc0, 0x52, 0xb0, 0x25, 0x94, 0x14, 0x7f, 0x0c,
0x68, 0x84, 0xbf, 0x3e, 0xa4, 0x22, 0x8e, 0x10,
0x76, 0x0b, 0x65, 0x88, 0xb6, 0x42, 0x9b, 0x26,
0x87, 0x14, 0x70, 0x0c, 0x5f, 0xc5, 0xc2, 0x3e,
0x97, 0x23, 0x83, 0x13, 0x6c, 0x0c, 0x5c, 0xb1,
0xc9, 0x76, 0xbc, 0x4a, 0xaa, 0x20, 0x8d, 0x12,
0x78, 0x93, 0xbf, 0x46, 0xa3, 0x26, 0x8d, 0x14,
0x74, 0x0c, 0x62, 0xc8, 0xc4, 0x3b, 0x97, 0x21,
0x82, 0x11, 0x6a, 0x0a, 0x59, 0xa3, 0xb9, 0x68,
0xa9, 0x30, 0x8d, 0x1a, 0x78, 0x0f, 0x61, 0xa0,
0xc9, 0x73, 0xbe, 0x50, 0xb1, 0x30, 0x9f, 0x14,
0x80, 0x83, 0xb7, 0x3c, 0x9a, 0x20, 0x84, 0x0e,
0x6a, 0x0a, 0x57, 0xac, 0xc2, 0x68, 0xb0, 0x2e,
0x92, 0x19, 0x7c, 0x0d, 0x63, 0x93, 0xbe, 0x62,
0xb0, 0x3c, 0x9e, 0x1a, 0x80, 0x0e, 0x6b, 0xbb,
0x02, 0xa0, 0x02, 0xa0, 0x02, 0x6f, 0x00, 0x75,
0x00, 0x75, 0x00, 0x00, 0x00, 0xad, 0x02, 0xb3,
0x02, 0x6f, 0x00, 0x87, 0x00, 0x85, 0xfe, 0x03,
0x00, 0xc2, 0x02, 0x82, 0x4d, 0x92, 0x6e, 0x4d,
0xb1, 0xa8, 0x84, 0x01, 0x00, 0x07, 0x7e, 0x00,
0xa8, 0x02, 0xa4, 0x02, 0xa4, 0x02, 0xa2, 0x00,
0xa6, 0x00, 0xa6, 0x00, 0x00, 0x00, 0xb4, 0x02,
0xb4, 0x02, 0x92, 0x00, 0x96, 0x00, 0x96, 0x46,
0x04, 0xb0, 0x02, 0x64, 0x02, 0x0a, 0x8c, 0x00,
0x90, 0x02, 0x98, 0x02, 0x98, 0x02, 0x0e, 0x01,
0x11, 0x01, 0x11, 0x50, 0xc3, 0x08, 0x88, 0x02,
0x88, 0x02, 0x19, 0x01, 0x02, 0x01, 0x02, 0x01,
0xf3, 0x2d, 0x00, 0x00
};
uint8_t *rb_hardconfig;
long rb_hardconfig_len;
static inline uint32_t get_u32(const void *buf);
int routerboot_find_tag(uint8_t *buf, unsigned int buflen, uint16_t tag_id,
uint8_t **tag_data, uint16_t *tag_len);
static inline int
rb_find_hard_cfg_tag(uint16_t tag_id, uint8_t **tag_data, uint16_t *tag_len);
const uint8_t * rb_get_board_product_code(void);
uint32_t rb_get_board_mac(void);
const uint8_t * rb_get_board_serial(void);
const uint8_t * rb_get_board_identifier(void);
const uint8_t * rb_get_board_name(void);
const uint8_t * rb_get_factory_booter_version(void);
uint32_t rb_get_flash_info(void);
uint32_t rb_get_hw_options(void);
int routerboot_find_magic(uint8_t *buf, unsigned int buflen, uint32_t *offset, bool hard);
uint8_t * __rb_get_wlan_data(void);
/*
* Magic numbers
*/
#define RB_ART_SIZE 0x10000
#define RB_MAGIC_HARD 0x64726148 /* "Hard" */
#define RB_MAGIC_SOFT 0x74666F53 /* "Soft" */
#define RB_MAGIC_ERD 0x00455244 /* extended radio data */
#define RB_MAGIC_LZOR 0x524F5A4C
#define RB_ID_TERMINATOR 0
/*
* ID values for Hardware settings
*/
#define RB_ID_HARD_01 1
#define RB_ID_HARD_02 2
#define RB_ID_FLASH_INFO 3
#define RB_ID_MAC_ADDRESS_PACK 4
#define RB_ID_BOARD_PRODUCT_CODE 5
#define RB_ID_BIOS_VERSION 6
#define RB_ID_HARD_07 7
#define RB_ID_SDRAM_TIMINGS 8
#define RB_ID_DEVICE_TIMINGS 9
#define RB_ID_SOFTWARE_ID 10
#define RB_ID_SERIAL_NUMBER 11
#define RB_ID_HARD_12 12
#define RB_ID_MEMORY_SIZE 13
#define RB_ID_MAC_ADDRESS_COUNT 14
#define RB_ID_HW_OPTIONS 21
#define RB_ID_WLAN_DATA 22
#define RB_ID_BOARD_IDENTIFIER 23
#define RB_ID_BOARD_NAME 33
#endif /* _RBEXTRACT_H */

View File

@ -121,7 +121,7 @@ case "$FIRMWARE" in
;;
rb-952ui-5ac2nd|\
rb-wapg-5hact2hnd)
ath10kcal_from_file "/sys/firmware/routerboot/ext_wlan_data" 0x5000 0x844
ath10kcal_from_file "/sys/firmware/mikrotik/hard_config/wlan_data" 0x5000 0x844
;;
re355|\
re450|\
@ -158,7 +158,7 @@ case "$FIRMWARE" in
rb-921gs-5hpacd-r2|\
rb-922uags-5hpacd|\
rb-962uigs-5hact2hnt)
ath10kcal_from_file "/sys/firmware/routerboot/ext_wlan_data" 0x5000 0x844
ath10kcal_from_file "/sys/firmware/mikrotik/hard_config/wlan_data" 0x5000 0x844
;;
wlr8100)
ath10kcal_extract "art" 0x5000 0x844

View File

@ -26,6 +26,8 @@ CONFIG_HW_HAS_PCI=y
CONFIG_LEDS_RB750=y
CONFIG_LZO_DECOMPRESS=y
# CONFIG_MARVELL_PHY is not set
CONFIG_MIKROTIK=y
CONFIG_MIKROTIK_RB_SYSFS=y
# CONFIG_MTD_CFI is not set
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CMDLINE_PARTS is not set

View File

@ -11,6 +11,7 @@
compatible = "tplink,tl-mr3040-v2", "qca,ar9331";
aliases {
serial0 = &uart;
led-boot = &led_lan;
led-failsafe = &led_lan;
label-mac-device = &eth0;

View File

@ -11,7 +11,6 @@
model = "MikroTik RouterBOARD wAP G-5HacT2HnD";
aliases {
label-mac-device = &eth1;
mdio-gpio1 = &mdio2;
serial0 = &uart;
};
@ -53,8 +52,6 @@
&eth1 {
status = "okay";
mtd-mac-address = <&hard_config 0x10>;
pll-data = <0x03000101 0x80000101 0x80001313>;
phy-handle = <&phy0>;
@ -84,37 +81,33 @@
label = "RouterBoot";
reg = <0x0 0x20000>;
read-only;
compatible = "fixed-partitions";
compatible = "mikrotik,routerboot-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "bootloader1";
reg = <0x0 0xe000>;
reg = <0x0 0x0>;
read-only;
};
hard_config: partition@e000 {
label = "hard_config";
reg = <0xe000 0x1000>;
hard_config: hard_config {
read-only;
};
partition@f000 {
label = "bios";
reg = <0xf000 0x1000>;
bios {
size = <0x1000>;
read-only;
};
partition@10000 {
label = "bootloader2";
reg = <0x10000 0xf000>;
reg = <0x10000 0x0>;
read-only;
};
partition@1f000 {
soft_config {
label = "soft_config";
reg = <0x1f000 0x1000>;
};
};

View File

@ -11,7 +11,6 @@
model = "MikroTik RouterBOARD 922UAGS-5HPacD";
aliases {
label-mac-device = &eth0;
led-boot = &led_user;
led-failsafe = &led_user;
led-upgrade = &led_user;
@ -80,7 +79,6 @@
&eth0 {
status = "okay";
mtd-mac-address = <&hard_config 0x10>;
phy-handle = <&phy4>;
pll-data = <0x8f000000 0xa0000101 0xa0001313>;
@ -99,32 +97,25 @@
spi-max-frequency = <25000000>;
partitions {
compatible = "fixed-partitions";
compatible = "mikrotik,routerboot-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "routerboot";
reg = <0x0000000 0x000c000>;
reg = <0x0 0x0>;
read-only;
};
hard_config: partition@c000 {
label = "hard_config";
reg = <0x000c000 0x0001000>;
hard_config: hard_config {
read-only;
};
partition@d000 {
label = "bios";
reg = <0x000d000 0x0001000>;
bios {
read-only;
};
partition@e000 {
label = "soft_config";
reg = <0x000e000 0x0001000>;
read-only;
soft_config {
};
};
};

View File

@ -1,6 +1,6 @@
define Device/mikrotik
DEVICE_VENDOR := MikroTik
DEVICE_PACKAGES := rbextract rbcfg
DEVICE_PACKAGES := rbcfg
LOADER_TYPE := elf
KERNEL := kernel-bin | append-dtb | lzma | loader-kernel
KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | loader-kernel

View File

@ -21,8 +21,17 @@ ath79_setup_interfaces()
ath79_setup_macs()
{
local board="$1"
local lan_mac=""
local wan_mac=""
local label_mac=""
local mac_base="$(cat /sys/firmware/mikrotik/hard_config/mac_base)"
case "$board" in
*)
label_mac="$mac_base"
wan_mac="$mac_base"
lan_mac=$(macaddr_add $mac_base 1)
;;
esac
[ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac

View File

@ -3,7 +3,9 @@
[ -e /lib/firmware/$FIRMWARE ] && exit 0
. /lib/functions/caldata.sh
. /lib/functions/mikrotik-caldata.sh
wlan_data="/sys/firmware/mikrotik/hard_config/wlan_data"
mac_base="$(cat /sys/firmware/mikrotik/hard_config/mac_base)"
board=$(board_name)
@ -11,8 +13,10 @@ case "$FIRMWARE" in
"ath9k-eeprom-ahb-18100000.wmac.bin")
case $board in
mikrotik,routerboard-wap-g-5hact2hnd)
mikrotik_caldata_extract "hard_config" 0x1000 0x440
ath9k_patch_mac $(macaddr_add $(mtd_get_mac_binary hard_config 0x10) +2)
caldata_from_file $wlan_data 0x1000 0x440 /tmp/$FIRMWARE
ath9k_patch_mac $(macaddr_add "$mac_base" +2) /tmp/$FIRMWARE
caldata_sysfsload_from_file /tmp/$FIRMWARE 0x0 0x440
rm -f /tmp/$FIRMWARE
;;
*)
caldata_die "board $board is not supported yet"

View File

@ -3,7 +3,8 @@
[ -e /lib/firmware/$FIRMWARE ] && exit 0
. /lib/functions/caldata.sh
. /lib/functions/mikrotik-caldata.sh
wlan_data="/sys/firmware/mikrotik/hard_config/wlan_data"
board=$(board_name)
@ -11,14 +12,14 @@ case "$FIRMWARE" in
"ath10k/cal-pci-0000:00:00.0.bin")
case $board in
mikrotik,routerboard-wap-g-5hact2hnd)
mikrotik_caldata_extract "hard_config" 0x5000 0x844
caldata_sysfsload_from_file $wlan_data 0x5000 0x844
;;
esac
;;
"ath10k/cal-pci-0000:01:00.0.bin")
case $board in
mikrotik,routerboard-922uags-5hpacd)
mikrotik_caldata_extract "hard_config" 0x5000 0x844
caldata_sysfsload_from_file $wlan_data 0x5000 0x844
;;
esac
;;

View File

@ -1,26 +0,0 @@
# Copyright (C) 2019 Robert Marko <robimarko@gmail.com>
# Copyright (C) 2019 Roger Pueyo Centelles <roger.pueyo@guifi.net>
#
# Helper function to extract MAC addresses and calibration data for MikroTik
#
mikrotik_caldata_extract() {
local part=$1
local offset=$(($2))
local count=$(($3))
local mtd
local erdfile="/tmp/erd.bin"
local fwfile="/lib/firmware/${FIRMWARE}"
[ -e $fwfile ] && exit 0
mtd=$(find_mtd_chardev $part)
[ -n "$mtd" ] || caldata_die "no mtd device found for partition $part"
rbextract -e $mtd $erdfile
dd if=$erdfile of=$fwfile iflag=skip_bytes bs=$count skip=$offset count=1 2>/dev/null || \
caldata_die "failed to extract calibration data from $mtd"
rm -f $erdfile
}

View File

@ -6,11 +6,14 @@ CONFIG_GPIO_WATCHDOG=y
CONFIG_GPIO_WATCHDOG_ARCH_INITCALL=y
CONFIG_LEDS_RESET=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_MIKROTIK=y
CONFIG_MIKROTIK_RB_SYSFS=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_AR934X=y
CONFIG_MTD_NAND_CORE=y
CONFIG_MTD_NAND_ECC=y
CONFIG_MTD_RAW_NAND=y
CONFIG_MTD_ROUTERBOOT_PARTS=y
CONFIG_MTD_SPI_NAND=y
CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
CONFIG_MTD_SPLIT_MINOR_FW=y

View File

@ -2651,6 +2651,7 @@ CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
# CONFIG_MIGRATION is not set
CONFIG_MII=y
# CONFIG_MIKROTIK_RB532 is not set
# CONFIG_MIKROTIK is not set
# CONFIG_MINIX_FS is not set
# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set
# CONFIG_MINIX_SUBPARTITION is not set
@ -2877,6 +2878,7 @@ CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
# CONFIG_MTD_ROM is not set
CONFIG_MTD_ROOTFS_ROOT_DEV=y
# CONFIG_MTD_ROUTERBOOT_PARTS is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_SM_COMMON is not set
# CONFIG_MTD_SPINAND_MT29F is not set

View File

@ -2791,6 +2791,7 @@ CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
# CONFIG_MIGRATION is not set
CONFIG_MII=y
# CONFIG_MIKROTIK_RB532 is not set
# CONFIG_MIKROTIK is not set
# CONFIG_MINIX_FS is not set
# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set
# CONFIG_MINIX_SUBPARTITION is not set
@ -3024,6 +3025,7 @@ CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
# CONFIG_MTD_ROM is not set
CONFIG_MTD_ROOTFS_ROOT_DEV=y
# CONFIG_MTD_ROUTERBOOT_PARTS is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_SM_COMMON is not set
# CONFIG_MTD_SPINAND_MT29F is not set

View File

@ -2971,6 +2971,7 @@ CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
# CONFIG_MIGRATION is not set
CONFIG_MII=y
# CONFIG_MIKROTIK_RB532 is not set
# CONFIG_MIKROTIK is not set
# CONFIG_MINIX_FS is not set
# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set
# CONFIG_MINIX_SUBPARTITION is not set
@ -3222,6 +3223,7 @@ CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
# CONFIG_MTD_ROM is not set
CONFIG_MTD_ROOTFS_ROOT_DEV=y
# CONFIG_MTD_SBC_GXX is not set
# CONFIG_MTD_ROUTERBOOT_PARTS is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_SM_COMMON is not set
# CONFIG_MTD_SPINAND_MT29F is not set
@ -4105,6 +4107,7 @@ CONFIG_PROC_SYSCTL=y
# CONFIG_PROFILING is not set
# CONFIG_PROVE_LOCKING is not set
# CONFIG_PROVE_RCU is not set
# CONFIG_PROVE_RCU_LIST is not set
# CONFIG_PROVE_RCU_REPEATEDLY is not set
# CONFIG_PSAMPLE is not set
# CONFIG_PSB6970_PHY is not set

View File

@ -0,0 +1,365 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Parser for MikroTik RouterBoot partitions.
*
* Copyright (C) 2020 Thibaut VARÈNE <hacks+kernel@slashdirt.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* This parser builds from the "fixed-partitions" one (see ofpart.c), but it can
* handle dynamic partitions as found on routerboot devices.
*
* DTS nodes are defined as follows:
* For fixed partitions:
* node-name@unit-address {
* reg = <prop-encoded-array>;
* label = <string>;
* read-only;
* lock;
* };
*
* reg property is mandatory; other properties are optional.
* reg format is <address length>. length can be 0 if the next partition is
* another fixed partition or a "well-known" partition as defined below: in that
* case the partition will extend up to the next one.
*
* For dynamic partitions:
* node-name {
* size = <prop-encoded-array>;
* label = <string>;
* read-only;
* lock;
* };
*
* size property is normally mandatory. It can only be omitted (or set to 0) if:
* - the partition is a "well-known" one (as defined below), in which case
* the partition size will be automatically adjusted; or
* - the next partition is a fixed one or a "well-known" one, in which case
* the current partition will extend up to the next one.
* Other properties are optional.
* size format is <length>.
* By default dynamic partitions are appended after the preceding one, except
* for "well-known" ones which are automatically located on flash.
*
* Well-known partitions (matched via label or node-name):
* - "hard_config"
* - "soft_config"
* - "dtb_config"
*
* Note: this parser will happily register 0-sized partitions if misused.
*
* This parser requires the DTS to list partitions in ascending order as
* expected on the MTD device.
*
* Since only the "hard_config" and "soft_config" partitions are used in OpenWRT,
* a minimal working DTS could define only these two partitions dynamically (in
* the right order, usually hard_config then soft_config).
*
* Note: some mips RB devices encode the hard_config offset and length in two
* consecutive u32 located at offset 0x14 (for ramips) or 0x24 (for ath79) on
* the SPI NOR flash. Unfortunately this seems inconsistent across machines and
* does not apply to e.g. ipq-based ones, so we ignore that information.
*
* Note: To find well-known partitions, this parser will go through the entire
* top mtd partition parsed, _before_ the DTS nodes are processed. This works
* well in the current state of affairs, and is a simpler implementation than
* searching for known partitions in the "holes" left between fixed-partition,
* _after_ processing DTS nodes.
*/
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/libfdt_env.h>
#include <linux/string.h>
#define RB_MAGIC_HARD (('H') | ('a' << 8) | ('r' << 16) | ('d' << 24))
#define RB_MAGIC_SOFT (('S') | ('o' << 8) | ('f' << 16) | ('t' << 24))
#define RB_BLOCK_SIZE 0x1000
struct routerboot_dynpart {
const char * const name;
const u32 magic;
int (* const size_fixup)(struct mtd_info *, struct routerboot_dynpart *);
size_t offset;
size_t size;
bool found;
};
static int routerboot_dtbsfixup(struct mtd_info *, struct routerboot_dynpart *);
static struct routerboot_dynpart rb_dynparts[] = {
{
.name = "hard_config",
.magic = RB_MAGIC_HARD, // stored in CPU-endianness on flash
.size_fixup = NULL,
.offset = 0x0,
.size = RB_BLOCK_SIZE,
.found = false,
}, {
.name = "soft_config",
.magic = RB_MAGIC_SOFT, // stored in CPU-endianness on flash
.size_fixup = NULL,
.offset = 0x0,
.size = RB_BLOCK_SIZE,
.found = false,
}, {
.name = "dtb_config",
.magic = fdt32_to_cpu(OF_DT_HEADER), // stored BE on flash
.size_fixup = routerboot_dtbsfixup,
.offset = 0x0,
.size = 0x0,
.found = false,
}
};
static int routerboot_dtbsfixup(struct mtd_info *master, struct routerboot_dynpart *rbdpart)
{
int err;
size_t bytes_read, psize;
struct {
fdt32_t magic;
fdt32_t totalsize;
fdt32_t off_dt_struct;
fdt32_t off_dt_strings;
fdt32_t off_mem_rsvmap;
fdt32_t version;
fdt32_t last_comp_version;
fdt32_t boot_cpuid_phys;
fdt32_t size_dt_strings;
fdt32_t size_dt_struct;
} fdt_header;
err = mtd_read(master, rbdpart->offset, sizeof(fdt_header),
&bytes_read, (u8 *)&fdt_header);
if (err)
return err;
if (bytes_read != sizeof(fdt_header))
return -EIO;
psize = fdt32_to_cpu(fdt_header.totalsize);
if (!psize)
return -EINVAL;
rbdpart->size = psize;
return 0;
}
static void routerboot_find_dynparts(struct mtd_info *master)
{
size_t bytes_read, offset;
bool allfound;
int err, i;
u32 buf;
/*
* Dynamic RouterBoot partitions offsets are aligned to RB_BLOCK_SIZE:
* read the whole partition at RB_BLOCK_SIZE intervals to find sigs.
* Skip partition content when possible.
*/
offset = 0;
while (offset < master->size) {
err = mtd_read(master, offset, sizeof(buf), &bytes_read, (u8 *)&buf);
if (err) {
pr_err("%s: mtd_read error while parsing (offset: 0x%X): %d\n",
master->name, offset, err);
continue;
}
allfound = true;
for (i = 0; i < ARRAY_SIZE(rb_dynparts); i++) {
if (rb_dynparts[i].found)
continue;
allfound = false;
if (rb_dynparts[i].magic == buf) {
rb_dynparts[i].offset = offset;
if (rb_dynparts[i].size_fixup) {
err = rb_dynparts[i].size_fixup(master, &rb_dynparts[i]);
if (err) {
pr_err("%s: size fixup error while parsing \"%s\": %d\n",
master->name, rb_dynparts[i].name, err);
continue;
}
}
rb_dynparts[i].found = true;
/*
* move offset to skip the whole partition on
* next iteration if size > RB_BLOCK_SIZE.
*/
if (rb_dynparts[i].size > RB_BLOCK_SIZE)
offset += ALIGN_DOWN((rb_dynparts[i].size - RB_BLOCK_SIZE), RB_BLOCK_SIZE);
break;
}
}
offset += RB_BLOCK_SIZE;
if (allfound)
break;
}
}
static int routerboot_partitions_parse(struct mtd_info *master,
const struct mtd_partition **pparts,
struct mtd_part_parser_data *data)
{
struct device_node *rbpart_node, *pp;
struct mtd_partition *parts;
const char *partname;
size_t master_ofs;
int np;
/* Pull of_node from the master device node */
rbpart_node = mtd_get_of_node(master);
if (!rbpart_node)
return 0;
/* First count the subnodes */
np = 0;
for_each_child_of_node(rbpart_node, pp)
np++;
if (!np)
return 0;
parts = kcalloc(np, sizeof(*parts), GFP_KERNEL);
if (!parts)
return -ENOMEM;
/* Preemptively look for known parts in flash */
routerboot_find_dynparts(master);
np = 0;
master_ofs = 0;
for_each_child_of_node(rbpart_node, pp) {
const __be32 *reg, *sz;
size_t offset, size;
int i, len, a_cells, s_cells;
partname = of_get_property(pp, "label", &len);
/* Allow deprecated use of "name" instead of "label" */
if (!partname)
partname = of_get_property(pp, "name", &len);
/* Fallback to node name per spec if all else fails: partname is always set */
if (!partname)
partname = pp->name;
parts[np].name = partname;
reg = of_get_property(pp, "reg", &len);
if (reg) {
/* Fixed partition */
a_cells = of_n_addr_cells(pp);
s_cells = of_n_size_cells(pp);
if ((len / 4) != (a_cells + s_cells)) {
pr_debug("%s: routerboot partition %pOF (%pOF) error parsing reg property.\n",
master->name, pp, rbpart_node);
goto rbpart_fail;
}
offset = of_read_number(reg, a_cells);
size = of_read_number(reg + a_cells, s_cells);
} else {
/* Dynamic partition */
/* Default: part starts at current offset, 0 size */
offset = master_ofs;
size = 0;
/* Check if well-known partition */
for (i = 0; i < ARRAY_SIZE(rb_dynparts); i++) {
if (!strcmp(partname, rb_dynparts[i].name) && rb_dynparts[i].found) {
offset = rb_dynparts[i].offset;
size = rb_dynparts[i].size;
break;
}
}
/* Standalone 'size' property? Override size */
sz = of_get_property(pp, "size", &len);
if (sz) {
s_cells = of_n_size_cells(pp);
if ((len / 4) != s_cells) {
pr_debug("%s: routerboot partition %pOF (%pOF) error parsing size property.\n",
master->name, pp, rbpart_node);
goto rbpart_fail;
}
size = of_read_number(sz, s_cells);
}
}
if (np > 0) {
/* Minor sanity check for overlaps */
if (offset < (parts[np-1].offset + parts[np-1].size)) {
pr_err("%s: routerboot partition %pOF (%pOF) \"%s\" overlaps with previous partition \"%s\".\n",
master->name, pp, rbpart_node,
partname, parts[np-1].name);
goto rbpart_fail;
}
/* Fixup end of previous partition if necessary */
if (!parts[np-1].size)
parts[np-1].size = (offset - parts[np-1].offset);
}
if ((offset + size) > master->size) {
pr_err("%s: routerboot partition %pOF (%pOF) \"%s\" extends past end of segment.\n",
master->name, pp, rbpart_node, partname);
goto rbpart_fail;
}
parts[np].offset = offset;
parts[np].size = size;
parts[np].of_node = pp;
if (of_get_property(pp, "read-only", &len))
parts[np].mask_flags |= MTD_WRITEABLE;
if (of_get_property(pp, "lock", &len))
parts[np].mask_flags |= MTD_POWERUP_LOCK;
/* Keep master offset aligned to RB_BLOCK_SIZE */
master_ofs = ALIGN(offset + size, RB_BLOCK_SIZE);
np++;
}
*pparts = parts;
return np;
rbpart_fail:
pr_err("%s: error parsing routerboot partition %pOF (%pOF)\n",
master->name, pp, rbpart_node);
of_node_put(pp);
kfree(parts);
return -EINVAL;
}
static const struct of_device_id parse_routerbootpart_match_table[] = {
{ .compatible = "mikrotik,routerboot-partitions" },
{},
};
MODULE_DEVICE_TABLE(of, parse_routerbootpart_match_table);
static struct mtd_part_parser routerbootpart_parser = {
.parse_fn = routerboot_partitions_parse,
.name = "routerbootpart",
.of_match_table = parse_routerbootpart_match_table,
};
module_mtd_part_parser(routerbootpart_parser);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("MTD partitioning for RouterBoot");
MODULE_AUTHOR("Thibaut VARENE");

View File

@ -0,0 +1,18 @@
menuconfig MIKROTIK
bool "Platform support for MikroTik RouterBoard virtual devices"
default n
depends on MTD
select LZO_DECOMPRESS
help
Say Y here to get to see options for the MikroTik RouterBoard platform.
This option alone does not add any kernel code.
if MIKROTIK
config MIKROTIK_RB_SYSFS
tristate "RouterBoot sysfs support"
help
This driver exposes RouterBoot configuration in sysfs.
endif # MIKROTIK

View File

@ -0,0 +1,4 @@
#
# Makefile for MikroTik RouterBoard platform specific drivers
#
obj-$(CONFIG_MIKROTIK_RB_SYSFS) += routerboot.o rb_hardconfig.o

View File

@ -0,0 +1,741 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Driver for MikroTik RouterBoot hard config.
*
* Copyright (C) 2020 Thibaut VARÈNE <hacks+kernel@slashdirt.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* This driver exposes the data encoded in the "hard_config" flash segment of
* MikroTik RouterBOARDs devices. It presents the data in a sysfs folder
* named "hard_config". The WLAN calibration data is available on demand via
* the 'wlan_data' sysfs file in that folder.
*
* This driver permanently allocates a chunk of RAM as large as the hard_config
* MTD partition, although it is technically possible to operate entirely from
* the MTD device without using a local buffer (except when requesting WLAN
* calibration data), at the cost of a performance penalty.
*
* Some constant defines extracted from routerboot.{c,h} by Gabor Juhos
* <juhosg@openwrt.org>
*/
#include <linux/types.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/kobject.h>
#include <linux/bitops.h>
#include <linux/string.h>
#include <linux/mtd/mtd.h>
#include <linux/sysfs.h>
#include <linux/lzo.h>
#include "routerboot.h"
#define RB_HARDCONFIG_VER "0.02"
#define RB_HC_PR_PFX "[rb_hardconfig] "
/* ID values for hardware settings */
#define RB_ID_FLASH_INFO 0x03
#define RB_ID_MAC_ADDRESS_PACK 0x04
#define RB_ID_BOARD_PRODUCT_CODE 0x05
#define RB_ID_BIOS_VERSION 0x06
#define RB_ID_SDRAM_TIMINGS 0x08
#define RB_ID_DEVICE_TIMINGS 0x09
#define RB_ID_SOFTWARE_ID 0x0A
#define RB_ID_SERIAL_NUMBER 0x0B
#define RB_ID_MEMORY_SIZE 0x0D
#define RB_ID_MAC_ADDRESS_COUNT 0x0E
#define RB_ID_HW_OPTIONS 0x15
#define RB_ID_WLAN_DATA 0x16
#define RB_ID_BOARD_IDENTIFIER 0x17
#define RB_ID_PRODUCT_NAME 0x21
#define RB_ID_DEFCONF 0x26
/* Bit definitions for hardware options */
#define RB_HW_OPT_NO_UART BIT(0)
#define RB_HW_OPT_HAS_VOLTAGE BIT(1)
#define RB_HW_OPT_HAS_USB BIT(2)
#define RB_HW_OPT_HAS_ATTINY BIT(3)
#define RB_HW_OPT_NO_NAND BIT(14)
#define RB_HW_OPT_HAS_LCD BIT(15)
#define RB_HW_OPT_HAS_POE_OUT BIT(16)
#define RB_HW_OPT_HAS_uSD BIT(17)
#define RB_HW_OPT_HAS_SIM BIT(18)
#define RB_HW_OPT_HAS_SFP BIT(20)
#define RB_HW_OPT_HAS_WIFI BIT(21)
#define RB_HW_OPT_HAS_TS_FOR_ADC BIT(22)
#define RB_HW_OPT_HAS_PLC BIT(29)
static struct kobject *hc_kobj;
static u8 *hc_buf; // ro buffer after init(): no locking required
static size_t hc_buflen;
/*
* For LZOR style WLAN data unpacking.
* This binary blob is prepended to the data encoded on some devices as
* RB_ID_WLAN_DATA, the result is then first decompressed with LZO, and then
* finally RLE-decoded.
* This binary blob has been extracted from RouterOS by
* https://forum.openwrt.org/u/ius
*/
static const u8 hc_lzor_prefix[] = {
0x00, 0x05, 0x4c, 0x4c, 0x44, 0x00, 0x34, 0xfe,
0xfe, 0x34, 0x11, 0x3c, 0x1e, 0x3c, 0x2e, 0x3c,
0x4c, 0x34, 0x00, 0x52, 0x62, 0x92, 0xa2, 0xb2,
0xc3, 0x2a, 0x14, 0x00, 0x00, 0x05, 0xfe, 0x6a,
0x3c, 0x16, 0x32, 0x16, 0x11, 0x1e, 0x12, 0x46,
0x32, 0x46, 0x11, 0x4e, 0x12, 0x36, 0x32, 0x36,
0x11, 0x3e, 0x12, 0x5a, 0x9a, 0x64, 0x00, 0x04,
0xfe, 0x10, 0x3c, 0x00, 0x01, 0x00, 0x00, 0x28,
0x0c, 0x00, 0x0f, 0xfe, 0x14, 0x00, 0x24, 0x24,
0x23, 0x24, 0x24, 0x23, 0x25, 0x22, 0x21, 0x21,
0x23, 0x22, 0x21, 0x22, 0x21, 0x2d, 0x38, 0x00,
0x0c, 0x25, 0x25, 0x24, 0x25, 0x25, 0x24, 0x23,
0x22, 0x21, 0x20, 0x23, 0x21, 0x21, 0x22, 0x21,
0x2d, 0x38, 0x00, 0x28, 0xb0, 0x00, 0x00, 0x22,
0x00, 0x00, 0xc0, 0xfe, 0x03, 0x00, 0xc0, 0x00,
0x62, 0xff, 0x62, 0xff, 0xfe, 0x06, 0x00, 0xbb,
0xff, 0xba, 0xff, 0xfe, 0x08, 0x00, 0x9e, 0xff,
0xfe, 0x0a, 0x00, 0x53, 0xff, 0xfe, 0x02, 0x00,
0x20, 0xff, 0xb1, 0xfe, 0xfe, 0xb2, 0xfe, 0xfe,
0xed, 0xfe, 0xfe, 0xfe, 0x04, 0x00, 0x3a, 0xff,
0x3a, 0xff, 0xde, 0xfd, 0x5f, 0x04, 0x33, 0xff,
0x4c, 0x74, 0x03, 0x05, 0x05, 0xff, 0x6d, 0xfe,
0xfe, 0x6d, 0xfe, 0xfe, 0xaf, 0x08, 0x63, 0xff,
0x64, 0x6f, 0x08, 0xac, 0xff, 0xbf, 0x6d, 0x08,
0x7a, 0x6d, 0x08, 0x96, 0x74, 0x04, 0x00, 0x08,
0x79, 0xff, 0xda, 0xfe, 0xfe, 0xdb, 0xfe, 0xfe,
0x56, 0xff, 0xfe, 0x04, 0x00, 0x5e, 0xff, 0x5e,
0xff, 0x6c, 0xfe, 0xfe, 0xfe, 0x06, 0x00, 0x41,
0xff, 0x7f, 0x74, 0x03, 0x00, 0x11, 0x44, 0xff,
0xa9, 0xfe, 0xfe, 0xa9, 0xfe, 0xfe, 0xa5, 0x8f,
0x01, 0x00, 0x08, 0x01, 0x01, 0x02, 0x04, 0x08,
0x02, 0x04, 0x08, 0x08, 0x01, 0x01, 0xfe, 0x22,
0x00, 0x4c, 0x60, 0x64, 0x8c, 0x90, 0xd0, 0xd4,
0xd8, 0x5c, 0x10, 0x09, 0xd8, 0xff, 0xb0, 0xff,
0x00, 0x00, 0xba, 0xff, 0x14, 0x00, 0xba, 0xff,
0x64, 0x00, 0x00, 0x08, 0xfe, 0x06, 0x00, 0x74,
0xff, 0x42, 0xff, 0xce, 0xff, 0x60, 0xff, 0x0a,
0x00, 0xb4, 0x00, 0xa0, 0x00, 0xa0, 0xfe, 0x07,
0x00, 0x0a, 0x00, 0xb0, 0xff, 0x96, 0x4d, 0x00,
0x56, 0x57, 0x18, 0xa6, 0xff, 0x92, 0x70, 0x11,
0x00, 0x12, 0x90, 0x90, 0x76, 0x5a, 0x54, 0x54,
0x4c, 0x46, 0x38, 0x00, 0x10, 0x10, 0x08, 0xfe,
0x05, 0x00, 0x38, 0x29, 0x25, 0x23, 0x22, 0x22,
0x1f, 0x00, 0x00, 0x00, 0xf6, 0xe1, 0xdd, 0xf8,
0xfe, 0x00, 0xfe, 0x15, 0x00, 0x00, 0xd0, 0x02,
0x74, 0x02, 0x08, 0xf8, 0xe5, 0xde, 0x02, 0x04,
0x04, 0xfd, 0x00, 0x00, 0x00, 0x07, 0x50, 0x2d,
0x01, 0x90, 0x90, 0x76, 0x60, 0xb0, 0x07, 0x07,
0x0c, 0x0c, 0x04, 0xfe, 0x05, 0x00, 0x66, 0x66,
0x5a, 0x56, 0xbc, 0x01, 0x06, 0xfc, 0xfc, 0xf1,
0xfe, 0x07, 0x00, 0x24, 0x95, 0x70, 0x64, 0x18,
0x06, 0x2c, 0xff, 0xb5, 0xfe, 0xfe, 0xb5, 0xfe,
0xfe, 0xe2, 0x8c, 0x24, 0x02, 0x2f, 0xff, 0x2f,
0xff, 0xb4, 0x78, 0x02, 0x05, 0x73, 0xff, 0xed,
0xfe, 0xfe, 0x4f, 0xff, 0x36, 0x74, 0x1e, 0x09,
0x4f, 0xff, 0x50, 0xff, 0xfe, 0x16, 0x00, 0x70,
0xac, 0x70, 0x8e, 0xac, 0x40, 0x0e, 0x01, 0x70,
0x7f, 0x8e, 0xac, 0x6c, 0x00, 0x0b, 0xfe, 0x02,
0x00, 0xfe, 0x0a, 0x2c, 0x2a, 0x2a, 0x28, 0x26,
0x1e, 0x1e, 0xfe, 0x02, 0x20, 0x65, 0x20, 0x00,
0x00, 0x05, 0x12, 0x00, 0x11, 0x1e, 0x11, 0x11,
0x41, 0x1e, 0x41, 0x11, 0x31, 0x1e, 0x31, 0x11,
0x70, 0x75, 0x7a, 0x7f, 0x84, 0x89, 0x8e, 0x93,
0x98, 0x30, 0x20, 0x00, 0x02, 0x00, 0xfe, 0x06,
0x3c, 0xbc, 0x32, 0x0c, 0x00, 0x00, 0x2a, 0x12,
0x1e, 0x12, 0x2e, 0x12, 0xcc, 0x12, 0x11, 0x1a,
0x1e, 0x1a, 0x2e, 0x1a, 0x4c, 0x10, 0x1e, 0x10,
0x11, 0x18, 0x1e, 0x42, 0x1e, 0x42, 0x2e, 0x42,
0xcc, 0x42, 0x11, 0x4a, 0x1e, 0x4a, 0x2e, 0x4a,
0x4c, 0x40, 0x1e, 0x40, 0x11, 0x48, 0x1e, 0x32,
0x1e, 0x32, 0x2e, 0x32, 0xcc, 0x32, 0x11, 0x3a,
0x1e, 0x3a, 0x2e, 0x3a, 0x4c, 0x30, 0x1e, 0x30,
0x11, 0x38, 0x1e, 0x27, 0x9a, 0x01, 0x9d, 0xa2,
0x2f, 0x28, 0x00, 0x00, 0x46, 0xde, 0xc4, 0xbf,
0xa6, 0x9d, 0x81, 0x7b, 0x5c, 0x61, 0x40, 0xc7,
0xc0, 0xae, 0xa9, 0x8c, 0x83, 0x6a, 0x62, 0x50,
0x3e, 0xce, 0xc2, 0xae, 0xa3, 0x8c, 0x7b, 0x6a,
0x5a, 0x50, 0x35, 0xd7, 0xc2, 0xb7, 0xa4, 0x95,
0x7e, 0x72, 0x5a, 0x59, 0x37, 0xfe, 0x02, 0xf8,
0x8c, 0x95, 0x90, 0x8f, 0x00, 0xd7, 0xc0, 0xb7,
0xa2, 0x95, 0x7b, 0x72, 0x56, 0x59, 0x32, 0xc7,
0xc3, 0xae, 0xad, 0x8c, 0x85, 0x6a, 0x63, 0x50,
0x3e, 0xce, 0xc3, 0xae, 0xa4, 0x8c, 0x7c, 0x6a,
0x59, 0x50, 0x34, 0xd7, 0xc2, 0xb7, 0xa5, 0x95,
0x7e, 0x72, 0x59, 0x59, 0x36, 0xfc, 0x05, 0x00,
0x02, 0xce, 0xc5, 0xae, 0xa5, 0x95, 0x83, 0x72,
0x5c, 0x59, 0x36, 0xbf, 0xc6, 0xa5, 0xab, 0x8c,
0x8c, 0x6a, 0x67, 0x50, 0x41, 0x64, 0x07, 0x00,
0x02, 0x95, 0x8c, 0x72, 0x65, 0x59, 0x3f, 0xce,
0xc7, 0xae, 0xa8, 0x95, 0x86, 0x72, 0x5f, 0x59,
0x39, 0xfe, 0x02, 0xf8, 0x8b, 0x7c, 0x0b, 0x09,
0xb7, 0xc2, 0x9d, 0xa4, 0x83, 0x85, 0x6a, 0x6b,
0x50, 0x44, 0xb7, 0xc1, 0x64, 0x01, 0x00, 0x06,
0x61, 0x5d, 0x48, 0x3d, 0xae, 0xc4, 0x9d, 0xad,
0x7b, 0x85, 0x61, 0x66, 0x48, 0x46, 0xae, 0xc3,
0x95, 0xa3, 0x72, 0x7c, 0x59, 0x56, 0x38, 0x31,
0x7c, 0x0b, 0x00, 0x0c, 0x96, 0x91, 0x8f, 0x00,
0xb7, 0xc0, 0xa5, 0xab, 0x8c, 0x8a, 0x6a, 0x64,
0x50, 0x3c, 0xb7, 0xc0, 0x9d, 0xa0, 0x83, 0x80,
0x6a, 0x64, 0x50, 0x3d, 0xb7, 0xc5, 0x9d, 0xa5,
0x83, 0x87, 0x6c, 0x08, 0x07, 0xae, 0xc0, 0x9d,
0xa8, 0x83, 0x88, 0x6a, 0x6d, 0x50, 0x46, 0xfc,
0x05, 0x00, 0x16, 0xbf, 0xc0, 0xa5, 0xa2, 0x8c,
0x7f, 0x6a, 0x57, 0x50, 0x2f, 0xb7, 0xc7, 0xa5,
0xb1, 0x8c, 0x8e, 0x72, 0x6d, 0x59, 0x45, 0xbf,
0xc6, 0xa5, 0xa8, 0x8c, 0x87, 0x6a, 0x5f, 0x50,
0x37, 0xbf, 0xc2, 0xa5, 0xa4, 0x8c, 0x83, 0x6a,
0x5c, 0x50, 0x34, 0xbc, 0x05, 0x00, 0x0e, 0x90,
0x00, 0xc7, 0xc2, 0xae, 0xaa, 0x95, 0x82, 0x7b,
0x60, 0x61, 0x3f, 0xb7, 0xc6, 0xa5, 0xb1, 0x8c,
0x8d, 0x72, 0x6b, 0x61, 0x51, 0xbf, 0xc4, 0xa5,
0xa5, 0x8c, 0x82, 0x72, 0x61, 0x59, 0x39, 0x6c,
0x26, 0x03, 0x95, 0x82, 0x7b, 0x61, 0x61, 0x40,
0xfc, 0x05, 0x00, 0x00, 0x7e, 0xd7, 0xc3, 0xb7,
0xa8, 0x9d, 0x80, 0x83, 0x5d, 0x6a, 0x3f, 0xbf,
0xc7, 0xa5, 0xa8, 0x8c, 0x84, 0x72, 0x60, 0x61,
0x46, 0xbf, 0xc2, 0xae, 0xb0, 0x9d, 0x92, 0x83,
0x6f, 0x6a, 0x50, 0xd7, 0xc3, 0xb7, 0xa7, 0x9d,
0x80, 0x83, 0x5e, 0x6a, 0x40, 0xfe, 0x02, 0xf8,
0x8d, 0x96, 0x90, 0x90, 0xfe, 0x05, 0x00, 0x8a,
0xc4, 0x63, 0xb8, 0x3c, 0xa6, 0x29, 0x97, 0x16,
0x81, 0x84, 0xb7, 0x5b, 0xa9, 0x33, 0x94, 0x1e,
0x83, 0x11, 0x70, 0xb8, 0xc2, 0x70, 0xb1, 0x4d,
0xa3, 0x2a, 0x8d, 0x1b, 0x7b, 0xa8, 0xbc, 0x68,
0xab, 0x47, 0x9d, 0x27, 0x87, 0x18, 0x75, 0xae,
0xc6, 0x7d, 0xbb, 0x4d, 0xaa, 0x1c, 0x84, 0x11,
0x72, 0xa3, 0xbb, 0x6e, 0xad, 0x3c, 0x97, 0x24,
0x85, 0x16, 0x71, 0x80, 0xb2, 0x57, 0xa4, 0x30,
0x8e, 0x1c, 0x7c, 0x10, 0x68, 0xbb, 0xbd, 0x75,
0xac, 0x4f, 0x9e, 0x2b, 0x87, 0x1a, 0x76, 0x96,
0xc5, 0x5e, 0xb5, 0x3e, 0xa5, 0x1f, 0x8c, 0x12,
0x7a, 0xc1, 0xc6, 0x42, 0x9f, 0x27, 0x8c, 0x16,
0x77, 0x0f, 0x67, 0x9d, 0xbc, 0x68, 0xad, 0x36,
0x95, 0x20, 0x83, 0x11, 0x6d, 0x9b, 0xb8, 0x67,
0xa8, 0x34, 0x90, 0x1f, 0x7c, 0x10, 0x67, 0x9e,
0xc9, 0x6a, 0xbb, 0x37, 0xa4, 0x20, 0x90, 0x11,
0x7b, 0xc6, 0xc8, 0x47, 0xa4, 0x2a, 0x90, 0x18,
0x7b, 0x10, 0x6c, 0xae, 0xc4, 0x5d, 0xad, 0x37,
0x9a, 0x1f, 0x85, 0x13, 0x75, 0x70, 0xad, 0x42,
0x99, 0x25, 0x84, 0x17, 0x74, 0x0b, 0x56, 0x87,
0xc8, 0x57, 0xb8, 0x2b, 0x9e, 0x19, 0x8a, 0x0d,
0x74, 0xa7, 0xc8, 0x6e, 0xb9, 0x36, 0xa0, 0x1f,
0x8b, 0x11, 0x75, 0x94, 0xbe, 0x4b, 0xa5, 0x2a,
0x92, 0x18, 0x7c, 0x0f, 0x6b, 0xaf, 0xc0, 0x58,
0xa8, 0x34, 0x94, 0x1d, 0x7d, 0x12, 0x6d, 0x82,
0xc0, 0x52, 0xb0, 0x25, 0x94, 0x14, 0x7f, 0x0c,
0x68, 0x84, 0xbf, 0x3e, 0xa4, 0x22, 0x8e, 0x10,
0x76, 0x0b, 0x65, 0x88, 0xb6, 0x42, 0x9b, 0x26,
0x87, 0x14, 0x70, 0x0c, 0x5f, 0xc5, 0xc2, 0x3e,
0x97, 0x23, 0x83, 0x13, 0x6c, 0x0c, 0x5c, 0xb1,
0xc9, 0x76, 0xbc, 0x4a, 0xaa, 0x20, 0x8d, 0x12,
0x78, 0x93, 0xbf, 0x46, 0xa3, 0x26, 0x8d, 0x14,
0x74, 0x0c, 0x62, 0xc8, 0xc4, 0x3b, 0x97, 0x21,
0x82, 0x11, 0x6a, 0x0a, 0x59, 0xa3, 0xb9, 0x68,
0xa9, 0x30, 0x8d, 0x1a, 0x78, 0x0f, 0x61, 0xa0,
0xc9, 0x73, 0xbe, 0x50, 0xb1, 0x30, 0x9f, 0x14,
0x80, 0x83, 0xb7, 0x3c, 0x9a, 0x20, 0x84, 0x0e,
0x6a, 0x0a, 0x57, 0xac, 0xc2, 0x68, 0xb0, 0x2e,
0x92, 0x19, 0x7c, 0x0d, 0x63, 0x93, 0xbe, 0x62,
0xb0, 0x3c, 0x9e, 0x1a, 0x80, 0x0e, 0x6b, 0xbb,
0x02, 0xa0, 0x02, 0xa0, 0x02, 0x6f, 0x00, 0x75,
0x00, 0x75, 0x00, 0x00, 0x00, 0xad, 0x02, 0xb3,
0x02, 0x6f, 0x00, 0x87, 0x00, 0x85, 0xfe, 0x03,
0x00, 0xc2, 0x02, 0x82, 0x4d, 0x92, 0x6e, 0x4d,
0xb1, 0xa8, 0x84, 0x01, 0x00, 0x07, 0x7e, 0x00,
0xa8, 0x02, 0xa4, 0x02, 0xa4, 0x02, 0xa2, 0x00,
0xa6, 0x00, 0xa6, 0x00, 0x00, 0x00, 0xb4, 0x02,
0xb4, 0x02, 0x92, 0x00, 0x96, 0x00, 0x96, 0x46,
0x04, 0xb0, 0x02, 0x64, 0x02, 0x0a, 0x8c, 0x00,
0x90, 0x02, 0x98, 0x02, 0x98, 0x02, 0x0e, 0x01,
0x11, 0x01, 0x11, 0x50, 0xc3, 0x08, 0x88, 0x02,
0x88, 0x02, 0x19, 0x01, 0x02, 0x01, 0x02, 0x01,
0xf3, 0x2d, 0x00, 0x00
};
/* Array of known hw_options bits with human-friendly parsing */
static struct hc_hwopt {
const u32 bit;
const char *str;
} const hc_hwopts[] = {
{
.bit = RB_HW_OPT_NO_UART,
.str = "no UART\t\t",
}, {
.bit = RB_HW_OPT_HAS_VOLTAGE,
.str = "has Vreg\t",
}, {
.bit = RB_HW_OPT_HAS_USB,
.str = "has usb\t\t",
}, {
.bit = RB_HW_OPT_HAS_ATTINY,
.str = "has ATtiny\t",
}, {
.bit = RB_HW_OPT_NO_NAND,
.str = "no NAND\t\t",
}, {
.bit = RB_HW_OPT_HAS_LCD,
.str = "has LCD\t\t",
}, {
.bit = RB_HW_OPT_HAS_POE_OUT,
.str = "has POE out\t",
}, {
.bit = RB_HW_OPT_HAS_uSD,
.str = "has MicroSD\t",
}, {
.bit = RB_HW_OPT_HAS_SIM,
.str = "has SIM\t\t",
}, {
.bit = RB_HW_OPT_HAS_SFP,
.str = "has SFP\t\t",
}, {
.bit = RB_HW_OPT_HAS_WIFI,
.str = "has WiFi\t",
}, {
.bit = RB_HW_OPT_HAS_TS_FOR_ADC,
.str = "has TS ADC\t",
}, {
.bit = RB_HW_OPT_HAS_PLC,
.str = "has PLC\t\t",
},
};
static ssize_t hc_tag_show_string(const u8 *pld, u16 pld_len, char *buf)
{
return snprintf(buf, pld_len+1, "%s\n", pld);
}
static ssize_t hc_tag_show_u32(const u8 *pld, u16 pld_len, char *buf)
{
char *out = buf;
u32 data; // cpu-endian
/* Caller ensures pld_len > 0 */
if (pld_len % sizeof(data))
return -EINVAL;
data = *(u32 *)pld;
do {
out += sprintf(out, "0x%08x\n", data);
data++;
} while ((pld_len -= sizeof(data)));
return out - buf;
}
/*
* The MAC is stored network-endian on all devices, in 2 32-bit segments:
* <XX:XX:XX:XX> <XX:XX:00:00>. Kernel print has us covered.
*/
static ssize_t hc_tag_show_mac(const u8 *pld, u16 pld_len, char *buf)
{
if (8 != pld_len)
return -EINVAL;
return sprintf(buf, "%pM\n", pld);
}
/*
* Print HW options in a human readable way:
* The raw number and in decoded form
*/
static ssize_t hc_tag_show_hwoptions(const u8 *pld, u16 pld_len, char *buf)
{
char *out = buf;
u32 data; // cpu-endian
int i;
if (sizeof(data) != pld_len)
return -EINVAL;
data = *(u32 *)pld;
out += sprintf(out, "raw\t\t: 0x%08x\n\n", data);
for (i = 0; i < ARRAY_SIZE(hc_hwopts); i++)
out += sprintf(out, "%s: %s\n", hc_hwopts[i].str,
(data & hc_hwopts[i].bit) ? "true" : "false");
return out - buf;
}
static ssize_t hc_wlan_data_bin_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr, char *buf,
loff_t off, size_t count);
static struct hc_wlan_attr {
struct bin_attribute battr;
u16 pld_ofs;
u16 pld_len;
} hc_wlandata_battr = {
.battr = __BIN_ATTR(wlan_data, S_IRUSR, hc_wlan_data_bin_read, NULL, 0),
};
static ssize_t hc_attr_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf);
/* Array of known tags to publish in sysfs */
static struct hc_attr {
const u16 tag_id;
ssize_t (* const tshow)(const u8 *pld, u16 pld_len, char *buf);
struct kobj_attribute kattr;
u16 pld_ofs;
u16 pld_len;
} hc_attrs[] = {
{
.tag_id = RB_ID_FLASH_INFO,
.tshow = hc_tag_show_u32,
.kattr = __ATTR(flash_info, S_IRUSR, hc_attr_show, NULL),
}, {
.tag_id = RB_ID_MAC_ADDRESS_PACK,
.tshow = hc_tag_show_mac,
.kattr = __ATTR(mac_base, S_IRUSR, hc_attr_show, NULL),
}, {
.tag_id = RB_ID_BOARD_PRODUCT_CODE,
.tshow = hc_tag_show_string,
.kattr = __ATTR(board_product_code, S_IRUSR, hc_attr_show, NULL),
}, {
.tag_id = RB_ID_BIOS_VERSION,
.tshow = hc_tag_show_string,
.kattr = __ATTR(booter_version, S_IRUSR, hc_attr_show, NULL),
}, {
.tag_id = RB_ID_SERIAL_NUMBER,
.tshow = hc_tag_show_string,
.kattr = __ATTR(board_serial, S_IRUSR, hc_attr_show, NULL),
}, {
.tag_id = RB_ID_MEMORY_SIZE,
.tshow = hc_tag_show_u32,
.kattr = __ATTR(mem_size, S_IRUSR, hc_attr_show, NULL),
}, {
.tag_id = RB_ID_MAC_ADDRESS_COUNT,
.tshow = hc_tag_show_u32,
.kattr = __ATTR(mac_count, S_IRUSR, hc_attr_show, NULL),
}, {
.tag_id = RB_ID_HW_OPTIONS,
.tshow = hc_tag_show_hwoptions,
.kattr = __ATTR(hw_options, S_IRUSR, hc_attr_show, NULL),
}, {
.tag_id = RB_ID_WLAN_DATA,
.tshow = NULL,
}, {
.tag_id = RB_ID_BOARD_IDENTIFIER,
.tshow = hc_tag_show_string,
.kattr = __ATTR(board_identifier, S_IRUSR, hc_attr_show, NULL),
}, {
.tag_id = RB_ID_PRODUCT_NAME,
.tshow = hc_tag_show_string,
.kattr = __ATTR(product_name, S_IRUSR, hc_attr_show, NULL),
}, {
.tag_id = RB_ID_DEFCONF,
.tshow = hc_tag_show_string,
.kattr = __ATTR(defconf, S_IRUSR, hc_attr_show, NULL),
}
};
/*
* If the RB_ID_WLAN_DATA payload starts with RB_MAGIC_ERD, then past
* that magic number the payload itself contains a routerboot tag node
* locating the LZO-compressed calibration data at id 0x1.
*/
static int hc_wlan_data_unpack_erd(const u8 *inbuf, size_t inlen,
void *outbuf, size_t *outlen)
{
u16 lzo_ofs, lzo_len;
int ret;
/* Find embedded tag */
ret = routerboot_tag_find(inbuf, inlen, 0x1, // always id 1
&lzo_ofs, &lzo_len);
if (ret) {
pr_debug(RB_HC_PR_PFX "ERD data not found\n");
goto fail;
}
if (lzo_len > inlen) {
pr_debug(RB_HC_PR_PFX "Invalid ERD data length\n");
ret = -EINVAL;
goto fail;
}
ret = lzo1x_decompress_safe(inbuf+lzo_ofs, lzo_len, outbuf, outlen);
if (ret)
pr_debug(RB_HC_PR_PFX "LZO decompression error (%d)\n", ret);
fail:
return ret;
}
/*
* If the RB_ID_WLAN_DATA payload starts with RB_MAGIC_LZOR, then past
* that magic number is a payload that must be appended to the hc_lzor_prefix,
* the resulting blob is LZO-compressed. In the LZO decompression result,
* the RB_MAGIC_ERD magic number (aligned) must be located. Following that
* magic, there is a routerboot tag node (id 0x1) locating the RLE-encoded
* calibration data payload.
*/
static int hc_wlan_data_unpack_lzor(const u8 *inbuf, size_t inlen,
void *outbuf, size_t *outlen)
{
u16 rle_ofs, rle_len;
size_t templen;
u8 *tempbuf;
int ret;
templen = inlen + sizeof(hc_lzor_prefix);
if (templen > *outlen)
return -EFBIG;
/* Temporary buffer same size as the outbuf */
tempbuf = kmalloc(*outlen, GFP_KERNEL);
if (!outbuf)
return -ENOMEM;
/* Concatenate into the outbuf */
memcpy(outbuf, hc_lzor_prefix, sizeof(hc_lzor_prefix));
memcpy(outbuf + sizeof(hc_lzor_prefix), inbuf, inlen);
/* LZO-decompress templen bytes of outbuf into the tempbuf */
ret = lzo1x_decompress_safe(outbuf, templen, tempbuf, outlen);
if (ret) {
pr_debug(RB_HC_PR_PFX "LZO decompression error (%d)\n", ret);
goto fail;
}
templen = *outlen;
/*
* Post decompression we have a blob (possibly byproduct of the lzo
* dictionary). We need to find RB_MAGIC_ERD. The magic number seems to
* be 32bit-aligned in the decompression output.
*/
while (RB_MAGIC_ERD != *(u32 *)tempbuf) {
tempbuf += 4;
templen -= 4;
}
/* Past magic. Look for tag node */
ret = routerboot_tag_find(tempbuf, templen, 0x1, &rle_ofs, &rle_len);
if (ret) {
pr_debug(RB_HC_PR_PFX "RLE data not found\n");
goto fail;
}
if (rle_len > templen) {
pr_debug(RB_HC_PR_PFX "Invalid RLE data length\n");
goto 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 "RLE decoding error (%d)\n", ret);
fail:
kfree(tempbuf);
return ret;
}
static int hc_wlan_data_unpack(const size_t tofs, size_t tlen,
void *outbuf, size_t *outlen)
{
const u8 *lbuf;
u32 magic;
int ret;
/* Caller ensure tlen > 0. tofs is aligned */
if ((tofs + tlen) > hc_buflen)
return -EIO;
lbuf = hc_buf + tofs;
magic = *(u32 *)lbuf;
ret = -ENODATA;
switch (magic) {
case RB_MAGIC_LZOR:
/* Skip magic */
lbuf += sizeof(magic);
tlen -= sizeof(magic);
ret = hc_wlan_data_unpack_lzor(lbuf, tlen, outbuf, outlen);
break;
case RB_MAGIC_ERD:
/* Skip magic */
lbuf += sizeof(magic);
tlen -= sizeof(magic);
ret = hc_wlan_data_unpack_erd(lbuf, tlen, outbuf, outlen);
break;
default:
/*
* If the RB_ID_WLAN_DATA payload doesn't start with a
* magic number, the payload itself is the raw RLE-encoded
* calibration data.
*/
ret = routerboot_rle_decode(lbuf, tlen, outbuf, outlen);
if (ret)
pr_debug(RB_HC_PR_PFX "RLE decoding error (%d)\n", ret);
break;
}
return ret;
}
static ssize_t hc_attr_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
{
struct hc_attr *hc_attr;
const u8 *pld;
u16 pld_len;
hc_attr = container_of(attr, typeof(*hc_attr), kattr);
if (!hc_attr->pld_len)
return -ENOENT;
pld = hc_buf + hc_attr->pld_ofs;
pld_len = hc_attr->pld_len;
return hc_attr->tshow(pld, pld_len, buf);
}
/*
* This function will allocate and free memory every time it is called. This
* is not the fastest way to do this, but since the data is rarely read (mainly
* at boot time to load wlan caldata), this makes it possible to save memory for
* the system.
*/
static ssize_t hc_wlan_data_bin_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr, char *buf,
loff_t off, size_t count)
{
struct hc_wlan_attr *hc_wattr;
size_t outlen;
void *outbuf;
int ret;
hc_wattr = container_of(attr, typeof(*hc_wattr), battr);
if (!hc_wattr->pld_len)
return -ENOENT;
outlen = RB_ART_SIZE;
/* Don't bother unpacking if the source is already too large */
if (hc_wattr->pld_len > outlen)
return -EFBIG;
outbuf = kmalloc(outlen, GFP_KERNEL);
if (!outbuf)
return -ENOMEM;
ret = hc_wlan_data_unpack(hc_wattr->pld_ofs, hc_wattr->pld_len, outbuf, &outlen);
if (ret) {
kfree(outbuf);
return ret;
}
if (off >= outlen) {
kfree(outbuf);
return 0;
}
if (off + count > outlen)
count = outlen - off;
memcpy(buf, outbuf + off, count);
kfree(outbuf);
return count;
}
int __init rb_hardconfig_init(struct kobject *rb_kobj)
{
struct mtd_info *mtd;
size_t bytes_read, buflen;
const u8 *buf;
int i, ret;
u32 magic;
// TODO allow override
mtd = get_mtd_device_nm(RB_MTD_HARD_CONFIG);
if (IS_ERR(mtd))
return -ENODEV;
hc_buflen = mtd->size;
hc_buf = kmalloc(hc_buflen, GFP_KERNEL);
if (!hc_buf)
return -ENOMEM;
ret = mtd_read(mtd, 0, hc_buflen, &bytes_read, hc_buf);
if (bytes_read != hc_buflen) {
ret = -EIO;
goto fail;
}
/* Check we have what we expect */
magic = *(const u32 *)hc_buf;
if (RB_MAGIC_HARD != magic) {
ret = -EINVAL;
goto fail;
}
/* Skip magic */
buf = hc_buf + sizeof(magic);
buflen = hc_buflen - sizeof(magic);
/* Populate sysfs */
ret = -ENOMEM;
hc_kobj = kobject_create_and_add(RB_MTD_HARD_CONFIG, rb_kobj);
if (!hc_kobj)
goto fail;
/* Locate and publish all known tags */
for (i = 0; i < ARRAY_SIZE(hc_attrs); i++) {
ret = routerboot_tag_find(buf, buflen, hc_attrs[i].tag_id,
&hc_attrs[i].pld_ofs, &hc_attrs[i].pld_len);
if (ret) {
hc_attrs[i].pld_ofs = hc_attrs[i].pld_len = 0;
continue;
}
/* Account for skipped magic */
hc_attrs[i].pld_ofs += sizeof(magic);
/* Special case RB_ID_WLAN_DATA to prep and create the binary attribute */
if ((RB_ID_WLAN_DATA == hc_attrs[i].tag_id) && hc_attrs[i].pld_len) {
hc_wlandata_battr.pld_ofs = hc_attrs[i].pld_ofs;
hc_wlandata_battr.pld_len = hc_attrs[i].pld_len;
ret = sysfs_create_bin_file(hc_kobj, &hc_wlandata_battr.battr);
if (ret)
pr_err(RB_HC_PR_PFX "Could not create %s sysfs entry (%d)\n",
hc_wlandata_battr.battr.attr.name, ret);
}
/* All other tags are published via standard attributes */
else {
ret = sysfs_create_file(hc_kobj, &hc_attrs[i].kattr.attr);
if (ret)
pr_err(RB_HC_PR_PFX "Could not create %s sysfs entry (%d)\n",
hc_attrs[i].kattr.attr.name, ret);
}
}
pr_info("MikroTik RouterBOARD hardware configuration sysfs driver v" RB_HARDCONFIG_VER "\n");
return 0;
fail:
kfree(hc_buf);
return ret;
}
void __exit rb_hardconfig_exit(void)
{
kobject_put(hc_kobj);
kfree(hc_buf);
}

View File

@ -0,0 +1,183 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Driver for MikroTik RouterBoot flash data. Common routines.
*
* Copyright (C) 2020 Thibaut VARÈNE <hacks+kernel@slashdirt.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*/
#include <linux/types.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sysfs.h>
#include "routerboot.h"
static struct kobject *rb_kobj;
/**
* routerboot_tag_find() - Locate a given tag in routerboot config data.
* @bufhead: the buffer to look into. Must start with a tag node.
* @buflen: size of bufhead
* @tag_id: the tag identifier to look for
* @pld_ofs: will be updated with tag payload offset in bufhead, if tag found
* @pld_len: will be updated with tag payload size, if tag found
*
* This incarnation of tag_find() does only that: it finds a specific routerboot
* tag node in the input buffer. Routerboot tag nodes are u32 values:
* - The low nibble is the tag identification number,
* - The high nibble is the tag payload length (node excluded) in bytes.
* The payload immediately follows the tag node. Tag nodes are 32bit-aligned.
* The returned pld_ofs will always be aligned. pld_len may not end on 32bit
* boundary (the only known case is when parsing ERD data).
* The nodes are cpu-endian on the flash media. The payload is cpu-endian when
* applicable. Tag nodes are not ordered (by ID) on flash.
*
* Return: 0 on success (tag found) or errno
*/
int routerboot_tag_find(const u8 *bufhead, const size_t buflen, const u16 tag_id,
u16 *pld_ofs, u16 *pld_len)
{
const u32 *datum, *bufend;
u32 node;
u16 id, len;
int ret;
if (!bufhead || !tag_id)
return -EINVAL;
ret = -ENOENT;
datum = (const u32 *)bufhead;
bufend = (const u32 *)(bufhead + buflen);
while (datum < bufend) {
node = *datum++;
/* Tag list ends with null node */
if (!node)
break;
id = node & 0xFFFF;
len = node >> 16;
if (tag_id == id) {
if (datum >= bufend)
break;
if (pld_ofs)
*pld_ofs = (u16)((u8 *)datum - bufhead);
if (pld_len)
*pld_len = len;
ret = 0;
break;
}
/*
* The only known situation where len may not end on 32bit
* boundary is within ERD data. Since we're only extracting
* one tag (the first and only one) from that data, we should
* never need to forcefully ALIGN(). Do it anyway, this is not a
* performance path.
*/
len = ALIGN(len, sizeof(*datum));
datum += len / sizeof(*datum);
}
return ret;
}
/**
* routerboot_rle_decode() - Simple RLE (MikroTik variant) decoding routine.
* @in: input buffer to decode
* @inlen: size of in
* @out: output buffer to write decoded data to
* @outlen: pointer to out size when function is called, will be updated with
* size of decoded output on return
*
* MikroTik's variant of RLE operates as follows, considering a signed run byte:
* - positive run => classic RLE
* - negative run => the next -<run> bytes must be copied verbatim
* The API is matched to the lzo1x routines for convenience.
*
* NB: The output buffer cannot overlap with the input buffer.
*
* Return: 0 on success or errno
*/
int routerboot_rle_decode(const u8 *in, size_t inlen, u8 *out, size_t *outlen)
{
int ret, run, nbytes; // use native types for speed
u8 byte;
if (!in || (inlen < 2) || !out)
return -EINVAL;
ret = -ENOSPC;
nbytes = 0;
while (inlen >= 2) {
run = *in++;
inlen--;
/* Verbatim copies */
if (run & 0x80) {
/* Invert run byte sign */
run = ~run & 0xFF;
run++;
if (run > inlen)
goto fail;
inlen -= run;
nbytes += run;
if (nbytes > *outlen)
goto fail;
/* Basic memcpy */
while (run-- > 0)
*out++ = *in++;
}
/* Stream of half-words RLE: <run><byte>. run == 0 is ignored */
else {
byte = *in++;
inlen--;
nbytes += run;
if (nbytes > *outlen)
goto fail;
while (run-- > 0)
*out++ = byte;
}
}
ret = 0;
fail:
*outlen = nbytes;
return ret;
}
static int __init routerboot_init(void)
{
rb_kobj = kobject_create_and_add("mikrotik", firmware_kobj);
if (!rb_kobj)
return -ENOMEM;
return rb_hardconfig_init(rb_kobj);
}
static void __exit routerboot_exit(void)
{
rb_hardconfig_exit();
kobject_put(rb_kobj); // recursive afaict
}
module_init(routerboot_init);
module_exit(routerboot_exit);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("MikroTik RouterBoot sysfs support");
MODULE_AUTHOR("Thibaut VARENE");

View File

@ -0,0 +1,31 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Common definitions for MikroTik RouterBoot data.
*
* Copyright (C) 2020 Thibaut VARÈNE <hacks+kernel@slashdirt.org>
*/
#ifndef _ROUTERBOOT_H_
#define _ROUTERBOOT_H_
#include <linux/types.h>
// these magic values are stored in cpu-endianness on flash
#define RB_MAGIC_HARD (('H') | ('a' << 8) | ('r' << 16) | ('d' << 24))
#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_ART_SIZE 0x10000
#define RB_MTD_HARD_CONFIG "hard_config"
#define RB_MTD_SOFT_CONFIG "soft_config"
int routerboot_tag_find(const u8 *bufhead, const size_t buflen, const u16 tag_id, u16 *pld_ofs, u16 *pld_len);
int routerboot_rle_decode(const u8 *in, size_t inlen, u8 *out, size_t *outlen);
int __init rb_hardconfig_init(struct kobject *rb_kobj);
void __exit rb_hardconfig_exit(void);
#endif /* _ROUTERBOOT_H_ */

View File

@ -0,0 +1,38 @@
From c2deb5ef01a0ef09088832744cbace9e239a6ee0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= <hacks@slashdirt.org>
Date: Tue, 24 Mar 2020 22:11:50 +0100
Subject: [PATCH] generic: platform/mikrotik build bits (4.14)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch adds platform/mikrotik kernel build bits
Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org>
---
drivers/platform/Kconfig | 2 ++
drivers/platform/Makefile | 1 +
2 files changed, 3 insertions(+)
diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig
index c11db8b..0283f0b 100644
--- a/drivers/platform/Kconfig
+++ b/drivers/platform/Kconfig
@@ -8,3 +8,5 @@ endif
source "drivers/platform/goldfish/Kconfig"
source "drivers/platform/chrome/Kconfig"
+
+source "drivers/platform/mikrotik/Kconfig"
diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile
index d3a6630..ad290c3 100644
--- a/drivers/platform/Makefile
+++ b/drivers/platform/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_MIPS) += mips/
obj-$(CONFIG_OLPC) += olpc/
obj-$(CONFIG_GOLDFISH) += goldfish/
obj-$(CONFIG_CHROME_PLATFORMS) += chrome/
+obj-$(CONFIG_MIKROTIK) += mikrotik/
--
2.11.0

View File

@ -0,0 +1,43 @@
From 4437e01fb6bca63fccdba5d6c44888b0935885c2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= <hacks@slashdirt.org>
Date: Tue, 24 Mar 2020 11:45:07 +0100
Subject: [PATCH] generic: routerboot partition build bits (4.14)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch adds routerbootpart kernel build bits
Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org>
---
drivers/mtd/parsers/Kconfig | 9 +++++++++
drivers/mtd/parsers/Makefile | 1 +
2 files changed, 10 insertions(+)
diff --git a/drivers/mtd/parsers/Kconfig b/drivers/mtd/parsers/Kconfig
index d206b3c..58cbdd6 100644
--- a/drivers/mtd/parsers/Kconfig
+++ b/drivers/mtd/parsers/Kconfig
@@ -6,3 +6,12 @@ config MTD_PARSER_TRX
may contain up to 3/4 partitions (depending on the version).
This driver will parse TRX header and report at least two partitions:
kernel and rootfs.
+
+config MTD_ROUTERBOOT_PARTS
+ tristate "RouterBoot flash partition parser"
+ depends on MTD && OF
+ help
+ MikroTik RouterBoot is implemented as a multi segment system on the
+ flash, some of which are fixed and some of which are located at
+ variable offsets. This parser handles both cases via properly
+ formatted DTS.
diff --git a/drivers/mtd/parsers/Makefile b/drivers/mtd/parsers/Makefile
index 4d9024e..41d363a 100644
--- a/drivers/mtd/parsers/Makefile
+++ b/drivers/mtd/parsers/Makefile
@@ -1 +1,2 @@
obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o
+obj-$(CONFIG_MTD_ROUTERBOOT_PARTS) += routerbootpart.o
--
2.11.0

View File

@ -0,0 +1,38 @@
From c2deb5ef01a0ef09088832744cbace9e239a6ee0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= <hacks@slashdirt.org>
Date: Sat, 28 Mar 2020 12:11:50 +0100
Subject: [PATCH] generic: platform/mikrotik build bits (4.19)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch adds platform/mikrotik kernel build bits
Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org>
---
drivers/platform/Kconfig | 2 ++
drivers/platform/Makefile | 1 +
2 files changed, 3 insertions(+)
diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig
index c11db8b..0283f0b 100644
--- a/drivers/platform/Kconfig
+++ b/drivers/platform/Kconfig
@@ -10,3 +10,5 @@
source "drivers/platform/chrome/Kconfig"
source "drivers/platform/mellanox/Kconfig"
+
+source "drivers/platform/mikrotik/Kconfig"
diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile
index d3a6630..ad290c3 100644
--- a/drivers/platform/Makefile
+++ b/drivers/platform/Makefile
@@ -9,3 +9,4 @@
obj-$(CONFIG_OLPC) += olpc/
obj-$(CONFIG_GOLDFISH) += goldfish/
obj-$(CONFIG_CHROME_PLATFORMS) += chrome/
+obj-$(CONFIG_MIKROTIK) += mikrotik/
--
2.11.0

View File

@ -0,0 +1,41 @@
From 4437e01fb6bca63fccdba5d6c44888b0935885c2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= <hacks@slashdirt.org>
Date: Tue, 24 Mar 2020 11:45:07 +0100
Subject: [PATCH] generic: routerboot partition build bits (4.19)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch adds routerbootpart kernel build bits
Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org>
---
drivers/mtd/parsers/Kconfig | 9 +++++++++
drivers/mtd/parsers/Makefile | 1 +
2 files changed, 10 insertions(+)
diff --git a/drivers/mtd/parsers/Kconfig b/drivers/mtd/parsers/Kconfig
index de6f5f8..0afa89c 100644
--- a/drivers/mtd/parsers/Kconfig
+++ b/drivers/mtd/parsers/Kconfig
@@ -22,3 +22,12 @@ config MTD_SHARPSL_PARTS
This provides the read-only FTL logic necessary to read the partition
table from the NAND flash of Sharp SL Series (Zaurus) and the MTD
partition parser using this code.
+
+config MTD_ROUTERBOOT_PARTS
+ tristate "RouterBoot flash partition parser"
+ depends on MTD && OF
+ help
+ MikroTik RouterBoot is implemented as a multi segment system on the
+ flash, some of which are fixed and some of which are located at
+ variable offsets. This parser handles both cases via properly
+ formatted DTS.
diff --git a/drivers/mtd/parsers/Makefile b/drivers/mtd/parsers/Makefile
index 44ff342..0543362 100644
--- a/drivers/mtd/parsers/Makefile
+++ b/drivers/mtd/parsers/Makefile
@@ -1,2 +1,3 @@
obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o
obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o
+obj-$(CONFIG_MTD_ROUTERBOOT_PARTS) += routerbootpart.o

View File

@ -0,0 +1,31 @@
From c2deb5ef01a0ef09088832744cbace9e239a6ee0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= <hacks@slashdirt.org>
Date: Sat, 28 Mar 2020 12:11:50 +0100
Subject: [PATCH] generic: platform/mikrotik build bits (5.4)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch adds platform/mikrotik kernel build bits
Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org>
---
drivers/platform/Kconfig | 2 ++
drivers/platform/Makefile | 1 +
2 files changed, 3 insertions(+)
--- a/drivers/platform/Kconfig
+++ b/drivers/platform/Kconfig
@@ -13,3 +13,5 @@ source "drivers/platform/chrome/Kconfig"
source "drivers/platform/mellanox/Kconfig"
source "drivers/platform/olpc/Kconfig"
+
+source "drivers/platform/mikrotik/Kconfig"
--- a/drivers/platform/Makefile
+++ b/drivers/platform/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_MIPS) += mips/
obj-$(CONFIG_OLPC_EC) += olpc/
obj-$(CONFIG_GOLDFISH) += goldfish/
obj-$(CONFIG_CHROME_PLATFORMS) += chrome/
+obj-$(CONFIG_MIKROTIK) += mikrotik/

View File

@ -0,0 +1,40 @@
From 4437e01fb6bca63fccdba5d6c44888b0935885c2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= <hacks@slashdirt.org>
Date: Tue, 24 Mar 2020 11:45:07 +0100
Subject: [PATCH] generic: routerboot partition build bits (5.4)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch adds routerbootpart kernel build bits
Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org>
---
drivers/mtd/parsers/Kconfig | 9 +++++++++
drivers/mtd/parsers/Makefile | 1 +
2 files changed, 10 insertions(+)
--- a/drivers/mtd/parsers/Kconfig
+++ b/drivers/mtd/parsers/Kconfig
@@ -176,3 +176,12 @@ config MTD_MYLOADER_PARTS
You will still need the parsing functions to be called by the driver
for your particular device. It won't happen automatically.
+
+config MTD_ROUTERBOOT_PARTS
+ tristate "RouterBoot flash partition parser"
+ depends on MTD && OF
+ help
+ MikroTik RouterBoot is implemented as a multi segment system on the
+ flash, some of which are fixed and some of which are located at
+ variable offsets. This parser handles both cases via properly
+ formatted DTS.
--- a/drivers/mtd/parsers/Makefile
+++ b/drivers/mtd/parsers/Makefile
@@ -9,4 +9,5 @@ obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o
obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o
obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
-obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o
+obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o
+obj-$(CONFIG_MTD_ROUTERBOOT_PARTS) += routerbootpart.o

View File

@ -110,5 +110,5 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};

View File

@ -176,5 +176,5 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};

View File

@ -212,5 +212,5 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};

View File

@ -145,7 +145,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -122,7 +122,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -127,7 +127,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&pcie {

View File

@ -164,7 +164,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&pcie {

View File

@ -149,7 +149,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
pinctrl-names = "default";
pinctrl-0 = <&pa_pins>;
};

View File

@ -149,7 +149,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&pcie {

View File

@ -182,7 +182,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
pinctrl-names = "default";
pinctrl-0 = <&pa_pins>;
};

View File

@ -190,7 +190,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&pcie {

View File

@ -175,7 +175,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&pcie {

View File

@ -173,7 +173,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&pcie {

View File

@ -140,7 +140,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
pinctrl-names = "default";
pinctrl-0 = <&pa_pins>, <&wled_pins>;
};

View File

@ -142,7 +142,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -133,7 +133,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -137,7 +137,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&pcie {

View File

@ -156,7 +156,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -120,7 +120,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
pinctrl-names = "default";
pinctrl-0 = <&pa_pins>;
};

View File

@ -169,7 +169,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -102,7 +102,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -94,7 +94,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
pinctrl-names = "default";
pinctrl-0 = <&pa_pins>;
};

View File

@ -156,5 +156,5 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};

View File

@ -94,7 +94,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -112,7 +112,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&sdhci {

View File

@ -135,7 +135,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
pinctrl-names = "default";
pinctrl-0 = <&pa_pins>;
};

View File

@ -116,5 +116,5 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};

View File

@ -74,5 +74,5 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};

View File

@ -151,5 +151,5 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};

View File

@ -99,5 +99,5 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};

View File

@ -119,7 +119,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&pcie {

View File

@ -135,5 +135,5 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};

View File

@ -140,7 +140,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&pcie {

View File

@ -174,7 +174,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -165,7 +165,7 @@
};
&wmac {
ralink,mtd-eeprom = <&radio 0>;
ralink,mtd-eeprom = <&radio 0x0>;
mtd-mac-address = <&rom 0xf100>;
};

View File

@ -135,7 +135,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
pinctrl-names = "default";
pinctrl-0 = <&pa_pins>;
};

View File

@ -124,7 +124,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&sdhci {

View File

@ -158,5 +158,5 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};

View File

@ -116,7 +116,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
pinctrl-names = "default";
pinctrl-0 = <&pa_pins>;
};

View File

@ -79,7 +79,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -102,7 +102,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&sdhci {

View File

@ -163,7 +163,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&ehci {

View File

@ -113,7 +113,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -126,7 +126,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -102,7 +102,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -111,7 +111,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -123,7 +123,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -102,7 +102,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -118,7 +118,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -118,7 +118,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -48,7 +48,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -104,7 +104,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -86,7 +86,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -91,7 +91,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -114,7 +114,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -118,7 +118,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -99,7 +99,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -112,7 +112,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&state_default {

View File

@ -137,7 +137,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&ehci {

View File

@ -137,7 +137,7 @@
};
&wmac {
ralink,mtd-eeprom = <&factory 0>;
ralink,mtd-eeprom = <&factory 0x0>;
};
&ehci {

View File

@ -17,12 +17,6 @@
bootargs = "console=ttyS0,57600";
};
palmbus: palmbus@1E000000 {
i2c@900 {
status = "okay";
};
};
keys {
compatible = "gpio-keys";
@ -60,6 +54,10 @@
};
};
&i2c {
status = "okay";
};
&sdhci {
status = "okay";
};

View File

@ -20,18 +20,6 @@
bootargs = "console=ttyS0,115200";
};
palmbus: palmbus@1E000000 {
i2c: i2c@900 {
status = "okay";
pcf8563: rtc@51 {
status = "okay";
compatible = "nxp,pcf8563";
reg = <0x51>;
};
};
};
leds {
compatible = "gpio-leds";
@ -101,6 +89,16 @@
};
};
&i2c {
status = "okay";
rtc@51 {
status = "okay";
compatible = "nxp,pcf8563";
reg = <0x51>;
};
};
&sdhci {
status = "okay";
};

Some files were not shown because too many files have changed in this diff Show More