Merge Official Source

This commit is contained in:
CN_SZTL 2020-04-25 11:29:03 +08:00
commit 0136f1d13a
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
50 changed files with 1094 additions and 524 deletions

View File

@ -13,7 +13,7 @@ PKG_RELEASE:=1
PKG_BUILD_DIR:=$(BUILD_DIR)/ltq-dsl-fw-$(PKG_VERSION)
PKG_SOURCE:=ltq-dsl-fw-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/
PKG_SOURCE_URL:=https://sources.openwrt.org/
PKG_HASH:=28676d41c4b76e5bf7a2c5eae106a61fb96b93eabc0cb71120575fff9997269f
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
@ -45,8 +45,8 @@ endef
define Package/kmod-ltq-adsl-$(BUILD_VARIANT)/install
$(INSTALL_DIR) $(1)/lib/firmware/
$(CP) $(PKG_BUILD_DIR)/$(FW_NAME)/ltq-dsl-fw-$(ANNEX)-$(SOC).bin $(1)/lib/firmware/
ln -s /lib/firmware/$(FW_NAME)/ltq-dsl-fw-$(ANNEX)-$(SOC).bin $(1)/lib/firmware/adsl.bin
$(CP) $(PKG_BUILD_DIR)/ltq-dsl-fw-$(ANNEX)-$(SOC).bin $(1)/lib/firmware/
ln -s /lib/firmware/ltq-dsl-fw-$(ANNEX)-$(SOC).bin $(1)/lib/firmware/adsl.bin
endef
$(eval $(call BuildPackage,kmod-ltq-adsl-danube-fw-a))

View File

@ -1,5 +1,5 @@
config LANTIQ_DSL_DEBUG
config LANTIQ_ADSL_DEBUG
bool "verbose debugging"
depends on PACKAGE_kmod-ltq-dsl
depends on PACKAGE_kmod-ltq-adsl
help
Say Y, if you need ltq-dsl to display debug messages.
Say Y, if you need ltq-adsl to display debug messages.

View File

