include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
-PKG_VERSION:=2025.07
-PKG_HASH:=0f933f6c5a426895bf306e93e6ac53c60870e4b54cda56d95211bec99e63bec7
+PKG_VERSION:=2025.10
+PKG_HASH:=b4f032848e56cc8f213ad59f9132c084dbbb632bc29176d024e58220e0efdf4a
PKG_BUILD_DEPENDS:=arm-trusted-firmware-tools/host
UBOOT_USE_INTREE_DTC:=1
+++ /dev/null
-From 4f1fcf5281ee4e22b1e89a62bd0417878bcbeca5 Mon Sep 17 00:00:00 2001
-Date: Tue, 3 Jun 2025 10:41:18 +0200
-Subject: [PATCH 1/2] linux/bitfield.h: import FIELD_PREP_CONST macro from
- Linux Kernel
-
-Import FIELD_PREP_CONST macro from Linux Kernel to permit usage of
-FIELD_PREP with scenario where a constant value is needed.
-
-Refer to commit e2192de59e45 ("bitfield: add FIELD_PREP_CONST()") in
-Linux kernel for extensive explaination of why this is useful.
-
-This is also to better align with the Linux Kernel for easier porting of
-driver.
-
----
- include/linux/bitfield.h | 26 ++++++++++++++++++++++++++
- 1 file changed, 26 insertions(+)
-
---- a/include/linux/bitfield.h
-+++ b/include/linux/bitfield.h
-@@ -90,6 +90,32 @@
- ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \
- })
-
-+#define __BF_CHECK_POW2(n) BUILD_BUG_ON_ZERO(((n) & ((n) - 1)) != 0)
-+
-+/**
-+ * FIELD_PREP_CONST() - prepare a constant bitfield element
-+ * @_mask: shifted mask defining the field's length and position
-+ * @_val: value to put in the field
-+ *
-+ * FIELD_PREP_CONST() masks and shifts up the value. The result should
-+ * be combined with other fields of the bitfield using logical OR.
-+ *
-+ * Unlike FIELD_PREP() this is a constant expression and can therefore
-+ * be used in initializers. Error checking is less comfortable for this
-+ * version, and non-constant masks cannot be used.
-+ */
-+#define FIELD_PREP_CONST(_mask, _val) \
-+ ( \
-+ /* mask must be non-zero */ \
-+ BUILD_BUG_ON_ZERO((_mask) == 0) + \
-+ /* check if value fits */ \
-+ BUILD_BUG_ON_ZERO(~((_mask) >> __bf_shf(_mask)) & (_val)) + \
-+ /* check if mask is contiguous */ \
-+ __BF_CHECK_POW2((_mask) + (1ULL << __bf_shf(_mask))) + \
-+ /* and create the value */ \
-+ (((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask)) \
-+ )
-+
- /**
- * FIELD_GET() - extract a bitfield element
- * @_mask: shifted mask defining the field's length and position
+++ /dev/null
-From 00e8038b8be74d599f7bc8078731cc2505832f57 Mon Sep 17 00:00:00 2001
-Date: Tue, 3 Jun 2025 10:47:15 +0200
-Subject: [PATCH 2/2] mtd: spinand: winbond: add Winbond W25N04KV flash support
-
-Add Winbond W25N04KV flash support that use a different value to detect
-ECC bitflip.
-
----
- drivers/mtd/nand/spi/winbond.c | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
---- a/drivers/mtd/nand/spi/winbond.c
-+++ b/drivers/mtd/nand/spi/winbond.c
-@@ -11,6 +11,7 @@
- #include <linux/device.h>
- #include <linux/kernel.h>
- #endif
-+#include <linux/bitfield.h>
- #include <linux/bug.h>
- #include <linux/mtd/spinand.h>
-
-@@ -18,6 +19,8 @@
-
- #define WINBOND_CFG_BUF_READ BIT(3)
-
-+#define W25N04KV_STATUS_ECC_5_8_BITFLIPS FIELD_PREP_CONST(STATUS_ECC_MASK, 0x3)
-+
- static SPINAND_OP_VARIANTS(read_cache_variants,
- SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
- SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
-@@ -121,6 +124,7 @@ static int w25n02kv_ecc_get_status(struc
- return -EBADMSG;
-
- case STATUS_ECC_HAS_BITFLIPS:
-+ case W25N04KV_STATUS_ECC_5_8_BITFLIPS:
- /*
- * Let's try to retrieve the real maximum number of bitflips
- * in order to avoid forcing the wear-leveling layer to move
-@@ -169,6 +173,15 @@ static const struct spinand_info winbond
- NAND_ECCREQ(8, 512),
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
- &write_cache_variants,
-+ &update_cache_variants),
-+ 0,
-+ SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
-+ SPINAND_INFO("W25N04KV",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x23),
-+ NAND_MEMORG(1, 2048, 128, 64, 4096, 40, 2, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
- &update_cache_variants),
- 0,
- SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
include/linux/mtd/spinand.h | 7 ++
2 files changed, 95 insertions(+), 97 deletions(-)
-diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
-index f5ddfbf4b83..ea00cd7dcf0 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -41,21 +41,6 @@ struct spinand_plat {
static const struct nand_ops spinand_ops = {
.erase = spinand_erase,
.markbad = spinand_markbad,
-@@ -1116,6 +1099,14 @@ static int spinand_init(struct spinand_device *spinand)
+@@ -1134,6 +1117,14 @@ static int spinand_init(struct spinand_device *spinand)
goto err_free_bufs;
}
int (*select_target)(struct spinand_device *spinand,
unsigned int target);
unsigned int cur_target;
---
-2.51.0
-
drivers/spi/airoha_snfi_spi.c | 16 ----------------
1 file changed, 16 deletions(-)
-diff --git a/drivers/spi/airoha_snfi_spi.c b/drivers/spi/airoha_snfi_spi.c
-index 3ea25b293d1..4eb01038404 100644
--- a/drivers/spi/airoha_snfi_spi.c
+++ b/drivers/spi/airoha_snfi_spi.c
@@ -525,21 +525,6 @@ static int airoha_snand_nfi_config(struct airoha_snand_priv *priv)
.supports_op = airoha_snand_supports_op,
.exec_op = airoha_snand_exec_op,
};
---
-2.51.0
-
drivers/spi/airoha_snfi_spi.c | 143 +++++++++++++++++++++++++++-------
1 file changed, 117 insertions(+), 26 deletions(-)
-diff --git a/drivers/spi/airoha_snfi_spi.c b/drivers/spi/airoha_snfi_spi.c
-index 4eb01038404..7cd409ba44a 100644
--- a/drivers/spi/airoha_snfi_spi.c
+++ b/drivers/spi/airoha_snfi_spi.c
@@ -186,6 +186,14 @@
if (err)
return err;
}
---
-2.51.0
-
drivers/spi/airoha_snfi_spi.c | 309 ++++++++++++++++++++++++++++++++++
1 file changed, 309 insertions(+)
-diff --git a/drivers/spi/airoha_snfi_spi.c b/drivers/spi/airoha_snfi_spi.c
-index 7cd409ba44a..f72d11f5b19 100644
--- a/drivers/spi/airoha_snfi_spi.c
+++ b/drivers/spi/airoha_snfi_spi.c
@@ -141,12 +141,14 @@
};
static const struct dm_spi_ops airoha_snfi_spi_ops = {
---
-2.51.0
-
drivers/spi/airoha_snfi_spi.c | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)
-diff --git a/drivers/spi/airoha_snfi_spi.c b/drivers/spi/airoha_snfi_spi.c
-index f72d11f5b19..7cafa900bbc 100644
--- a/drivers/spi/airoha_snfi_spi.c
+++ b/drivers/spi/airoha_snfi_spi.c
@@ -141,6 +141,7 @@
if (err)
goto error_dma_unmap;
---
-2.51.0
-
drivers/spi/airoha_snfi_spi.c | 38 -----------------------------------
1 file changed, 38 deletions(-)
-diff --git a/drivers/spi/airoha_snfi_spi.c b/drivers/spi/airoha_snfi_spi.c
-index 7cafa900bbc..71e4fc13924 100644
--- a/drivers/spi/airoha_snfi_spi.c
+++ b/drivers/spi/airoha_snfi_spi.c
@@ -514,44 +514,6 @@ static int airoha_snand_nfi_config(struct airoha_snand_priv *priv)
/* sec num */
val = FIELD_PREP(SPI_NFI_SEC_NUM, priv->nfi_cfg.sec_num);
err = regmap_update_bits(priv->regmap_nfi, REG_SPI_NFI_CON,
---
-2.51.0
-
drivers/spi/airoha_snfi_spi.c | 134 +++++++++++++++++++++++++---------
1 file changed, 101 insertions(+), 33 deletions(-)
-diff --git a/drivers/spi/airoha_snfi_spi.c b/drivers/spi/airoha_snfi_spi.c
-index 71e4fc13924..1fcf5dd89e9 100644
--- a/drivers/spi/airoha_snfi_spi.c
+++ b/drivers/spi/airoha_snfi_spi.c
@@ -641,7 +641,47 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
err = regmap_write(priv->regmap_nfi, REG_SPI_NFI_CMD, 0x80);
if (err)
goto error_dma_unmap;
---
-2.51.0
-
drivers/spi/airoha_snfi_spi.c | 35 +++++++++++++++++++----------------
1 file changed, 19 insertions(+), 16 deletions(-)
-diff --git a/drivers/spi/airoha_snfi_spi.c b/drivers/spi/airoha_snfi_spi.c
-index 1fcf5dd89e9..c9feef83f89 100644
--- a/drivers/spi/airoha_snfi_spi.c
+++ b/drivers/spi/airoha_snfi_spi.c
@@ -515,7 +515,7 @@ static int airoha_snand_nfi_config(struct airoha_snand_priv *priv)
if (err)
goto error_dma_unmap;
---
-2.51.0
-
drivers/spi/airoha_snfi_spi.c | 94 ++---------------------------------
1 file changed, 4 insertions(+), 90 deletions(-)
-diff --git a/drivers/spi/airoha_snfi_spi.c b/drivers/spi/airoha_snfi_spi.c
-index c9feef83f89..37fee0c6655 100644
--- a/drivers/spi/airoha_snfi_spi.c
+++ b/drivers/spi/airoha_snfi_spi.c
@@ -218,13 +218,6 @@ struct airoha_snand_priv {
};
static const struct udevice_id airoha_snand_ids[] = {
---
-2.51.0
-
board/airoha/an7583/MAINTAINERS | 5 +
board/airoha/an7583/Makefile | 3 +
board/airoha/an7583/an7583_rfb.c | 16 ++
- configs/an7583_evb_defconfig | 83 ++++++
+ configs/an7583_evb_defconfig | 81 ++++++
include/configs/an7583.h | 19 ++
- 11 files changed, 645 insertions(+)
+ 11 files changed, 643 insertions(+)
create mode 100644 arch/arm/dts/an7583-evb.dts
create mode 100644 arch/arm/dts/an7583.dtsi
create mode 100644 arch/arm/mach-airoha/an7583/Makefile
+CONFIG_CMD_LOG=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MMC=y
-+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
++CONFIG_ENV_RELOC_GD_ENV_ADDR=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
static int airoha_reset_update(struct airoha_reset_priv *priv,
unsigned long id, bool assert)
{
-@@ -135,7 +191,7 @@ static int airoha_reset_xlate(struct res
+@@ -135,7 +191,7 @@ static int airoha_reset_xlate(struct reset_ctl *reset_ctl,
{
struct airoha_reset_priv *priv = dev_get_priv(reset_ctl->dev);
return -EINVAL;
reset_ctl->id = priv->idx_map[args->args[0]];
-@@ -150,7 +206,7 @@ static struct reset_ops airoha_reset_ops
+@@ -150,7 +206,7 @@ static struct reset_ops airoha_reset_ops = {
.rst_status = airoha_reset_status,
};
{
struct airoha_reset_priv *priv = dev_get_priv(dev);
int ret;
-@@ -161,10 +217,44 @@ static int airoha_reset_probe(struct ude
+@@ -161,10 +217,44 @@ static int airoha_reset_probe(struct udevice *dev)
priv->bank_ofs = en7581_rst_ofs;
priv->idx_map = en7581_rst_map;
+ priv->num_rsts = ARRAY_SIZE(en7581_rst_map);
-
- return 0;
- }
-
++
++ return 0;
++}
++
+static int an7583_reset_probe(struct udevice *dev)
+{
+ struct airoha_reset_priv *priv = dev_get_priv(dev);
+ priv->bank_ofs = en7581_rst_ofs;
+ priv->idx_map = an7583_rst_map;
+ priv->num_rsts = ARRAY_SIZE(an7583_rst_map);
-+
-+ return 0;
-+}
-+
+
+ return 0;
+ }
+
+static int airoha_reset_probe(struct udevice *dev)
+{
+ if (ofnode_device_is_compatible(dev_ofnode(dev),
+#define AN7583_XPON_MAC_RST 47
+
+#endif /* __DT_BINDINGS_RESET_CONTROLLER_AIROHA_AN7583_H_ */
+
-From 289503869e5580658035e82d91b02a43c775f1a1 Mon Sep 17 00:00:00 2001
+From dfdc7309ba22f6a6b6c581acfe95a222108bd760 Mon Sep 17 00:00:00 2001
Date: Mon, 19 May 2025 14:29:53 +0200
-Subject: [PATCH 1/4] net: airoha: add support for Airoha AN7583
+Subject: [PATCH] net: airoha: add support for Airoha AN7583
Add support for Ethernet controller present in Airoha AN7583. This
follow the same implementation of Airoha AN7581 with the only difference
/* FE */
#define PSE_BASE 0x0100
-@@ -311,6 +330,26 @@ struct airoha_eth {
+@@ -312,6 +331,26 @@ struct airoha_eth {
struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS];
};
static u32 airoha_rr(void __iomem *base, u32 offset)
{
return readl(base + offset);
-@@ -351,8 +390,12 @@ static u32 airoha_rmw(void __iomem *base
+@@ -352,8 +391,12 @@ static u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val)
#define airoha_qdma_clear(qdma, offset, val) \
airoha_rmw((qdma)->regs, (offset), (val), 0)
+#define airoha_switch_rmw(eth, offset, mask, val) \
+ airoha_rmw((eth)->switch_regs, (offset), (mask), (val))
- static void airoha_fe_maccr_init(struct airoha_eth *eth)
- {
-@@ -652,10 +695,12 @@ static int airoha_hw_init(struct udevice
+ static inline dma_addr_t dma_map_unaligned(void *vaddr, size_t len,
+ enum dma_data_direction dir)
+@@ -682,10 +725,12 @@ static int airoha_hw_init(struct udevice *dev,
static int airoha_switch_init(struct udevice *dev, struct airoha_eth *eth)
{
if (!ofnode_valid(switch_node))
return -EINVAL;
-@@ -687,17 +732,71 @@ static int airoha_switch_init(struct ude
+@@ -717,17 +762,71 @@ static int airoha_switch_init(struct udevice *dev, struct airoha_eth *eth)
FIELD_PREP(SWITCH_PHY_END_ADDR, 0xc) |
FIELD_PREP(SWITCH_PHY_ST_ADDR, 0x8));
if (!ofnode_valid(scu_node))
return -EINVAL;
-@@ -721,11 +820,11 @@ static int airoha_eth_probe(struct udevi
+@@ -751,11 +850,11 @@ static int airoha_eth_probe(struct udevice *dev)
return -ENOMEM;
eth->rsts.count = AIROHA_MAX_NUM_RSTS;
ret = reset_get_by_name(dev, "fe", ð->rsts.resets[0]);
if (ret)
-@@ -739,21 +838,12 @@ static int airoha_eth_probe(struct udevi
+@@ -769,21 +868,12 @@ static int airoha_eth_probe(struct udevice *dev)
if (ret)
return ret;
ret = airoha_hw_init(dev, eth);
if (ret)
-@@ -924,8 +1014,44 @@ static int arht_eth_write_hwaddr(struct
+@@ -971,8 +1061,43 @@ static int arht_eth_write_hwaddr(struct udevice *dev)
return 0;
}
-+
+static ofnode en7581_get_scu_node(struct udevice *dev)
+{
+ return ofnode_by_compatible(ofnode_null(), "airoha,en7581-scu");
+ { .compatible = "airoha,an7583-eth",
+ .data = (ulong)&an7583_data,
+ },
+ { }
};
- static const struct eth_ops airoha_eth_ops = {
+++ /dev/null
-From a11420dac873fbd5b8a81192571d914f01bee26d Mon Sep 17 00:00:00 2001
-Date: Wed, 9 Jul 2025 12:28:07 +0300
-Subject: [PATCH 1/5] drivers/net/airoha_eth: add missing terminator for
- compatible devices list
-
-Compatible device list must have a terminator. If terminator is missed
-the u-boot driver subsystem will access random data placed after the
-list in the memory.
-
-The issue can be observed with the "dm compat" command.
-
----
- drivers/net/airoha_eth.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/drivers/net/airoha_eth.c b/drivers/net/airoha_eth.c
-index b3fd1ab9064..db34ec48c81 100644
---- a/drivers/net/airoha_eth.c
-+++ b/drivers/net/airoha_eth.c
-@@ -1052,6 +1052,7 @@ static const struct udevice_id airoha_eth_ids[] = {
- { .compatible = "airoha,an7583-eth",
- .data = (ulong)&an7583_data,
- },
-+ { }
- };
-
- static const struct eth_ops airoha_eth_ops = {
---
-2.51.0
-
--- /dev/null
+From e7b7bd119b68fe9106a1c9a45a7eba811fc40ce0 Mon Sep 17 00:00:00 2001
+Date: Fri, 3 Oct 2025 20:12:06 +0300
+Subject: [PATCH v2 1/2] net: airoha: simplify rx/free packet logic a bit
+
+The commit 997786bbf473 ("drivers/net/airoha_eth: fix stalling in package
+receiving") can be improved. Instead of returning previous descriptor
+it's possible:
+ * do nothing in even descriptor case
+ * return 2 descriptor to the queue (current and previous) in the odd
+ descriptor case.
+
+This patch:
+ * implements above approach
+ * remove logic not required within new approach
+ * adds note that PKTBUFSRX must be even and larger than 7
+ for reliable driver operations
+
+---
+ drivers/net/airoha_eth.c | 40 +++++++++++++++++++++-------------------
+ 1 file changed, 21 insertions(+), 19 deletions(-)
+
+--- a/drivers/net/airoha_eth.c
++++ b/drivers/net/airoha_eth.c
+@@ -492,14 +492,10 @@ static int airoha_qdma_init_rx_queue(struct airoha_queue *q,
+ RX_RING_SIZE_MASK,
+ FIELD_PREP(RX_RING_SIZE_MASK, ndesc));
+
+- /*
+- * See arht_eth_free_pkt() for the reasons used to fill
+- * REG_RX_CPU_IDX(qid) register.
+- */
+ airoha_qdma_rmw(qdma, REG_RX_RING_SIZE(qid), RX_RING_THR_MASK,
+ FIELD_PREP(RX_RING_THR_MASK, 0));
+ airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK,
+- FIELD_PREP(RX_RING_CPU_IDX_MASK, q->ndesc - 3));
++ FIELD_PREP(RX_RING_CPU_IDX_MASK, q->ndesc - 1));
+ airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK,
+ FIELD_PREP(RX_RING_DMA_IDX_MASK, q->head));
+
+@@ -1010,7 +1006,6 @@ static int arht_eth_free_pkt(struct udevice *dev, uchar *packet, int length)
+ struct airoha_qdma *qdma = ð->qdma[0];
+ struct airoha_queue *q;
+ int qid;
+- u16 prev, pprev;
+
+ if (!packet)
+ return 0;
+@@ -1020,22 +1015,29 @@ static int arht_eth_free_pkt(struct udevice *dev, uchar *packet, int length)
+
+ /*
+ * Due to cpu cache issue the airoha_qdma_reset_rx_desc() function
+- * will always touch 2 descriptors:
+- * - if current descriptor is even, then the previous and the one
+- * before previous descriptors will be touched (previous cacheline)
+- * - if current descriptor is odd, then only current and previous
+- * descriptors will be touched (current cacheline)
++ * will always touch 2 descriptors placed on the same cacheline:
++ * - if current descriptor is even, then current and next
++ * descriptors will be touched
++ * - if current descriptor is odd, then current and previous
++ * descriptors will be touched
+ *
+- * Thus, to prevent possible destroying of rx queue, only (q->ndesc - 2)
+- * descriptors might be used for packet receiving.
++ * Thus, to prevent possible destroying of rx queue, we should:
++ * - do nothing in the even descriptor case,
++ * - utilize 2 descriptors (current and previous one) in the
++ * odd descriptor case.
++ *
++ * WARNING: Observations shows that PKTBUFSRX must be even and
++ * larger than 7 for reliable driver operations.
+ */
+- prev = (q->head + q->ndesc - 1) % q->ndesc;
+- pprev = (q->head + q->ndesc - 2) % q->ndesc;
+- q->head = (q->head + 1) % q->ndesc;
++ if (q->head & 0x01) {
++ airoha_qdma_reset_rx_desc(q, q->head - 1);
++ airoha_qdma_reset_rx_desc(q, q->head);
+
+- airoha_qdma_reset_rx_desc(q, prev);
+- airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK,
+- FIELD_PREP(RX_RING_CPU_IDX_MASK, pprev));
++ airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK,
++ FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head));
++ }
++
++ q->head = (q->head + 1) % q->ndesc;
+
+ return 0;
+ }
+
+++ /dev/null
-From 8fce1cfe775e1f3b5d7cecb8bdcc8271bf9f799c Mon Sep 17 00:00:00 2001
-Date: Wed, 9 Jul 2025 12:28:08 +0300
-Subject: [PATCH 2/5] drivers/net/airoha_eth: fix packet transmission errors
-
-The dma_map_single() function calls one of the functions
- * invalidate_dcache_range(),
- * flush_dcache_range().
-Both of them expect that 'vaddr' is aligned to the ARCH_DMA_MINALIGN
-boundary. Unfortunately, RX/TX descriptors are 32-byte long. Thus they
-might not be aligned to the ARCH_DMA_MINALIGN boundary. Data flushing
-(or invalidating) might do nothing in this case.
-
-The same applies to dma_unmap_single() function.
-
-In the TX path case the issue might prevent package transmission (filled
-TX descriptor was not flushed).
-
-To fix an issue a special wrappers for
- * dma_map_single(),
- * dma_unmap_single()
-functions were created. The patch fix flushing/invalidatiog for the
-RX path as well.
-
-The bug appears on 32-bit airoha platform, but should be present on
-64-bit as well.
-
-The code was tested both on 32-bit and 64-bit airoha boards.
-
----
- drivers/net/airoha_eth.c | 33 +++++++++++++++++++++++++++------
- 1 file changed, 27 insertions(+), 6 deletions(-)
-
-diff --git a/drivers/net/airoha_eth.c b/drivers/net/airoha_eth.c
-index db34ec48c81..aae6922f3c7 100644
---- a/drivers/net/airoha_eth.c
-+++ b/drivers/net/airoha_eth.c
-@@ -397,6 +397,27 @@ static u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val)
- #define airoha_switch_rmw(eth, offset, mask, val) \
- airoha_rmw((eth)->switch_regs, (offset), (mask), (val))
-
-+static inline dma_addr_t dma_map_unaligned(void *vaddr, size_t len,
-+ enum dma_data_direction dir)
-+{
-+ uintptr_t start, end;
-+
-+ start = ALIGN_DOWN((uintptr_t)vaddr, ARCH_DMA_MINALIGN);
-+ end = ALIGN((uintptr_t)(vaddr + len), ARCH_DMA_MINALIGN);
-+
-+ return dma_map_single((void *)start, end - start, dir);
-+}
-+
-+static inline void dma_unmap_unaligned(dma_addr_t addr, size_t len,
-+ enum dma_data_direction dir)
-+{
-+ uintptr_t start, end;
-+
-+ start = ALIGN_DOWN((uintptr_t)addr, ARCH_DMA_MINALIGN);
-+ end = ALIGN((uintptr_t)(addr + len), ARCH_DMA_MINALIGN);
-+ dma_unmap_single(start, end - start, dir);
-+}
-+
- static void airoha_fe_maccr_init(struct airoha_eth *eth)
- {
- int p;
-@@ -434,7 +455,7 @@ static void airoha_qdma_reset_rx_desc(struct airoha_queue *q, int index,
- val = FIELD_PREP(QDMA_DESC_LEN_MASK, PKTSIZE_ALIGN);
- WRITE_ONCE(desc->ctrl, cpu_to_le32(val));
-
-- dma_map_single(desc, sizeof(*desc), DMA_TO_DEVICE);
-+ dma_map_unaligned(desc, sizeof(*desc), DMA_TO_DEVICE);
- }
-
- static void airoha_qdma_init_rx_desc(struct airoha_queue *q)
-@@ -916,14 +937,14 @@ static int airoha_eth_send(struct udevice *dev, void *packet, int length)
- WRITE_ONCE(desc->msg1, cpu_to_le32(msg1));
- WRITE_ONCE(desc->msg2, cpu_to_le32(0xffff));
-
-- dma_map_single(desc, sizeof(*desc), DMA_TO_DEVICE);
-+ dma_map_unaligned(desc, sizeof(*desc), DMA_TO_DEVICE);
-
- airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK,
- FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
-
- for (i = 0; i < 100; i++) {
-- dma_unmap_single(virt_to_phys(desc), sizeof(*desc),
-- DMA_FROM_DEVICE);
-+ dma_unmap_unaligned(virt_to_phys(desc), sizeof(*desc),
-+ DMA_FROM_DEVICE);
- if (desc->ctrl & QDMA_DESC_DONE_MASK)
- break;
-
-@@ -954,8 +975,8 @@ static int airoha_eth_recv(struct udevice *dev, int flags, uchar **packetp)
- q = &qdma->q_rx[qid];
- desc = &q->desc[q->head];
-
-- dma_unmap_single(virt_to_phys(desc), sizeof(*desc),
-- DMA_FROM_DEVICE);
-+ dma_unmap_unaligned(virt_to_phys(desc), sizeof(*desc),
-+ DMA_FROM_DEVICE);
-
- if (!(desc->ctrl & QDMA_DESC_DONE_MASK))
- return -EAGAIN;
---
-2.51.0
-
+++ /dev/null
-From 352c071bc18855238565cc6417a4c15a4e24bad8 Mon Sep 17 00:00:00 2001
-Date: Wed, 9 Jul 2025 12:28:09 +0300
-Subject: [PATCH 3/5] drivers/net/airoha_eth: fix stalling in package
- receiving
-
-ARCH_DMA_MINALIGN is 64 for ARMv7a/ARMv8a architectures, but RX/TX
-descriptors are 32 bytes long. So they may not be aligned on an
-ARCH_DMA_MINALIGN boundary. In case of RX path, this may cause the
-following problem
-
-1) Assume that a packet has arrived and the EVEN rx descriptor has been
- updated with the incoming data. The driver will invalidate and check
- the corresponding rx descriptor.
-
-2) Now suppose the next descriptor (ODD) has not yet completed.
-
- Please note that all even descriptors starts on 64-byte boundary,
- and the odd ones are NOT aligned on 64-byte boundary.
-
- Inspecting even descriptor, we will read the entire CPU cache line
- (64 bytes). So we read and sore in CPU cache also the next (odd)
- descriptor.
-
-3) Now suppose the next packet (for the odd rx descriptor) arrived
- while the first packet was being processed. So we have new data
- in memory but old data in cache.
-
-4) After packet processing (in arht_eth_free_pkt() function) we will
- cleanup the descriptor and put it back to rx queue.
-
- This will call flush_dcache_range() function for the even descriptor,
- so the odd one will be flushed as well (it is in the same cache line).
- So the old data will be written to the next rx descriptor.
-
-5) We get a freeze. The next descriptor is empty (so the driver is
- waiting for packets), but the hardware will continue to receive
- packets on other available descriptors. This will continue until
- the last available rx descriptor is full. Then the hardware will
- also freeze.
-
-The problem will be solved if:
- * do nothing in even descriptor case,
- * return 2 descriptor to the queue (current and previous) in the odd
- descriptor case.
-
-If the current descriptor is even nothing will be done, so no issue
-will arrise.
-
-If the current descriptor is odd, then the previous descriptor is on
-the same cache line. Both (current and previous) descriptors are not
-currently in use, so issue will not arrise as well.
-
-WARNING: The following restrictions on PKTBUFSRX must be held:
- * PKTBUFSRX is even,
- * PKTBUFSRX >= 4. Observations shows that PKTBUFSRX must be at least 8.
-
-The bug appears on 32-bit airoha platform, but should be present on
-64-bit as well.
-
-The code was tested both on 32-bit and 64-bit airoha boards.
-
----
- drivers/net/airoha_eth.c | 33 ++++++++++++++++++++++++++-------
- 1 file changed, 26 insertions(+), 7 deletions(-)
-
-diff --git a/drivers/net/airoha_eth.c b/drivers/net/airoha_eth.c
-index aae6922f3c7..44d4773bc5d 100644
---- a/drivers/net/airoha_eth.c
-+++ b/drivers/net/airoha_eth.c
-@@ -435,13 +435,14 @@ static int airoha_fe_init(struct airoha_eth *eth)
- return 0;
- }
-
--static void airoha_qdma_reset_rx_desc(struct airoha_queue *q, int index,
-- uchar *rx_packet)
-+static void airoha_qdma_reset_rx_desc(struct airoha_queue *q, int index)
- {
- struct airoha_qdma_desc *desc;
-+ uchar *rx_packet;
- u32 val;
-
- desc = &q->desc[index];
-+ rx_packet = net_rx_packets[index];
- index = (index + 1) % q->ndesc;
-
- dma_map_single(rx_packet, PKTSIZE_ALIGN, DMA_TO_DEVICE);
-@@ -463,7 +464,7 @@ static void airoha_qdma_init_rx_desc(struct airoha_queue *q)
- int i;
-
- for (i = 0; i < q->ndesc; i++)
-- airoha_qdma_reset_rx_desc(q, i, net_rx_packets[i]);
-+ airoha_qdma_reset_rx_desc(q, i);
- }
-
- static int airoha_qdma_init_rx_queue(struct airoha_queue *q,
-@@ -1003,12 +1004,30 @@ static int arht_eth_free_pkt(struct udevice *dev, uchar *packet, int length)
- qid = 0;
- q = &qdma->q_rx[qid];
-
-- dma_map_single(packet, length, DMA_TO_DEVICE);
-+ /*
-+ * Due to cpu cache issue the airoha_qdma_reset_rx_desc() function
-+ * will always touch 2 descriptors placed on the same cacheline:
-+ * - if current descriptor is even, then current and next
-+ * descriptors will be touched
-+ * - if current descriptor is odd, then current and previous
-+ * descriptors will be touched
-+ *
-+ * Thus, to prevent possible destroying of rx queue, we should:
-+ * - do nothing in the even descriptor case,
-+ * - utilize 2 descriptors (current and previous one) in the
-+ * odd descriptor case.
-+ *
-+ * WARNING: Observations shows that PKTBUFSRX must be even and
-+ * larger than 7 for reliable driver operations.
-+ */
-+ if (q->head & 0x01) {
-+ airoha_qdma_reset_rx_desc(q, q->head - 1);
-+ airoha_qdma_reset_rx_desc(q, q->head);
-
-- airoha_qdma_reset_rx_desc(q, q->head, packet);
-+ airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK,
-+ FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head));
-+ }
-
-- airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK,
-- FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head));
- q->head = (q->head + 1) % q->ndesc;
-
- return 0;
---
-2.51.0
-
+++ /dev/null
-From dc0ae3455f4344403e293c9b385653ad3fddb0b1 Mon Sep 17 00:00:00 2001
-Date: Wed, 9 Jul 2025 12:28:10 +0300
-Subject: [PATCH 4/5] drivers/net/airoha_eth: enable hw padding of short tx
- packets
-
-Transmission of short packets does not work good for XFI (GDM2) and
-HSGMII (GDM3) interfaces. The issue can be solved with:
-
- - padding of short packets to 60 bytes
- - setting of PAD_EN bit in the corresponding REG_GDM_FWD_CFG(n)
- register.
-
-The issue should present for the lan switch (GDM1) as well, but it does
-does not appear due to unknown reason.
-
-This patch set PAD_EN bit for the used GDM.
-
----
- drivers/net/airoha_eth.c | 13 +++++++++++--
- 1 file changed, 11 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/net/airoha_eth.c b/drivers/net/airoha_eth.c
-index 53c722379c9..b2f73c7dbb7 100644
---- a/drivers/net/airoha_eth.c
-+++ b/drivers/net/airoha_eth.c
-@@ -116,6 +116,7 @@
- (_n) == 2 ? GDM2_BASE : GDM1_BASE)
-
- #define REG_GDM_FWD_CFG(_n) GDM_BASE(_n)
-+#define GDM_PAD_EN BIT(28)
- #define GDM_DROP_CRC_ERR BIT(23)
- #define GDM_IP4_CKSUM BIT(22)
- #define GDM_TCP_CKSUM BIT(21)
-@@ -423,8 +424,11 @@ static void airoha_fe_maccr_init(struct airoha_eth *eth)
- int p;
-
- for (p = 1; p <= ARRAY_SIZE(eth->ports); p++) {
-- /* Disable any kind of CRC drop or offload */
-- airoha_fe_wr(eth, REG_GDM_FWD_CFG(p), 0);
-+ /*
-+ * Disable any kind of CRC drop or offload.
-+ * Enable padding of short TX packets to 60 bytes.
-+ */
-+ airoha_fe_wr(eth, REG_GDM_FWD_CFG(p), GDM_PAD_EN);
- }
- }
-
-@@ -920,6 +924,11 @@ static int airoha_eth_send(struct udevice *dev, void *packet, int length)
- u32 val;
- int i;
-
-+ /*
-+ * There is no need to pad short TX packets to 60 bytes since the
-+ * GDM_PAD_EN bit set in the corresponding REG_GDM_FWD_CFG(n) register.
-+ */
-+
- dma_addr = dma_map_single(packet, length, DMA_TO_DEVICE);
-
- qid = 0;
---
-2.51.0
-
configs/an7583_evb_defconfig | 1 +
2 files changed, 2 insertions(+)
-diff --git a/configs/an7581_evb_defconfig b/configs/an7581_evb_defconfig
-index c74247e13db..aa1a30aad6a 100644
--- a/configs/an7581_evb_defconfig
+++ b/configs/an7581_evb_defconfig
-@@ -44,6 +44,7 @@ CONFIG_ENV_IS_IN_MMC=y
- CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+@@ -43,6 +43,7 @@ CONFIG_ENV_IS_IN_MMC=y
+ CONFIG_ENV_RELOC_GD_ENV_ADDR=y
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SYS_RX_ETH_BUFFER=8
CONFIG_REGMAP=y
CONFIG_SYSCON=y
CONFIG_CLK=y
-diff --git a/configs/an7583_evb_defconfig b/configs/an7583_evb_defconfig
-index 057104b93af..c67444ae8bf 100644
--- a/configs/an7583_evb_defconfig
+++ b/configs/an7583_evb_defconfig
@@ -44,6 +44,7 @@ CONFIG_ENV_IS_IN_MMC=y
- CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+ CONFIG_ENV_RELOC_GD_ENV_ADDR=y
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SYS_RX_ETH_BUFFER=8
CONFIG_REGMAP=y
CONFIG_SYSCON=y
CONFIG_CLK=y
---
-2.51.0
-
--- a/arch/arm/dts/an7583-evb.dts
+++ b/arch/arm/dts/an7583-evb.dts
-@@ -46,6 +46,28 @@
+@@ -46,6 +46,24 @@
};
};
-+&snfi {
-+ status = "okay";
-+};
-+
+&spi_nand {
+ partitions {
+ compatible = "fixed-partitions";
pinctrl-0 = <&pcie0_rst_pins>;
--- a/configs/an7581_evb_defconfig
+++ b/configs/an7581_evb_defconfig
-@@ -77,3 +77,19 @@ CONFIG_SPI=y
+@@ -78,3 +78,19 @@ CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_AIROHA_SNFI_SPI=y
CONFIG_SHA512=y
+# CONFIG_UBIFS_SILENCE_DEBUG_DUMP is not set
--- a/configs/an7583_evb_defconfig
+++ b/configs/an7583_evb_defconfig
-@@ -79,3 +79,19 @@ CONFIG_SHA512=y
+@@ -80,3 +80,19 @@ CONFIG_SHA512=y
CONFIG_AIROHA_ETH=y
CONFIG_MMC_MTK=y
CONFIG_AIROHA_SNFI_SPI=y
---
configs/an7581_evb_defconfig | 2 ++
configs/an7583_evb_defconfig | 2 ++
- defenvs/an7581_rfb_env | 3 +++
- defenvs/an7583_rfb_env | 3 +++
- 4 files changed, 10 insertions(+)
+ defenvs/an7581_rfb_env | 4 ++++
+ defenvs/an7583_rfb_env | 4 ++++
+ 4 files changed, 12 insertions(+)
create mode 100644 defenvs/an7581_rfb_env
create mode 100644 defenvs/an7583_rfb_env
--- a/configs/an7581_evb_defconfig
+++ b/configs/an7581_evb_defconfig
-@@ -93,3 +93,5 @@ CONFIG_MTD_UBI_BEB_LIMIT=20
+@@ -94,3 +94,5 @@ CONFIG_MTD_UBI_BEB_LIMIT=20
CONFIG_UBI_BLOCK=y
# CONFIG_UBIFS_SILENCE_MSG is not set
# CONFIG_UBIFS_SILENCE_DEBUG_DUMP is not set
-+CONFIG_USE_DEFAULT_ENV_FILE=y
-+CONFIG_DEFAULT_ENV_FILE="defenvs/an7581_rfb_env"
++CONFIG_ENV_USE_DEFAULT_ENV_TEXT_FILE=y
++CONFIG_ENV_DEFAULT_ENV_TEXT_FILE="defenvs/an7581_rfb_env"
--- a/configs/an7583_evb_defconfig
+++ b/configs/an7583_evb_defconfig
-@@ -95,3 +95,5 @@ CONFIG_MTD_UBI_BEB_LIMIT=20
+@@ -96,3 +96,5 @@ CONFIG_MTD_UBI_BEB_LIMIT=20
CONFIG_UBI_BLOCK=y
# CONFIG_UBIFS_SILENCE_MSG is not set
# CONFIG_UBIFS_SILENCE_DEBUG_DUMP is not set
-+CONFIG_USE_DEFAULT_ENV_FILE=y
-+CONFIG_DEFAULT_ENV_FILE="defenvs/an7583_rfb_env"
++CONFIG_ENV_USE_DEFAULT_ENV_TEXT_FILE=y
++CONFIG_ENV_DEFAULT_ENV_TEXT_FILE="defenvs/an7583_rfb_env"
--- /dev/null
+++ b/defenvs/an7581_rfb_env
@@ -0,0 +1,4 @@
--- /dev/null
+From 10bd131a6a365965ce868419933fd7936e91c635 Mon Sep 17 00:00:00 2001
+Date: Mon, 13 Oct 2025 20:48:00 +0300
+Subject: [PATCH 2/3] arm: airoha: disable environment inside mtd partition
+
+When booting on en7581_evb board equipped with spinand flash, a u-boot
+panic occurs. The panic is caused by the absence any available mtd
+partition.
+
+Disable CONFIG_ENV_IS_IN_MTD to avoid an issue. The environment will
+be stored in the EMMC or in UBI, so actually CONFIG_ENV_IS_IN_MTD is
+not needed.
+
+---
+ configs/an7581_evb_defconfig | 1 +
+ configs/an7583_evb_defconfig | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/configs/an7581_evb_defconfig
++++ b/configs/an7581_evb_defconfig
+@@ -40,6 +40,7 @@ CONFIG_CMD_LOG=y
+ CONFIG_OF_UPSTREAM=y
+ CONFIG_ENV_OVERWRITE=y
+ CONFIG_ENV_IS_IN_MMC=y
++# CONFIG_ENV_IS_IN_MTD is not set
+ CONFIG_ENV_RELOC_GD_ENV_ADDR=y
+ CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+ CONFIG_NET_RANDOM_ETHADDR=y
+--- a/configs/an7583_evb_defconfig
++++ b/configs/an7583_evb_defconfig
+@@ -41,6 +41,7 @@ CONFIG_CMD_MTDPARTS=y
+ CONFIG_CMD_LOG=y
+ CONFIG_ENV_OVERWRITE=y
+ CONFIG_ENV_IS_IN_MMC=y
++# CONFIG_ENV_IS_IN_MTD is not set
+ CONFIG_ENV_RELOC_GD_ENV_ADDR=y
+ CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+ CONFIG_NET_RANDOM_ETHADDR=y
+
--- /dev/null
+From 6c4a07ecf211b56eb28fe2dbd8e324b2fdecb84a Mon Sep 17 00:00:00 2001
+Date: Mon, 13 Oct 2025 20:44:24 +0300
+Subject: [PATCH 1/3] arm: airoha: dts: enable spi support for en7581_evb board
+
+spinand flashes are inaccessible without this patch
+
+---
+ arch/arm/dts/en7581-evb-u-boot.dtsi | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/arm/dts/en7581-evb-u-boot.dtsi
++++ b/arch/arm/dts/en7581-evb-u-boot.dtsi
+@@ -9,3 +9,7 @@
+ };
+
+ #include "an7581-u-boot.dtsi"
++
++&snfi {
++ status = "okay";
++};
+
--- /dev/null
+From bee36b6f42792556e123f331ece80f8d5a40e8cd Mon Sep 17 00:00:00 2001
+Date: Mon, 13 Oct 2025 20:56:31 +0300
+Subject: [PATCH 3/3] arm: airoha: enable position independent code
+
+This slightly increase the code, but makes debugging a bit easy
+
+---
+ configs/an7581_evb_defconfig | 1 +
+ configs/an7583_evb_defconfig | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/configs/an7581_evb_defconfig
++++ b/configs/an7581_evb_defconfig
+@@ -1,5 +1,6 @@
+ CONFIG_ARM=y
+ CONFIG_ARCH_AIROHA=y
++CONFIG_POSITION_INDEPENDENT=y
+ CONFIG_TEXT_BASE=0x81E00000
+ CONFIG_SYS_MALLOC_F_LEN=0x4000
+ CONFIG_NR_DRAM_BANKS=1
+--- a/configs/an7583_evb_defconfig
++++ b/configs/an7583_evb_defconfig
+@@ -1,5 +1,6 @@
+ CONFIG_ARM=y
+ CONFIG_ARCH_AIROHA=y
++CONFIG_POSITION_INDEPENDENT=y
+ CONFIG_TARGET_AN7583=y
+ CONFIG_TEXT_BASE=0x81E00000
+ CONFIG_SYS_MALLOC_F_LEN=0x4000
+