diff --git a/target/linux/airoha/dts/an7583.dtsi b/target/linux/airoha/dts/an7583.dtsi index 57a4746c46e74d..64ab69055466e9 100644 --- a/target/linux/airoha/dts/an7583.dtsi +++ b/target/linux/airoha/dts/an7583.dtsi @@ -636,7 +636,7 @@ }; npu: npu@1e900000 { - compatible = "airoha,en7581-npu"; + compatible = "airoha,an7583-npu"; reg = <0x0 0x1e900000 0x0 0x313000>; interrupts = , , @@ -765,6 +765,7 @@ compatible = "airoha,eth-mac"; reg = <3>; pcs = <ð_pcs>; + airoha,gdm-srcport = <0x16>; status = "disabled"; }; diff --git a/target/linux/airoha/patches-6.6/400-net-airoha-add-support-for-Airoha-AN7583-SoC.patch b/target/linux/airoha/patches-6.6/400-net-airoha-add-support-for-Airoha-AN7583-SoC.patch deleted file mode 100644 index d9cf0468079aa3..00000000000000 --- a/target/linux/airoha/patches-6.6/400-net-airoha-add-support-for-Airoha-AN7583-SoC.patch +++ /dev/null @@ -1,234 +0,0 @@ -From 37b0ce896156d89a38e5a26158decafd413e1d85 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 2 May 2025 01:00:34 +0200 -Subject: [PATCH] net: airoha: add support for Airoha AN7583 SoC - -Add support for Airoha AN7583 SoC. The same feature of Airoha EN7581 are -supported with the only difference of AN7583 supporting only one PPE and -different reset number for XSI. - -To support this, move the PPE num to match data and rework the reset -name logic for XSI. - -Signed-off-by: Christian Marangi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 78 ++++++++++++++++++------ - drivers/net/ethernet/airoha/airoha_eth.h | 7 ++- - drivers/net/ethernet/airoha/airoha_ppe.c | 5 +- - 3 files changed, 70 insertions(+), 20 deletions(-) - -diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c -index d748dc6de923..788d75a37ac8 100644 ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -283,6 +283,7 @@ static int airoha_fe_set_pse_oq_rsv(struct airoha_eth *eth, - - static void airoha_fe_pse_ports_init(struct airoha_eth *eth) - { -+ const struct airoha_eth_match_data *data; - const u32 pse_port_num_queues[] = { - [FE_PSE_PORT_CDM1] = 6, - [FE_PSE_PORT_GDM1] = 6, -@@ -299,9 +300,13 @@ static void airoha_fe_pse_ports_init(struct airoha_eth *eth) - u32 all_rsv; - int q; - -+ data = of_device_get_match_data(eth->dev); -+ - all_rsv = airoha_fe_get_pse_all_rsv(eth); -- /* hw misses PPE2 oq rsv */ -- all_rsv += PSE_RSV_PAGES * pse_port_num_queues[FE_PSE_PORT_PPE2]; -+ if (data->ppe_num > 1) { -+ /* hw misses PPE2 oq rsv */ -+ all_rsv += PSE_RSV_PAGES * pse_port_num_queues[FE_PSE_PORT_PPE2]; -+ } - airoha_fe_set(eth, REG_FE_PSE_BUF_SET, all_rsv); - - /* CMD1 */ -@@ -338,13 +343,15 @@ static void airoha_fe_pse_ports_init(struct airoha_eth *eth) - for (q = 4; q < pse_port_num_queues[FE_PSE_PORT_CDM4]; q++) - airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM4, q, - PSE_QUEUE_RSV_PAGES); -- /* PPE2 */ -- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE2]; q++) { -- if (q < pse_port_num_queues[FE_PSE_PORT_PPE2] / 2) -- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, q, -- PSE_QUEUE_RSV_PAGES); -- else -- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, q, 0); -+ if (data->ppe_num > 1) { -+ /* PPE2 */ -+ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE2]; q++) { -+ if (q < pse_port_num_queues[FE_PSE_PORT_PPE2] / 2) -+ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, q, -+ PSE_QUEUE_RSV_PAGES); -+ else -+ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, q, 0); -+ } - } - /* GMD4 */ - for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM4]; q++) -@@ -1293,10 +1300,13 @@ static int airoha_qdma_init(struct platform_device *pdev, - static int airoha_hw_init(struct platform_device *pdev, - struct airoha_eth *eth) - { -+ const struct airoha_eth_match_data *data; - int err, i; - -+ data = of_device_get_match_data(eth->dev); -+ - /* disable xsi */ -- err = reset_control_bulk_assert(ARRAY_SIZE(eth->xsi_rsts), -+ err = reset_control_bulk_assert(data->num_xsi_rsts, - eth->xsi_rsts); - if (err) - return err; -@@ -1300,7 +1305,7 @@ static int airoha_qdma_init(struct platform_device *pdev, - if (err) - return err; - -- err = reset_control_bulk_deassert(ARRAY_SIZE(eth->xsi_rsts), eth->xsi_rsts); -+ err = reset_control_bulk_deassert(data->num_xsi_rsts, eth->xsi_rsts); - if (err) - return err; - -@@ -1659,8 +1669,11 @@ static int airoha_dev_init(struct net_device *dev) - { - struct airoha_gdm_port *port = netdev_priv(dev); - struct airoha_eth *eth = port->qdma->eth; -+ const struct airoha_eth_match_data *data; - u32 pse_port; - -+ data = of_device_get_match_data(eth->dev); -+ - airoha_set_macaddr(port, dev->dev_addr); - - switch (port->id) { -@@ -1671,7 +1684,10 @@ static int airoha_dev_init(struct net_device *dev) - airhoha_set_gdm2_loopback(port); - fallthrough; - case 2: -- pse_port = FE_PSE_PORT_PPE2; -+ if (data->ppe_num > 1) -+ pse_port = FE_PSE_PORT_PPE2; -+ else -+ pse_port = FE_PSE_PORT_PPE1; - break; - default: - pse_port = FE_PSE_PORT_PPE1; -@@ -2550,10 +2566,13 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth, - - static int airoha_probe(struct platform_device *pdev) - { -+ const struct airoha_eth_match_data *data; - struct device_node *np; - struct airoha_eth *eth; - int i, err; - -+ data = of_device_get_match_data(&pdev->dev); -+ - eth = devm_kzalloc(&pdev->dev, sizeof(*eth), GFP_KERNEL); - if (!eth) - return -ENOMEM; -@@ -2582,12 +2601,10 @@ static int airoha_probe(struct platform_device *pdev) - return err; - } - -- eth->xsi_rsts[0].id = "hsi0-mac"; -- eth->xsi_rsts[1].id = "hsi1-mac"; -- eth->xsi_rsts[2].id = "hsi-mac"; -- eth->xsi_rsts[3].id = "xfp-mac"; -+ for (i = 0; i < data->num_xsi_rsts; i++) -+ eth->xsi_rsts[i].id = data->xsi_rsts_names[i]; - err = devm_reset_control_bulk_get_exclusive(eth->dev, -- ARRAY_SIZE(eth->xsi_rsts), -+ data->num_xsi_rsts, - eth->xsi_rsts); - if (err) { - dev_err(eth->dev, "failed to get bulk xsi reset lines\n"); -@@ -2675,8 +2691,34 @@ static void airoha_remove(struct platform_device *pdev) - platform_set_drvdata(pdev, NULL); - } - -+static const char * const en7581_xsi_rsts_names[] = { -+ "hsi0-mac", -+ "hsi1-mac", -+ "hsi-mac", -+ "xfp-mac", -+}; -+ -+static const char * const an7583_xsi_rsts_names[] = { -+ "hsi0-mac", -+ "hsi1-mac", -+ "xfp-mac", -+}; -+ -+static const struct airoha_eth_match_data en7581_match_data = { -+ .ppe_num = 2, -+ .xsi_rsts_names = en7581_xsi_rsts_names, -+ .num_xsi_rsts = ARRAY_SIZE(en7581_xsi_rsts_names), -+}; -+ -+static const struct airoha_eth_match_data an7583_match_data = { -+ .ppe_num = 1, -+ .xsi_rsts_names = an7583_xsi_rsts_names, -+ .num_xsi_rsts = ARRAY_SIZE(an7583_xsi_rsts_names), -+}; -+ - static const struct of_device_id of_airoha_match[] = { -- { .compatible = "airoha,en7581-eth" }, -+ { .compatible = "airoha,en7581-eth", .data = &en7581_match_data }, -+ { .compatible = "airoha,an7583-eth", .data = &an7583_match_data }, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, of_airoha_match); -diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h -index ec8908f904c6..b02fe26ff48a 100644 ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -46,7 +46,6 @@ - #define QDMA_METER_IDX(_n) ((_n) & 0xff) - #define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3) - --#define PPE_NUM 2 - #define PPE1_SRAM_NUM_ENTRIES (8 * 1024) - #define PPE_SRAM_NUM_ENTRIES (2 * PPE1_SRAM_NUM_ENTRIES) - #define PPE_DRAM_NUM_ENTRIES (16 * 1024) -@@ -506,6 +505,12 @@ struct airoha_eth { - struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS]; - }; - -+struct airoha_eth_match_data { -+ unsigned int ppe_num; -+ int num_xsi_rsts; -+ const char * const *xsi_rsts_names; -+}; -+ - u32 airoha_rr(void __iomem *base, u32 offset); - void airoha_wr(void __iomem *base, u32 offset, u32 val); - u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val); -diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c -index f10dab935cab..c5a4f7785d33 100644 ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -39,13 +39,16 @@ static u32 airoha_ppe_get_timestamp(struct airoha_ppe *ppe) - static void airoha_ppe_hw_init(struct airoha_ppe *ppe) - { - u32 sram_tb_size, sram_num_entries, dram_num_entries; -+ const struct airoha_eth_match_data *data; - struct airoha_eth *eth = ppe->eth; - int i; - -+ data = of_device_get_match_data(eth->dev); -+ - sram_tb_size = PPE_SRAM_NUM_ENTRIES * sizeof(struct airoha_foe_entry); - dram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(PPE_DRAM_NUM_ENTRIES); - -- for (i = 0; i < PPE_NUM; i++) { -+ for (i = 0; i < data->ppe_num; i++) { - int p; - - airoha_fe_wr(eth, REG_PPE_TB_BASE(i), --- -2.48.1 - diff --git a/target/linux/airoha/patches-6.6/411-net-airoha-npu-Add-7583-SoC-support.patch b/target/linux/airoha/patches-6.6/411-net-airoha-npu-Add-7583-SoC-support.patch new file mode 100644 index 00000000000000..75e84ee0d90ffe --- /dev/null +++ b/target/linux/airoha/patches-6.6/411-net-airoha-npu-Add-7583-SoC-support.patch @@ -0,0 +1,72 @@ +From 6cc8cf5869e3d87d7ef37fc66e682c6c78960cd4 Mon Sep 17 00:00:00 2001 +Message-ID: <6cc8cf5869e3d87d7ef37fc66e682c6c78960cd4.1758640781.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +Date: Wed, 17 Sep 2025 09:01:09 +0200 +Subject: [PATCH net-next 01/12] net: airoha: npu: Add 7583 SoC support + +Introduce support for Airoha 7583 SoC selecting proper firmware images. + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/airoha/airoha_npu.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_npu.c ++++ b/drivers/net/ethernet/airoha/airoha_npu.c +@@ -16,6 +16,8 @@ + + #define NPU_EN7581_FIRMWARE_DATA "airoha/en7581_npu_data.bin" + #define NPU_EN7581_FIRMWARE_RV32 "airoha/en7581_npu_rv32.bin" ++#define NPU_AN7583_FIRMWARE_DATA "airoha/an7583_npu_data.bin" ++#define NPU_AN7583_FIRMWARE_RV32 "airoha/an7583_npu_rv32.bin" + #define NPU_EN7581_FIRMWARE_RV32_MAX_SIZE 0x200000 + #define NPU_EN7581_FIRMWARE_DATA_MAX_SIZE 0x10000 + #define NPU_DUMP_SIZE 512 +@@ -186,10 +188,15 @@ static int airoha_npu_run_firmware(struc + struct reserved_mem *rmem) + { + const struct firmware *fw; ++ const char *fw_name; + void __iomem *addr; + int ret; + +- ret = request_firmware(&fw, NPU_EN7581_FIRMWARE_RV32, dev); ++ if (of_device_is_compatible(dev->of_node, "airoha,an7583-npu")) ++ fw_name = NPU_AN7583_FIRMWARE_RV32; ++ else ++ fw_name = NPU_EN7581_FIRMWARE_RV32; ++ ret = request_firmware(&fw, fw_name, dev); + if (ret) + return ret == -ENOENT ? -EPROBE_DEFER : ret; + +@@ -209,7 +216,11 @@ static int airoha_npu_run_firmware(struc + memcpy_toio(addr, fw->data, fw->size); + release_firmware(fw); + +- ret = request_firmware(&fw, NPU_EN7581_FIRMWARE_DATA, dev); ++ if (of_device_is_compatible(dev->of_node, "airoha,an7583-npu")) ++ fw_name = NPU_AN7583_FIRMWARE_DATA; ++ else ++ fw_name = NPU_EN7581_FIRMWARE_DATA; ++ ret = request_firmware(&fw, fw_name, dev); + if (ret) + return ret == -ENOENT ? -EPROBE_DEFER : ret; + +@@ -611,6 +622,7 @@ EXPORT_SYMBOL_GPL(airoha_npu_put); + + static const struct of_device_id of_airoha_npu_match[] = { + { .compatible = "airoha,en7581-npu" }, ++ { .compatible = "airoha,an7583-npu" }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, of_airoha_npu_match); +@@ -754,5 +766,9 @@ static struct platform_driver airoha_npu + module_platform_driver(airoha_npu_driver); + + MODULE_LICENSE("GPL"); ++MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_DATA); ++MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_RV32); ++MODULE_FIRMWARE(NPU_AN7583_FIRMWARE_DATA); ++MODULE_FIRMWARE(NPU_AN7583_FIRMWARE_RV32); + MODULE_AUTHOR("Lorenzo Bianconi "); + MODULE_DESCRIPTION("Airoha Network Processor Unit driver"); diff --git a/target/linux/airoha/patches-6.6/412-net-airoha-Add-airoha_eth_soc_data-struct.patch b/target/linux/airoha/patches-6.6/412-net-airoha-Add-airoha_eth_soc_data-struct.patch new file mode 100644 index 00000000000000..9758ed22460a83 --- /dev/null +++ b/target/linux/airoha/patches-6.6/412-net-airoha-Add-airoha_eth_soc_data-struct.patch @@ -0,0 +1,160 @@ +From dd4b2c638336bf390ff123f31d59e696c0c7a007 Mon Sep 17 00:00:00 2001 +Message-ID: +In-Reply-To: <6cc8cf5869e3d87d7ef37fc66e682c6c78960cd4.1758640781.git.lorenzo@kernel.org> +References: <6cc8cf5869e3d87d7ef37fc66e682c6c78960cd4.1758640781.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +Date: Thu, 11 Sep 2025 10:22:06 +0200 +Subject: [PATCH net-next 02/12] net: airoha: Add airoha_eth_soc_data struct + +Introduce airoha_eth_soc_data struct to contain differences between +various SoC. Move XSI reset names in airoha_eth_soc_data. This is a +preliminary patch to enable AN7583 ethernet controller support in +airoha-eth driver. + +Co-developed-by: Christian Marangi +Signed-off-by: Christian Marangi +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/airoha/airoha_eth.c | 42 +++++++++++++++++++----- + drivers/net/ethernet/airoha/airoha_eth.h | 17 ++++++++-- + 2 files changed, 48 insertions(+), 11 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1530,8 +1530,7 @@ static int airoha_hw_init(struct platfor + int err, i; + + /* disable xsi */ +- err = reset_control_bulk_assert(ARRAY_SIZE(eth->xsi_rsts), +- eth->xsi_rsts); ++ err = reset_control_bulk_assert(eth->soc->num_xsi_rsts, eth->xsi_rsts); + if (err) + return err; + +@@ -1539,7 +1538,8 @@ static int airoha_hw_init(struct platfor + if (err) + return err; + +- err = reset_control_bulk_deassert(ARRAY_SIZE(eth->xsi_rsts), eth->xsi_rsts); ++ err = reset_control_bulk_deassert(eth->soc->num_xsi_rsts, ++ eth->xsi_rsts); + if (err) + return err; + +@@ -3371,6 +3371,7 @@ free_metadata_dst: + + static int airoha_probe(struct platform_device *pdev) + { ++ struct reset_control_bulk_data *xsi_rsts; + struct device_node *np; + struct airoha_eth *eth; + int i, err; +@@ -3379,6 +3380,10 @@ static int airoha_probe(struct platform_ + if (!eth) + return -ENOMEM; + ++ eth->soc = of_device_get_match_data(&pdev->dev); ++ if (!eth->soc) ++ return -EINVAL; ++ + eth->dev = &pdev->dev; + + err = dma_set_mask_and_coherent(eth->dev, DMA_BIT_MASK(32)); +@@ -3403,12 +3408,18 @@ static int airoha_probe(struct platform_ + return err; + } + +- eth->xsi_rsts[0].id = "hsi0-mac"; +- eth->xsi_rsts[1].id = "hsi1-mac"; +- eth->xsi_rsts[2].id = "hsi-mac"; +- eth->xsi_rsts[3].id = "xfp-mac"; ++ xsi_rsts = devm_kzalloc(eth->dev, ++ eth->soc->num_xsi_rsts * sizeof(*xsi_rsts), ++ GFP_KERNEL); ++ if (err) ++ return err; ++ ++ eth->xsi_rsts = xsi_rsts; ++ for (i = 0; i < eth->soc->num_xsi_rsts; i++) ++ eth->xsi_rsts[i].id = eth->soc->xsi_rsts_names[i]; ++ + err = devm_reset_control_bulk_get_exclusive(eth->dev, +- ARRAY_SIZE(eth->xsi_rsts), ++ eth->soc->num_xsi_rsts, + eth->xsi_rsts); + if (err) { + dev_err(eth->dev, "failed to get bulk xsi reset lines\n"); +@@ -3506,8 +3517,22 @@ static void airoha_remove(struct platfor + platform_set_drvdata(pdev, NULL); + } + ++static const char * const en7581_xsi_rsts_names[] = { ++ "hsi0-mac", ++ "hsi1-mac", ++ "hsi-mac", ++ "xfp-mac", ++}; ++ ++static const struct airoha_eth_soc_data en7581_soc_data = { ++ .version = 0x7581, ++ .xsi_rsts_names = en7581_xsi_rsts_names, ++ .num_xsi_rsts = ARRAY_SIZE(en7581_xsi_rsts_names), ++ .num_ppe = 2, ++}; ++ + static const struct of_device_id of_airoha_match[] = { +- { .compatible = "airoha,en7581-eth" }, ++ { .compatible = "airoha,en7581-eth", .data = &en7581_soc_data }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, of_airoha_match); +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -21,7 +21,6 @@ + #define AIROHA_MAX_NUM_IRQ_BANKS 4 + #define AIROHA_MAX_DSA_PORTS 7 + #define AIROHA_MAX_NUM_RSTS 3 +-#define AIROHA_MAX_NUM_XSI_RSTS 4 + #define AIROHA_MAX_MTU 9216 + #define AIROHA_MAX_PACKET_SIZE 2048 + #define AIROHA_NUM_QOS_CHANNELS 4 +@@ -575,9 +574,18 @@ struct airoha_ppe { + struct dentry *debugfs_dir; + }; + ++struct airoha_eth_soc_data { ++ u16 version; ++ const char * const *xsi_rsts_names; ++ int num_xsi_rsts; ++ int num_ppe; ++}; ++ + struct airoha_eth { + struct device *dev; + ++ const struct airoha_eth_soc_data *soc; ++ + unsigned long state; + void __iomem *fe_regs; + +@@ -587,7 +595,7 @@ struct airoha_eth { + struct rhashtable flow_table; + + struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS]; +- struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS]; ++ struct reset_control_bulk_data *xsi_rsts; + + struct net_device *napi_dev; + +@@ -632,6 +640,11 @@ static inline bool airhoa_is_lan_gdm_por + return port->id == 1; + } + ++static inline bool airoha_is_7581(struct airoha_eth *eth) ++{ ++ return eth->soc->version == 0x7581; ++} ++ + bool airoha_is_valid_gdm_port(struct airoha_eth *eth, + struct airoha_gdm_port *port); + diff --git a/target/linux/airoha/patches-6.6/413-net-airoha-Generalize-airoha_ppe2_is_enabled-routine.patch b/target/linux/airoha/patches-6.6/413-net-airoha-Generalize-airoha_ppe2_is_enabled-routine.patch new file mode 100644 index 00000000000000..837410a1227475 --- /dev/null +++ b/target/linux/airoha/patches-6.6/413-net-airoha-Generalize-airoha_ppe2_is_enabled-routine.patch @@ -0,0 +1,148 @@ +From 48a9727ecb08c9546accf746923fd8a3c45948fb Mon Sep 17 00:00:00 2001 +Message-ID: <48a9727ecb08c9546accf746923fd8a3c45948fb.1758640781.git.lorenzo@kernel.org> +In-Reply-To: <6cc8cf5869e3d87d7ef37fc66e682c6c78960cd4.1758640781.git.lorenzo@kernel.org> +References: <6cc8cf5869e3d87d7ef37fc66e682c6c78960cd4.1758640781.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +Date: Sun, 14 Sep 2025 13:05:06 +0200 +Subject: [PATCH net-next 03/12] net: airoha: Generalize airoha_ppe2_is_enabled + routine + +Rename airoha_ppe2_is_enabled() in airoha_ppe_is_enabled() and +generalize it in order to check if each PPE module is enabled. +Use this routine to properly initialize PPE for AN7583 SoC where +PPE2 is not available. + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/airoha/airoha_eth.c | 32 ++++++++++++++++-------- + drivers/net/ethernet/airoha/airoha_eth.h | 1 + + drivers/net/ethernet/airoha/airoha_ppe.c | 17 +++++++------ + 3 files changed, 32 insertions(+), 18 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -304,8 +304,11 @@ static void airoha_fe_pse_ports_init(str + int q; + + all_rsv = airoha_fe_get_pse_all_rsv(eth); +- /* hw misses PPE2 oq rsv */ +- all_rsv += PSE_RSV_PAGES * pse_port_num_queues[FE_PSE_PORT_PPE2]; ++ if (airoha_ppe_is_enabled(eth, 1)) { ++ /* hw misses PPE2 oq rsv */ ++ all_rsv += PSE_RSV_PAGES * ++ pse_port_num_queues[FE_PSE_PORT_PPE2]; ++ } + airoha_fe_set(eth, REG_FE_PSE_BUF_SET, all_rsv); + + /* CMD1 */ +@@ -342,13 +345,17 @@ static void airoha_fe_pse_ports_init(str + for (q = 4; q < pse_port_num_queues[FE_PSE_PORT_CDM4]; q++) + airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM4, q, + PSE_QUEUE_RSV_PAGES); +- /* PPE2 */ +- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE2]; q++) { +- if (q < pse_port_num_queues[FE_PSE_PORT_PPE2] / 2) +- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, q, +- PSE_QUEUE_RSV_PAGES); +- else +- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, q, 0); ++ if (airoha_ppe_is_enabled(eth, 1)) { ++ /* PPE2 */ ++ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE2]; q++) { ++ if (q < pse_port_num_queues[FE_PSE_PORT_PPE2] / 2) ++ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, ++ q, ++ PSE_QUEUE_RSV_PAGES); ++ else ++ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, ++ q, 0); ++ } + } + /* GMD4 */ + for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM4]; q++) +@@ -1925,8 +1932,11 @@ static int airoha_dev_init(struct net_de + airhoha_set_gdm2_loopback(port); + fallthrough; + case 2: +- pse_port = FE_PSE_PORT_PPE2; +- break; ++ if (airoha_ppe_is_enabled(eth, 1)) { ++ pse_port = FE_PSE_PORT_PPE2; ++ break; ++ } ++ fallthrough; + default: + pse_port = FE_PSE_PORT_PPE1; + break; +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -648,6 +648,7 @@ static inline bool airoha_is_7581(struct + bool airoha_is_valid_gdm_port(struct airoha_eth *eth, + struct airoha_gdm_port *port); + ++bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index); + void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb, + u16 hash, bool rx_wlan); + int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data); +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -32,9 +32,12 @@ static const struct rhashtable_params ai + .automatic_shrinking = true, + }; + +-static bool airoha_ppe2_is_enabled(struct airoha_eth *eth) ++bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index) + { +- return airoha_fe_rr(eth, REG_PPE_GLO_CFG(1)) & PPE_GLO_CFG_EN_MASK; ++ if (index >= eth->soc->num_ppe) ++ return false; ++ ++ return airoha_fe_rr(eth, REG_PPE_GLO_CFG(index)) & PPE_GLO_CFG_EN_MASK; + } + + static u32 airoha_ppe_get_timestamp(struct airoha_ppe *ppe) +@@ -102,7 +105,7 @@ static void airoha_ppe_hw_init(struct ai + AIROHA_MAX_MTU)); + } + +- if (airoha_ppe2_is_enabled(eth)) { ++ if (airoha_ppe_is_enabled(eth, 1)) { + sram_num_entries = + PPE_RAM_NUM_ENTRIES_SHIFT(PPE1_SRAM_NUM_DATA_ENTRIES); + airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), +@@ -496,7 +499,7 @@ static u32 airoha_ppe_foe_get_entry_hash + + static u32 airoha_ppe_foe_get_flow_stats_index(struct airoha_ppe *ppe, u32 hash) + { +- if (!airoha_ppe2_is_enabled(ppe->eth)) ++ if (!airoha_ppe_is_enabled(ppe->eth, 1)) + return hash; + + return hash >= PPE_STATS_NUM_ENTRIES ? hash - PPE1_STATS_NUM_ENTRIES +@@ -580,7 +583,7 @@ airoha_ppe_foe_get_entry_locked(struct a + u32 val; + int i; + +- ppe2 = airoha_ppe2_is_enabled(ppe->eth) && ++ ppe2 = airoha_ppe_is_enabled(ppe->eth, 1) && + hash >= PPE1_SRAM_NUM_ENTRIES; + airoha_fe_wr(ppe->eth, REG_PPE_RAM_CTRL(ppe2), + FIELD_PREP(PPE_SRAM_CTRL_ENTRY_MASK, hash) | +@@ -658,7 +661,7 @@ static int airoha_ppe_foe_commit_entry(s + + if (hash < PPE_SRAM_NUM_ENTRIES) { + dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe); +- bool ppe2 = airoha_ppe2_is_enabled(eth) && ++ bool ppe2 = airoha_ppe_is_enabled(eth, 1) && + hash >= PPE1_SRAM_NUM_ENTRIES; + + err = npu->ops.ppe_foe_commit_entry(npu, addr, sizeof(*hwe), +@@ -1249,7 +1252,7 @@ static int airoha_ppe_flush_sram_entries + int i, sram_num_entries = PPE_SRAM_NUM_ENTRIES; + struct airoha_foe_entry *hwe = ppe->foe; + +- if (airoha_ppe2_is_enabled(ppe->eth)) ++ if (airoha_ppe_is_enabled(ppe->eth, 1)) + sram_num_entries = sram_num_entries / 2; + + for (i = 0; i < sram_num_entries; i++) diff --git a/target/linux/airoha/patches-6.6/414-net-airoha-ppe-Dynamically-allocate-foe_check_time-a.patch b/target/linux/airoha/patches-6.6/414-net-airoha-ppe-Dynamically-allocate-foe_check_time-a.patch new file mode 100644 index 00000000000000..1af7e3b894a1bc --- /dev/null +++ b/target/linux/airoha/patches-6.6/414-net-airoha-ppe-Dynamically-allocate-foe_check_time-a.patch @@ -0,0 +1,43 @@ +From c94abda86e1aa36e50cbdd3ecebdc4dc472e7c5c Mon Sep 17 00:00:00 2001 +Message-ID: +In-Reply-To: <6cc8cf5869e3d87d7ef37fc66e682c6c78960cd4.1758640781.git.lorenzo@kernel.org> +References: <6cc8cf5869e3d87d7ef37fc66e682c6c78960cd4.1758640781.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +Date: Sat, 13 Sep 2025 18:41:57 +0200 +Subject: [PATCH net-next 04/12] net: airoha: ppe: Dynamically allocate + foe_check_time array in airoha_ppe struct + +This is a preliminary patch to properly enable PPE support for AN7583 +SoC. + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/airoha/airoha_eth.h | 2 +- + drivers/net/ethernet/airoha/airoha_ppe.c | 5 +++++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -566,7 +566,7 @@ struct airoha_ppe { + struct rhashtable l2_flows; + + struct hlist_head *foe_flow; +- u16 foe_check_time[PPE_NUM_ENTRIES]; ++ u16 *foe_check_time; + + struct airoha_foe_stats *foe_stats; + dma_addr_t foe_stats_dma; +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -1454,6 +1454,11 @@ int airoha_ppe_init(struct airoha_eth *e + return -ENOMEM; + } + ++ ppe->foe_check_time = devm_kzalloc(eth->dev, PPE_NUM_ENTRIES, ++ GFP_KERNEL); ++ if (!ppe->foe_check_time) ++ return -ENOMEM; ++ + err = rhashtable_init(ð->flow_table, &airoha_flow_table_params); + if (err) + return err; diff --git a/target/linux/airoha/patches-6.6/415-net-airoha-npu-Add-a-NPU-callback-to-initialize-stat.patch b/target/linux/airoha/patches-6.6/415-net-airoha-npu-Add-a-NPU-callback-to-initialize-stat.patch new file mode 100644 index 00000000000000..59370c2f4d3b62 --- /dev/null +++ b/target/linux/airoha/patches-6.6/415-net-airoha-npu-Add-a-NPU-callback-to-initialize-stat.patch @@ -0,0 +1,159 @@ +From 72b9ea13a54ba2b499139712bf713202e3342f44 Mon Sep 17 00:00:00 2001 +Message-ID: <72b9ea13a54ba2b499139712bf713202e3342f44.1758640781.git.lorenzo@kernel.org> +In-Reply-To: <6cc8cf5869e3d87d7ef37fc66e682c6c78960cd4.1758640781.git.lorenzo@kernel.org> +References: <6cc8cf5869e3d87d7ef37fc66e682c6c78960cd4.1758640781.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +Date: Sat, 13 Sep 2025 18:32:10 +0200 +Subject: [PATCH net-next 05/12] net: airoha: npu: Add a NPU callback to + initialize stats + +Introduce a NPU callback to initialize stats and remove NPU stats +initialization from airoha_npu_get routine. Add num_stats_entries to +airoha_npu_ppe_stats_setup routine. +This patch makes the code more readable since NPU statistic are +initialized just by PPE module and not in MT76 driver. +Moreover this patch allows the PPE module to check if stats are enabled +by the user. + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/airoha/airoha_npu.c | 24 ++++++----------------- + drivers/net/ethernet/airoha/airoha_ppe.c | 19 ++++++++++++------ + include/linux/soc/airoha/airoha_offload.h | 7 ++++--- + 3 files changed, 23 insertions(+), 27 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_npu.c ++++ b/drivers/net/ethernet/airoha/airoha_npu.c +@@ -390,15 +390,13 @@ out: + return err; + } + +-static int airoha_npu_stats_setup(struct airoha_npu *npu, +- dma_addr_t foe_stats_addr) ++static int airoha_npu_ppe_stats_setup(struct airoha_npu *npu, ++ dma_addr_t foe_stats_addr, ++ u32 num_stats_entries) + { +- int err, size = PPE_STATS_NUM_ENTRIES * sizeof(*npu->stats); ++ int err, size = num_stats_entries * sizeof(*npu->stats); + struct ppe_mbox_data *ppe_data; + +- if (!size) /* flow stats are disabled */ +- return 0; +- + ppe_data = kzalloc(sizeof(*ppe_data), GFP_ATOMIC); + if (!ppe_data) + return -ENOMEM; +@@ -553,7 +551,7 @@ static void airoha_npu_wlan_irq_disable( + regmap_clear_bits(npu->regmap, REG_IRQ_RXDONE(q), NPU_IRQ_RX_MASK(q)); + } + +-struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr) ++struct airoha_npu *airoha_npu_get(struct device *dev) + { + struct platform_device *pdev; + struct device_node *np; +@@ -591,17 +589,6 @@ struct airoha_npu *airoha_npu_get(struct + goto error_module_put; + } + +- if (stats_addr) { +- int err; +- +- err = airoha_npu_stats_setup(npu, *stats_addr); +- if (err) { +- dev_err(dev, "failed to allocate npu stats buffer\n"); +- npu = ERR_PTR(err); +- goto error_module_put; +- } +- } +- + return npu; + + error_module_put: +@@ -655,6 +642,7 @@ static int airoha_npu_probe(struct platf + npu->dev = dev; + npu->ops.ppe_init = airoha_npu_ppe_init; + npu->ops.ppe_deinit = airoha_npu_ppe_deinit; ++ npu->ops.ppe_init_stats = airoha_npu_ppe_stats_setup; + npu->ops.ppe_flush_sram_entries = airoha_npu_ppe_flush_sram_entries; + npu->ops.ppe_foe_commit_entry = airoha_npu_foe_commit_entry; + npu->ops.wlan_init_reserved_memory = airoha_npu_wlan_init_memory; +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -1264,12 +1264,11 @@ static int airoha_ppe_flush_sram_entries + + static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth) + { +- struct airoha_npu *npu = airoha_npu_get(eth->dev, +- ð->ppe->foe_stats_dma); ++ struct airoha_npu *npu = airoha_npu_get(eth->dev); + + if (IS_ERR(npu)) { + request_module("airoha-npu"); +- npu = airoha_npu_get(eth->dev, ð->ppe->foe_stats_dma); ++ npu = airoha_npu_get(eth->dev); + } + + return npu; +@@ -1278,6 +1277,7 @@ static struct airoha_npu *airoha_ppe_npu + static int airoha_ppe_offload_setup(struct airoha_eth *eth) + { + struct airoha_npu *npu = airoha_ppe_npu_get(eth); ++ struct airoha_ppe *ppe = eth->ppe; + int err; + + if (IS_ERR(npu)) +@@ -1287,12 +1287,19 @@ static int airoha_ppe_offload_setup(stru + if (err) + goto error_npu_put; + +- airoha_ppe_hw_init(eth->ppe); +- err = airoha_ppe_flush_sram_entries(eth->ppe, npu); ++ if (PPE_STATS_NUM_ENTRIES) { ++ err = npu->ops.ppe_init_stats(npu, ppe->foe_stats_dma, ++ PPE_STATS_NUM_ENTRIES); ++ if (err) ++ goto error_npu_put; ++ } ++ ++ airoha_ppe_hw_init(ppe); ++ err = airoha_ppe_flush_sram_entries(ppe, npu); + if (err) + goto error_npu_put; + +- airoha_ppe_foe_flow_stats_reset(eth->ppe, npu); ++ airoha_ppe_foe_flow_stats_reset(ppe, npu); + + rcu_assign_pointer(eth->npu, npu); + synchronize_rcu(); +--- a/include/linux/soc/airoha/airoha_offload.h ++++ b/include/linux/soc/airoha/airoha_offload.h +@@ -181,6 +181,8 @@ struct airoha_npu { + struct { + int (*ppe_init)(struct airoha_npu *npu); + int (*ppe_deinit)(struct airoha_npu *npu); ++ int (*ppe_init_stats)(struct airoha_npu *npu, ++ dma_addr_t addr, u32 num_stats_entries); + int (*ppe_flush_sram_entries)(struct airoha_npu *npu, + dma_addr_t foe_addr, + int sram_num_entries); +@@ -206,7 +208,7 @@ struct airoha_npu { + }; + + #if (IS_BUILTIN(CONFIG_NET_AIROHA_NPU) || IS_MODULE(CONFIG_NET_AIROHA_NPU)) +-struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr); ++struct airoha_npu *airoha_npu_get(struct device *dev); + void airoha_npu_put(struct airoha_npu *npu); + + static inline int airoha_npu_wlan_init_reserved_memory(struct airoha_npu *npu) +@@ -256,8 +258,7 @@ static inline void airoha_npu_wlan_disab + npu->ops.wlan_disable_irq(npu, q); + } + #else +-static inline struct airoha_npu *airoha_npu_get(struct device *dev, +- dma_addr_t *foe_stats_addr) ++static inline struct airoha_npu *airoha_npu_get(struct device *dev) + { + return NULL; + } diff --git a/target/linux/airoha/patches-6.6/416-net-airoha-ppe-Move-PPE-memory-info-in-airoha_eth_so.patch b/target/linux/airoha/patches-6.6/416-net-airoha-ppe-Move-PPE-memory-info-in-airoha_eth_so.patch new file mode 100644 index 00000000000000..db81386c924338 --- /dev/null +++ b/target/linux/airoha/patches-6.6/416-net-airoha-ppe-Move-PPE-memory-info-in-airoha_eth_so.patch @@ -0,0 +1,479 @@ +From e19b18ef5214d4664698675d5e8c6a55d5eab038 Mon Sep 17 00:00:00 2001 +Message-ID: +In-Reply-To: <6cc8cf5869e3d87d7ef37fc66e682c6c78960cd4.1758640781.git.lorenzo@kernel.org> +References: <6cc8cf5869e3d87d7ef37fc66e682c6c78960cd4.1758640781.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +Date: Sat, 13 Sep 2025 00:17:43 +0200 +Subject: [PATCH net-next 06/12] net: airoha: ppe: Move PPE memory info in + airoha_eth_soc_data struct + +AN7583 SoC runs single PPE device while EN7581 runs two of them. +Moreover PPE SRAM in AN7583 SoC is reduced to 8K (while SRAM is 16K on +EN7581). Take into account PPE memory layout during PPE configuration. + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/airoha/airoha_eth.h | 16 +- + drivers/net/ethernet/airoha/airoha_ppe.c | 202 ++++++++++++------ + .../net/ethernet/airoha/airoha_ppe_debugfs.c | 3 +- + 3 files changed, 136 insertions(+), 85 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -57,20 +57,9 @@ + #define QDMA_METER_IDX(_n) ((_n) & 0xff) + #define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3) + +-#define PPE_NUM 2 +-#define PPE1_SRAM_NUM_ENTRIES (8 * 1024) +-#define PPE_SRAM_NUM_ENTRIES (2 * PPE1_SRAM_NUM_ENTRIES) +-#ifdef CONFIG_NET_AIROHA_FLOW_STATS +-#define PPE1_STATS_NUM_ENTRIES (4 * 1024) +-#else +-#define PPE1_STATS_NUM_ENTRIES 0 +-#endif /* CONFIG_NET_AIROHA_FLOW_STATS */ +-#define PPE_STATS_NUM_ENTRIES (2 * PPE1_STATS_NUM_ENTRIES) +-#define PPE1_SRAM_NUM_DATA_ENTRIES (PPE1_SRAM_NUM_ENTRIES - PPE1_STATS_NUM_ENTRIES) +-#define PPE_SRAM_NUM_DATA_ENTRIES (2 * PPE1_SRAM_NUM_DATA_ENTRIES) ++#define PPE_SRAM_NUM_ENTRIES (8 * 1024) ++#define PPE_STATS_NUM_ENTRIES (4 * 1024) + #define PPE_DRAM_NUM_ENTRIES (16 * 1024) +-#define PPE_NUM_ENTRIES (PPE_SRAM_NUM_ENTRIES + PPE_DRAM_NUM_ENTRIES) +-#define PPE_HASH_MASK (PPE_NUM_ENTRIES - 1) + #define PPE_ENTRY_SIZE 80 + #define PPE_RAM_NUM_ENTRIES_SHIFT(_n) (__ffs((_n) >> 10)) + +@@ -655,6 +644,7 @@ int airoha_ppe_setup_tc_block_cb(struct + int airoha_ppe_init(struct airoha_eth *eth); + void airoha_ppe_deinit(struct airoha_eth *eth); + void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port); ++u32 airoha_ppe_get_total_num_entries(struct airoha_ppe *ppe); + struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, + u32 hash); + void airoha_ppe_foe_entry_get_stats(struct airoha_ppe *ppe, u32 hash, +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -32,6 +32,45 @@ static const struct rhashtable_params ai + .automatic_shrinking = true, + }; + ++static int airoha_ppe_get_num_stats_entries(struct airoha_ppe *ppe, ++ u32 *num_stats) ++{ ++#ifdef CONFIG_NET_AIROHA_FLOW_STATS ++ *num_stats = PPE_STATS_NUM_ENTRIES; ++ return 0; ++#else ++ return -EOPNOTSUPP; ++#endif ++} ++ ++static int airoha_ppe_get_total_num_stats_entries(struct airoha_ppe *ppe, ++ u32 *num_stats) ++{ ++ struct airoha_eth *eth = ppe->eth; ++ int err; ++ ++ err = airoha_ppe_get_num_stats_entries(ppe, num_stats); ++ if (err) ++ return err; ++ ++ *num_stats = *num_stats * eth->soc->num_ppe; ++ return 0; ++} ++ ++static u32 airoha_ppe_get_total_sram_num_entries(struct airoha_ppe *ppe) ++{ ++ struct airoha_eth *eth = ppe->eth; ++ ++ return PPE_SRAM_NUM_ENTRIES * eth->soc->num_ppe; ++} ++ ++u32 airoha_ppe_get_total_num_entries(struct airoha_ppe *ppe) ++{ ++ u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe); ++ ++ return sram_num_entries + PPE_DRAM_NUM_ENTRIES; ++} ++ + bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index) + { + if (index >= eth->soc->num_ppe) +@@ -49,14 +88,22 @@ static u32 airoha_ppe_get_timestamp(stru + + static void airoha_ppe_hw_init(struct airoha_ppe *ppe) + { +- u32 sram_tb_size, sram_num_entries, dram_num_entries; ++ u32 sram_ppe_num_data_entries = PPE_SRAM_NUM_ENTRIES, sram_num_entries; ++ u32 sram_tb_size, dram_num_entries, sram_num_stats_entries; + struct airoha_eth *eth = ppe->eth; + int i; + +- sram_tb_size = PPE_SRAM_NUM_ENTRIES * sizeof(struct airoha_foe_entry); ++ sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe); ++ sram_tb_size = sram_num_entries * sizeof(struct airoha_foe_entry); + dram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(PPE_DRAM_NUM_ENTRIES); + +- for (i = 0; i < PPE_NUM; i++) { ++ if (!airoha_ppe_get_num_stats_entries(ppe, &sram_num_stats_entries)) ++ sram_ppe_num_data_entries -= sram_num_stats_entries; ++ ++ sram_ppe_num_data_entries = ++ PPE_RAM_NUM_ENTRIES_SHIFT(sram_ppe_num_data_entries); ++ ++ for (i = 0; i < eth->soc->num_ppe; i++) { + int p; + + airoha_fe_wr(eth, REG_PPE_TB_BASE(i), +@@ -88,10 +135,16 @@ static void airoha_ppe_hw_init(struct ai + + airoha_fe_rmw(eth, REG_PPE_TB_CFG(i), + PPE_TB_CFG_SEARCH_MISS_MASK | ++ PPE_SRAM_TB_NUM_ENTRY_MASK | ++ PPE_DRAM_TB_NUM_ENTRY_MASK | + PPE_TB_CFG_KEEPALIVE_MASK | + PPE_TB_ENTRY_SIZE_MASK, + FIELD_PREP(PPE_TB_CFG_SEARCH_MISS_MASK, 3) | +- FIELD_PREP(PPE_TB_ENTRY_SIZE_MASK, 0)); ++ FIELD_PREP(PPE_TB_ENTRY_SIZE_MASK, 0) | ++ FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, ++ sram_ppe_num_data_entries) | ++ FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, ++ dram_num_entries)); + + airoha_fe_wr(eth, REG_PPE_HASH_SEED(i), PPE_HASH_SEED); + +@@ -104,35 +157,6 @@ static void airoha_ppe_hw_init(struct ai + FIELD_PREP(FP1_EGRESS_MTU_MASK, + AIROHA_MAX_MTU)); + } +- +- if (airoha_ppe_is_enabled(eth, 1)) { +- sram_num_entries = +- PPE_RAM_NUM_ENTRIES_SHIFT(PPE1_SRAM_NUM_DATA_ENTRIES); +- airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), +- PPE_SRAM_TB_NUM_ENTRY_MASK | +- PPE_DRAM_TB_NUM_ENTRY_MASK, +- FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, +- sram_num_entries) | +- FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, +- dram_num_entries)); +- airoha_fe_rmw(eth, REG_PPE_TB_CFG(1), +- PPE_SRAM_TB_NUM_ENTRY_MASK | +- PPE_DRAM_TB_NUM_ENTRY_MASK, +- FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, +- sram_num_entries) | +- FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, +- dram_num_entries)); +- } else { +- sram_num_entries = +- PPE_RAM_NUM_ENTRIES_SHIFT(PPE_SRAM_NUM_DATA_ENTRIES); +- airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), +- PPE_SRAM_TB_NUM_ENTRY_MASK | +- PPE_DRAM_TB_NUM_ENTRY_MASK, +- FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, +- sram_num_entries) | +- FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, +- dram_num_entries)); +- } + } + + static void airoha_ppe_flow_mangle_eth(const struct flow_action_entry *act, void *eth) +@@ -445,9 +469,11 @@ static int airoha_ppe_foe_entry_set_ipv6 + return 0; + } + +-static u32 airoha_ppe_foe_get_entry_hash(struct airoha_foe_entry *hwe) ++static u32 airoha_ppe_foe_get_entry_hash(struct airoha_ppe *ppe, ++ struct airoha_foe_entry *hwe) + { + int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); ++ u32 ppe_hash_mask = airoha_ppe_get_total_num_entries(ppe) - 1; + u32 hash, hv1, hv2, hv3; + + switch (type) { +@@ -485,25 +511,35 @@ static u32 airoha_ppe_foe_get_entry_hash + case PPE_PKT_TYPE_IPV6_6RD: + default: + WARN_ON_ONCE(1); +- return PPE_HASH_MASK; ++ return ppe_hash_mask; + } + + hash = (hv1 & hv2) | ((~hv1) & hv3); + hash = (hash >> 24) | ((hash & 0xffffff) << 8); + hash ^= hv1 ^ hv2 ^ hv3; + hash ^= hash >> 16; +- hash &= PPE_NUM_ENTRIES - 1; ++ hash &= ppe_hash_mask; + + return hash; + } + +-static u32 airoha_ppe_foe_get_flow_stats_index(struct airoha_ppe *ppe, u32 hash) ++static int airoha_ppe_foe_get_flow_stats_index(struct airoha_ppe *ppe, ++ u32 hash, u32 *index) + { +- if (!airoha_ppe_is_enabled(ppe->eth, 1)) +- return hash; ++ u32 ppe_num_stats_entries; ++ int err; ++ ++ err = airoha_ppe_get_total_num_stats_entries(ppe, ++ &ppe_num_stats_entries); ++ if (err) ++ return err; + +- return hash >= PPE_STATS_NUM_ENTRIES ? hash - PPE1_STATS_NUM_ENTRIES +- : hash; ++ *index = hash; ++ if (airoha_ppe_is_enabled(ppe->eth, 1) && ++ hash >= ppe_num_stats_entries) ++ *index = *index - PPE_STATS_NUM_ENTRIES; ++ ++ return 0; + } + + static void airoha_ppe_foe_flow_stat_entry_reset(struct airoha_ppe *ppe, +@@ -517,9 +553,14 @@ static void airoha_ppe_foe_flow_stat_ent + static void airoha_ppe_foe_flow_stats_reset(struct airoha_ppe *ppe, + struct airoha_npu *npu) + { ++ u32 ppe_num_stats_entries; + int i; + +- for (i = 0; i < PPE_STATS_NUM_ENTRIES; i++) ++ if (airoha_ppe_get_total_num_stats_entries(ppe, ++ &ppe_num_stats_entries)) ++ return; ++ ++ for (i = 0; i < ppe_num_stats_entries; i++) + airoha_ppe_foe_flow_stat_entry_reset(ppe, npu, i); + } + +@@ -528,12 +569,18 @@ static void airoha_ppe_foe_flow_stats_up + struct airoha_foe_entry *hwe, + u32 hash) + { ++ u32 ppe_num_stats_entries, index, pse_port, val, *data, *ib2, *meter; + int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); +- u32 index, pse_port, val, *data, *ib2, *meter; + u8 nbq; + +- index = airoha_ppe_foe_get_flow_stats_index(ppe, hash); +- if (index >= PPE_STATS_NUM_ENTRIES) ++ if (airoha_ppe_get_total_num_stats_entries(ppe, ++ &ppe_num_stats_entries)) ++ return; ++ ++ if (airoha_ppe_foe_get_flow_stats_index(ppe, hash, &index)) ++ return; ++ ++ if (index >= ppe_num_stats_entries) + return; + + if (type == PPE_PKT_TYPE_BRIDGE) { +@@ -574,9 +621,11 @@ static void airoha_ppe_foe_flow_stats_up + static struct airoha_foe_entry * + airoha_ppe_foe_get_entry_locked(struct airoha_ppe *ppe, u32 hash) + { ++ u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe); ++ + lockdep_assert_held(&ppe_lock); + +- if (hash < PPE_SRAM_NUM_ENTRIES) { ++ if (hash < sram_num_entries) { + u32 *hwe = ppe->foe + hash * sizeof(struct airoha_foe_entry); + struct airoha_eth *eth = ppe->eth; + bool ppe2; +@@ -584,7 +633,7 @@ airoha_ppe_foe_get_entry_locked(struct a + int i; + + ppe2 = airoha_ppe_is_enabled(ppe->eth, 1) && +- hash >= PPE1_SRAM_NUM_ENTRIES; ++ hash >= PPE_SRAM_NUM_ENTRIES; + airoha_fe_wr(ppe->eth, REG_PPE_RAM_CTRL(ppe2), + FIELD_PREP(PPE_SRAM_CTRL_ENTRY_MASK, hash) | + PPE_SRAM_CTRL_REQ_MASK); +@@ -636,6 +685,7 @@ static int airoha_ppe_foe_commit_entry(s + u32 hash, bool rx_wlan) + { + struct airoha_foe_entry *hwe = ppe->foe + hash * sizeof(*hwe); ++ u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe); + u32 ts = airoha_ppe_get_timestamp(ppe); + struct airoha_eth *eth = ppe->eth; + struct airoha_npu *npu; +@@ -659,10 +709,10 @@ static int airoha_ppe_foe_commit_entry(s + if (!rx_wlan) + airoha_ppe_foe_flow_stats_update(ppe, npu, hwe, hash); + +- if (hash < PPE_SRAM_NUM_ENTRIES) { ++ if (hash < sram_num_entries) { + dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe); + bool ppe2 = airoha_ppe_is_enabled(eth, 1) && +- hash >= PPE1_SRAM_NUM_ENTRIES; ++ hash >= PPE_SRAM_NUM_ENTRIES; + + err = npu->ops.ppe_foe_commit_entry(npu, addr, sizeof(*hwe), + hash, ppe2); +@@ -789,7 +839,7 @@ static void airoha_ppe_foe_insert_entry( + if (state == AIROHA_FOE_STATE_BIND) + goto unlock; + +- index = airoha_ppe_foe_get_entry_hash(hwe); ++ index = airoha_ppe_foe_get_entry_hash(ppe, hwe); + hlist_for_each_entry_safe(e, n, &ppe->foe_flow[index], list) { + if (e->type == FLOW_TYPE_L2_SUBFLOW) { + state = FIELD_GET(AIROHA_FOE_IB1_BIND_STATE, hwe->ib1); +@@ -849,7 +899,7 @@ static int airoha_ppe_foe_flow_commit_en + if (type == PPE_PKT_TYPE_BRIDGE) + return airoha_ppe_foe_l2_flow_commit_entry(ppe, e); + +- hash = airoha_ppe_foe_get_entry_hash(&e->data); ++ hash = airoha_ppe_foe_get_entry_hash(ppe, &e->data); + e->type = FLOW_TYPE_L4; + e->hash = 0xffff; + +@@ -1179,11 +1229,18 @@ static int airoha_ppe_flow_offload_destr + void airoha_ppe_foe_entry_get_stats(struct airoha_ppe *ppe, u32 hash, + struct airoha_foe_stats64 *stats) + { +- u32 index = airoha_ppe_foe_get_flow_stats_index(ppe, hash); + struct airoha_eth *eth = ppe->eth; ++ u32 index, ppe_num_stats_entries; + struct airoha_npu *npu; + +- if (index >= PPE_STATS_NUM_ENTRIES) ++ if (airoha_ppe_get_total_num_stats_entries(ppe, ++ &ppe_num_stats_entries)) ++ return; ++ ++ if (airoha_ppe_foe_get_flow_stats_index(ppe, hash, &index)) ++ return; ++ ++ if (index >= ppe_num_stats_entries) + return; + + rcu_read_lock(); +@@ -1249,17 +1306,15 @@ static int airoha_ppe_flow_offload_cmd(s + static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe, + struct airoha_npu *npu) + { +- int i, sram_num_entries = PPE_SRAM_NUM_ENTRIES; ++ u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe); + struct airoha_foe_entry *hwe = ppe->foe; ++ int i; + +- if (airoha_ppe_is_enabled(ppe->eth, 1)) +- sram_num_entries = sram_num_entries / 2; +- +- for (i = 0; i < sram_num_entries; i++) ++ for (i = 0; i < PPE_SRAM_NUM_ENTRIES; i++) + memset(&hwe[i], 0, sizeof(*hwe)); + + return npu->ops.ppe_flush_sram_entries(npu, ppe->foe_dma, +- PPE_SRAM_NUM_ENTRIES); ++ sram_num_entries); + } + + static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth) +@@ -1276,8 +1331,9 @@ static struct airoha_npu *airoha_ppe_npu + + static int airoha_ppe_offload_setup(struct airoha_eth *eth) + { +- struct airoha_npu *npu = airoha_ppe_npu_get(eth); + struct airoha_ppe *ppe = eth->ppe; ++ struct airoha_npu *npu = airoha_ppe_npu_get(eth); ++ u32 ppe_num_stats_entries; + int err; + + if (IS_ERR(npu)) +@@ -1287,9 +1343,10 @@ static int airoha_ppe_offload_setup(stru + if (err) + goto error_npu_put; + +- if (PPE_STATS_NUM_ENTRIES) { ++ if (!airoha_ppe_get_total_num_stats_entries(ppe, ++ &ppe_num_stats_entries)) { + err = npu->ops.ppe_init_stats(npu, ppe->foe_stats_dma, +- PPE_STATS_NUM_ENTRIES); ++ ppe_num_stats_entries); + if (err) + goto error_npu_put; + } +@@ -1334,9 +1391,10 @@ void airoha_ppe_check_skb(struct airoha_ + u16 hash, bool rx_wlan) + { + struct airoha_ppe *ppe = dev->priv; ++ u32 ppe_hash_mask = airoha_ppe_get_total_num_entries(ppe) - 1; + u16 now, diff; + +- if (hash > PPE_HASH_MASK) ++ if (hash > ppe_hash_mask) + return; + + now = (u16)jiffies; +@@ -1426,6 +1484,7 @@ EXPORT_SYMBOL_GPL(airoha_ppe_put_dev); + + int airoha_ppe_init(struct airoha_eth *eth) + { ++ u32 ppe_num_entries, ppe_num_stats_entries; + struct airoha_ppe *ppe; + int foe_size, err; + +@@ -1436,24 +1495,25 @@ int airoha_ppe_init(struct airoha_eth *e + ppe->dev.ops.setup_tc_block_cb = airoha_ppe_setup_tc_block_cb; + ppe->dev.ops.check_skb = airoha_ppe_check_skb; + ppe->dev.priv = ppe; ++ ppe->eth = eth; ++ eth->ppe = ppe; + +- foe_size = PPE_NUM_ENTRIES * sizeof(struct airoha_foe_entry); ++ ppe_num_entries = airoha_ppe_get_total_num_entries(ppe); ++ foe_size = ppe_num_entries * sizeof(struct airoha_foe_entry); + ppe->foe = dmam_alloc_coherent(eth->dev, foe_size, &ppe->foe_dma, + GFP_KERNEL); + if (!ppe->foe) + return -ENOMEM; + +- ppe->eth = eth; +- eth->ppe = ppe; +- + ppe->foe_flow = devm_kzalloc(eth->dev, +- PPE_NUM_ENTRIES * sizeof(*ppe->foe_flow), ++ ppe_num_entries * sizeof(*ppe->foe_flow), + GFP_KERNEL); + if (!ppe->foe_flow) + return -ENOMEM; + +- foe_size = PPE_STATS_NUM_ENTRIES * sizeof(*ppe->foe_stats); +- if (foe_size) { ++ if (!airoha_ppe_get_total_num_stats_entries(ppe, ++ &ppe_num_stats_entries)) { ++ foe_size = ppe_num_stats_entries * sizeof(*ppe->foe_stats); + ppe->foe_stats = dmam_alloc_coherent(eth->dev, foe_size, + &ppe->foe_stats_dma, + GFP_KERNEL); +@@ -1461,7 +1521,7 @@ int airoha_ppe_init(struct airoha_eth *e + return -ENOMEM; + } + +- ppe->foe_check_time = devm_kzalloc(eth->dev, PPE_NUM_ENTRIES, ++ ppe->foe_check_time = devm_kzalloc(eth->dev, ppe_num_entries, + GFP_KERNEL); + if (!ppe->foe_check_time) + return -ENOMEM; +--- a/drivers/net/ethernet/airoha/airoha_ppe_debugfs.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe_debugfs.c +@@ -53,9 +53,10 @@ static int airoha_ppe_debugfs_foe_show(s + [AIROHA_FOE_STATE_FIN] = "FIN", + }; + struct airoha_ppe *ppe = m->private; ++ u32 ppe_num_entries = airoha_ppe_get_total_num_entries(ppe); + int i; + +- for (i = 0; i < PPE_NUM_ENTRIES; i++) { ++ for (i = 0; i < ppe_num_entries; i++) { + const char *state_str, *type_str = "UNKNOWN"; + void *src_addr = NULL, *dest_addr = NULL; + u16 *src_port = NULL, *dest_port = NULL; diff --git a/target/linux/airoha/patches-6.6/417-net-airoha-ppe-Remove-airoha_ppe_is_enabled-where-no.patch b/target/linux/airoha/patches-6.6/417-net-airoha-ppe-Remove-airoha_ppe_is_enabled-where-no.patch new file mode 100644 index 00000000000000..487126d00a9787 --- /dev/null +++ b/target/linux/airoha/patches-6.6/417-net-airoha-ppe-Remove-airoha_ppe_is_enabled-where-no.patch @@ -0,0 +1,58 @@ +From 2a9ba507b4a8a2220dfb903a3272bae4480145fb Mon Sep 17 00:00:00 2001 +Message-ID: <2a9ba507b4a8a2220dfb903a3272bae4480145fb.1758640781.git.lorenzo@kernel.org> +In-Reply-To: <6cc8cf5869e3d87d7ef37fc66e682c6c78960cd4.1758640781.git.lorenzo@kernel.org> +References: <6cc8cf5869e3d87d7ef37fc66e682c6c78960cd4.1758640781.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +Date: Sun, 14 Sep 2025 10:09:49 +0200 +Subject: [PATCH net-next 07/12] net: airoha: ppe: Remove + airoha_ppe_is_enabled() where not necessary + +Now each PPE has always PPE_STATS_NUM_ENTRIES entries so we do not need +to run airoha_ppe_is_enabled routine to check if the hash refers to +PPE1 or PPE2. + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/airoha/airoha_ppe.c | 13 ++++--------- + 1 file changed, 4 insertions(+), 9 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -534,10 +534,8 @@ static int airoha_ppe_foe_get_flow_stats + if (err) + return err; + +- *index = hash; +- if (airoha_ppe_is_enabled(ppe->eth, 1) && +- hash >= ppe_num_stats_entries) +- *index = *index - PPE_STATS_NUM_ENTRIES; ++ *index = hash >= ppe_num_stats_entries ? hash - PPE_STATS_NUM_ENTRIES ++ : hash; + + return 0; + } +@@ -627,13 +625,11 @@ airoha_ppe_foe_get_entry_locked(struct a + + if (hash < sram_num_entries) { + u32 *hwe = ppe->foe + hash * sizeof(struct airoha_foe_entry); ++ bool ppe2 = hash >= PPE_SRAM_NUM_ENTRIES; + struct airoha_eth *eth = ppe->eth; +- bool ppe2; + u32 val; + int i; + +- ppe2 = airoha_ppe_is_enabled(ppe->eth, 1) && +- hash >= PPE_SRAM_NUM_ENTRIES; + airoha_fe_wr(ppe->eth, REG_PPE_RAM_CTRL(ppe2), + FIELD_PREP(PPE_SRAM_CTRL_ENTRY_MASK, hash) | + PPE_SRAM_CTRL_REQ_MASK); +@@ -711,8 +707,7 @@ static int airoha_ppe_foe_commit_entry(s + + if (hash < sram_num_entries) { + dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe); +- bool ppe2 = airoha_ppe_is_enabled(eth, 1) && +- hash >= PPE_SRAM_NUM_ENTRIES; ++ bool ppe2 = hash >= PPE_SRAM_NUM_ENTRIES; + + err = npu->ops.ppe_foe_commit_entry(npu, addr, sizeof(*hwe), + hash, ppe2); diff --git a/target/linux/airoha/patches-6.6/418-net-airoha-ppe-Configure-SRAM-PPE-entries-via-the-cp.patch b/target/linux/airoha/patches-6.6/418-net-airoha-ppe-Configure-SRAM-PPE-entries-via-the-cp.patch new file mode 100644 index 00000000000000..f20e6ca0fae976 --- /dev/null +++ b/target/linux/airoha/patches-6.6/418-net-airoha-ppe-Configure-SRAM-PPE-entries-via-the-cp.patch @@ -0,0 +1,64 @@ +From 722b925eea5f560224c7f0760e9f2b05a223f51e Mon Sep 17 00:00:00 2001 +Message-ID: <722b925eea5f560224c7f0760e9f2b05a223f51e.1758640781.git.lorenzo@kernel.org> +In-Reply-To: <6cc8cf5869e3d87d7ef37fc66e682c6c78960cd4.1758640781.git.lorenzo@kernel.org> +References: <6cc8cf5869e3d87d7ef37fc66e682c6c78960cd4.1758640781.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +Date: Thu, 18 Sep 2025 11:15:35 +0200 +Subject: [PATCH net-next 08/12] net: airoha: ppe: Configure SRAM PPE entries + via the cpu + +Introduce airoha_ppe_foe_commit_sram_entry routine in order to configure +the SRAM PPE entries via the CPU instead of using the NPU APIs and +increase the PPE entries inserction rate. + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/airoha/airoha_ppe.c | 30 ++++++++++++++++++------ + 1 file changed, 23 insertions(+), 7 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -676,6 +676,27 @@ static bool airoha_ppe_foe_compare_entry + return !memcmp(&e->data.d, &hwe->d, len - sizeof(hwe->ib1)); + } + ++static int airoha_ppe_foe_commit_sram_entry(struct airoha_ppe *ppe, u32 hash) ++{ ++ struct airoha_foe_entry *hwe = ppe->foe + hash * sizeof(*hwe); ++ bool ppe2 = hash >= PPE_SRAM_NUM_ENTRIES; ++ u32 *ptr = (u32 *)hwe, val; ++ int i; ++ ++ for (i = 0; i < sizeof(*hwe) / 4; i++) ++ airoha_fe_wr(ppe->eth, REG_PPE_RAM_ENTRY(ppe2, i), ptr[i]); ++ ++ wmb(); ++ airoha_fe_wr(ppe->eth, REG_PPE_RAM_CTRL(ppe2), ++ FIELD_PREP(PPE_SRAM_CTRL_ENTRY_MASK, hash) | ++ PPE_SRAM_CTRL_WR_MASK | PPE_SRAM_CTRL_REQ_MASK); ++ ++ return read_poll_timeout_atomic(airoha_fe_rr, val, ++ val & PPE_SRAM_CTRL_ACK_MASK, ++ 10, 100, false, ppe->eth, ++ REG_PPE_RAM_CTRL(ppe2)); ++} ++ + static int airoha_ppe_foe_commit_entry(struct airoha_ppe *ppe, + struct airoha_foe_entry *e, + u32 hash, bool rx_wlan) +@@ -705,13 +726,8 @@ static int airoha_ppe_foe_commit_entry(s + if (!rx_wlan) + airoha_ppe_foe_flow_stats_update(ppe, npu, hwe, hash); + +- if (hash < sram_num_entries) { +- dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe); +- bool ppe2 = hash >= PPE_SRAM_NUM_ENTRIES; +- +- err = npu->ops.ppe_foe_commit_entry(npu, addr, sizeof(*hwe), +- hash, ppe2); +- } ++ if (hash < sram_num_entries) ++ err = airoha_ppe_foe_commit_sram_entry(ppe, hash); + unlock: + rcu_read_unlock(); + diff --git a/target/linux/airoha/patches-6.6/419-net-airoha-ppe-Flush-PPE-SRAM-table-during-PPE-setup.patch b/target/linux/airoha/patches-6.6/419-net-airoha-ppe-Flush-PPE-SRAM-table-during-PPE-setup.patch new file mode 100644 index 00000000000000..6ccd4f467f5e53 --- /dev/null +++ b/target/linux/airoha/patches-6.6/419-net-airoha-ppe-Flush-PPE-SRAM-table-during-PPE-setup.patch @@ -0,0 +1,70 @@ +From a3dc2eb72d3fcd0515354727a2f87290de2a5434 Mon Sep 17 00:00:00 2001 +Message-ID: +In-Reply-To: <6cc8cf5869e3d87d7ef37fc66e682c6c78960cd4.1758640781.git.lorenzo@kernel.org> +References: <6cc8cf5869e3d87d7ef37fc66e682c6c78960cd4.1758640781.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +Date: Thu, 18 Sep 2025 11:30:35 +0200 +Subject: [PATCH net-next 09/12] net: airoha: ppe: Flush PPE SRAM table during + PPE setup + +Rely on airoha_ppe_foe_commit_sram_entry routine to flush SRAM PPE table +entries. This patch allow moving PPE SRAM flush during PPE setup. + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/airoha/airoha_ppe.c | 24 ++++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -1314,18 +1314,22 @@ static int airoha_ppe_flow_offload_cmd(s + return -EOPNOTSUPP; + } + +-static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe, +- struct airoha_npu *npu) ++static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe) + { + u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe); + struct airoha_foe_entry *hwe = ppe->foe; +- int i; ++ int i, err = 0; ++ ++ for (i = 0; i < sram_num_entries; i++) { ++ int err; + +- for (i = 0; i < PPE_SRAM_NUM_ENTRIES; i++) + memset(&hwe[i], 0, sizeof(*hwe)); ++ err = airoha_ppe_foe_commit_sram_entry(ppe, i); ++ if (err) ++ break; ++ } + +- return npu->ops.ppe_flush_sram_entries(npu, ppe->foe_dma, +- sram_num_entries); ++ return err; + } + + static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth) +@@ -1363,10 +1367,6 @@ static int airoha_ppe_offload_setup(stru + } + + airoha_ppe_hw_init(ppe); +- err = airoha_ppe_flush_sram_entries(ppe, npu); +- if (err) +- goto error_npu_put; +- + airoha_ppe_foe_flow_stats_reset(ppe, npu); + + rcu_assign_pointer(eth->npu, npu); +@@ -1537,6 +1537,10 @@ int airoha_ppe_init(struct airoha_eth *e + if (!ppe->foe_check_time) + return -ENOMEM; + ++ err = airoha_ppe_flush_sram_entries(ppe); ++ if (err) ++ return err; ++ + err = rhashtable_init(ð->flow_table, &airoha_flow_table_params); + if (err) + return err; diff --git a/target/linux/airoha/patches-6.6/420-net-airoha-Read-the-GDM-3-4-src_port-index-from-the-.patch b/target/linux/airoha/patches-6.6/420-net-airoha-Read-the-GDM-3-4-src_port-index-from-the-.patch new file mode 100644 index 00000000000000..203ebcd6da27d3 --- /dev/null +++ b/target/linux/airoha/patches-6.6/420-net-airoha-Read-the-GDM-3-4-src_port-index-from-the-.patch @@ -0,0 +1,103 @@ +From f8e2fa02a3000d80cf187acb55abc86cc3e9d2f0 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Lorenzo Bianconi +Date: Thu, 18 Sep 2025 12:28:35 +0200 +Subject: [PATCH 1/4] net: airoha: Read the GDM{3,4} src_port index from the + device tree + +Read default src port connected to external phy from device tree if the +user provided it. + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/airoha/airoha_eth.c | 35 +++++++++-------------- + drivers/net/ethernet/airoha/airoha_eth.h | 1 + + drivers/net/ethernet/airoha/airoha_regs.h | 5 +--- + 3 files changed, 16 insertions(+), 25 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1869,8 +1869,8 @@ static int airoha_dev_set_macaddr(struct + static void airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) + { + u32 pse_port = port->id == 3 ? FE_PSE_PORT_GDM3 : FE_PSE_PORT_GDM4; ++ u32 src_port, chan = port->id == 3 ? 4 : 0; + struct airoha_eth *eth = port->qdma->eth; +- u32 chan = port->id == 3 ? 4 : 0; + + /* Forward the traffic to the proper GDM port */ + airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port); +@@ -1891,29 +1891,21 @@ static void airhoha_set_gdm2_loopback(st + airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2)); + airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2)); + +- if (port->id == 3) { +- /* FIXME: handle XSI_PCE1_PORT */ +- airoha_fe_rmw(eth, REG_FE_WAN_PORT, +- WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, +- FIELD_PREP(WAN0_MASK, HSGMII_LAN_PCIE0_SRCPORT)); +- airoha_fe_rmw(eth, +- REG_SP_DFT_CPORT(HSGMII_LAN_PCIE0_SRCPORT >> 3), +- SP_CPORT_PCIE0_MASK, +- FIELD_PREP(SP_CPORT_PCIE0_MASK, +- FE_PSE_PORT_CDM2)); +- } else { +- /* FIXME: handle XSI_USB_PORT */ ++ if (of_property_read_u32(port->np, "airoha,gdm-srcport", &src_port)) ++ src_port = port->id == 3 ? HSGMII_LAN_PCIE0_SRCPORT ++ : HSGMII_LAN_ETH_SRCPORT; ++ ++ airoha_fe_rmw(eth, REG_FE_WAN_PORT, ++ WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, ++ FIELD_PREP(WAN0_MASK, src_port)); ++ airoha_fe_rmw(eth, REG_SP_DFT_CPORT(src_port >> 3), ++ SP_CPORT_MASK(src_port & 0x7), ++ FE_PSE_PORT_CDM2 << __ffs(SP_CPORT_MASK(src_port & 0x7))); ++ ++ if (port->id != 3) + airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, + FC_ID_OF_SRC_PORT24_MASK, + FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2)); +- airoha_fe_rmw(eth, REG_FE_WAN_PORT, +- WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, +- FIELD_PREP(WAN0_MASK, HSGMII_LAN_ETH_SRCPORT)); +- airoha_fe_rmw(eth, +- REG_SP_DFT_CPORT(HSGMII_LAN_ETH_SRCPORT >> 3), +- SP_CPORT_ETH_MASK, +- FIELD_PREP(SP_CPORT_ETH_MASK, FE_PSE_PORT_CDM2)); +- } + } + + static int airoha_dev_init(struct net_device *dev) +@@ -3352,6 +3344,7 @@ static int airoha_alloc_gdm_port(struct + port->qdma = qdma; + port->dev = dev; + port->id = id; ++ port->np = np; + eth->ports[p] = port; + + err = airoha_metadata_dst_alloc(port); +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -525,6 +525,7 @@ struct airoha_qdma { + struct airoha_gdm_port { + struct airoha_qdma *qdma; + struct net_device *dev; ++ struct device_node *np; + int id; + + struct phylink *phylink; +--- a/drivers/net/ethernet/airoha/airoha_regs.h ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -403,10 +403,7 @@ + #define REG_MC_VLAN_DATA 0x2108 + + #define REG_SP_DFT_CPORT(_n) (0x20e0 + ((_n) << 2)) +-#define SP_CPORT_PCIE1_MASK GENMASK(31, 28) +-#define SP_CPORT_PCIE0_MASK GENMASK(27, 24) +-#define SP_CPORT_USB_MASK GENMASK(7, 4) +-#define SP_CPORT_ETH_MASK GENMASK(7, 4) ++#define SP_CPORT_MASK(_n) GENMASK(3 + ((_n) << 2), ((_n) << 2)) + + #define REG_SRC_PORT_FC_MAP6 0x2298 + #define FC_ID_OF_SRC_PORT27_MASK GENMASK(28, 24) diff --git a/target/linux/airoha/patches-6.6/421-net-airoha-Select-default-ppe-cpu-port-in-airoha_dev.patch b/target/linux/airoha/patches-6.6/421-net-airoha-Select-default-ppe-cpu-port-in-airoha_dev.patch new file mode 100644 index 00000000000000..17890daec0a423 --- /dev/null +++ b/target/linux/airoha/patches-6.6/421-net-airoha-Select-default-ppe-cpu-port-in-airoha_dev.patch @@ -0,0 +1,88 @@ +From 14549a23214ad4bc7d88f182f44d030405c0f7b9 Mon Sep 17 00:00:00 2001 +Message-ID: <14549a23214ad4bc7d88f182f44d030405c0f7b9.1758815505.git.lorenzo@kernel.org> +In-Reply-To: +References: +From: Lorenzo Bianconi +Date: Sun, 21 Sep 2025 15:38:32 +0200 +Subject: [PATCH 2/4] net: airoha: Select default ppe cpu port in + airoha_dev_init() + +Select PPE defualt cpu port in airoha_dev_init routine. +For PPE2 always use secondary cpu port. For PPE1 select cpu port +according to the running QDMA. + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/airoha/airoha_eth.c | 38 ++++++++++-------------- + 1 file changed, 16 insertions(+), 22 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -574,25 +574,6 @@ static int airoha_fe_init(struct airoha_ + /* disable IFC by default */ + airoha_fe_clear(eth, REG_FE_CSR_IFC_CFG, FE_IFC_EN_MASK); + +- airoha_fe_wr(eth, REG_PPE_DFT_CPORT0(0), +- FIELD_PREP(DFT_CPORT_MASK(7), FE_PSE_PORT_CDM1) | +- FIELD_PREP(DFT_CPORT_MASK(6), FE_PSE_PORT_CDM1) | +- FIELD_PREP(DFT_CPORT_MASK(5), FE_PSE_PORT_CDM1) | +- FIELD_PREP(DFT_CPORT_MASK(4), FE_PSE_PORT_CDM1) | +- FIELD_PREP(DFT_CPORT_MASK(3), FE_PSE_PORT_CDM1) | +- FIELD_PREP(DFT_CPORT_MASK(2), FE_PSE_PORT_CDM1) | +- FIELD_PREP(DFT_CPORT_MASK(1), FE_PSE_PORT_CDM1) | +- FIELD_PREP(DFT_CPORT_MASK(0), FE_PSE_PORT_CDM1)); +- airoha_fe_wr(eth, REG_PPE_DFT_CPORT0(1), +- FIELD_PREP(DFT_CPORT_MASK(7), FE_PSE_PORT_CDM2) | +- FIELD_PREP(DFT_CPORT_MASK(6), FE_PSE_PORT_CDM2) | +- FIELD_PREP(DFT_CPORT_MASK(5), FE_PSE_PORT_CDM2) | +- FIELD_PREP(DFT_CPORT_MASK(4), FE_PSE_PORT_CDM2) | +- FIELD_PREP(DFT_CPORT_MASK(3), FE_PSE_PORT_CDM2) | +- FIELD_PREP(DFT_CPORT_MASK(2), FE_PSE_PORT_CDM2) | +- FIELD_PREP(DFT_CPORT_MASK(1), FE_PSE_PORT_CDM2) | +- FIELD_PREP(DFT_CPORT_MASK(0), FE_PSE_PORT_CDM2)); +- + /* enable 1:N vlan action, init vlan table */ + airoha_fe_set(eth, REG_MC_VLAN_EN, MC_VLAN_EN_MASK); + +@@ -1911,8 +1892,10 @@ static void airhoha_set_gdm2_loopback(st + static int airoha_dev_init(struct net_device *dev) + { + struct airoha_gdm_port *port = netdev_priv(dev); +- struct airoha_eth *eth = port->qdma->eth; +- u32 pse_port; ++ struct airoha_qdma *qdma = port->qdma; ++ struct airoha_eth *eth = qdma->eth; ++ u32 pse_port, fe_cpu_port; ++ u8 ppe_id; + + airoha_set_macaddr(port, dev->dev_addr); + +@@ -1925,16 +1908,27 @@ static int airoha_dev_init(struct net_de + fallthrough; + case 2: + if (airoha_ppe_is_enabled(eth, 1)) { ++ /* For PPE2 always use secondary cpu port. */ ++ fe_cpu_port = FE_PSE_PORT_CDM2; + pse_port = FE_PSE_PORT_PPE2; + break; + } + fallthrough; +- default: ++ default: { ++ u8 qdma_id = qdma - ð->qdma[0]; ++ ++ /* For PPE1 select cpu port according to the running QDMA. */ ++ fe_cpu_port = qdma_id ? FE_PSE_PORT_CDM2 : FE_PSE_PORT_CDM1; + pse_port = FE_PSE_PORT_PPE1; + break; + } ++ } + + airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id), pse_port); ++ ppe_id = pse_port == FE_PSE_PORT_PPE2 ? 1 : 0; ++ airoha_fe_rmw(eth, REG_PPE_DFT_CPORT0(ppe_id), ++ DFT_CPORT_MASK(port->id), ++ fe_cpu_port << __ffs(DFT_CPORT_MASK(port->id))); + + return 0; + } diff --git a/target/linux/airoha/patches-6.6/422-net-airoha-Fix-loopback-mode-configuration-for-GDM2-.patch b/target/linux/airoha/patches-6.6/422-net-airoha-Fix-loopback-mode-configuration-for-GDM2-.patch new file mode 100644 index 00000000000000..01ef1fff5d3d90 --- /dev/null +++ b/target/linux/airoha/patches-6.6/422-net-airoha-Fix-loopback-mode-configuration-for-GDM2-.patch @@ -0,0 +1,27 @@ +From f7c73a1ed287675ca75029cdb45a824f264533db Mon Sep 17 00:00:00 2001 +Message-ID: +In-Reply-To: +References: +From: Lorenzo Bianconi +Date: Thu, 25 Sep 2025 17:42:03 +0200 +Subject: [PATCH 3/4] net: airoha: Fix loopback mode configuration for GDM2 + port + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/airoha/airoha_eth.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1862,7 +1862,9 @@ static void airhoha_set_gdm2_loopback(st + airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff); + airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2), + LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK, +- FIELD_PREP(LPBK_CHAN_MASK, chan) | LPBK_EN_MASK); ++ FIELD_PREP(LPBK_CHAN_MASK, chan) | ++ FIELD_PREP(LPBK_MODE_MASK, 7) | ++ LPBK_EN_MASK); + airoha_fe_rmw(eth, REG_GDM_LEN_CFG(2), + GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, + FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | diff --git a/target/linux/airoha/patches-6.6/423-net-airoha-Add-AN7583-SoC-support.patch b/target/linux/airoha/patches-6.6/423-net-airoha-Add-AN7583-SoC-support.patch new file mode 100644 index 00000000000000..ad45090463880e --- /dev/null +++ b/target/linux/airoha/patches-6.6/423-net-airoha-Add-AN7583-SoC-support.patch @@ -0,0 +1,149 @@ +From 0861ebe1e50d924bbd4b9e1de4d4797ae8e42172 Mon Sep 17 00:00:00 2001 +Message-ID: <0861ebe1e50d924bbd4b9e1de4d4797ae8e42172.1758815505.git.lorenzo@kernel.org> +In-Reply-To: +References: +From: Lorenzo Bianconi +Date: Thu, 11 Sep 2025 10:31:26 +0200 +Subject: [PATCH 4/4] net: airoha: Add AN7583 SoC support + +Introduce support for AN7583 ethernet controller to airoha-eth dirver. + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/airoha/airoha_eth.c | 39 +++++++++++++++++++++--- + drivers/net/ethernet/airoha/airoha_eth.h | 5 +++ + drivers/net/ethernet/airoha/airoha_ppe.c | 3 ++ + 3 files changed, 43 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -117,11 +117,13 @@ static int airoha_set_vip_for_gdm_port(s + switch (port->id) { + case 3: + /* FIXME: handle XSI_PCIE1_PORT */ +- vip_port = XSI_PCIE0_VIP_PORT_MASK; ++ vip_port = airoha_is_7581(eth) ? XSI_PCIE0_VIP_PORT_MASK ++ : XSI_ETH_VIP_PORT_MASK; + break; + case 4: + /* FIXME: handle XSI_USB_PORT */ +- vip_port = XSI_ETH_VIP_PORT_MASK; ++ vip_port = airoha_is_7581(eth) ? XSI_ETH_VIP_PORT_MASK ++ : XSI_PCIE0_VIP_PORT_MASK; + break; + default: + return 0; +@@ -1850,8 +1852,8 @@ static int airoha_dev_set_macaddr(struct + static void airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) + { + u32 pse_port = port->id == 3 ? FE_PSE_PORT_GDM3 : FE_PSE_PORT_GDM4; +- u32 src_port, chan = port->id == 3 ? 4 : 0; + struct airoha_eth *eth = port->qdma->eth; ++ u32 src_port, chan; + + /* Forward the traffic to the proper GDM port */ + airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port); +@@ -1860,6 +1862,8 @@ static void airhoha_set_gdm2_loopback(st + /* Enable GDM2 loopback */ + airoha_fe_wr(eth, REG_GDM_TXCHN_EN(2), 0xffffffff); + airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff); ++ ++ chan = port->id == 3 ? airoha_is_7581(eth) ? 4 : 3 : 0; + airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2), + LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK, + FIELD_PREP(LPBK_CHAN_MASK, chan) | +@@ -1885,7 +1889,7 @@ static void airhoha_set_gdm2_loopback(st + SP_CPORT_MASK(src_port & 0x7), + FE_PSE_PORT_CDM2 << __ffs(SP_CPORT_MASK(src_port & 0x7))); + +- if (port->id != 3) ++ if (port->id != 3 && airoha_is_7581(eth)) + airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, + FC_ID_OF_SRC_PORT24_MASK, + FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2)); +@@ -2074,6 +2078,20 @@ static int airoha_dev_set_features(struc + return 0; + } + ++static int airoha_get_fe_port(struct airoha_gdm_port *port) ++{ ++ struct airoha_qdma *qdma = port->qdma; ++ struct airoha_eth *eth = qdma->eth; ++ ++ switch (eth->soc->version) { ++ case 0x7583: ++ return port->id == 3 ? FE_PSE_PORT_GDM3 : port->id; ++ case 0x7581: ++ default: ++ return port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; ++ } ++} ++ + static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, + struct net_device *dev) + { +@@ -2114,7 +2132,7 @@ static netdev_tx_t airoha_dev_xmit(struc + } + } + +- fport = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; ++ fport = airoha_get_fe_port(port); + msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) | + FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f); + +@@ -3538,6 +3556,12 @@ static const char * const en7581_xsi_rst + "xfp-mac", + }; + ++static const char * const an7583_xsi_rsts_names[] = { ++ "hsi0-mac", ++ "hsi1-mac", ++ "xfp-mac", ++}; ++ + static const struct airoha_eth_soc_data en7581_soc_data = { + .version = 0x7581, + .xsi_rsts_names = en7581_xsi_rsts_names, +@@ -3545,8 +3569,16 @@ static const struct airoha_eth_soc_data + .num_ppe = 2, + }; + ++static const struct airoha_eth_soc_data an7583_soc_data = { ++ .version = 0x7583, ++ .xsi_rsts_names = an7583_xsi_rsts_names, ++ .num_xsi_rsts = ARRAY_SIZE(an7583_xsi_rsts_names), ++ .num_ppe = 1, ++}; ++ + static const struct of_device_id of_airoha_match[] = { + { .compatible = "airoha,en7581-eth", .data = &en7581_soc_data }, ++ { .compatible = "airoha,an7583-eth", .data = &an7583_soc_data }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, of_airoha_match); +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -648,6 +648,11 @@ static inline bool airoha_is_7581(struct + return eth->soc->version == 0x7581; + } + ++static inline bool airoha_is_7583(struct airoha_eth *eth) ++{ ++ return eth->soc->version == 0x7583; ++} ++ + bool airoha_is_valid_gdm_port(struct airoha_eth *eth, + struct airoha_gdm_port *port); + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -36,6 +36,9 @@ static int airoha_ppe_get_num_stats_entr + u32 *num_stats) + { + #ifdef CONFIG_NET_AIROHA_FLOW_STATS ++ if (airoha_is_7583(ppe->eth)) ++ return -EOPNOTSUPP; ++ + *num_stats = PPE_STATS_NUM_ENTRIES; + return 0; + #else diff --git a/target/linux/airoha/patches-6.6/999-26-net-airoha-take-into-account-all-possible-GDM-combin.patch b/target/linux/airoha/patches-6.6/999-26-net-airoha-take-into-account-all-possible-GDM-combin.patch index 6dba6dfc550ad8..45978552a2b5d4 100644 --- a/target/linux/airoha/patches-6.6/999-26-net-airoha-take-into-account-all-possible-GDM-combin.patch +++ b/target/linux/airoha/patches-6.6/999-26-net-airoha-take-into-account-all-possible-GDM-combin.patch @@ -12,7 +12,7 @@ Signed-off-by: Lorenzo Bianconi --- a/drivers/net/ethernet/airoha/airoha_eth.h +++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -67,13 +67,26 @@ static void airoha_qdma_irq_disable(stru +@@ -621,13 +621,26 @@ u32 airoha_rmw(void __iomem *base, u32 o #define airoha_qdma_clear(qdma, offset, val) \ airoha_rmw((qdma)->regs, (offset), (val), 0) @@ -40,10 +40,10 @@ Signed-off-by: Lorenzo Bianconi + return !eth->ports[0]; } - bool airoha_is_valid_gdm_port(struct airoha_eth *eth, + static inline bool airoha_is_7581(struct airoha_eth *eth) --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -81,8 +94,8 @@ static void airoha_set_macaddr(struct ai +@@ -83,8 +83,8 @@ static void airoha_set_macaddr(struct ai struct airoha_eth *eth = port->qdma->eth; u32 val, reg; @@ -54,7 +54,7 @@ Signed-off-by: Lorenzo Bianconi val = (addr[0] << 16) | (addr[1] << 8) | addr[2]; airoha_fe_wr(eth, reg, val); -@@ -2589,11 +2602,10 @@ static int airoha_register_port_debugfs( +@@ -3286,11 +3286,10 @@ static int airoha_register_port_debugfs( } static int airoha_alloc_gdm_port(struct airoha_eth *eth, @@ -67,7 +67,7 @@ Signed-off-by: Lorenzo Bianconi struct net_device *dev; int err, p; u32 id; -@@ -2624,7 +2636,6 @@ static int airoha_alloc_gdm_port(struct +@@ -3321,7 +3320,6 @@ static int airoha_alloc_gdm_port(struct return -ENOMEM; } @@ -75,38 +75,32 @@ Signed-off-by: Lorenzo Bianconi dev->netdev_ops = &airoha_netdev_ops; dev->ethtool_ops = &airoha_ethtool_ops; dev->max_mtu = AIROHA_MAX_MTU; -@@ -2636,7 +2647,6 @@ static int airoha_alloc_gdm_port(struct - dev->features |= dev->hw_features; - dev->vlan_features = dev->hw_features; +@@ -3330,7 +3328,6 @@ static int airoha_alloc_gdm_port(struct + dev->features |= AIROHA_HW_FEATURES; + dev->vlan_features = AIROHA_HW_FEATURES; dev->dev.of_node = np; - dev->irq = qdma->irq_banks[0].irq; SET_NETDEV_DEV(dev, eth->dev); /* reserve hw queues for HTB offloading */ -@@ -2667,34 +2677,46 @@ static int airoha_alloc_gdm_port(struct +@@ -3351,35 +3348,47 @@ static int airoha_alloc_gdm_port(struct port = netdev_priv(dev); u64_stats_init(&port->stats.syncp); spin_lock_init(&port->stats.lock); - port->qdma = qdma; port->dev = dev; port->id = id; + port->np = np; eth->ports[p] = port; - err = airoha_metadata_dst_alloc(port); - if (err) - return err; -- -- if (airhoa_is_phy_external(port)) { -- err = airoha_setup_phylink(dev); -- if (err) -- goto free_metadata_dst; -- } + return airoha_metadata_dst_alloc(port); +} -- err = airoha_register_port_debugfs(port); -- if (err) -- goto free_metadata_dst; +- if (airhoa_is_phy_external(port)) { +- err = airoha_setup_phylink(dev); +static int airoha_register_gdm_ports(struct airoha_eth *eth) +{ + int i; @@ -118,41 +112,44 @@ Signed-off-by: Lorenzo Bianconi + + if (!port) + continue; - -- err = register_netdev(dev); -- if (err) -- goto free_metadata_dst; -- -- return 0; -- --free_metadata_dst: -- airoha_metadata_dst_free(port); -- return err; ++ + qdma_idx = airhoa_is_lan_gdm_port(eth, port) ? 0 : 1; + qdma = ð->qdma[qdma_idx]; + port->dev->irq = qdma->irq_banks[0].irq; + port->qdma = qdma; + + err = airoha_register_port_debugfs(port); -+ if (err) + if (err) +- goto free_metadata_dst; +- } + return err; -+ + +- err = airoha_register_port_debugfs(port); +- if (err) +- goto free_metadata_dst; + if (airhoa_is_phy_external(port)) { + err = airoha_setup_phylink(port->dev); + if (err) + return err; + } -+ + +- err = register_netdev(dev); +- if (err) +- goto free_metadata_dst; + err = register_netdev(port->dev); + if (err) + return err; + } -+ -+ return 0; + + return 0; +- +-free_metadata_dst: +- airoha_metadata_dst_free(port); +- return err; } static int airoha_probe(struct platform_device *pdev) -@@ -2737,7 +2767,6 @@ static int airoha_probe(struct platform_ +@@ -3456,7 +3465,6 @@ static int airoha_probe(struct platform_ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) airoha_qdma_start_napi(ð->qdma[i]); @@ -160,7 +157,7 @@ Signed-off-by: Lorenzo Bianconi for_each_child_of_node(pdev->dev.of_node, np) { if (!of_device_is_compatible(np, "airoha,eth-mac")) continue; -@@ -2745,13 +2774,17 @@ static int airoha_probe(struct platform_ +@@ -3464,13 +3472,17 @@ static int airoha_probe(struct platform_ if (!of_device_is_available(np)) continue; @@ -179,7 +176,7 @@ Signed-off-by: Lorenzo Bianconi return 0; error_napi_stop: -@@ -2765,14 +2780,17 @@ error_hw_cleanup: +@@ -3484,14 +3496,17 @@ error_hw_cleanup: for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { struct airoha_gdm_port *port = eth->ports[i]; @@ -201,7 +198,7 @@ Signed-off-by: Lorenzo Bianconi platform_set_drvdata(pdev, NULL); --- a/drivers/net/ethernet/airoha/airoha_ppe.c +++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -225,7 +226,7 @@ static int airoha_ppe_foe_entry_prepare( +@@ -316,7 +316,7 @@ static int airoha_ppe_foe_entry_prepare( if (!airoha_is_valid_gdm_port(eth, port)) return -EINVAL; @@ -210,12 +207,12 @@ Signed-off-by: Lorenzo Bianconi pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; else -@@ -300,7 +300,7 @@ static int airoha_ppe_foe_entry_prepare( - /* For downlink traffic consume SRAM memory for hw forwarding - * descriptors queue. +@@ -337,7 +337,7 @@ static int airoha_ppe_foe_entry_prepare( + /* For downlink traffic consume SRAM memory for hw + * forwarding descriptors queue. */ - if (airhoa_is_lan_gdm_port(port)) + if (airhoa_is_lan_gdm_port(eth, port)) val |= AIROHA_FOE_IB2_FAST_PATH; - } - + if (dsa_port >= 0) + val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, diff --git a/target/linux/airoha/patches-6.6/999-36-add-rx_maxrate-sysfs-entry.patch b/target/linux/airoha/patches-6.6/999-36-add-rx_maxrate-sysfs-entry.patch deleted file mode 100644 index 531708e6d934c6..00000000000000 --- a/target/linux/airoha/patches-6.6/999-36-add-rx_maxrate-sysfs-entry.patch +++ /dev/null @@ -1,162 +0,0 @@ -From b40747ff393ecb79b8023c37b064f556463d08e4 Mon Sep 17 00:00:00 2001 -Message-ID: -From: Lorenzo Bianconi -Date: Wed, 19 Mar 2025 22:30:50 +0100 -Subject: [PATCH net-next] add rx_maxrate sysfs entry - -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 31 ++++++++++++++++ - include/linux/netdevice.h | 7 ++++ - include/net/netdev_rx_queue.h | 1 + - net/core/net-sysfs.c | 47 ++++++++++++++++++++++++ - 4 files changed, 86 insertions(+) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -2731,6 +2732,30 @@ static int airoha_dev_tc_setup(struct ne - } - } - -+static int airoha_dev_set_rx_maxrate(struct net_device *dev, int queue, -+ u32 rate) -+{ -+ struct netdev_rx_queue *rxq = __netif_get_rx_queue(dev, queue); -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_qdma *qdma = port->qdma; -+ u32 rate_val = rate * 1000; /* Kbps */ -+ int err; -+ -+ if (rate == rxq->rx_maxrate) -+ return 0; -+ -+ if (!qdma->q_rx[queue].ndesc) -+ return -EINVAL; -+ -+ err = airoha_qdma_init_rl_config(qdma, queue, !!rate, -+ TRTCM_BYTE_UNIT); -+ if (err) -+ return err; -+ -+ return airoha_qdma_set_rl_token_bucket(qdma, queue, rate_val, -+ MIN_TOKEN_SIZE); -+} -+ - static const struct net_device_ops airoha_netdev_ops = { - .ndo_init = airoha_dev_init, - .ndo_open = airoha_dev_open, -@@ -2741,6 +2766,7 @@ static const struct net_device_ops airoh - .ndo_get_stats64 = airoha_dev_get_stats64, - .ndo_set_mac_address = airoha_dev_set_macaddr, - .ndo_setup_tc = airoha_dev_tc_setup, -+ .ndo_set_rx_maxrate = airoha_dev_set_rx_maxrate, - }; - - static const struct ethtool_ops airoha_ethtool_ops = { ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -1374,6 +1374,10 @@ struct netdev_net_notifier { - * int queue_index, u32 maxrate); - * Called when a user wants to set a max-rate limitation of specific - * TX queue. -+ * int (*ndo_set_rx_maxrate)(struct net_device *dev, -+ * int queue_index, u32 maxrate); -+ * Called when a user wants to set a max-rate limitation of specific -+ * RX queue. - * int (*ndo_get_iflink)(const struct net_device *dev); - * Called to get the iflink value of this device. - * int (*ndo_fill_metadata_dst)(struct net_device *dev, struct sk_buff *skb); -@@ -1642,6 +1646,9 @@ struct net_device_ops { - int (*ndo_set_tx_maxrate)(struct net_device *dev, - int queue_index, - u32 maxrate); -+ int (*ndo_set_rx_maxrate)(struct net_device *dev, -+ int queue_index, -+ u32 maxrate); - int (*ndo_get_iflink)(const struct net_device *dev); - int (*ndo_fill_metadata_dst)(struct net_device *dev, - struct sk_buff *skb); ---- a/include/net/netdev_rx_queue.h -+++ b/include/net/netdev_rx_queue.h -@@ -13,6 +13,7 @@ struct netdev_rx_queue { - #ifdef CONFIG_RPS - struct rps_map __rcu *rps_map; - struct rps_dev_flow_table __rcu *rps_flow_table; -+ unsigned long rx_maxrate; - #endif - struct kobject kobj; - struct net_device *dev; ---- a/net/core/net-sysfs.c -+++ b/net/core/net-sysfs.c -@@ -990,18 +990,63 @@ static ssize_t store_rps_dev_flow_table_ - return len; - } - -+static ssize_t rx_maxrate_show(struct netdev_rx_queue *queue, char *buf) -+{ -+ return sysfs_emit(buf, "%lu\n", queue->rx_maxrate); -+} -+ -+static ssize_t rx_maxrate_store(struct netdev_rx_queue *queue, -+ const char *buf, size_t len) -+{ -+ int err, index = get_netdev_rx_queue_index(queue); -+ struct net_device *dev = queue->dev; -+ static DEFINE_MUTEX(rx_maxrate_mutex); -+ u32 rate; -+ -+ if (!capable(CAP_NET_ADMIN)) -+ return -EPERM; -+ -+ /* The check is also done later; this helps returning early without -+ * hitting the locking section below. -+ */ -+ if (!dev->netdev_ops->ndo_set_rx_maxrate) -+ return -EOPNOTSUPP; -+ -+ err = kstrtou32(buf, 10, &rate); -+ if (err < 0) -+ return err; -+ -+ mutex_lock(&rx_maxrate_mutex); -+ -+ err = -EOPNOTSUPP; -+ if (dev->netdev_ops->ndo_set_rx_maxrate) -+ err = dev->netdev_ops->ndo_set_rx_maxrate(dev, index, rate); -+ -+ if (!err) -+ queue->rx_maxrate = rate; -+ -+ mutex_unlock(&rx_maxrate_mutex); -+ -+ return !err ? len : err; -+} -+ - static struct rx_queue_attribute rps_cpus_attribute __ro_after_init - = __ATTR(rps_cpus, 0644, show_rps_map, store_rps_map); - - static struct rx_queue_attribute rps_dev_flow_table_cnt_attribute __ro_after_init - = __ATTR(rps_flow_cnt, 0644, - show_rps_dev_flow_table_cnt, store_rps_dev_flow_table_cnt); -+ -+static struct rx_queue_attribute queue_rx_maxrate __ro_after_init -+ = __ATTR(rx_maxrate, 0644, rx_maxrate_show, rx_maxrate_store); -+ - #endif /* CONFIG_RPS */ - - static struct attribute *rx_queue_default_attrs[] __ro_after_init = { - #ifdef CONFIG_RPS - &rps_cpus_attribute.attr, - &rps_dev_flow_table_cnt_attribute.attr, -+ &queue_rx_maxrate.attr, - #endif - NULL - }; diff --git a/target/linux/airoha/patches-6.6/999-51-lro.patch b/target/linux/airoha/patches-6.6/999-51-lro.patch index 365577d79259e2..1a75bfe73845cd 100644 --- a/target/linux/airoha/patches-6.6/999-51-lro.patch +++ b/target/linux/airoha/patches-6.6/999-51-lro.patch @@ -1,14 +1,14 @@ --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -17,6 +17,7 @@ - #include +@@ -13,6 +13,7 @@ + #include #include #include +#include #include #include "airoha_regs.h" -@@ -481,6 +482,40 @@ static void airoha_fe_crsn_qsel_init(str +@@ -454,6 +455,40 @@ static void airoha_fe_crsn_qsel_init(str CDM_CRSN_QSEL_Q1)); } @@ -49,7 +49,7 @@ static int airoha_fe_init(struct airoha_eth *eth) { airoha_fe_maccr_init(eth); -@@ -667,9 +702,87 @@ static int airoha_qdma_get_gdm_port(stru +@@ -641,9 +676,87 @@ static int airoha_qdma_get_gdm_port(stru return port >= ARRAY_SIZE(eth->ports) ? -EINVAL : port; } @@ -137,7 +137,7 @@ struct airoha_qdma *qdma = q->qdma; struct airoha_eth *eth = qdma->eth; int qid = q - &qdma->q_rx[0]; -@@ -719,9 +825,14 @@ static int airoha_qdma_rx_process(struct +@@ -686,9 +799,14 @@ static int airoha_qdma_rx_process(struct __skb_put(q->skb, len); skb_mark_for_recycle(q->skb); q->skb->dev = port->dev; @@ -153,7 +153,7 @@ } else { /* scattered frame */ struct skb_shared_info *shinfo = skb_shinfo(q->skb); int nr_frags = shinfo->nr_frags; -@@ -807,15 +919,17 @@ static int airoha_qdma_rx_napi_poll(stru +@@ -775,15 +893,17 @@ static int airoha_qdma_rx_napi_poll(stru } static int airoha_qdma_init_rx_queue(struct airoha_queue *q, @@ -175,7 +175,7 @@ .nid = NUMA_NO_NODE, .dev = qdma->eth->dev, .napi = &q->napi, -@@ -824,7 +938,7 @@ static int airoha_qdma_init_rx_queue(str +@@ -792,7 +912,7 @@ static int airoha_qdma_init_rx_queue(str int qid = q - &qdma->q_rx[0], thr; dma_addr_t dma_addr; @@ -184,7 +184,7 @@ q->ndesc = ndesc; q->qdma = qdma; -@@ -886,15 +1000,18 @@ static int airoha_qdma_init_rx(struct ai +@@ -854,15 +974,18 @@ static int airoha_qdma_init_rx(struct ai int i; for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { @@ -206,8 +206,8 @@ if (err) return err; } -@@ -1973,6 +2090,47 @@ static u32 airoha_get_dsa_tag(struct sk_ - #endif +@@ -1938,6 +2061,47 @@ static int airoha_get_fe_port(struct air + } } +static int airoha_dev_set_features(struct net_device *dev, @@ -254,7 +254,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, struct net_device *dev) { -@@ -2878,6 +3036,7 @@ static const struct net_device_ops airoh +@@ -2821,6 +2985,7 @@ static const struct net_device_ops airoh .ndo_stop = airoha_dev_stop, .ndo_change_mtu = airoha_dev_change_mtu, .ndo_select_queue = airoha_dev_select_queue, @@ -262,7 +262,7 @@ .ndo_start_xmit = airoha_dev_xmit, .ndo_get_stats64 = airoha_dev_get_stats64, .ndo_set_mac_address = airoha_dev_set_macaddr, -@@ -3152,6 +3311,31 @@ static int airoha_xmit_rings_show(struct +@@ -3021,6 +3186,31 @@ static int airoha_xmit_rings_show(struct } DEFINE_SHOW_ATTRIBUTE(airoha_xmit_rings); @@ -294,7 +294,7 @@ static int airoha_tx_meter_show(struct seq_file *s, void *data) { struct airoha_gdm_port *port = s->private; -@@ -3234,6 +3418,8 @@ static int airoha_register_port_debugfs( +@@ -3103,6 +3293,8 @@ static int airoha_register_port_debugfs( &airoha_tx_meter_fops); debugfs_create_file("xmit-rings", 0400, root, port, &airoha_xmit_rings_fops); @@ -303,7 +303,7 @@ return 0; } -@@ -3290,12 +3476,9 @@ static int airoha_alloc_gdm_port(struct +@@ -3146,12 +3338,9 @@ static int airoha_alloc_gdm_port(struct dev->ethtool_ops = &airoha_ethtool_ops; dev->max_mtu = AIROHA_MAX_MTU; dev->watchdog_timeo = 5 * HZ; @@ -371,7 +371,7 @@ #define REG_GDM_FWD_CFG(_n) GDM_BASE(_n) #define GDM_PAD_EN BIT(28) #define GDM_DROP_CRC_ERR BIT(23) -@@ -900,9 +917,15 @@ +@@ -903,9 +920,15 @@ #define QDMA_ETH_RXMSG_SPORT_MASK GENMASK(25, 21) #define QDMA_ETH_RXMSG_CRSN_MASK GENMASK(20, 16) #define QDMA_ETH_RXMSG_PPE_ENTRY_MASK GENMASK(15, 0) diff --git a/target/linux/airoha/patches-6.6/999-57-airoha-8021p-dscp-mark.patch b/target/linux/airoha/patches-6.6/999-57-airoha-8021p-dscp-mark.patch index 6e5ed99973c07c..b5c81808d84fe3 100644 --- a/target/linux/airoha/patches-6.6/999-57-airoha-8021p-dscp-mark.patch +++ b/target/linux/airoha/patches-6.6/999-57-airoha-8021p-dscp-mark.patch @@ -1,6 +1,6 @@ --- a/drivers/net/ethernet/airoha/airoha_ppe.c +++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -265,7 +265,8 @@ static int airoha_ppe_foe_entry_prepare( +@@ -267,7 +267,8 @@ static int airoha_ppe_foe_entry_prepare( AIROHA_FOE_IB1_BIND_TTL; hwe->ib1 = val; @@ -10,7 +10,7 @@ if (dev) { struct airoha_wdma_info info = {}; -@@ -357,9 +358,11 @@ static int airoha_ppe_foe_entry_prepare( +@@ -365,9 +366,11 @@ static int airoha_ppe_foe_entry_prepare( } if (data->vlan.num) { @@ -25,7 +25,7 @@ if (wlan_etype >= 0) { --- a/drivers/net/ethernet/airoha/airoha_ppe_debugfs.c +++ b/drivers/net/ethernet/airoha/airoha_ppe_debugfs.c -@@ -158,7 +158,7 @@ static int airoha_ppe_debugfs_foe_show(s +@@ -153,7 +153,7 @@ static int airoha_ppe_debugfs_foe_show(s *((__be32 *)h_source) = cpu_to_be32(l2->src_mac_hi); seq_printf(m, " eth=%pM->%pM etype=%04x data=%08x"