diff --git a/target/linux/ath79/config-5.4 b/target/linux/ath79/config-5.4 index 60f57692e2..e47398ce2b 100644 --- a/target/linux/ath79/config-5.4 +++ b/target/linux/ath79/config-5.4 @@ -175,6 +175,7 @@ CONFIG_MTD_CMDLINE_PARTS=y # CONFIG_MTD_MAP_BANK_WIDTH_4 is not set # CONFIG_MTD_NAND_RB91X is not set CONFIG_MTD_PARSER_CYBERTAN=y +# CONFIG_MTD_PARSER_TPLINK_SAFELOADER is not set CONFIG_MTD_PHYSMAP=y CONFIG_MTD_SPI_NOR=y CONFIG_MTD_SPLIT_ELF_FW=y diff --git a/target/linux/ath79/patches-5.4/404-mtd-cybertan-trx-parser.patch b/target/linux/ath79/patches-5.4/404-mtd-cybertan-trx-parser.patch index 923589661e..540e134ef0 100644 --- a/target/linux/ath79/patches-5.4/404-mtd-cybertan-trx-parser.patch +++ b/target/linux/ath79/patches-5.4/404-mtd-cybertan-trx-parser.patch @@ -7,7 +7,7 @@ +obj-$(CONFIG_MTD_PARSER_CYBERTAN) += parser_cybertan.o obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o obj-$(CONFIG_MTD_AFS_PARTS) += afs.o - obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o + obj-$(CONFIG_MTD_PARSER_TPLINK_SAFELOADER) += tplink_safeloader.o --- a/drivers/mtd/parsers/Kconfig +++ b/drivers/mtd/parsers/Kconfig @@ -102,6 +102,14 @@ config MTD_OF_PARTS_LINKSYS_NS diff --git a/target/linux/bcm4908/patches-5.4/077-v5.17-net-broadcom-bcm4908enet-remove-redundant-variable-b.patch b/target/linux/bcm4908/patches-5.4/077-v5.17-net-broadcom-bcm4908enet-remove-redundant-variable-b.patch new file mode 100644 index 0000000000..03e546cb5f --- /dev/null +++ b/target/linux/bcm4908/patches-5.4/077-v5.17-net-broadcom-bcm4908enet-remove-redundant-variable-b.patch @@ -0,0 +1,34 @@ +From 62a3106697f3c6f9af64a2cd0f9ff58552010dc8 Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Wed, 22 Dec 2021 00:39:37 +0000 +Subject: [PATCH] net: broadcom: bcm4908enet: remove redundant variable bytes + +The variable bytes is being used to summate slot lengths, +however the value is never used afterwards. The summation +is redundant so remove variable bytes. + +Signed-off-by: Colin Ian King +Link: https://lore.kernel.org/r/20211222003937.727325-1-colin.i.king@gmail.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/broadcom/bcm4908_enet.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bcm4908_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c +@@ -634,7 +634,6 @@ static int bcm4908_enet_poll_tx(struct n + struct bcm4908_enet_dma_ring_bd *buf_desc; + struct bcm4908_enet_dma_ring_slot *slot; + struct device *dev = enet->dev; +- unsigned int bytes = 0; + int handled = 0; + + while (handled < weight && tx_ring->read_idx != tx_ring->write_idx) { +@@ -645,7 +644,6 @@ static int bcm4908_enet_poll_tx(struct n + + dma_unmap_single(dev, slot->dma_addr, slot->len, DMA_TO_DEVICE); + dev_kfree_skb(slot->skb); +- bytes += slot->len; + if (++tx_ring->read_idx == tx_ring->length) + tx_ring->read_idx = 0; + diff --git a/target/linux/bcm4908/patches-5.4/078-v6.1-net-broadcom-bcm4908_enet-handle-EPROBE_DEFER-when-g.patch b/target/linux/bcm4908/patches-5.4/078-v6.1-0001-net-broadcom-bcm4908_enet-handle-EPROBE_DEFER-when-g.patch similarity index 93% rename from target/linux/bcm4908/patches-5.4/078-v6.1-net-broadcom-bcm4908_enet-handle-EPROBE_DEFER-when-g.patch rename to target/linux/bcm4908/patches-5.4/078-v6.1-0001-net-broadcom-bcm4908_enet-handle-EPROBE_DEFER-when-g.patch index de13dcf663..f97a9094ee 100644 --- a/target/linux/bcm4908/patches-5.4/078-v6.1-net-broadcom-bcm4908_enet-handle-EPROBE_DEFER-when-g.patch +++ b/target/linux/bcm4908/patches-5.4/078-v6.1-0001-net-broadcom-bcm4908_enet-handle-EPROBE_DEFER-when-g.patch @@ -20,7 +20,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/ethernet/broadcom/bcm4908_enet.c +++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c -@@ -716,10 +716,14 @@ static int bcm4908_enet_probe(struct pla +@@ -714,10 +714,14 @@ static int bcm4908_enet_probe(struct pla SET_NETDEV_DEV(netdev, &pdev->dev); mac = of_get_mac_address(dev->of_node); @@ -37,7 +37,7 @@ Signed-off-by: Jakub Kicinski netdev->netdev_ops = &bcm4908_enet_netdev_ops; netdev->min_mtu = ETH_ZLEN; netdev->mtu = ETH_DATA_LEN; -@@ -728,14 +732,17 @@ static int bcm4908_enet_probe(struct pla +@@ -726,14 +730,17 @@ static int bcm4908_enet_probe(struct pla netif_napi_add(netdev, &enet->rx_ring.napi, bcm4908_enet_poll_rx, NAPI_POLL_WEIGHT); err = register_netdev(netdev); diff --git a/target/linux/bcm4908/patches-5.4/078-v6.1-0002-net-broadcom-bcm4908_enet-update-TX-stats-after-actu.patch b/target/linux/bcm4908/patches-5.4/078-v6.1-0002-net-broadcom-bcm4908_enet-update-TX-stats-after-actu.patch new file mode 100644 index 0000000000..29cf3742f4 --- /dev/null +++ b/target/linux/bcm4908/patches-5.4/078-v6.1-0002-net-broadcom-bcm4908_enet-update-TX-stats-after-actu.patch @@ -0,0 +1,65 @@ +From ef3556ee16c68735ec69bd08df41d1cd83b14ad3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 27 Oct 2022 13:24:30 +0200 +Subject: [PATCH] net: broadcom: bcm4908_enet: update TX stats after actual + transmission +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Queueing packets doesn't guarantee their transmission. Update TX stats +after hardware confirms consuming submitted data. + +This also fixes a possible race and NULL dereference. +bcm4908_enet_start_xmit() could try to access skb after freeing it in +the bcm4908_enet_poll_tx(). + +Reported-by: Florian Fainelli +Fixes: 4feffeadbcb2e ("net: broadcom: bcm4908enet: add BCM4908 controller driver") +Signed-off-by: Rafał Miłecki +Reviewed-by: Florian Fainelli +Link: https://lore.kernel.org/r/20221027112430.8696-1-zajec5@gmail.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/broadcom/bcm4908_enet.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bcm4908_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c +@@ -560,8 +560,6 @@ static int bcm4908_enet_start_xmit(struc + + if (++ring->write_idx == ring->length - 1) + ring->write_idx = 0; +- enet->netdev->stats.tx_bytes += skb->len; +- enet->netdev->stats.tx_packets++; + + return NETDEV_TX_OK; + } +@@ -634,6 +632,7 @@ static int bcm4908_enet_poll_tx(struct n + struct bcm4908_enet_dma_ring_bd *buf_desc; + struct bcm4908_enet_dma_ring_slot *slot; + struct device *dev = enet->dev; ++ unsigned int bytes = 0; + int handled = 0; + + while (handled < weight && tx_ring->read_idx != tx_ring->write_idx) { +@@ -644,12 +643,17 @@ static int bcm4908_enet_poll_tx(struct n + + dma_unmap_single(dev, slot->dma_addr, slot->len, DMA_TO_DEVICE); + dev_kfree_skb(slot->skb); +- if (++tx_ring->read_idx == tx_ring->length) +- tx_ring->read_idx = 0; + + handled++; ++ bytes += slot->len; ++ ++ if (++tx_ring->read_idx == tx_ring->length) ++ tx_ring->read_idx = 0; + } + ++ enet->netdev->stats.tx_packets += handled; ++ enet->netdev->stats.tx_bytes += bytes; ++ + if (handled < weight) { + napi_complete_done(napi, handled); + bcm4908_enet_dma_ring_intrs_on(enet, tx_ring); diff --git a/target/linux/bcm4908/patches-5.4/079-v6.2-0001-net-broadcom-bcm4908_enet-use-build_skb.patch b/target/linux/bcm4908/patches-5.4/079-v6.2-0001-net-broadcom-bcm4908_enet-use-build_skb.patch new file mode 100644 index 0000000000..834973f5c7 --- /dev/null +++ b/target/linux/bcm4908/patches-5.4/079-v6.2-0001-net-broadcom-bcm4908_enet-use-build_skb.patch @@ -0,0 +1,152 @@ +From 3a1cc23a75abcd9cea585eb84846507363d58397 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 25 Oct 2022 15:22:45 +0200 +Subject: [PATCH] net: broadcom: bcm4908_enet: use build_skb() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RX code can be more efficient with the build_skb(). Allocating actual +SKB around eth packet buffer - right before passing it up - results in +a better cache usage. + +Without RPS (echo 0 > rps_cpus) BCM4908 NAT masq performance "jumps" +between two speeds: ~900 Mbps and 940 Mbps (it's a 4 CPUs SoC). This +change bumps the lower speed from 905 Mb/s to 918 Mb/s (tested using +single stream iperf 2.0.5 traffic). + +There are more optimizations to consider. One obvious to try is GRO +however as BCM4908 doesn't do hw csum is may actually lower performance. +Sometimes. Some early testing: + +┌─────────────────────────────────┬─────────────────────┬────────────────────┐ +│ │ netif_receive_skb() │ napi_gro_receive() │ +├─────────────────────────────────┼─────────────────────┼────────────────────┤ +│ netdev_alloc_skb() │ 905 Mb/s │ 892 Mb/s │ +│ napi_alloc_frag() + build_skb() │ 918 Mb/s │ 917 Mb/s │ +└─────────────────────────────────┴─────────────────────┴────────────────────┘ + +Another ideas: +1. napi_build_skb() +2. skb_copy_from_linear_data() for small packets + +Those need proper testing first though. That can be done later. + +Signed-off-by: Rafał Miłecki +Link: https://lore.kernel.org/r/20221025132245.22871-1-zajec5@gmail.com +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/broadcom/bcm4908_enet.c | 53 +++++++++++++------- + 1 file changed, 36 insertions(+), 17 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bcm4908_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c +@@ -36,13 +36,24 @@ + #define ENET_MAX_ETH_OVERHEAD (ETH_HLEN + BRCM_MAX_TAG_LEN + VLAN_HLEN + \ + ETH_FCS_LEN + 4) /* 32 */ + ++#define ENET_RX_SKB_BUF_SIZE (NET_SKB_PAD + NET_IP_ALIGN + \ ++ ETH_HLEN + BRCM_MAX_TAG_LEN + VLAN_HLEN + \ ++ ENET_MTU_MAX + ETH_FCS_LEN + 4) ++#define ENET_RX_SKB_BUF_ALLOC_SIZE (SKB_DATA_ALIGN(ENET_RX_SKB_BUF_SIZE) + \ ++ SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) ++#define ENET_RX_BUF_DMA_OFFSET (NET_SKB_PAD + NET_IP_ALIGN) ++#define ENET_RX_BUF_DMA_SIZE (ENET_RX_SKB_BUF_SIZE - ENET_RX_BUF_DMA_OFFSET) ++ + struct bcm4908_enet_dma_ring_bd { + __le32 ctl; + __le32 addr; + } __packed; + + struct bcm4908_enet_dma_ring_slot { +- struct sk_buff *skb; ++ union { ++ void *buf; /* RX */ ++ struct sk_buff *skb; /* TX */ ++ }; + unsigned int len; + dma_addr_t dma_addr; + }; +@@ -259,22 +270,21 @@ static int bcm4908_enet_dma_alloc_rx_buf + u32 tmp; + int err; + +- slot->len = ENET_MTU_MAX + ENET_MAX_ETH_OVERHEAD; +- +- slot->skb = netdev_alloc_skb(enet->netdev, slot->len); +- if (!slot->skb) ++ slot->buf = napi_alloc_frag(ENET_RX_SKB_BUF_ALLOC_SIZE); ++ if (!slot->buf) + return -ENOMEM; + +- slot->dma_addr = dma_map_single(dev, slot->skb->data, slot->len, DMA_FROM_DEVICE); ++ slot->dma_addr = dma_map_single(dev, slot->buf + ENET_RX_BUF_DMA_OFFSET, ++ ENET_RX_BUF_DMA_SIZE, DMA_FROM_DEVICE); + err = dma_mapping_error(dev, slot->dma_addr); + if (err) { + dev_err(dev, "Failed to map DMA buffer: %d\n", err); +- kfree_skb(slot->skb); +- slot->skb = NULL; ++ skb_free_frag(slot->buf); ++ slot->buf = NULL; + return err; + } + +- tmp = slot->len << DMA_CTL_LEN_DESC_BUFLENGTH_SHIFT; ++ tmp = ENET_RX_BUF_DMA_SIZE << DMA_CTL_LEN_DESC_BUFLENGTH_SHIFT; + tmp |= DMA_CTL_STATUS_OWN; + if (idx == enet->rx_ring.length - 1) + tmp |= DMA_CTL_STATUS_WRAP; +@@ -314,11 +324,11 @@ static void bcm4908_enet_dma_uninit(stru + + for (i = rx_ring->length - 1; i >= 0; i--) { + slot = &rx_ring->slots[i]; +- if (!slot->skb) ++ if (!slot->buf) + continue; + dma_unmap_single(dev, slot->dma_addr, slot->len, DMA_FROM_DEVICE); +- kfree_skb(slot->skb); +- slot->skb = NULL; ++ skb_free_frag(slot->buf); ++ slot->buf = NULL; + } + } + +@@ -574,6 +584,7 @@ static int bcm4908_enet_poll_rx(struct n + while (handled < weight) { + struct bcm4908_enet_dma_ring_bd *buf_desc; + struct bcm4908_enet_dma_ring_slot slot; ++ struct sk_buff *skb; + u32 ctl; + int len; + int err; +@@ -597,16 +608,24 @@ static int bcm4908_enet_poll_rx(struct n + + if (len < ETH_ZLEN || + (ctl & (DMA_CTL_STATUS_SOP | DMA_CTL_STATUS_EOP)) != (DMA_CTL_STATUS_SOP | DMA_CTL_STATUS_EOP)) { +- kfree_skb(slot.skb); ++ skb_free_frag(slot.buf); + enet->netdev->stats.rx_dropped++; + break; + } + +- dma_unmap_single(dev, slot.dma_addr, slot.len, DMA_FROM_DEVICE); ++ dma_unmap_single(dev, slot.dma_addr, ENET_RX_BUF_DMA_SIZE, DMA_FROM_DEVICE); ++ ++ skb = build_skb(slot.buf, ENET_RX_SKB_BUF_ALLOC_SIZE); ++ if (unlikely(!skb)) { ++ skb_free_frag(slot.buf); ++ enet->netdev->stats.rx_dropped++; ++ break; ++ } ++ skb_reserve(skb, ENET_RX_BUF_DMA_OFFSET); ++ skb_put(skb, len - ETH_FCS_LEN); ++ skb->protocol = eth_type_trans(skb, enet->netdev); + +- skb_put(slot.skb, len - ETH_FCS_LEN); +- slot.skb->protocol = eth_type_trans(slot.skb, enet->netdev); +- netif_receive_skb(slot.skb); ++ netif_receive_skb(skb); + + enet->netdev->stats.rx_packets++; + enet->netdev->stats.rx_bytes += len; diff --git a/target/linux/bcm4908/patches-5.4/079-v6.2-0002-net-broadcom-bcm4908_enet-report-queued-and-transmit.patch b/target/linux/bcm4908/patches-5.4/079-v6.2-0002-net-broadcom-bcm4908_enet-report-queued-and-transmit.patch new file mode 100644 index 0000000000..9f85a77b76 --- /dev/null +++ b/target/linux/bcm4908/patches-5.4/079-v6.2-0002-net-broadcom-bcm4908_enet-report-queued-and-transmit.patch @@ -0,0 +1,45 @@ +From 471ef777ec79baadc5cd9773d08f95f49cf5e2b1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Mon, 31 Oct 2022 11:48:56 +0100 +Subject: [PATCH] net: broadcom: bcm4908_enet: report queued and transmitted + bytes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This allows BQL to operate avoiding buffer bloat and reducing latency. + +Signed-off-by: Rafał Miłecki +Link: https://lore.kernel.org/r/20221031104856.32388-1-zajec5@gmail.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/broadcom/bcm4908_enet.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/net/ethernet/broadcom/bcm4908_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c +@@ -504,6 +504,7 @@ static int bcm4908_enet_stop(struct net_ + netif_carrier_off(netdev); + napi_disable(&rx_ring->napi); + napi_disable(&tx_ring->napi); ++ netdev_reset_queue(netdev); + + bcm4908_enet_dma_rx_ring_disable(enet, &enet->rx_ring); + bcm4908_enet_dma_tx_ring_disable(enet, &enet->tx_ring); +@@ -563,6 +564,8 @@ static int bcm4908_enet_start_xmit(struc + if (ring->write_idx + 1 == ring->length - 1) + tmp |= DMA_CTL_STATUS_WRAP; + ++ netdev_sent_queue(enet->netdev, skb->len); ++ + buf_desc->addr = cpu_to_le32((uint32_t)slot->dma_addr); + buf_desc->ctl = cpu_to_le32(tmp); + +@@ -670,6 +673,7 @@ static int bcm4908_enet_poll_tx(struct n + tx_ring->read_idx = 0; + } + ++ netdev_completed_queue(enet->netdev, handled, bytes); + enet->netdev->stats.tx_packets += handled; + enet->netdev->stats.tx_bytes += bytes; + diff --git a/target/linux/bcm53xx/config-5.4 b/target/linux/bcm53xx/config-5.4 index bee678bcf4..abfd693f39 100644 --- a/target/linux/bcm53xx/config-5.4 +++ b/target/linux/bcm53xx/config-5.4 @@ -260,6 +260,7 @@ CONFIG_MTD_NAND_BRCMNAND=y CONFIG_MTD_NAND_CORE=y CONFIG_MTD_NAND_ECC_SW_HAMMING=y CONFIG_MTD_OF_PARTS_LINKSYS_NS=y +CONFIG_MTD_PARSER_TPLINK_SAFELOADER=y CONFIG_MTD_PARSER_TRX=y CONFIG_MTD_RAW_NAND=y CONFIG_MTD_SPI_NOR=y diff --git a/target/linux/generic/backport-5.4/420-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch b/target/linux/generic/backport-5.4/420-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch new file mode 100644 index 0000000000..898a9bf383 --- /dev/null +++ b/target/linux/generic/backport-5.4/420-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch @@ -0,0 +1,229 @@ +From aec4d5f5ffd0f0092bd9dc21ea90e0bc237d4b74 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Sat, 15 Oct 2022 11:29:50 +0200 +Subject: [PATCH] mtd: parsers: add TP-Link SafeLoader partitions table parser +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This parser deals with most TP-Link home routers. It reads info about +partitions and registers them in the MTD subsystem. + +Example from TP-Link Archer C5 V2: + +spi-nor spi0.0: s25fl128s1 (16384 Kbytes) +15 tplink-safeloader partitions found on MTD device spi0.0 +Creating 15 MTD partitions on "spi0.0": +0x000000000000-0x000000040000 : "fs-uboot" +0x000000040000-0x000000440000 : "os-image" +0x000000440000-0x000000e40000 : "rootfs" +0x000000e40000-0x000000e40200 : "default-mac" +0x000000e40200-0x000000e40400 : "pin" +0x000000e40400-0x000000e40600 : "product-info" +0x000000e50000-0x000000e60000 : "partition-table" +0x000000e60000-0x000000e60200 : "soft-version" +0x000000e61000-0x000000e70000 : "support-list" +0x000000e70000-0x000000e80000 : "profile" +0x000000e80000-0x000000e90000 : "default-config" +0x000000e90000-0x000000ee0000 : "user-config" +0x000000ee0000-0x000000fe0000 : "log" +0x000000fe0000-0x000000ff0000 : "radio_bk" +0x000000ff0000-0x000001000000 : "radio" + +Signed-off-by: Rafał Miłecki +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20221015092950.27467-2-zajec5@gmail.com +--- + drivers/mtd/parsers/Kconfig | 15 +++ + drivers/mtd/parsers/Makefile | 1 + + drivers/mtd/parsers/tplink_safeloader.c | 150 ++++++++++++++++++++++++ + 3 files changed, 166 insertions(+) + create mode 100644 drivers/mtd/parsers/tplink_safeloader.c + +--- a/drivers/mtd/parsers/Kconfig ++++ b/drivers/mtd/parsers/Kconfig +@@ -113,6 +113,21 @@ config MTD_AFS_PARTS + for your particular device. It won't happen automatically. The + 'physmap' map driver (CONFIG_MTD_PHYSMAP) does this, for example. + ++config MTD_PARSER_TPLINK_SAFELOADER ++ tristate "TP-Link Safeloader partitions parser" ++ depends on MTD && (ARCH_BCM_5301X || ATH79 || SOC_MT7620 || SOC_MT7621 || COMPILE_TEST) ++ help ++ TP-Link home routers use flash partitions to store various data. Info ++ about flash space layout is stored in a partitions table using a ++ custom ASCII-based format. ++ ++ That format was first found in devices with SafeLoader bootloader and ++ was named after it. Later it was adapted to CFE and U-Boot ++ bootloaders. ++ ++ This driver reads partitions table, parses it and creates MTD ++ partitions. ++ + config MTD_PARSER_TRX + tristate "Parser for TRX format partitions" + depends on MTD && (BCM47XX || ARCH_BCM_5301X || COMPILE_TEST) +--- a/drivers/mtd/parsers/Makefile ++++ b/drivers/mtd/parsers/Makefile +@@ -9,6 +9,7 @@ ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908) += + ofpart-$(CONFIG_MTD_OF_PARTS_LINKSYS_NS)+= ofpart_linksys_ns.o + obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o + obj-$(CONFIG_MTD_AFS_PARTS) += afs.o ++obj-$(CONFIG_MTD_PARSER_TPLINK_SAFELOADER) += tplink_safeloader.o + obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o + obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o + obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o +--- /dev/null ++++ b/drivers/mtd/parsers/tplink_safeloader.c +@@ -0,0 +1,150 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright © 2022 Rafał Miłecki ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define TPLINK_SAFELOADER_DATA_OFFSET 4 ++#define TPLINK_SAFELOADER_MAX_PARTS 32 ++ ++struct safeloader_cmn_header { ++ __be32 size; ++ uint32_t unused; ++} __packed; ++ ++static void *mtd_parser_tplink_safeloader_read_table(struct mtd_info *mtd) ++{ ++ struct safeloader_cmn_header hdr; ++ struct device_node *np; ++ size_t bytes_read; ++ size_t offset; ++ size_t size; ++ char *buf; ++ int err; ++ ++ np = mtd_get_of_node(mtd); ++ if (mtd_is_partition(mtd)) ++ of_node_get(np); ++ else ++ np = of_get_child_by_name(np, "partitions"); ++ ++ if (of_property_read_u32(np, "partitions-table-offset", (u32 *)&offset)) { ++ pr_err("Failed to get partitions table offset\n"); ++ goto err_put; ++ } ++ ++ err = mtd_read(mtd, offset, sizeof(hdr), &bytes_read, (uint8_t *)&hdr); ++ if (err && !mtd_is_bitflip(err)) { ++ pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset); ++ goto err_put; ++ } ++ ++ size = be32_to_cpu(hdr.size); ++ ++ buf = kmalloc(size + 1, GFP_KERNEL); ++ if (!buf) ++ goto err_put; ++ ++ err = mtd_read(mtd, offset + sizeof(hdr), size, &bytes_read, buf); ++ if (err && !mtd_is_bitflip(err)) { ++ pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset + sizeof(hdr)); ++ goto err_kfree; ++ } ++ ++ buf[size] = '\0'; ++ ++ of_node_put(np); ++ ++ return buf; ++ ++err_kfree: ++ kfree(buf); ++err_put: ++ of_node_put(np); ++ return NULL; ++} ++ ++static int mtd_parser_tplink_safeloader_parse(struct mtd_info *mtd, ++ const struct mtd_partition **pparts, ++ struct mtd_part_parser_data *data) ++{ ++ struct mtd_partition *parts; ++ char name[65]; ++ size_t offset; ++ size_t bytes; ++ char *buf; ++ int idx; ++ int err; ++ ++ parts = kcalloc(TPLINK_SAFELOADER_MAX_PARTS, sizeof(*parts), GFP_KERNEL); ++ if (!parts) { ++ err = -ENOMEM; ++ goto err_out; ++ } ++ ++ buf = mtd_parser_tplink_safeloader_read_table(mtd); ++ if (!buf) { ++ err = -ENOENT; ++ goto err_out; ++ } ++ ++ for (idx = 0, offset = TPLINK_SAFELOADER_DATA_OFFSET; ++ idx < TPLINK_SAFELOADER_MAX_PARTS && ++ sscanf(buf + offset, "partition %64s base 0x%llx size 0x%llx%zn\n", ++ name, &parts[idx].offset, &parts[idx].size, &bytes) == 3; ++ idx++, offset += bytes + 1) { ++ parts[idx].name = kstrdup(name, GFP_KERNEL); ++ if (!parts[idx].name) { ++ err = -ENOMEM; ++ goto err_free; ++ } ++ } ++ ++ if (idx == TPLINK_SAFELOADER_MAX_PARTS) ++ pr_warn("Reached maximum number of partitions!\n"); ++ ++ kfree(buf); ++ ++ *pparts = parts; ++ ++ return idx; ++ ++err_free: ++ for (idx -= 1; idx >= 0; idx--) ++ kfree(parts[idx].name); ++err_out: ++ return err; ++}; ++ ++static void mtd_parser_tplink_safeloader_cleanup(const struct mtd_partition *pparts, ++ int nr_parts) ++{ ++ int i; ++ ++ for (i = 0; i < nr_parts; i++) ++ kfree(pparts[i].name); ++ ++ kfree(pparts); ++} ++ ++static const struct of_device_id mtd_parser_tplink_safeloader_of_match_table[] = { ++ { .compatible = "tplink,safeloader-partitions" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, mtd_parser_tplink_safeloader_of_match_table); ++ ++static struct mtd_part_parser mtd_parser_tplink_safeloader = { ++ .parse_fn = mtd_parser_tplink_safeloader_parse, ++ .cleanup = mtd_parser_tplink_safeloader_cleanup, ++ .name = "tplink-safeloader", ++ .of_match_table = mtd_parser_tplink_safeloader_of_match_table, ++}; ++module_mtd_part_parser(mtd_parser_tplink_safeloader); ++ ++MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/pending-5.4/435-mtd-add-routerbootpart-parser-config.patch b/target/linux/generic/pending-5.4/435-mtd-add-routerbootpart-parser-config.patch index ab1e09a5f1..8705a38f84 100644 --- a/target/linux/generic/pending-5.4/435-mtd-add-routerbootpart-parser-config.patch +++ b/target/linux/generic/pending-5.4/435-mtd-add-routerbootpart-parser-config.patch @@ -16,7 +16,7 @@ Signed-off-by: Thibaut VARÈNE --- a/drivers/mtd/parsers/Kconfig +++ b/drivers/mtd/parsers/Kconfig -@@ -195,3 +195,12 @@ config MTD_REDBOOT_PARTS_READONLY +@@ -210,3 +210,12 @@ config MTD_REDBOOT_PARTS_READONLY 'FIS directory' images, enable this option. endif # MTD_REDBOOT_PARTS @@ -31,7 +31,7 @@ Signed-off-by: Thibaut VARÈNE + formatted DTS. --- a/drivers/mtd/parsers/Makefile +++ b/drivers/mtd/parsers/Makefile -@@ -13,3 +13,4 @@ obj-$(CONFIG_MTD_AFS_PARTS) += afs.o +@@ -14,3 +14,4 @@ obj-$(CONFIG_MTD_PARSER_TPLINK_SAFELOADE obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o diff --git a/target/linux/ipq806x/patches-5.4/0031-mtd-add-SMEM-parser-for-QCOM-platforms.patch b/target/linux/ipq806x/patches-5.4/0031-mtd-add-SMEM-parser-for-QCOM-platforms.patch index 6b7119b8e0..8445900e01 100644 --- a/target/linux/ipq806x/patches-5.4/0031-mtd-add-SMEM-parser-for-QCOM-platforms.patch +++ b/target/linux/ipq806x/patches-5.4/0031-mtd-add-SMEM-parser-for-QCOM-platforms.patch @@ -18,7 +18,7 @@ Signed-off-by: Ram Chandra Jangir --- a/drivers/mtd/parsers/Kconfig +++ b/drivers/mtd/parsers/Kconfig -@@ -138,6 +138,13 @@ config MTD_PARSER_TRX +@@ -153,6 +153,13 @@ config MTD_PARSER_TRX This driver will parse TRX header and report at least two partitions: kernel and rootfs. @@ -34,9 +34,9 @@ Signed-off-by: Ram Chandra Jangir depends on MTD_NAND_SHARPSL || MTD_NAND_TMIO || COMPILE_TEST --- a/drivers/mtd/parsers/Makefile +++ b/drivers/mtd/parsers/Makefile -@@ -11,6 +11,7 @@ ofpart-$(CONFIG_MTD_OF_PARTS_LINKSYS_NS) - obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o +@@ -12,6 +12,7 @@ obj-$(CONFIG_MTD_PARSER_IMAGETAG) += par obj-$(CONFIG_MTD_AFS_PARTS) += afs.o + obj-$(CONFIG_MTD_PARSER_TPLINK_SAFELOADER) += tplink_safeloader.o obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o +obj-$(CONFIG_MTD_QCOM_SMEM_PARTS) += qcom_smem_part.o obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o diff --git a/target/linux/ramips/mt7620/config-5.4 b/target/linux/ramips/mt7620/config-5.4 index a886875716..6ee5ce8d64 100644 --- a/target/linux/ramips/mt7620/config-5.4 +++ b/target/linux/ramips/mt7620/config-5.4 @@ -167,6 +167,7 @@ CONFIG_MODULES_USE_ELF_REL=y # CONFIG_MT7621_WDT is not set # CONFIG_MTD_CFI_INTELEXT is not set CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_PARSER_TPLINK_SAFELOADER is not set CONFIG_MTD_PHYSMAP=y CONFIG_MTD_SPI_NOR=y CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y diff --git a/target/linux/ramips/mt7621/config-5.4 b/target/linux/ramips/mt7621/config-5.4 index b9eb282886..c6ae28f304 100644 --- a/target/linux/ramips/mt7621/config-5.4 +++ b/target/linux/ramips/mt7621/config-5.4 @@ -158,6 +158,7 @@ CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_NAND_CORE=y CONFIG_MTD_NAND_ECC_SW_HAMMING=y CONFIG_MTD_NAND_MT7621=y +# CONFIG_MTD_PARSER_TPLINK_SAFELOADER is not set CONFIG_MTD_PHYSMAP=y CONFIG_MTD_RAW_NAND=y CONFIG_MTD_ROUTERBOOT_PARTS=y diff --git a/target/linux/ramips/mt76x8/config-5.4 b/target/linux/ramips/mt76x8/config-5.4 index dfd01598ad..0c53b6f8b4 100644 --- a/target/linux/ramips/mt76x8/config-5.4 +++ b/target/linux/ramips/mt76x8/config-5.4 @@ -164,6 +164,7 @@ CONFIG_MODULES_USE_ELF_REL=y CONFIG_MT7621_WDT=y # CONFIG_MTD_CFI_INTELEXT is not set CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_PARSER_TPLINK_SAFELOADER is not set CONFIG_MTD_PHYSMAP=y CONFIG_MTD_SPI_NOR=y CONFIG_MTD_SPLIT_TPLINK_FW=y