[rdkb][common][bsp][Refactor and sync kernel from openwrt]
[Description]
7854d26d [openwrt][mt7988][hnat][Add extensions for 3-WED/3-WDMA offload]
25a45c80 [[openwrt][mt7986][config][free pse buffer or drop the packets that forward to pse port when the pse port link down]]
32b812fc [openwrt][mt7988][arm64: dts: mt7988: add tops pce device tree node]
a867fd44 [openwrt][mt7988][tops][TOPS Alpha release]
e7e3b623 [openwrt][mt7988][pce][TOPS Alpha release]
3009511b [MT7981 SPIM NAND: backport gigadevice.c of kernel v6.4 to v5.4]
4b93c614 [MAC80211][wed][add dma mask limitation for the board w/ >= 4GB dram]
b1cbdaec [kernel][common][config][Enable full debug information for vmlinux]
d97130d4 [openwrt][common][crypto][upgrade openssl from 1.1.1t to 1.1.1v]
b9bf21c8 [kernel][gphy][Add CH395 solution to dsa, gsw]
[Release-log]
Change-Id: I9a221d6f2303a5e0dc297c4ff4479c105a11d6c6
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-1410-mtd-spinand-gigadevice-Support-for-modify-GD-Serial-NAND-from-v6-4-9.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-1410-mtd-spinand-gigadevice-Support-for-modify-GD-Serial-NAND-from-v6-4-9.patch
new file mode 100644
index 0000000..1365854
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-1410-mtd-spinand-gigadevice-Support-for-modify-GD-Serial-NAND-from-v6-4-9.patch
@@ -0,0 +1,420 @@
+Index: linux-5.4.246/drivers/mtd/nand/spi/gigadevice.c
+===================================================================
+--- linux-5.4.246.orig/drivers/mtd/nand/spi/gigadevice.c
++++ linux-5.4.246/drivers/mtd/nand/spi/gigadevice.c
+@@ -13,7 +13,10 @@
+ #define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4)
+ #define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4)
+
+-#define GD5FXGQ4UEXXG_REG_STATUS2 0xf0
++#define GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS (1 << 4)
++#define GD5FXGQ5XE_STATUS_ECC_4_BITFLIPS (3 << 4)
++
++#define GD5FXGQXXEXXG_REG_STATUS2 0xf0
+
+ #define GD5FXGQ4UXFXXG_STATUS_ECC_MASK (7 << 4)
+ #define GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS (0 << 4)
+@@ -36,6 +39,22 @@ static SPINAND_OP_VARIANTS(read_cache_va
+ SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0));
+
++static SPINAND_OP_VARIANTS(read_cache_variants_1gq5,
++ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
++ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
++ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
++ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
++ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
++ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
++
++static SPINAND_OP_VARIANTS(read_cache_variants_2gq5,
++ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 4, NULL, 0),
++ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
++ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 2, NULL, 0),
++ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
++ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
++ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
++
+ static SPINAND_OP_VARIANTS(write_cache_variants,
+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
+ SPINAND_PROG_LOAD(true, 0, NULL, 0));
+@@ -102,7 +121,7 @@ static int gd5fxgq4xa_ecc_get_status(str
+ return -EINVAL;
+ }
+
+-static int gd5fxgq4_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
++static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+ {
+ if (section)
+@@ -114,7 +133,7 @@ static int gd5fxgq4_variant2_ooblayout_e
+ return 0;
+ }
+
+-static int gd5fxgq4_variant2_ooblayout_free(struct mtd_info *mtd, int section,
++static int gd5fxgqx_variant2_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+ {
+ if (section)
+@@ -127,16 +146,46 @@ static int gd5fxgq4_variant2_ooblayout_f
+ return 0;
+ }
+
+-static const struct mtd_ooblayout_ops gd5fxgq4_variant2_ooblayout = {
+- .ecc = gd5fxgq4_variant2_ooblayout_ecc,
+- .free = gd5fxgq4_variant2_ooblayout_free,
++/* Valid for Q4/Q5 and Q6 (untested) devices */
++static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = {
++ .ecc = gd5fxgqx_variant2_ooblayout_ecc,
++ .free = gd5fxgqx_variant2_ooblayout_free,
++};
++
++static int gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info *mtd, int section,
++ struct mtd_oob_region *oobregion)
++{
++ if (section)
++ return -ERANGE;
++
++ oobregion->offset = 128;
++ oobregion->length = 128;
++
++ return 0;
++}
++
++static int gd5fxgq4xc_ooblayout_256_free(struct mtd_info *mtd, int section,
++ struct mtd_oob_region *oobregion)
++{
++ if (section)
++ return -ERANGE;
++
++ oobregion->offset = 1;
++ oobregion->length = 127;
++
++ return 0;
++}
++
++static const struct mtd_ooblayout_ops gd5fxgq4xc_oob_256_ops = {
++ .ecc = gd5fxgq4xc_ooblayout_256_ecc,
++ .free = gd5fxgq4xc_ooblayout_256_free,
+ };
+
+ static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
+ u8 status)
+ {
+ u8 status2;
+- struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQ4UEXXG_REG_STATUS2,
++ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
+ &status2);
+ int ret;
+
+@@ -174,6 +223,43 @@ static int gd5fxgq4uexxg_ecc_get_status(
+ return -EINVAL;
+ }
+
++static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand,
++ u8 status)
++{
++ u8 status2;
++ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
++ &status2);
++ int ret;
++
++ switch (status & STATUS_ECC_MASK) {
++ case STATUS_ECC_NO_BITFLIPS:
++ return 0;
++
++ case GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS:
++ /*
++ * Read status2 register to determine a more fine grained
++ * bit error status
++ */
++ ret = spi_mem_exec_op(spinand->spimem, &op);
++ if (ret)
++ return ret;
++
++ /*
++ * 1 ... 4 bits are flipped (and corrected)
++ */
++ /* bits sorted this way (1...0): ECCSE1, ECCSE0 */
++ return ((status2 & STATUS_ECC_MASK) >> 4) + 1;
++
++ case STATUS_ECC_UNCOR_ERROR:
++ return -EBADMSG;
++
++ default:
++ break;
++ }
++
++ return -EINVAL;
++}
++
+ static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
+ u8 status)
+ {
+@@ -195,7 +281,8 @@ static int gd5fxgq4ufxxg_ecc_get_status(
+ }
+
+ static const struct spinand_info gigadevice_spinand_table[] = {
+- SPINAND_INFO("GD5F1GQ4xA", 0xF1,
++ SPINAND_INFO("GD5F1GQ4xA",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -204,7 +291,8 @@ static const struct spinand_info gigadev
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
+ gd5fxgq4xa_ecc_get_status)),
+- SPINAND_INFO("GD5F2GQ4xA", 0xF2,
++ SPINAND_INFO("GD5F2GQ4xA",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2),
+ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -213,7 +301,8 @@ static const struct spinand_info gigadev
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
+ gd5fxgq4xa_ecc_get_status)),
+- SPINAND_INFO("GD5F4GQ4xA", 0xF4,
++ SPINAND_INFO("GD5F4GQ4xA",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4),
+ NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -222,59 +311,205 @@ static const struct spinand_info gigadev
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
+ gd5fxgq4xa_ecc_get_status)),
+- SPINAND_INFO("GD5F1GQ4UExxG", 0xd1,
++ SPINAND_INFO("GD5F4GQ4RC",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xa4, 0x68),
++ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
++ NAND_ECCREQ(8, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
++ &write_cache_variants,
++ &update_cache_variants),
++ SPINAND_HAS_QE_BIT,
++ SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
++ gd5fxgq4ufxxg_ecc_get_status)),
++ SPINAND_INFO("GD5F4GQ4UC",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb4, 0x68),
++ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
++ NAND_ECCREQ(8, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
++ &write_cache_variants,
++ &update_cache_variants),
++ SPINAND_HAS_QE_BIT,
++ SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
++ gd5fxgq4ufxxg_ecc_get_status)),
++ SPINAND_INFO("GD5F1GQ4UExxG",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1),
++ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
++ NAND_ECCREQ(8, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++ &write_cache_variants,
++ &update_cache_variants),
++ SPINAND_HAS_QE_BIT,
++ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++ gd5fxgq4uexxg_ecc_get_status)),
++ SPINAND_INFO("GD5F1GQ4RExxG",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc1),
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+- SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout,
++ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++ gd5fxgq4uexxg_ecc_get_status)),
++ SPINAND_INFO("GD5F2GQ4UExxG",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd2),
++ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
++ NAND_ECCREQ(8, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++ &write_cache_variants,
++ &update_cache_variants),
++ SPINAND_HAS_QE_BIT,
++ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
+ gd5fxgq4uexxg_ecc_get_status)),
+- SPINAND_INFO("GD5F1GQ4UFxxG", 0xb148,
++ SPINAND_INFO("GD5F2GQ4RExxG",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc2),
++ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
++ NAND_ECCREQ(8, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++ &write_cache_variants,
++ &update_cache_variants),
++ SPINAND_HAS_QE_BIT,
++ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++ gd5fxgq4uexxg_ecc_get_status)),
++ SPINAND_INFO("GD5F1GQ4UFxxG",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48),
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+- SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout,
++ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
+ gd5fxgq4ufxxg_ecc_get_status)),
++ SPINAND_INFO("GD5F1GQ5UExxG",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51),
++ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
++ NAND_ECCREQ(4, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
++ &write_cache_variants,
++ &update_cache_variants),
++ SPINAND_HAS_QE_BIT,
++ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++ gd5fxgq5xexxg_ecc_get_status)),
++ SPINAND_INFO("GD5F1GQ5RExxG",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x41),
++ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
++ NAND_ECCREQ(4, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
++ &write_cache_variants,
++ &update_cache_variants),
++ SPINAND_HAS_QE_BIT,
++ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++ gd5fxgq5xexxg_ecc_get_status)),
++ SPINAND_INFO("GD5F2GQ5UExxG",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x52),
++ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
++ NAND_ECCREQ(4, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
++ &write_cache_variants,
++ &update_cache_variants),
++ SPINAND_HAS_QE_BIT,
++ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++ gd5fxgq5xexxg_ecc_get_status)),
++ SPINAND_INFO("GD5F2GQ5RExxG",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x42),
++ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
++ NAND_ECCREQ(4, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
++ &write_cache_variants,
++ &update_cache_variants),
++ SPINAND_HAS_QE_BIT,
++ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++ gd5fxgq5xexxg_ecc_get_status)),
++ SPINAND_INFO("GD5F4GQ6UExxG",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x55),
++ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1),
++ NAND_ECCREQ(4, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
++ &write_cache_variants,
++ &update_cache_variants),
++ SPINAND_HAS_QE_BIT,
++ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++ gd5fxgq5xexxg_ecc_get_status)),
++ SPINAND_INFO("GD5F4GQ6RExxG",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x45),
++ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1),
++ NAND_ECCREQ(4, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
++ &write_cache_variants,
++ &update_cache_variants),
++ SPINAND_HAS_QE_BIT,
++ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++ gd5fxgq5xexxg_ecc_get_status)),
++ SPINAND_INFO("GD5F1GM7UExxG",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x91),
++ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
++ NAND_ECCREQ(8, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
++ &write_cache_variants,
++ &update_cache_variants),
++ SPINAND_HAS_QE_BIT,
++ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++ gd5fxgq4uexxg_ecc_get_status)),
++ SPINAND_INFO("GD5F1GM7RExxG",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x81),
++ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
++ NAND_ECCREQ(8, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
++ &write_cache_variants,
++ &update_cache_variants),
++ SPINAND_HAS_QE_BIT,
++ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++ gd5fxgq4uexxg_ecc_get_status)),
++ SPINAND_INFO("GD5F2GM7UExxG",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92),
++ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
++ NAND_ECCREQ(8, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
++ &write_cache_variants,
++ &update_cache_variants),
++ SPINAND_HAS_QE_BIT,
++ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++ gd5fxgq4uexxg_ecc_get_status)),
++ SPINAND_INFO("GD5F2GM7RExxG",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x82),
++ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
++ NAND_ECCREQ(8, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
++ &write_cache_variants,
++ &update_cache_variants),
++ SPINAND_HAS_QE_BIT,
++ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++ gd5fxgq4uexxg_ecc_get_status)),
++ SPINAND_INFO("GD5F4GM8UExxG",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x95),
++ NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
++ NAND_ECCREQ(8, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
++ &write_cache_variants,
++ &update_cache_variants),
++ SPINAND_HAS_QE_BIT,
++ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++ gd5fxgq4uexxg_ecc_get_status)),
++ SPINAND_INFO("GD5F4GM8RExxG",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x85),
++ NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
++ NAND_ECCREQ(8, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
++ &write_cache_variants,
++ &update_cache_variants),
++ SPINAND_HAS_QE_BIT,
++ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++ gd5fxgq4uexxg_ecc_get_status)),
+ };
+
+-static int gigadevice_spinand_detect(struct spinand_device *spinand)
+-{
+- u8 *id = spinand->id.data;
+- u16 did;
+- int ret;
+-
+- /*
+- * Earlier GDF5-series devices (A,E) return [0][MID][DID]
+- * Later (F) devices return [MID][DID1][DID2]
+- */
+-
+- if (id[0] == SPINAND_MFR_GIGADEVICE)
+- did = (id[1] << 8) + id[2];
+- else if (id[0] == 0 && id[1] == SPINAND_MFR_GIGADEVICE)
+- did = id[2];
+- else
+- return 0;
+-
+- ret = spinand_match_and_init(spinand, gigadevice_spinand_table,
+- ARRAY_SIZE(gigadevice_spinand_table),
+- did);
+- if (ret)
+- return ret;
+-
+- return 1;
+-}
+-
+ static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
+- .detect = gigadevice_spinand_detect,
+ };
+
+ const struct spinand_manufacturer gigadevice_spinand_manufacturer = {
+ .id = SPINAND_MFR_GIGADEVICE,
+ .name = "GigaDevice",
++ .chips = gigadevice_spinand_table,
++ .nchips = ARRAY_SIZE(gigadevice_spinand_table),
+ .ops = &gigadevice_spinand_manuf_ops,
+ };
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2310-v5.7-mtd-nand-spi-rework-detect-procedure-for-different-read-id-op.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2310-v5.7-mtd-nand-spi-rework-detect-procedure-for-different-read-id-op.patch
index f9c3542..a8c62fa 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2310-v5.7-mtd-nand-spi-rework-detect-procedure-for-different-read-id-op.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2310-v5.7-mtd-nand-spi-rework-detect-procedure-for-different-read-id-op.patch
@@ -6,7 +6,6 @@
---
drivers/mtd/nand/spi/core.c | 86 ++++++++++++++++++++++---------
- drivers/mtd/nand/spi/gigadevice.c | 45 +++++-----------
drivers/mtd/nand/spi/macronix.c | 30 +++--------
drivers/mtd/nand/spi/micron.c | 26 ++--------
drivers/mtd/nand/spi/paragon.c | 28 +++-------
@@ -172,102 +171,6 @@
if (ret) {
dev_err(dev, "unknown raw ID %*phN\n", SPINAND_MAX_ID_LEN,
spinand->id.data);
-diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
-index b13b39763..a34c5ede1 100644
---- a/drivers/mtd/nand/spi/gigadevice.c
-+++ b/drivers/mtd/nand/spi/gigadevice.c
-@@ -195,7 +195,8 @@ static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
- }
-
- static const struct spinand_info gigadevice_spinand_table[] = {
-- SPINAND_INFO("GD5F1GQ4xA", 0xF1,
-+ SPINAND_INFO("GD5F1GQ4xA",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
- NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
- NAND_ECCREQ(8, 512),
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -204,7 +205,8 @@ static const struct spinand_info gigadevice_spinand_table[] = {
- SPINAND_HAS_QE_BIT,
- SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
- gd5fxgq4xa_ecc_get_status)),
-- SPINAND_INFO("GD5F2GQ4xA", 0xF2,
-+ SPINAND_INFO("GD5F2GQ4xA",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2),
- NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
- NAND_ECCREQ(8, 512),
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -213,7 +215,8 @@ static const struct spinand_info gigadevice_spinand_table[] = {
- SPINAND_HAS_QE_BIT,
- SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
- gd5fxgq4xa_ecc_get_status)),
-- SPINAND_INFO("GD5F4GQ4xA", 0xF4,
-+ SPINAND_INFO("GD5F4GQ4xA",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4),
- NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1),
- NAND_ECCREQ(8, 512),
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -222,7 +225,8 @@ static const struct spinand_info gigadevice_spinand_table[] = {
- SPINAND_HAS_QE_BIT,
- SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
- gd5fxgq4xa_ecc_get_status)),
-- SPINAND_INFO("GD5F1GQ4UExxG", 0xd1,
-+ SPINAND_INFO("GD5F1GQ4UExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1),
- NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
- NAND_ECCREQ(8, 512),
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -231,7 +235,8 @@ static const struct spinand_info gigadevice_spinand_table[] = {
- SPINAND_HAS_QE_BIT,
- SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout,
- gd5fxgq4uexxg_ecc_get_status)),
-- SPINAND_INFO("GD5F1GQ4UFxxG", 0xb148,
-+ SPINAND_INFO("GD5F1GQ4UFxxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48),
- NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
- NAND_ECCREQ(8, 512),
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
-@@ -242,39 +247,13 @@ static const struct spinand_info gigadevice_spinand_table[] = {
- gd5fxgq4ufxxg_ecc_get_status)),
- };
-
--static int gigadevice_spinand_detect(struct spinand_device *spinand)
--{
-- u8 *id = spinand->id.data;
-- u16 did;
-- int ret;
--
-- /*
-- * Earlier GDF5-series devices (A,E) return [0][MID][DID]
-- * Later (F) devices return [MID][DID1][DID2]
-- */
--
-- if (id[0] == SPINAND_MFR_GIGADEVICE)
-- did = (id[1] << 8) + id[2];
-- else if (id[0] == 0 && id[1] == SPINAND_MFR_GIGADEVICE)
-- did = id[2];
-- else
-- return 0;
--
-- ret = spinand_match_and_init(spinand, gigadevice_spinand_table,
-- ARRAY_SIZE(gigadevice_spinand_table),
-- did);
-- if (ret)
-- return ret;
--
-- return 1;
--}
--
- static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
-- .detect = gigadevice_spinand_detect,
- };
-
- const struct spinand_manufacturer gigadevice_spinand_manufacturer = {
- .id = SPINAND_MFR_GIGADEVICE,
- .name = "GigaDevice",
-+ .chips = gigadevice_spinand_table,
-+ .nchips = ARRAY_SIZE(gigadevice_spinand_table),
- .ops = &gigadevice_spinand_manuf_ops,
- };
diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
index 21def3f8f..0f900f3aa 100644
--- a/drivers/mtd/nand/spi/macronix.c
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2311-mtd-spinand-gigadevice-Support-GD5F1GQ5UExxG.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2311-mtd-spinand-gigadevice-Support-GD5F1GQ5UExxG.patch
deleted file mode 100644
index e3e81e5..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2311-mtd-spinand-gigadevice-Support-GD5F1GQ5UExxG.patch
+++ /dev/null
@@ -1,142 +0,0 @@
-From 2f8ed664925318dacb6a92ca6383b5589cc2f7e1 Mon Sep 17 00:00:00 2001
-From: Sam Shih <sam.shih@mediatek.com>
-Date: Fri, 2 Jun 2023 13:06:09 +0800
-Subject: [PATCH]
- [spi-and-storage][999-2311-mtd-spinand-gigadevice-Support-GD5F1GQ5UExxG.patch]
-
----
- drivers/mtd/nand/spi/gigadevice.c | 69 +++++++++++++++++++++++++++----
- 1 file changed, 60 insertions(+), 9 deletions(-)
-
-diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
-index a34c5ede1..937a04ce6 100644
---- a/drivers/mtd/nand/spi/gigadevice.c
-+++ b/drivers/mtd/nand/spi/gigadevice.c
-@@ -13,7 +13,10 @@
- #define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4)
- #define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4)
-
--#define GD5FXGQ4UEXXG_REG_STATUS2 0xf0
-+#define GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS (1 << 4)
-+#define GD5FXGQ5XE_STATUS_ECC_4_BITFLIPS (3 << 4)
-+
-+#define GD5FXGQXXEXXG_REG_STATUS2 0xf0
-
- #define GD5FXGQ4UXFXXG_STATUS_ECC_MASK (7 << 4)
- #define GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS (0 << 4)
-@@ -102,7 +105,7 @@ static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand,
- return -EINVAL;
- }
-
--static int gd5fxgq4_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
-+static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
- struct mtd_oob_region *region)
- {
- if (section)
-@@ -114,7 +117,7 @@ static int gd5fxgq4_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
- return 0;
- }
-
--static int gd5fxgq4_variant2_ooblayout_free(struct mtd_info *mtd, int section,
-+static int gd5fxgqx_variant2_ooblayout_free(struct mtd_info *mtd, int section,
- struct mtd_oob_region *region)
- {
- if (section)
-@@ -127,16 +130,17 @@ static int gd5fxgq4_variant2_ooblayout_free(struct mtd_info *mtd, int section,
- return 0;
- }
-
--static const struct mtd_ooblayout_ops gd5fxgq4_variant2_ooblayout = {
-- .ecc = gd5fxgq4_variant2_ooblayout_ecc,
-- .free = gd5fxgq4_variant2_ooblayout_free,
-+/* Valid for Q4/Q5 and Q6 (untested) devices */
-+static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = {
-+ .ecc = gd5fxgqx_variant2_ooblayout_ecc,
-+ .free = gd5fxgqx_variant2_ooblayout_free,
- };
-
- static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
- u8 status)
- {
- u8 status2;
-- struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQ4UEXXG_REG_STATUS2,
-+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
- &status2);
- int ret;
-
-@@ -174,6 +178,43 @@ static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
- return -EINVAL;
- }
-
-+static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand,
-+ u8 status)
-+{
-+ u8 status2;
-+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
-+ &status2);
-+ int ret;
-+
-+ switch (status & STATUS_ECC_MASK) {
-+ case STATUS_ECC_NO_BITFLIPS:
-+ return 0;
-+
-+ case GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS:
-+ /*
-+ * Read status2 register to determine a more fine grained
-+ * bit error status
-+ */
-+ ret = spi_mem_exec_op(spinand->spimem, &op);
-+ if (ret)
-+ return ret;
-+
-+ /*
-+ * 1 ... 4 bits are flipped (and corrected)
-+ */
-+ /* bits sorted this way (1...0): ECCSE1, ECCSE0 */
-+ return ((status2 & STATUS_ECC_MASK) >> 4) + 1;
-+
-+ case STATUS_ECC_UNCOR_ERROR:
-+ return -EBADMSG;
-+
-+ default:
-+ break;
-+ }
-+
-+ return -EINVAL;
-+}
-+
- static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
- u8 status)
- {
-@@ -233,7 +274,7 @@ static const struct spinand_info gigadevice_spinand_table[] = {
- &write_cache_variants,
- &update_cache_variants),
- SPINAND_HAS_QE_BIT,
-- SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
- gd5fxgq4uexxg_ecc_get_status)),
- SPINAND_INFO("GD5F1GQ4UFxxG",
- SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48),
-@@ -243,8 +284,18 @@ static const struct spinand_info gigadevice_spinand_table[] = {
- &write_cache_variants,
- &update_cache_variants),
- SPINAND_HAS_QE_BIT,
-- SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
- gd5fxgq4ufxxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F1GQ5UExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51),
-+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
-+ NAND_ECCREQ(4, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq5xexxg_ecc_get_status)),
- };
-
- static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
---
-2.34.1
-
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/backport-5.4.inc b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/backport-5.4.inc
index d2c5014..10b63da 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/backport-5.4.inc
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/backport-5.4.inc
@@ -300,10 +300,10 @@
file://900-v5.9-0001-dt-bindings-Add-multicolor-class-dt-bindings-documen.patch \
file://900-v5.9-0002-leds-Add-multicolor-ID-to-the-color-ID-list.patch \
file://900-v5.9-0003-leds-add-RGB-color-option-as-that-is-different-from-.patch \
+ file://999-1410-mtd-spinand-gigadevice-Support-for-modify-GD-Serial-NAND-from-v6-4-9.patch \
file://999-1900-lib-add-Dhrystone-benchmark-test.patch \
file://999-2210-v6.1-iio-adc-add-rtq6056-support.patch \
file://999-2310-v5.7-mtd-nand-spi-rework-detect-procedure-for-different-read-id-op.patch \
- file://999-2311-mtd-spinand-gigadevice-Support-GD5F1GQ5UExxG.patch \
file://999-2312-mtd-spinand-macronix-Add-support-for-MX31LF1GE4BC.patch \
file://999-2313-mtd-spinand-macronix-Add-support-for-MX31UF1GE4BC.patch \
file://999-2314-mtd-spinand-macronix-Add-support-for-MX35LFxGE4AD.patch \
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi
index 3033801..92b32c5 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi
@@ -370,6 +370,61 @@
};
+ tops: tops@09100000 {
+ compatible = "mediatek,tops";
+ reg = <0 0x09100000 0 0x01000000>;
+ reg-names = "tops-base";
+ clocks = <&topckgen CK_TOP_BUS_TOPS_SEL>,
+ <&topckgen CK_TOP_TOPS_P2_26M_SEL>,
+ <&topckgen CK_TOP_NETSYS_TOPS_400M_SEL>,
+ <&topckgen CK_TOP_NPU_TOPS_SEL>,
+ <&topckgen CK_TOP_CK_NPU_SEL_CM_TOPS_SEL>;
+ clock-names = "bus", "sram", "xdma", "offload", "mgmt";
+ power-domains = <&topmisc MT7988_POWER_DOMAIN_TOPS0>,
+ <&topmisc MT7988_POWER_DOMAIN_TOPS1>;
+
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tdma-tx-pause", "mbox", "wdt";
+
+ dmas = <&hpdma1 0>;
+ dma-names = "tnl-sync";
+
+ fe_mem = <ð>;
+ };
+
+ tops-mbox {
+ compatible = "mediatek,tops-mbox";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "mbox";
+ tops = <&tops>;
+ };
+
+ hpdma1: hpdma@09106000 {
+ compatible = "mediatek,hpdma-top";
+ reg = <0 0x09106000 0 0x1000>;
+ reg-names = "base";
+ #dma-cells = <1>;
+ };
+
+ hpdma2: hpdma@09606000 {
+ compatible = "mediatek,hpdma-sub";
+ reg = <0 0x09606000 0 0x1000>;
+ reg-names = "base";
+ #dma-cells = <2>;
+ };
+
+ tops-ocd@0e500000 {
+ compatible = "mediatek,tops-ocd";
+ reg = <0 0x0e500000 0 0x15000>;
+ reg-names = "tops-ocd-base";
+ clocks = <&infracfg_ao CK_INFRA_AUD_L>;
+ clock-names = "debugsys";
+ };
+
watchdog: watchdog@1001c000 {
compatible = "mediatek,mt7622-wdt",
"mediatek,mt6589-wdt",
@@ -865,6 +920,12 @@
status = "disabled";
};
+ pce: pce@15100000 {
+ compatible = "mediatek,pce";
+
+ fe_mem = <ð>;
+ };
+
sgmiisys0: syscon@10060000 {
compatible = "mediatek,mt7988-sgmiisys",
"mediatek,mt7988-sgmiisys_0",
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 6272f11..29630a8 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -875,6 +875,82 @@
return 1;
}
+static int mtk_gdm_fsm_get(struct mtk_mac *mac, u32 gdm)
+{
+ u32 fsm = mtk_r32(mac->hw, gdm);
+ u32 ret = 0;
+
+ if (mac->type == MTK_GDM_TYPE)
+ ret = fsm == 0;
+ else if (mac->type == MTK_XGDM_TYPE) {
+ if (mac->id == MTK_GMAC1_ID) {
+ if (((fsm & 0x7ffffff) == 0) &&
+ (mtk_r32(mac->hw, MTK_MAC_FSM(mac->id)) == 0x1010000))
+ ret = 1;
+ } else
+ ret = ((mac->interface == PHY_INTERFACE_MODE_XGMII) ?
+ ((fsm & 0xfffffff) == 0) : ((fsm & 0x0ffffff) == 0));
+ }
+
+ return ret;
+}
+
+static void mtk_gdm_fsm_poll(struct mtk_mac *mac)
+{
+ u32 gdm = 0, i = 0;
+
+ switch (mac->id) {
+ case MTK_GMAC1_ID:
+ gdm = MTK_FE_GDM1_FSM;
+ break;
+ case MTK_GMAC2_ID:
+ gdm = MTK_FE_GDM2_FSM;
+ break;
+ case MTK_GMAC3_ID:
+ gdm = MTK_FE_GDM3_FSM;
+ break;
+ default:
+ pr_info("%s mac id invalid", __func__);
+ break;
+ }
+ msleep(500);
+ while (i < 3) {
+ if (mtk_gdm_fsm_get(mac, gdm))
+ break;
+ msleep(500);
+ i++;
+ }
+
+ if (i == 3)
+ pr_info("%s fsm invalid", __func__);
+}
+
+static void mtk_pse_port_link_set(struct mtk_mac *mac, bool up)
+{
+ u32 fe_glo_cfg, val;
+
+ fe_glo_cfg = mtk_r32(mac->hw, MTK_FE_GLO_CFG(mac->id));
+ switch (mac->id) {
+ case MTK_GMAC1_ID:
+ val = MTK_FE_LINK_DOWN_P1;
+ break;
+ case MTK_GMAC2_ID:
+ val = MTK_FE_LINK_DOWN_P2;
+ break;
+ case MTK_GMAC3_ID:
+ val = MTK_FE_LINK_DOWN_P15;
+ break;
+ }
+
+ if (!up)
+ fe_glo_cfg |= val;
+ else
+ fe_glo_cfg &= ~val;
+
+ mtk_w32(mac->hw, fe_glo_cfg, MTK_FE_GLO_CFG(mac->id));
+ mtk_gdm_fsm_poll(mac);
+}
+
static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode,
phy_interface_t interface)
{
@@ -882,9 +958,10 @@
phylink_config);
u32 mcr, sts;
+ mtk_pse_port_link_set(mac, false);
if (mac->type == MTK_GDM_TYPE) {
mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
- mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN);
+ mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK);
mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
} else if (mac->type == MTK_XGDM_TYPE && mac->id != MTK_GMAC1_ID) {
mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
@@ -986,6 +1063,7 @@
mcr &= ~(XMAC_MCR_TRX_DISABLE);
mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
}
+ mtk_pse_port_link_set(mac, true);
}
static void mtk_validate(struct phylink_config *config,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 57bf7b1..f87635c 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -69,9 +69,12 @@
#define MTK_RSS_MAX_INDIRECTION_TABLE 128
/* Frame Engine Global Configuration */
-#define MTK_FE_GLO_CFG 0x00
+#define MTK_FE_GLO_CFG(x) ((x == MTK_GMAC3_ID) ? 0x24 : 0x00)
+#define MTK_FE_LINK_DOWN_P1 BIT(9)
+#define MTK_FE_LINK_DOWN_P2 BIT(10)
#define MTK_FE_LINK_DOWN_P3 BIT(11)
#define MTK_FE_LINK_DOWN_P4 BIT(12)
+#define MTK_FE_LINK_DOWN_P15 BIT(7)
/* Frame Engine Global Reset Register */
#define MTK_RST_GL 0x04
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
index 2337f0e..331fce9 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
@@ -1048,7 +1048,8 @@
#define FROM_GE_VIRTUAL(skb) (skb_hnat_iface(skb) == FOE_MAGIC_GE_VIRTUAL)
#define FROM_EXT(skb) (skb_hnat_iface(skb) == FOE_MAGIC_EXT)
#define FROM_WED(skb) ((skb_hnat_iface(skb) == FOE_MAGIC_WED0) || \
- (skb_hnat_iface(skb) == FOE_MAGIC_WED1))
+ (skb_hnat_iface(skb) == FOE_MAGIC_WED1) || \
+ (skb_hnat_iface(skb) == FOE_MAGIC_WED2))
#define FOE_MAGIC_GE_LAN 0x1
#define FOE_MAGIC_GE_WAN 0x2
#define FOE_MAGIC_EXT 0x3
@@ -1084,6 +1085,7 @@
#define NR_DISCARD 7
#define NR_WDMA0_PORT 8
#define NR_WDMA1_PORT 9
+#define NR_WDMA2_PORT 13
#define NR_GMAC3_PORT 15
#define LAN_DEV_NAME hnat_priv->lan
#define LAN2_DEV_NAME hnat_priv->lan2
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
index 59b3e71..31c03ca 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
@@ -1834,7 +1834,7 @@
skb_hnat_wc_id(skb), skb_hnat_rx_id(skb));
if ((gmac_no != NR_WDMA0_PORT) && (gmac_no != NR_WDMA1_PORT) &&
- (gmac_no != NR_WHNAT_WDMA_PORT))
+ (gmac_no != NR_WDMA2_PORT) && (gmac_no != NR_WHNAT_WDMA_PORT))
return NF_ACCEPT;
if (unlikely(!skb_mac_header_was_set(skb)))
@@ -1914,7 +1914,8 @@
gmac_no == NR_WHNAT_WDMA_PORT) ||
((hnat_priv->data->version == MTK_HNAT_V2 ||
hnat_priv->data->version == MTK_HNAT_V3) &&
- (gmac_no == NR_WDMA0_PORT || gmac_no == NR_WDMA1_PORT))) {
+ (gmac_no == NR_WDMA0_PORT || gmac_no == NR_WDMA1_PORT ||
+ gmac_no == NR_WDMA2_PORT))) {
entry->ipv4_hnapt.winfo.bssid = skb_hnat_bss_id(skb);
entry->ipv4_hnapt.winfo.wcid = skb_hnat_wc_id(skb);
#if defined(CONFIG_MEDIATEK_NETSYS_V3)
@@ -1984,7 +1985,8 @@
gmac_no == NR_WHNAT_WDMA_PORT) ||
((hnat_priv->data->version == MTK_HNAT_V2 ||
hnat_priv->data->version == MTK_HNAT_V3) &&
- (gmac_no == NR_WDMA0_PORT || gmac_no == NR_WDMA1_PORT))) {
+ (gmac_no == NR_WDMA0_PORT || gmac_no == NR_WDMA1_PORT ||
+ gmac_no == NR_WDMA2_PORT))) {
entry->ipv6_5t_route.winfo.bssid = skb_hnat_bss_id(skb);
entry->ipv6_5t_route.winfo.wcid = skb_hnat_wc_id(skb);
#if defined(CONFIG_MEDIATEK_NETSYS_V3)
@@ -2063,6 +2065,8 @@
skb_hnat_sport(skb) = NR_WDMA0_PORT;
else if (skb_hnat_iface(skb) == FOE_MAGIC_WED1)
skb_hnat_sport(skb) = NR_WDMA1_PORT;
+ else if (skb_hnat_iface(skb) == FOE_MAGIC_WED2)
+ skb_hnat_sport(skb) = NR_WDMA2_PORT;
return NF_ACCEPT;
}
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-ge.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-ge.c
index 977a90b..60ef22c 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-ge.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-ge.c
@@ -11,6 +11,10 @@
#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
+#define MTK_PHY_RG_DEV1E_REG2C7 0x2c7
+#define MTK_PHY_MAX_GAIN_MASK GENMASK(4, 0)
+#define MTK_PHY_MIN_GAIN_MASK GENMASK(12, 8)
+
static int mtk_gephy_read_page(struct phy_device *phydev)
{
return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
@@ -65,6 +69,11 @@
phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
+ /* Adjust RX min/max gain to fix CH395 100Mbps link up fail */
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7,
+ FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) |
+ FIELD_PREP(MTK_PHY_MIN_GAIN_MASK, 0x13));
+
return 0;
}
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt7531.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt7531.c
index b27c679..4cfb0ef 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt7531.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt7531.c
@@ -132,6 +132,10 @@
#define PHY_DEV1E_REG_189 0x189
#define PHY_DEV1E_REG_234 0x234
+#define PHY_DEV1E_REG_2C7 0x2c7
+#define MTK_PHY_MAX_GAIN_MASK GENMASK(4, 0)
+#define MTK_PHY_MIN_GAIN_MASK GENMASK(12, 8)
+
/* Fields of PHY_DEV1E_REG_0C6 */
#define PHY_POWER_SAVING_S 8
#define PHY_POWER_SAVING_M 0x300
@@ -874,6 +878,11 @@
val = gsw->mii_read(gsw, i, MII_ADVERTISE);
val |= ADVERTISE_PAUSE_ASYM;
gsw->mii_write(gsw, i, MII_ADVERTISE, val);
+
+ /* Adjust RX min/max gain to fix CH395 100Mbps link up fail */
+ gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_2C7,
+ FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) |
+ FIELD_PREP(MTK_PHY_MIN_GAIN_MASK, 0x13));
}
}
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7986.cfg b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7986.cfg
index 2f3f416..830294f 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7986.cfg
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7986.cfg
@@ -301,7 +301,7 @@
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
# CONFIG_MEDIATEK_2P5GE_PHY is not set
-# CONFIG_MEDIATEK_GE_PHY is not set
+CONFIG_MEDIATEK_GE_PHY=y
# CONFIG_MEDIATEK_GE_SOC_PHY is not set
CONFIG_MEDIATEK_MT6577_AUXADC=y
CONFIG_MEDIATEK_NETSYS_V2=y
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4100-mtk-tops-tunnel-offload-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4100-mtk-tops-tunnel-offload-support.patch
new file mode 100644
index 0000000..a4a6d95
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4100-mtk-tops-tunnel-offload-support.patch
@@ -0,0 +1,450 @@
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -245,6 +245,9 @@ static const char * const mtk_clks_sourc
+ "top_netsys_warp_sel",
+ };
+
++struct net_device *(*mtk_get_tnl_dev)(int tnl_idx) = NULL;
++EXPORT_SYMBOL(mtk_get_tnl_dev);
++
+ void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg)
+ {
+ __raw_writel(val, eth->base + reg);
+@@ -2089,6 +2092,7 @@ static int mtk_poll_rx(struct napi_struc
+ u64 addr64 = 0;
+ u8 *data, *new_data;
+ struct mtk_rx_dma_v2 *rxd, trxd;
++ int tnl_idx = 0;
+ int done = 0;
+
+ if (unlikely(!ring))
+@@ -2132,11 +2136,20 @@ static int mtk_poll_rx(struct napi_struc
+ 0 : RX_DMA_GET_SPORT(trxd.rxd4) - 1;
+ }
+
+- if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
+- !eth->netdev[mac]))
+- goto release_desc;
++ tnl_idx = RX_DMA_GET_TOPS_CRSN(trxd.rxd6);
++ if (mtk_get_tnl_dev && tnl_idx) {
++ netdev = mtk_get_tnl_dev(tnl_idx);
++ if (unlikely(IS_ERR(netdev)))
++ netdev = NULL;
++ }
+
+- netdev = eth->netdev[mac];
++ if (!netdev) {
++ if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
++ !eth->netdev[mac]))
++ goto release_desc;
++
++ netdev = eth->netdev[mac];
++ }
+
+ if (unlikely(test_bit(MTK_RESETTING, ð->state)))
+ goto release_desc;
+@@ -2221,6 +2234,8 @@ static int mtk_poll_rx(struct napi_struc
+ skb_hnat_alg(skb) = 0;
+ skb_hnat_filled(skb) = 0;
+ skb_hnat_magic_tag(skb) = HNAT_MAGIC_TAG;
++ skb_hnat_set_tops(skb, 0);
++ skb_hnat_set_is_decap(skb, 0);
+
+ if (skb_hnat_reason(skb) == HIT_BIND_FORCE_TO_CPU) {
+ trace_printk("[%s] reason=0x%x(force to CPU) from WAN to Ext\n",
+--- a/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c
++++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c
+@@ -43,6 +43,12 @@ void (*ppe_dev_register_hook)(struct net
+ EXPORT_SYMBOL(ppe_dev_register_hook);
+ void (*ppe_dev_unregister_hook)(struct net_device *dev) = NULL;
+ EXPORT_SYMBOL(ppe_dev_unregister_hook);
++int (*mtk_tnl_encap_offload)(struct sk_buff *skb) = NULL;
++EXPORT_SYMBOL(mtk_tnl_encap_offload);
++int (*mtk_tnl_decap_offload)(struct sk_buff *skb) = NULL;
++EXPORT_SYMBOL(mtk_tnl_decap_offload);
++bool (*mtk_tnl_decap_offloadable)(struct sk_buff *skb) = NULL;
++EXPORT_SYMBOL(mtk_tnl_decap_offloadable);
+
+ static void hnat_sma_build_entry(struct timer_list *t)
+ {
+@@ -53,6 +59,16 @@ static void hnat_sma_build_entry(struct
+ SMA, SMA_FWD_CPU_BUILD_ENTRY);
+ }
+
++struct foe_entry *hnat_get_foe_entry(u32 ppe_id, u32 index)
++{
++ if (index == 0x7fff || index >= hnat_priv->foe_etry_num
++ || ppe_id >= CFG_PPE_NUM)
++ return ERR_PTR(-EINVAL);
++
++ return &hnat_priv->foe_table_cpu[ppe_id][index];
++}
++EXPORT_SYMBOL(hnat_get_foe_entry);
++
+ void hnat_cache_ebl(int enable)
+ {
+ int i;
+@@ -63,6 +79,7 @@ void hnat_cache_ebl(int enable)
+ cr_set_field(hnat_priv->ppe_base[i] + PPE_CAH_CTRL, CAH_EN, enable);
+ }
+ }
++EXPORT_SYMBOL(hnat_cache_ebl);
+
+ static void hnat_reset_timestamp(struct timer_list *t)
+ {
+--- a/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
++++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
+@@ -1085,6 +1085,8 @@ enum FoeIpAct {
+ #define NR_WDMA0_PORT 8
+ #define NR_WDMA1_PORT 9
+ #define NR_GMAC3_PORT 15
++#define NR_TDMA_TPORT 4
++#define NR_TDMA_QDMA_TPORT 5
+ #define LAN_DEV_NAME hnat_priv->lan
+ #define LAN2_DEV_NAME hnat_priv->lan2
+ #define IS_WAN(dev) \
+@@ -1208,6 +1210,8 @@ static inline bool hnat_dsa_is_enable(st
+ }
+ #endif
+
++struct foe_entry *hnat_get_foe_entry(u32 ppe_id, u32 index);
++
+ void hnat_deinit_debugfs(struct mtk_hnat *h);
+ int hnat_init_debugfs(struct mtk_hnat *h);
+ int hnat_register_nf_hooks(void);
+@@ -1224,6 +1228,9 @@ extern int qos_ul_toggle;
+ extern int hook_toggle;
+ extern int mape_toggle;
+ extern int qos_toggle;
++extern int (*mtk_tnl_encap_offload)(struct sk_buff *skb);
++extern int (*mtk_tnl_decap_offload)(struct sk_buff *skb);
++extern bool (*mtk_tnl_decap_offloadable)(struct sk_buff *skb);
+
+ int ext_if_add(struct extdev_entry *ext_entry);
+ int ext_if_del(struct extdev_entry *ext_entry);
+--- a/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
++++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
+@@ -726,10 +726,14 @@ static unsigned int is_ppe_support_type(
+ case ETH_P_IP:
+ iph = ip_hdr(skb);
+
+- /* do not accelerate non tcp/udp traffic */
+- if ((iph->protocol == IPPROTO_TCP) ||
++ if (mtk_tnl_decap_offloadable && mtk_tnl_decap_offloadable(skb)) {
++ /* tunnel protocol is offloadable */
++ skb_hnat_set_is_decap(skb, 1);
++ return 1;
++ } else if ((iph->protocol == IPPROTO_TCP) ||
+ (iph->protocol == IPPROTO_UDP) ||
+ (iph->protocol == IPPROTO_IPV6)) {
++ /* do not accelerate non tcp/udp traffic */
+ return 1;
+ }
+
+@@ -846,6 +850,13 @@ mtk_hnat_ipv4_nf_pre_routing(void *priv,
+
+ hnat_set_head_frags(state, skb, -1, hnat_set_iif);
+
++ if (skb_hnat_tops(skb) && skb_hnat_is_decap(skb)
++ && is_magic_tag_valid(skb)
++ && skb_hnat_iface(skb) == FOE_MAGIC_GE_VIRTUAL
++ && mtk_tnl_decap_offload && mtk_tnl_decap_offload(skb)) {
++ return NF_ACCEPT;
++ }
++
+ /*
+ * Avoid mistakenly binding of outer IP, ports in SW L2TP decap flow.
+ * In pre-routing, if dev is virtual iface, TOPS module is not loaded,
+@@ -922,6 +933,13 @@ mtk_hnat_br_nf_local_in(void *priv, stru
+
+ hnat_set_head_frags(state, skb, -1, hnat_set_iif);
+
++ if (skb_hnat_tops(skb) && skb_hnat_is_decap(skb)
++ && is_magic_tag_valid(skb)
++ && skb_hnat_iface(skb) == FOE_MAGIC_GE_VIRTUAL
++ && mtk_tnl_decap_offload && mtk_tnl_decap_offload(skb)) {
++ return NF_ACCEPT;
++ }
++
+ pre_routing_print(skb, state->in, state->out, __func__);
+
+ if (unlikely(debug_level >= 7)) {
+@@ -1074,9 +1092,22 @@ static unsigned int hnat_ipv4_get_nextho
+ return -1;
+ }
+
++ /*
++ * if this packet is a tunnel packet and is about to construct
++ * outer header, we must update its outer mac header pointer
++ * before filling outer mac or it may screw up inner mac
++ */
++ if (skb_hnat_tops(skb) && skb_hnat_is_encap(skb)) {
++ skb_push(skb, sizeof(struct ethhdr));
++ skb_reset_mac_header(skb);
++ }
++
+ memcpy(eth_hdr(skb)->h_dest, neigh->ha, ETH_ALEN);
+ memcpy(eth_hdr(skb)->h_source, out->dev_addr, ETH_ALEN);
+
++ if (skb_hnat_tops(skb) && skb_hnat_is_encap(skb))
++ skb_pull(skb, sizeof(struct ethhdr));
++
+ rcu_read_unlock_bh();
+
+ return 0;
+@@ -1202,6 +1233,37 @@ static struct ethhdr *get_ipv6_ipip_ethh
+ return eth;
+ }
+
++static inline void hnat_get_filled_unbind_entry(struct sk_buff *skb,
++ struct foe_entry *entry)
++{
++ if (unlikely(!skb || !entry))
++ return;
++
++ memcpy(entry,
++ &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)],
++ sizeof(*entry));
++}
++
++static inline void hnat_fill_offload_engine_entry(struct sk_buff *skb,
++ struct foe_entry *entry)
++{
++#if defined(CONFIG_MEDIATEK_NETSYS_V3)
++ if (skb_hnat_tops(skb) && skb_hnat_is_encap(skb)) {
++ /*
++ * if skb_hnat_tops(skb) is setup for encapsulation,
++ * we fill in hnat tport and tops_entry for tunnel encapsulation
++ * offloading
++ */
++ entry->ipv4_hnapt.tport_id = NR_TDMA_QDMA_TPORT;
++ entry->ipv4_hnapt.tops_entry = skb_hnat_tops(skb);
++ } else {
++ return;
++ }
++
++ entry->ipv4_hnapt.iblk2.qid = 12; /* offload engine use QID 12 */
++#endif /* defined(CONFIG_MEDIATEK_NETSYS_V3) */
++}
++
+ static unsigned int skb_to_hnat_info(struct sk_buff *skb,
+ const struct net_device *dev,
+ struct foe_entry *foe,
+@@ -1237,6 +1299,11 @@ static unsigned int skb_to_hnat_info(str
+ if (whnat && is_hnat_pre_filled(foe))
+ return 0;
+
++ if (skb_hnat_tops(skb) && !(hw_path->flags & FLOW_OFFLOAD_PATH_TNL)) {
++ hnat_get_filled_unbind_entry(skb, &entry);
++ goto hnat_entry_bind;
++ }
++
+ entry.bfib1.pkt_type = foe->udib1.pkt_type; /* Get packte type state*/
+ entry.bfib1.state = foe->udib1.state;
+
+@@ -1247,6 +1314,7 @@ static unsigned int skb_to_hnat_info(str
+ switch (ntohs(eth->h_proto)) {
+ case ETH_P_IP:
+ iph = ip_hdr(skb);
++
+ switch (iph->protocol) {
+ case IPPROTO_UDP:
+ udp = 1;
+@@ -1628,6 +1696,10 @@ static unsigned int skb_to_hnat_info(str
+ /* Fill Layer2 Info.*/
+ entry = ppe_fill_L2_info(eth, entry, hw_path);
+
++ if (skb_hnat_tops(skb) && hw_path->flags & FLOW_OFFLOAD_PATH_TNL)
++ goto hnat_entry_skip_bind;
++
++hnat_entry_bind:
+ /* Fill Info Blk*/
+ entry = ppe_fill_info_blk(eth, entry, hw_path);
+
+@@ -1806,7 +1878,20 @@ static unsigned int skb_to_hnat_info(str
+ entry.ipv6_5t_route.act_dp |= UDF_HNAT_PRE_FILLED;
+ }
+
++#if defined(CONFIG_MEDIATEK_NETSYS_V3)
++ hnat_fill_offload_engine_entry(skb, &entry);
++#endif
++
++hnat_entry_skip_bind:
+ wmb();
++
++ /*
++ * final check before we write BIND info.
++ * If this entry is already bound, we should not modify it right now
++ */
++ if (entry_hnat_is_bound(foe))
++ return 0;
++
+ memcpy(foe, &entry, sizeof(entry));
+ /*reset statistic for this entry*/
+ if (hnat_priv->data->per_flow_accounting &&
+@@ -1859,6 +1944,7 @@ int mtk_sw_nat_hook_tx(struct sk_buff *s
+ return NF_ACCEPT;
+
+ eth = eth_hdr(skb);
++
+ memcpy(&bfib1_tx, &entry->bfib1, sizeof(entry->bfib1));
+
+ /*not bind multicast if PPE mcast not enable*/
+@@ -1878,6 +1964,12 @@ int mtk_sw_nat_hook_tx(struct sk_buff *s
+ switch ((int)bfib1_tx.pkt_type) {
+ case IPV4_HNAPT:
+ case IPV4_HNAT:
++ /*
++ * skip if packet is an encap tnl packet or it may
++ * screw up inner mac header
++ */
++ if (skb_hnat_tops(skb) && skb_hnat_is_encap(skb))
++ break;
+ entry->ipv4_hnapt.smac_hi = swab32(*((u32 *)eth->h_source));
+ entry->ipv4_hnapt.smac_lo = swab16(*((u16 *)ð->h_source[4]));
+ break;
+@@ -2037,6 +2129,10 @@ int mtk_sw_nat_hook_tx(struct sk_buff *s
+ entry->ipv6_5t_route.iblk2.dp = gmac_no;
+ }
+
++#if defined(CONFIG_MEDIATEK_NETSYS_V3)
++ hnat_fill_offload_engine_entry(skb, entry);
++#endif
++
+ bfib1_tx.ttl = 1;
+ bfib1_tx.state = BIND;
+ wmb();
+@@ -2058,6 +2154,7 @@ int mtk_sw_nat_hook_rx(struct sk_buff *s
+ }
+
+ skb_hnat_alg(skb) = 0;
++ skb_hnat_set_tops(skb, 0);
+ skb_hnat_magic_tag(skb) = HNAT_MAGIC_TAG;
+
+ if (skb_hnat_iface(skb) == FOE_MAGIC_WED0)
+@@ -2504,6 +2601,7 @@ static unsigned int mtk_hnat_nf_post_rou
+ struct flow_offload_hw_path hw_path = { .dev = (struct net_device*)out,
+ .virt_dev = (struct net_device*)out };
+ const struct net_device *arp_dev = out;
++ bool is_virt_dev = false;
+
+ if (xlat_toggle && !mtk_464xlat_post_process(skb, out))
+ return 0;
+@@ -2524,10 +2622,18 @@ static unsigned int mtk_hnat_nf_post_rou
+
+ if (out->netdev_ops->ndo_flow_offload_check) {
+ out->netdev_ops->ndo_flow_offload_check(&hw_path);
++
+ out = (IS_GMAC1_MODE) ? hw_path.virt_dev : hw_path.dev;
++ if (hw_path.flags & FLOW_OFFLOAD_PATH_TNL && mtk_tnl_encap_offload)
++ skb_hnat_set_tops(skb, hw_path.tnl_type + 1);
+ }
+
+ if (!IS_LAN_GRP(out) && !IS_WAN(out) && !IS_EXT(out))
++ is_virt_dev = true;
++
++ if (is_virt_dev
++ && !(skb_hnat_tops(skb) && skb_hnat_is_encap(skb)
++ && (hw_path.flags & FLOW_OFFLOAD_PATH_TNL)))
+ return 0;
+
+ trace_printk("[%s] case hit, %x-->%s, reason=%x\n", __func__,
+@@ -2547,9 +2653,18 @@ static unsigned int mtk_hnat_nf_post_rou
+ if (fn && !mtk_hnat_accel_type(skb))
+ break;
+
+- if (fn && fn(skb, arp_dev, &hw_path))
++ if (!is_virt_dev && fn && fn(skb, arp_dev, &hw_path))
+ break;
+
++ /* skb_hnat_tops(skb) is updated in mtk_tnl_offload() */
++ if (skb_hnat_tops(skb)) {
++ if (skb_hnat_is_encap(skb) && !is_virt_dev
++ && mtk_tnl_encap_offload && mtk_tnl_encap_offload(skb))
++ break;
++ if (skb_hnat_is_decap(skb))
++ break;
++ }
++
+ skb_to_hnat_info(skb, out, entry, &hw_path);
+ break;
+ case HIT_BIND_KEEPALIVE_DUP_OLD_HDR:
+@@ -2820,7 +2935,7 @@ mtk_hnat_ipv4_nf_local_out(void *priv, s
+ if (iph->protocol == IPPROTO_IPV6) {
+ entry->udib1.pkt_type = IPV6_6RD;
+ hnat_set_head_frags(state, skb, 0, hnat_set_alg);
+- } else {
++ } else if (!skb_hnat_tops(skb)) {
+ hnat_set_head_frags(state, skb, 1, hnat_set_alg);
+ }
+
+--- a/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h
++++ b/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h
+@@ -44,7 +44,9 @@ struct hnat_desc {
+ u32 is_sp : 1;
+ u32 hf : 1;
+ u32 amsdu : 1;
+- u32 resv3 : 19;
++ u32 tops : 6;
++ u32 is_decap : 1;
++ u32 resv3 : 12;
+ u32 magic_tag_protect : 16;
+ } __packed;
+ #elif defined(CONFIG_MEDIATEK_NETSYS_RX_V2)
+@@ -91,6 +93,19 @@ struct hnat_desc {
+ ((((skb_headroom(skb) >= FOE_INFO_LEN) ? 1 : 0)))
+
+ #define skb_hnat_info(skb) ((struct hnat_desc *)(skb->head))
++#if defined(CONFIG_MEDIATEK_NETSYS_V3)
++#define skb_hnat_tops(skb) (((struct hnat_desc *)((skb)->head))->tops)
++#define skb_hnat_is_decap(skb) (((struct hnat_desc *)((skb)->head))->is_decap)
++#define skb_hnat_is_encap(skb) (!skb_hnat_is_decap(skb))
++#define skb_hnat_set_tops(skb, tops) ((skb_hnat_tops(skb)) = (tops))
++#define skb_hnat_set_is_decap(skb, is_decap) ((skb_hnat_is_decap(skb)) = (is_decap))
++#else /* !defined(CONFIG_MEDIATEK_NETSYS_V3) */
++#define skb_hnat_tops(skb) (0)
++#define skb_hnat_is_decap(skb) (0)
++#define skb_hnat_is_encap(skb) (0)
++#define skb_hnat_set_tops(skb, tops)
++#define skb_hnat_set_is_decap(skb, is_decap)
++#endif /* defined(CONFIG_MEDIATEK_NETSYS_V3) */
+ #define skb_hnat_magic(skb) (((struct hnat_desc *)(skb->head))->magic)
+ #define skb_hnat_reason(skb) (((struct hnat_desc *)(skb->head))->crsn)
+ #define skb_hnat_entry(skb) (((struct hnat_desc *)(skb->head))->entry)
+--- a/include/net/netfilter/nf_flow_table.h
++++ b/include/net/netfilter/nf_flow_table.h
+@@ -98,10 +98,22 @@ struct flow_offload {
+ #define FLOW_OFFLOAD_PATH_6RD BIT(5)
+ #define FLOW_OFFLOAD_PATH_TNL BIT(6)
+
++enum flow_offload_tnl {
++ FLOW_OFFLOAD_TNL_GRETAP,
++ FLOW_OFFLOAD_TNL_PPTP,
++ FLOW_OFFLOAD_TNL_IP_L2TP,
++ FLOW_OFFLOAD_TNL_UDP_L2TP_CTRL,
++ FLOW_OFFLOAD_TNL_UDP_L2TP_DATA,
++ FLOW_OFFLOAD_VXLAN,
++ FLOW_OFFLOAD_NATT,
++ __FLOW_OFFLOAD_MAX,
++};
++
+ struct flow_offload_hw_path {
+ struct net_device *dev;
+ struct net_device *virt_dev;
+ u32 flags;
++ u32 tnl_type;
+
+ u8 eth_src[ETH_ALEN];
+ u8 eth_dest[ETH_ALEN];
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -1868,6 +1868,9 @@ extern const struct of_device_id of_mtk_
+ extern u32 mtk_hwlro_stats_ebl;
+ extern u32 dbg_show_level;
+
++/* tunnel offload related */
++extern struct net_device *(*mtk_get_tnl_dev)(int tnl_idx);
++
+ /* read the hardware status register */
+ void mtk_stats_update_mac(struct mtk_mac *mac);
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4101-mtk-tops-network-service-error-recover-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4101-mtk-tops-network-service-error-recover-support.patch
new file mode 100644
index 0000000..fbb46ac
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4101-mtk-tops-network-service-error-recover-support.patch
@@ -0,0 +1,49 @@
+--- a/drivers/net/ethernet/mediatek/mtk_eth_reset.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_reset.c
+@@ -635,6 +635,9 @@ static int mtk_eth_netdevice_event(struc
+ unsigned long event, void *ptr)
+ {
+ switch (event) {
++ case MTK_TOPS_DUMP_DONE:
++ complete(&wait_tops_done);
++ break;
+ case MTK_WIFI_RESET_DONE:
+ case MTK_FE_STOP_TRAFFIC_DONE:
+ pr_info("%s rcv done event:%lx\n", __func__, event);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_reset.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_reset.h
+@@ -13,6 +13,7 @@
+ #define MTK_WIFI_RESET_DONE 0x2002
+ #define MTK_WIFI_CHIP_ONLINE 0x2003
+ #define MTK_WIFI_CHIP_OFFLINE 0x2004
++#define MTK_TOPS_DUMP_DONE 0x3001
+ #define MTK_FE_RESET_NAT_DONE 0x4001
+
+ #define MTK_FE_STOP_TRAFFIC (0x2005)
+@@ -67,6 +68,7 @@ enum mtk_reset_event_id {
+
+ extern struct notifier_block mtk_eth_netdevice_nb __read_mostly;
+ extern struct completion wait_ser_done;
++extern struct completion wait_tops_done;
+ extern char* mtk_reset_event_name[32];
+ extern atomic_t reset_lock;
+ extern struct completion wait_nat_done;
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -38,6 +38,7 @@ atomic_t force = ATOMIC_INIT(0);
+ module_param_named(msg_level, mtk_msg_level, int, 0);
+ MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)");
+ DECLARE_COMPLETION(wait_ser_done);
++DECLARE_COMPLETION(wait_tops_done);
+
+ #define MTK_ETHTOOL_STAT(x) { #x, \
+ offsetof(struct mtk_hw_stats, x) / sizeof(u64) }
+@@ -4057,6 +4058,8 @@ static void mtk_pending_work(struct work
+ }
+ pr_warn("wait for MTK_FE_START_RESET\n");
+ }
++ if (!try_wait_for_completion(&wait_tops_done))
++ pr_warn("wait for MTK_TOPS_DUMP_DONE\n");
+ rtnl_lock();
+ break;
+ }
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4500-mtk-tops-gre-offload-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4500-mtk-tops-gre-offload-support.patch
new file mode 100644
index 0000000..3833fa0
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4500-mtk-tops-gre-offload-support.patch
@@ -0,0 +1,45 @@
+--- a/net/ipv4/ip_gre.c
++++ b/net/ipv4/ip_gre.c
+@@ -39,6 +39,7 @@
+ #include <net/inet_ecn.h>
+ #include <net/xfrm.h>
+ #include <net/net_namespace.h>
++#include <net/netfilter/nf_flow_table.h>
+ #include <net/netns/generic.h>
+ #include <net/rtnetlink.h>
+ #include <net/gre.h>
+@@ -901,6 +902,24 @@ static int ipgre_close(struct net_device
+ }
+ #endif
+
++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
++static int gre_dev_flow_offload_check(struct flow_offload_hw_path *path)
++{
++ struct net_device *dev = path->dev;
++ struct ip_tunnel *tunnel = netdev_priv(dev);
++
++ if (path->flags & FLOW_OFFLOAD_PATH_TNL)
++ return -EEXIST;
++
++ path->flags |= FLOW_OFFLOAD_PATH_TNL;
++ path->tnl_type = FLOW_OFFLOAD_TNL_GRETAP;
++ path->virt_dev = dev;
++ path->dev = tunnel->dev;
++
++ return 0;
++}
++#endif /* CONFIG_NF_FLOW_TABLE */
++
+ static const struct net_device_ops ipgre_netdev_ops = {
+ .ndo_init = ipgre_tunnel_init,
+ .ndo_uninit = ip_tunnel_uninit,
+@@ -1264,6 +1283,9 @@ static const struct net_device_ops gre_t
+ .ndo_get_stats64 = ip_tunnel_get_stats64,
+ .ndo_get_iflink = ip_tunnel_get_iflink,
+ .ndo_fill_metadata_dst = gre_fill_metadata_dst,
++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
++ .ndo_flow_offload_check = gre_dev_flow_offload_check,
++#endif
+ };
+
+ static int erspan_tunnel_init(struct net_device *dev)
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4500-mtk-tops-l2tp-offload-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4500-mtk-tops-l2tp-offload-support.patch
new file mode 100644
index 0000000..e6583b6
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-4500-mtk-tops-l2tp-offload-support.patch
@@ -0,0 +1,35 @@
+--- a/net/l2tp/l2tp_core.c
++++ b/net/l2tp/l2tp_core.c
+@@ -1068,6 +1068,10 @@ int l2tp_xmit_skb(struct l2tp_session *s
+ int udp_len;
+ int ret = NET_XMIT_SUCCESS;
+
++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
++ skb_reset_inner_headers(skb);
++#endif
++
+ /* Check that there's enough headroom in the skb to insert IP,
+ * UDP and L2TP headers. If not enough, expand it to
+ * make room. Adjust truesize.
+--- a/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
++++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
+@@ -855,7 +855,8 @@ mtk_hnat_ipv4_nf_pre_routing(void *priv,
+ * and it's L2TP flow, then do not bind.
+ */
+ if (skb_hnat_iface(skb) == FOE_MAGIC_GE_VIRTUAL
+- && skb->dev->netdev_ops->ndo_flow_offload_check) {
++ && skb->dev->netdev_ops->ndo_flow_offload_check
++ && !mtk_tnl_decap_offload) {
+ skb->dev->netdev_ops->ndo_flow_offload_check(&hw_path);
+
+ if (hw_path.flags & FLOW_OFFLOAD_PATH_TNL)
+--- a/net/l2tp/l2tp_ppp.c
++++ b/net/l2tp/l2tp_ppp.c
+@@ -356,6 +356,7 @@ static int l2tp_ppp_flow_offload_check(s
+ return -EINVAL;
+
+ path->flags |= FLOW_OFFLOAD_PATH_TNL;
++ path->tnl_type = FLOW_OFFLOAD_TNL_UDP_L2TP_DATA;
+
+ return 0;
+ }
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2333-mtd-spinand-gigadevice-Add-support-for-F50L1G41LB-and-GD5F1GQ5UExxG.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2333-mtd-spinand-gigadevice-Add-support-for-F50L1G41LB-and-GD5F1GQ5UExxG.patch
deleted file mode 100644
index d37dd56..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2333-mtd-spinand-gigadevice-Add-support-for-F50L1G41LB-and-GD5F1GQ5UExxG.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 39ee4e9fb5fd3ce678223147df9d9bef0ce822cd Mon Sep 17 00:00:00 2001
-From: Sam Shih <sam.shih@mediatek.com>
-Date: Fri, 2 Jun 2023 13:06:15 +0800
-Subject: [PATCH]
- [spi-and-storage][999-2333-mtd-spinand-gigadevice-Add-support-for-F50L1G41LB-and-GD5F1GQ5UExxG.patch]
-
----
- drivers/mtd/nand/spi/gigadevice.c | 21 ++++++++++++++++++++-
- 1 file changed, 20 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
-index 937a04ce6..ce88f0c91 100644
---- a/drivers/mtd/nand/spi/gigadevice.c
-+++ b/drivers/mtd/nand/spi/gigadevice.c
-@@ -39,6 +39,15 @@ static SPINAND_OP_VARIANTS(read_cache_variants_f,
- SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0),
- SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0));
-
-+/* Q5 devices, QUADIO: Dummy bytes only valid for 1 GBit variants */
-+static SPINAND_OP_VARIANTS(gd5f1gq5_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),
-+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
-+
- static SPINAND_OP_VARIANTS(write_cache_variants,
- SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
- SPINAND_PROG_LOAD(true, 0, NULL, 0));
-@@ -236,6 +245,16 @@ static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
- }
-
- static const struct spinand_info gigadevice_spinand_table[] = {
-+ SPINAND_INFO("F50L1G41LB",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x01),
-+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&gd5f1gq5_read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ 0,
-+ SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
-+ gd5fxgq4xa_ecc_get_status)),
- SPINAND_INFO("GD5F1GQ4xA",
- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
- NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
-@@ -290,7 +309,7 @@ static const struct spinand_info gigadevice_spinand_table[] = {
- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51),
- NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
- NAND_ECCREQ(4, 512),
-- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ SPINAND_INFO_OP_VARIANTS(&gd5f1gq5_read_cache_variants,
- &write_cache_variants,
- &update_cache_variants),
- SPINAND_HAS_QE_BIT,
---
-2.34.1
-
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2334-mtd-spinand-gigadevice-Add-support-for-GD5FxGQxUExxG-GD5FxGQxUExxH-and-GD5FxGMxUExxG-series.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2334-mtd-spinand-gigadevice-Add-support-for-GD5FxGQxUExxG-GD5FxGQxUExxH-and-GD5FxGMxUExxG-series.patch
deleted file mode 100644
index c609bd7..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2334-mtd-spinand-gigadevice-Add-support-for-GD5FxGQxUExxG-GD5FxGQxUExxH-and-GD5FxGMxUExxG-series.patch
+++ /dev/null
@@ -1,143 +0,0 @@
-From b8ffe42101eb8abfb6530396e0c74a85b43eed44 Mon Sep 17 00:00:00 2001
-From: Sam Shih <sam.shih@mediatek.com>
-Date: Fri, 2 Jun 2023 13:06:15 +0800
-Subject: [PATCH]
- [spi-and-storage][999-2334-mtd-spinand-gigadevice-Add-support-for-GD5FxGQxUExxG-GD5FxGQxUExxH-and-GD5FxGMxUExxG-series.patch]
-
----
- drivers/mtd/nand/spi/gigadevice.c | 98 +++++++++++++++++++++++++++++--
- 1 file changed, 94 insertions(+), 4 deletions(-)
-
-diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
-index ce88f0c91..a4e89529d 100644
---- a/drivers/mtd/nand/spi/gigadevice.c
-+++ b/drivers/mtd/nand/spi/gigadevice.c
-@@ -39,8 +39,9 @@ static SPINAND_OP_VARIANTS(read_cache_variants_f,
- SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0),
- SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0));
-
--/* Q5 devices, QUADIO: Dummy bytes only valid for 1 GBit variants */
--static SPINAND_OP_VARIANTS(gd5f1gq5_read_cache_variants,
-+/* For Q5 devices, QUADIO use different dummy byte settings */
-+/* Q5 1Gb */
-+static SPINAND_OP_VARIANTS(dummy2_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),
- SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
-@@ -48,6 +49,15 @@ static SPINAND_OP_VARIANTS(gd5f1gq5_read_cache_variants,
- SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
- SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
-
-+/* Q5 2Gb & 4Gb */
-+static SPINAND_OP_VARIANTS(dummy4_read_cache_variants,
-+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 4, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 2, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
-+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
-+
- static SPINAND_OP_VARIANTS(write_cache_variants,
- SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
- SPINAND_PROG_LOAD(true, 0, NULL, 0));
-@@ -249,7 +259,7 @@ static const struct spinand_info gigadevice_spinand_table[] = {
- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x01),
- NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
- NAND_ECCREQ(8, 512),
-- SPINAND_INFO_OP_VARIANTS(&gd5f1gq5_read_cache_variants,
-+ SPINAND_INFO_OP_VARIANTS(&dummy2_read_cache_variants,
- &write_cache_variants,
- &update_cache_variants),
- 0,
-@@ -309,7 +319,87 @@ static const struct spinand_info gigadevice_spinand_table[] = {
- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51),
- NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
- NAND_ECCREQ(4, 512),
-- SPINAND_INFO_OP_VARIANTS(&gd5f1gq5_read_cache_variants,
-+ SPINAND_INFO_OP_VARIANTS(&dummy2_read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq5xexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F2GQ5UExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x52),
-+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
-+ NAND_ECCREQ(4, 512),
-+ SPINAND_INFO_OP_VARIANTS(&dummy4_read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq5xexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F4GQ6UExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x55),
-+ NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
-+ NAND_ECCREQ(4, 512),
-+ SPINAND_INFO_OP_VARIANTS(&dummy4_read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq5xexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F1GM7UExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x91),
-+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq4uexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F2GM7UExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x92),
-+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq4uexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F4GM8UExxG",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x95),
-+ NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq4uexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F1GQ5UExxH",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x31),
-+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
-+ NAND_ECCREQ(4, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq5xexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F2GQ5UExxH",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x32),
-+ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
-+ NAND_ECCREQ(4, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
-+ gd5fxgq5xexxg_ecc_get_status)),
-+ SPINAND_INFO("GD5F4GQ6UExxH",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x32),
-+ NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1),
-+ NAND_ECCREQ(4, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
- &write_cache_variants,
- &update_cache_variants),
- SPINAND_HAS_QE_BIT,
---
-2.34.1
-
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2335-mtd-spinand-fix-gigadevice-read-dummy.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2335-mtd-spinand-fix-gigadevice-read-dummy.patch
deleted file mode 100644
index 977c65c..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2335-mtd-spinand-fix-gigadevice-read-dummy.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From be41be0e740933fa976ad2990b94ef1e62542a8e Mon Sep 17 00:00:00 2001
-From: Sam Shih <sam.shih@mediatek.com>
-Date: Fri, 2 Jun 2023 13:06:15 +0800
-Subject: [PATCH]
- [spi-and-storage][999-2335-mtd-spinand-fix-gigadevice-read-dummy.patch]
-
----
- drivers/mtd/nand/spi/gigadevice.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
-index a4e89529d..b163ea5dc 100644
---- a/drivers/mtd/nand/spi/gigadevice.c
-+++ b/drivers/mtd/nand/spi/gigadevice.c
-@@ -379,7 +379,7 @@ static const struct spinand_info gigadevice_spinand_table[] = {
- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x31),
- NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
- NAND_ECCREQ(4, 512),
-- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ SPINAND_INFO_OP_VARIANTS(&dummy2_read_cache_variants,
- &write_cache_variants,
- &update_cache_variants),
- SPINAND_HAS_QE_BIT,
-@@ -389,17 +389,17 @@ static const struct spinand_info gigadevice_spinand_table[] = {
- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x32),
- NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
- NAND_ECCREQ(4, 512),
-- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ SPINAND_INFO_OP_VARIANTS(&dummy4_read_cache_variants,
- &write_cache_variants,
- &update_cache_variants),
- SPINAND_HAS_QE_BIT,
- SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
- gd5fxgq5xexxg_ecc_get_status)),
- SPINAND_INFO("GD5F4GQ6UExxH",
-- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x32),
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
- NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1),
- NAND_ECCREQ(4, 512),
-- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ SPINAND_INFO_OP_VARIANTS(&dummy4_read_cache_variants,
- &write_cache_variants,
- &update_cache_variants),
- SPINAND_HAS_QE_BIT,
---
-2.34.1
-
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2336-mtd-spinand-fix-F50L1G41LB-ecc-check.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2336-mtd-spinand-fix-F50L1G41LB-ecc-check.patch
deleted file mode 100644
index 644c6b3..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2336-mtd-spinand-fix-F50L1G41LB-ecc-check.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From c93adec4ad0e8ca47f1a622fb3a5ae445251af36 Mon Sep 17 00:00:00 2001
-From: Sam Shih <sam.shih@mediatek.com>
-Date: Fri, 2 Jun 2023 13:06:16 +0800
-Subject: [PATCH]
- [spi-and-storage][999-2336-mtd-spinand-fix-F50L1G41LB-ecc-check.patch]
-
----
- drivers/mtd/nand/spi/gigadevice.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
-index b163ea5dc..6ee569de2 100644
---- a/drivers/mtd/nand/spi/gigadevice.c
-+++ b/drivers/mtd/nand/spi/gigadevice.c
-@@ -263,8 +263,7 @@ static const struct spinand_info gigadevice_spinand_table[] = {
- &write_cache_variants,
- &update_cache_variants),
- 0,
-- SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
-- gd5fxgq4xa_ecc_get_status)),
-+ SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, NULL)),
- SPINAND_INFO("GD5F1GQ4xA",
- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
- NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
---
-2.34.1
-
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2343-mtd-spinand-gigadevice-Add-support-for-F50L1G41LB.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2343-mtd-spinand-gigadevice-Add-support-for-F50L1G41LB.patch
new file mode 100644
index 0000000..acf4775
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2343-mtd-spinand-gigadevice-Add-support-for-F50L1G41LB.patch
@@ -0,0 +1,20 @@
+Index: linux-5.4.246/drivers/mtd/nand/spi/gigadevice.c
+===================================================================
+--- linux-5.4.246.orig/drivers/mtd/nand/spi/gigadevice.c
++++ linux-5.4.246/drivers/mtd/nand/spi/gigadevice.c
+@@ -281,6 +281,15 @@ static int gd5fxgq4ufxxg_ecc_get_status(
+ }
+
+ static const struct spinand_info gigadevice_spinand_table[] = {
++ SPINAND_INFO("F50L1G41LB",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x01),
++ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
++ NAND_ECCREQ(8, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
++ &write_cache_variants,
++ &update_cache_variants),
++ 0,
++ SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, NULL)),
+ SPINAND_INFO("GD5F1GQ4xA",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/patches-5.4.inc b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/patches-5.4.inc
index 1fe0212..8f19163 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/patches-5.4.inc
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/patches-5.4.inc
@@ -82,16 +82,13 @@
file://999-2330-mtd-spinand-winbond-Support-for-W25MxxGV-W25NxxKV-series.patch \
file://999-2331-mtd-spinand-macronix-suppress-mx35lf1ge4ab-warning-log.patch \
file://999-2332-mtd-add-mtk-snand-driver.patch \
- file://999-2333-mtd-spinand-gigadevice-Add-support-for-F50L1G41LB-and-GD5F1GQ5UExxG.patch \
- file://999-2334-mtd-spinand-gigadevice-Add-support-for-GD5FxGQxUExxG-GD5FxGQxUExxH-and-GD5FxGMxUExxG-series.patch \
- file://999-2335-mtd-spinand-fix-gigadevice-read-dummy.patch \
- file://999-2336-mtd-spinand-fix-F50L1G41LB-ecc-check.patch \
file://999-2337-mtd-spinor-support-EN25QX128A.patch \
file://999-2338-mtd-tests-fix-pagetest-load.patch \
file://999-2339-drivers-mtd-spinand-Add-calibration-support-for-spinand.patch \
file://999-2340-drivers-mtd-spi-nor-Add-calibration-support-for-spi-nor.patch \
file://999-2341-mtd-spinand-Add-support-etron.patch \
file://999-2342-drivers-mtd-spi-nor-Add-support-EN25QX256A-2S.patch \
+ file://999-2343-mtd-spinand-gigadevice-Add-support-for-F50L1G41LB.patch \
file://999-2350-nvmem-core-Add-functions-to-make-number-reading-easy.patch \
file://999-2351-nvmem-mtk-efuse-support-minimum-one-byte-access-stri.patch \
file://999-2361-add-spimem-support-to-mtk-spi.patch \
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/wed3/999-3023-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-for-bo.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/wed3/999-3023-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-for-bo.patch
new file mode 100644
index 0000000..e27c903
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/wed3/999-3023-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-for-bo.patch
@@ -0,0 +1,106 @@
+From 57294c4562d1f93ee2deaef67a2ad15fb925c288 Mon Sep 17 00:00:00 2001
+From: "sujuan.chen" <sujuan.chen@mediatek.com>
+Date: Wed, 19 Jul 2023 17:22:59 +0800
+Subject: [PATCH] mtk: wed: add dma mask limitation and GFP_DMA32 for board w/
+ >= 4GB dram
+
+Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
+---
+ drivers/net/ethernet/mediatek/mtk_wed.c | 8 ++++++--
+ drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 4 ++--
+ drivers/net/ethernet/mediatek/mtk_wed_wo.c | 4 ++--
+ drivers/net/ethernet/mediatek/mtk_wed_wo.h | 1 +
+ 4 files changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
+index 45dfa0c..d4d8658 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed.c
+@@ -472,7 +472,7 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev)
+ void *buf;
+ int s;
+
+- page = __dev_alloc_pages(GFP_KERNEL, 0);
++ page = __dev_alloc_pages(GFP_KERNEL | GFP_DMA32, 0);
+ if (!page)
+ return -ENOMEM;
+
+@@ -636,7 +636,7 @@ mtk_wed_rx_page_buffer_alloc(struct mtk_wed_device *dev)
+ void *buf;
+ int s;
+
+- page = __dev_alloc_pages(GFP_KERNEL, 0);
++ page = __dev_alloc_pages(GFP_KERNEL | GFP_DMA32, 0);
+ if (!page)
+ return -ENOMEM;
+
+@@ -2239,6 +2239,10 @@ mtk_wed_attach(struct mtk_wed_device *dev)
+ dev->wdma_idx = hw->index;
+ dev->ver = hw->version;
+
++ ret = dma_set_mask_and_coherent(hw->dev, DMA_BIT_MASK(32));
++ if (ret)
++ return ret;
++
+ if (dev->hw->version == 3)
+ dev->hw->pci_base = mtk_wed_get_pci_base(dev);
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
+index 055594d..4ed1548 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
+@@ -131,7 +131,7 @@ int mtk_wed_exception_init(struct mtk_wed_wo *wo)
+ }req;
+
+ exp->log_size = EXCEPTION_LOG_SIZE;
+- exp->log = kmalloc(exp->log_size, GFP_ATOMIC);
++ exp->log = page_frag_alloc(&wo->page, exp->log_size, GFP_ATOMIC | GFP_DMA32);
+ if (!exp->log)
+ return -ENOMEM;
+
+@@ -151,7 +151,7 @@ int mtk_wed_exception_init(struct mtk_wed_wo *wo)
+ &req, sizeof(req), false);
+
+ free:
+- kfree(exp->log);
++ skb_free_frag(exp->log);
+ return -ENOMEM;
+ }
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed_wo.c b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
+index 54b7787..e991d20 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
+@@ -88,7 +88,7 @@ woif_q_rx_fill(struct mtk_wed_wo *wo, struct wed_wo_queue *q, bool rx)
+ page = &q->rx_page;
+
+ while (q->queued < q->ndesc) {
+- buf = page_frag_alloc(page, len, GFP_ATOMIC);
++ buf = page_frag_alloc(page, len, GFP_ATOMIC | GFP_DMA32);
+ if (!buf)
+ break;
+
+@@ -555,7 +555,7 @@ void mtk_wed_wo_exit(struct mtk_wed_hw *hw)
+
+ if (wo->exp.log) {
+ dma_unmap_single(wo->hw->dev, wo->exp.phys, wo->exp.log_size, DMA_FROM_DEVICE);
+- kfree(wo->exp.log);
++ skb_free_frag(wo->exp.log);
+ }
+
+ wo->hw = NULL;
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed_wo.h b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
+index 548b38e..3fd1f3f 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
++++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
+@@ -193,6 +193,7 @@ struct mtk_wed_wo {
+ const struct wed_wo_drv_ops *drv_ops;
+ const struct wed_wo_mcu_ops *mcu_ops;
+ const struct wed_wo_queue_ops *queue_ops;
++ struct page_frag_cache page;
+
+ struct net_device napi_dev;
+ spinlock_t rx_lock;
+--
+2.18.0
+