@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=ltq-adsl
PKG_VERSION:=3.24.4.4
PKG_RELEASE:=2
PKG_RELEASE:=3
PKG_SOURCE:=drv_dsl_cpe_api_danube-$(PKG_VERSION).tar.gz
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/ltq-dsl-$(BUILD_VARIANT)/drv_dsl_cpe_api-$(PKG_VERSION)
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/
PKG_SOURCE_URL:=https://mirror2.openwrt.org/sources/
PKG_HASH:=eb2ed59715d3bf4e8a1460bbbe2f1660039e0a9f9d72afb1b2b16590094eb33c
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
@ -38,7 +38,7 @@ KernelPackage/ltq-adsl-danube=$(call KernelPackage/ltq-adsl-template,danube,(TAR
KernelPackage/ltq-adsl-ar9=$(call KernelPackage/ltq-adsl-template,ar9,TARGET_lantiq_xway)
KernelPackage/ltq-adsl-ase=$(call KernelPackage/ltq-adsl-template,ase,TARGET_lantiq_ase)
define KernelPackage/ltq-dsl/config
define KernelPackage/ltq-adsl/config
source "$(SOURCE)/Config.in"
endef
@ -75,7 +75,7 @@ CONFIGURE_ARGS += --enable-add-drv-cflags="-DMODULE -DCONFIG_$(CONFIG_TAG_$(BUIL
CONFIGURE_ARGS += --enable-danube
ifeq ($(CONFIG_LANTIQ_DSL_DEBUG),y)
ifeq ($(CONFIG_LANTIQ_ADSL_DEBUG),y)
CONFIGURE_ARGS += \
--enable-debug=yes \
--enable-debug-prints=yes

View File

@ -399,7 +399,7 @@ $(eval $(call KernelPackage,ip6-vti))
define KernelPackage/xfrm-interface
SUBMENU:=$(NETWORK_SUPPORT_MENU)
TITLE:=IPsec XFRM Interface
DEPENDS:=+kmod-ipsec4 +@IPV6:kmod-ipsec6 @!LINUX_4_14
DEPENDS:=+kmod-ipsec4 +IPV6:kmod-ipsec6 @!LINUX_4_14
KCONFIG:=CONFIG_XFRM_INTERFACE
FILES:=$(LINUX_DIR)/net/xfrm/xfrm_interface.ko
AUTOLOAD:=$(call AutoProbe,xfrm_interface)

View File

@ -34,7 +34,7 @@
ahb {
apb {
ddr_ctrl: memory-controller@18000000 {
compatible = "qca,ar9530-ddr-controller",
compatible = "qca,qca9530-ddr-controller",
"qca,ar7240-ddr-controller";
reg = <0x18000000 0x128>;
@ -69,7 +69,7 @@
};
gpio: gpio@18040000 {
compatible = "qca,ar9530-gpio",
compatible = "qca,qca9530-gpio",
"qca,ar9340-gpio";
reg = <0x18040000 0x28>;

View File

@ -4,7 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
chosen {

View File

@ -5,7 +5,7 @@
#include "qca9556_avm_fritz-repeater.dtsi"
/ {
compatible = "avm,fritz1750e", "qca,qca9557";
compatible = "avm,fritz1750e", "qca,qca9556";
model = "AVM FRITZ!WLAN Repeater 1750E";
aliases {

View File

@ -5,7 +5,7 @@
#include "qca9556_avm_fritz-repeater.dtsi"
/ {
compatible = "avm,fritz450e", "qca,qca9557";
compatible = "avm,fritz450e", "qca,qca9556";
model = "AVM FRITZ!WLAN Repeater 450E";
aliases {

View File

@ -4,7 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
compatible = "mikrotik,routerboard-wap-g-5hact2hnd", "qca,qca9556";

View File

@ -4,7 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
compatible = "buffalo,bhr-4grv2", "qca,qca9557";

View File

@ -3,7 +3,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
aliases {

View File

@ -3,7 +3,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
chosen {

View File

@ -4,7 +4,7 @@
#include "qca9558_devolo_dvl1xxx.dtsi"
/ {
compatible = "devolo,dvl1200e", "qca,qca9557";
compatible = "devolo,dvl1200e", "qca,qca9558";
model = "devolo WiFi pro 1200e";
aliases {

View File

@ -4,7 +4,7 @@
#include "qca9558_devolo_dvl1xxx.dtsi"
/ {
compatible = "devolo,dvl1200i", "qca,qca9557";
compatible = "devolo,dvl1200i", "qca,qca9558";
model = "devolo WiFi pro 1200i";
aliases {

View File

@ -4,7 +4,7 @@
#include "qca9558_devolo_dvl1xxx.dtsi"
/ {
compatible = "devolo,dvl1750c", "qca,qca9557";
compatible = "devolo,dvl1750c", "qca,qca9558";
model = "devolo WiFi pro 1750c";
aliases {

View File

@ -4,7 +4,7 @@
#include "qca9558_devolo_dvl1xxx.dtsi"
/ {
compatible = "devolo,dvl1750e", "qca,qca9557";
compatible = "devolo,dvl1750e", "qca,qca9558";
model = "devolo WiFi pro 1750e";
aliases {

View File

@ -4,7 +4,7 @@
#include "qca9558_devolo_dvl1xxx.dtsi"
/ {
compatible = "devolo,dvl1750i", "qca,qca9557";
compatible = "devolo,dvl1750i", "qca,qca9558";
model = "devolo WiFi pro 1750i";
aliases {

View File

@ -13,7 +13,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
chosen {

View File

@ -4,7 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
compatible = "domywifi,dw33d", "qca,qca9558";

View File

@ -4,10 +4,10 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
compatible = "engenius,ecb1750", "qca,qca9557";
compatible = "engenius,ecb1750", "qca,qca9558";
model = "EnGenius ECB1750";
chosen {

View File

@ -4,11 +4,11 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
model = "EnGenius EPG5000";
compatible = "engenius,epg5000", "qca,qca9557";
compatible = "engenius,epg5000", "qca,qca9558";
chosen {
bootargs = "console=ttyS0,115200n8";

View File

@ -4,7 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
compatible = "librerouter,librerouter-v1", "qca,qca9558";

View File

@ -4,7 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
compatible = "mikrotik,routerboard-922uags-5hpacd", "qca,qca9558";

View File

@ -3,7 +3,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
chosen {

View File

@ -4,10 +4,10 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
compatible = "ocedo,koala", "qca,qca9557";
compatible = "ocedo,koala", "qca,qca9558";
model = "OCEDO Koala";
chosen {

View File

@ -4,7 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
compatible = "ocedo,ursus", "qca,qca9558";

View File

@ -4,10 +4,10 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
compatible = "openmesh,om5p-ac-v2", "qca,qca9557";
compatible = "openmesh,om5p-ac-v2", "qca,qca9558";
model = "OpenMesh OM5P-AC V2";
extosc: ref {

View File

@ -4,7 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
model = "Sitecom WLR-8100 (X8 AC1750)";

View File

@ -3,7 +3,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
chosen {

View File

@ -3,7 +3,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
chosen {

View File

@ -4,7 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
model = "TP-Link RE350K v1";

View File

@ -3,7 +3,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
chosen {

View File

@ -4,7 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
compatible = "tplink,tl-wdr4900-v2", "qca,qca9558";

View File

@ -4,6 +4,6 @@
#include "qca9558_tplink_tl-wr1043nd.dtsi"
/ {
compatible = "tplink,tl-wr1043nd-v2", "qca,qca9557";
compatible = "tplink,tl-wr1043nd-v2", "qca,qca9558";
model = "TP-Link TL-WR1043ND v2";
};

View File

@ -4,6 +4,6 @@
#include "qca9558_tplink_tl-wr1043nd.dtsi"
/ {
compatible = "tplink,tl-wr1043nd-v3", "qca,qca9557";
compatible = "tplink,tl-wr1043nd-v3", "qca,qca9558";
model = "TP-Link TL-WR1043ND v3";
};

View File

@ -3,7 +3,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
chosen {

View File

@ -4,6 +4,6 @@
#include "qca9558_tplink_tl-wr1043nd.dtsi"
/ {
compatible = "tplink,tl-wr1045nd-v2", "qca,qca9557";
compatible = "tplink,tl-wr1045nd-v2", "qca,qca9558";
model = "TP-Link TL-WR1045ND v2";
};

View File

@ -4,7 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
compatible = "tplink,tl-wr941n-v7-cn", "qca,qca9558";

View File

@ -4,7 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
compatible = "trendnet,tew-823dru", "qca,qca9558";

View File

@ -4,7 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "qca9557.dtsi"
#include "qca955x.dtsi"
/ {
compatible = "zyxel,nbg6716", "qca,qca9558";

View File

@ -3,7 +3,7 @@
#include "ath79.dtsi"
/ {
compatible = "qca,qca9557";
compatible = "qca,qca9550";
#address-cells = <1>;
#size-cells = <1>;
@ -30,7 +30,7 @@
ahb {
apb {
ddr_ctrl: memory-controller@18000000 {
compatible = "qca,ar9557-ddr-controller",
compatible = "qca,qca9550-ddr-controller",
"qca,ar7240-ddr-controller";
reg = <0x18000000 0x100>;
@ -78,7 +78,7 @@
};
gpio: gpio@18040000 {
compatible = "qca,ar9557-gpio",
compatible = "qca,qca9550-gpio",
"qca,ar9340-gpio";
reg = <0x18040000 0x28>;
@ -110,7 +110,7 @@
};
pll: pll-controller@18050000 {
compatible = "qca,ar9557-pll",
compatible = "qca,qca9550-pll",
"qca,qca9550-pll", "syscon";
reg = <0x18050000 0x50>;

View File

@ -1,235 +0,0 @@
/*
* Copyright (C) 2011 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 <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/magic.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/version.h>
#define TPLINK_NUM_PARTS 5
#define TPLINK_HEADER_V1 0x01000000
#define TPLINK_HEADER_V2 0x02000000
#define MD5SUM_LEN 16
#define TPLINK_ART_LEN 0x10000
#define TPLINK_KERNEL_OFFS 0x20000
#define TPLINK_64K_KERNEL_OFFS 0x10000
struct tplink_fw_header {
uint32_t version; /* header version */
char vendor_name[24];
char fw_version[36];
uint32_t hw_id; /* hardware id */
uint32_t hw_rev; /* hardware revision */
uint32_t unk1;
uint8_t md5sum1[MD5SUM_LEN];
uint32_t unk2;
uint8_t md5sum2[MD5SUM_LEN];
uint32_t unk3;
uint32_t kernel_la; /* kernel load address */
uint32_t kernel_ep; /* kernel entry point */
uint32_t fw_length; /* total length of the firmware */
uint32_t kernel_ofs; /* kernel data offset */
uint32_t kernel_len; /* kernel data length */
uint32_t rootfs_ofs; /* rootfs data offset */
uint32_t rootfs_len; /* rootfs data length */
uint32_t boot_ofs; /* bootloader data offset */
uint32_t boot_len; /* bootloader data length */
uint8_t pad[360];
} __attribute__ ((packed));
static struct tplink_fw_header *
tplink_read_header(struct mtd_info *mtd, size_t offset)
{
struct tplink_fw_header *header;
size_t header_len;
size_t retlen;
int ret;
u32 t;
header = vmalloc(sizeof(*header));
if (!header)
goto err;
header_len = sizeof(struct tplink_fw_header);
ret = mtd_read(mtd, offset, header_len, &retlen,
(unsigned char *) header);
if (ret)
goto err_free_header;
if (retlen != header_len)
goto err_free_header;
/* sanity checks */
t = be32_to_cpu(header->version);
if ((t != TPLINK_HEADER_V1) && (t != TPLINK_HEADER_V2))
goto err_free_header;
t = be32_to_cpu(header->kernel_ofs);
if (t != header_len)
goto err_free_header;
return header;
err_free_header:
vfree(header);
err:
return NULL;
}
static int tplink_check_rootfs_magic(struct mtd_info *mtd, size_t offset)
{
u32 magic;
size_t retlen;
int ret;
ret = mtd_read(mtd, offset, sizeof(magic), &retlen,
(unsigned char *) &magic);
if (ret)
return ret;
if (retlen != sizeof(magic))
return -EIO;
if (le32_to_cpu(magic) != SQUASHFS_MAGIC &&
magic != 0x19852003)
return -EINVAL;
return 0;
}
static int tplink_parse_partitions_offset(struct mtd_info *master,
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0)
struct mtd_partition **pparts,
#else
const struct mtd_partition **pparts,
#endif
struct mtd_part_parser_data *data,
size_t offset)
{
struct mtd_partition *parts;
struct tplink_fw_header *header;
int nr_parts;
size_t art_offset;
size_t rootfs_offset;
size_t squashfs_offset;
int ret;
nr_parts = TPLINK_NUM_PARTS;
parts = kzalloc(nr_parts * sizeof(struct mtd_partition), GFP_KERNEL);
if (!parts) {
ret = -ENOMEM;
goto err;
}
header = tplink_read_header(master, offset);
if (!header) {
pr_notice("%s: no TP-Link header found\n", master->name);
ret = -ENODEV;
goto err_free_parts;
}
squashfs_offset = offset + sizeof(struct tplink_fw_header) +
be32_to_cpu(header->kernel_len);
ret = tplink_check_rootfs_magic(master, squashfs_offset);
if (ret == 0)
rootfs_offset = squashfs_offset;
else
rootfs_offset = offset + be32_to_cpu(header->rootfs_ofs);
art_offset = master->size - TPLINK_ART_LEN;
parts[0].name = "u-boot";
parts[0].offset = 0;
parts[0].size = offset;
parts[0].mask_flags = MTD_WRITEABLE;
parts[1].name = "kernel";
parts[1].offset = offset;
parts[1].size = rootfs_offset - offset;
parts[2].name = "rootfs";
parts[2].offset = rootfs_offset;
parts[2].size = art_offset - rootfs_offset;
parts[3].name = "art";
parts[3].offset = art_offset;
parts[3].size = TPLINK_ART_LEN;
parts[3].mask_flags = MTD_WRITEABLE;
parts[4].name = "firmware";
parts[4].offset = offset;
parts[4].size = art_offset - offset;
vfree(header);
*pparts = parts;
return nr_parts;
err_free_parts:
kfree(parts);
err:
*pparts = NULL;
return ret;
}
static int tplink_parse_partitions(struct mtd_info *master,
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0)
struct mtd_partition **pparts,
#else
const struct mtd_partition **pparts,
#endif
struct mtd_part_parser_data *data)
{
return tplink_parse_partitions_offset(master, pparts, data,
TPLINK_KERNEL_OFFS);
}
static int tplink_parse_64k_partitions(struct mtd_info *master,
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0)
struct mtd_partition **pparts,
#else
const struct mtd_partition **pparts,
#endif
struct mtd_part_parser_data *data)
{
return tplink_parse_partitions_offset(master, pparts, data,
TPLINK_64K_KERNEL_OFFS);
}
static struct mtd_part_parser tplink_parser = {
.owner = THIS_MODULE,
.parse_fn = tplink_parse_partitions,
.name = "tp-link",
};
static struct mtd_part_parser tplink_64k_parser = {
.owner = THIS_MODULE,
.parse_fn = tplink_parse_64k_partitions,
.name = "tp-link-64k",
};
static int __init tplink_parser_init(void)
{
register_mtd_parser(&tplink_parser);
register_mtd_parser(&tplink_64k_parser);
return 0;
}
module_init(tplink_parser_init);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");

View File

@ -23,3 +23,228 @@
# 'Users' - code which presents functionality to userspace.
obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o
--- /dev/null
+++ b/drivers/mtd/tplinkpart.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2011 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 <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/magic.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/version.h>
+
+#define TPLINK_NUM_PARTS 5
+#define TPLINK_HEADER_V1 0x01000000
+#define TPLINK_HEADER_V2 0x02000000
+#define MD5SUM_LEN 16
+
+#define TPLINK_ART_LEN 0x10000
+#define TPLINK_KERNEL_OFFS 0x20000
+#define TPLINK_64K_KERNEL_OFFS 0x10000
+
+struct tplink_fw_header {
+ uint32_t version; /* header version */
+ char vendor_name[24];
+ char fw_version[36];
+ uint32_t hw_id; /* hardware id */
+ uint32_t hw_rev; /* hardware revision */
+ uint32_t unk1;
+ uint8_t md5sum1[MD5SUM_LEN];
+ uint32_t unk2;
+ uint8_t md5sum2[MD5SUM_LEN];
+ uint32_t unk3;
+ uint32_t kernel_la; /* kernel load address */
+ uint32_t kernel_ep; /* kernel entry point */
+ uint32_t fw_length; /* total length of the firmware */
+ uint32_t kernel_ofs; /* kernel data offset */
+ uint32_t kernel_len; /* kernel data length */
+ uint32_t rootfs_ofs; /* rootfs data offset */
+ uint32_t rootfs_len; /* rootfs data length */
+ uint32_t boot_ofs; /* bootloader data offset */
+ uint32_t boot_len; /* bootloader data length */
+ uint8_t pad[360];
+} __attribute__ ((packed));
+
+static struct tplink_fw_header *
+tplink_read_header(struct mtd_info *mtd, size_t offset)
+{
+ struct tplink_fw_header *header;
+ size_t header_len;
+ size_t retlen;
+ int ret;
+ u32 t;
+
+ header = vmalloc(sizeof(*header));
+ if (!header)
+ goto err;
+
+ header_len = sizeof(struct tplink_fw_header);
+ ret = mtd_read(mtd, offset, header_len, &retlen,
+ (unsigned char *) header);
+ if (ret)
+ goto err_free_header;
+
+ if (retlen != header_len)
+ goto err_free_header;
+
+ /* sanity checks */
+ t = be32_to_cpu(header->version);
+ if ((t != TPLINK_HEADER_V1) && (t != TPLINK_HEADER_V2))
+ goto err_free_header;
+
+ t = be32_to_cpu(header->kernel_ofs);
+ if (t != header_len)
+ goto err_free_header;
+
+ return header;
+
+err_free_header:
+ vfree(header);
+err:
+ return NULL;
+}
+
+static int tplink_check_rootfs_magic(struct mtd_info *mtd, size_t offset)
+{
+ u32 magic;
+ size_t retlen;
+ int ret;
+
+ ret = mtd_read(mtd, offset, sizeof(magic), &retlen,
+ (unsigned char *) &magic);
+ if (ret)
+ return ret;
+
+ if (retlen != sizeof(magic))
+ return -EIO;
+
+ if (le32_to_cpu(magic) != SQUASHFS_MAGIC &&
+ magic != 0x19852003)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int tplink_parse_partitions_offset(struct mtd_info *master,
+ const struct mtd_partition **pparts,
+ struct mtd_part_parser_data *data,
+ size_t offset)
+{
+ struct mtd_partition *parts;
+ struct tplink_fw_header *header;
+ int nr_parts;
+ size_t art_offset;
+ size_t rootfs_offset;
+ size_t squashfs_offset;
+ int ret;
+
+ nr_parts = TPLINK_NUM_PARTS;
+ parts = kzalloc(nr_parts * sizeof(struct mtd_partition), GFP_KERNEL);
+ if (!parts) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ header = tplink_read_header(master, offset);
+ if (!header) {
+ pr_notice("%s: no TP-Link header found\n", master->name);
+ ret = -ENODEV;
+ goto err_free_parts;
+ }
+
+ squashfs_offset = offset + sizeof(struct tplink_fw_header) +
+ be32_to_cpu(header->kernel_len);
+
+ ret = tplink_check_rootfs_magic(master, squashfs_offset);
+ if (ret == 0)
+ rootfs_offset = squashfs_offset;
+ else
+ rootfs_offset = offset + be32_to_cpu(header->rootfs_ofs);
+
+ art_offset = master->size - TPLINK_ART_LEN;
+
+ parts[0].name = "u-boot";
+ parts[0].offset = 0;
+ parts[0].size = offset;
+ parts[0].mask_flags = MTD_WRITEABLE;
+
+ parts[1].name = "kernel";
+ parts[1].offset = offset;
+ parts[1].size = rootfs_offset - offset;
+
+ parts[2].name = "rootfs";
+ parts[2].offset = rootfs_offset;
+ parts[2].size = art_offset - rootfs_offset;
+
+ parts[3].name = "art";
+ parts[3].offset = art_offset;
+ parts[3].size = TPLINK_ART_LEN;
+ parts[3].mask_flags = MTD_WRITEABLE;
+
+ parts[4].name = "firmware";
+ parts[4].offset = offset;
+ parts[4].size = art_offset - offset;
+
+ vfree(header);
+
+ *pparts = parts;
+ return nr_parts;
+
+err_free_parts:
+ kfree(parts);
+err:
+ *pparts = NULL;
+ return ret;
+}
+
+static int tplink_parse_partitions(struct mtd_info *master,
+ const struct mtd_partition **pparts,
+ struct mtd_part_parser_data *data)
+{
+ return tplink_parse_partitions_offset(master, pparts, data,
+ TPLINK_KERNEL_OFFS);
+}
+
+static int tplink_parse_64k_partitions(struct mtd_info *master,
+ const struct mtd_partition **pparts,
+ struct mtd_part_parser_data *data)
+{
+ return tplink_parse_partitions_offset(master, pparts, data,
+ TPLINK_64K_KERNEL_OFFS);
+}
+
+static struct mtd_part_parser tplink_parser = {
+ .owner = THIS_MODULE,
+ .parse_fn = tplink_parse_partitions,
+ .name = "tp-link",
+};
+
+static struct mtd_part_parser tplink_64k_parser = {
+ .owner = THIS_MODULE,
+ .parse_fn = tplink_parse_64k_partitions,
+ .name = "tp-link-64k",
+};
+
+static int __init tplink_parser_init(void)
+{
+ register_mtd_parser(&tplink_parser);
+ register_mtd_parser(&tplink_64k_parser);
+
+ return 0;
+}
+
+module_init(tplink_parser_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");

View File

@ -1,25 +1,244 @@
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -62,6 +62,12 @@ config MTD_MYLOADER_PARTS
--- a/drivers/mtd/parsers/Kconfig
+++ b/drivers/mtd/parsers/Kconfig
@@ -184,3 +184,9 @@ 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_TPLINK_PARTS
+ tristate "TP-Link AR7XXX/AR9XXX partitioning support"
+ depends on ATH79
+ ---help---
+ TBD.
--- a/drivers/mtd/parsers/Makefile
+++ b/drivers/mtd/parsers/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_MTD_PARSER_TRX) += parser_
obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o
obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o
+obj-$(CONFIG_MTD_TPLINK_PARTS) += tplinkpart.o
--- /dev/null
+++ b/drivers/mtd/parsers/tplinkpart.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
comment "User Modules And Translation Layers"
#
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_MTD) += mtd.o
mtd-y := mtdcore.o mtdsuper.o mtdconcat.o mtdpart.o mtdchar.o
obj-y += parsers/
+obj-$(CONFIG_MTD_TPLINK_PARTS) += tplinkpart.o
obj-$(CONFIG_MTD_SPLIT) += mtdsplit/
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/magic.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/version.h>
+
+#define TPLINK_NUM_PARTS 5
+#define TPLINK_HEADER_V1 0x01000000
+#define TPLINK_HEADER_V2 0x02000000
+#define MD5SUM_LEN 16
+
+#define TPLINK_ART_LEN 0x10000
+#define TPLINK_KERNEL_OFFS 0x20000
+#define TPLINK_64K_KERNEL_OFFS 0x10000
+
+struct tplink_fw_header {
+ uint32_t version; /* header version */
+ char vendor_name[24];
+ char fw_version[36];
+ uint32_t hw_id; /* hardware id */
+ uint32_t hw_rev; /* hardware revision */
+ uint32_t unk1;
+ uint8_t md5sum1[MD5SUM_LEN];
+ uint32_t unk2;
+ uint8_t md5sum2[MD5SUM_LEN];
+ uint32_t unk3;
+ uint32_t kernel_la; /* kernel load address */
+ uint32_t kernel_ep; /* kernel entry point */
+ uint32_t fw_length; /* total length of the firmware */
+ uint32_t kernel_ofs; /* kernel data offset */
+ uint32_t kernel_len; /* kernel data length */
+ uint32_t rootfs_ofs; /* rootfs data offset */
+ uint32_t rootfs_len; /* rootfs data length */
+ uint32_t boot_ofs; /* bootloader data offset */
+ uint32_t boot_len; /* bootloader data length */
+ uint8_t pad[360];
+} __attribute__ ((packed));
+
+static struct tplink_fw_header *
+tplink_read_header(struct mtd_info *mtd, size_t offset)
+{
+ struct tplink_fw_header *header;
+ size_t header_len;
+ size_t retlen;
+ int ret;
+ u32 t;
+
+ header = vmalloc(sizeof(*header));
+ if (!header)
+ goto err;
+
+ header_len = sizeof(struct tplink_fw_header);
+ ret = mtd_read(mtd, offset, header_len, &retlen,
+ (unsigned char *) header);
+ if (ret)
+ goto err_free_header;
+
+ if (retlen != header_len)
+ goto err_free_header;
+
+ /* sanity checks */
+ t = be32_to_cpu(header->version);
+ if ((t != TPLINK_HEADER_V1) && (t != TPLINK_HEADER_V2))
+ goto err_free_header;
+
+ t = be32_to_cpu(header->kernel_ofs);
+ if (t != header_len)
+ goto err_free_header;
+
+ return header;
+
+err_free_header:
+ vfree(header);
+err:
+ return NULL;
+}
+
+static int tplink_check_rootfs_magic(struct mtd_info *mtd, size_t offset)
+{
+ u32 magic;
+ size_t retlen;
+ int ret;
+
+ ret = mtd_read(mtd, offset, sizeof(magic), &retlen,
+ (unsigned char *) &magic);
+ if (ret)
+ return ret;
+
+ if (retlen != sizeof(magic))
+ return -EIO;
+
+ if (le32_to_cpu(magic) != SQUASHFS_MAGIC &&
+ magic != 0x19852003)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int tplink_parse_partitions_offset(struct mtd_info *master,
+ const struct mtd_partition **pparts,
+ struct mtd_part_parser_data *data,
+ size_t offset)
+{
+ struct mtd_partition *parts;
+ struct tplink_fw_header *header;
+ int nr_parts;
+ size_t art_offset;
+ size_t rootfs_offset;
+ size_t squashfs_offset;
+ int ret;
+
+ nr_parts = TPLINK_NUM_PARTS;
+ parts = kzalloc(nr_parts * sizeof(struct mtd_partition), GFP_KERNEL);
+ if (!parts) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ header = tplink_read_header(master, offset);
+ if (!header) {
+ pr_notice("%s: no TP-Link header found\n", master->name);
+ ret = -ENODEV;
+ goto err_free_parts;
+ }
+
+ squashfs_offset = offset + sizeof(struct tplink_fw_header) +
+ be32_to_cpu(header->kernel_len);
+
+ ret = tplink_check_rootfs_magic(master, squashfs_offset);
+ if (ret == 0)
+ rootfs_offset = squashfs_offset;
+ else
+ rootfs_offset = offset + be32_to_cpu(header->rootfs_ofs);
+
+ art_offset = master->size - TPLINK_ART_LEN;
+
+ parts[0].name = "u-boot";
+ parts[0].offset = 0;
+ parts[0].size = offset;
+ parts[0].mask_flags = MTD_WRITEABLE;
+
+ parts[1].name = "kernel";
+ parts[1].offset = offset;
+ parts[1].size = rootfs_offset - offset;
+
+ parts[2].name = "rootfs";
+ parts[2].offset = rootfs_offset;
+ parts[2].size = art_offset - rootfs_offset;
+
+ parts[3].name = "art";
+ parts[3].offset = art_offset;
+ parts[3].size = TPLINK_ART_LEN;
+ parts[3].mask_flags = MTD_WRITEABLE;
+
+ parts[4].name = "firmware";
+ parts[4].offset = offset;
+ parts[4].size = art_offset - offset;
+
+ vfree(header);
+
+ *pparts = parts;
+ return nr_parts;
+
+err_free_parts:
+ kfree(parts);
+err:
+ *pparts = NULL;
+ return ret;
+}
+
+static int tplink_parse_partitions(struct mtd_info *master,
+ const struct mtd_partition **pparts,
+ struct mtd_part_parser_data *data)
+{
+ return tplink_parse_partitions_offset(master, pparts, data,
+ TPLINK_KERNEL_OFFS);
+}
+
+static int tplink_parse_64k_partitions(struct mtd_info *master,
+ const struct mtd_partition **pparts,
+ struct mtd_part_parser_data *data)
+{
+ return tplink_parse_partitions_offset(master, pparts, data,
+ TPLINK_64K_KERNEL_OFFS);
+}
+
+static struct mtd_part_parser tplink_parser = {
+ .owner = THIS_MODULE,
+ .parse_fn = tplink_parse_partitions,
+ .name = "tp-link",
+};
+
+static struct mtd_part_parser tplink_64k_parser = {
+ .owner = THIS_MODULE,
+ .parse_fn = tplink_parse_64k_partitions,
+ .name = "tp-link-64k",
+};
+
+static int __init tplink_parser_init(void)
+{
+ register_mtd_parser(&tplink_parser);
+ register_mtd_parser(&tplink_64k_parser);
+
+ return 0;
+}
+
+module_init(tplink_parser_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");

View File

@ -1,182 +0,0 @@
/*
* Parse MyLoader-style flash partition tables and produce a Linux partition
* array to match.
*
* Copyright (C) 2007-2009 Gabor Juhos <juhosg@openwrt.org>
*
* This file was based on drivers/mtd/redboot.c
* Author: Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.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 <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/vmalloc.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/byteorder/generic.h>
#include <linux/myloader.h>
#define BLOCK_LEN_MIN 0x10000
#define PART_NAME_LEN 32
struct part_data {
struct mylo_partition_table tab;
char names[MYLO_MAX_PARTITIONS][PART_NAME_LEN];
};
static int myloader_parse_partitions(struct mtd_info *master,
const struct mtd_partition **pparts,
struct mtd_part_parser_data *data)
{
struct part_data *buf;
struct mylo_partition_table *tab;
struct mylo_partition *part;
struct mtd_partition *mtd_parts;
struct mtd_partition *mtd_part;
int num_parts;
int ret, i;
size_t retlen;
char *names;
unsigned long offset;
unsigned long blocklen;
buf = vmalloc(sizeof(*buf));
if (!buf) {
return -ENOMEM;
goto out;
}
tab = &buf->tab;
blocklen = master->erasesize;
if (blocklen < BLOCK_LEN_MIN)
blocklen = BLOCK_LEN_MIN;
offset = blocklen;
/* Find the partition table */
for (i = 0; i < 4; i++, offset += blocklen) {
printk(KERN_DEBUG "%s: searching for MyLoader partition table"
" at offset 0x%lx\n", master->name, offset);
ret = mtd_read(master, offset, sizeof(*buf), &retlen,
(void *)buf);
if (ret)
goto out_free_buf;
if (retlen != sizeof(*buf)) {
ret = -EIO;
goto out_free_buf;
}
/* Check for Partition Table magic number */
if (tab->magic == le32_to_cpu(MYLO_MAGIC_PARTITIONS))
break;
}
if (tab->magic != le32_to_cpu(MYLO_MAGIC_PARTITIONS)) {
printk(KERN_DEBUG "%s: no MyLoader partition table found\n",
master->name);
ret = 0;
goto out_free_buf;
}
/* The MyLoader and the Partition Table is always present */
num_parts = 2;
/* Detect number of used partitions */
for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
part = &tab->partitions[i];
if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
continue;
num_parts++;
}
mtd_parts = kzalloc((num_parts * sizeof(*mtd_part) +
num_parts * PART_NAME_LEN), GFP_KERNEL);
if (!mtd_parts) {
ret = -ENOMEM;
goto out_free_buf;
}
mtd_part = mtd_parts;
names = (char *)&mtd_parts[num_parts];
strncpy(names, "myloader", PART_NAME_LEN);
mtd_part->name = names;
mtd_part->offset = 0;
mtd_part->size = offset;
mtd_part->mask_flags = MTD_WRITEABLE;
mtd_part++;
names += PART_NAME_LEN;
strncpy(names, "partition_table", PART_NAME_LEN);
mtd_part->name = names;
mtd_part->offset = offset;
mtd_part->size = blocklen;
mtd_part->mask_flags = MTD_WRITEABLE;
mtd_part++;
names += PART_NAME_LEN;
for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
part = &tab->partitions[i];
if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
continue;
if ((buf->names[i][0]) && (buf->names[i][0] != '\xff'))
strncpy(names, buf->names[i], PART_NAME_LEN);
else
snprintf(names, PART_NAME_LEN, "partition%d", i);
mtd_part->offset = le32_to_cpu(part->addr);
mtd_part->size = le32_to_cpu(part->size);
mtd_part->name = names;
mtd_part++;
names += PART_NAME_LEN;
}
*pparts = mtd_parts;
ret = num_parts;
out_free_buf:
vfree(buf);
out:
return ret;
}
static struct mtd_part_parser myloader_mtd_parser = {
.owner = THIS_MODULE,
.parse_fn = myloader_parse_partitions,
.name = "MyLoader",
};
static int __init myloader_mtd_parser_init(void)
{
register_mtd_parser(&myloader_mtd_parser);
return 0;
}
static void __exit myloader_mtd_parser_exit(void)
{
deregister_mtd_parser(&myloader_mtd_parser);
}
module_init(myloader_mtd_parser_init);
module_exit(myloader_mtd_parser_exit);
MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
MODULE_DESCRIPTION("Parsing code for MyLoader partition tables");
MODULE_LICENSE("GPL v2");

View File

@ -5,10 +5,8 @@ Subject: Add myloader partition table parser
lede-commit: d8bf22859b51faa09d22c056fe221a45d2f7a3b8
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/mtd/Kconfig | 16 ++++++++++++++++
drivers/mtd/Makefile | 1 +
2 files changed, 17 insertions(+)
[add myloader.c to patch]
Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@ -45,3 +43,187 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
obj-y += parsers/
# 'Users' - code which presents functionality to userspace.
--- /dev/null
+++ b/drivers/mtd/myloader.c
@@ -0,0 +1,181 @@
+/*
+ * Parse MyLoader-style flash partition tables and produce a Linux partition
+ * array to match.
+ *
+ * Copyright (C) 2007-2009 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This file was based on drivers/mtd/redboot.c
+ * Author: Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.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 <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/byteorder/generic.h>
+#include <linux/myloader.h>
+
+#define BLOCK_LEN_MIN 0x10000
+#define PART_NAME_LEN 32
+
+struct part_data {
+ struct mylo_partition_table tab;
+ char names[MYLO_MAX_PARTITIONS][PART_NAME_LEN];
+};
+
+static int myloader_parse_partitions(struct mtd_info *master,
+ const struct mtd_partition **pparts,
+ struct mtd_part_parser_data *data)
+{
+ struct part_data *buf;
+ struct mylo_partition_table *tab;
+ struct mylo_partition *part;
+ struct mtd_partition *mtd_parts;
+ struct mtd_partition *mtd_part;
+ int num_parts;
+ int ret, i;
+ size_t retlen;
+ char *names;
+ unsigned long offset;
+ unsigned long blocklen;
+
+ buf = vmalloc(sizeof(*buf));
+ if (!buf) {
+ return -ENOMEM;
+ goto out;
+ }
+ tab = &buf->tab;
+
+ blocklen = master->erasesize;
+ if (blocklen < BLOCK_LEN_MIN)
+ blocklen = BLOCK_LEN_MIN;
+
+ offset = blocklen;
+
+ /* Find the partition table */
+ for (i = 0; i < 4; i++, offset += blocklen) {
+ printk(KERN_DEBUG "%s: searching for MyLoader partition table"
+ " at offset 0x%lx\n", master->name, offset);
+
+ ret = mtd_read(master, offset, sizeof(*buf), &retlen,
+ (void *)buf);
+ if (ret)
+ goto out_free_buf;
+
+ if (retlen != sizeof(*buf)) {
+ ret = -EIO;
+ goto out_free_buf;
+ }
+
+ /* Check for Partition Table magic number */
+ if (tab->magic == le32_to_cpu(MYLO_MAGIC_PARTITIONS))
+ break;
+
+ }
+
+ if (tab->magic != le32_to_cpu(MYLO_MAGIC_PARTITIONS)) {
+ printk(KERN_DEBUG "%s: no MyLoader partition table found\n",
+ master->name);
+ ret = 0;
+ goto out_free_buf;
+ }
+
+ /* The MyLoader and the Partition Table is always present */
+ num_parts = 2;
+
+ /* Detect number of used partitions */
+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
+ part = &tab->partitions[i];
+
+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
+ continue;
+
+ num_parts++;
+ }
+
+ mtd_parts = kzalloc((num_parts * sizeof(*mtd_part) +
+ num_parts * PART_NAME_LEN), GFP_KERNEL);
+
+ if (!mtd_parts) {
+ ret = -ENOMEM;
+ goto out_free_buf;
+ }
+
+ mtd_part = mtd_parts;
+ names = (char *)&mtd_parts[num_parts];
+
+ strncpy(names, "myloader", PART_NAME_LEN);
+ mtd_part->name = names;
+ mtd_part->offset = 0;
+ mtd_part->size = offset;
+ mtd_part->mask_flags = MTD_WRITEABLE;
+ mtd_part++;
+ names += PART_NAME_LEN;
+
+ strncpy(names, "partition_table", PART_NAME_LEN);
+ mtd_part->name = names;
+ mtd_part->offset = offset;
+ mtd_part->size = blocklen;
+ mtd_part->mask_flags = MTD_WRITEABLE;
+ mtd_part++;
+ names += PART_NAME_LEN;
+
+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
+ part = &tab->partitions[i];
+
+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
+ continue;
+
+ if ((buf->names[i][0]) && (buf->names[i][0] != '\xff'))
+ strncpy(names, buf->names[i], PART_NAME_LEN);
+ else
+ snprintf(names, PART_NAME_LEN, "partition%d", i);
+
+ mtd_part->offset = le32_to_cpu(part->addr);
+ mtd_part->size = le32_to_cpu(part->size);
+ mtd_part->name = names;
+ mtd_part++;
+ names += PART_NAME_LEN;
+ }
+
+ *pparts = mtd_parts;
+ ret = num_parts;
+
+ out_free_buf:
+ vfree(buf);
+ out:
+ return ret;
+}
+
+static struct mtd_part_parser myloader_mtd_parser = {
+ .owner = THIS_MODULE,
+ .parse_fn = myloader_parse_partitions,
+ .name = "MyLoader",
+};
+
+static int __init myloader_mtd_parser_init(void)
+{
+ register_mtd_parser(&myloader_mtd_parser);
+
+ return 0;
+}
+
+static void __exit myloader_mtd_parser_exit(void)
+{
+ deregister_mtd_parser(&myloader_mtd_parser);
+}
+
+module_init(myloader_mtd_parser_init);
+module_exit(myloader_mtd_parser_exit);
+
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
+MODULE_DESCRIPTION("Parsing code for MyLoader partition tables");
+MODULE_LICENSE("GPL v2");

View File

@ -5,10 +5,8 @@ Subject: Add myloader partition table parser
lede-commit: d8bf22859b51faa09d22c056fe221a45d2f7a3b8
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/mtd/Kconfig | 16 ++++++++++++++++
drivers/mtd/Makefile | 1 +
2 files changed, 17 insertions(+)
[add myloader.c to patch]
Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@ -45,3 +43,187 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
obj-y += parsers/
# 'Users' - code which presents functionality to userspace.
--- /dev/null
+++ b/drivers/mtd/myloader.c
@@ -0,0 +1,181 @@
+/*
+ * Parse MyLoader-style flash partition tables and produce a Linux partition
+ * array to match.
+ *
+ * Copyright (C) 2007-2009 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This file was based on drivers/mtd/redboot.c
+ * Author: Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.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 <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/byteorder/generic.h>
+#include <linux/myloader.h>
+
+#define BLOCK_LEN_MIN 0x10000
+#define PART_NAME_LEN 32
+
+struct part_data {
+ struct mylo_partition_table tab;
+ char names[MYLO_MAX_PARTITIONS][PART_NAME_LEN];
+};
+
+static int myloader_parse_partitions(struct mtd_info *master,
+ const struct mtd_partition **pparts,
+ struct mtd_part_parser_data *data)
+{
+ struct part_data *buf;
+ struct mylo_partition_table *tab;
+ struct mylo_partition *part;
+ struct mtd_partition *mtd_parts;
+ struct mtd_partition *mtd_part;
+ int num_parts;
+ int ret, i;
+ size_t retlen;
+ char *names;
+ unsigned long offset;
+ unsigned long blocklen;
+
+ buf = vmalloc(sizeof(*buf));
+ if (!buf) {
+ return -ENOMEM;
+ goto out;
+ }
+ tab = &buf->tab;
+
+ blocklen = master->erasesize;
+ if (blocklen < BLOCK_LEN_MIN)
+ blocklen = BLOCK_LEN_MIN;
+
+ offset = blocklen;
+
+ /* Find the partition table */
+ for (i = 0; i < 4; i++, offset += blocklen) {
+ printk(KERN_DEBUG "%s: searching for MyLoader partition table"
+ " at offset 0x%lx\n", master->name, offset);
+
+ ret = mtd_read(master, offset, sizeof(*buf), &retlen,
+ (void *)buf);
+ if (ret)
+ goto out_free_buf;
+
+ if (retlen != sizeof(*buf)) {
+ ret = -EIO;
+ goto out_free_buf;
+ }
+
+ /* Check for Partition Table magic number */
+ if (tab->magic == le32_to_cpu(MYLO_MAGIC_PARTITIONS))
+ break;
+
+ }
+
+ if (tab->magic != le32_to_cpu(MYLO_MAGIC_PARTITIONS)) {
+ printk(KERN_DEBUG "%s: no MyLoader partition table found\n",
+ master->name);
+ ret = 0;
+ goto out_free_buf;
+ }
+
+ /* The MyLoader and the Partition Table is always present */
+ num_parts = 2;
+
+ /* Detect number of used partitions */
+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
+ part = &tab->partitions[i];
+
+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
+ continue;
+
+ num_parts++;
+ }
+
+ mtd_parts = kzalloc((num_parts * sizeof(*mtd_part) +
+ num_parts * PART_NAME_LEN), GFP_KERNEL);
+
+ if (!mtd_parts) {
+ ret = -ENOMEM;
+ goto out_free_buf;
+ }
+
+ mtd_part = mtd_parts;
+ names = (char *)&mtd_parts[num_parts];
+
+ strncpy(names, "myloader", PART_NAME_LEN);
+ mtd_part->name = names;
+ mtd_part->offset = 0;
+ mtd_part->size = offset;
+ mtd_part->mask_flags = MTD_WRITEABLE;
+ mtd_part++;
+ names += PART_NAME_LEN;
+
+ strncpy(names, "partition_table", PART_NAME_LEN);
+ mtd_part->name = names;
+ mtd_part->offset = offset;
+ mtd_part->size = blocklen;
+ mtd_part->mask_flags = MTD_WRITEABLE;
+ mtd_part++;
+ names += PART_NAME_LEN;
+
+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
+ part = &tab->partitions[i];
+
+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
+ continue;
+
+ if ((buf->names[i][0]) && (buf->names[i][0] != '\xff'))
+ strncpy(names, buf->names[i], PART_NAME_LEN);
+ else
+ snprintf(names, PART_NAME_LEN, "partition%d", i);
+
+ mtd_part->offset = le32_to_cpu(part->addr);
+ mtd_part->size = le32_to_cpu(part->size);
+ mtd_part->name = names;
+ mtd_part++;
+ names += PART_NAME_LEN;
+ }
+
+ *pparts = mtd_parts;
+ ret = num_parts;
+
+ out_free_buf:
+ vfree(buf);
+ out:
+ return ret;
+}
+
+static struct mtd_part_parser myloader_mtd_parser = {
+ .owner = THIS_MODULE,
+ .parse_fn = myloader_parse_partitions,
+ .name = "MyLoader",
+};
+
+static int __init myloader_mtd_parser_init(void)
+{
+ register_mtd_parser(&myloader_mtd_parser);
+
+ return 0;
+}
+
+static void __exit myloader_mtd_parser_exit(void)
+{
+ deregister_mtd_parser(&myloader_mtd_parser);
+}
+
+module_init(myloader_mtd_parser_init);
+module_exit(myloader_mtd_parser_exit);
+
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
+MODULE_DESCRIPTION("Parsing code for MyLoader partition tables");
+MODULE_LICENSE("GPL v2");

View File

@ -5,17 +5,16 @@ Subject: Add myloader partition table parser
lede-commit: d8bf22859b51faa09d22c056fe221a45d2f7a3b8
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/mtd/Kconfig | 16 ++++++++++++++++
drivers/mtd/Makefile | 1 +
2 files changed, 17 insertions(+)
[adjust for kernel 5.4, add myloader.c to patch]
Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -46,6 +46,22 @@ menu "Partition parsers"
source "drivers/mtd/parsers/Kconfig"
endmenu
--- a/drivers/mtd/parsers/Kconfig
+++ b/drivers/mtd/parsers/Kconfig
@@ -160,3 +160,19 @@ config MTD_REDBOOT_PARTS_READONLY
'FIS directory' images, enable this option.
endif # MTD_REDBOOT_PARTS
+
+config MTD_MYLOADER_PARTS
+ tristate "MyLoader partition parsing"
+ depends on ADM5120 || ATH25 || ATH79
@ -31,14 +30,194 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+
+ You will still need the parsing functions to be called by the driver
+ for your particular device. It won't happen automatically.
+
comment "User Modules And Translation Layers"
#
--- a/drivers/mtd/parsers/Makefile
+++ b/drivers/mtd/parsers/Makefile
@@ -9,3 +9,4 @@ 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
--- /dev/null
+++ b/drivers/mtd/parsers/myloader.c
@@ -0,0 +1,181 @@
+/*
+ * Parse MyLoader-style flash partition tables and produce a Linux partition
+ * array to match.
+ *
+ * Copyright (C) 2007-2009 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This file was based on drivers/mtd/redboot.c
+ * Author: Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.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 <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/byteorder/generic.h>
+#include <linux/myloader.h>
+
+#define BLOCK_LEN_MIN 0x10000
+#define PART_NAME_LEN 32
+
+struct part_data {
+ struct mylo_partition_table tab;
+ char names[MYLO_MAX_PARTITIONS][PART_NAME_LEN];
+};
+
+static int myloader_parse_partitions(struct mtd_info *master,
+ const struct mtd_partition **pparts,
+ struct mtd_part_parser_data *data)
+{
+ struct part_data *buf;
+ struct mylo_partition_table *tab;
+ struct mylo_partition *part;
+ struct mtd_partition *mtd_parts;
+ struct mtd_partition *mtd_part;
+ int num_parts;
+ int ret, i;
+ size_t retlen;
+ char *names;
+ unsigned long offset;
+ unsigned long blocklen;
+
+ buf = vmalloc(sizeof(*buf));
+ if (!buf) {
+ return -ENOMEM;
+ goto out;
+ }
+ tab = &buf->tab;
+
+ blocklen = master->erasesize;
+ if (blocklen < BLOCK_LEN_MIN)
+ blocklen = BLOCK_LEN_MIN;
+
+ offset = blocklen;
+
+ /* Find the partition table */
+ for (i = 0; i < 4; i++, offset += blocklen) {
+ printk(KERN_DEBUG "%s: searching for MyLoader partition table"
+ " at offset 0x%lx\n", master->name, offset);
+
+ ret = mtd_read(master, offset, sizeof(*buf), &retlen,
+ (void *)buf);
+ if (ret)
+ goto out_free_buf;
+
+ if (retlen != sizeof(*buf)) {
+ ret = -EIO;
+ goto out_free_buf;
+ }
+
+ /* Check for Partition Table magic number */
+ if (tab->magic == le32_to_cpu(MYLO_MAGIC_PARTITIONS))
+ break;
+
+ }
+
+ if (tab->magic != le32_to_cpu(MYLO_MAGIC_PARTITIONS)) {
+ printk(KERN_DEBUG "%s: no MyLoader partition table found\n",
+ master->name);
+ ret = 0;
+ goto out_free_buf;
+ }
+
+ /* The MyLoader and the Partition Table is always present */
+ num_parts = 2;
+
+ /* Detect number of used partitions */
+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
+ part = &tab->partitions[i];
+
+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
+ continue;
+
+ num_parts++;
+ }
+
+ mtd_parts = kzalloc((num_parts * sizeof(*mtd_part) +
+ num_parts * PART_NAME_LEN), GFP_KERNEL);
+
+ if (!mtd_parts) {
+ ret = -ENOMEM;
+ goto out_free_buf;
+ }
+
+ mtd_part = mtd_parts;
+ names = (char *)&mtd_parts[num_parts];
+
+ strncpy(names, "myloader", PART_NAME_LEN);
+ mtd_part->name = names;
+ mtd_part->offset = 0;
+ mtd_part->size = offset;
+ mtd_part->mask_flags = MTD_WRITEABLE;
+ mtd_part++;
+ names += PART_NAME_LEN;
+
+ strncpy(names, "partition_table", PART_NAME_LEN);
+ mtd_part->name = names;
+ mtd_part->offset = offset;
+ mtd_part->size = blocklen;
+ mtd_part->mask_flags = MTD_WRITEABLE;
+ mtd_part++;
+ names += PART_NAME_LEN;
+
+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
+ part = &tab->partitions[i];
+
+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
+ continue;
+
+ if ((buf->names[i][0]) && (buf->names[i][0] != '\xff'))
+ strncpy(names, buf->names[i], PART_NAME_LEN);
+ else
+ snprintf(names, PART_NAME_LEN, "partition%d", i);
+
+ mtd_part->offset = le32_to_cpu(part->addr);
+ mtd_part->size = le32_to_cpu(part->size);
+ mtd_part->name = names;
+ mtd_part++;
+ names += PART_NAME_LEN;
+ }
+
+ *pparts = mtd_parts;
+ ret = num_parts;
+
+ out_free_buf:
+ vfree(buf);
+ out:
+ return ret;
+}
+
+static struct mtd_part_parser myloader_mtd_parser = {
+ .owner = THIS_MODULE,
+ .parse_fn = myloader_parse_partitions,
+ .name = "MyLoader",
+};
+
+static int __init myloader_mtd_parser_init(void)
+{
+ register_mtd_parser(&myloader_mtd_parser);
+
+ return 0;
+}
+
+static void __exit myloader_mtd_parser_exit(void)
+{
+ deregister_mtd_parser(&myloader_mtd_parser);
+}
+
+module_init(myloader_mtd_parser_init);
+module_exit(myloader_mtd_parser_exit);
+
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
+MODULE_DESCRIPTION("Parsing code for MyLoader partition tables");
+MODULE_LICENSE("GPL v2");

View File

@ -43,7 +43,7 @@ Signed-off-by: Bernhard Frauendienst <kernel@nospam.obeliks.de>
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -244,4 +244,6 @@ source "drivers/mtd/ubi/Kconfig"
@@ -228,4 +228,6 @@ source "drivers/mtd/ubi/Kconfig"
source "drivers/mtd/hyperbus/Kconfig"

View File

@ -18,6 +18,17 @@ ipq40xx_setup_interfaces()
engenius,ens620ext)
ucidef_set_interfaces_lan_wan "eth0" "eth1"
;;
aruba,ap-303|\
avm,fritzrepeater-1200|\
dlink,dap-2610 |\
engenius,eap1300|\
engenius,emd1|\
meraki,mr33|\
netgear,ex6100v2|\
netgear,ex6150v2|\
zyxel,wre6606)
ucidef_set_interface_lan "eth0"
;;
aruba,ap-303h)
ucidef_set_interfaces_lan_wan "eth0" "eth1"
ucidef_add_switch "switch0" \
@ -48,17 +59,6 @@ ipq40xx_setup_interfaces()
ucidef_add_switch "switch0" \
"0u@eth0" "1:lan" "2:lan" "3:lan" "4:lan"
;;
aruba,ap-303|\
avm,fritzrepeater-1200|\
dlink,dap-2610 |\
engenius,eap1300|\
engenius,emd1|\
meraki,mr33|\
netgear,ex6100v2|\
netgear,ex6150v2|\
zyxel,wre6606)
ucidef_set_interface_lan "eth0"
;;
avm,fritzrepeater-3000|\
compex,wpj419|\
compex,wpj428|\