From 7495acb555730b56ca85e259c1565d141220674a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 19 Jan 2021 21:36:30 +0100 Subject: [PATCH 01/34] kernel: backport mtd commit converting partitions doc syntax MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. It's useful for developing & validating DTS files inside OpenWrt 2. This will allow backporting later changes that depend on it Signed-off-by: Rafał Miłecki --- ...partition-Document-the-slc-mode-prop.patch | 28 ++ ...convert-fixed-partitions-to-the-json.patch | 324 ++++++++++++++++++ 2 files changed, 352 insertions(+) create mode 100644 target/linux/generic/backport-5.4/400-v5.8-dt-bindings-mtd-partition-Document-the-slc-mode-prop.patch create mode 100644 target/linux/generic/backport-5.4/401-v5.11-dt-bindings-mtd-convert-fixed-partitions-to-the-json.patch diff --git a/target/linux/generic/backport-5.4/400-v5.8-dt-bindings-mtd-partition-Document-the-slc-mode-prop.patch b/target/linux/generic/backport-5.4/400-v5.8-dt-bindings-mtd-partition-Document-the-slc-mode-prop.patch new file mode 100644 index 0000000000..7926843686 --- /dev/null +++ b/target/linux/generic/backport-5.4/400-v5.8-dt-bindings-mtd-partition-Document-the-slc-mode-prop.patch @@ -0,0 +1,28 @@ +From 422928a040fe17d17ded69c57903c7908423c7ef Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Sun, 3 May 2020 17:53:38 +0200 +Subject: [PATCH] dt-bindings: mtd: partition: Document the slc-mode property + +Add a boolean property to force a specific partition attached to an MLC +NAND to be accessed in an emulated SLC mode this making this partition +immune to paired-pages corruptions. + +Signed-off-by: Boris Brezillon +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20200503155341.16712-6-miquel.raynal@bootlin.com +--- + Documentation/devicetree/bindings/mtd/partition.txt | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/Documentation/devicetree/bindings/mtd/partition.txt ++++ b/Documentation/devicetree/bindings/mtd/partition.txt +@@ -61,6 +61,9 @@ Optional properties: + clobbered. + - lock : Do not unlock the partition at initialization time (not supported on + all devices) ++- slc-mode: This parameter, if present, allows one to emulate SLC mode on a ++ partition attached to an MLC NAND thus making this partition immune to ++ paired-pages corruptions + + Examples: + diff --git a/target/linux/generic/backport-5.4/401-v5.11-dt-bindings-mtd-convert-fixed-partitions-to-the-json.patch b/target/linux/generic/backport-5.4/401-v5.11-dt-bindings-mtd-convert-fixed-partitions-to-the-json.patch new file mode 100644 index 0000000000..8aded43526 --- /dev/null +++ b/target/linux/generic/backport-5.4/401-v5.11-dt-bindings-mtd-convert-fixed-partitions-to-the-json.patch @@ -0,0 +1,324 @@ +From 04e9ab75267489224364fa510a88ada83e11c325 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 10 Dec 2020 18:23:52 +0100 +Subject: [PATCH] dt-bindings: mtd: convert "fixed-partitions" to the + json-schema +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This standardizes its documentation, allows validating with Makefile +checks and helps writing DTS files. + +Noticeable changes: +1. Dropped "Partitions can be represented by sub-nodes of a flash + device." as we also support subpartitions (don't have to be part of + flash device node) +2. Dropped "to Linux" as bindings are meant to be os agnostic. + +Signed-off-by: Rafał Miłecki +Link: https://lore.kernel.org/r/20201210172352.31632-1-zajec5@gmail.com +Signed-off-by: Rob Herring +--- + .../devicetree/bindings/mtd/partition.txt | 131 +-------------- + .../mtd/partitions/fixed-partitions.yaml | 152 ++++++++++++++++++ + 2 files changed, 154 insertions(+), 129 deletions(-) + create mode 100644 Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml + +--- a/Documentation/devicetree/bindings/mtd/partition.txt ++++ b/Documentation/devicetree/bindings/mtd/partition.txt +@@ -24,137 +24,10 @@ another partitioning method. + Available bindings are listed in the "partitions" subdirectory. + + +-Fixed Partitions +-================ +- +-Partitions can be represented by sub-nodes of a flash device. This can be used +-on platforms which have strong conventions about which portions of a flash are +-used for what purposes, but which don't use an on-flash partition table such +-as RedBoot. +- +-The partition table should be a subnode of the flash node and should be named +-'partitions'. This node should have the following property: +-- compatible : (required) must be "fixed-partitions" +-Partitions are then defined in subnodes of the partitions node. ++Deprecated: partitions defined in flash node ++============================================ + + For backwards compatibility partitions as direct subnodes of the flash device are + supported. This use is discouraged. + NOTE: also for backwards compatibility, direct subnodes that have a compatible + string are not considered partitions, as they may be used for other bindings. +- +-#address-cells & #size-cells must both be present in the partitions subnode of the +-flash device. There are two valid values for both: +-<1>: for partitions that require a single 32-bit cell to represent their +- size/address (aka the value is below 4 GiB) +-<2>: for partitions that require two 32-bit cells to represent their +- size/address (aka the value is 4 GiB or greater). +- +-Required properties: +-- reg : The partition's offset and size within the flash +- +-Optional properties: +-- label : The label / name for this partition. If omitted, the label is taken +- from the node name (excluding the unit address). +-- read-only : This parameter, if present, is a hint to Linux that this +- partition should only be mounted read-only. This is usually used for flash +- partitions containing early-boot firmware images or data which should not be +- clobbered. +-- lock : Do not unlock the partition at initialization time (not supported on +- all devices) +-- slc-mode: This parameter, if present, allows one to emulate SLC mode on a +- partition attached to an MLC NAND thus making this partition immune to +- paired-pages corruptions +- +-Examples: +- +- +-flash@0 { +- partitions { +- compatible = "fixed-partitions"; +- #address-cells = <1>; +- #size-cells = <1>; +- +- partition@0 { +- label = "u-boot"; +- reg = <0x0000000 0x100000>; +- read-only; +- }; +- +- uimage@100000 { +- reg = <0x0100000 0x200000>; +- }; +- }; +-}; +- +-flash@1 { +- partitions { +- compatible = "fixed-partitions"; +- #address-cells = <1>; +- #size-cells = <2>; +- +- /* a 4 GiB partition */ +- partition@0 { +- label = "filesystem"; +- reg = <0x00000000 0x1 0x00000000>; +- }; +- }; +-}; +- +-flash@2 { +- partitions { +- compatible = "fixed-partitions"; +- #address-cells = <2>; +- #size-cells = <2>; +- +- /* an 8 GiB partition */ +- partition@0 { +- label = "filesystem #1"; +- reg = <0x0 0x00000000 0x2 0x00000000>; +- }; +- +- /* a 4 GiB partition */ +- partition@200000000 { +- label = "filesystem #2"; +- reg = <0x2 0x00000000 0x1 0x00000000>; +- }; +- }; +-}; +- +-flash@3 { +- partitions { +- compatible = "fixed-partitions"; +- #address-cells = <1>; +- #size-cells = <1>; +- +- partition@0 { +- label = "bootloader"; +- reg = <0x000000 0x100000>; +- read-only; +- }; +- +- firmware@100000 { +- label = "firmware"; +- reg = <0x100000 0xe00000>; +- compatible = "brcm,trx"; +- }; +- +- calibration@f00000 { +- label = "calibration"; +- reg = <0xf00000 0x100000>; +- compatible = "fixed-partitions"; +- ranges = <0 0xf00000 0x100000>; +- #address-cells = <1>; +- #size-cells = <1>; +- +- partition@0 { +- label = "wifi0"; +- reg = <0x000000 0x080000>; +- }; +- +- partition@80000 { +- label = "wifi1"; +- reg = <0x080000 0x080000>; +- }; +- }; +- }; +-}; +--- /dev/null ++++ b/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml +@@ -0,0 +1,152 @@ ++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/mtd/partitions/fixed-partitions.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Fixed partitions ++ ++description: | ++ This binding can be used on platforms which have strong conventions about ++ which portions of a flash are used for what purposes, but which don't use an ++ on-flash partition table such as RedBoot. ++ ++ The partition table should be a node named "partitions". Partitions are then ++ defined as subnodes. ++ ++maintainers: ++ - Rafał Miłecki ++ ++properties: ++ compatible: ++ const: fixed-partitions ++ ++ "#address-cells": true ++ ++ "#size-cells": true ++ ++patternProperties: ++ "@[0-9a-f]+$": ++ description: node describing a single flash partition ++ type: object ++ ++ properties: ++ reg: ++ description: partition's offset and size within the flash ++ maxItems: 1 ++ ++ label: ++ description: The label / name for this partition. If omitted, the label ++ is taken from the node name (excluding the unit address). ++ ++ read-only: ++ description: This parameter, if present, is a hint that this partition ++ should only be mounted read-only. This is usually used for flash ++ partitions containing early-boot firmware images or data which should ++ not be clobbered. ++ type: boolean ++ ++ lock: ++ description: Do not unlock the partition at initialization time (not ++ supported on all devices) ++ type: boolean ++ ++ slc-mode: ++ description: This parameter, if present, allows one to emulate SLC mode ++ on a partition attached to an MLC NAND thus making this partition ++ immune to paired-pages corruptions ++ type: boolean ++ ++ required: ++ - reg ++ ++required: ++ - "#address-cells" ++ - "#size-cells" ++ ++additionalProperties: true ++ ++examples: ++ - | ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "u-boot"; ++ reg = <0x0000000 0x100000>; ++ read-only; ++ }; ++ ++ uimage@100000 { ++ reg = <0x0100000 0x200000>; ++ }; ++ }; ++ - | ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <2>; ++ ++ /* a 4 GiB partition */ ++ partition@0 { ++ label = "filesystem"; ++ reg = <0x00000000 0x1 0x00000000>; ++ }; ++ }; ++ - | ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ++ /* an 8 GiB partition */ ++ partition@0 { ++ label = "filesystem #1"; ++ reg = <0x0 0x00000000 0x2 0x00000000>; ++ }; ++ ++ /* a 4 GiB partition */ ++ partition@200000000 { ++ label = "filesystem #2"; ++ reg = <0x2 0x00000000 0x1 0x00000000>; ++ }; ++ }; ++ - | ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "bootloader"; ++ reg = <0x000000 0x100000>; ++ read-only; ++ }; ++ ++ firmware@100000 { ++ compatible = "brcm,trx"; ++ label = "firmware"; ++ reg = <0x100000 0xe00000>; ++ }; ++ ++ calibration@f00000 { ++ compatible = "fixed-partitions"; ++ label = "calibration"; ++ reg = <0xf00000 0x100000>; ++ ranges = <0 0xf00000 0x100000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "wifi0"; ++ reg = <0x000000 0x080000>; ++ }; ++ ++ partition@80000 { ++ label = "wifi1"; ++ reg = <0x080000 0x080000>; ++ }; ++ }; ++ }; From 20a0d435d80a98ecf5405c0c0bc9a56bcd04add1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 20 Jan 2021 07:39:25 +0100 Subject: [PATCH 02/34] bcm4908: add pending mtd patches for BCM4908 partitioning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BCM4908 can have multiple firmware partitions. MTD needs to detect which one is currently used. Signed-off-by: Rafał Miłecki --- ...move-partition-binding-to-its-own-fi.patch | 113 +++++++++++ ...-add-binding-from-BCM4908-partitions.patch | 89 ++++++++ ...art-support-BCM4908-fixed-partitions.patch | 191 ++++++++++++++++++ 3 files changed, 393 insertions(+) create mode 100644 target/linux/bcm4908/patches-5.4/140-0001-dt-bindings-mtd-move-partition-binding-to-its-own-fi.patch create mode 100644 target/linux/bcm4908/patches-5.4/140-0002-dt-bindings-mtd-add-binding-from-BCM4908-partitions.patch create mode 100644 target/linux/bcm4908/patches-5.4/140-0003-mtd-parsers-ofpart-support-BCM4908-fixed-partitions.patch diff --git a/target/linux/bcm4908/patches-5.4/140-0001-dt-bindings-mtd-move-partition-binding-to-its-own-fi.patch b/target/linux/bcm4908/patches-5.4/140-0001-dt-bindings-mtd-move-partition-binding-to-its-own-fi.patch new file mode 100644 index 0000000000..1ad61d89f9 --- /dev/null +++ b/target/linux/bcm4908/patches-5.4/140-0001-dt-bindings-mtd-move-partition-binding-to-its-own-fi.patch @@ -0,0 +1,113 @@ +From 4fdbaa5a3dbe761b231c13feaa53242aae3306cc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Fri, 15 Jan 2021 15:23:02 +0100 +Subject: [PATCH 1/3] dt-bindings: mtd: move partition binding to its own file +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Single partition binding is quite common and may be: +1. Used by multiple parsers +2. Extended for more specific cases + +Move it to separated file to avoid code duplication. + +Signed-off-by: Rafał Miłecki +--- + .../mtd/partitions/fixed-partitions.yaml | 33 +------------ + .../bindings/mtd/partitions/partition.yaml | 47 +++++++++++++++++++ + 2 files changed, 48 insertions(+), 32 deletions(-) + create mode 100644 Documentation/devicetree/bindings/mtd/partitions/partition.yaml + +--- a/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml ++++ b/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml +@@ -27,38 +27,7 @@ properties: + + patternProperties: + "@[0-9a-f]+$": +- description: node describing a single flash partition +- type: object +- +- properties: +- reg: +- description: partition's offset and size within the flash +- maxItems: 1 +- +- label: +- description: The label / name for this partition. If omitted, the label +- is taken from the node name (excluding the unit address). +- +- read-only: +- description: This parameter, if present, is a hint that this partition +- should only be mounted read-only. This is usually used for flash +- partitions containing early-boot firmware images or data which should +- not be clobbered. +- type: boolean +- +- lock: +- description: Do not unlock the partition at initialization time (not +- supported on all devices) +- type: boolean +- +- slc-mode: +- description: This parameter, if present, allows one to emulate SLC mode +- on a partition attached to an MLC NAND thus making this partition +- immune to paired-pages corruptions +- type: boolean +- +- required: +- - reg ++ $ref: "partition.yaml#" + + required: + - "#address-cells" +--- /dev/null ++++ b/Documentation/devicetree/bindings/mtd/partitions/partition.yaml +@@ -0,0 +1,47 @@ ++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/mtd/partitions/partition.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Partition ++ ++description: | ++ This binding describes a single flash partition. Each partition must have its ++ relative offset and size specified. Depending on partition function extra ++ properties can be used. ++ ++maintainers: ++ - Rafał Miłecki ++ ++properties: ++ reg: ++ description: partition's offset and size within the flash ++ maxItems: 1 ++ ++ label: ++ description: The label / name for this partition. If omitted, the label ++ is taken from the node name (excluding the unit address). ++ ++ read-only: ++ description: This parameter, if present, is a hint that this partition ++ should only be mounted read-only. This is usually used for flash ++ partitions containing early-boot firmware images or data which should ++ not be clobbered. ++ type: boolean ++ ++ lock: ++ description: Do not unlock the partition at initialization time (not ++ supported on all devices) ++ type: boolean ++ ++ slc-mode: ++ description: This parameter, if present, allows one to emulate SLC mode ++ on a partition attached to an MLC NAND thus making this partition ++ immune to paired-pages corruptions ++ type: boolean ++ ++required: ++ - reg ++ ++additionalProperties: true diff --git a/target/linux/bcm4908/patches-5.4/140-0002-dt-bindings-mtd-add-binding-from-BCM4908-partitions.patch b/target/linux/bcm4908/patches-5.4/140-0002-dt-bindings-mtd-add-binding-from-BCM4908-partitions.patch new file mode 100644 index 0000000000..4967e6c1e3 --- /dev/null +++ b/target/linux/bcm4908/patches-5.4/140-0002-dt-bindings-mtd-add-binding-from-BCM4908-partitions.patch @@ -0,0 +1,89 @@ +From 4f740351484e88bcea3776578288b6ec400829c8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Fri, 15 Jan 2021 16:01:04 +0100 +Subject: [PATCH 2/3] dt-bindings: mtd: add binding from BCM4908 partitions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BCM4908 uses fixed partitions layout but function of some partitions may +vary. Some devices use multiple firmware partitions and those should be +marked to let system discover their purpose. + +Signed-off-by: Rafał Miłecki +--- + .../partitions/brcm,bcm4908-partitions.yaml | 68 +++++++++++++++++++ + 1 file changed, 68 insertions(+) + create mode 100644 Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml +@@ -0,0 +1,68 @@ ++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/mtd/partitions/brcm,bcm4908-partitions.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Broadcom BCM4908 partitioning ++ ++description: | ++ Broadcom BCM4908 CFE bootloader supports two firmware partitions. One is used ++ for regular booting, the other is treated as fallback. ++ ++ This binding allows defining all fixed partitions and marking those containing ++ firmware. System can use that information e.g. for booting or flashing ++ purposes. ++ ++maintainers: ++ - Rafał Miłecki ++ ++properties: ++ compatible: ++ const: brcm,bcm4908-partitions ++ ++ "#address-cells": true ++ ++ "#size-cells": true ++ ++patternProperties: ++ "@[0-9a-f]+$": ++ allOf: ++ - $ref: "partition.yaml#" ++ - properties: ++ compatible: ++ const: brcm,bcm4908-firmware ++ ++required: ++ - "#address-cells" ++ - "#size-cells" ++ ++additionalProperties: false ++ ++examples: ++ - | ++ partitions { ++ compatible = "brcm,bcm4908-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "cferom"; ++ reg = <0x0 0x100000>; ++ }; ++ ++ partition@100000 { ++ compatible = "brcm,bcm4908-firmware"; ++ reg = <0x100000 0xf00000>; ++ }; ++ ++ partition@1000000 { ++ compatible = "brcm,bcm4908-firmware"; ++ reg = <0x1000000 0xf00000>; ++ }; ++ ++ partition@1f00000 { ++ label = "calibration"; ++ reg = <0x1f00000 0x100000>; ++ }; ++ }; diff --git a/target/linux/bcm4908/patches-5.4/140-0003-mtd-parsers-ofpart-support-BCM4908-fixed-partitions.patch b/target/linux/bcm4908/patches-5.4/140-0003-mtd-parsers-ofpart-support-BCM4908-fixed-partitions.patch new file mode 100644 index 0000000000..689807d48e --- /dev/null +++ b/target/linux/bcm4908/patches-5.4/140-0003-mtd-parsers-ofpart-support-BCM4908-fixed-partitions.patch @@ -0,0 +1,191 @@ +From db18357719613cc40234300b10e28e4dfa075375 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Fri, 15 Jan 2021 16:23:01 +0100 +Subject: [PATCH 3/3] mtd: parsers: ofpart: support BCM4908 fixed partitions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BCM4908 partitioning is based on fixed layout but allows specifying +multiple firmware partitions. It requires detecting which firmware +partition was used for booting current kernel. + +To support such cases without duplicating a lot of code (without copying +most of the ofpart.c code) support for post-parsing callback was added. + +BCM4908 callback simply reads offset of currently used firmware +partition from the DT. Bootloader specifies it using the "brcm_blparms" +property. + +Signed-off-by: Rafał Miłecki +--- + drivers/mtd/parsers/Makefile | 1 + + drivers/mtd/parsers/bcm4908-partitions.c | 62 ++++++++++++++++++++++++ + drivers/mtd/parsers/bcm4908-partitions.h | 7 +++ + drivers/mtd/parsers/ofpart.c | 28 ++++++++++- + 4 files changed, 96 insertions(+), 2 deletions(-) + create mode 100644 drivers/mtd/parsers/bcm4908-partitions.c + create mode 100644 drivers/mtd/parsers/bcm4908-partitions.h + +--- a/drivers/mtd/parsers/Makefile ++++ b/drivers/mtd/parsers/Makefile +@@ -5,6 +5,7 @@ obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm6 + obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o + obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o + obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o ++obj-$(CONFIG_MTD_OF_PARTS) += bcm4908-partitions.o + obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o + obj-$(CONFIG_MTD_AFS_PARTS) += afs.o + obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o +--- /dev/null ++++ b/drivers/mtd/parsers/bcm4908-partitions.c +@@ -0,0 +1,62 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2021 Rafał Miłecki ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define BLPARAMS_FW_OFFSET "NAND_RFS_OFS" ++ ++static long long bcm4908_partitions_fw_offset(void) ++{ ++ struct device_node *root; ++ struct property *prop; ++ const char *s; ++ ++ root = of_find_node_by_path("/"); ++ if (!root) ++ return -ENOENT; ++ ++ of_property_for_each_string(root, "brcm_blparms", prop, s) { ++ size_t len = strlen(BLPARAMS_FW_OFFSET); ++ unsigned long offset; ++ int err; ++ ++ if (strncmp(s, BLPARAMS_FW_OFFSET, len) || s[len] != '=') ++ continue; ++ ++ err = kstrtoul(s + len + 1, 0, &offset); ++ if (err) { ++ pr_err("failed to parse %s\n", s + len + 1); ++ return err; ++ } ++ ++ return offset << 10; ++ } ++ ++ return -ENOENT; ++} ++ ++int bcm4908_partitions_post_parse(struct mtd_info *mtd, struct mtd_partition *parts, int nr_parts) ++{ ++ long long fw_offset; ++ int i; ++ ++ fw_offset = bcm4908_partitions_fw_offset(); ++ ++ for (i = 0; i < nr_parts; i++) { ++ if (of_device_is_compatible(parts[i].of_node, "brcm,bcm4908-firmware")) { ++ if (fw_offset < 0 || parts[i].offset == fw_offset) ++ parts[i].name = "firmware"; ++ else ++ parts[i].name = "backup"; ++ } ++ } ++ ++ return 0; ++} +--- /dev/null ++++ b/drivers/mtd/parsers/bcm4908-partitions.h +@@ -0,0 +1,7 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef __BCM4908_PARTITIONS_H ++#define __BCM4908_PARTITIONS_H ++ ++int bcm4908_partitions_post_parse(struct mtd_info *mtd, struct mtd_partition *parts, int nr_parts); ++ ++#endif +--- a/drivers/mtd/parsers/ofpart.c ++++ b/drivers/mtd/parsers/ofpart.c +@@ -16,6 +16,18 @@ + #include + #include + ++#include "bcm4908-partitions.h" ++ ++struct fixed_partitions_quirks { ++ int (*post_parse)(struct mtd_info *mtd, struct mtd_partition *parts, int nr_parts); ++}; ++ ++struct fixed_partitions_quirks bcm4908_partitions_quirks = { ++ .post_parse = bcm4908_partitions_post_parse, ++}; ++ ++static const struct of_device_id parse_ofpart_match_table[]; ++ + static bool node_has_compatible(struct device_node *pp) + { + return of_get_property(pp, "compatible", NULL); +@@ -25,6 +37,8 @@ static int parse_fixed_partitions(struct + const struct mtd_partition **pparts, + struct mtd_part_parser_data *data) + { ++ const struct fixed_partitions_quirks *quirks; ++ const struct of_device_id *of_id; + struct mtd_partition *parts; + struct device_node *mtd_node; + struct device_node *ofpart_node; +@@ -33,7 +47,6 @@ static int parse_fixed_partitions(struct + int nr_parts, i, ret = 0; + bool dedicated = true; + +- + /* Pull of_node from the master device node */ + mtd_node = mtd_get_of_node(master); + if (!mtd_node) +@@ -50,11 +63,16 @@ static int parse_fixed_partitions(struct + master->name, mtd_node); + ofpart_node = mtd_node; + dedicated = false; +- } else if (!of_device_is_compatible(ofpart_node, "fixed-partitions")) { ++ } ++ ++ of_id = of_match_node(parse_ofpart_match_table, ofpart_node); ++ if (dedicated && !of_id) { + /* The 'partitions' subnode might be used by another parser */ + return 0; + } + ++ quirks = of_id ? of_id->data : NULL; ++ + /* First count the subnodes */ + nr_parts = 0; + for_each_child_of_node(ofpart_node, pp) { +@@ -123,6 +141,9 @@ static int parse_fixed_partitions(struct + if (!nr_parts) + goto ofpart_none; + ++ if (quirks && quirks->post_parse) ++ quirks->post_parse(master, parts, nr_parts); ++ + *pparts = parts; + return nr_parts; + +@@ -137,7 +158,10 @@ ofpart_none: + } + + static const struct of_device_id parse_ofpart_match_table[] = { ++ /* Generic */ + { .compatible = "fixed-partitions" }, ++ /* Customized */ ++ { .compatible = "brcm,bcm4908-partitions", .data = &bcm4908_partitions_quirks, }, + {}, + }; + MODULE_DEVICE_TABLE(of, parse_ofpart_match_table); From 707ad89f064b9e7ed9f2dc3afcdf03f9871cb463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 20 Jan 2021 20:20:24 +0100 Subject: [PATCH 03/34] bcm4908: use backported switch & PMB DTS patches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Final versions differ slightly from what was used initially. Signed-off-by: Rafał Miłecki --- ...s-broadcom-bcm4908-describe-internal-switch.patch} | 7 ++++--- ...m64-dts-broadcom-bcm4908-describe-PMB-block.patch} | 11 ++++------- 2 files changed, 8 insertions(+), 10 deletions(-) rename target/linux/bcm4908/patches-5.4/{130-arm64-dts-broadcom-bcm4908-describe-internal-switch.patch => 031-v5.12-0005-arm64-dts-broadcom-bcm4908-describe-internal-switch.patch} (94%) rename target/linux/bcm4908/patches-5.4/{131-arm64-dts-broadcom-bcm4908-describe-PMB-block.patch => 031-v5.12-0006-arm64-dts-broadcom-bcm4908-describe-PMB-block.patch} (81%) diff --git a/target/linux/bcm4908/patches-5.4/130-arm64-dts-broadcom-bcm4908-describe-internal-switch.patch b/target/linux/bcm4908/patches-5.4/031-v5.12-0005-arm64-dts-broadcom-bcm4908-describe-internal-switch.patch similarity index 94% rename from target/linux/bcm4908/patches-5.4/130-arm64-dts-broadcom-bcm4908-describe-internal-switch.patch rename to target/linux/bcm4908/patches-5.4/031-v5.12-0005-arm64-dts-broadcom-bcm4908-describe-internal-switch.patch index d039e04172..c0e27a4e92 100644 --- a/target/linux/bcm4908/patches-5.4/130-arm64-dts-broadcom-bcm4908-describe-internal-switch.patch +++ b/target/linux/bcm4908/patches-5.4/031-v5.12-0005-arm64-dts-broadcom-bcm4908-describe-internal-switch.patch @@ -1,6 +1,6 @@ -From 12cda92893ea57cdd84a8ccfcc05946d7f3a1cd7 Mon Sep 17 00:00:00 2001 +From 961c38974fa5b34d6232d7485120e4392d279ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 12 Jan 2021 12:56:58 +0100 +Date: Wed, 13 Jan 2021 12:14:06 +0100 Subject: [PATCH] arm64: dts: broadcom: bcm4908: describe internal switch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -15,6 +15,7 @@ internal MDIO. CPU port and Ethernet interface remain to be documented. Signed-off-by: Rafał Miłecki +Signed-off-by: Florian Fainelli --- .../bcm4908/bcm4908-asus-gt-ac5300.dts | 51 +++++++++++ .../boot/dts/broadcom/bcm4908/bcm4908.dtsi | 85 ++++++++++++++++++- @@ -97,7 +98,7 @@ Signed-off-by: Rafał Miłecki }; + + switch@80000 { -+ compatible = "simple-mfd"; ++ compatible = "simple-bus"; + #size-cells = <1>; + #address-cells = <1>; + ranges = <0 0x80000 0x50000>; diff --git a/target/linux/bcm4908/patches-5.4/131-arm64-dts-broadcom-bcm4908-describe-PMB-block.patch b/target/linux/bcm4908/patches-5.4/031-v5.12-0006-arm64-dts-broadcom-bcm4908-describe-PMB-block.patch similarity index 81% rename from target/linux/bcm4908/patches-5.4/131-arm64-dts-broadcom-bcm4908-describe-PMB-block.patch rename to target/linux/bcm4908/patches-5.4/031-v5.12-0006-arm64-dts-broadcom-bcm4908-describe-PMB-block.patch index 5b0ae7af1c..c1a9c35837 100644 --- a/target/linux/bcm4908/patches-5.4/131-arm64-dts-broadcom-bcm4908-describe-PMB-block.patch +++ b/target/linux/bcm4908/patches-5.4/031-v5.12-0006-arm64-dts-broadcom-bcm4908-describe-PMB-block.patch @@ -1,6 +1,6 @@ -From 11a7fb140af5cfa706a8d9c0a309247f020a8d0c Mon Sep 17 00:00:00 2001 +From edcf90801c8e58bd6306d85a4e714a6f09f452df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Mon, 11 Jan 2021 08:15:35 +0100 +Date: Wed, 13 Jan 2021 12:15:47 +0100 Subject: [PATCH] arm64: dts: broadcom: bcm4908: describe PMB block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -10,10 +10,7 @@ PMB (Power Management Bus) controls powering connected devices (e.g. PCIe, USB, SATA). In BCM4908 it's a part of the PROCMON block. Signed-off-by: Rafał Miłecki ---- -Florian: this patch is based on top of the -[PATCH] arm64: dts: broadcom: bcm4908: describe internal switch -one. Both modify "ranges". +Signed-off-by: Florian Fainelli --- .../boot/dts/broadcom/bcm4908/bcm4908.dtsi | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) @@ -35,7 +32,7 @@ one. Both modify "ranges". }; + + procmon: syscon@280000 { -+ compatible = "simple-mfd"; ++ compatible = "simple-bus"; + reg = <0x280000 0x1000>; + ranges; + From bc3dbd68c4ea8898d9f6b11984b80044a65d919f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 20 Jan 2021 21:13:08 +0100 Subject: [PATCH 04/34] bcm4908: use backported brcmstb soc stubs patch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Final version differs slightly - uses IS_ENABLED() Signed-off-by: Rafał Miłecki --- ...-add-stubs-for-getting-platform-IDs.patch} | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) rename target/linux/bcm4908/patches-5.4/{180-soc-brcmstb-add-stubs-for-getting-platform-IDs.patch => 082-v5.12-0003-soc-bcm-brcmstb-add-stubs-for-getting-platform-IDs.patch} (59%) diff --git a/target/linux/bcm4908/patches-5.4/180-soc-brcmstb-add-stubs-for-getting-platform-IDs.patch b/target/linux/bcm4908/patches-5.4/082-v5.12-0003-soc-bcm-brcmstb-add-stubs-for-getting-platform-IDs.patch similarity index 59% rename from target/linux/bcm4908/patches-5.4/180-soc-brcmstb-add-stubs-for-getting-platform-IDs.patch rename to target/linux/bcm4908/patches-5.4/082-v5.12-0003-soc-bcm-brcmstb-add-stubs-for-getting-platform-IDs.patch index 366e6089c4..aab65925b4 100644 --- a/target/linux/bcm4908/patches-5.4/180-soc-brcmstb-add-stubs-for-getting-platform-IDs.patch +++ b/target/linux/bcm4908/patches-5.4/082-v5.12-0003-soc-bcm-brcmstb-add-stubs-for-getting-platform-IDs.patch @@ -1,7 +1,10 @@ -From c149974b2ae2e2296c66262a4ee797c06c39982b Mon Sep 17 00:00:00 2001 +From 149ae80b1d50e7db5ac7df1cdf0820017b70e716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 14 Jan 2021 11:33:01 +0100 -Subject: [PATCH] soc: brcmstb: add stubs for getting platform IDs +Date: Thu, 14 Jan 2021 11:53:18 +0100 +Subject: [PATCH] soc: bcm: brcmstb: add stubs for getting platform IDs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Some brcmstb drivers may be shared with other SoC families. E.g. the same USB PHY block is shared by brcmstb and BCM4908. @@ -14,27 +17,38 @@ stubs for: With this change PHY_BRCM_USB will not have to unconditionally select SOC_BRCMSTB anymore. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Florian Fainelli --- include/linux/soc/brcmstb/brcmstb.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) --- a/include/linux/soc/brcmstb/brcmstb.h +++ b/include/linux/soc/brcmstb/brcmstb.h -@@ -12,6 +12,8 @@ static inline u32 BRCM_REV(u32 reg) +@@ -2,6 +2,8 @@ + #ifndef __BRCMSTB_SOC_H + #define __BRCMSTB_SOC_H + ++#include ++ + static inline u32 BRCM_ID(u32 reg) + { + return reg >> 28 ? reg >> 16 : reg >> 8; +@@ -12,6 +14,8 @@ static inline u32 BRCM_REV(u32 reg) return reg & 0xff; } -+#ifdef CONFIG_SOC_BRCMSTB ++#if IS_ENABLED(CONFIG_SOC_BRCMSTB) + /* * Helper functions for getting family or product id from the * SoC driver. -@@ -19,4 +21,18 @@ static inline u32 BRCM_REV(u32 reg) +@@ -19,4 +23,16 @@ static inline u32 BRCM_REV(u32 reg) u32 brcmstb_get_family_id(void); u32 brcmstb_get_product_id(void); +#else -+ +static inline u32 brcmstb_get_family_id(void) +{ + return 0; @@ -44,7 +58,6 @@ SOC_BRCMSTB anymore. +{ + return 0; +} -+ +#endif + #endif /* __BRCMSTB_SOC_H */ From e6fb4d08a1aef49c5a10743dcdb72f59ff53870a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 20 Jan 2021 21:23:49 +0100 Subject: [PATCH 05/34] bcm4908: add DTS patches for USB PHY and partitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki --- ...ts-broadcom-bcm4908-describe-USB-PHY.patch | 132 ++++++++++++++++++ ...om-bcm4908-improve-partitions-descri.patch | 69 +++++++++ 2 files changed, 201 insertions(+) create mode 100644 target/linux/bcm4908/patches-5.4/300-arm64-dts-broadcom-bcm4908-describe-USB-PHY.patch create mode 100644 target/linux/bcm4908/patches-5.4/301-arm64-dts-broadcom-bcm4908-improve-partitions-descri.patch diff --git a/target/linux/bcm4908/patches-5.4/300-arm64-dts-broadcom-bcm4908-describe-USB-PHY.patch b/target/linux/bcm4908/patches-5.4/300-arm64-dts-broadcom-bcm4908-describe-USB-PHY.patch new file mode 100644 index 0000000000..b0b8cc5748 --- /dev/null +++ b/target/linux/bcm4908/patches-5.4/300-arm64-dts-broadcom-bcm4908-describe-USB-PHY.patch @@ -0,0 +1,132 @@ +From 28d11220a92e9fc4d7d1b8e52dc1c48980e336a1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Wed, 20 Jan 2021 20:34:00 +0100 +Subject: [PATCH] arm64: dts: broadcom: bcm4908: describe USB PHY +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BCM4908 uses slightly modified STB family USB PHY. It handles OHCI/EHCI +and XHCI. It requires powering up using the PMB. + +Signed-off-by: Rafał Miłecki +--- + .../bcm4908/bcm4906-netgear-r8000p.dts | 17 +++++++++++++ + .../bcm4908/bcm4908-asus-gt-ac5300.dts | 16 ++++++++++++ + .../boot/dts/broadcom/bcm4908/bcm4908.dtsi | 25 ++++++++++++++++--- + 3 files changed, 54 insertions(+), 4 deletions(-) + +--- a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4906-netgear-r8000p.dts ++++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4906-netgear-r8000p.dts +@@ -26,6 +26,23 @@ + }; + }; + ++&usb_phy { ++ brcm,ioc = <1>; ++ status = "okay"; ++}; ++ ++&ehci { ++ status = "okay"; ++}; ++ ++&ohci { ++ status = "okay"; ++}; ++ ++&xhci { ++ status = "okay"; ++}; ++ + &nandcs { + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; +--- a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908-asus-gt-ac5300.dts ++++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908-asus-gt-ac5300.dts +@@ -44,6 +44,22 @@ + }; + }; + ++&usb_phy { ++ status = "okay"; ++}; ++ ++&ehci { ++ status = "okay"; ++}; ++ ++&ohci { ++ status = "okay"; ++}; ++ ++&xhci { ++ status = "okay"; ++}; ++ + &ports { + port@0 { + label = "lan2"; +--- a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi ++++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi +@@ -2,6 +2,8 @@ + + #include + #include ++#include ++#include + + /dts-v1/; + +@@ -110,24 +112,39 @@ + #size-cells = <1>; + ranges = <0x00 0x00 0x80000000 0x281000>; + +- usb@c300 { ++ usb_phy: usb-phy@c200 { ++ compatible = "brcm,bcm4908-usb-phy"; ++ reg = <0xc200 0x100>; ++ reg-names = "crtl"; ++ power-domains = <&pmb BCM_PMB_HOST_USB>; ++ dr_mode = "host"; ++ brcm,has-xhci; ++ brcm,has-eohci; ++ #phy-cells = <1>; ++ status = "disabled"; ++ }; ++ ++ ehci: usb@c300 { + compatible = "generic-ehci"; + reg = <0xc300 0x100>; + interrupts = ; ++ phys = <&usb_phy PHY_TYPE_USB2>; + status = "disabled"; + }; + +- usb@c400 { ++ ohci: usb@c400 { + compatible = "generic-ohci"; + reg = <0xc400 0x100>; + interrupts = ; ++ phys = <&usb_phy PHY_TYPE_USB2>; + status = "disabled"; + }; + +- usb@d000 { ++ xhci: usb@d000 { + compatible = "generic-xhci"; + reg = <0xd000 0x8c8>; + interrupts = ; ++ phys = <&usb_phy PHY_TYPE_USB3>; + status = "disabled"; + }; + +@@ -222,7 +239,7 @@ + #address-cells = <1>; + #size-cells = <1>; + +- power-controller@2800c0 { ++ pmb: power-controller@2800c0 { + compatible = "brcm,bcm4908-pmb"; + reg = <0x2800c0 0x40>; + #power-domain-cells = <1>; diff --git a/target/linux/bcm4908/patches-5.4/301-arm64-dts-broadcom-bcm4908-improve-partitions-descri.patch b/target/linux/bcm4908/patches-5.4/301-arm64-dts-broadcom-bcm4908-improve-partitions-descri.patch new file mode 100644 index 0000000000..524a433335 --- /dev/null +++ b/target/linux/bcm4908/patches-5.4/301-arm64-dts-broadcom-bcm4908-improve-partitions-descri.patch @@ -0,0 +1,69 @@ +From e401e6fe9195eabfc6c81d8aed920a75b5d7987b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Wed, 20 Jan 2021 20:53:35 +0100 +Subject: [PATCH] arm64: dts: broadcom: bcm4908: improve partitions description +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +1. Use proper bindings +2. Add missing partitions + +Signed-off-by: Rafał Miłecki +--- + .../bcm4908/bcm4906-netgear-r8000p.dts | 1 + + .../bcm4908/bcm4908-asus-gt-ac5300.dts | 27 ++++++++++++++++++- + 2 files changed, 27 insertions(+), 1 deletion(-) + +--- a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4906-netgear-r8000p.dts ++++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4906-netgear-r8000p.dts +@@ -62,6 +62,7 @@ + }; + + partition@100000 { ++ compatible = "brcm,bcm4908-firmware"; + label = "firmware"; + reg = <0x100000 0x4400000>; + }; +--- a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908-asus-gt-ac5300.dts ++++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908-asus-gt-ac5300.dts +@@ -121,7 +121,7 @@ + #size-cells = <0>; + + partitions { +- compatible = "fixed-partitions"; ++ compatible = "brcm,bcm4908-partitions"; + #address-cells = <1>; + #size-cells = <1>; + +@@ -129,5 +129,30 @@ + label = "cferom"; + reg = <0x0 0x100000>; + }; ++ ++ partition@100000 { ++ compatible = "brcm,bcm4908-firmware"; ++ reg = <0x100000 0x5700000>; ++ }; ++ ++ partition@5800000 { ++ compatible = "brcm,bcm4908-firmware"; ++ reg = <0x5800000 0x5700000>; ++ }; ++ ++ partition@af00000 { ++ label = "misc1"; ++ reg = <0xaf00000 0x800000>; ++ }; ++ ++ partition@b700000 { ++ label = "misc2"; ++ reg = <0xb700000 0x4000000>; ++ }; ++ ++ partition@f700000 { ++ label = "data"; ++ reg = <0xf700000 0x800000>; ++ }; + }; + }; From 095ed5e8e1efd6da509be1064c5c7c9811fa32de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 21 Jan 2021 09:14:20 +0100 Subject: [PATCH 06/34] bcm4908: set console in the CONFIG_CMDLINE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit procd doesn't work with just serial specified in the DT (using chosen & stdout-path). It requires tty device to be explicitly specified in the cmdline. Signed-off-by: Rafał Miłecki --- target/linux/bcm4908/config-5.4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/linux/bcm4908/config-5.4 b/target/linux/bcm4908/config-5.4 index 9991afda15..aa2e088756 100644 --- a/target/linux/bcm4908/config-5.4 +++ b/target/linux/bcm4908/config-5.4 @@ -48,7 +48,7 @@ CONFIG_BLK_PM=y CONFIG_CAVIUM_TX2_ERRATUM_219=y CONFIG_CLKDEV_LOOKUP=y CONFIG_CLONE_BACKWARDS=y -CONFIG_CMDLINE="earlycon=bcm63xx_uart,0xff800640" +CONFIG_CMDLINE="earlycon=bcm63xx_uart,0xff800640 console=ttyS0,115200" CONFIG_CMDLINE_FORCE=y CONFIG_COMMON_CLK=y CONFIG_CPU_RMAP=y From 4e1e18af653da81b07d3f12336925c82a07b0433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 20 Jan 2021 09:21:21 +0100 Subject: [PATCH 07/34] bcm4908: build flashable & bootable firmware images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BCM4908 bootloader requires firmware with JFFS2 image containing: 1. cferam.000 2. 94908.dtb 3. vmlinux.lz 4. device custom files cferam.000 can be obtained from the bcm63xx-cfe repository. device custom files are stored in images dir. Signed-off-by: Rafał Miłecki --- target/linux/bcm4908/image/Makefile | 15 +++++++++++++++ .../image/asus_gt-ac5300/rom/etc/image_ident | 2 ++ .../image/asus_gt-ac5300/rom/etc/image_version | 1 + .../bcm4908/image/netgear_r8000p/etc/image_ident | 4 ++++ .../image/netgear_r8000p/etc/image_version | 1 + 5 files changed, 23 insertions(+) create mode 100644 target/linux/bcm4908/image/asus_gt-ac5300/rom/etc/image_ident create mode 100644 target/linux/bcm4908/image/asus_gt-ac5300/rom/etc/image_version create mode 100644 target/linux/bcm4908/image/netgear_r8000p/etc/image_ident create mode 100644 target/linux/bcm4908/image/netgear_r8000p/etc/image_version diff --git a/target/linux/bcm4908/image/Makefile b/target/linux/bcm4908/image/Makefile index f5db38915d..afe88e6902 100644 --- a/target/linux/bcm4908/image/Makefile +++ b/target/linux/bcm4908/image/Makefile @@ -13,6 +13,19 @@ define Build/bcm4908kernel mv $@.new $@ endef +define Build/bcm4908img + rm -fr $@-bootfs + mkdir -p $@-bootfs + cp -r $(DEVICE_NAME)/* $@-bootfs/ + touch $@-bootfs/1-dummy + cp $(DTS_DIR)/$(firstword $(DEVICE_DTS)).dtb $@-bootfs/94908.dtb + cp $(KDIR)/bcm63xx-cfe/$(subst _,$(comma),$(DEVICE_NAME))/cferam.000 $@-bootfs/ + cp $(IMAGE_KERNEL) $@-bootfs/vmlinux.lz + + $(STAGING_DIR_HOST)/bin/mkfs.jffs2 --pad --little-endian --squash-uids -v -e 128KiB -o $@-bootfs.jffs2 -d $@-bootfs -m none -n + $(STAGING_DIR_HOST)/bin/bcm4908img create $@ -f $@-bootfs.jffs2 +endef + define Device/Default KERNEL := kernel-bin | bcm4908lzma | bcm4908kernel KERNEL_DEPENDS = $$(wildcard $(DTS_DIR)/$$(DEVICE_DTS).dts) @@ -30,6 +43,7 @@ define Device/asus_gt-ac5300 DEVICE_MODEL := GT-AC5300 DEVICE_DTS := broadcom/bcm4908/bcm4908-asus-gt-ac5300 IMAGES := bin + IMAGE/bin := bcm4908img endef TARGET_DEVICES += asus_gt-ac5300 @@ -38,6 +52,7 @@ define Device/netgear_r8000p DEVICE_MODEL := R8000P DEVICE_DTS := broadcom/bcm4908/bcm4906-netgear-r8000p IMAGES := bin + IMAGE/bin := bcm4908img endef TARGET_DEVICES += netgear_r8000p diff --git a/target/linux/bcm4908/image/asus_gt-ac5300/rom/etc/image_ident b/target/linux/bcm4908/image/asus_gt-ac5300/rom/etc/image_ident new file mode 100644 index 0000000000..9e73fe74a7 --- /dev/null +++ b/target/linux/bcm4908/image/asus_gt-ac5300/rom/etc/image_ident @@ -0,0 +1,2 @@ +@(#) $imageversion: HND1731918 $ +@(#) $imageversion: HND1731918 $ diff --git a/target/linux/bcm4908/image/asus_gt-ac5300/rom/etc/image_version b/target/linux/bcm4908/image/asus_gt-ac5300/rom/etc/image_version new file mode 100644 index 0000000000..fd67746f78 --- /dev/null +++ b/target/linux/bcm4908/image/asus_gt-ac5300/rom/etc/image_version @@ -0,0 +1 @@ +HND1731918 diff --git a/target/linux/bcm4908/image/netgear_r8000p/etc/image_ident b/target/linux/bcm4908/image/netgear_r8000p/etc/image_ident new file mode 100644 index 0000000000..15cb69d1af --- /dev/null +++ b/target/linux/bcm4908/image/netgear_r8000p/etc/image_ident @@ -0,0 +1,4 @@ +@(#) $imageversion: 5024HNDrc11R8000P2602103 $ +@(#) $imageversion: 5024HNDrc11R8000P2602103 $ +@(#) $changelist: Changelist: REL_502HND04rc11_BISON04T_REL_7_14_170_34Revision: 765096 $ +@(#) $changelist: Changelist: REL_502HND04rc11_BISON04T_REL_7_14_170_34Revision: 765096 $ diff --git a/target/linux/bcm4908/image/netgear_r8000p/etc/image_version b/target/linux/bcm4908/image/netgear_r8000p/etc/image_version new file mode 100644 index 0000000000..f469dfed31 --- /dev/null +++ b/target/linux/bcm4908/image/netgear_r8000p/etc/image_version @@ -0,0 +1 @@ +5024HNDrc11R8000P2602103 From e78d3e44dddaaa89e101b42574f13bc6aeb6b6ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 21 Jan 2021 13:23:56 +0100 Subject: [PATCH 08/34] bcm4908: append UBI with rootfs to device images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also enable UBI kernel support. Signed-off-by: Rafał Miłecki --- target/linux/bcm4908/config-5.4 | 25 +++++++++++++++++++++++++ target/linux/bcm4908/image/Makefile | 7 ++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/target/linux/bcm4908/config-5.4 b/target/linux/bcm4908/config-5.4 index aa2e088756..3dfa7b21dc 100644 --- a/target/linux/bcm4908/config-5.4 +++ b/target/linux/bcm4908/config-5.4 @@ -52,13 +52,19 @@ CONFIG_CMDLINE="earlycon=bcm63xx_uart,0xff800640 console=ttyS0,115200" CONFIG_CMDLINE_FORCE=y CONFIG_COMMON_CLK=y CONFIG_CPU_RMAP=y +CONFIG_CRC16=y +CONFIG_CRYPTO_ACOMP2=y CONFIG_CRYPTO_AEAD=y CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_LZO=y CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_MANAGER2=y CONFIG_CRYPTO_NULL2=y CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_ZSTD=y CONFIG_DCACHE_WORD_ACCESS=y CONFIG_DMA_DIRECT_REMAP=y CONFIG_DMA_REMAP=y @@ -114,10 +120,13 @@ CONFIG_IRQ_DOMAIN=y CONFIG_IRQ_DOMAIN_HIERARCHY=y CONFIG_IRQ_FORCED_THREADING=y CONFIG_IRQ_WORK=y +# CONFIG_JFFS2_FS is not set CONFIG_LEDS_GPIO=y CONFIG_LIBFDT=y CONFIG_LOCK_DEBUGGING_SUPPORT=y CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y CONFIG_MDIO_BCM_UNIMAC=y CONFIG_MDIO_BUS=y CONFIG_MDIO_DEVICE=y @@ -129,6 +138,11 @@ CONFIG_MTD_NAND_BRCMNAND=y CONFIG_MTD_NAND_CORE=y CONFIG_MTD_NAND_ECC_SW_HAMMING=y CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_SPLIT_BCM_WFI_FW=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BEB_LIMIT=20 +CONFIG_MTD_UBI_BLOCK=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 CONFIG_MUTEX_SPIN_ON_OWNER=y CONFIG_NEED_DMA_MAP_STATE=y CONFIG_NEED_SG_DMA_LENGTH=y @@ -180,6 +194,7 @@ CONFIG_RWSEM_SPIN_ON_OWNER=y # CONFIG_SERIAL_8250 is not set CONFIG_SERIAL_BCM63XX=y CONFIG_SERIAL_BCM63XX_CONSOLE=y +CONFIG_SGL_ALLOC=y CONFIG_SMP=y CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y CONFIG_SPARSE_IRQ=y @@ -194,8 +209,18 @@ CONFIG_TIMER_OF=y CONFIG_TIMER_PROBE=y CONFIG_TREE_RCU=y CONFIG_TREE_SRCU=y +CONFIG_UBIFS_FS=y +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +CONFIG_UBIFS_FS_ZSTD=y CONFIG_UNMAP_KERNEL_AT_EL0=y CONFIG_USB_SUPPORT=y CONFIG_VMAP_STACK=y CONFIG_XPS=y +CONFIG_XXHASH=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y CONFIG_ZONE_DMA32=y +CONFIG_ZSTD_COMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y diff --git a/target/linux/bcm4908/image/Makefile b/target/linux/bcm4908/image/Makefile index afe88e6902..d6b5f07e2a 100644 --- a/target/linux/bcm4908/image/Makefile +++ b/target/linux/bcm4908/image/Makefile @@ -23,7 +23,8 @@ define Build/bcm4908img cp $(IMAGE_KERNEL) $@-bootfs/vmlinux.lz $(STAGING_DIR_HOST)/bin/mkfs.jffs2 --pad --little-endian --squash-uids -v -e 128KiB -o $@-bootfs.jffs2 -d $@-bootfs -m none -n - $(STAGING_DIR_HOST)/bin/bcm4908img create $@ -f $@-bootfs.jffs2 + $(STAGING_DIR_HOST)/bin/bcm4908img create $@.new -f $@-bootfs.jffs2 -a 0x20000 -f $@ + mv $@.new $@ endef define Device/Default @@ -43,7 +44,7 @@ define Device/asus_gt-ac5300 DEVICE_MODEL := GT-AC5300 DEVICE_DTS := broadcom/bcm4908/bcm4908-asus-gt-ac5300 IMAGES := bin - IMAGE/bin := bcm4908img + IMAGE/bin := append-ubi | bcm4908img endef TARGET_DEVICES += asus_gt-ac5300 @@ -52,7 +53,7 @@ define Device/netgear_r8000p DEVICE_MODEL := R8000P DEVICE_DTS := broadcom/bcm4908/bcm4906-netgear-r8000p IMAGES := bin - IMAGE/bin := bcm4908img + IMAGE/bin := append-ubi | bcm4908img endef TARGET_DEVICES += netgear_r8000p From 3bd8f660a4b967a25aa7b605f0ead44ddfab9ea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 21 Jan 2021 13:26:17 +0100 Subject: [PATCH 09/34] bcm4908: workaround NAND controller #WP issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There seems to be a problem with setting #WP. On the other hand ignoring the #WP seems to work. rootfs_data UBI volume seems to persist changes. Signed-off-by: Rafał Miłecki --- ...wnand-brcmnand-disable-WP-on-BCM4908.patch | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 target/linux/bcm4908/patches-5.4/400-mtd-rawnand-brcmnand-disable-WP-on-BCM4908.patch diff --git a/target/linux/bcm4908/patches-5.4/400-mtd-rawnand-brcmnand-disable-WP-on-BCM4908.patch b/target/linux/bcm4908/patches-5.4/400-mtd-rawnand-brcmnand-disable-WP-on-BCM4908.patch new file mode 100644 index 0000000000..65066236db --- /dev/null +++ b/target/linux/bcm4908/patches-5.4/400-mtd-rawnand-brcmnand-disable-WP-on-BCM4908.patch @@ -0,0 +1,34 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 21 Jan 2021 10:44:53 +0100 +Subject: [PATCH] mtd: rawnand: brcmnand: disable WP on BCM4908 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BCM4908 contains NAND controller version 0x0701 (v7.1). It means that +NAND_WP should be available. + +For some reason setting #WP on doesn't result in clearing NAND_STATUS_WP +status bit: +[ 1.077857] bcm63138_nand ff801800.nand: timeout on status poll (expected c0000040 got c00000c0) +[ 1.086832] bcm63138_nand ff801800.nand: nand #WP expected on + +For now try working without touching #WP. + +Signed-off-by: Rafał Miłecki +--- + +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +@@ -38,7 +38,11 @@ + * 1: NAND_WP is set by default, cleared for erase/write operations + * 2: NAND_WP is always cleared + */ ++#if IS_ENABLED(CONFIG_ARCH_BCM4908) ++static int wp_on = 0; ++#else + static int wp_on = 1; ++#endif + module_param(wp_on, int, 0444); + + /*********************************************************************** From 36347d003a934372bf10e59645121ba387a6d27e Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Thu, 21 Jan 2021 13:08:57 +0100 Subject: [PATCH 10/34] ipq40xx: fix boards being shown twice Since generic images have been split to their own Makefile boards are showing up twice in menuconfig as $(eval $(call BuildImage)) was not dropped from the new generic.mk. Hence $(eval $(call BuildImage)) was being called twice. So, lets simply drop it from generic.mk. Fixes: 378c7ff28210 ("ipq40xx: split generic images into own file") Signed-off-by: Robert Marko --- target/linux/ipq40xx/image/generic.mk | 2 -- 1 file changed, 2 deletions(-) diff --git a/target/linux/ipq40xx/image/generic.mk b/target/linux/ipq40xx/image/generic.mk index 9cd50e23ff..4e40b8be50 100644 --- a/target/linux/ipq40xx/image/generic.mk +++ b/target/linux/ipq40xx/image/generic.mk @@ -805,5 +805,3 @@ define Device/zyxel_wre6606 DEVICE_PACKAGES := -kmod-ath10k-ct kmod-ath10k-ct-smallbuffers endef TARGET_DEVICES += zyxel_wre6606 - -$(eval $(call BuildImage)) From 5a46b718260fba4253ea0153d93a02a7c3a7b710 Mon Sep 17 00:00:00 2001 From: Adrian Schmutzler Date: Tue, 19 Jan 2021 18:34:21 +0100 Subject: [PATCH 11/34] ramips: mt7621: reorganize shared device definitions for Xiaomi This creates a shared device definition for Xiaomi devices with NAND and "separate" images, i.e. kernel1.bin and rootfs0.bin. This allows to consolidate similar/duplicate code for AC2100 family and Mi Router 3G. Signed-off-by: Adrian Schmutzler --- target/linux/ramips/image/mt7621.mk | 34 +++++++++++------------------ 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk index d530d5ad3e..ff39cbf39a 100644 --- a/target/linux/ramips/image/mt7621.mk +++ b/target/linux/ramips/image/mt7621.mk @@ -1220,39 +1220,27 @@ define Device/winstars_ws-wn583a6 endef TARGET_DEVICES += winstars_ws-wn583a6 -define Device/xiaomi-ac2100 +define Device/xiaomi_nand_separate $(Device/dsa-migration) $(Device/uimage-lzma-loader) + DEVICE_VENDOR := Xiaomi + DEVICE_PACKAGES := uboot-envtools BLOCKSIZE := 128k PAGESIZE := 2048 KERNEL_SIZE := 4096k - IMAGE_SIZE := 120320k UBINIZE_OPTS := -E 5 IMAGES += kernel1.bin rootfs0.bin IMAGE/kernel1.bin := append-kernel IMAGE/rootfs0.bin := append-ubi | check-size IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata - DEVICE_VENDOR := Xiaomi - DEVICE_PACKAGES := kmod-mt7603 kmod-mt7615e kmod-mt7615-firmware \ - uboot-envtools endef define Device/xiaomi_mi-router-3g - $(Device/dsa-migration) - $(Device/uimage-lzma-loader) - BLOCKSIZE := 128k - PAGESIZE := 2048 - KERNEL_SIZE := 4096k - IMAGE_SIZE := 124416k - UBINIZE_OPTS := -E 5 - IMAGES += kernel1.bin rootfs0.bin - IMAGE/kernel1.bin := append-kernel - IMAGE/rootfs0.bin := append-ubi | check-size - IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata - DEVICE_VENDOR := Xiaomi + $(Device/xiaomi_nand_separate) DEVICE_MODEL := Mi Router 3G - DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 \ - kmod-usb-ledtrig-usbport uboot-envtools + IMAGE_SIZE := 124416k + DEVICE_PACKAGES += kmod-mt7603 kmod-mt76x2 kmod-usb3 \ + kmod-usb-ledtrig-usbport SUPPORTED_DEVICES += R3G mir3g xiaomi,mir3g endef TARGET_DEVICES += xiaomi_mi-router-3g @@ -1301,14 +1289,18 @@ endef TARGET_DEVICES += xiaomi_mi-router-4a-gigabit define Device/xiaomi_mi-router-ac2100 - $(Device/xiaomi-ac2100) + $(Device/xiaomi_nand_separate) DEVICE_MODEL := Mi Router AC2100 + IMAGE_SIZE := 120320k + DEVICE_PACKAGES += kmod-mt7603 kmod-mt7615e kmod-mt7615-firmware endef TARGET_DEVICES += xiaomi_mi-router-ac2100 define Device/xiaomi_redmi-router-ac2100 - $(Device/xiaomi-ac2100) + $(Device/xiaomi_nand_separate) DEVICE_MODEL := Redmi Router AC2100 + IMAGE_SIZE := 120320k + DEVICE_PACKAGES += kmod-mt7603 kmod-mt7615e kmod-mt7615-firmware endef TARGET_DEVICES += xiaomi_redmi-router-ac2100 From 93be5926a2c2ebda05486a43f998a2ee38d32e61 Mon Sep 17 00:00:00 2001 From: Adrian Schmutzler Date: Tue, 19 Jan 2021 18:48:48 +0100 Subject: [PATCH 12/34] ramips: mt7621: create DTSI for Xiaomi NAND devices This creates a DTSI for Xiaomi devices with 128M NAND. This allows to consolidate the partitions and a few other nodes for AC2100 family and Mi Router 3G. Note that the Mi Router 3 Pro has 256M NAND and differently sized partitions. Signed-off-by: Adrian Schmutzler --- .../ramips/dts/mt7621_xiaomi_mi-router-3g.dts | 105 +---------------- .../ramips/dts/mt7621_xiaomi_nand_128m.dtsi | 109 ++++++++++++++++++ .../dts/mt7621_xiaomi_router-ac2100.dtsi | 86 +------------- 3 files changed, 111 insertions(+), 189 deletions(-) create mode 100644 target/linux/ramips/dts/mt7621_xiaomi_nand_128m.dtsi diff --git a/target/linux/ramips/dts/mt7621_xiaomi_mi-router-3g.dts b/target/linux/ramips/dts/mt7621_xiaomi_mi-router-3g.dts index 479cfc354c..40ea6625d4 100644 --- a/target/linux/ramips/dts/mt7621_xiaomi_mi-router-3g.dts +++ b/target/linux/ramips/dts/mt7621_xiaomi_mi-router-3g.dts @@ -1,7 +1,4 @@ -#include "mt7621.dtsi" - -#include -#include +#include "mt7621_xiaomi_nand_128m.dtsi" / { compatible = "xiaomi,mi-router-3g", "mediatek,mt7621-soc"; @@ -15,10 +12,6 @@ label-mac-device = &gmac0; }; - chosen { - bootargs = "console=ttyS0,115200n8"; - }; - leds { compatible = "gpio-leds"; @@ -56,16 +49,6 @@ }; }; - keys { - compatible = "gpio-keys"; - - reset { - label = "reset"; - gpios = <&gpio 18 GPIO_ACTIVE_LOW>; - linux,code = ; - }; - }; - reg_usb_vbus: regulator { compatible = "regulator-fixed"; regulator-name = "usb_vbus"; @@ -80,92 +63,6 @@ vbus-supply = <®_usb_vbus>; }; -&nand { - status = "okay"; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - partition@0 { - label = "Bootloader"; - reg = <0x0 0x80000>; - read-only; - }; - - partition@80000 { - label = "Config"; - reg = <0x80000 0x40000>; - }; - - partition@c0000 { - label = "Bdata"; - reg = <0xc0000 0x40000>; - read-only; - }; - - factory: partition@100000 { - label = "factory"; - reg = <0x100000 0x40000>; - read-only; - }; - - partition@140000 { - label = "crash"; - reg = <0x140000 0x40000>; - }; - - partition@180000 { - label = "crash_syslog"; - reg = <0x180000 0x40000>; - }; - - partition@1c0000 { - label = "reserved0"; - reg = <0x1c0000 0x40000>; - read-only; - }; - - /* uboot expects to find kernels at 0x200000 & 0x600000 - * referred to as system 1 & system 2 respectively. - * a kernel is considered suitable for handing control over - * if its linux magic number exists & uImage CRC are correct. - * If either of those conditions fail, a matching sys'n'_fail flag - * is set in uboot env & a restart performed in the hope that the - * alternate kernel is okay. - * if neither kernel checksums ok and both are marked failed, system 2 - * is booted anyway. - * - * Note uboot's tftp flash install writes the transferred - * image to both kernel partitions. - */ - - partition@200000 { - label = "kernel_stock"; - reg = <0x200000 0x400000>; - }; - - partition@600000 { - label = "kernel"; - reg = <0x600000 0x400000>; - }; - - /* ubi partition is the result of squashing - * next consecutive stock partitions: - * - rootfs0 (rootfs partition for stock kernel0), - * - rootfs1 (rootfs partition for stock failsafe kernel1), - * - overlay (used as ubi overlay in stock fw) - * resulting 117,5MiB space for packages. - */ - - partition@a00000 { - label = "ubi"; - reg = <0xa00000 0x7580000>; - }; - }; -}; - &pcie { status = "okay"; }; diff --git a/target/linux/ramips/dts/mt7621_xiaomi_nand_128m.dtsi b/target/linux/ramips/dts/mt7621_xiaomi_nand_128m.dtsi new file mode 100644 index 0000000000..12e6bccc2e --- /dev/null +++ b/target/linux/ramips/dts/mt7621_xiaomi_nand_128m.dtsi @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "mt7621.dtsi" + +#include +#include + +/ { + chosen { + bootargs = "console=ttyS0,115200n8"; + }; + + keys: keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + gpios = <&gpio 18 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; +}; + +&nand { + status = "okay"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "Bootloader"; + reg = <0x0 0x80000>; + read-only; + }; + + partition@80000 { + label = "Config"; + reg = <0x80000 0x40000>; + }; + + partition@c0000 { + label = "Bdata"; + reg = <0xc0000 0x40000>; + read-only; + }; + + factory: partition@100000 { + label = "factory"; + reg = <0x100000 0x40000>; + read-only; + }; + + partition@140000 { + label = "crash"; + reg = <0x140000 0x40000>; + }; + + partition@180000 { + label = "crash_syslog"; + reg = <0x180000 0x40000>; + }; + + partition@1c0000 { + label = "reserved0"; + reg = <0x1c0000 0x40000>; + read-only; + }; + + /* uboot expects to find kernels at 0x200000 & 0x600000 + * referred to as system 1 & system 2 respectively. + * a kernel is considered suitable for handing control over + * if its linux magic number exists & uImage CRC are correct. + * If either of those conditions fail, a matching sys'n'_fail flag + * is set in uboot env & a restart performed in the hope that the + * alternate kernel is okay. + * if neither kernel checksums ok and both are marked failed, system 2 + * is booted anyway. + * + * Note uboot's tftp flash install writes the transferred + * image to both kernel partitions. + */ + + /* We keep stock xiaomi firmware (kernel0) here */ + partition@200000 { + label = "kernel_stock"; + reg = <0x200000 0x400000>; + }; + + partition@600000 { + label = "kernel"; + reg = <0x600000 0x400000>; + }; + + /* ubi partition is the result of squashing + * next consecutive stock partitions: + * - rootfs0 (rootfs partition for stock kernel0), + * - rootfs1 (rootfs partition for stock failsafe kernel1), + * - overlay (used as ubi overlay in stock fw) + * resulting 117,5MiB space for packages. + */ + + partition@a00000 { + label = "ubi"; + reg = <0xa00000 0x7580000>; + }; + }; +}; diff --git a/target/linux/ramips/dts/mt7621_xiaomi_router-ac2100.dtsi b/target/linux/ramips/dts/mt7621_xiaomi_router-ac2100.dtsi index 8241517c73..7e6b3afcdf 100644 --- a/target/linux/ramips/dts/mt7621_xiaomi_router-ac2100.dtsi +++ b/target/linux/ramips/dts/mt7621_xiaomi_router-ac2100.dtsi @@ -1,90 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later OR MIT -#include "mt7621.dtsi" - -#include -#include - -/ { - chosen { - bootargs = "console=ttyS0,115200n8"; - }; - - keys { - compatible = "gpio-keys"; - - reset { - label = "reset"; - gpios = <&gpio 18 GPIO_ACTIVE_LOW>; - linux,code = ; - }; - }; -}; - -&nand { - status = "okay"; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - partition@0 { - label = "Bootloader"; - reg = <0x0 0x80000>; - read-only; - }; - - partition@80000 { - label = "Config"; - reg = <0x80000 0x40000>; - }; - - partition@c0000 { - label = "Bdata"; - reg = <0xc0000 0x40000>; - read-only; - }; - - factory: partition@100000 { - label = "factory"; - reg = <0x100000 0x40000>; - read-only; - }; - - partition@140000 { - label = "crash"; - reg = <0x140000 0x40000>; - }; - - partition@180000 { - label = "crash_syslog"; - reg = <0x180000 0x40000>; - }; - - partition@1c0000 { - label = "reserved0"; - reg = <0x1c0000 0x40000>; - read-only; - }; - - /* We keep stock xiaomi firmware (kernel0) here */ - partition@200000 { - label = "kernel_stock"; - reg = <0x200000 0x400000>; - }; - - partition@600000 { - label = "kernel"; - reg = <0x600000 0x400000>; - }; - - partition@a00000 { - label = "ubi"; - reg = <0xa00000 0x7580000>; - }; - }; -}; +#include "mt7621_xiaomi_nand_128m.dtsi" &pcie { status = "okay"; From c2a7bb520a0fb107984ad3757174d391796cd222 Mon Sep 17 00:00:00 2001 From: Dmytro Oz Date: Mon, 14 Dec 2020 21:07:32 +0200 Subject: [PATCH 13/34] ramips: mt7621: add support for Xiaomi Mi Router 4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xiaomi Mi Router 4 is the same as Xiaomi Mi Router 3G, except for the RAM (256Mib→128Mib), LEDs and gpio (MiNet button). Specifications: Power: 12 VDC, 1 A Connector type: barrel CPU1: MediaTek MT7621A (880 MHz, 4 cores) FLA1: 128 MiB (ESMT F59L1G81MA) RAM1: 128 MiB (ESMT M15T1G1664A) WI1 chip1: MediaTek MT7603EN WI1 802dot11 protocols: bgn WI1 MIMO config: 2x2:2 WI1 antenna connector: U.FL WI2 chip1: MediaTek MT7612EN WI2 802dot11 protocols: an+ac WI2 MIMO config: 2x2:2 WI2 antenna connector: U.FL ETH chip1: MediaTek MT7621A Switch: MediaTek MT7621A UART Serial [o] TX [o] GND [o] RX [ ] VCC - Do not connect it MAC addresses as verified by OEM firmware: use address source LAN *:c2 factory 0xe000 (label) WAN *:c3 factory 0xe006 2g *:c4 factory 0x0000 5g *:c5 factory 0x8000 Flashing instructions: 1.Create a simple http server (nginx etc) 2.set uart enable To enable writing to the console, you must reset to factory settings Then you see uboot boot, press the keyboard 4 button (enter uboot command line) If it is not successful, repeat the above operation of restoring the factory settings. After entering the uboot command line, type: setenv uart_en 1 saveenv boot 3.use shell in uart cd /tmp wget http://"your_computer_ip:80"/openwrt-ramips-mt7621-xiaomi_mir4-squashfs-kernel1.bin wget http://"your_computer_ip:80"/openwrt-ramips-mt7621-xiaomi_mir4-squashfs-rootfs0.bin mtd write openwrt-ramips-mt7621-xiaomi_mir4-squashfs-kernel1.bin kernel1 mtd write openwrt-ramips-mt7621-xiaomi_mir4-squashfs-rootfs0.bin rootfs0 nvram set flag_try_sys1_failed=1 nvram commit reboot 4.login to the router http://192.168.1.1/ Installation via Software exploit Find the instructions in the https://github.com/acecilia/OpenWRTInvasion Signed-off-by: Dmytro Oz [commit message facelift, rebase onto shared DTSI/common device definition, bump uboot-envtools] Signed-off-by: Adrian Schmutzler --- package/boot/uboot-envtools/files/ramips | 1 + .../ramips/dts/mt7621_xiaomi_mi-router-4.dts | 96 +++++++++++++++++++ target/linux/ramips/image/mt7621.mk | 8 ++ .../mt7621/base-files/etc/board.d/02_network | 1 + .../mt7621/base-files/lib/upgrade/platform.sh | 1 + 5 files changed, 107 insertions(+) create mode 100644 target/linux/ramips/dts/mt7621_xiaomi_mi-router-4.dts diff --git a/package/boot/uboot-envtools/files/ramips b/package/boot/uboot-envtools/files/ramips index 0568f1fa69..597c8f6ca6 100644 --- a/package/boot/uboot-envtools/files/ramips +++ b/package/boot/uboot-envtools/files/ramips @@ -48,6 +48,7 @@ linksys,ea7300-v2|\ linksys,ea7500-v2|\ xiaomi,mi-router-3g|\ xiaomi,mi-router-3-pro|\ +xiaomi,mi-router-4|\ xiaomi,mi-router-ac2100|\ xiaomi,redmi-router-ac2100) ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x1000" "0x20000" diff --git a/target/linux/ramips/dts/mt7621_xiaomi_mi-router-4.dts b/target/linux/ramips/dts/mt7621_xiaomi_mi-router-4.dts new file mode 100644 index 0000000000..f8fc01ee30 --- /dev/null +++ b/target/linux/ramips/dts/mt7621_xiaomi_mi-router-4.dts @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "mt7621_xiaomi_nand_128m.dtsi" + +/ { + compatible = "xiaomi,mi-router-4", "mediatek,mt7621-soc"; + model = "Xiaomi Mi Router 4"; + + aliases { + led-boot = &led_status_yellow; + led-failsafe = &led_status_red; + led-running = &led_status_blue; + led-upgrade = &led_status_yellow; + label-mac-device = &gmac0; + }; + + leds { + compatible = "gpio-leds"; + + led_status_red: status_red { + label = "red:status"; + gpios = <&gpio 6 GPIO_ACTIVE_LOW>; + }; + + led_status_blue: status_blue { + label = "blue:status"; + gpios = <&gpio 8 GPIO_ACTIVE_LOW>; + }; + + led_status_yellow: status_yellow { + label = "yellow:status"; + gpios = <&gpio 10 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&keys { + minet { + label = "minet"; + gpios = <&gpio 12 GPIO_ACTIVE_LOW>; + linux,code = ; + }; +}; + +&pcie { + status = "okay"; +}; + +&pcie0 { + wifi@0,0 { + compatible = "pci14c3,7603"; + reg = <0x0000 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x0000>; + ieee80211-freq-limit = <2400000 2500000>; + }; +}; + +&pcie1 { + wifi@0,0 { + compatible = "pci14c3,7662"; + reg = <0x0000 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x8000>; + ieee80211-freq-limit = <5000000 6000000>; + }; +}; + +&gmac0 { + mtd-mac-address = <&factory 0xe000>; +}; + +&switch0 { + ports { + port@1 { + status = "okay"; + label = "lan1"; + }; + + port@2 { + status = "okay"; + label = "lan2"; + }; + + port@4 { + status = "okay"; + label = "wan"; + mtd-mac-address = <&factory 0xe006>; + }; + }; +}; + +&state_default { + gpio { + groups = "jtag", "uart2", "uart3", "wdt"; + function = "gpio"; + }; +}; diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk index ff39cbf39a..005a9bdc55 100644 --- a/target/linux/ramips/image/mt7621.mk +++ b/target/linux/ramips/image/mt7621.mk @@ -1277,6 +1277,14 @@ define Device/xiaomi_mi-router-3-pro endef TARGET_DEVICES += xiaomi_mi-router-3-pro +define Device/xiaomi_mi-router-4 + $(Device/xiaomi_nand_separate) + DEVICE_MODEL := Mi Router 4 + IMAGE_SIZE := 124416k + DEVICE_PACKAGES += kmod-mt7603 kmod-mt76x2 +endef +TARGET_DEVICES += xiaomi_mi-router-4 + define Device/xiaomi_mi-router-4a-gigabit $(Device/dsa-migration) $(Device/uimage-lzma-loader) diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/02_network b/target/linux/ramips/mt7621/base-files/etc/board.d/02_network index 83c4162e2f..154f218bfe 100755 --- a/target/linux/ramips/mt7621/base-files/etc/board.d/02_network +++ b/target/linux/ramips/mt7621/base-files/etc/board.d/02_network @@ -19,6 +19,7 @@ ramips_setup_interfaces() mikrotik,routerboard-m33g|\ xiaomi,mi-router-3g|\ xiaomi,mi-router-3g-v2|\ + xiaomi,mi-router-4|\ xiaomi,mi-router-4a-gigabit) ucidef_set_interfaces_lan_wan "lan1 lan2" "wan" ;; diff --git a/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh b/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh index 99ed36e429..5bb0386253 100755 --- a/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh +++ b/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh @@ -63,6 +63,7 @@ platform_do_upgrade() { netis,wf2881|\ xiaomi,mi-router-3g|\ xiaomi,mi-router-3-pro|\ + xiaomi,mi-router-4|\ xiaomi,mi-router-ac2100|\ xiaomi,redmi-router-ac2100) nand_do_upgrade "$1" From b3eccbca7c476c967af8e56c73061df2893ded7d Mon Sep 17 00:00:00 2001 From: Adrian Schmutzler Date: Thu, 21 Jan 2021 22:56:43 +0100 Subject: [PATCH 14/34] ramips: fix port labels for Xiaomi Mi Router 4 The OEM assignment of LAN ports is swapped. Fixes: c2a7bb520a0f ("ramips: mt7621: add support for Xiaomi Mi Router 4") Signed-off-by: Adrian Schmutzler --- target/linux/ramips/dts/mt7621_xiaomi_mi-router-4.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/linux/ramips/dts/mt7621_xiaomi_mi-router-4.dts b/target/linux/ramips/dts/mt7621_xiaomi_mi-router-4.dts index f8fc01ee30..18cbe0c013 100644 --- a/target/linux/ramips/dts/mt7621_xiaomi_mi-router-4.dts +++ b/target/linux/ramips/dts/mt7621_xiaomi_mi-router-4.dts @@ -72,12 +72,12 @@ ports { port@1 { status = "okay"; - label = "lan1"; + label = "lan2"; }; port@2 { status = "okay"; - label = "lan2"; + label = "lan1"; }; port@4 { From 2d8422842c7b2ca91956d9629f41083f99f12eac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Fri, 22 Jan 2021 11:10:12 +0100 Subject: [PATCH 15/34] bcm63xx: nand: fix OOB R/W for non Hamming ECC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hamming ECC devices do not cover OOB data, as opposed to BCH ECC devices. Therefore, disabling ECC for all devices is preventing BCH devices from correctly reading and writing the OOB data. Signed-off-by: Álvaro Fernández Rojas --- ...rcmnand-fix-OOB-R-W-with-Hamming-ECC.patch | 34 +++++++++++++++++++ ...te_oob_raw-for-MTD_OPS_AUTO_OOB-mode.patch | 11 ------ 2 files changed, 34 insertions(+), 11 deletions(-) create mode 100644 target/linux/bcm63xx/patches-5.4/434-nand-brcmnand-fix-OOB-R-W-with-Hamming-ECC.patch delete mode 100644 target/linux/bcm63xx/patches-5.4/434-nand-raw-use-write_oob_raw-for-MTD_OPS_AUTO_OOB-mode.patch diff --git a/target/linux/bcm63xx/patches-5.4/434-nand-brcmnand-fix-OOB-R-W-with-Hamming-ECC.patch b/target/linux/bcm63xx/patches-5.4/434-nand-brcmnand-fix-OOB-R-W-with-Hamming-ECC.patch new file mode 100644 index 0000000000..c3bb1ae1e8 --- /dev/null +++ b/target/linux/bcm63xx/patches-5.4/434-nand-brcmnand-fix-OOB-R-W-with-Hamming-ECC.patch @@ -0,0 +1,34 @@ +From cf0d2fbaae9e962d91a321de75e0d4f9f9ccbdfe Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= +Date: Thu, 21 Jan 2021 18:17:37 +0100 +Subject: [PATCH] nand: brcmnand: fix OOB R/W with Hamming ECC +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Hamming ECC doesn't cover the OOB data, so reading or writing OOB shall +always be done without ECC enabled. +This is a problem when adding JFFS2 cleanmarkers to erased blocks. When JFFS2 +clenmarkers are added to the OOB with ECC enabled, OOB bytes will be changed +from ff ff ff to 00 00 00, reporting incorrect ECC errors. + +Signed-off-by: Álvaro Fernández Rojas +--- + drivers/mtd/nand/raw/brcmnand/brcmnand.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +@@ -2426,6 +2426,12 @@ static int brcmnand_attach_chip(struct n + + ret = brcmstb_choose_ecc_layout(host); + ++ /* If OOB is written with ECC enabled it will cause ECC errors */ ++ if (is_hamming_ecc(host->ctrl, &host->hwcfg)) { ++ chip->ecc.write_oob = brcmnand_write_oob_raw; ++ chip->ecc.read_oob = brcmnand_read_oob_raw; ++ } ++ + return ret; + } + diff --git a/target/linux/bcm63xx/patches-5.4/434-nand-raw-use-write_oob_raw-for-MTD_OPS_AUTO_OOB-mode.patch b/target/linux/bcm63xx/patches-5.4/434-nand-raw-use-write_oob_raw-for-MTD_OPS_AUTO_OOB-mode.patch deleted file mode 100644 index cf4322f29f..0000000000 --- a/target/linux/bcm63xx/patches-5.4/434-nand-raw-use-write_oob_raw-for-MTD_OPS_AUTO_OOB-mode.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/drivers/mtd/nand/raw/nand_base.c -+++ b/drivers/mtd/nand/raw/nand_base.c -@@ -488,7 +488,7 @@ static int nand_do_write_oob(struct nand - - nand_fill_oob(chip, ops->oobbuf, ops->ooblen, ops); - -- if (ops->mode == MTD_OPS_RAW) -+ if (ops->mode == MTD_OPS_AUTO_OOB || ops->mode == MTD_OPS_RAW) - status = chip->ecc.write_oob_raw(chip, page & chip->pagemask); - else - status = chip->ecc.write_oob(chip, page & chip->pagemask); From 1d6f422e346ba1f39165577ffbe2ad15b944171c Mon Sep 17 00:00:00 2001 From: Sieng Piaw Liew Date: Tue, 12 Jan 2021 10:35:55 +0800 Subject: [PATCH 16/34] bcm63xx: sync ethernet driver with net-next MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sync ethernet driver code with upstream Linux kernel: -Reduce xmit_more code changes. -Combine rx cleanup code into a function. -Convert to build_skb. -Improve rx loop by optimizing loop tracking. https://lore.kernel.org/netdev/20210106144208.1935-1-liew.s.piaw@gmail.com/ Signed-off-by: Sieng Piaw Liew [Amend commit description, move patches to the top since they are going to be upstreamed] Signed-off-by: Álvaro Fernández Rojas --- ...-bcm63xx_enet-batch-process-rx-path.patch} | 30 +- ...1-v5.12-bcm63xx_enet-add-BQL-support.patch | 68 ++++ ...2-bcm63xx_enet-add-xmit_more-support.patch | 26 ++ ..._enet-alloc-rx-skb-with-NET_IP_ALIGN.patch | 45 +++ ...consolidate-rx-SKB-ring-cleanup-code.patch | 142 +++++++ ...12-bcm63xx_enet-convert-to-build_skb.patch | 347 ++++++++++++++++++ ...6-v5.12-bcm63xx_enet-improve-rx-loop.patch | 40 ++ ...402_bcm63xx_enet_vlan_incoming_fixed.patch | 2 +- ...-move-phy_-dis-connect-into-probe-re.patch | 22 +- ...enable-rgmii-clock-on-external-ports.patch | 2 +- .../423-bcm63xx_enet_add_b53_support.patch | 10 +- .../428-bcm63xx_enet-rgmii-ctrl-fix.patch | 2 +- ...1-bcm63xx_enet-alloc_rx_skb_ip_align.patch | 37 -- .../442-bcm63xx_enet-add_bql_support.patch | 67 ---- ...cm63xx_enet-support_xmit_more_in_bql.patch | 54 --- 15 files changed, 703 insertions(+), 191 deletions(-) rename target/linux/bcm63xx/patches-5.4/{440-bcm63xx_enet-batch_process_RX_path.patch => 040-v5.12-bcm63xx_enet-batch-process-rx-path.patch} (70%) create mode 100644 target/linux/bcm63xx/patches-5.4/041-v5.12-bcm63xx_enet-add-BQL-support.patch create mode 100644 target/linux/bcm63xx/patches-5.4/042-v5.12-bcm63xx_enet-add-xmit_more-support.patch create mode 100644 target/linux/bcm63xx/patches-5.4/043-v5.12-bcm63xx_enet-alloc-rx-skb-with-NET_IP_ALIGN.patch create mode 100644 target/linux/bcm63xx/patches-5.4/044-v5.12-bcm63xx_enet-consolidate-rx-SKB-ring-cleanup-code.patch create mode 100644 target/linux/bcm63xx/patches-5.4/045-v5.12-bcm63xx_enet-convert-to-build_skb.patch create mode 100644 target/linux/bcm63xx/patches-5.4/046-v5.12-bcm63xx_enet-improve-rx-loop.patch delete mode 100644 target/linux/bcm63xx/patches-5.4/441-bcm63xx_enet-alloc_rx_skb_ip_align.patch delete mode 100644 target/linux/bcm63xx/patches-5.4/442-bcm63xx_enet-add_bql_support.patch delete mode 100644 target/linux/bcm63xx/patches-5.4/443-bcm63xx_enet-support_xmit_more_in_bql.patch diff --git a/target/linux/bcm63xx/patches-5.4/440-bcm63xx_enet-batch_process_RX_path.patch b/target/linux/bcm63xx/patches-5.4/040-v5.12-bcm63xx_enet-batch-process-rx-path.patch similarity index 70% rename from target/linux/bcm63xx/patches-5.4/440-bcm63xx_enet-batch_process_RX_path.patch rename to target/linux/bcm63xx/patches-5.4/040-v5.12-bcm63xx_enet-batch-process-rx-path.patch index 0a22d8c651..ab1a4a91e1 100644 --- a/target/linux/bcm63xx/patches-5.4/440-bcm63xx_enet-batch_process_RX_path.patch +++ b/target/linux/bcm63xx/patches-5.4/040-v5.12-bcm63xx_enet-batch-process-rx-path.patch @@ -1,43 +1,45 @@ -From 1606f78dc82e4f311ca5844a0605a62cd141a072 Mon Sep 17 00:00:00 2001 +From 9cbfea02c1dbee0afb9128f065e6e793672b9ff7 Mon Sep 17 00:00:00 2001 From: Sieng Piaw Liew -Date: Mon, 30 Nov 2020 11:07:47 +0800 -Subject: [PATCH] bcm63xx: batch process RX path +Date: Wed, 6 Jan 2021 22:42:02 +0800 +Subject: [PATCH 1/7] bcm63xx_enet: batch process rx path -Use netif_receive_skb_list to batch process skb in RX. +Use netif_receive_skb_list to batch process rx skb. Tested on BCM6328 320 MHz using iperf3 -M 512, increasing performance by 12.5%. Before: [ ID] Interval Transfer Bandwidth Retr -[ 4] 0.00-30.00 sec 120 MBytes 33.7 Mbits/sec 277 sender -[ 4] 0.00-30.00 sec 120 MBytes 33.5 Mbits/sec receiver +[ 4] 0.00-30.00 sec 120 MBytes 33.7 Mbits/sec 277 sender +[ 4] 0.00-30.00 sec 120 MBytes 33.5 Mbits/sec receiver After: [ ID] Interval Transfer Bandwidth Retr -[ 4] 0.00-30.00 sec 136 MBytes 37.9 Mbits/sec 203 sender -[ 4] 0.00-30.00 sec 135 MBytes 37.7 Mbits/sec receiver +[ 4] 0.00-30.00 sec 136 MBytes 37.9 Mbits/sec 203 sender +[ 4] 0.00-30.00 sec 135 MBytes 37.7 Mbits/sec receiver Signed-off-by: Sieng Piaw Liew +Acked-by: Florian Fainelli +Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/broadcom/bcm63xx_enet.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c -@@ -301,10 +301,12 @@ static int bcm_enet_receive_queue(struct +@@ -298,10 +298,12 @@ static void bcm_enet_refill_rx_timer(str + static int bcm_enet_receive_queue(struct net_device *dev, int budget) + { struct bcm_enet_priv *priv; ++ struct list_head rx_list; struct device *kdev; int processed; -+ struct list_head rx_list; priv = netdev_priv(dev); ++ INIT_LIST_HEAD(&rx_list); kdev = &priv->pdev->dev; processed = 0; -+ INIT_LIST_HEAD(&rx_list); - /* don't scan ring further than number of refilled - * descriptor */ -@@ -393,10 +395,12 @@ static int bcm_enet_receive_queue(struct +@@ -392,10 +394,12 @@ static int bcm_enet_receive_queue(struct skb->protocol = eth_type_trans(skb, dev); dev->stats.rx_packets++; dev->stats.rx_bytes += len; diff --git a/target/linux/bcm63xx/patches-5.4/041-v5.12-bcm63xx_enet-add-BQL-support.patch b/target/linux/bcm63xx/patches-5.4/041-v5.12-bcm63xx_enet-add-BQL-support.patch new file mode 100644 index 0000000000..f55aa8fe17 --- /dev/null +++ b/target/linux/bcm63xx/patches-5.4/041-v5.12-bcm63xx_enet-add-BQL-support.patch @@ -0,0 +1,68 @@ +From 4c59b0f5543db80abbbe9efdd9b25e7899501db5 Mon Sep 17 00:00:00 2001 +From: Sieng Piaw Liew +Date: Wed, 6 Jan 2021 22:42:03 +0800 +Subject: [PATCH 2/7] bcm63xx_enet: add BQL support + +Add Byte Queue Limits support to reduce/remove bufferbloat in +bcm63xx_enet. + +Signed-off-by: Sieng Piaw Liew +Acked-by: Florian Fainelli +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -418,9 +418,11 @@ static int bcm_enet_receive_queue(struct + static int bcm_enet_tx_reclaim(struct net_device *dev, int force) + { + struct bcm_enet_priv *priv; ++ unsigned int bytes; + int released; + + priv = netdev_priv(dev); ++ bytes = 0; + released = 0; + + while (priv->tx_desc_count < priv->tx_ring_size) { +@@ -457,10 +459,13 @@ static int bcm_enet_tx_reclaim(struct ne + if (desc->len_stat & DMADESC_UNDER_MASK) + dev->stats.tx_errors++; + ++ bytes += skb->len; + dev_kfree_skb(skb); + released++; + } + ++ netdev_completed_queue(dev, released, bytes); ++ + if (netif_queue_stopped(dev) && released) + netif_wake_queue(dev); + +@@ -627,6 +632,8 @@ bcm_enet_start_xmit(struct sk_buff *skb, + desc->len_stat = len_stat; + wmb(); + ++ netdev_sent_queue(dev, skb->len); ++ + /* kick tx dma */ + enet_dmac_writel(priv, priv->dma_chan_en_mask, + ENETDMAC_CHANCFG, priv->tx_chan); +@@ -1170,6 +1177,7 @@ static int bcm_enet_stop(struct net_devi + kdev = &priv->pdev->dev; + + netif_stop_queue(dev); ++ netdev_reset_queue(dev); + napi_disable(&priv->napi); + if (priv->has_phy) + phy_stop(dev->phydev); +@@ -2343,6 +2351,7 @@ static int bcm_enetsw_stop(struct net_de + + del_timer_sync(&priv->swphy_poll); + netif_stop_queue(dev); ++ netdev_reset_queue(dev); + napi_disable(&priv->napi); + del_timer_sync(&priv->rx_timeout); + diff --git a/target/linux/bcm63xx/patches-5.4/042-v5.12-bcm63xx_enet-add-xmit_more-support.patch b/target/linux/bcm63xx/patches-5.4/042-v5.12-bcm63xx_enet-add-xmit_more-support.patch new file mode 100644 index 0000000000..4b02cd7849 --- /dev/null +++ b/target/linux/bcm63xx/patches-5.4/042-v5.12-bcm63xx_enet-add-xmit_more-support.patch @@ -0,0 +1,26 @@ +From 375281d3a6dcabaa98f489ee412aedca6d99dffb Mon Sep 17 00:00:00 2001 +From: Sieng Piaw Liew +Date: Wed, 6 Jan 2021 22:42:04 +0800 +Subject: [PATCH 3/7] bcm63xx_enet: add xmit_more support + +Support bulking hardware TX queue by using netdev_xmit_more(). + +Signed-off-by: Sieng Piaw Liew +Acked-by: Florian Fainelli +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -635,7 +635,8 @@ bcm_enet_start_xmit(struct sk_buff *skb, + netdev_sent_queue(dev, skb->len); + + /* kick tx dma */ +- enet_dmac_writel(priv, priv->dma_chan_en_mask, ++ if (!netdev_xmit_more() || !priv->tx_desc_count) ++ enet_dmac_writel(priv, priv->dma_chan_en_mask, + ENETDMAC_CHANCFG, priv->tx_chan); + + /* stop queue if no more desc available */ diff --git a/target/linux/bcm63xx/patches-5.4/043-v5.12-bcm63xx_enet-alloc-rx-skb-with-NET_IP_ALIGN.patch b/target/linux/bcm63xx/patches-5.4/043-v5.12-bcm63xx_enet-alloc-rx-skb-with-NET_IP_ALIGN.patch new file mode 100644 index 0000000000..575dcb9ad8 --- /dev/null +++ b/target/linux/bcm63xx/patches-5.4/043-v5.12-bcm63xx_enet-alloc-rx-skb-with-NET_IP_ALIGN.patch @@ -0,0 +1,45 @@ +From c4a207865e7ea310dc146ff4aa1b0aa0c78d3fe1 Mon Sep 17 00:00:00 2001 +From: Sieng Piaw Liew +Date: Wed, 6 Jan 2021 22:42:05 +0800 +Subject: [PATCH 4/7] bcm63xx_enet: alloc rx skb with NET_IP_ALIGN + +Use netdev_alloc_skb_ip_align on newer SoCs with integrated switch +(enetsw) when refilling RX. Increases packet processing performance +by 30% (with netif_receive_skb_list). + +Non-enetsw SoCs cannot function with the extra pad so continue to use +the regular netdev_alloc_skb. + +Tested on BCM6328 320 MHz and iperf3 -M 512 to measure packet/sec +performance. + +Before: +[ ID] Interval Transfer Bandwidth Retr +[ 4] 0.00-30.00 sec 120 MBytes 33.7 Mbits/sec 277 sender +[ 4] 0.00-30.00 sec 120 MBytes 33.5 Mbits/sec receiver + +After (+netif_receive_skb_list): +[ 4] 0.00-30.00 sec 155 MBytes 43.3 Mbits/sec 354 sender +[ 4] 0.00-30.00 sec 154 MBytes 43.1 Mbits/sec receiver + +Signed-off-by: Sieng Piaw Liew +Acked-by: Florian Fainelli +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -238,7 +238,10 @@ static int bcm_enet_refill_rx(struct net + desc = &priv->rx_desc_cpu[desc_idx]; + + if (!priv->rx_skb[desc_idx]) { +- skb = netdev_alloc_skb(dev, priv->rx_skb_size); ++ if (priv->enet_is_sw) ++ skb = netdev_alloc_skb_ip_align(dev, priv->rx_skb_size); ++ else ++ skb = netdev_alloc_skb(dev, priv->rx_skb_size); + if (!skb) + break; + priv->rx_skb[desc_idx] = skb; diff --git a/target/linux/bcm63xx/patches-5.4/044-v5.12-bcm63xx_enet-consolidate-rx-SKB-ring-cleanup-code.patch b/target/linux/bcm63xx/patches-5.4/044-v5.12-bcm63xx_enet-consolidate-rx-SKB-ring-cleanup-code.patch new file mode 100644 index 0000000000..0976252673 --- /dev/null +++ b/target/linux/bcm63xx/patches-5.4/044-v5.12-bcm63xx_enet-consolidate-rx-SKB-ring-cleanup-code.patch @@ -0,0 +1,142 @@ +From 3d0b72654b0c8304424503e7560ee8635dd56340 Mon Sep 17 00:00:00 2001 +From: Sieng Piaw Liew +Date: Wed, 6 Jan 2021 22:42:06 +0800 +Subject: [PATCH 5/7] bcm63xx_enet: consolidate rx SKB ring cleanup code + +The rx SKB ring use the same code for cleanup at various points. +Combine them into a function to reduce lines of code. + +Signed-off-by: Sieng Piaw Liew +Acked-by: Florian Fainelli +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 72 ++++++-------------- + 1 file changed, 22 insertions(+), 50 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -861,6 +861,24 @@ static void bcm_enet_adjust_link(struct + priv->pause_tx ? "tx" : "off"); + } + ++static void bcm_enet_free_rx_skb_ring(struct device *kdev, struct bcm_enet_priv *priv) ++{ ++ int i; ++ ++ for (i = 0; i < priv->rx_ring_size; i++) { ++ struct bcm_enet_desc *desc; ++ ++ if (!priv->rx_skb[i]) ++ continue; ++ ++ desc = &priv->rx_desc_cpu[i]; ++ dma_unmap_single(kdev, desc->address, priv->rx_skb_size, ++ DMA_FROM_DEVICE); ++ kfree_skb(priv->rx_skb[i]); ++ } ++ kfree(priv->rx_skb); ++} ++ + /* + * open callback, allocate dma rings & buffers and start rx operation + */ +@@ -1085,18 +1103,7 @@ static int bcm_enet_open(struct net_devi + return 0; + + out: +- for (i = 0; i < priv->rx_ring_size; i++) { +- struct bcm_enet_desc *desc; +- +- if (!priv->rx_skb[i]) +- continue; +- +- desc = &priv->rx_desc_cpu[i]; +- dma_unmap_single(kdev, desc->address, priv->rx_skb_size, +- DMA_FROM_DEVICE); +- kfree_skb(priv->rx_skb[i]); +- } +- kfree(priv->rx_skb); ++ bcm_enet_free_rx_skb_ring(kdev, priv); + + out_free_tx_skb: + kfree(priv->tx_skb); +@@ -1175,7 +1182,6 @@ static int bcm_enet_stop(struct net_devi + { + struct bcm_enet_priv *priv; + struct device *kdev; +- int i; + + priv = netdev_priv(dev); + kdev = &priv->pdev->dev; +@@ -1204,20 +1210,9 @@ static int bcm_enet_stop(struct net_devi + bcm_enet_tx_reclaim(dev, 1); + + /* free the rx skb ring */ +- for (i = 0; i < priv->rx_ring_size; i++) { +- struct bcm_enet_desc *desc; +- +- if (!priv->rx_skb[i]) +- continue; +- +- desc = &priv->rx_desc_cpu[i]; +- dma_unmap_single(kdev, desc->address, priv->rx_skb_size, +- DMA_FROM_DEVICE); +- kfree_skb(priv->rx_skb[i]); +- } ++ bcm_enet_free_rx_skb_ring(kdev, priv); + + /* free remaining allocated memory */ +- kfree(priv->rx_skb); + kfree(priv->tx_skb); + dma_free_coherent(kdev, priv->rx_desc_alloc_size, + priv->rx_desc_cpu, priv->rx_desc_dma); +@@ -2308,18 +2303,7 @@ static int bcm_enetsw_open(struct net_de + return 0; + + out: +- for (i = 0; i < priv->rx_ring_size; i++) { +- struct bcm_enet_desc *desc; +- +- if (!priv->rx_skb[i]) +- continue; +- +- desc = &priv->rx_desc_cpu[i]; +- dma_unmap_single(kdev, desc->address, priv->rx_skb_size, +- DMA_FROM_DEVICE); +- kfree_skb(priv->rx_skb[i]); +- } +- kfree(priv->rx_skb); ++ bcm_enet_free_rx_skb_ring(kdev, priv); + + out_free_tx_skb: + kfree(priv->tx_skb); +@@ -2348,7 +2332,6 @@ static int bcm_enetsw_stop(struct net_de + { + struct bcm_enet_priv *priv; + struct device *kdev; +- int i; + + priv = netdev_priv(dev); + kdev = &priv->pdev->dev; +@@ -2371,20 +2354,9 @@ static int bcm_enetsw_stop(struct net_de + bcm_enet_tx_reclaim(dev, 1); + + /* free the rx skb ring */ +- for (i = 0; i < priv->rx_ring_size; i++) { +- struct bcm_enet_desc *desc; +- +- if (!priv->rx_skb[i]) +- continue; +- +- desc = &priv->rx_desc_cpu[i]; +- dma_unmap_single(kdev, desc->address, priv->rx_skb_size, +- DMA_FROM_DEVICE); +- kfree_skb(priv->rx_skb[i]); +- } ++ bcm_enet_free_rx_skb_ring(kdev, priv); + + /* free remaining allocated memory */ +- kfree(priv->rx_skb); + kfree(priv->tx_skb); + dma_free_coherent(kdev, priv->rx_desc_alloc_size, + priv->rx_desc_cpu, priv->rx_desc_dma); diff --git a/target/linux/bcm63xx/patches-5.4/045-v5.12-bcm63xx_enet-convert-to-build_skb.patch b/target/linux/bcm63xx/patches-5.4/045-v5.12-bcm63xx_enet-convert-to-build_skb.patch new file mode 100644 index 0000000000..80d44ec981 --- /dev/null +++ b/target/linux/bcm63xx/patches-5.4/045-v5.12-bcm63xx_enet-convert-to-build_skb.patch @@ -0,0 +1,347 @@ +From d27de0ef5ef995df2cc5f5c006c0efcf0a62b6af Mon Sep 17 00:00:00 2001 +From: Sieng Piaw Liew +Date: Wed, 6 Jan 2021 22:42:07 +0800 +Subject: [PATCH 6/7] bcm63xx_enet: convert to build_skb + +We can increase the efficiency of rx path by using buffers to receive +packets then build SKBs around them just before passing into the network +stack. In contrast, preallocating SKBs too early reduces CPU cache +efficiency. + +Check if we're in NAPI context when refilling RX. Normally we're almost +always running in NAPI context. Dispatch to napi_alloc_frag directly +instead of relying on netdev_alloc_frag which does the same but +with the overhead of local_bh_disable/enable. + +Tested on BCM6328 320 MHz and iperf3 -M 512 to measure packet/sec +performance. Included netif_receive_skb_list and NET_IP_ALIGN +optimizations. + +Before: +[ ID] Interval Transfer Bandwidth Retr +[ 4] 0.00-10.00 sec 49.9 MBytes 41.9 Mbits/sec 197 sender +[ 4] 0.00-10.00 sec 49.3 MBytes 41.3 Mbits/sec receiver + +After: +[ ID] Interval Transfer Bandwidth Retr +[ 4] 0.00-30.00 sec 171 MBytes 47.8 Mbits/sec 272 sender +[ 4] 0.00-30.00 sec 170 MBytes 47.6 Mbits/sec receiver + +Signed-off-by: Sieng Piaw Liew +Acked-by: Florian Fainelli +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 111 ++++++++++--------- + drivers/net/ethernet/broadcom/bcm63xx_enet.h | 14 ++- + 2 files changed, 71 insertions(+), 54 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -221,7 +221,7 @@ static void bcm_enet_mdio_write_mii(stru + /* + * refill rx queue + */ +-static int bcm_enet_refill_rx(struct net_device *dev) ++static int bcm_enet_refill_rx(struct net_device *dev, bool napi_mode) + { + struct bcm_enet_priv *priv; + +@@ -229,29 +229,29 @@ static int bcm_enet_refill_rx(struct net + + while (priv->rx_desc_count < priv->rx_ring_size) { + struct bcm_enet_desc *desc; +- struct sk_buff *skb; +- dma_addr_t p; + int desc_idx; + u32 len_stat; + + desc_idx = priv->rx_dirty_desc; + desc = &priv->rx_desc_cpu[desc_idx]; + +- if (!priv->rx_skb[desc_idx]) { +- if (priv->enet_is_sw) +- skb = netdev_alloc_skb_ip_align(dev, priv->rx_skb_size); ++ if (!priv->rx_buf[desc_idx]) { ++ void *buf; ++ ++ if (likely(napi_mode)) ++ buf = napi_alloc_frag(priv->rx_frag_size); + else +- skb = netdev_alloc_skb(dev, priv->rx_skb_size); +- if (!skb) ++ buf = netdev_alloc_frag(priv->rx_frag_size); ++ if (unlikely(!buf)) + break; +- priv->rx_skb[desc_idx] = skb; +- p = dma_map_single(&priv->pdev->dev, skb->data, +- priv->rx_skb_size, +- DMA_FROM_DEVICE); +- desc->address = p; ++ priv->rx_buf[desc_idx] = buf; ++ desc->address = dma_map_single(&priv->pdev->dev, ++ buf + priv->rx_buf_offset, ++ priv->rx_buf_size, ++ DMA_FROM_DEVICE); + } + +- len_stat = priv->rx_skb_size << DMADESC_LENGTH_SHIFT; ++ len_stat = priv->rx_buf_size << DMADESC_LENGTH_SHIFT; + len_stat |= DMADESC_OWNER_MASK; + if (priv->rx_dirty_desc == priv->rx_ring_size - 1) { + len_stat |= (DMADESC_WRAP_MASK >> priv->dma_desc_shift); +@@ -291,7 +291,7 @@ static void bcm_enet_refill_rx_timer(str + struct net_device *dev = priv->net_dev; + + spin_lock(&priv->rx_lock); +- bcm_enet_refill_rx(dev); ++ bcm_enet_refill_rx(dev, false); + spin_unlock(&priv->rx_lock); + } + +@@ -321,6 +321,7 @@ static int bcm_enet_receive_queue(struct + int desc_idx; + u32 len_stat; + unsigned int len; ++ void *buf; + + desc_idx = priv->rx_curr_desc; + desc = &priv->rx_desc_cpu[desc_idx]; +@@ -366,16 +367,14 @@ static int bcm_enet_receive_queue(struct + } + + /* valid packet */ +- skb = priv->rx_skb[desc_idx]; ++ buf = priv->rx_buf[desc_idx]; + len = (len_stat & DMADESC_LENGTH_MASK) >> DMADESC_LENGTH_SHIFT; + /* don't include FCS */ + len -= 4; + + if (len < copybreak) { +- struct sk_buff *nskb; +- +- nskb = napi_alloc_skb(&priv->napi, len); +- if (!nskb) { ++ skb = napi_alloc_skb(&priv->napi, len); ++ if (unlikely(!skb)) { + /* forget packet, just rearm desc */ + dev->stats.rx_dropped++; + continue; +@@ -383,14 +382,21 @@ static int bcm_enet_receive_queue(struct + + dma_sync_single_for_cpu(kdev, desc->address, + len, DMA_FROM_DEVICE); +- memcpy(nskb->data, skb->data, len); ++ memcpy(skb->data, buf + priv->rx_buf_offset, len); + dma_sync_single_for_device(kdev, desc->address, + len, DMA_FROM_DEVICE); +- skb = nskb; + } else { +- dma_unmap_single(&priv->pdev->dev, desc->address, +- priv->rx_skb_size, DMA_FROM_DEVICE); +- priv->rx_skb[desc_idx] = NULL; ++ dma_unmap_single(kdev, desc->address, ++ priv->rx_buf_size, DMA_FROM_DEVICE); ++ priv->rx_buf[desc_idx] = NULL; ++ ++ skb = build_skb(buf, priv->rx_frag_size); ++ if (unlikely(!skb)) { ++ skb_free_frag(buf); ++ dev->stats.rx_dropped++; ++ continue; ++ } ++ skb_reserve(skb, priv->rx_buf_offset); + } + + skb_put(skb, len); +@@ -404,7 +410,7 @@ static int bcm_enet_receive_queue(struct + netif_receive_skb_list(&rx_list); + + if (processed || !priv->rx_desc_count) { +- bcm_enet_refill_rx(dev); ++ bcm_enet_refill_rx(dev, true); + + /* kick rx dma */ + enet_dmac_writel(priv, priv->dma_chan_en_mask, +@@ -861,22 +867,22 @@ static void bcm_enet_adjust_link(struct + priv->pause_tx ? "tx" : "off"); + } + +-static void bcm_enet_free_rx_skb_ring(struct device *kdev, struct bcm_enet_priv *priv) ++static void bcm_enet_free_rx_buf_ring(struct device *kdev, struct bcm_enet_priv *priv) + { + int i; + + for (i = 0; i < priv->rx_ring_size; i++) { + struct bcm_enet_desc *desc; + +- if (!priv->rx_skb[i]) ++ if (!priv->rx_buf[i]) + continue; + + desc = &priv->rx_desc_cpu[i]; +- dma_unmap_single(kdev, desc->address, priv->rx_skb_size, ++ dma_unmap_single(kdev, desc->address, priv->rx_buf_size, + DMA_FROM_DEVICE); +- kfree_skb(priv->rx_skb[i]); ++ skb_free_frag(priv->rx_buf[i]); + } +- kfree(priv->rx_skb); ++ kfree(priv->rx_buf); + } + + /* +@@ -988,10 +994,10 @@ static int bcm_enet_open(struct net_devi + priv->tx_curr_desc = 0; + spin_lock_init(&priv->tx_lock); + +- /* init & fill rx ring with skbs */ +- priv->rx_skb = kcalloc(priv->rx_ring_size, sizeof(struct sk_buff *), ++ /* init & fill rx ring with buffers */ ++ priv->rx_buf = kcalloc(priv->rx_ring_size, sizeof(void *), + GFP_KERNEL); +- if (!priv->rx_skb) { ++ if (!priv->rx_buf) { + ret = -ENOMEM; + goto out_free_tx_skb; + } +@@ -1008,8 +1014,8 @@ static int bcm_enet_open(struct net_devi + enet_dmac_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0, + ENETDMAC_BUFALLOC, priv->rx_chan); + +- if (bcm_enet_refill_rx(dev)) { +- dev_err(kdev, "cannot allocate rx skb queue\n"); ++ if (bcm_enet_refill_rx(dev, false)) { ++ dev_err(kdev, "cannot allocate rx buffer queue\n"); + ret = -ENOMEM; + goto out; + } +@@ -1103,7 +1109,7 @@ static int bcm_enet_open(struct net_devi + return 0; + + out: +- bcm_enet_free_rx_skb_ring(kdev, priv); ++ bcm_enet_free_rx_buf_ring(kdev, priv); + + out_free_tx_skb: + kfree(priv->tx_skb); +@@ -1209,8 +1215,8 @@ static int bcm_enet_stop(struct net_devi + /* force reclaim of all tx buffers */ + bcm_enet_tx_reclaim(dev, 1); + +- /* free the rx skb ring */ +- bcm_enet_free_rx_skb_ring(kdev, priv); ++ /* free the rx buffer ring */ ++ bcm_enet_free_rx_buf_ring(kdev, priv); + + /* free remaining allocated memory */ + kfree(priv->tx_skb); +@@ -1637,9 +1643,12 @@ static int bcm_enet_change_mtu(struct ne + * align rx buffer size to dma burst len, account FCS since + * it's appended + */ +- priv->rx_skb_size = ALIGN(actual_mtu + ETH_FCS_LEN, ++ priv->rx_buf_size = ALIGN(actual_mtu + ETH_FCS_LEN, + priv->dma_maxburst * 4); + ++ priv->rx_frag_size = SKB_DATA_ALIGN(priv->rx_buf_offset + priv->rx_buf_size) + ++ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); ++ + dev->mtu = new_mtu; + return 0; + } +@@ -1725,6 +1734,7 @@ static int bcm_enet_probe(struct platfor + + priv->enet_is_sw = false; + priv->dma_maxburst = BCMENET_DMA_MAXBURST; ++ priv->rx_buf_offset = NET_SKB_PAD; + + ret = bcm_enet_change_mtu(dev, dev->mtu); + if (ret) +@@ -2142,7 +2152,7 @@ static int bcm_enetsw_open(struct net_de + priv->tx_skb = kcalloc(priv->tx_ring_size, sizeof(struct sk_buff *), + GFP_KERNEL); + if (!priv->tx_skb) { +- dev_err(kdev, "cannot allocate rx skb queue\n"); ++ dev_err(kdev, "cannot allocate tx skb queue\n"); + ret = -ENOMEM; + goto out_free_tx_ring; + } +@@ -2152,11 +2162,11 @@ static int bcm_enetsw_open(struct net_de + priv->tx_curr_desc = 0; + spin_lock_init(&priv->tx_lock); + +- /* init & fill rx ring with skbs */ +- priv->rx_skb = kcalloc(priv->rx_ring_size, sizeof(struct sk_buff *), ++ /* init & fill rx ring with buffers */ ++ priv->rx_buf = kcalloc(priv->rx_ring_size, sizeof(void *), + GFP_KERNEL); +- if (!priv->rx_skb) { +- dev_err(kdev, "cannot allocate rx skb queue\n"); ++ if (!priv->rx_buf) { ++ dev_err(kdev, "cannot allocate rx buffer queue\n"); + ret = -ENOMEM; + goto out_free_tx_skb; + } +@@ -2203,8 +2213,8 @@ static int bcm_enetsw_open(struct net_de + enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0, + ENETDMA_BUFALLOC_REG(priv->rx_chan)); + +- if (bcm_enet_refill_rx(dev)) { +- dev_err(kdev, "cannot allocate rx skb queue\n"); ++ if (bcm_enet_refill_rx(dev, false)) { ++ dev_err(kdev, "cannot allocate rx buffer queue\n"); + ret = -ENOMEM; + goto out; + } +@@ -2303,7 +2313,7 @@ static int bcm_enetsw_open(struct net_de + return 0; + + out: +- bcm_enet_free_rx_skb_ring(kdev, priv); ++ bcm_enet_free_rx_buf_ring(kdev, priv); + + out_free_tx_skb: + kfree(priv->tx_skb); +@@ -2353,8 +2363,8 @@ static int bcm_enetsw_stop(struct net_de + /* force reclaim of all tx buffers */ + bcm_enet_tx_reclaim(dev, 1); + +- /* free the rx skb ring */ +- bcm_enet_free_rx_skb_ring(kdev, priv); ++ /* free the rx buffer ring */ ++ bcm_enet_free_rx_buf_ring(kdev, priv); + + /* free remaining allocated memory */ + kfree(priv->tx_skb); +@@ -2655,6 +2665,7 @@ static int bcm_enetsw_probe(struct platf + priv->rx_ring_size = BCMENET_DEF_RX_DESC; + priv->tx_ring_size = BCMENET_DEF_TX_DESC; + priv->dma_maxburst = BCMENETSW_DMA_MAXBURST; ++ priv->rx_buf_offset = NET_SKB_PAD + NET_IP_ALIGN; + + pd = dev_get_platdata(&pdev->dev); + if (pd) { +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h +@@ -230,11 +230,17 @@ struct bcm_enet_priv { + /* next dirty rx descriptor to refill */ + int rx_dirty_desc; + +- /* size of allocated rx skbs */ +- unsigned int rx_skb_size; ++ /* size of allocated rx buffers */ ++ unsigned int rx_buf_size; + +- /* list of skb given to hw for rx */ +- struct sk_buff **rx_skb; ++ /* allocated rx buffer offset */ ++ unsigned int rx_buf_offset; ++ ++ /* size of allocated rx frag */ ++ unsigned int rx_frag_size; ++ ++ /* list of buffer given to hw for rx */ ++ void **rx_buf; + + /* used when rx skb allocation failed, so we defer rx queue + * refill */ diff --git a/target/linux/bcm63xx/patches-5.4/046-v5.12-bcm63xx_enet-improve-rx-loop.patch b/target/linux/bcm63xx/patches-5.4/046-v5.12-bcm63xx_enet-improve-rx-loop.patch new file mode 100644 index 0000000000..65d3e2571a --- /dev/null +++ b/target/linux/bcm63xx/patches-5.4/046-v5.12-bcm63xx_enet-improve-rx-loop.patch @@ -0,0 +1,40 @@ +From ae2259eebeacb7753e3043278957b45840123972 Mon Sep 17 00:00:00 2001 +From: Sieng Piaw Liew +Date: Wed, 6 Jan 2021 22:42:08 +0800 +Subject: [PATCH 7/7] bcm63xx_enet: improve rx loop + +Use existing rx processed count to track against budget, thereby making +budget decrement operation redundant. + +rx_desc_count can be calculated outside the rx loop, making the loop a +bit smaller. + +Signed-off-by: Sieng Piaw Liew +Acked-by: Florian Fainelli +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -340,7 +340,6 @@ static int bcm_enet_receive_queue(struct + priv->rx_curr_desc++; + if (priv->rx_curr_desc == priv->rx_ring_size) + priv->rx_curr_desc = 0; +- priv->rx_desc_count--; + + /* if the packet does not have start of packet _and_ + * end of packet flag set, then just recycle it */ +@@ -405,9 +404,10 @@ static int bcm_enet_receive_queue(struct + dev->stats.rx_bytes += len; + list_add_tail(&skb->list, &rx_list); + +- } while (--budget > 0); ++ } while (processed < budget); + + netif_receive_skb_list(&rx_list); ++ priv->rx_desc_count -= processed; + + if (processed || !priv->rx_desc_count) { + bcm_enet_refill_rx(dev, true); diff --git a/target/linux/bcm63xx/patches-5.4/402_bcm63xx_enet_vlan_incoming_fixed.patch b/target/linux/bcm63xx/patches-5.4/402_bcm63xx_enet_vlan_incoming_fixed.patch index 389e3f71bb..949fb8d293 100644 --- a/target/linux/bcm63xx/patches-5.4/402_bcm63xx_enet_vlan_incoming_fixed.patch +++ b/target/linux/bcm63xx/patches-5.4/402_bcm63xx_enet_vlan_incoming_fixed.patch @@ -1,6 +1,6 @@ --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c -@@ -1612,7 +1612,7 @@ static int bcm_enet_change_mtu(struct ne +@@ -1629,7 +1629,7 @@ static int bcm_enet_change_mtu(struct ne return -EBUSY; /* add ethernet header + vlan tag size */ diff --git a/target/linux/bcm63xx/patches-5.4/404-NET-bcm63xx_enet-move-phy_-dis-connect-into-probe-re.patch b/target/linux/bcm63xx/patches-5.4/404-NET-bcm63xx_enet-move-phy_-dis-connect-into-probe-re.patch index 11059b3bb0..d9e49727da 100644 --- a/target/linux/bcm63xx/patches-5.4/404-NET-bcm63xx_enet-move-phy_-dis-connect-into-probe-re.patch +++ b/target/linux/bcm63xx/patches-5.4/404-NET-bcm63xx_enet-move-phy_-dis-connect-into-probe-re.patch @@ -15,7 +15,7 @@ Signed-off-by: Jonas Gorski --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c -@@ -854,10 +854,8 @@ static int bcm_enet_open(struct net_devi +@@ -893,10 +893,8 @@ static int bcm_enet_open(struct net_devi struct bcm_enet_priv *priv; struct sockaddr addr; struct device *kdev; @@ -26,7 +26,7 @@ Signed-off-by: Jonas Gorski void *p; u32 val; -@@ -865,31 +863,10 @@ static int bcm_enet_open(struct net_devi +@@ -904,31 +902,10 @@ static int bcm_enet_open(struct net_devi kdev = &priv->pdev->dev; if (priv->has_phy) { @@ -59,7 +59,7 @@ Signed-off-by: Jonas Gorski } /* mask all interrupts and request them */ -@@ -899,7 +876,7 @@ static int bcm_enet_open(struct net_devi +@@ -938,7 +915,7 @@ static int bcm_enet_open(struct net_devi ret = request_irq(dev->irq, bcm_enet_isr_mac, 0, dev->name, dev); if (ret) @@ -68,7 +68,7 @@ Signed-off-by: Jonas Gorski ret = request_irq(priv->irq_rx, bcm_enet_isr_dma, 0, dev->name, dev); -@@ -1061,8 +1038,8 @@ static int bcm_enet_open(struct net_devi +@@ -1100,8 +1077,8 @@ static int bcm_enet_open(struct net_devi enet_dmac_writel(priv, priv->dma_chan_int_mask, ENETDMAC_IRMASK, priv->tx_chan); @@ -79,7 +79,7 @@ Signed-off-by: Jonas Gorski else bcm_enet_adjust_link(dev); -@@ -1103,10 +1080,6 @@ out_freeirq_rx: +@@ -1131,10 +1108,6 @@ out_freeirq_rx: out_freeirq: free_irq(dev->irq, dev); @@ -90,7 +90,7 @@ Signed-off-by: Jonas Gorski return ret; } -@@ -1211,10 +1184,6 @@ static int bcm_enet_stop(struct net_devi +@@ -1228,10 +1201,6 @@ static int bcm_enet_stop(struct net_devi free_irq(priv->irq_rx, dev); free_irq(dev->irq, dev); @@ -101,7 +101,7 @@ Signed-off-by: Jonas Gorski return 0; } -@@ -1779,14 +1748,47 @@ static int bcm_enet_probe(struct platfor +@@ -1800,14 +1769,47 @@ static int bcm_enet_probe(struct platfor /* do minimal hardware init to be able to probe mii bus */ bcm_enet_hw_preinit(priv); @@ -150,7 +150,7 @@ Signed-off-by: Jonas Gorski } bus = priv->mii_bus; -@@ -1810,6 +1812,26 @@ static int bcm_enet_probe(struct platfor +@@ -1831,6 +1833,26 @@ static int bcm_enet_probe(struct platfor dev_err(&pdev->dev, "unable to register mdio bus\n"); goto out_free_mdio; } @@ -177,7 +177,7 @@ Signed-off-by: Jonas Gorski } else { /* run platform code to initialize PHY device */ -@@ -1817,45 +1839,16 @@ static int bcm_enet_probe(struct platfor +@@ -1838,45 +1860,16 @@ static int bcm_enet_probe(struct platfor pd->mii_config(dev, 1, bcm_enet_mdio_read_mii, bcm_enet_mdio_write_mii)) { dev_err(&pdev->dev, "unable to configure mdio bus\n"); @@ -227,7 +227,7 @@ Signed-off-by: Jonas Gorski if (priv->mii_bus) mdiobus_unregister(priv->mii_bus); -@@ -1863,6 +1856,9 @@ out_free_mdio: +@@ -1884,6 +1877,9 @@ out_free_mdio: if (priv->mii_bus) mdiobus_free(priv->mii_bus); @@ -237,7 +237,7 @@ Signed-off-by: Jonas Gorski out_uninit_hw: /* turn off mdc clock */ enet_writel(priv, 0, ENET_MIISC_REG); -@@ -1893,6 +1889,7 @@ static int bcm_enet_remove(struct platfo +@@ -1914,6 +1910,7 @@ static int bcm_enet_remove(struct platfo enet_writel(priv, 0, ENET_MIISC_REG); if (priv->has_phy) { diff --git a/target/linux/bcm63xx/patches-5.4/408-bcm63xx_enet-enable-rgmii-clock-on-external-ports.patch b/target/linux/bcm63xx/patches-5.4/408-bcm63xx_enet-enable-rgmii-clock-on-external-ports.patch index 703b83a897..d4a22c99f2 100644 --- a/target/linux/bcm63xx/patches-5.4/408-bcm63xx_enet-enable-rgmii-clock-on-external-ports.patch +++ b/target/linux/bcm63xx/patches-5.4/408-bcm63xx_enet-enable-rgmii-clock-on-external-ports.patch @@ -32,7 +32,7 @@ Subject: [PATCH 54/81] bcm63xx_enet: enable rgmii clock on external ports #define ENETSW_MDIOC_EXT_MASK (1 << 16) --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c -@@ -2162,6 +2162,18 @@ static int bcm_enetsw_open(struct net_de +@@ -2183,6 +2183,18 @@ static int bcm_enetsw_open(struct net_de priv->sw_port_link[i] = 0; } diff --git a/target/linux/bcm63xx/patches-5.4/423-bcm63xx_enet_add_b53_support.patch b/target/linux/bcm63xx/patches-5.4/423-bcm63xx_enet_add_b53_support.patch index 490b59c3f8..92dc05f909 100644 --- a/target/linux/bcm63xx/patches-5.4/423-bcm63xx_enet_add_b53_support.patch +++ b/target/linux/bcm63xx/patches-5.4/423-bcm63xx_enet_add_b53_support.patch @@ -1,6 +1,6 @@ --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h -@@ -332,6 +332,9 @@ struct bcm_enet_priv { +@@ -338,6 +338,9 @@ struct bcm_enet_priv { struct bcm63xx_enetsw_port used_ports[ENETSW_MAX_PORT]; int sw_port_link[ENETSW_MAX_PORT]; @@ -20,7 +20,7 @@ #include #include "bcm63xx_enet.h" -@@ -1909,7 +1910,8 @@ static int bcm_enet_remove(struct platfo +@@ -1930,7 +1931,8 @@ static int bcm_enet_remove(struct platfo return 0; } @@ -30,7 +30,7 @@ .probe = bcm_enet_probe, .remove = bcm_enet_remove, .driver = { -@@ -1918,6 +1920,42 @@ struct platform_driver bcm63xx_enet_driv +@@ -1939,6 +1941,42 @@ struct platform_driver bcm63xx_enet_driv }, }; @@ -73,7 +73,7 @@ /* * switch mii access callbacks */ -@@ -2174,29 +2212,6 @@ static int bcm_enetsw_open(struct net_de +@@ -2195,29 +2233,6 @@ static int bcm_enetsw_open(struct net_de enetsw_writeb(priv, rgmii_ctrl, ENETSW_RGMII_CTRL_REG(i)); } @@ -103,7 +103,7 @@ /* initialize flow control buffer allocation */ enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0, ENETDMA_BUFALLOC_REG(priv->rx_chan)); -@@ -2652,6 +2667,9 @@ static int bcm_enetsw_probe(struct platf +@@ -2651,6 +2666,9 @@ static int bcm_enetsw_probe(struct platf struct bcm63xx_enetsw_platform_data *pd; struct resource *res_mem; int ret, irq_rx, irq_tx; diff --git a/target/linux/bcm63xx/patches-5.4/428-bcm63xx_enet-rgmii-ctrl-fix.patch b/target/linux/bcm63xx/patches-5.4/428-bcm63xx_enet-rgmii-ctrl-fix.patch index f744d3dab9..3c4fa8ffad 100644 --- a/target/linux/bcm63xx/patches-5.4/428-bcm63xx_enet-rgmii-ctrl-fix.patch +++ b/target/linux/bcm63xx/patches-5.4/428-bcm63xx_enet-rgmii-ctrl-fix.patch @@ -12,7 +12,7 @@ --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c -@@ -2209,6 +2209,10 @@ static int bcm_enetsw_open(struct net_de +@@ -2230,6 +2230,10 @@ static int bcm_enetsw_open(struct net_de rgmii_ctrl = enetsw_readb(priv, ENETSW_RGMII_CTRL_REG(i)); rgmii_ctrl |= ENETSW_RGMII_CTRL_GMII_CLK_EN; diff --git a/target/linux/bcm63xx/patches-5.4/441-bcm63xx_enet-alloc_rx_skb_ip_align.patch b/target/linux/bcm63xx/patches-5.4/441-bcm63xx_enet-alloc_rx_skb_ip_align.patch deleted file mode 100644 index ade99beacc..0000000000 --- a/target/linux/bcm63xx/patches-5.4/441-bcm63xx_enet-alloc_rx_skb_ip_align.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sieng Piaw Liew -Date: Mon, 30 Nov 2020 11:07:47 +0800 -Subject: [PATCH] bcm63xx: enetsw: switch to netdev_alloc_skb_ip_align - -Increases packet processing performance by 30%. -Tested on BCM6328 320 MHz and iperf3 -M 512 for packet/sec performance. - -Before: -[ ID] Interval Transfer Bandwidth Retr -[ 4] 0.00-30.00 sec 120 MBytes 33.7 Mbits/sec 277 sender -[ 4] 0.00-30.00 sec 120 MBytes 33.5 Mbits/sec receiver - -After: -[ ID] Interval Transfer Bandwidth Retr -[ 4] 0.00-30.00 sec 155 MBytes 43.3 Mbits/sec 354 sender -[ 4] 0.00-30.00 sec 154 MBytes 43.1 Mbits/sec receiver - -Signed-off-by: Sieng Piaw Liew ---- - drivers/net/ethernet/broadcom/bcm63xx_enet.c | 6 +++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c -+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c -@@ -239,7 +239,10 @@ static int bcm_enet_refill_rx(struct net - desc = &priv->rx_desc_cpu[desc_idx]; - - if (!priv->rx_skb[desc_idx]) { -- skb = netdev_alloc_skb(dev, priv->rx_skb_size); -+ if (priv->enet_is_sw) -+ skb = netdev_alloc_skb_ip_align(dev, priv->rx_skb_size); -+ else -+ skb = netdev_alloc_skb(dev, priv->rx_skb_size); - if (!skb) - break; - priv->rx_skb[desc_idx] = skb; diff --git a/target/linux/bcm63xx/patches-5.4/442-bcm63xx_enet-add_bql_support.patch b/target/linux/bcm63xx/patches-5.4/442-bcm63xx_enet-add_bql_support.patch deleted file mode 100644 index 7955b7134f..0000000000 --- a/target/linux/bcm63xx/patches-5.4/442-bcm63xx_enet-add_bql_support.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 3c0e8e1259d223a1493c47f7e277d05b93909b6b Mon Sep 17 00:00:00 2001 -From: Sieng Piaw Liew -Date: Mon, 2 Nov 2020 11:34:06 +0800 -Subject: [PATCH 1/2] bcm63xx: add BQL support - -Add Byte Queue Limits support to reduce/remove bufferbloat in bcm63xx target. - -Signed-off-by: Sieng Piaw Liew ---- - bcm63xx_enet.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - ---- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c -+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c -@@ -423,9 +423,11 @@ static int bcm_enet_tx_reclaim(struct ne - { - struct bcm_enet_priv *priv; - int released; -+ unsigned int bytes; - - priv = netdev_priv(dev); - released = 0; -+ bytes = 0; - - while (priv->tx_desc_count < priv->tx_ring_size) { - struct bcm_enet_desc *desc; -@@ -461,10 +463,13 @@ static int bcm_enet_tx_reclaim(struct ne - if (desc->len_stat & DMADESC_UNDER_MASK) - dev->stats.tx_errors++; - -+ bytes += skb->len; - dev_kfree_skb(skb); - released++; - } - -+ netdev_completed_queue(dev, released, bytes); -+ - if (netif_queue_stopped(dev) && released) - netif_wake_queue(dev); - -@@ -631,6 +636,8 @@ bcm_enet_start_xmit(struct sk_buff *skb, - desc->len_stat = len_stat; - wmb(); - -+ netdev_sent_queue(dev, skb->len); -+ - /* kick tx dma */ - enet_dmac_writel(priv, priv->dma_chan_en_mask, - ENETDMAC_CHANCFG, priv->tx_chan); -@@ -1051,6 +1058,8 @@ static int bcm_enet_open(struct net_devi - else - bcm_enet_adjust_link(dev); - -+ netdev_reset_queue(dev); -+ - netif_start_queue(dev); - return 0; - -@@ -2281,6 +2290,8 @@ static int bcm_enetsw_open(struct net_de - enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, - ENETDMAC_IRMASK, priv->tx_chan); - -+ netdev_reset_queue(dev); -+ - netif_carrier_on(dev); - netif_start_queue(dev); - diff --git a/target/linux/bcm63xx/patches-5.4/443-bcm63xx_enet-support_xmit_more_in_bql.patch b/target/linux/bcm63xx/patches-5.4/443-bcm63xx_enet-support_xmit_more_in_bql.patch deleted file mode 100644 index 122cbf1138..0000000000 --- a/target/linux/bcm63xx/patches-5.4/443-bcm63xx_enet-support_xmit_more_in_bql.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 79bfb73319098bc4cb701139a6677dcdec99182f Mon Sep 17 00:00:00 2001 -From: Sieng Piaw Liew -Date: Tue, 3 Nov 2020 08:14:35 +0800 -Subject: [PATCH 2/2] bcm63xx: support xmit_more in BQL - -Support bulking hardware TX queue by using xmit_more. - -Signed-off-by: Sieng Piaw Liew ---- - bcm63xx_enet.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c -+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c -@@ -638,14 +638,16 @@ bcm_enet_start_xmit(struct sk_buff *skb, - - netdev_sent_queue(dev, skb->len); - -- /* kick tx dma */ -- enet_dmac_writel(priv, priv->dma_chan_en_mask, -- ENETDMAC_CHANCFG, priv->tx_chan); -- - /* stop queue if no more desc available */ - if (!priv->tx_desc_count) - netif_stop_queue(dev); - -+ /* kick tx dma */ -+ if(!netdev_xmit_more() || !priv->tx_desc_count) -+ enet_dmac_writel(priv, priv->dma_chan_en_mask, -+ ENETDMAC_CHANCFG, priv->tx_chan); -+ -+ - dev->stats.tx_bytes += skb->len; - dev->stats.tx_packets++; - ret = NETDEV_TX_OK; -@@ -2713,7 +2715,7 @@ static int bcm_enetsw_probe(struct platf - priv->irq_rx = irq_rx; - priv->irq_tx = irq_tx; - priv->rx_ring_size = BCMENET_DEF_RX_DESC; -- priv->tx_ring_size = BCMENET_DEF_TX_DESC; -+ priv->tx_ring_size = BCMENETSW_DEF_TX_DESC; - priv->dma_maxburst = BCMENETSW_DMA_MAXBURST; - - pd = dev_get_platdata(&pdev->dev); ---- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h -+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h -@@ -15,6 +15,7 @@ - /* default number of descriptor */ - #define BCMENET_DEF_RX_DESC 64 - #define BCMENET_DEF_TX_DESC 32 -+#define BCMENETSW_DEF_TX_DESC 48 - - /* maximum burst len for dma (4 bytes unit) */ - #define BCMENET_DMA_MAXBURST 16 From c31f7975277b5870ef146fb3ec4eaa829365b727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 21 Jan 2021 13:04:45 +0100 Subject: [PATCH 17/34] firmware-utils: bcm4908asus: tool inserting Asus tail into BCM4908 image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Asus looks for an extra data at the end of BCM4908 image, right before the BCM4908 tail. It needs to be properly filled to make Asus accept firmware image. This tool constructs such a tail, writes it and updates CRC32 in BCM4908 tail accordingly. Signed-off-by: Rafał Miłecki --- tools/firmware-utils/Makefile | 1 + tools/firmware-utils/src/bcm4908asus.c | 444 +++++++++++++++++++++++++ 2 files changed, 445 insertions(+) create mode 100644 tools/firmware-utils/src/bcm4908asus.c diff --git a/tools/firmware-utils/Makefile b/tools/firmware-utils/Makefile index 055082593b..e4a31b6fd0 100644 --- a/tools/firmware-utils/Makefile +++ b/tools/firmware-utils/Makefile @@ -27,6 +27,7 @@ define Host/Compile $(call cc,add_header) $(call cc,addpattern) $(call cc,asustrx) + $(call cc,bcm4908asus,-Wall) $(call cc,bcm4908img,-Wall) $(call cc,bcm4908kernel,-Wall) $(call cc,buffalo-enc buffalo-lib,-Wall) diff --git a/tools/firmware-utils/src/bcm4908asus.c b/tools/firmware-utils/src/bcm4908asus.c new file mode 100644 index 0000000000..837c02c33a --- /dev/null +++ b/tools/firmware-utils/src/bcm4908asus.c @@ -0,0 +1,444 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2021 Rafał Miłecki + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if __BYTE_ORDER == __BIG_ENDIAN +#define cpu_to_le32(x) bswap_32(x) +#define le32_to_cpu(x) bswap_32(x) +#define cpu_to_le16(x) bswap_16(x) +#define le16_to_cpu(x) bswap_16(x) +#elif __BYTE_ORDER == __LITTLE_ENDIAN +#define cpu_to_le32(x) (x) +#define le32_to_cpu(x) (x) +#define cpu_to_le16(x) (x) +#define le16_to_cpu(x) (x) +#else +#error "Unsupported endianness" +#endif + +/* BCM4908 specific tail - appended to the firmware image */ +struct bcm4908img_tail { + uint32_t crc32; + uint32_t unk1; + uint32_t family; + uint32_t unk2; + uint32_t unk3; +}; + +/* Asus BCM4908 tail - placed at the end of BCM4908 firmware, right before BCM4908 tail */ +struct bcm4908asus_tail { + uint8_t fw_ver[4]; + uint16_t build_no; + uint16_t extend_no_u16; + char productid[12]; /* The longest seen was 9 (e.g. GT-AC5300) */ + uint8_t unused1[8]; + uint32_t extend_no_u32; + uint8_t unused2[31]; + uint8_t ver_flags; /* Version or flags (only seen values: 0x00 and 0x01) */ +}; + +/* + * Example: + * + * 0053ffb0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| + * 0053ffc0 03 00 00 04 80 01 94 52 47 54 2d 41 43 35 33 30 |.......RGT-AC530| + * 0053ffd0 30 00 00 00 00 00 00 00 00 00 00 00 94 52 00 00 |0............R..| + * 0053ffe0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + * 0053fff0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 |................| + * 00540000 c4 20 e6 72 32 57 00 00 08 49 00 00 03 00 00 00 |. .r2W...I......| + * 00540010 02 00 00 00 |....| + */ + +char *in_path = NULL; +char *out_path = NULL; + +static inline size_t bcm4908asus_min(size_t x, size_t y) { + return x < y ? x : y; +} + +static const uint32_t crc32_tbl[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +}; + +uint32_t bcm4908img_crc32(uint32_t crc, uint8_t *buf, size_t len) { + while (len) { + crc = crc32_tbl[(crc ^ *buf) & 0xff] ^ (crc >> 8); + buf++; + len--; + } + + return crc; +} + +/************************************************** + * Info + **************************************************/ + +static int bcm4908asus_info(int argc, char **argv) +{ + struct bcm4908asus_tail asus_tail; + struct bcm4908img_tail img_tail; + struct stat st; + const char *pathname; + size_t bytes, length; + uint8_t buf[1024]; + uint32_t crc32; + bool empty; + FILE *fp; + int i; + int err = 0; + + if (argc < 3) { + fprintf(stderr, "No BCM4908 Asus image pathname passed\n"); + err = -EINVAL; + goto out; + } + pathname = argv[2]; + + if (stat(pathname, &st)) { + fprintf(stderr, "Failed to stat %s\n", pathname); + err = -EIO; + goto out; + } + + fp = fopen(pathname, "r"); + if (!fp) { + fprintf(stderr, "Failed to open %s\n", pathname); + err = -EACCES; + goto out; + } + + crc32 = 0xffffffff; + length = st.st_size - sizeof(asus_tail) - sizeof(img_tail); + while (length && (bytes = fread(buf, 1, bcm4908asus_min(sizeof(buf), length), fp)) > 0) { + crc32 = bcm4908img_crc32(crc32, buf, bytes); + length -= bytes; + } + + if (length) { + fprintf(stderr, "Failed to read from %s\n", pathname); + err = -EIO; + goto err_close; + } + + if (fread(&asus_tail, 1, sizeof(asus_tail), fp) != sizeof(asus_tail)) { + fprintf(stderr, "Failed to read BCM4908 Asus image tail\n"); + err = -EIO; + goto err_close; + } + crc32 = bcm4908img_crc32(crc32, (uint8_t *)&asus_tail, sizeof(asus_tail)); + + if (fread(&img_tail, 1, sizeof(img_tail), fp) != sizeof(img_tail)) { + fprintf(stderr, "Failed to read BCM4908 Asus image tail\n"); + err = -EIO; + goto err_close; + } + + if (crc32 != le32_to_cpu(img_tail.crc32)) { + fprintf(stderr, "Invalid crc32 (calculated 0x%08x expected 0x%08x)\n", crc32, le32_to_cpu(img_tail.crc32)); + err = -EINVAL; + goto err_close; + } + + empty = true; + for (i = 0; i < sizeof(asus_tail); i++) { + if (((uint8_t *)&asus_tail)[i] != 0xff) { + empty = false; + break; + } + } + if (empty) { + fprintf(stderr, "BCM4908 image doesn't contain Asus tail\n"); + err = -EINVAL; + goto err_close; + } + + printf("Firmware version:\t%u.%u.%u.%u\n", asus_tail.fw_ver[0], asus_tail.fw_ver[1], asus_tail.fw_ver[2], asus_tail.fw_ver[3]); + printf("Build number:\t\t%u\n", le16_to_cpu(asus_tail.build_no)); + printf("Extended number:\t%u\n", asus_tail.ver_flags & 0x1 ? le32_to_cpu(asus_tail.extend_no_u32) : le16_to_cpu(asus_tail.extend_no_u16)); + printf("Product ID:\t\t%s\n", asus_tail.productid); + +err_close: + fclose(fp); +out: + return err; +} + +/************************************************** + * Create + **************************************************/ + +static void bcm4908asus_create_parse_options(int argc, char **argv, struct bcm4908asus_tail *tail) +{ + uint32_t tmp32; + uint16_t tmp16; + int c; + + while ((c = getopt(argc, argv, "i:o:p:f:b:e:")) != -1) { + switch (c) { + case 'i': + in_path = optarg; + break; + case 'o': + out_path = optarg; + break; + case 'p': + strncpy(tail->productid, optarg, sizeof(tail->productid)); + break; + case 'f': + if (sscanf(optarg, "%hhu.%hhu.%hhu.%hhu", &(tail->fw_ver[0]), &tail->fw_ver[1], &tail->fw_ver[2], &tail->fw_ver[3]) != 4) + fprintf(stderr, "Version %s doesn't match suppored 4-digits format\n", optarg); + break; + case 'b': + tmp16 = strtol(optarg, NULL, 0); + tail->build_no = cpu_to_le16(tmp16); + break; + case 'e': + tmp32 = strtol(optarg, NULL, 0); + tail->ver_flags = 0x01; + tail->extend_no_u32 = cpu_to_le32(tmp32); + tail->extend_no_u16 = cpu_to_le16((uint16_t)tmp32); + break; + } + } +} + +static int bcm4908asus_create(int argc, char **argv) +{ + struct bcm4908asus_tail asus_tail = {}; + struct bcm4908img_tail img_tail = {}; + struct stat st; + uint32_t crc32_old; + uint32_t crc32_new; + uint8_t buf[1024]; + FILE *out = NULL; + FILE *in = NULL; + size_t length; + size_t bytes; + FILE *fp; + int i; + int err = 0; + + /* Parse & validate arguments */ + bcm4908asus_create_parse_options(argc, argv, &asus_tail); + if (!in_path) { + fprintf(stderr, "No BCM4908 Asus image pathname passed\n"); + err = -EINVAL; + goto err; + } + + /* Check input file: size, access, empty space for Asus tail */ + + if (stat(in_path, &st)) { + fprintf(stderr, "Failed to stat %s\n", in_path); + err = -EIO; + goto err; + } + + in = fopen(in_path, "r+"); + if (!in) { + fprintf(stderr, "Failed to open %s\n", in_path); + err = -EIO; + goto err; + } + + length = st.st_size - sizeof(asus_tail) - sizeof(img_tail); + fseek(in, length, SEEK_SET); + if (fread(buf, 1, sizeof(asus_tail), in) != sizeof(asus_tail)) { + fprintf(stderr, "Failed to read BCM4908 image from %s\n", in_path); + err = -EIO; + goto err; + } + for (i = 0; i < sizeof(asus_tail); i++) { + if (buf[i] != 0xff) { + fprintf(stderr, "Input BCM4908 image doesn't have empty 64 B tail\n"); + err = -ENOSPC; + goto err; + } + } + rewind(in); + + /* Create new BCM4908 Asus image file if requested (otherwise input file will get modified) */ + + if (out_path && !(out = fopen(out_path, "w+"))) { + fprintf(stderr, "Failed to open %s\n", out_path); + err = -EIO; + goto err; + } + + /* Calculate CRC for data that doesn't get modified. Optionally copy input file if requested */ + + crc32_old = 0xffffffff; + length = st.st_size - sizeof(asus_tail) - sizeof(img_tail); + while (length && (bytes = fread(buf, 1, bcm4908asus_min(sizeof(buf), length), in)) > 0) { + if (out && fwrite(buf, 1, bytes, out) != bytes) { + fprintf(stderr, "Failed to write %zu B to %s\n", bytes, out_path); + err = -EIO; + goto err; + } + crc32_old = bcm4908img_crc32(crc32_old, buf, bytes); + length -= bytes; + } + + if (length) { + fprintf(stderr, "Failed to read from %s\n", in_path); + err = -EIO; + goto err; + } + + crc32_new = crc32_old; + + /* Finish calculating old checksum & verify it */ + + for (i = 0; i < sizeof(asus_tail); i++) { + uint8_t val = 0xff; + + crc32_old = bcm4908img_crc32(crc32_old, &val, 1); + } + fseek(in, sizeof(asus_tail), SEEK_CUR); + + if (fread(&img_tail, 1, sizeof(img_tail), in) != sizeof(img_tail)) { + fprintf(stderr, "Failed to read BCM4908 image tail from %s\n", in_path); + err = -EIO; + goto err; + } + + if (crc32_old != le32_to_cpu(img_tail.crc32)) { + fprintf(stderr, "Invalid data crc32: calculated 0x%08x instead of 0x%08x\n", crc32_old, le32_to_cpu(img_tail.crc32)); + err = -EPROTO; + goto err; + } + + /* Write Asus tail & updated BCM4908 tail */ + + if (out) { + fp = out; + } else { + fp = in; + fseek(in, -sizeof(asus_tail) - sizeof(img_tail), SEEK_CUR); + } + + if (fwrite(&asus_tail, 1, sizeof(asus_tail), fp) != sizeof(asus_tail)) { + fprintf(stderr, "Failed to write BCM4908 image Asus tail to %s\n", out_path); + err = -EIO; + goto err; + } + + crc32_new = bcm4908img_crc32(crc32_new, (uint8_t *)&asus_tail, sizeof(asus_tail)); + img_tail.crc32 = cpu_to_le32(crc32_new); + if (fwrite(&img_tail, 1, sizeof(img_tail), fp) != sizeof(img_tail)) { + fprintf(stderr, "Failed to write BCM4908 image tail to %s\n", out_path); + err = -EIO; + goto err; + } + +err: + if (out) + fclose(out); + if (in) + fclose(in); + return err; +} + +static void usage() { + printf("Usage:\n"); + printf("\n"); + printf("Info about BCM4908 Asus image:\n"); + printf("\tbcm4908asus info \tget info about BCM4908 Asus image\n"); + printf("\n"); + printf("Create a BCM4908 Asus image:\n"); + printf("\tbcm4908asus create\tinsert Asus info into BCM4908 image\n"); + printf("\t-i file\t\t\t\tinput BCM4908 image file (required)\n"); + printf("\t-o file\t\t\t\toutput BCM4908 Asus image file\n"); + printf("\t-p productid\t\t\tproduct (device) ID\n"); + printf("\t-f firmware version\t\tfirmware version formatted with 4 digits like: 1.2.3.4\n"); + printf("\t-b build number\t\tbuild number (e.g. 380, 382, 384)\n"); + printf("\t-e extend number\t\textended number (e.g. 21140, 81622, 81695, 82037)\n"); +} + +int main(int argc, char **argv) { + if (argc > 1) { + if (!strcmp(argv[1], "info")) + return bcm4908asus_info(argc, argv); + else if (!strcmp(argv[1], "create")) + return bcm4908asus_create(argc, argv); + } + + usage(); + + return 0; +} From 6ba3a0e889053475930e9a23a2404d8872eb887a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 21 Jan 2021 16:07:49 +0100 Subject: [PATCH 18/34] bcm4908: build valid Asus GT-AC5300 firmware image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Insert Asus specific tail that is required for image identification. Signed-off-by: Rafał Miłecki --- target/linux/bcm4908/image/Makefile | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/target/linux/bcm4908/image/Makefile b/target/linux/bcm4908/image/Makefile index d6b5f07e2a..b744839e5b 100644 --- a/target/linux/bcm4908/image/Makefile +++ b/target/linux/bcm4908/image/Makefile @@ -27,6 +27,12 @@ define Build/bcm4908img mv $@.new $@ endef +define Build/bcm4908asus + $(STAGING_DIR_HOST)/bin/bcm4908asus create -i $@ -p $(ASUS_PRODUCTID) -b $(ASUS_BUILD_NO) -f $(ASUS_FW_REV) -e $(ASUS_EXT_NO) +endef + +DEVICE_VARS += ASUS_PRODUCTID ASUS_BUILD_NO ASUS_FW_REV ASUS_EXT_NO + define Device/Default KERNEL := kernel-bin | bcm4908lzma | bcm4908kernel KERNEL_DEPENDS = $$(wildcard $(DTS_DIR)/$$(DEVICE_DTS).dts) @@ -44,7 +50,11 @@ define Device/asus_gt-ac5300 DEVICE_MODEL := GT-AC5300 DEVICE_DTS := broadcom/bcm4908/bcm4908-asus-gt-ac5300 IMAGES := bin - IMAGE/bin := append-ubi | bcm4908img + IMAGE/bin := append-ubi | bcm4908img | bcm4908asus + ASUS_PRODUCTID := GT-AC5300 + ASUS_BUILD_NO := 384 + ASUS_FW_REV := 3.0.0.4 + ASUS_EXT_NO := 21140 endef TARGET_DEVICES += asus_gt-ac5300 From 20b4f77bb69cdded143c15ce962ccd3483bfe77a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 20 Jan 2021 16:49:26 +0100 Subject: [PATCH 19/34] kernel: add parser finding rootfs after CFE bootfs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's required for BCM4908. It cannot use "bcm-wfi-fw" parser because that one requires *two* JFFS2 partitions which is untested / unsupported on the BCM4908 architecture. With a single JFFS2 partition "bcm-wfi-fw" parser will: 1. Fail to find "vmlinux.lz" as it doesn't follow "1-openwrt" file 2. Create partitions that don't precisely match bootfs layout The new parser is described in details in the MTD_SPLIT_CFE_BOOTFS symbol help message. Signed-off-by: Rafał Miłecki --- target/linux/bcm4908/config-5.4 | 3 +- .../files/drivers/mtd/mtdsplit/Kconfig | 12 +++ .../files/drivers/mtd/mtdsplit/Makefile | 1 + .../mtd/mtdsplit/mtdsplit_cfe_bootfs.c | 86 +++++++++++++++++++ 4 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_cfe_bootfs.c diff --git a/target/linux/bcm4908/config-5.4 b/target/linux/bcm4908/config-5.4 index 3dfa7b21dc..d13753c49d 100644 --- a/target/linux/bcm4908/config-5.4 +++ b/target/linux/bcm4908/config-5.4 @@ -138,7 +138,8 @@ CONFIG_MTD_NAND_BRCMNAND=y CONFIG_MTD_NAND_CORE=y CONFIG_MTD_NAND_ECC_SW_HAMMING=y CONFIG_MTD_RAW_NAND=y -CONFIG_MTD_SPLIT_BCM_WFI_FW=y +CONFIG_MTD_SPLIT_CFE_BOOTFS=y +# CONFIG_MTD_SPLIT_SQUASHFS_ROOT is not set CONFIG_MTD_UBI=y CONFIG_MTD_UBI_BEB_LIMIT=20 CONFIG_MTD_UBI_BLOCK=y diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/Kconfig b/target/linux/generic/files/drivers/mtd/mtdsplit/Kconfig index 3b7e23af33..4832b8d9e4 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/Kconfig +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/Kconfig @@ -25,6 +25,18 @@ config MTD_SPLIT_BCM_WFI_FW depends on MTD_SPLIT_SUPPORT select MTD_SPLIT +config MTD_SPLIT_CFE_BOOTFS + bool "Parser finding rootfs appended to the CFE bootfs" + depends on MTD_SPLIT_SUPPORT && ARCH_BCM4908 + select MTD_SPLIT + help + cferom on BCM4908 (and bcm63xx) uses JFFS2 bootfs partition + for storing kernel, cferam and some device specific files. + There isn't any straight way of storing rootfs so it gets + appended to the JFFS2 bootfs partition. Kernel needs to find + it and run init from it. This parser is responsible for + finding appended rootfs. + config MTD_SPLIT_SEAMA_FW bool "Seama firmware parser" depends on MTD_SPLIT_SUPPORT diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/Makefile b/target/linux/generic/files/drivers/mtd/mtdsplit/Makefile index 8671628e7c..9217d8f64f 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/Makefile +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_MTD_SPLIT) += mtdsplit.o obj-$(CONFIG_MTD_SPLIT_BCM_WFI_FW) += mtdsplit_bcm_wfi.o +obj-$(CONFIG_MTD_SPLIT_CFE_BOOTFS) += mtdsplit_cfe_bootfs.o obj-$(CONFIG_MTD_SPLIT_SEAMA_FW) += mtdsplit_seama.o obj-$(CONFIG_MTD_SPLIT_SQUASHFS_ROOT) += mtdsplit_squashfs.o obj-$(CONFIG_MTD_SPLIT_UIMAGE_FW) += mtdsplit_uimage.o diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_cfe_bootfs.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_cfe_bootfs.c new file mode 100644 index 0000000000..5c8a5e1b9b --- /dev/null +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_cfe_bootfs.c @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2021 Rafał Miłecki + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mtdsplit.h" + +#define je16_to_cpu(x) ((x).v16) +#define je32_to_cpu(x) ((x).v32) + +#define NR_PARTS 1 + +static int mtdsplit_cfe_bootfs_parse(struct mtd_info *mtd, + const struct mtd_partition **pparts, + struct mtd_part_parser_data *data) +{ + struct jffs2_raw_dirent node; + enum mtdsplit_part_type type; + struct mtd_partition *parts; + size_t rootfs_offset; + size_t retlen; + size_t offset; + int err; + + /* Don't parse backup partitions */ + if (strcmp(mtd->name, "firmware")) + return -EINVAL; + + /* Find the end of JFFS2 bootfs partition */ + offset = 0; + do { + err = mtd_read(mtd, offset, sizeof(node), &retlen, (void *)&node); + if (err || retlen != sizeof(node)) + break; + + if (je16_to_cpu(node.magic) != JFFS2_MAGIC_BITMASK) + break; + + offset += je32_to_cpu(node.totlen); + offset = (offset + 0x3) & ~0x3; + } while (offset < mtd->size); + + /* Find rootfs partition that follows the bootfs */ + err = mtd_find_rootfs_from(mtd, mtd->erasesize, mtd->size, &rootfs_offset, &type); + if (err) + return err; + + parts = kzalloc(NR_PARTS * sizeof(*parts), GFP_KERNEL); + if (!parts) + return -ENOMEM; + + if (type == MTDSPLIT_PART_TYPE_UBI) + parts[0].name = UBI_PART_NAME; + else + parts[0].name = ROOTFS_PART_NAME; + parts[0].offset = rootfs_offset; + parts[0].size = mtd->size - rootfs_offset; + + *pparts = parts; + + return NR_PARTS; +} + +static const struct of_device_id mtdsplit_cfe_bootfs_of_match_table[] = { + { .compatible = "brcm,bcm4908-firmware" }, + {}, +}; +MODULE_DEVICE_TABLE(of, mtdsplit_cfe_bootfs_of_match_table); + +static struct mtd_part_parser mtdsplit_cfe_bootfs_parser = { + .owner = THIS_MODULE, + .name = "cfe-bootfs", + .of_match_table = mtdsplit_cfe_bootfs_of_match_table, + .parse_fn = mtdsplit_cfe_bootfs_parse, +}; + +module_mtd_part_parser(mtdsplit_cfe_bootfs_parser); From dd5ac0546ca3f80de10db309e57090cf809b1b72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 20 Jan 2021 18:36:44 +0100 Subject: [PATCH 20/34] dt-bindings: mtd: partitions: add OpenWrt defined U-Boot Image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add devicetree bindings for vendor specific variants of U-Boot Images, as defined by OpenWrt. Signed-off-by: Bjørn Mork --- .../mtd/partitions/openwrt,uimage.yaml | 91 +++++++++ .../dt-bindings/mtd/partitions/uimage.h | 191 ++++++++++++++++++ 2 files changed, 282 insertions(+) create mode 100644 target/linux/generic/files/Documentation/devicetree/bindings/mtd/partitions/openwrt,uimage.yaml create mode 100644 target/linux/generic/files/include/dt-bindings/mtd/partitions/uimage.h diff --git a/target/linux/generic/files/Documentation/devicetree/bindings/mtd/partitions/openwrt,uimage.yaml b/target/linux/generic/files/Documentation/devicetree/bindings/mtd/partitions/openwrt,uimage.yaml new file mode 100644 index 0000000000..d052ab1fc9 --- /dev/null +++ b/target/linux/generic/files/Documentation/devicetree/bindings/mtd/partitions/openwrt,uimage.yaml @@ -0,0 +1,91 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mtd/partitions/openwrt,uimage.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: OpenWrt variations of U-Boot Image partitions + +maintainers: + - Bjørn Mork + +description: | + The image format defined by the boot loader "Das U-Boot" is often + modified or extended by device vendors. This defines a few optional + properties which can be used to describe such modifications. + +# partition.txt defines common properties, but has not yet been +# converted to YAML +#allOf: +# - $ref: ../partition.yaml# + +properties: + compatible: + items: + - enum: + - openwrt,uimage + - const: denx,uimage + + openwrt,padding: + description: Number of padding bytes between header and data + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0 + + openwrt,ih-magic: + description: U-Boot Image Header magic number. + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x27051956 # IH_MAGIC + + openwrt,ih-type: + description: U-Boot Image type + $ref: /schemas/types.yaml#/definitions/uint32 + default: 2 # IH_TYPE_KERNEL + + openwrt,offset: + description: + Offset between partition start and U-Boot Image in bytes + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0 + + openwrt,partition-magic: + description: + Magic number found at the start of the partition. Will only be + validated if both this property and openwrt,offset is non-zero + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0 + +required: + - compatible + - reg + +#unevaluatedProperties: false +additionalProperties: false + +examples: + - | + // device with non-default magic + partition@300000 { + compatible = "openwrt,uimage", "denx,uimage"; + reg = <0x00300000 0xe80000>; + label = "firmware"; + openwrt,ih-magic = <0x4e474520>; + }; + - | + // device with U-Boot Image at an offset, with a partition magic value + partition@70000 { + compatible = "openwrt,uimage", "denx,uimage"; + reg = <0x00070000 0x00790000>; + label = "firmware"; + openwrt,offset = <20>; + openwrt,partition-magic = <0x43535953>; + }; + - | + // device using a non-default image type + #include "dt-bindings/mtd/partitions/uimage.h" + partition@6c0000 { + compatible = "openwrt,uimage", "denx,uimage"; + reg = <0x6c0000 0x1900000>; + label = "firmware"; + openwrt,ih-magic = <0x33373033>; + openwrt,ih-type = ; + }; diff --git a/target/linux/generic/files/include/dt-bindings/mtd/partitions/uimage.h b/target/linux/generic/files/include/dt-bindings/mtd/partitions/uimage.h new file mode 100644 index 0000000000..29eec38dd2 --- /dev/null +++ b/target/linux/generic/files/include/dt-bindings/mtd/partitions/uimage.h @@ -0,0 +1,191 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * *** IMPORTANT *** + * This file is not only included from C-code but also from devicetree source + * files. As such this file MUST only contain comments and defines. + * + * Based on image.h from U-Boot which is + * (C) Copyright 2008 Semihalf + * (C) Copyright 2000-2005 Wolfgang Denk, DENX Software Engineering, wd@denx.de. + */ + +#ifndef __UIMAGE_H__ +#define __UIMAGE_H__ + +/* + * Operating System Codes + * + * The following are exposed to uImage header. + * New IDs *MUST* be appended at the end of the list and *NEVER* + * inserted for backward compatibility. + */ +#define IH_OS_INVALID 0 /* Invalid OS */ +#define IH_OS_OPENBSD 1 /* OpenBSD */ +#define IH_OS_NETBSD 2 /* NetBSD */ +#define IH_OS_FREEBSD 3 /* FreeBSD */ +#define IH_OS_4_4BSD 4 /* 4.4BSD */ +#define IH_OS_LINUX 5 /* Linux */ +#define IH_OS_SVR4 6 /* SVR4 */ +#define IH_OS_ESIX 7 /* Esix */ +#define IH_OS_SOLARIS 8 /* Solaris */ +#define IH_OS_IRIX 9 /* Irix */ +#define IH_OS_SCO 10 /* SCO */ +#define IH_OS_DELL 11 /* Dell */ +#define IH_OS_NCR 12 /* NCR */ +#define IH_OS_LYNXOS 13 /* LynxOS */ +#define IH_OS_VXWORKS 14 /* VxWorks */ +#define IH_OS_PSOS 15 /* pSOS */ +#define IH_OS_QNX 16 /* QNX */ +#define IH_OS_U_BOOT 17 /* Firmware */ +#define IH_OS_RTEMS 18 /* RTEMS */ +#define IH_OS_ARTOS 19 /* ARTOS */ +#define IH_OS_UNITY 20 /* Unity OS */ +#define IH_OS_INTEGRITY 21 /* INTEGRITY */ +#define IH_OS_OSE 22 /* OSE */ +#define IH_OS_PLAN9 23 /* Plan 9 */ +#define IH_OS_OPENRTOS 24 /* OpenRTOS */ +#define IH_OS_ARM_TRUSTED_FIRMWARE 25 /* ARM Trusted Firmware */ +#define IH_OS_TEE 26 /* Trusted Execution Environment */ +#define IH_OS_OPENSBI 27 /* RISC-V OpenSBI */ +#define IH_OS_EFI 28 /* EFI Firmware (e.g. GRUB2) */ + +/* + * CPU Architecture Codes (supported by Linux) + * + * The following are exposed to uImage header. + * New IDs *MUST* be appended at the end of the list and *NEVER* + * inserted for backward compatibility. + */ +#define IH_ARCH_INVALID 0 /* Invalid CPU */ +#define IH_ARCH_ALPHA 1 /* Alpha */ +#define IH_ARCH_ARM 2 /* ARM */ +#define IH_ARCH_I386 3 /* Intel x86 */ +#define IH_ARCH_IA64 4 /* IA64 */ +#define IH_ARCH_MIPS 5 /* MIPS */ +#define IH_ARCH_MIPS64 6 /* MIPS 64 Bit */ +#define IH_ARCH_PPC 7 /* PowerPC */ +#define IH_ARCH_S390 8 /* IBM S390 */ +#define IH_ARCH_SH 9 /* SuperH */ +#define IH_ARCH_SPARC 10 /* Sparc */ +#define IH_ARCH_SPARC64 11 /* Sparc 64 Bit */ +#define IH_ARCH_M68K 12 /* M68K */ +#define IH_ARCH_NIOS 13 /* Nios-32 */ +#define IH_ARCH_MICROBLAZE 14 /* MicroBlaze */ +#define IH_ARCH_NIOS2 15 /* Nios-II */ +#define IH_ARCH_BLACKFIN 16 /* Blackfin */ +#define IH_ARCH_AVR32 17 /* AVR32 */ +#define IH_ARCH_ST200 18 /* STMicroelectronics ST200 */ +#define IH_ARCH_SANDBOX 19 /* Sandbox architecture (test only) */ +#define IH_ARCH_NDS32 20 /* ANDES Technology - NDS32 */ +#define IH_ARCH_OPENRISC 21 /* OpenRISC 1000 */ +#define IH_ARCH_ARM64 22 /* ARM64 */ +#define IH_ARCH_ARC 23 /* Synopsys DesignWare ARC */ +#define IH_ARCH_X86_64 24 /* AMD x86_64, Intel and Via */ +#define IH_ARCH_XTENSA 25 /* Xtensa */ +#define IH_ARCH_RISCV 26 /* RISC-V */ + +/* + * Image Types + * + * "Standalone Programs" are directly runnable in the environment + * provided by U-Boot; it is expected that (if they behave + * well) you can continue to work in U-Boot after return from + * the Standalone Program. + * "OS Kernel Images" are usually images of some Embedded OS which + * will take over control completely. Usually these programs + * will install their own set of exception handlers, device + * drivers, set up the MMU, etc. - this means, that you cannot + * expect to re-enter U-Boot except by resetting the CPU. + * "RAMDisk Images" are more or less just data blocks, and their + * parameters (address, size) are passed to an OS kernel that is + * being started. + * "Multi-File Images" contain several images, typically an OS + * (Linux) kernel image and one or more data images like + * RAMDisks. This construct is useful for instance when you want + * to boot over the network using BOOTP etc., where the boot + * server provides just a single image file, but you want to get + * for instance an OS kernel and a RAMDisk image. + * + * "Multi-File Images" start with a list of image sizes, each + * image size (in bytes) specified by an "uint32_t" in network + * byte order. This list is terminated by an "(uint32_t)0". + * Immediately after the terminating 0 follow the images, one by + * one, all aligned on "uint32_t" boundaries (size rounded up to + * a multiple of 4 bytes - except for the last file). + * + * "Firmware Images" are binary images containing firmware (like + * U-Boot or FPGA images) which usually will be programmed to + * flash memory. + * + * "Script files" are command sequences that will be executed by + * U-Boot's command interpreter; this feature is especially + * useful when you configure U-Boot to use a real shell (hush) + * as command interpreter (=> Shell Scripts). + * + * The following are exposed to uImage header. + * New IDs *MUST* be appended at the end of the list and *NEVER* + * inserted for backward compatibility. + */ +#define IH_TYPE_INVALID 0 /* Invalid Image */ +#define IH_TYPE_STANDALONE 1 /* Standalone Program */ +#define IH_TYPE_KERNEL 2 /* OS Kernel Image */ +#define IH_TYPE_RAMDISK 3 /* RAMDisk Image */ +#define IH_TYPE_MULTI 4 /* Multi-File Image */ +#define IH_TYPE_FIRMWARE 5 /* Firmware Image */ +#define IH_TYPE_SCRIPT 6 /* Script file */ +#define IH_TYPE_FILESYSTEM 7 /* Filesystem Image (any type) */ +#define IH_TYPE_FLATDT 8 /* Binary Flat Device Tree Blob */ +#define IH_TYPE_KWBIMAGE 9 /* Kirkwood Boot Image */ +#define IH_TYPE_IMXIMAGE 10 /* Freescale IMXBoot Image */ +#define IH_TYPE_UBLIMAGE 11 /* Davinci UBL Image */ +#define IH_TYPE_OMAPIMAGE 12 /* TI OMAP Config Header Image */ +#define IH_TYPE_AISIMAGE 13 /* TI Davinci AIS Image */ + /* OS Kernel Image, can run from any load address */ +#define IH_TYPE_KERNEL_NOLOAD 14 +#define IH_TYPE_PBLIMAGE 15 /* Freescale PBL Boot Image */ +#define IH_TYPE_MXSIMAGE 16 /* Freescale MXSBoot Image */ +#define IH_TYPE_GPIMAGE 17 /* TI Keystone GPHeader Image */ +#define IH_TYPE_ATMELIMAGE 18 /* ATMEL ROM bootable Image */ +#define IH_TYPE_SOCFPGAIMAGE 19 /* Altera SOCFPGA CV/AV Preloader */ +#define IH_TYPE_X86_SETUP 20 /* x86 setup.bin Image */ +#define IH_TYPE_LPC32XXIMAGE 21 /* x86 setup.bin Image */ +#define IH_TYPE_LOADABLE 22 /* A list of typeless images */ +#define IH_TYPE_RKIMAGE 23 /* Rockchip Boot Image */ +#define IH_TYPE_RKSD 24 /* Rockchip SD card */ +#define IH_TYPE_RKSPI 25 /* Rockchip SPI image */ +#define IH_TYPE_ZYNQIMAGE 26 /* Xilinx Zynq Boot Image */ +#define IH_TYPE_ZYNQMPIMAGE 27 /* Xilinx ZynqMP Boot Image */ +#define IH_TYPE_ZYNQMPBIF 28 /* Xilinx ZynqMP Boot Image (bif) */ +#define IH_TYPE_FPGA 29 /* FPGA Image */ +#define IH_TYPE_VYBRIDIMAGE 30 /* VYBRID .vyb Image */ +#define IH_TYPE_TEE 31 /* Trusted Execution Environment OS Image */ +#define IH_TYPE_FIRMWARE_IVT 32 /* Firmware Image with HABv4 IVT */ +#define IH_TYPE_PMMC 33 /* TI Power Management Micro-Controller Firmware */ +#define IH_TYPE_STM32IMAGE 34 /* STMicroelectronics STM32 Image */ +#define IH_TYPE_SOCFPGAIMAGE_V1 35 /* Altera SOCFPGA A10 Preloader */ +#define IH_TYPE_MTKIMAGE 36 /* MediaTek BootROM loadable Image */ +#define IH_TYPE_IMX8MIMAGE 37 /* Freescale IMX8MBoot Image */ +#define IH_TYPE_IMX8IMAGE 38 /* Freescale IMX8Boot Image */ +#define IH_TYPE_COPRO 39 /* Coprocessor Image for remoteproc*/ + + +/* + * Compression Types + * + * The following are exposed to uImage header. + * New IDs *MUST* be appended at the end of the list and *NEVER* + * inserted for backward compatibility. + */ +#define IH_COMP_NONE 0 /* No Compression Used */ +#define IH_COMP_GZIP 1 /* gzip Compression Used */ +#define IH_COMP_BZIP2 2 /* bzip2 Compression Used */ +#define IH_COMP_LZMA 3 /* lzma Compression Used */ +#define IH_COMP_LZO 4 /* lzo Compression Used */ +#define IH_COMP_LZ4 5 /* lz4 Compression Used */ + + +#define LZ4F_MAGIC 0x184D2204 /* LZ4 Magic Number */ +#define IH_MAGIC 0x27051956 /* Image Magic Number */ +#define IH_NMLEN 32 /* Image Name Length */ + +#endif /* __UIMAGE_H__ */ From 76ea7a91cf96203418dd9165c46eb737de77ee99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 20 Jan 2021 18:36:45 +0100 Subject: [PATCH 21/34] kernel: mtdsplit_uimage: read extralen from device tree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An "openwrt,padding" property in device tree can replace two device specific parsers. Signed-off-by: Bjørn Mork --- .../drivers/mtd/mtdsplit/mtdsplit_uimage.c | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c index 57d8b9f420..f9544ec382 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "mtdsplit.h" @@ -28,14 +29,6 @@ */ #define MAX_HEADER_LEN 96 -#define IH_MAGIC 0x27051956 /* Image Magic Number */ -#define IH_NMLEN 32 /* Image Name Length */ - -#define IH_OS_LINUX 5 /* Linux */ - -#define IH_TYPE_KERNEL 2 /* OS Kernel Image */ -#define IH_TYPE_FILESYSTEM 7 /* Filesystem Image */ - /* * Legacy format image header, * all data in network byte order (aka natural aka bigendian). @@ -76,6 +69,15 @@ read_uimage_header(struct mtd_info *mtd, size_t offset, u_char *buf, return 0; } +static void uimage_parse_dt(struct mtd_info *master, int *extralen) +{ + struct device_node *np = mtd_get_of_node(master); + + if (!np || !of_device_is_compatible(np, "openwrt,uimage")) + return; + of_property_read_u32(np, "openwrt,padding", extralen); +} + /** * __mtdsplit_parse_uimage - scan partition and create kernel + rootfs parts * @@ -97,7 +99,7 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, size_t rootfs_size = 0; int uimage_part, rf_part; int ret; - int extralen; + int extralen = 0; enum mtdsplit_part_type type; nr_parts = 2; @@ -111,6 +113,8 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, goto err_free_parts; } + uimage_parse_dt(master, &extralen); + /* find uImage on erase block boundaries */ for (offset = 0; offset < master->size; offset += master->erasesize) { struct uimage_header *header; @@ -121,7 +125,6 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, if (ret) continue; - extralen = 0; ret = find_header(buf, MAX_HEADER_LEN, &extralen); if (ret < 0) { pr_debug("no valid uImage found in \"%s\" at offset %llx\n", @@ -247,6 +250,7 @@ mtdsplit_uimage_parse_generic(struct mtd_info *master, static const struct of_device_id mtdsplit_uimage_of_match_table[] = { { .compatible = "denx,uimage" }, + { .compatible = "openwrt,uimage" }, {}, }; From 5ab5bacda280362851830e30d4f9d38b785aac9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 20 Jan 2021 18:36:46 +0100 Subject: [PATCH 22/34] kernel: mtdsplit_uimage: replace "fonfxc" and "sge" parsers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert users of the "fonfxc" and "sge" parsers to the generic "openwrt,uimage", using device specific "openwrt,padding" properties. Tested-by: Stijn Segers [DIR-878 A1] Signed-off-by: Bjørn Mork --- .../drivers/mtd/mtdsplit/mtdsplit_uimage.c | 93 ++----------------- .../linux/ramips/dts/mt7620a_fon_fon2601.dts | 3 +- .../ramips/dts/mt7621_dlink_dir-8xx-a1.dtsi | 3 +- .../ramips/dts/mt7621_dlink_dir-xx60-a1.dtsi | 6 +- 4 files changed, 16 insertions(+), 89 deletions(-) diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c index f9544ec382..f5e48c661e 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c @@ -87,7 +87,7 @@ static void uimage_parse_dt(struct mtd_info *master, int *extralen) static int __mtdsplit_parse_uimage(struct mtd_info *master, const struct mtd_partition **pparts, struct mtd_part_parser_data *data, - ssize_t (*find_header)(u_char *buf, size_t len, int *extralen)) + ssize_t (*find_header)(u_char *buf, size_t len)) { struct mtd_partition *parts; u_char *buf; @@ -125,7 +125,7 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, if (ret) continue; - ret = find_header(buf, MAX_HEADER_LEN, &extralen); + ret = find_header(buf, MAX_HEADER_LEN); if (ret < 0) { pr_debug("no valid uImage found in \"%s\" at offset %llx\n", master->name, (unsigned long long) offset); @@ -213,7 +213,7 @@ err_free_parts: return ret; } -static ssize_t uimage_verify_default(u_char *buf, size_t len, int *extralen) +static ssize_t uimage_verify_default(u_char *buf, size_t len) { struct uimage_header *header = (struct uimage_header *)buf; @@ -274,7 +274,7 @@ static struct mtd_part_parser uimage_generic_parser = { #define FW_MAGIC_WNDR3700V2 0x33373031 #define FW_MAGIC_WPN824N 0x31313030 -static ssize_t uimage_verify_wndr3700(u_char *buf, size_t len, int *extralen) +static ssize_t uimage_verify_wndr3700(u_char *buf, size_t len) { struct uimage_header *header = (struct uimage_header *)buf; uint8_t expected_type = IH_TYPE_FILESYSTEM; @@ -336,7 +336,7 @@ static struct mtd_part_parser uimage_netgear_parser = { #define FW_MAGIC_SG8208M 0x00000006 #define FW_MAGIC_SG8310PM 0x83000006 -static ssize_t uimage_verify_allnet(u_char *buf, size_t len, int *extralen) +static ssize_t uimage_verify_allnet(u_char *buf, size_t len) { struct uimage_header *header = (struct uimage_header *)buf; @@ -383,7 +383,7 @@ static struct mtd_part_parser uimage_allnet_parser = { #define FW_EDIMAX_OFFSET 20 #define FW_MAGIC_EDIMAX 0x43535953 -static ssize_t uimage_find_edimax(u_char *buf, size_t len, int *extralen) +static ssize_t uimage_find_edimax(u_char *buf, size_t len) { u32 *magic; @@ -396,7 +396,7 @@ static ssize_t uimage_find_edimax(u_char *buf, size_t len, int *extralen) if (be32_to_cpu(*magic) != FW_MAGIC_EDIMAX) return -EINVAL; - if (!uimage_verify_default(buf + FW_EDIMAX_OFFSET, len, extralen)) + if (!uimage_verify_default(buf + FW_EDIMAX_OFFSET, len)) return FW_EDIMAX_OFFSET; return -EINVAL; @@ -424,88 +424,13 @@ static struct mtd_part_parser uimage_edimax_parser = { .type = MTD_PARSER_TYPE_FIRMWARE, }; - -/************************************************** - * Fon(Foxconn) - **************************************************/ - -#define FONFXC_PAD_LEN 32 - -static ssize_t uimage_find_fonfxc(u_char *buf, size_t len, int *extralen) -{ - if (uimage_verify_default(buf, len, extralen) < 0) - return -EINVAL; - - *extralen = FONFXC_PAD_LEN; - - return 0; -} - -static int -mtdsplit_uimage_parse_fonfxc(struct mtd_info *master, - const struct mtd_partition **pparts, - struct mtd_part_parser_data *data) -{ - return __mtdsplit_parse_uimage(master, pparts, data, - uimage_find_fonfxc); -} - -static const struct of_device_id mtdsplit_uimage_fonfxc_of_match_table[] = { - { .compatible = "fonfxc,uimage" }, - {}, -}; - -static struct mtd_part_parser uimage_fonfxc_parser = { - .owner = THIS_MODULE, - .name = "fonfxc-fw", - .of_match_table = mtdsplit_uimage_fonfxc_of_match_table, - .parse_fn = mtdsplit_uimage_parse_fonfxc, -}; - -/************************************************** - * SGE (T&W) Shenzhen Gongjin Electronics - **************************************************/ - -#define SGE_PAD_LEN 96 - -static ssize_t uimage_find_sge(u_char *buf, size_t len, int *extralen) -{ - if (uimage_verify_default(buf, len, extralen) < 0) - return -EINVAL; - - *extralen = SGE_PAD_LEN; - - return 0; -} - -static int -mtdsplit_uimage_parse_sge(struct mtd_info *master, - const struct mtd_partition **pparts, - struct mtd_part_parser_data *data) -{ - return __mtdsplit_parse_uimage(master, pparts, data, - uimage_find_sge); -} - -static const struct of_device_id mtdsplit_uimage_sge_of_match_table[] = { - { .compatible = "sge,uimage" }, - {}, -}; - -static struct mtd_part_parser uimage_sge_parser = { - .owner = THIS_MODULE, - .name = "sge-fw", - .of_match_table = mtdsplit_uimage_sge_of_match_table, - .parse_fn = mtdsplit_uimage_parse_sge, -}; - /************************************************** * OKLI (OpenWrt Kernel Loader Image) **************************************************/ #define IH_MAGIC_OKLI 0x4f4b4c49 -static ssize_t uimage_verify_okli(u_char *buf, size_t len, int *extralen) +static ssize_t uimage_verify_okli(u_char *buf, size_t len) { struct uimage_header *header = (struct uimage_header *)buf; @@ -562,8 +487,6 @@ static int __init mtdsplit_uimage_init(void) register_mtd_parser(&uimage_netgear_parser); register_mtd_parser(&uimage_allnet_parser); register_mtd_parser(&uimage_edimax_parser); - register_mtd_parser(&uimage_fonfxc_parser); - register_mtd_parser(&uimage_sge_parser); register_mtd_parser(&uimage_okli_parser); return 0; diff --git a/target/linux/ramips/dts/mt7620a_fon_fon2601.dts b/target/linux/ramips/dts/mt7620a_fon_fon2601.dts index 4dc0e28c9f..ee61c6e59e 100644 --- a/target/linux/ramips/dts/mt7620a_fon_fon2601.dts +++ b/target/linux/ramips/dts/mt7620a_fon_fon2601.dts @@ -83,7 +83,8 @@ }; partition@50000 { - compatible = "fonfxc,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,padding = <32>; label = "firmware"; reg = <0x50000 0xf90000>; }; diff --git a/target/linux/ramips/dts/mt7621_dlink_dir-8xx-a1.dtsi b/target/linux/ramips/dts/mt7621_dlink_dir-8xx-a1.dtsi index c43cc49aa1..95ef0afcd9 100644 --- a/target/linux/ramips/dts/mt7621_dlink_dir-8xx-a1.dtsi +++ b/target/linux/ramips/dts/mt7621_dlink_dir-8xx-a1.dtsi @@ -34,7 +34,8 @@ }; partition@60000 { - compatible = "sge,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,padding = <96>; label = "firmware"; reg = <0x60000 0xfa0000>; }; diff --git a/target/linux/ramips/dts/mt7621_dlink_dir-xx60-a1.dtsi b/target/linux/ramips/dts/mt7621_dlink_dir-xx60-a1.dtsi index 96c6921124..a54b2be4f0 100644 --- a/target/linux/ramips/dts/mt7621_dlink_dir-xx60-a1.dtsi +++ b/target/linux/ramips/dts/mt7621_dlink_dir-xx60-a1.dtsi @@ -89,7 +89,8 @@ partition@180000 { label = "firmware"; - compatible = "sge,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,padding = <96>; reg = <0x180000 0x2800000>; }; @@ -101,7 +102,8 @@ partition@4980000 { label = "firmware2"; - compatible = "sge,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,padding = <96>; reg = <0x4980000 0x2800000>; }; From ed39f7ec1abde0d447a2dde8a8dce8042a3c5b29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 20 Jan 2021 18:36:47 +0100 Subject: [PATCH 23/34] kernel: mtdsplit_uimage: add "openwrt, ih-magic" device-tree property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Many devices use uimages with non-standard magic values. Let device tree override the default magic. Signed-off-by: Bjørn Mork --- .../drivers/mtd/mtdsplit/mtdsplit_uimage.c | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c index f5e48c661e..58c40e9ec7 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c @@ -69,13 +69,17 @@ read_uimage_header(struct mtd_info *mtd, size_t offset, u_char *buf, return 0; } -static void uimage_parse_dt(struct mtd_info *master, int *extralen) +static void uimage_parse_dt(struct mtd_info *master, int *extralen, u32 *ih_magic) { struct device_node *np = mtd_get_of_node(master); if (!np || !of_device_is_compatible(np, "openwrt,uimage")) return; - of_property_read_u32(np, "openwrt,padding", extralen); + + if (!of_property_read_u32(np, "openwrt,padding", extralen)) + pr_debug("got openwrt,padding=%d from device-tree\n", *extralen); + if (!of_property_read_u32(np, "openwrt,ih-magic", ih_magic)) + pr_debug("got openwrt,ih-magic=%08x from device-tree\n", *ih_magic); } /** @@ -87,7 +91,7 @@ static void uimage_parse_dt(struct mtd_info *master, int *extralen) static int __mtdsplit_parse_uimage(struct mtd_info *master, const struct mtd_partition **pparts, struct mtd_part_parser_data *data, - ssize_t (*find_header)(u_char *buf, size_t len)) + ssize_t (*find_header)(u_char *buf, size_t len, u32 ih_magic)) { struct mtd_partition *parts; u_char *buf; @@ -100,6 +104,7 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, int uimage_part, rf_part; int ret; int extralen = 0; + u32 ih_magic = IH_MAGIC; enum mtdsplit_part_type type; nr_parts = 2; @@ -113,7 +118,7 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, goto err_free_parts; } - uimage_parse_dt(master, &extralen); + uimage_parse_dt(master, &extralen, &ih_magic); /* find uImage on erase block boundaries */ for (offset = 0; offset < master->size; offset += master->erasesize) { @@ -125,7 +130,7 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, if (ret) continue; - ret = find_header(buf, MAX_HEADER_LEN); + ret = find_header(buf, MAX_HEADER_LEN, ih_magic); if (ret < 0) { pr_debug("no valid uImage found in \"%s\" at offset %llx\n", master->name, (unsigned long long) offset); @@ -213,26 +218,26 @@ err_free_parts: return ret; } -static ssize_t uimage_verify_default(u_char *buf, size_t len) +static ssize_t uimage_verify_default(u_char *buf, size_t len, u32 ih_magic) { struct uimage_header *header = (struct uimage_header *)buf; /* default sanity checks */ - if (be32_to_cpu(header->ih_magic) != IH_MAGIC) { - pr_debug("invalid uImage magic: %08x\n", - be32_to_cpu(header->ih_magic)); + if (be32_to_cpu(header->ih_magic) != ih_magic) { + pr_debug("invalid uImage magic: %08x != %08x\n", + be32_to_cpu(header->ih_magic), ih_magic); return -EINVAL; } if (header->ih_os != IH_OS_LINUX) { - pr_debug("invalid uImage OS: %08x\n", - be32_to_cpu(header->ih_os)); + pr_debug("invalid uImage OS: %08x != %08x\n", + be32_to_cpu(header->ih_os), IH_OS_LINUX); return -EINVAL; } if (header->ih_type != IH_TYPE_KERNEL) { - pr_debug("invalid uImage type: %08x\n", - be32_to_cpu(header->ih_type)); + pr_debug("invalid uImage type: %08x != %08x\n", + be32_to_cpu(header->ih_type), IH_TYPE_KERNEL); return -EINVAL; } @@ -274,7 +279,7 @@ static struct mtd_part_parser uimage_generic_parser = { #define FW_MAGIC_WNDR3700V2 0x33373031 #define FW_MAGIC_WPN824N 0x31313030 -static ssize_t uimage_verify_wndr3700(u_char *buf, size_t len) +static ssize_t uimage_verify_wndr3700(u_char *buf, size_t len, u32 ih_magic) { struct uimage_header *header = (struct uimage_header *)buf; uint8_t expected_type = IH_TYPE_FILESYSTEM; @@ -336,7 +341,7 @@ static struct mtd_part_parser uimage_netgear_parser = { #define FW_MAGIC_SG8208M 0x00000006 #define FW_MAGIC_SG8310PM 0x83000006 -static ssize_t uimage_verify_allnet(u_char *buf, size_t len) +static ssize_t uimage_verify_allnet(u_char *buf, size_t len, u32 ih_magic) { struct uimage_header *header = (struct uimage_header *)buf; @@ -383,7 +388,7 @@ static struct mtd_part_parser uimage_allnet_parser = { #define FW_EDIMAX_OFFSET 20 #define FW_MAGIC_EDIMAX 0x43535953 -static ssize_t uimage_find_edimax(u_char *buf, size_t len) +static ssize_t uimage_find_edimax(u_char *buf, size_t len, u32 ih_magic) { u32 *magic; @@ -396,7 +401,7 @@ static ssize_t uimage_find_edimax(u_char *buf, size_t len) if (be32_to_cpu(*magic) != FW_MAGIC_EDIMAX) return -EINVAL; - if (!uimage_verify_default(buf + FW_EDIMAX_OFFSET, len)) + if (!uimage_verify_default(buf + FW_EDIMAX_OFFSET, len, ih_magic)) return FW_EDIMAX_OFFSET; return -EINVAL; @@ -430,7 +435,7 @@ static struct mtd_part_parser uimage_edimax_parser = { #define IH_MAGIC_OKLI 0x4f4b4c49 -static ssize_t uimage_verify_okli(u_char *buf, size_t len) +static ssize_t uimage_verify_okli(u_char *buf, size_t len, u32 ih_magic) { struct uimage_header *header = (struct uimage_header *)buf; From 01a1e21863aa30c7a2c252ff06b9aef0cf957970 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 20 Jan 2021 18:36:48 +0100 Subject: [PATCH 24/34] kernel: mtdsplit_uimage: replace "openwrt, okli" parser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The only difference between the "openwrt,okli" and the generic parser is the magic. Set this in device tree for all affected devices and remove the "openwrt,okli" parser. Tested-by: Michael Pratt # EAP300 v2, ENS202EXT and ENH202 Signed-off-by: Bjørn Mork --- .../ath79/dts/ar7240_engenius_enh202-v1.dts | 4 +- .../ath79/dts/ar7242_engenius_eap350-v1.dts | 4 +- .../ath79/dts/ar7242_engenius_ecb350-v1.dts | 4 +- .../ath79/dts/ar9341_engenius_eap300-v2.dts | 4 +- .../dts/ar9341_engenius_ens202ext-v1.dts | 4 +- .../linux/ath79/dts/ar9341_pisen_wmb001n.dts | 4 +- .../ath79/dts/ar9344_engenius_exx600.dtsi | 4 +- .../dts/qca9557_engenius_enstationac-v1.dts | 4 +- .../ath79/dts/qca9558_belkin_f9x-v2.dtsi | 4 +- .../drivers/mtd/mtdsplit/mtdsplit_uimage.c | 53 ------------------- .../dt-bindings/mtd/partitions/uimage.h | 5 ++ .../ramips/dts/mt7620n_sunvalley_filehub.dtsi | 4 +- 12 files changed, 35 insertions(+), 63 deletions(-) diff --git a/target/linux/ath79/dts/ar7240_engenius_enh202-v1.dts b/target/linux/ath79/dts/ar7240_engenius_enh202-v1.dts index 1d26a9765b..7c819e88e7 100644 --- a/target/linux/ath79/dts/ar7240_engenius_enh202-v1.dts +++ b/target/linux/ath79/dts/ar7240_engenius_enh202-v1.dts @@ -4,6 +4,7 @@ #include #include +#include / { compatible = "engenius,enh202-v1", "qca,ar7240"; @@ -80,7 +81,8 @@ #size-cells = <1>; partition@0 { - compatible = "openwrt,okli"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = ; label = "firmware"; reg = <0x0 0x0>; }; diff --git a/target/linux/ath79/dts/ar7242_engenius_eap350-v1.dts b/target/linux/ath79/dts/ar7242_engenius_eap350-v1.dts index 4001897adf..39a8a7f25f 100644 --- a/target/linux/ath79/dts/ar7242_engenius_eap350-v1.dts +++ b/target/linux/ath79/dts/ar7242_engenius_eap350-v1.dts @@ -4,6 +4,7 @@ #include #include +#include / { compatible = "engenius,eap350-v1", "qca,ar7242"; @@ -59,7 +60,8 @@ #size-cells = <1>; partition@0 { - compatible = "openwrt,okli"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = ; label = "firmware"; reg = <0x0 0x0>; }; diff --git a/target/linux/ath79/dts/ar7242_engenius_ecb350-v1.dts b/target/linux/ath79/dts/ar7242_engenius_ecb350-v1.dts index e73082267c..0e06ee0128 100644 --- a/target/linux/ath79/dts/ar7242_engenius_ecb350-v1.dts +++ b/target/linux/ath79/dts/ar7242_engenius_ecb350-v1.dts @@ -4,6 +4,7 @@ #include #include +#include / { compatible = "engenius,ecb350-v1", "qca,ar7242"; @@ -59,7 +60,8 @@ #size-cells = <1>; partition@0 { - compatible = "openwrt,okli"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = ; label = "firmware"; reg = <0x0 0x0>; }; diff --git a/target/linux/ath79/dts/ar9341_engenius_eap300-v2.dts b/target/linux/ath79/dts/ar9341_engenius_eap300-v2.dts index 3121ec0e01..7aa89a4cce 100644 --- a/target/linux/ath79/dts/ar9341_engenius_eap300-v2.dts +++ b/target/linux/ath79/dts/ar9341_engenius_eap300-v2.dts @@ -4,6 +4,7 @@ #include #include +#include / { model = "Engenius EAP300 v2"; @@ -60,7 +61,8 @@ #size-cells = <1>; partition@0 { - compatible = "openwrt,okli"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = ; label = "firmware"; reg = <0x0 0x0>; }; diff --git a/target/linux/ath79/dts/ar9341_engenius_ens202ext-v1.dts b/target/linux/ath79/dts/ar9341_engenius_ens202ext-v1.dts index 6e296ab496..38e9b381c0 100644 --- a/target/linux/ath79/dts/ar9341_engenius_ens202ext-v1.dts +++ b/target/linux/ath79/dts/ar9341_engenius_ens202ext-v1.dts @@ -4,6 +4,7 @@ #include #include +#include / { model = "Engenius ENS202EXT v1"; @@ -70,7 +71,8 @@ #size-cells = <1>; partition@0 { - compatible = "openwrt,okli"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = ; label = "firmware"; reg = <0x0 0x0>; }; diff --git a/target/linux/ath79/dts/ar9341_pisen_wmb001n.dts b/target/linux/ath79/dts/ar9341_pisen_wmb001n.dts index aaa4d1576b..98236d44a6 100644 --- a/target/linux/ath79/dts/ar9341_pisen_wmb001n.dts +++ b/target/linux/ath79/dts/ar9341_pisen_wmb001n.dts @@ -4,6 +4,7 @@ #include #include +#include / { model = "PISEN WMB001N"; @@ -106,7 +107,8 @@ partition@0 { reg = <0x0 0x0>; label = "firmware"; - compatible = "openwrt,okli"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = ; }; }; }; diff --git a/target/linux/ath79/dts/ar9344_engenius_exx600.dtsi b/target/linux/ath79/dts/ar9344_engenius_exx600.dtsi index 5ae2ea66ef..340357b8de 100644 --- a/target/linux/ath79/dts/ar9344_engenius_exx600.dtsi +++ b/target/linux/ath79/dts/ar9344_engenius_exx600.dtsi @@ -4,6 +4,7 @@ #include #include +#include / { aliases { @@ -47,7 +48,8 @@ #size-cells = <1>; partition@0 { - compatible = "openwrt,okli"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = ; label = "firmware"; reg = <0x0 0x0>; }; diff --git a/target/linux/ath79/dts/qca9557_engenius_enstationac-v1.dts b/target/linux/ath79/dts/qca9557_engenius_enstationac-v1.dts index f9801693c5..2cf800cddc 100644 --- a/target/linux/ath79/dts/qca9557_engenius_enstationac-v1.dts +++ b/target/linux/ath79/dts/qca9557_engenius_enstationac-v1.dts @@ -4,6 +4,7 @@ #include #include +#include / { compatible = "engenius,enstationac-v1", "qca,qca9557"; @@ -70,7 +71,8 @@ #size-cells = <1>; partition@0 { - compatible = "openwrt,okli"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = ; label = "firmware"; reg = <0x0 0x0>; }; diff --git a/target/linux/ath79/dts/qca9558_belkin_f9x-v2.dtsi b/target/linux/ath79/dts/qca9558_belkin_f9x-v2.dtsi index af22f6681a..624e20096f 100644 --- a/target/linux/ath79/dts/qca9558_belkin_f9x-v2.dtsi +++ b/target/linux/ath79/dts/qca9558_belkin_f9x-v2.dtsi @@ -4,6 +4,7 @@ #include #include +#include / { aliases { @@ -85,7 +86,8 @@ #size-cells = <1>; partition@0 { - compatible = "openwrt,okli"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = ; label = "firmware"; reg = <0x0 0x0>; }; diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c index 58c40e9ec7..32c027d3e9 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c @@ -429,58 +429,6 @@ static struct mtd_part_parser uimage_edimax_parser = { .type = MTD_PARSER_TYPE_FIRMWARE, }; -/************************************************** - * OKLI (OpenWrt Kernel Loader Image) - **************************************************/ - -#define IH_MAGIC_OKLI 0x4f4b4c49 - -static ssize_t uimage_verify_okli(u_char *buf, size_t len, u32 ih_magic) -{ - struct uimage_header *header = (struct uimage_header *)buf; - - /* default sanity checks */ - if (be32_to_cpu(header->ih_magic) != IH_MAGIC_OKLI) { - pr_debug("invalid uImage magic: %08x\n", - be32_to_cpu(header->ih_magic)); - return -EINVAL; - } - - if (header->ih_os != IH_OS_LINUX) { - pr_debug("invalid uImage OS: %08x\n", - be32_to_cpu(header->ih_os)); - return -EINVAL; - } - - if (header->ih_type != IH_TYPE_KERNEL) { - pr_debug("invalid uImage type: %08x\n", - be32_to_cpu(header->ih_type)); - return -EINVAL; - } - - return 0; -} - -static int -mtdsplit_uimage_parse_okli(struct mtd_info *master, - const struct mtd_partition **pparts, - struct mtd_part_parser_data *data) -{ - return __mtdsplit_parse_uimage(master, pparts, data, - uimage_verify_okli); -} - -static const struct of_device_id mtdsplit_uimage_okli_of_match_table[] = { - { .compatible = "openwrt,okli" }, - {}, -}; - -static struct mtd_part_parser uimage_okli_parser = { - .owner = THIS_MODULE, - .name = "okli-fw", - .of_match_table = mtdsplit_uimage_okli_of_match_table, - .parse_fn = mtdsplit_uimage_parse_okli, -}; /************************************************** * Init @@ -492,7 +440,6 @@ static int __init mtdsplit_uimage_init(void) register_mtd_parser(&uimage_netgear_parser); register_mtd_parser(&uimage_allnet_parser); register_mtd_parser(&uimage_edimax_parser); - register_mtd_parser(&uimage_okli_parser); return 0; } diff --git a/target/linux/generic/files/include/dt-bindings/mtd/partitions/uimage.h b/target/linux/generic/files/include/dt-bindings/mtd/partitions/uimage.h index 29eec38dd2..407e46ce2c 100644 --- a/target/linux/generic/files/include/dt-bindings/mtd/partitions/uimage.h +++ b/target/linux/generic/files/include/dt-bindings/mtd/partitions/uimage.h @@ -188,4 +188,9 @@ #define IH_MAGIC 0x27051956 /* Image Magic Number */ #define IH_NMLEN 32 /* Image Name Length */ +/* + * Magic values specific to "openwrt,uimage" partitions + */ +#define IH_MAGIC_OKLI 0x4f4b4c49 /* 'OKLI' */ + #endif /* __UIMAGE_H__ */ diff --git a/target/linux/ramips/dts/mt7620n_sunvalley_filehub.dtsi b/target/linux/ramips/dts/mt7620n_sunvalley_filehub.dtsi index beca2954dc..20ff2dbd1c 100644 --- a/target/linux/ramips/dts/mt7620n_sunvalley_filehub.dtsi +++ b/target/linux/ramips/dts/mt7620n_sunvalley_filehub.dtsi @@ -4,6 +4,7 @@ #include #include +#include / { aliases { @@ -31,7 +32,8 @@ #size-cells = <1>; partition@0 { - compatible = "openwrt,okli"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = ; label = "firmware"; reg = <0x0 0x0>; }; From 647fdafcc57e7bb214ba5c745be63a55211e3422 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 20 Jan 2021 18:36:49 +0100 Subject: [PATCH 25/34] kernel: mtdsplit_uimage: replace "allnet, uimage" parser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert users to the generic "openwrt,uimage" using device specific "openwrt,ih-magic" properties, and remove "allnet,uimage". Signed-off-by: Bjørn Mork --- .../drivers/mtd/mtdsplit/mtdsplit_uimage.c | 49 ------------------- .../dts/rtl8382_allnet_all-sg8208m.dts | 3 +- 2 files changed, 2 insertions(+), 50 deletions(-) diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c index 32c027d3e9..55eaca9946 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c @@ -333,54 +333,6 @@ static struct mtd_part_parser uimage_netgear_parser = { }; - -/************************************************** - * ALLNET - **************************************************/ - -#define FW_MAGIC_SG8208M 0x00000006 -#define FW_MAGIC_SG8310PM 0x83000006 - -static ssize_t uimage_verify_allnet(u_char *buf, size_t len, u32 ih_magic) -{ - struct uimage_header *header = (struct uimage_header *)buf; - - switch (be32_to_cpu(header->ih_magic)) { - case FW_MAGIC_SG8208M: - case FW_MAGIC_SG8310PM: - break; - default: - return -EINVAL; - } - - if (header->ih_os != IH_OS_LINUX) - return -EINVAL; - - return 0; -} - -static int -mtdsplit_uimage_parse_allnet(struct mtd_info *master, - const struct mtd_partition **pparts, - struct mtd_part_parser_data *data) -{ - return __mtdsplit_parse_uimage(master, pparts, data, - uimage_verify_allnet); -} - -static const struct of_device_id mtdsplit_uimage_allnet_of_match_table[] = { - { .compatible = "allnet,uimage" }, - {}, -}; - -static struct mtd_part_parser uimage_allnet_parser = { - .owner = THIS_MODULE, - .name = "allnet-fw", - .of_match_table = mtdsplit_uimage_allnet_of_match_table, - .parse_fn = mtdsplit_uimage_parse_allnet, -}; - - /************************************************** * Edimax **************************************************/ @@ -438,7 +390,6 @@ static int __init mtdsplit_uimage_init(void) { register_mtd_parser(&uimage_generic_parser); register_mtd_parser(&uimage_netgear_parser); - register_mtd_parser(&uimage_allnet_parser); register_mtd_parser(&uimage_edimax_parser); return 0; diff --git a/target/linux/realtek/dts/rtl8382_allnet_all-sg8208m.dts b/target/linux/realtek/dts/rtl8382_allnet_all-sg8208m.dts index 28c4fd2970..681d699e8a 100644 --- a/target/linux/realtek/dts/rtl8382_allnet_all-sg8208m.dts +++ b/target/linux/realtek/dts/rtl8382_allnet_all-sg8208m.dts @@ -95,7 +95,8 @@ partition@2a0000 { label = "firmware"; reg = <0x2a0000 0xd60000>; - compatible = "allnet,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = <0x00000006>; }; }; }; From de64d4b9586c86018097fc33ce3210128da11287 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 20 Jan 2021 18:36:50 +0100 Subject: [PATCH 26/34] kernel: mtdsplit_uimage: add "openwrt, ih-type" device-tree property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some devices use uimage headers with a non-default ih_type. Add support for overriding this in device tree. Signed-off-by: Bjørn Mork --- .../drivers/mtd/mtdsplit/mtdsplit_uimage.c | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c index 55eaca9946..ef2d857abb 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c @@ -69,7 +69,8 @@ read_uimage_header(struct mtd_info *mtd, size_t offset, u_char *buf, return 0; } -static void uimage_parse_dt(struct mtd_info *master, int *extralen, u32 *ih_magic) +static void uimage_parse_dt(struct mtd_info *master, int *extralen, + u32 *ih_magic, u32 *ih_type) { struct device_node *np = mtd_get_of_node(master); @@ -80,6 +81,8 @@ static void uimage_parse_dt(struct mtd_info *master, int *extralen, u32 *ih_magi pr_debug("got openwrt,padding=%d from device-tree\n", *extralen); if (!of_property_read_u32(np, "openwrt,ih-magic", ih_magic)) pr_debug("got openwrt,ih-magic=%08x from device-tree\n", *ih_magic); + if (!of_property_read_u32(np, "openwrt,ih-type", ih_type)) + pr_debug("got openwrt,ih-type=%08x from device-tree\n", *ih_type); } /** @@ -91,7 +94,7 @@ static void uimage_parse_dt(struct mtd_info *master, int *extralen, u32 *ih_magi static int __mtdsplit_parse_uimage(struct mtd_info *master, const struct mtd_partition **pparts, struct mtd_part_parser_data *data, - ssize_t (*find_header)(u_char *buf, size_t len, u32 ih_magic)) + ssize_t (*find_header)(u_char *buf, size_t len, u32 ih_magic, u32 ih_type)) { struct mtd_partition *parts; u_char *buf; @@ -105,6 +108,7 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, int ret; int extralen = 0; u32 ih_magic = IH_MAGIC; + u32 ih_type = IH_TYPE_KERNEL; enum mtdsplit_part_type type; nr_parts = 2; @@ -118,7 +122,7 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, goto err_free_parts; } - uimage_parse_dt(master, &extralen, &ih_magic); + uimage_parse_dt(master, &extralen, &ih_magic, &ih_type); /* find uImage on erase block boundaries */ for (offset = 0; offset < master->size; offset += master->erasesize) { @@ -130,7 +134,7 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, if (ret) continue; - ret = find_header(buf, MAX_HEADER_LEN, ih_magic); + ret = find_header(buf, MAX_HEADER_LEN, ih_magic, ih_type); if (ret < 0) { pr_debug("no valid uImage found in \"%s\" at offset %llx\n", master->name, (unsigned long long) offset); @@ -218,7 +222,7 @@ err_free_parts: return ret; } -static ssize_t uimage_verify_default(u_char *buf, size_t len, u32 ih_magic) +static ssize_t uimage_verify_default(u_char *buf, size_t len, u32 ih_magic, u32 ih_type) { struct uimage_header *header = (struct uimage_header *)buf; @@ -235,9 +239,9 @@ static ssize_t uimage_verify_default(u_char *buf, size_t len, u32 ih_magic) return -EINVAL; } - if (header->ih_type != IH_TYPE_KERNEL) { + if (header->ih_type != ih_type) { pr_debug("invalid uImage type: %08x != %08x\n", - be32_to_cpu(header->ih_type), IH_TYPE_KERNEL); + be32_to_cpu(header->ih_type), ih_type); return -EINVAL; } @@ -279,7 +283,7 @@ static struct mtd_part_parser uimage_generic_parser = { #define FW_MAGIC_WNDR3700V2 0x33373031 #define FW_MAGIC_WPN824N 0x31313030 -static ssize_t uimage_verify_wndr3700(u_char *buf, size_t len, u32 ih_magic) +static ssize_t uimage_verify_wndr3700(u_char *buf, size_t len, u32 ih_magic, u32 ih_type) { struct uimage_header *header = (struct uimage_header *)buf; uint8_t expected_type = IH_TYPE_FILESYSTEM; @@ -340,7 +344,7 @@ static struct mtd_part_parser uimage_netgear_parser = { #define FW_EDIMAX_OFFSET 20 #define FW_MAGIC_EDIMAX 0x43535953 -static ssize_t uimage_find_edimax(u_char *buf, size_t len, u32 ih_magic) +static ssize_t uimage_find_edimax(u_char *buf, size_t len, u32 ih_magic, u32 ih_type) { u32 *magic; @@ -353,7 +357,7 @@ static ssize_t uimage_find_edimax(u_char *buf, size_t len, u32 ih_magic) if (be32_to_cpu(*magic) != FW_MAGIC_EDIMAX) return -EINVAL; - if (!uimage_verify_default(buf + FW_EDIMAX_OFFSET, len, ih_magic)) + if (!uimage_verify_default(buf + FW_EDIMAX_OFFSET, len, ih_magic, ih_type)) return FW_EDIMAX_OFFSET; return -EINVAL; From ff7709d223e15cfc496abf09acae12826d9216e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 20 Jan 2021 18:36:51 +0100 Subject: [PATCH 27/34] kernel: mtdsplit_uimage: replace "netgear, uimage" parser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "netgear,uimage" parser can be replaced by the generic parser using device specific openwrt,ih-magic and openwrt,ih-type properties. Device tree properties for the following devices have not been set, as they have been dropped from OpenWrt with the removal of the ar71xx target: FW_MAGIC_WNR2000V1 0x32303031 FW_MAGIC_WNR2000V4 0x32303034 FW_MAGIC_WNR1000V2_VC 0x31303030 FW_MAGIC_WPN824N 0x31313030 Tested-by: Sander Vanheule # WNDR3700v2 Tested-by: Stijn Segers # WNDR3700v1 Signed-off-by: Bjørn Mork --- .../linux/ath79/dts/ar7161_netgear_wndr.dtsi | 1 + .../ath79/dts/ar7161_netgear_wndr3700-v2.dts | 4 +- .../ath79/dts/ar7161_netgear_wndr3700.dts | 4 +- .../ath79/dts/ar7161_netgear_wndr3800.dts | 4 +- .../ath79/dts/ar7161_netgear_wndr3800ch.dts | 4 +- .../ath79/dts/ar7161_netgear_wndrmac-v1.dts | 4 +- .../ath79/dts/ar7161_netgear_wndrmac-v2.dts | 4 +- .../ath79/dts/ar7240_netgear_wnr1000-v2.dts | 5 +- .../ath79/dts/ar7240_netgear_wnr612-v2.dtsi | 5 +- .../ath79/dts/ar7241_netgear_wnr2000-v3.dts | 5 +- .../ath79/dts/ar7241_netgear_wnr2200-16m.dts | 4 +- .../ath79/dts/ar7241_netgear_wnr2200-8m.dts | 4 +- .../ath79/dts/ar7241_netgear_wnr2200.dtsi | 1 + .../linux/ath79/dts/ar9344_netgear_wndr.dtsi | 5 +- .../drivers/mtd/mtdsplit/mtdsplit_uimage.c | 67 ------------------- .../dts/rtl8380_netgear_gs110tpp-v1.dts | 3 +- 16 files changed, 44 insertions(+), 80 deletions(-) diff --git a/target/linux/ath79/dts/ar7161_netgear_wndr.dtsi b/target/linux/ath79/dts/ar7161_netgear_wndr.dtsi index 61097f9679..217128546f 100644 --- a/target/linux/ath79/dts/ar7161_netgear_wndr.dtsi +++ b/target/linux/ath79/dts/ar7161_netgear_wndr.dtsi @@ -4,6 +4,7 @@ #include #include +#include / { aliases { diff --git a/target/linux/ath79/dts/ar7161_netgear_wndr3700-v2.dts b/target/linux/ath79/dts/ar7161_netgear_wndr3700-v2.dts index 0543c47113..6d78c019da 100644 --- a/target/linux/ath79/dts/ar7161_netgear_wndr3700-v2.dts +++ b/target/linux/ath79/dts/ar7161_netgear_wndr3700-v2.dts @@ -22,7 +22,9 @@ partition@70000 { label = "firmware"; reg = <0x070000 0xf80000>; - compatible = "netgear,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = <0x33373031>; + openwrt,ih-type = ; }; art: partition@ff0000 { diff --git a/target/linux/ath79/dts/ar7161_netgear_wndr3700.dts b/target/linux/ath79/dts/ar7161_netgear_wndr3700.dts index 955dd2edf0..ad29d256f6 100644 --- a/target/linux/ath79/dts/ar7161_netgear_wndr3700.dts +++ b/target/linux/ath79/dts/ar7161_netgear_wndr3700.dts @@ -22,7 +22,9 @@ partition@70000 { label = "firmware"; reg = <0x070000 0x780000>; - compatible = "netgear,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = <0x33373030>; + openwrt,ih-type = ; }; art: partition@7f0000 { diff --git a/target/linux/ath79/dts/ar7161_netgear_wndr3800.dts b/target/linux/ath79/dts/ar7161_netgear_wndr3800.dts index 41fe401ddb..80b25492b1 100644 --- a/target/linux/ath79/dts/ar7161_netgear_wndr3800.dts +++ b/target/linux/ath79/dts/ar7161_netgear_wndr3800.dts @@ -23,7 +23,9 @@ partition@70000 { label = "firmware"; reg = <0x070000 0xf80000>; - compatible = "netgear,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = <0x33373031>; + openwrt,ih-type = ; }; art: partition@ff0000 { diff --git a/target/linux/ath79/dts/ar7161_netgear_wndr3800ch.dts b/target/linux/ath79/dts/ar7161_netgear_wndr3800ch.dts index 79569adba8..cc51aca8b6 100644 --- a/target/linux/ath79/dts/ar7161_netgear_wndr3800ch.dts +++ b/target/linux/ath79/dts/ar7161_netgear_wndr3800ch.dts @@ -23,7 +23,9 @@ partition@70000 { label = "firmware"; reg = <0x070000 0xf80000>; - compatible = "netgear,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = <0x33373031>; + openwrt,ih-type = ; }; art: partition@ff0000 { diff --git a/target/linux/ath79/dts/ar7161_netgear_wndrmac-v1.dts b/target/linux/ath79/dts/ar7161_netgear_wndrmac-v1.dts index 65d2393c67..8604414d19 100644 --- a/target/linux/ath79/dts/ar7161_netgear_wndrmac-v1.dts +++ b/target/linux/ath79/dts/ar7161_netgear_wndrmac-v1.dts @@ -22,7 +22,9 @@ partition@70000 { label = "firmware"; reg = <0x070000 0xf80000>; - compatible = "netgear,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = <0x33373031>; + openwrt,ih-type = ; }; art: partition@ff0000 { diff --git a/target/linux/ath79/dts/ar7161_netgear_wndrmac-v2.dts b/target/linux/ath79/dts/ar7161_netgear_wndrmac-v2.dts index f7641203cf..bebd96c72f 100644 --- a/target/linux/ath79/dts/ar7161_netgear_wndrmac-v2.dts +++ b/target/linux/ath79/dts/ar7161_netgear_wndrmac-v2.dts @@ -23,7 +23,9 @@ partition@70000 { label = "firmware"; reg = <0x070000 0xf80000>; - compatible = "netgear,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = <0x33373031>; + openwrt,ih-type = ; }; art: partition@ff0000 { diff --git a/target/linux/ath79/dts/ar7240_netgear_wnr1000-v2.dts b/target/linux/ath79/dts/ar7240_netgear_wnr1000-v2.dts index d700ea73fa..0c94c90284 100644 --- a/target/linux/ath79/dts/ar7240_netgear_wnr1000-v2.dts +++ b/target/linux/ath79/dts/ar7240_netgear_wnr1000-v2.dts @@ -4,6 +4,7 @@ #include #include +#include / { compatible = "netgear,wnr1000-v2", "qca,ar7240"; @@ -158,7 +159,9 @@ partition@50000 { label = "firmware"; reg = <0x50000 0x3a0000>; - compatible = "netgear,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = <0x31303031>; + openwrt,ih-type = ; }; art: partition@3f0000 { diff --git a/target/linux/ath79/dts/ar7240_netgear_wnr612-v2.dtsi b/target/linux/ath79/dts/ar7240_netgear_wnr612-v2.dtsi index 382529b32d..0360412598 100644 --- a/target/linux/ath79/dts/ar7240_netgear_wnr612-v2.dtsi +++ b/target/linux/ath79/dts/ar7240_netgear_wnr612-v2.dtsi @@ -4,6 +4,7 @@ #include #include +#include / { aliases { @@ -89,7 +90,9 @@ }; partition@50000 { - compatible = "netgear,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = <0x32303631>; + openwrt,ih-type = ; reg = <0x50000 0x3a0000>; label = "firmware"; }; diff --git a/target/linux/ath79/dts/ar7241_netgear_wnr2000-v3.dts b/target/linux/ath79/dts/ar7241_netgear_wnr2000-v3.dts index 2e7ea746df..831f3e9c25 100644 --- a/target/linux/ath79/dts/ar7241_netgear_wnr2000-v3.dts +++ b/target/linux/ath79/dts/ar7241_netgear_wnr2000-v3.dts @@ -4,6 +4,7 @@ #include #include +#include / { compatible = "netgear,wnr2000-v3", "qca,ar7241"; @@ -161,7 +162,9 @@ partition@50000 { label = "firmware"; reg = <0x50000 0x3a0000>; - compatible = "netgear,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = <0x32303033>; + openwrt,ih-type = ; }; art: partition@3f0000 { diff --git a/target/linux/ath79/dts/ar7241_netgear_wnr2200-16m.dts b/target/linux/ath79/dts/ar7241_netgear_wnr2200-16m.dts index 2c74436547..3842238e54 100644 --- a/target/linux/ath79/dts/ar7241_netgear_wnr2200-16m.dts +++ b/target/linux/ath79/dts/ar7241_netgear_wnr2200-16m.dts @@ -22,7 +22,9 @@ partition@50000 { label = "firmware"; reg = <0x50000 0xfa0000>; - compatible = "netgear,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = <0x32323030>; + openwrt,ih-type = ; }; art: partition@ff0000 { diff --git a/target/linux/ath79/dts/ar7241_netgear_wnr2200-8m.dts b/target/linux/ath79/dts/ar7241_netgear_wnr2200-8m.dts index c23cb6e002..4eb15e2313 100644 --- a/target/linux/ath79/dts/ar7241_netgear_wnr2200-8m.dts +++ b/target/linux/ath79/dts/ar7241_netgear_wnr2200-8m.dts @@ -22,7 +22,9 @@ partition@50000 { label = "firmware"; reg = <0x50000 0x7a0000>; - compatible = "netgear,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = <0x32323030>; + openwrt,ih-type = ; }; art: partition@7f0000 { diff --git a/target/linux/ath79/dts/ar7241_netgear_wnr2200.dtsi b/target/linux/ath79/dts/ar7241_netgear_wnr2200.dtsi index c61e188e32..625f4b0684 100644 --- a/target/linux/ath79/dts/ar7241_netgear_wnr2200.dtsi +++ b/target/linux/ath79/dts/ar7241_netgear_wnr2200.dtsi @@ -4,6 +4,7 @@ #include #include +#include / { chosen { diff --git a/target/linux/ath79/dts/ar9344_netgear_wndr.dtsi b/target/linux/ath79/dts/ar9344_netgear_wndr.dtsi index 26f9db5924..ac012eafb4 100644 --- a/target/linux/ath79/dts/ar9344_netgear_wndr.dtsi +++ b/target/linux/ath79/dts/ar9344_netgear_wndr.dtsi @@ -4,6 +4,7 @@ #include #include +#include / { chosen { @@ -161,7 +162,9 @@ partition@6c0000 { label = "firmware"; reg = <0x6c0000 0x1900000>; - compatible = "netgear,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = <0x33373033>; + openwrt,ih-type = ; }; partition@1fc0000 { diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c index ef2d857abb..c29eb6234b 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c @@ -271,72 +271,6 @@ static struct mtd_part_parser uimage_generic_parser = { .type = MTD_PARSER_TYPE_FIRMWARE, }; -#define FW_MAGIC_GS110TPPV1 0x4e474520 -#define FW_MAGIC_WNR2000V1 0x32303031 -#define FW_MAGIC_WNR2000V3 0x32303033 -#define FW_MAGIC_WNR2000V4 0x32303034 -#define FW_MAGIC_WNR2200 0x32323030 -#define FW_MAGIC_WNR612V2 0x32303631 -#define FW_MAGIC_WNR1000V2 0x31303031 -#define FW_MAGIC_WNR1000V2_VC 0x31303030 -#define FW_MAGIC_WNDR3700 0x33373030 -#define FW_MAGIC_WNDR3700V2 0x33373031 -#define FW_MAGIC_WPN824N 0x31313030 - -static ssize_t uimage_verify_wndr3700(u_char *buf, size_t len, u32 ih_magic, u32 ih_type) -{ - struct uimage_header *header = (struct uimage_header *)buf; - uint8_t expected_type = IH_TYPE_FILESYSTEM; - - switch (be32_to_cpu(header->ih_magic)) { - case FW_MAGIC_GS110TPPV1: - case FW_MAGIC_WNR2000V4: - expected_type = IH_TYPE_KERNEL; - break; - case FW_MAGIC_WNR612V2: - case FW_MAGIC_WNR1000V2: - case FW_MAGIC_WNR1000V2_VC: - case FW_MAGIC_WNR2000V1: - case FW_MAGIC_WNR2000V3: - case FW_MAGIC_WNR2200: - case FW_MAGIC_WNDR3700: - case FW_MAGIC_WNDR3700V2: - case FW_MAGIC_WPN824N: - break; - default: - return -EINVAL; - } - - if (header->ih_os != IH_OS_LINUX || - header->ih_type != expected_type) - return -EINVAL; - - return 0; -} - -static int -mtdsplit_uimage_parse_netgear(struct mtd_info *master, - const struct mtd_partition **pparts, - struct mtd_part_parser_data *data) -{ - return __mtdsplit_parse_uimage(master, pparts, data, - uimage_verify_wndr3700); -} - -static const struct of_device_id mtdsplit_uimage_netgear_of_match_table[] = { - { .compatible = "netgear,uimage" }, - {}, -}; - -static struct mtd_part_parser uimage_netgear_parser = { - .owner = THIS_MODULE, - .name = "netgear-fw", - .of_match_table = mtdsplit_uimage_netgear_of_match_table, - .parse_fn = mtdsplit_uimage_parse_netgear, - .type = MTD_PARSER_TYPE_FIRMWARE, - -}; - /************************************************** * Edimax **************************************************/ @@ -393,7 +327,6 @@ static struct mtd_part_parser uimage_edimax_parser = { static int __init mtdsplit_uimage_init(void) { register_mtd_parser(&uimage_generic_parser); - register_mtd_parser(&uimage_netgear_parser); register_mtd_parser(&uimage_edimax_parser); return 0; diff --git a/target/linux/realtek/dts/rtl8380_netgear_gs110tpp-v1.dts b/target/linux/realtek/dts/rtl8380_netgear_gs110tpp-v1.dts index 251585a8da..cd9342f3f1 100644 --- a/target/linux/realtek/dts/rtl8380_netgear_gs110tpp-v1.dts +++ b/target/linux/realtek/dts/rtl8380_netgear_gs110tpp-v1.dts @@ -70,7 +70,8 @@ }; partition@300000{ label = "firmware"; - compatible = "netgear,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = <0x4e474520>; reg = <0x0300000 0x1d00000>; }; }; From 3f36dffbdee0d08f982950490b6d2bfb6568d376 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 20 Jan 2021 18:36:52 +0100 Subject: [PATCH 28/34] kernel: mtdsplit_uimage: add "openwrt, offset" and "openwrt, partition-magic" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some devices prepend a standard U-Boot Image with a vendor specific header, having its own magic. Adding two new properties will support validation of such images, including the additional magic. Signed-off-by: Bjørn Mork --- .../drivers/mtd/mtdsplit/mtdsplit_uimage.c | 40 +++++++++++++------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c index c29eb6234b..7a8ccdf8f5 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c @@ -70,7 +70,8 @@ read_uimage_header(struct mtd_info *mtd, size_t offset, u_char *buf, } static void uimage_parse_dt(struct mtd_info *master, int *extralen, - u32 *ih_magic, u32 *ih_type) + u32 *ih_magic, u32 *ih_type, + u32 *header_offset, u32 *part_magic) { struct device_node *np = mtd_get_of_node(master); @@ -83,6 +84,10 @@ static void uimage_parse_dt(struct mtd_info *master, int *extralen, pr_debug("got openwrt,ih-magic=%08x from device-tree\n", *ih_magic); if (!of_property_read_u32(np, "openwrt,ih-type", ih_type)) pr_debug("got openwrt,ih-type=%08x from device-tree\n", *ih_type); + if (!of_property_read_u32(np, "openwrt,offset", header_offset)) + pr_debug("got ih-start=%u from device-tree\n", *header_offset); + if (!of_property_read_u32(np, "openwrt,partition-magic", part_magic)) + pr_debug("got openwrt,partition-magic=%08x from device-tree\n", *part_magic); } /** @@ -92,9 +97,9 @@ static void uimage_parse_dt(struct mtd_info *master, int *extralen, * and tail padding length of a valid uImage header if found */ static int __mtdsplit_parse_uimage(struct mtd_info *master, - const struct mtd_partition **pparts, - struct mtd_part_parser_data *data, - ssize_t (*find_header)(u_char *buf, size_t len, u32 ih_magic, u32 ih_type)) + const struct mtd_partition **pparts, + struct mtd_part_parser_data *data, + ssize_t (*find_header)(u_char *buf, size_t len, u32 ih_magic, u32 ih_type)) { struct mtd_partition *parts; u_char *buf; @@ -104,11 +109,14 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, size_t uimage_size = 0; size_t rootfs_offset; size_t rootfs_size = 0; + size_t buflen; int uimage_part, rf_part; int ret; int extralen = 0; u32 ih_magic = IH_MAGIC; u32 ih_type = IH_TYPE_KERNEL; + u32 header_offset = 0; + u32 part_magic = 0; enum mtdsplit_part_type type; nr_parts = 2; @@ -116,34 +124,42 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, if (!parts) return -ENOMEM; - buf = vmalloc(MAX_HEADER_LEN); + uimage_parse_dt(master, &extralen, &ih_magic, &ih_type, &header_offset, &part_magic); + buflen = MAX_HEADER_LEN; + buf = vmalloc(buflen); if (!buf) { ret = -ENOMEM; goto err_free_parts; } - uimage_parse_dt(master, &extralen, &ih_magic, &ih_type); - /* find uImage on erase block boundaries */ for (offset = 0; offset < master->size; offset += master->erasesize) { struct uimage_header *header; uimage_size = 0; - ret = read_uimage_header(master, offset, buf, MAX_HEADER_LEN); + ret = read_uimage_header(master, offset, buf, buflen); if (ret) continue; - ret = find_header(buf, MAX_HEADER_LEN, ih_magic, ih_type); + /* verify optional partition magic before uimage header */ + if (header_offset && part_magic && (be32_to_cpu(*(u32 *)buf) != part_magic)) + continue; + + ret = find_header(buf + header_offset, buflen, ih_magic, ih_type); if (ret < 0) { pr_debug("no valid uImage found in \"%s\" at offset %llx\n", master->name, (unsigned long long) offset); continue; } - header = (struct uimage_header *)(buf + ret); + + /* let uimage_find_edimax override the offset */ + if (ret > 0) + header_offset = ret; + header = (struct uimage_header *)(buf + header_offset); uimage_size = sizeof(*header) + - be32_to_cpu(header->ih_size) + ret + extralen; + be32_to_cpu(header->ih_size) + header_offset + extralen; if ((offset + uimage_size) > master->size) { pr_debug("uImage exceeds MTD device \"%s\"\n", @@ -254,7 +270,7 @@ mtdsplit_uimage_parse_generic(struct mtd_info *master, struct mtd_part_parser_data *data) { return __mtdsplit_parse_uimage(master, pparts, data, - uimage_verify_default); + uimage_verify_default); } static const struct of_device_id mtdsplit_uimage_of_match_table[] = { From 402408b36840e078b8a98d66163d72e48ca3275b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 20 Jan 2021 18:36:53 +0100 Subject: [PATCH 29/34] kernel: mtdsplit_uimage: replace "edimax, uimage" parser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "edimax,uimage"" parser can be replaced by the generic parser using device specific openwrt,partition-magic and openwrt,offset properties. Signed-off-by: Bjørn Mork --- .../drivers/mtd/mtdsplit/mtdsplit_uimage.c | 129 ++++-------------- .../dt-bindings/mtd/partitions/uimage.h | 2 + .../dts/mt7620a_edimax_br-6478ac-v2.dts | 5 +- .../ramips/dts/mt7620a_edimax_ew-7478apc.dts | 5 +- .../ramips/dts/mt7620a_edimax_ew-747x.dtsi | 5 +- .../linux/ramips/dts/mt7621_edimax_re23s.dts | 5 +- .../ramips/dts/rt3050_edimax_3g-6200n.dts | 5 +- .../ramips/dts/rt3050_edimax_3g-6200nl.dts | 5 +- .../ramips/dts/rt3662_edimax_br-6475nd.dts | 5 +- 9 files changed, 60 insertions(+), 106 deletions(-) diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c index 7a8ccdf8f5..a3e55fb1fe 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c @@ -23,12 +23,6 @@ #include "mtdsplit.h" -/* - * uimage_header itself is only 64B, but it may be prepended with another data. - * Currently the biggest size is for Fon(Foxconn) devices: 64B + 32B - */ -#define MAX_HEADER_LEN 96 - /* * Legacy format image header, * all data in network byte order (aka natural aka bigendian). @@ -90,6 +84,32 @@ static void uimage_parse_dt(struct mtd_info *master, int *extralen, pr_debug("got openwrt,partition-magic=%08x from device-tree\n", *part_magic); } +static ssize_t uimage_verify_default(u_char *buf, u32 ih_magic, u32 ih_type) +{ + struct uimage_header *header = (struct uimage_header *)buf; + + /* default sanity checks */ + if (be32_to_cpu(header->ih_magic) != ih_magic) { + pr_debug("invalid uImage magic: %08x != %08x\n", + be32_to_cpu(header->ih_magic), ih_magic); + return -EINVAL; + } + + if (header->ih_os != IH_OS_LINUX) { + pr_debug("invalid uImage OS: %08x != %08x\n", + be32_to_cpu(header->ih_os), IH_OS_LINUX); + return -EINVAL; + } + + if (header->ih_type != ih_type) { + pr_debug("invalid uImage type: %08x != %08x\n", + be32_to_cpu(header->ih_type), ih_type); + return -EINVAL; + } + + return 0; +} + /** * __mtdsplit_parse_uimage - scan partition and create kernel + rootfs parts * @@ -98,8 +118,7 @@ static void uimage_parse_dt(struct mtd_info *master, int *extralen, */ static int __mtdsplit_parse_uimage(struct mtd_info *master, const struct mtd_partition **pparts, - struct mtd_part_parser_data *data, - ssize_t (*find_header)(u_char *buf, size_t len, u32 ih_magic, u32 ih_type)) + struct mtd_part_parser_data *data) { struct mtd_partition *parts; u_char *buf; @@ -125,7 +144,7 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, return -ENOMEM; uimage_parse_dt(master, &extralen, &ih_magic, &ih_type, &header_offset, &part_magic); - buflen = MAX_HEADER_LEN; + buflen = sizeof(struct uimage_header) + header_offset; buf = vmalloc(buflen); if (!buf) { ret = -ENOMEM; @@ -146,16 +165,13 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, if (header_offset && part_magic && (be32_to_cpu(*(u32 *)buf) != part_magic)) continue; - ret = find_header(buf + header_offset, buflen, ih_magic, ih_type); + ret = uimage_verify_default(buf + header_offset, ih_magic, ih_type); if (ret < 0) { pr_debug("no valid uImage found in \"%s\" at offset %llx\n", master->name, (unsigned long long) offset); continue; } - /* let uimage_find_edimax override the offset */ - if (ret > 0) - header_offset = ret; header = (struct uimage_header *)(buf + header_offset); uimage_size = sizeof(*header) + @@ -238,41 +254,6 @@ err_free_parts: return ret; } -static ssize_t uimage_verify_default(u_char *buf, size_t len, u32 ih_magic, u32 ih_type) -{ - struct uimage_header *header = (struct uimage_header *)buf; - - /* default sanity checks */ - if (be32_to_cpu(header->ih_magic) != ih_magic) { - pr_debug("invalid uImage magic: %08x != %08x\n", - be32_to_cpu(header->ih_magic), ih_magic); - return -EINVAL; - } - - if (header->ih_os != IH_OS_LINUX) { - pr_debug("invalid uImage OS: %08x != %08x\n", - be32_to_cpu(header->ih_os), IH_OS_LINUX); - return -EINVAL; - } - - if (header->ih_type != ih_type) { - pr_debug("invalid uImage type: %08x != %08x\n", - be32_to_cpu(header->ih_type), ih_type); - return -EINVAL; - } - - return 0; -} - -static int -mtdsplit_uimage_parse_generic(struct mtd_info *master, - const struct mtd_partition **pparts, - struct mtd_part_parser_data *data) -{ - return __mtdsplit_parse_uimage(master, pparts, data, - uimage_verify_default); -} - static const struct of_device_id mtdsplit_uimage_of_match_table[] = { { .compatible = "denx,uimage" }, { .compatible = "openwrt,uimage" }, @@ -283,59 +264,10 @@ static struct mtd_part_parser uimage_generic_parser = { .owner = THIS_MODULE, .name = "uimage-fw", .of_match_table = mtdsplit_uimage_of_match_table, - .parse_fn = mtdsplit_uimage_parse_generic, + .parse_fn = __mtdsplit_parse_uimage, .type = MTD_PARSER_TYPE_FIRMWARE, }; -/************************************************** - * Edimax - **************************************************/ - -#define FW_EDIMAX_OFFSET 20 -#define FW_MAGIC_EDIMAX 0x43535953 - -static ssize_t uimage_find_edimax(u_char *buf, size_t len, u32 ih_magic, u32 ih_type) -{ - u32 *magic; - - if (len < FW_EDIMAX_OFFSET + sizeof(struct uimage_header)) { - pr_err("Buffer too small for checking Edimax header\n"); - return -ENOSPC; - } - - magic = (u32 *)buf; - if (be32_to_cpu(*magic) != FW_MAGIC_EDIMAX) - return -EINVAL; - - if (!uimage_verify_default(buf + FW_EDIMAX_OFFSET, len, ih_magic, ih_type)) - return FW_EDIMAX_OFFSET; - - return -EINVAL; -} - -static int -mtdsplit_uimage_parse_edimax(struct mtd_info *master, - const struct mtd_partition **pparts, - struct mtd_part_parser_data *data) -{ - return __mtdsplit_parse_uimage(master, pparts, data, - uimage_find_edimax); -} - -static const struct of_device_id mtdsplit_uimage_edimax_of_match_table[] = { - { .compatible = "edimax,uimage" }, - {}, -}; - -static struct mtd_part_parser uimage_edimax_parser = { - .owner = THIS_MODULE, - .name = "edimax-fw", - .of_match_table = mtdsplit_uimage_edimax_of_match_table, - .parse_fn = mtdsplit_uimage_parse_edimax, - .type = MTD_PARSER_TYPE_FIRMWARE, -}; - - /************************************************** * Init **************************************************/ @@ -343,7 +275,6 @@ static struct mtd_part_parser uimage_edimax_parser = { static int __init mtdsplit_uimage_init(void) { register_mtd_parser(&uimage_generic_parser); - register_mtd_parser(&uimage_edimax_parser); return 0; } diff --git a/target/linux/generic/files/include/dt-bindings/mtd/partitions/uimage.h b/target/linux/generic/files/include/dt-bindings/mtd/partitions/uimage.h index 407e46ce2c..43d5f7b5da 100644 --- a/target/linux/generic/files/include/dt-bindings/mtd/partitions/uimage.h +++ b/target/linux/generic/files/include/dt-bindings/mtd/partitions/uimage.h @@ -192,5 +192,7 @@ * Magic values specific to "openwrt,uimage" partitions */ #define IH_MAGIC_OKLI 0x4f4b4c49 /* 'OKLI' */ +#define FW_EDIMAX_OFFSET 20 /* Edimax Firmware Offset */ +#define FW_MAGIC_EDIMAX 0x43535953 /* Edimax Firmware Magic Number */ #endif /* __UIMAGE_H__ */ diff --git a/target/linux/ramips/dts/mt7620a_edimax_br-6478ac-v2.dts b/target/linux/ramips/dts/mt7620a_edimax_br-6478ac-v2.dts index 0b991611b2..773db22c74 100644 --- a/target/linux/ramips/dts/mt7620a_edimax_br-6478ac-v2.dts +++ b/target/linux/ramips/dts/mt7620a_edimax_br-6478ac-v2.dts @@ -15,6 +15,7 @@ #include #include +#include / { compatible = "edimax,br-6478ac-v2", "ralink,mt7620a-soc"; @@ -116,7 +117,9 @@ }; partition@70000 { - compatible = "edimax,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,offset = ; + openwrt,partition-magic = ; label = "firmware"; reg = <0x00070000 0x00790000>; }; diff --git a/target/linux/ramips/dts/mt7620a_edimax_ew-7478apc.dts b/target/linux/ramips/dts/mt7620a_edimax_ew-7478apc.dts index 1e1b2830f0..77d214e888 100644 --- a/target/linux/ramips/dts/mt7620a_edimax_ew-7478apc.dts +++ b/target/linux/ramips/dts/mt7620a_edimax_ew-7478apc.dts @@ -4,6 +4,7 @@ #include #include +#include / { compatible = "edimax,ew-7478apc", "ralink,mt7620a-soc"; @@ -102,7 +103,9 @@ }; partition@70000 { - compatible = "edimax,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,offset = ; + openwrt,partition-magic = ; label = "firmware"; reg = <0x00070000 0x00790000>; }; diff --git a/target/linux/ramips/dts/mt7620a_edimax_ew-747x.dtsi b/target/linux/ramips/dts/mt7620a_edimax_ew-747x.dtsi index 78b481bd2a..d17cc090c2 100644 --- a/target/linux/ramips/dts/mt7620a_edimax_ew-747x.dtsi +++ b/target/linux/ramips/dts/mt7620a_edimax_ew-747x.dtsi @@ -4,6 +4,7 @@ #include #include +#include / { compatible = "ralink,mt7620a-soc"; @@ -122,7 +123,9 @@ }; partition@70000 { - compatible = "edimax,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,offset = ; + openwrt,partition-magic = ; label = "firmware"; reg = <0x00070000 0x00790000>; }; diff --git a/target/linux/ramips/dts/mt7621_edimax_re23s.dts b/target/linux/ramips/dts/mt7621_edimax_re23s.dts index cf44746e8f..9b96573446 100644 --- a/target/linux/ramips/dts/mt7621_edimax_re23s.dts +++ b/target/linux/ramips/dts/mt7621_edimax_re23s.dts @@ -4,6 +4,7 @@ #include #include +#include / { compatible = "edimax,re23s", "mediatek,mt7621-soc"; @@ -97,7 +98,9 @@ }; partition@70000 { - compatible = "edimax,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,offset = ; + openwrt,partition-magic = ; label = "firmware"; reg = <0x70000 0xf50000>; }; diff --git a/target/linux/ramips/dts/rt3050_edimax_3g-6200n.dts b/target/linux/ramips/dts/rt3050_edimax_3g-6200n.dts index a185e5d5bb..07ff8bc9bc 100644 --- a/target/linux/ramips/dts/rt3050_edimax_3g-6200n.dts +++ b/target/linux/ramips/dts/rt3050_edimax_3g-6200n.dts @@ -2,6 +2,7 @@ #include #include +#include / { compatible = "edimax,3g-6200n", "ralink,rt3050-soc"; @@ -50,7 +51,9 @@ }; partition@50000 { - compatible = "edimax,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,offset = ; + openwrt,partition-magic = ; label = "firmware"; reg = <0x50000 0x390000>; }; diff --git a/target/linux/ramips/dts/rt3050_edimax_3g-6200nl.dts b/target/linux/ramips/dts/rt3050_edimax_3g-6200nl.dts index 41768078f5..f339b7ebe8 100644 --- a/target/linux/ramips/dts/rt3050_edimax_3g-6200nl.dts +++ b/target/linux/ramips/dts/rt3050_edimax_3g-6200nl.dts @@ -2,6 +2,7 @@ #include #include +#include / { compatible = "edimax,3g-6200nl", "ralink,rt3050-soc"; @@ -50,7 +51,9 @@ }; partition@50000 { - compatible = "edimax,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,offset = ; + openwrt,partition-magic = ; label = "firmware"; reg = <0x50000 0x390000>; }; diff --git a/target/linux/ramips/dts/rt3662_edimax_br-6475nd.dts b/target/linux/ramips/dts/rt3662_edimax_br-6475nd.dts index a1e7c837d1..56d9dc0894 100644 --- a/target/linux/ramips/dts/rt3662_edimax_br-6475nd.dts +++ b/target/linux/ramips/dts/rt3662_edimax_br-6475nd.dts @@ -2,6 +2,7 @@ #include #include +#include / { compatible = "edimax,br-6475nd", "ralink,rt3662-soc", "ralink,rt3883-soc"; @@ -86,7 +87,9 @@ }; partition@70000 { - compatible = "edimax,uimage"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,offset = ; + openwrt,partition-magic = ; reg = <0x00070000 0x00790000>; label = "firmware"; }; From ad54af2ae0281707c60073bacc1c5fb7be096710 Mon Sep 17 00:00:00 2001 From: Florian Eckert Date: Fri, 22 Jan 2021 10:14:48 +0100 Subject: [PATCH 30/34] iperf: remove This package is not needed in base. It will be imported in the packages feed. Signed-off-by: Florian Eckert --- package/network/utils/iperf/Makefile | 68 ------------------- .../patches/0003-fix-non-ipv6-builds.patch | 20 ------ .../utils/iperf/patches/010-libcxx.patch | 12 ---- 3 files changed, 100 deletions(-) delete mode 100644 package/network/utils/iperf/Makefile delete mode 100644 package/network/utils/iperf/patches/0003-fix-non-ipv6-builds.patch delete mode 100644 package/network/utils/iperf/patches/010-libcxx.patch diff --git a/package/network/utils/iperf/Makefile b/package/network/utils/iperf/Makefile deleted file mode 100644 index d739b063ca..0000000000 --- a/package/network/utils/iperf/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -# -# Copyright (C) 2007-2010 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=iperf -PKG_VERSION:=2.0.13 -PKG_RELEASE:=2 - -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_HASH:=c88adec966096a81136dda91b4bd19c27aae06df4d45a7f547a8e50d723778ad -PKG_SOURCE_URL:=@SF/iperf2 - -PKG_MAINTAINER:=Felix Fietkau -PKG_LICENSE:=BSD-3-Clause - -PKG_BUILD_PARALLEL:=1 - -PKG_CONFIG_DEPENDS:=CONFIG_IPERF_ENABLE_MULTICAST - -include $(INCLUDE_DIR)/uclibc++.mk -include $(INCLUDE_DIR)/package.mk - -define Package/iperf - SECTION:=net - CATEGORY:=Network - DEPENDS:= $(CXX_DEPENDS) +libpthread - TITLE:=Internet Protocol bandwidth measuring tool - URL:=http://sourceforge.net/projects/iperf2/ -endef - -define Package/iperf/description - Iperf is a modern alternative for measuring TCP and UDP bandwidth - performance, allowing the tuning of various parameters and - characteristics. -endef - -define Package/iperf/config - config IPERF_ENABLE_MULTICAST - depends on PACKAGE_iperf - bool "Enable multicast support" -endef - - -TARGET_CFLAGS += -D_GNU_SOURCE -ifeq ($(CONFIG_IPERF_ENABLE_MULTICAST),y) -CONFIGURE_ARGS += --enable-multicast -else -CONFIGURE_ARGS += --disable-multicast -endif - -ifeq ($(CONFIG_IPV6),) - CONFIGURE_ARGS += --disable-ipv6 -endif - -CONFIGURE_VARS += CXXFLAGS="$$$$CXXFLAGS -fno-rtti" -CONFIGURE_VARS += LIBS="-lpthread -lm" - -define Package/iperf/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/iperf $(1)/usr/bin/iperf -endef - -$(eval $(call BuildPackage,iperf)) diff --git a/package/network/utils/iperf/patches/0003-fix-non-ipv6-builds.patch b/package/network/utils/iperf/patches/0003-fix-non-ipv6-builds.patch deleted file mode 100644 index c6afa3e160..0000000000 --- a/package/network/utils/iperf/patches/0003-fix-non-ipv6-builds.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/src/Listener.cpp -+++ b/src/Listener.cpp -@@ -723,6 +723,7 @@ int Listener::L2_setup (void) { - - // Now optimize packet flow up the raw socket - // Establish the flow BPF to forward up only "connected" packets to this raw socket -+#ifdef HAVE_IPV6 - if (l->sa_family == AF_INET6) { - #ifdef HAVE_IPV6 - struct in6_addr *v6peer = SockAddr_get_in6_addr(&server->peer); -@@ -740,6 +741,9 @@ int Listener::L2_setup (void) { - return -1; - #endif /* HAVE_IPV6 */ - } else { -+#else -+ { -+#endif - rc = SockAddr_v4_Connect_BPF(server->mSock, ((struct sockaddr_in *)(l))->sin_addr.s_addr, ((struct sockaddr_in *)(p))->sin_addr.s_addr, ((struct sockaddr_in *)(l))->sin_port, ((struct sockaddr_in *)(p))->sin_port); - WARN_errno( rc == SOCKET_ERROR, "l2 connect ip bpf"); - } diff --git a/package/network/utils/iperf/patches/010-libcxx.patch b/package/network/utils/iperf/patches/010-libcxx.patch deleted file mode 100644 index cf0124232f..0000000000 --- a/package/network/utils/iperf/patches/010-libcxx.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/config.h.in -+++ b/config.h.in -@@ -360,7 +360,9 @@ - #undef _REENTRANT - - /* */ -+#ifndef __cplusplus - #undef bool -+#endif - - /* Define to empty if `const' does not conform to ANSI C. */ - #undef const From e779d30f32836a89fc8e5997edc9a5444283ae15 Mon Sep 17 00:00:00 2001 From: Florian Eckert Date: Fri, 22 Jan 2021 13:06:10 +0100 Subject: [PATCH 31/34] iperf3: remove This package is not needed in base. It will be imported in the packages feed. Signed-off-by: Florian Eckert --- package/network/utils/iperf3/Makefile | 83 --------------------------- 1 file changed, 83 deletions(-) delete mode 100644 package/network/utils/iperf3/Makefile diff --git a/package/network/utils/iperf3/Makefile b/package/network/utils/iperf3/Makefile deleted file mode 100644 index 6f90bc9221..0000000000 --- a/package/network/utils/iperf3/Makefile +++ /dev/null @@ -1,83 +0,0 @@ -# -# Copyright (C) 2007-2010 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=iperf -PKG_VERSION:=3.9 -PKG_RELEASE:=1 - -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=https://downloads.es.net/pub/iperf -PKG_HASH:=24b63a26382325f759f11d421779a937b63ca1bc17c44587d2fcfedab60ac038 - -PKG_MAINTAINER:=Felix Fietkau -PKG_LICENSE:=BSD-3-Clause - -PKG_BUILD_PARALLEL:=1 -PKG_INSTALL:=1 - -PKG_FIXUP:=autoreconf - -include $(INCLUDE_DIR)/package.mk - -DISABLE_NLS:= - -define Package/iperf3/default - SECTION:=net - CATEGORY:=Network - TITLE:=Internet Protocol bandwidth measuring tool - URL:=https://github.com/esnet/iperf -endef - -define Package/iperf3 -$(call Package/iperf3/default) - VARIANT:=nossl -endef - -define Package/iperf3-ssl -$(call Package/iperf3/default) - TITLE+= with iperf_auth support - VARIANT:=ssl - DEPENDS:= +libopenssl -endef - -TARGET_CFLAGS += -D_GNU_SOURCE -CONFIGURE_ARGS += --disable-shared - -ifeq ($(BUILD_VARIANT),ssl) - CONFIGURE_ARGS += --with-openssl="$(STAGING_DIR)/usr" -else - CONFIGURE_ARGS += --without-openssl -endif - -MAKE_FLAGS += noinst_PROGRAMS= - -define Package/iperf3/description - Iperf is a modern alternative for measuring TCP and UDP bandwidth - performance, allowing the tuning of various parameters and - characteristics. -endef - -# autoreconf fails if the README file isn't present -define Build/Prepare - $(call Build/Prepare/Default) - touch $(PKG_BUILD_DIR)/README -endef - -define Package/iperf3/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/iperf3 $(1)/usr/bin/ -endef - -define Package/iperf3-ssl/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/iperf3 $(1)/usr/bin/ -endef - -$(eval $(call BuildPackage,iperf3)) -$(eval $(call BuildPackage,iperf3-ssl)) From 9ae3c6f94c616cfbf854d3ec749c7fafc9893942 Mon Sep 17 00:00:00 2001 From: Paul Spooren Date: Fri, 1 Jan 2021 14:02:12 -1000 Subject: [PATCH 32/34] rules: add AUTORELEASE and COMMITCOUNT variables The lack of bumped PKG_RELEASE variables is a recurring theme on the mailing list and in GitHub comments. This costs precious review time, a rare good within the OpenWrt project. Instead of relying on a manually set PKG_RELEASE this commit adds a `commitcount` function that uses the number of Git commits to determine the release. The function is called via the variables `$(AUTORELEASE)` or `$(COMMITCOUNT)`. The `PKG_RELEASE` variable can be set to either of the two. - $(AUTORELEASE): Release is automagically set to the number of commits since the last commit containing either ": update to " or ": bump to ". Example below: $ git log packages/foobar/ foobar: fixup file location foobar: disable docs foobar: bump to 5.3.2 foobar: fixup copyright Resulting package name: foobar_5.3.2-3_all.ipk, two package changes since the last upstream version change, using a 1 based counter. - $(COMMITCOUNT): For non-traditional versioning (x.y.z), most prominent `base-files`, this variable contains the total number of package commits. The new functionality can also be used by other feeds like packages.git. In case no build information is available, e.g. when using release tarballs, the SOURCE_DATE_EPOCH is used to have a reproducible release identifier. Suggested-by: Daniel Golle Signed-off-by: Paul Spooren --- rules.mk | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/rules.mk b/rules.mk index f79340b124..cf4aa30d21 100644 --- a/rules.mk +++ b/rules.mk @@ -408,6 +408,32 @@ endef # file extension ext=$(word $(words $(subst ., ,$(1))),$(subst ., ,$(1))) +# Count Git commits of a package +# $(1) => if non-empty: count commits since last ": [uU]pdate to " or ": [bB]ump to " in commit message +define commitcount +$(shell \ + if git log -1 >/dev/null 2>/dev/null; then \ + if [ -n "$(1)" ]; then \ + last_bump="$$(git log --pretty=format:'%h %s' . | \ + grep --max-count=1 -e ': [uU]pdate to ' -e ': [bB]ump to ' | \ + cut -f 1 -d ' ')"; \ + fi; \ + if [ -n "$$last_bump" ]; then \ + echo -n $$(($$(git rev-list --count "$$last_bump..HEAD" .) + 1)); \ + else \ + echo -n $$(($$(git rev-list --count HEAD .) + 1)); \ + fi; \ + else \ + secs="$$(($(SOURCE_DATE_EPOCH) % 86400))"; \ + date="$$(date --utc --date="@$(SOURCE_DATE_EPOCH)" "+%y%m%d")"; \ + printf '%s.%05d' "$$date" "$$secs"; \ + fi; \ +) +endef + +COMMITCOUNT = $(if $(DUMP),,$(call commitcount)) +AUTORELEASE = $(if $(DUMP),,$(call commitcount,1)) + all: FORCE: ; .PHONY: FORCE From aa589c77b4e431455f2de225bbf38a391f76aad6 Mon Sep 17 00:00:00 2001 From: Paul Spooren Date: Fri, 1 Jan 2021 14:18:32 -1000 Subject: [PATCH 33/34] base-files: use $(COMMITCOUNT) in PKG_RELEASE The newly added `$(COMMITCOUNT)` varialbe allows automatic versioning based on the number of Git commits of a package. Replace *tedious to bump* and *merge conflict causing* `PKG_RELEASE` and replace it with `$(COMMITCOUNT)`. Signed-off-by: Paul Spooren --- package/base-files/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/base-files/Makefile b/package/base-files/Makefile index f18f221129..d134641cb9 100644 --- a/package/base-files/Makefile +++ b/package/base-files/Makefile @@ -12,8 +12,8 @@ include $(INCLUDE_DIR)/version.mk include $(INCLUDE_DIR)/feeds.mk PKG_NAME:=base-files -PKG_RELEASE:=246 PKG_FLAGS:=nonshared +PKG_RELEASE:=$(COMMITCOUNT) PKG_FILE_DEPENDS:=$(PLATFORM_DIR)/ $(GENERIC_PLATFORM_DIR)/base-files/ PKG_BUILD_DEPENDS:=usign/host ucert/host From 465eaa0e0701253dc2ce9101073f94aba741c323 Mon Sep 17 00:00:00 2001 From: Paul Spooren Date: Wed, 6 Jan 2021 22:56:54 -1000 Subject: [PATCH 34/34] uboot-envtools: use $(AUTORELEASE) for PKG_RELEASE Use `$(AUTORELEASE)` variable rather than setting a PKG_RELEASE on every commit manually. Signed-off-by: Paul Spooren --- package/boot/uboot-envtools/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/boot/uboot-envtools/Makefile b/package/boot/uboot-envtools/Makefile index dda9d6be9c..5014b71ef6 100644 --- a/package/boot/uboot-envtools/Makefile +++ b/package/boot/uboot-envtools/Makefile @@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=uboot-envtools PKG_DISTNAME:=u-boot PKG_VERSION:=2020.04 -PKG_RELEASE:=20 +PKG_RELEASE:=$(AUTORELEASE) PKG_SOURCE:=$(PKG_DISTNAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:= \