diff --git a/target/linux/airoha/patches-6.12/092-v6.18-net-airoha-Avoid-Wflex-array-member-not-at-end-warni.patch b/target/linux/airoha/patches-6.12/092-v6.18-net-airoha-Avoid-Wflex-array-member-not-at-end-warni.patch new file mode 100644 index 0000000000..5e52a3b429 --- /dev/null +++ b/target/linux/airoha/patches-6.12/092-v6.18-net-airoha-Avoid-Wflex-array-member-not-at-end-warni.patch @@ -0,0 +1,45 @@ +From 09630ab91d840416b0178f3660afa4eebce24286 Mon Sep 17 00:00:00 2001 +From: "Gustavo A. R. Silva" +Date: Mon, 22 Sep 2025 16:08:21 +0200 +Subject: [PATCH] net: airoha: Avoid -Wflex-array-member-not-at-end warning + +-Wflex-array-member-not-at-end was introduced in GCC-14, and we are +getting ready to enable it, globally. + +Move the conflicting declaration to the end of the corresponding +structure. Notice that `struct airoha_foe_entry` is a flexible +structure, this is a structure that contains a flexible-array +member. + +Fix the following warning: + +drivers/net/ethernet/airoha/airoha_eth.h:474:33: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] + +Signed-off-by: Gustavo A. R. Silva +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/aNFYVYLXQDqm4yxb@kspp +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.h | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -471,7 +471,6 @@ struct airoha_flow_table_entry { + }; + }; + +- struct airoha_foe_entry data; + struct hlist_node l2_subflow_node; /* PPE L2 subflow entry */ + u32 hash; + +@@ -480,6 +479,9 @@ struct airoha_flow_table_entry { + + struct rhash_head node; + unsigned long cookie; ++ ++ /* Must be last --ends in a flexible-array member. */ ++ struct airoha_foe_entry data; + }; + + struct airoha_wdma_info { diff --git a/target/linux/airoha/patches-6.12/093-v6.18-net-airoha-Fix-PPE_IP_PROTO_CHK-register-definitions.patch b/target/linux/airoha/patches-6.12/093-v6.18-net-airoha-Fix-PPE_IP_PROTO_CHK-register-definitions.patch new file mode 100644 index 0000000000..31cd950437 --- /dev/null +++ b/target/linux/airoha/patches-6.12/093-v6.18-net-airoha-Fix-PPE_IP_PROTO_CHK-register-definitions.patch @@ -0,0 +1,29 @@ +From e156dd6b856fa462430d875b0d4cd281ecd66c23 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Thu, 18 Sep 2025 08:59:41 +0200 +Subject: [PATCH] net: airoha: Fix PPE_IP_PROTO_CHK register definitions + +Fix typo in PPE_IP_PROTO_CHK_IPV4_MASK and PPE_IP_PROTO_CHK_IPV6_MASK +register mask definitions. This is not a real problem since this +register is not actually used in the current codebase. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_regs.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_regs.h ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -237,8 +237,8 @@ + #define PPE_FLOW_CFG_IP4_TCP_FRAG_MASK BIT(6) + + #define REG_PPE_IP_PROTO_CHK(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x208) +-#define PPE_IP_PROTO_CHK_IPV4_MASK GENMASK(15, 0) +-#define PPE_IP_PROTO_CHK_IPV6_MASK GENMASK(31, 16) ++#define PPE_IP_PROTO_CHK_IPV4_MASK GENMASK(31, 16) ++#define PPE_IP_PROTO_CHK_IPV6_MASK GENMASK(15, 0) + + #define REG_PPE_TB_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x21c) + #define PPE_SRAM_TB_NUM_ENTRY_MASK GENMASK(26, 24) diff --git a/target/linux/airoha/patches-6.12/094-v6.18-net-airoha-npu-Add-a-NPU-callback-to-initialize-flow.patch b/target/linux/airoha/patches-6.12/094-v6.18-net-airoha-npu-Add-a-NPU-callback-to-initialize-flow.patch new file mode 100644 index 0000000000..021ec0c8df --- /dev/null +++ b/target/linux/airoha/patches-6.12/094-v6.18-net-airoha-npu-Add-a-NPU-callback-to-initialize-flow.patch @@ -0,0 +1,159 @@ +From 105ce7ad57e492b75ab40f2dc591db645fadbaa2 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 24 Sep 2025 23:14:53 +0200 +Subject: [PATCH] net: airoha: npu: Add a NPU callback to initialize flow stats + +Introduce a NPU callback to initialize flow 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 now +initialized on demand by the NPU consumer (at the moment NPU statistic +are configured just by the airoha_eth driver). +Moreover this patch allows the NPU consumer (PPE module) to explicitly +enable/disable NPU flow stats. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250924-airoha-npu-init-stats-callback-v1-1-88bdf3c941b2@kernel.org +Signed-off-by: Jakub Kicinski +--- + 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 +@@ -379,15 +379,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; +@@ -542,7 +540,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; +@@ -580,17 +578,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: +@@ -643,6 +630,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 +@@ -1243,12 +1243,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; +@@ -1257,6 +1256,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)) +@@ -1266,12 +1266,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.12/095-v6.19-net-airoha-Fix-loopback-mode-configuration-for-GDM2-.patch b/target/linux/airoha/patches-6.12/095-v6.19-net-airoha-Fix-loopback-mode-configuration-for-GDM2-.patch new file mode 100644 index 0000000000..5c3fcc0c20 --- /dev/null +++ b/target/linux/airoha/patches-6.12/095-v6.19-net-airoha-Fix-loopback-mode-configuration-for-GDM2-.patch @@ -0,0 +1,43 @@ +From fea8cdf6738a8b25fccbb7b109b440795a0892cb Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 8 Oct 2025 11:27:43 +0200 +Subject: [PATCH] net: airoha: Fix loopback mode configuration for GDM2 port + +Add missing configuration for loopback mode in airhoha_set_gdm2_loopback +routine. + +Fixes: 9cd451d414f6e ("net: airoha: Add loopback support for GDM2") +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20251008-airoha-loopback-mode-fix-v2-1-045694fe7f60@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 4 +++- + drivers/net/ethernet/airoha/airoha_regs.h | 3 +++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1715,7 +1715,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) | ++ LBK_GAP_MODE_MASK | LBK_LEN_MODE_MASK | ++ LBK_CHAN_MODE_MASK | 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) | +--- a/drivers/net/ethernet/airoha/airoha_regs.h ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -151,6 +151,9 @@ + #define LPBK_LEN_MASK GENMASK(23, 10) + #define LPBK_CHAN_MASK GENMASK(8, 4) + #define LPBK_MODE_MASK GENMASK(3, 1) ++#define LBK_GAP_MODE_MASK BIT(3) ++#define LBK_LEN_MODE_MASK BIT(2) ++#define LBK_CHAN_MODE_MASK BIT(1) + #define LPBK_EN_MASK BIT(0) + + #define REG_GDM_TXCHN_EN(_n) (GDM_BASE(_n) + 0x24) diff --git a/target/linux/airoha/patches-6.12/096-v6.19-net-airoha-Add-missing-stats-to-ethtool_eth_mac_stat.patch b/target/linux/airoha/patches-6.12/096-v6.19-net-airoha-Add-missing-stats-to-ethtool_eth_mac_stat.patch new file mode 100644 index 0000000000..66d72ded83 --- /dev/null +++ b/target/linux/airoha/patches-6.12/096-v6.19-net-airoha-Add-missing-stats-to-ethtool_eth_mac_stat.patch @@ -0,0 +1,34 @@ +From 331f8a8bea22aecf99437f3561453a85f40026de Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 13 Oct 2025 16:29:41 +0200 +Subject: [PATCH] net: airoha: Add missing stats to ethtool_eth_mac_stats + +Add the following stats to ethtool ethtool_eth_mac_stats stats: +- FramesTransmittedOK +- OctetsTransmittedOK +- FramesReceivedOK +- OctetsReceivedOK + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20251013-airoha-ethtool-improvements-v1-1-fdd1c6fc9be1@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -2027,8 +2027,12 @@ static void airoha_ethtool_get_mac_stats + airoha_update_hw_stats(port); + do { + start = u64_stats_fetch_begin(&port->stats.syncp); ++ stats->FramesTransmittedOK = port->stats.tx_ok_pkts; ++ stats->OctetsTransmittedOK = port->stats.tx_ok_bytes; + stats->MulticastFramesXmittedOK = port->stats.tx_multicast; + stats->BroadcastFramesXmittedOK = port->stats.tx_broadcast; ++ stats->FramesReceivedOK = port->stats.rx_ok_pkts; ++ stats->OctetsReceivedOK = port->stats.rx_ok_bytes; + stats->BroadcastFramesReceivedOK = port->stats.rx_broadcast; + } while (u64_stats_fetch_retry(&port->stats.syncp, start)); + } diff --git a/target/linux/airoha/patches-6.12/097-v6.19-net-airoha-Add-get_link-ethtool-callback.patch b/target/linux/airoha/patches-6.12/097-v6.19-net-airoha-Add-get_link-ethtool-callback.patch new file mode 100644 index 0000000000..7d78bd6c03 --- /dev/null +++ b/target/linux/airoha/patches-6.12/097-v6.19-net-airoha-Add-get_link-ethtool-callback.patch @@ -0,0 +1,25 @@ +From fc4fed9054ef5b5269d4395dd9db36fe98fce9e3 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 13 Oct 2025 16:29:42 +0200 +Subject: [PATCH] net: airoha: Add get_link ethtool callback + +Set get_link ethtool callback to ethtool_op_get_link routine. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20251013-airoha-ethtool-improvements-v1-2-fdd1c6fc9be1@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/airoha/airoha_eth.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -2775,6 +2775,7 @@ static const struct ethtool_ops airoha_e + .get_drvinfo = airoha_ethtool_get_drvinfo, + .get_eth_mac_stats = airoha_ethtool_get_mac_stats, + .get_rmon_stats = airoha_ethtool_get_rmon_stats, ++ .get_link = ethtool_op_get_link, + }; + + static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port) diff --git a/target/linux/airoha/patches-6.12/098-v6.19-net-airoha-Take-into-account-out-of-order-tx-complet.patch b/target/linux/airoha/patches-6.12/098-v6.19-net-airoha-Take-into-account-out-of-order-tx-complet.patch new file mode 100644 index 0000000000..46432b2480 --- /dev/null +++ b/target/linux/airoha/patches-6.12/098-v6.19-net-airoha-Take-into-account-out-of-order-tx-complet.patch @@ -0,0 +1,54 @@ +From bd5afca115f181c85f992d42a57cd497bc823ccb Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Sun, 12 Oct 2025 11:19:44 +0200 +Subject: [PATCH] net: airoha: Take into account out-of-order tx completions in + airoha_dev_xmit() + +Completion napi can free out-of-order tx descriptors if hw QoS is +enabled and packets with different priority are queued to same DMA ring. +Take into account possible out-of-order reports checking if the tx queue +is full using circular buffer head/tail pointer instead of the number of +queued packets. + +Fixes: 23020f0493270 ("net: airoha: Introduce ethernet support for EN7581 SoC") +Suggested-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20251012-airoha-tx-busy-queue-v2-1-a600b08bab2d@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1878,6 +1878,20 @@ static u32 airoha_get_dsa_tag(struct sk_ + #endif + } + ++static bool airoha_dev_tx_queue_busy(struct airoha_queue *q, u32 nr_frags) ++{ ++ u32 tail = q->tail <= q->head ? q->tail + q->ndesc : q->tail; ++ u32 index = q->head + nr_frags; ++ ++ /* completion napi can free out-of-order tx descriptors if hw QoS is ++ * enabled and packets with different priorities are queued to the same ++ * DMA ring. Take into account possible out-of-order reports checking ++ * if the tx queue is full using circular buffer head/tail pointers ++ * instead of the number of queued packets. ++ */ ++ return index >= tail; ++} ++ + static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, + struct net_device *dev) + { +@@ -1931,7 +1945,7 @@ static netdev_tx_t airoha_dev_xmit(struc + txq = netdev_get_tx_queue(dev, qid); + nr_frags = 1 + skb_shinfo(skb)->nr_frags; + +- if (q->queued + nr_frags > q->ndesc) { ++ if (airoha_dev_tx_queue_busy(q, nr_frags)) { + /* not enough space in the queue */ + netif_tx_stop_queue(txq); + spin_unlock_bh(&q->lock); diff --git a/target/linux/airoha/patches-6.12/099-01-v6.19-net-airoha-ppe-Dynamically-allocate-foe_check_time-a.patch b/target/linux/airoha/patches-6.12/099-01-v6.19-net-airoha-ppe-Dynamically-allocate-foe_check_time-a.patch new file mode 100644 index 0000000000..3d4b0cfab0 --- /dev/null +++ b/target/linux/airoha/patches-6.12/099-01-v6.19-net-airoha-ppe-Dynamically-allocate-foe_check_time-a.patch @@ -0,0 +1,43 @@ +From 6d5b601d52a27aafff555b480e538507901c672c Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:11 +0200 +Subject: [PATCH 01/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. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-2-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + 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 +@@ -554,7 +554,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 +@@ -1440,6 +1440,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.12/099-02-v6.19-net-airoha-Add-airoha_ppe_get_num_stats_entries-and-.patch b/target/linux/airoha/patches-6.12/099-02-v6.19-net-airoha-Add-airoha_ppe_get_num_stats_entries-and-.patch new file mode 100644 index 0000000000..6733331f1f --- /dev/null +++ b/target/linux/airoha/patches-6.12/099-02-v6.19-net-airoha-Add-airoha_ppe_get_num_stats_entries-and-.patch @@ -0,0 +1,239 @@ +From 15f357cd4581ce6e02e5e97719320600783140ec Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:12 +0200 +Subject: [PATCH 02/12] net: airoha: Add airoha_ppe_get_num_stats_entries() and + airoha_ppe_get_num_total_stats_entries() + +Introduce airoha_ppe_get_num_stats_entries and +airoha_ppe_get_num_total_stats_entries routines in order to make the +code more readable controlling if CONFIG_NET_AIROHA_FLOW_STATS is +enabled or disabled. +Modify airoha_ppe_foe_get_flow_stats_index routine signature relying on +airoha_ppe_get_num_total_stats_entries(). + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-3-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.h | 10 +-- + drivers/net/ethernet/airoha/airoha_ppe.c | 101 ++++++++++++++++++----- + 2 files changed, 81 insertions(+), 30 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -50,15 +50,9 @@ + + #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 PPE_SRAM_NUM_ENTRIES (PPE_NUM * PPE1_SRAM_NUM_ENTRIES) + #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_STATS_NUM_ENTRIES (PPE_NUM * PPE1_STATS_NUM_ENTRIES) + #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) +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -32,6 +32,24 @@ static const struct rhashtable_params ai + .automatic_shrinking = true, + }; + ++static int airoha_ppe_get_num_stats_entries(struct airoha_ppe *ppe) ++{ ++ if (!IS_ENABLED(CONFIG_NET_AIROHA_FLOW_STATS)) ++ return -EOPNOTSUPP; ++ ++ return PPE1_STATS_NUM_ENTRIES; ++} ++ ++static int airoha_ppe_get_total_num_stats_entries(struct airoha_ppe *ppe) ++{ ++ int num_stats = airoha_ppe_get_num_stats_entries(ppe); ++ ++ if (num_stats > 0) ++ num_stats = num_stats * PPE_NUM; ++ ++ return num_stats; ++} ++ + static bool airoha_ppe2_is_enabled(struct airoha_eth *eth) + { + return airoha_fe_rr(eth, REG_PPE_GLO_CFG(1)) & PPE_GLO_CFG_EN_MASK; +@@ -48,7 +66,7 @@ static void airoha_ppe_hw_init(struct ai + { + u32 sram_tb_size, sram_num_entries, dram_num_entries; + struct airoha_eth *eth = ppe->eth; +- int i; ++ int i, sram_num_stats_entries; + + sram_tb_size = PPE_SRAM_NUM_ENTRIES * sizeof(struct airoha_foe_entry); + dram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(PPE_DRAM_NUM_ENTRIES); +@@ -103,8 +121,13 @@ static void airoha_ppe_hw_init(struct ai + } + + if (airoha_ppe2_is_enabled(eth)) { +- sram_num_entries = +- PPE_RAM_NUM_ENTRIES_SHIFT(PPE1_SRAM_NUM_DATA_ENTRIES); ++ sram_num_entries = PPE1_SRAM_NUM_ENTRIES; ++ sram_num_stats_entries = ++ airoha_ppe_get_num_stats_entries(ppe); ++ if (sram_num_stats_entries > 0) ++ sram_num_entries -= sram_num_stats_entries; ++ sram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(sram_num_entries); ++ + airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), + PPE_SRAM_TB_NUM_ENTRY_MASK | + PPE_DRAM_TB_NUM_ENTRY_MASK, +@@ -120,8 +143,13 @@ static void airoha_ppe_hw_init(struct ai + 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); ++ sram_num_entries = PPE_SRAM_NUM_ENTRIES; ++ sram_num_stats_entries = ++ airoha_ppe_get_total_num_stats_entries(ppe); ++ if (sram_num_stats_entries > 0) ++ sram_num_entries -= sram_num_stats_entries; ++ sram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(sram_num_entries); ++ + airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), + PPE_SRAM_TB_NUM_ENTRY_MASK | + PPE_DRAM_TB_NUM_ENTRY_MASK, +@@ -480,13 +508,21 @@ static u32 airoha_ppe_foe_get_entry_hash + 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_ppe2_is_enabled(ppe->eth)) +- return hash; ++ int ppe_num_stats_entries; ++ ++ ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe); ++ if (ppe_num_stats_entries < 0) ++ return ppe_num_stats_entries; ++ ++ *index = hash; ++ if (airoha_ppe2_is_enabled(ppe->eth) && ++ hash >= ppe_num_stats_entries) ++ *index = *index - PPE_STATS_NUM_ENTRIES; + +- return hash >= PPE_STATS_NUM_ENTRIES ? hash - PPE1_STATS_NUM_ENTRIES +- : hash; ++ return 0; + } + + static void airoha_ppe_foe_flow_stat_entry_reset(struct airoha_ppe *ppe, +@@ -500,9 +536,13 @@ static void airoha_ppe_foe_flow_stat_ent + static void airoha_ppe_foe_flow_stats_reset(struct airoha_ppe *ppe, + struct airoha_npu *npu) + { +- int i; ++ int i, ppe_num_stats_entries; ++ ++ ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe); ++ if (ppe_num_stats_entries < 0) ++ return; + +- for (i = 0; i < PPE_STATS_NUM_ENTRIES; i++) ++ for (i = 0; i < ppe_num_stats_entries; i++) + airoha_ppe_foe_flow_stat_entry_reset(ppe, npu, i); + } + +@@ -513,10 +553,17 @@ static void airoha_ppe_foe_flow_stats_up + { + int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); + u32 index, pse_port, val, *data, *ib2, *meter; ++ int ppe_num_stats_entries; + u8 nbq; + +- index = airoha_ppe_foe_get_flow_stats_index(ppe, hash); +- if (index >= PPE_STATS_NUM_ENTRIES) ++ ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe); ++ if (ppe_num_stats_entries < 0) ++ 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) { +@@ -1158,11 +1205,19 @@ 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; ++ int ppe_num_stats_entries; + struct airoha_npu *npu; ++ u32 index; ++ ++ ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe); ++ if (ppe_num_stats_entries < 0) ++ return; + +- if (index >= PPE_STATS_NUM_ENTRIES) ++ if (airoha_ppe_foe_get_flow_stats_index(ppe, hash, &index)) ++ return; ++ ++ if (index >= ppe_num_stats_entries) + return; + + rcu_read_lock(); +@@ -1257,7 +1312,7 @@ static int airoha_ppe_offload_setup(stru + { + struct airoha_npu *npu = airoha_ppe_npu_get(eth); + struct airoha_ppe *ppe = eth->ppe; +- int err; ++ int err, ppe_num_stats_entries; + + if (IS_ERR(npu)) + return PTR_ERR(npu); +@@ -1266,9 +1321,10 @@ static int airoha_ppe_offload_setup(stru + if (err) + goto error_npu_put; + +- if (PPE_STATS_NUM_ENTRIES) { ++ ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe); ++ if (ppe_num_stats_entries > 0) { + 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; + } +@@ -1405,8 +1461,8 @@ EXPORT_SYMBOL_GPL(airoha_ppe_put_dev); + + int airoha_ppe_init(struct airoha_eth *eth) + { ++ int foe_size, err, ppe_num_stats_entries; + struct airoha_ppe *ppe; +- int foe_size, err; + + ppe = devm_kzalloc(eth->dev, sizeof(*ppe), GFP_KERNEL); + if (!ppe) +@@ -1431,8 +1487,9 @@ int airoha_ppe_init(struct airoha_eth *e + if (!ppe->foe_flow) + return -ENOMEM; + +- foe_size = PPE_STATS_NUM_ENTRIES * sizeof(*ppe->foe_stats); +- if (foe_size) { ++ ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe); ++ if (ppe_num_stats_entries > 0) { ++ 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); diff --git a/target/linux/airoha/patches-6.12/099-03-v6.19-net-airoha-Add-airoha_eth_soc_data-struct.patch b/target/linux/airoha/patches-6.12/099-03-v6.19-net-airoha-Add-airoha_eth_soc_data-struct.patch new file mode 100644 index 0000000000..9035e21447 --- /dev/null +++ b/target/linux/airoha/patches-6.12/099-03-v6.19-net-airoha-Add-airoha_eth_soc_data-struct.patch @@ -0,0 +1,152 @@ +From 5863b4e065e2253ef05684f728a04e4972046bcb Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:13 +0200 +Subject: [PATCH 03/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 +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-4-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + 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 +@@ -1392,8 +1392,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; + +@@ -2927,6 +2926,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; +@@ -2935,6 +2935,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)); +@@ -2959,13 +2963,18 @@ static int airoha_probe(struct platform_ + return err; + } + +- eth->xsi_rsts[0].id = "xsi-mac"; +- eth->xsi_rsts[1].id = "hsi0-mac"; +- eth->xsi_rsts[2].id = "hsi1-mac"; +- eth->xsi_rsts[3].id = "hsi-mac"; +- eth->xsi_rsts[4].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"); +@@ -3052,8 +3061,23 @@ static void airoha_remove(struct platfor + platform_set_drvdata(pdev, NULL); + } + ++static const char * const en7581_xsi_rsts_names[] = { ++ "xsi-mac", ++ "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 5 + #define AIROHA_MAX_MTU 9216 + #define AIROHA_MAX_PACKET_SIZE 2048 + #define AIROHA_NUM_QOS_CHANNELS 4 +@@ -556,9 +555,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; + +@@ -568,7 +576,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; + +@@ -611,6 +619,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.12/099-04-v6.19-net-airoha-Generalize-airoha_ppe2_is_enabled-routine.patch b/target/linux/airoha/patches-6.12/099-04-v6.19-net-airoha-Generalize-airoha_ppe2_is_enabled-routine.patch new file mode 100644 index 0000000000..e82ce24e4f --- /dev/null +++ b/target/linux/airoha/patches-6.12/099-04-v6.19-net-airoha-Generalize-airoha_ppe2_is_enabled-routine.patch @@ -0,0 +1,147 @@ +From ef9449f080b61920cdc3d3106f8ffc2d9ba8b861 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:14 +0200 +Subject: [PATCH 04/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. +Rely on airoha_ppe_is_enabled routine to properly initialize PPE for +AN7583 SoC since AN7583 does not support PPE2. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-5-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + 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 +@@ -297,8 +297,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 */ +@@ -335,13 +338,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++) +@@ -1767,8 +1774,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 +@@ -627,6 +627,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 +@@ -50,9 +50,12 @@ static int airoha_ppe_get_total_num_stat + return num_stats; + } + +-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) +@@ -120,7 +123,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 = PPE1_SRAM_NUM_ENTRIES; + sram_num_stats_entries = + airoha_ppe_get_num_stats_entries(ppe); +@@ -518,7 +521,7 @@ static int airoha_ppe_foe_get_flow_stats + return ppe_num_stats_entries; + + *index = hash; +- if (airoha_ppe2_is_enabled(ppe->eth) && ++ if (airoha_ppe_is_enabled(ppe->eth, 1) && + hash >= ppe_num_stats_entries) + *index = *index - PPE_STATS_NUM_ENTRIES; + +@@ -613,7 +616,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) | +@@ -691,7 +694,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), +@@ -1286,7 +1289,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.12/099-05-v6.19-net-airoha-ppe-Move-PPE-memory-info-in-airoha_eth_so.patch b/target/linux/airoha/patches-6.12/099-05-v6.19-net-airoha-ppe-Move-PPE-memory-info-in-airoha_eth_so.patch new file mode 100644 index 0000000000..2382a21168 --- /dev/null +++ b/target/linux/airoha/patches-6.12/099-05-v6.19-net-airoha-ppe-Move-PPE-memory-info-in-airoha_eth_so.patch @@ -0,0 +1,359 @@ +From 5bd1d1fd48ea9f8300b211540d946899c7f96480 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:15 +0200 +Subject: [PATCH 05/12] net: airoha: ppe: Move PPE memory info in + airoha_eth_soc_data struct + +AN7583 SoC runs a 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. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-6-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.h | 10 +- + drivers/net/ethernet/airoha/airoha_ppe.c | 133 +++++++++--------- + .../net/ethernet/airoha/airoha_ppe_debugfs.c | 3 +- + 3 files changed, 70 insertions(+), 76 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -47,14 +47,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 (PPE_NUM * PPE1_SRAM_NUM_ENTRIES) +-#define PPE1_STATS_NUM_ENTRIES (4 * 1024) +-#define PPE_STATS_NUM_ENTRIES (PPE_NUM * PPE1_STATS_NUM_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)) + +@@ -634,6 +629,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 +@@ -37,19 +37,36 @@ static int airoha_ppe_get_num_stats_entr + if (!IS_ENABLED(CONFIG_NET_AIROHA_FLOW_STATS)) + return -EOPNOTSUPP; + +- return PPE1_STATS_NUM_ENTRIES; ++ return PPE_STATS_NUM_ENTRIES; + } + + static int airoha_ppe_get_total_num_stats_entries(struct airoha_ppe *ppe) + { + int num_stats = airoha_ppe_get_num_stats_entries(ppe); + +- if (num_stats > 0) +- num_stats = num_stats * PPE_NUM; ++ if (num_stats > 0) { ++ struct airoha_eth *eth = ppe->eth; ++ ++ num_stats = num_stats * eth->soc->num_ppe; ++ } + + return num_stats; + } + ++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) +@@ -67,14 +84,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; + struct airoha_eth *eth = ppe->eth; + int i, sram_num_stats_entries; + +- 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++) { ++ sram_num_stats_entries = airoha_ppe_get_num_stats_entries(ppe); ++ if (sram_num_stats_entries > 0) ++ 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), +@@ -106,10 +131,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); + +@@ -122,45 +153,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 = PPE1_SRAM_NUM_ENTRIES; +- sram_num_stats_entries = +- airoha_ppe_get_num_stats_entries(ppe); +- if (sram_num_stats_entries > 0) +- sram_num_entries -= sram_num_stats_entries; +- sram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(sram_num_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_SRAM_NUM_ENTRIES; +- sram_num_stats_entries = +- airoha_ppe_get_total_num_stats_entries(ppe); +- if (sram_num_stats_entries > 0) +- sram_num_entries -= sram_num_stats_entries; +- sram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(sram_num_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) +@@ -459,9 +451,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) { +@@ -499,14 +493,14 @@ 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; + } +@@ -607,9 +601,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; +@@ -617,7 +613,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); +@@ -668,6 +664,7 @@ static int airoha_ppe_foe_commit_entry(s + struct airoha_foe_entry *e, + u32 hash, bool rx_wlan) + { ++ u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe); + struct airoha_foe_entry *hwe = ppe->foe + hash * sizeof(*hwe); + u32 ts = airoha_ppe_get_timestamp(ppe); + struct airoha_eth *eth = ppe->eth; +@@ -692,10 +689,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); +@@ -822,7 +819,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); +@@ -882,7 +879,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; + +@@ -1286,17 +1283,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) +@@ -1372,9 +1367,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; +@@ -1465,6 +1461,7 @@ EXPORT_SYMBOL_GPL(airoha_ppe_put_dev); + int airoha_ppe_init(struct airoha_eth *eth) + { + int foe_size, err, ppe_num_stats_entries; ++ u32 ppe_num_entries; + struct airoha_ppe *ppe; + + ppe = devm_kzalloc(eth->dev, sizeof(*ppe), GFP_KERNEL); +@@ -1474,18 +1471,18 @@ 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; +@@ -1500,7 +1497,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.12/099-06-v6.19-net-airoha-ppe-Remove-airoha_ppe_is_enabled-where-no.patch b/target/linux/airoha/patches-6.12/099-06-v6.19-net-airoha-ppe-Remove-airoha_ppe_is_enabled-where-no.patch new file mode 100644 index 0000000000..18b92fb50d --- /dev/null +++ b/target/linux/airoha/patches-6.12/099-06-v6.19-net-airoha-ppe-Remove-airoha_ppe_is_enabled-where-no.patch @@ -0,0 +1,58 @@ +From 41139125f5c70e0f66f0cc4ac1b3a62f5801ab42 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:16 +0200 +Subject: [PATCH 06/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. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-7-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + 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 +@@ -514,10 +514,8 @@ static int airoha_ppe_foe_get_flow_stats + if (ppe_num_stats_entries < 0) + return ppe_num_stats_entries; + +- *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; + } +@@ -607,13 +605,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); +@@ -691,8 +687,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.12/099-07-v6.19-net-airoha-ppe-Configure-SRAM-PPE-entries-via-the-cp.patch b/target/linux/airoha/patches-6.12/099-07-v6.19-net-airoha-ppe-Configure-SRAM-PPE-entries-via-the-cp.patch new file mode 100644 index 0000000000..60b4ee1e44 --- /dev/null +++ b/target/linux/airoha/patches-6.12/099-07-v6.19-net-airoha-ppe-Configure-SRAM-PPE-entries-via-the-cp.patch @@ -0,0 +1,65 @@ +From 306b78f5035af4bd011753c5a6b12812515caa6c Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:17 +0200 +Subject: [PATCH 07/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 directly via the CPU instead of using the NPU APIs. +This is a preliminary patch to enable netfilter flowtable hw offload for +AN7583 SoC. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-8-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + 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 +@@ -656,6 +656,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) / sizeof(*ptr); 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) +@@ -685,13 +706,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.12/099-08-v6.19-net-airoha-ppe-Flush-PPE-SRAM-table-during-PPE-setup.patch b/target/linux/airoha/patches-6.12/099-08-v6.19-net-airoha-ppe-Flush-PPE-SRAM-table-during-PPE-setup.patch new file mode 100644 index 0000000000..24ecccabc8 --- /dev/null +++ b/target/linux/airoha/patches-6.12/099-08-v6.19-net-airoha-ppe-Flush-PPE-SRAM-table-during-PPE-setup.patch @@ -0,0 +1,71 @@ +From 620d7b91aadbd4eb930895b07e34f0a155a9d3c1 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:18 +0200 +Subject: [PATCH 08/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 and +avoid dumping uninitialized values via the debugfs if no entries are +offloaded yet. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-9-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + 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 +@@ -1291,18 +1291,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) +@@ -1339,10 +1343,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); +@@ -1513,6 +1513,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.12/099-09-v6.19-net-airoha-Select-default-ppe-cpu-port-in-airoha_dev.patch b/target/linux/airoha/patches-6.12/099-09-v6.19-net-airoha-Select-default-ppe-cpu-port-in-airoha_dev.patch new file mode 100644 index 0000000000..c6ecbdb829 --- /dev/null +++ b/target/linux/airoha/patches-6.12/099-09-v6.19-net-airoha-Select-default-ppe-cpu-port-in-airoha_dev.patch @@ -0,0 +1,91 @@ +From c71a7a861ef02aa2bebb18c2f3385aa3f19094e0 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:19 +0200 +Subject: [PATCH 09/12] net: airoha: Select default ppe cpu port in + airoha_dev_init() + +Select the PPE default cpu port in airoha_dev_init routine. +This patch allows to distribute the load between the two available cpu +ports (FE_PSE_PORT_CDM1 and FE_PSE_PORT_CDM2) if the device is running a +single PPE module (e.g. 7583) selecting the cpu port based on the use +QDMA device. For multi-PPE device (e.g. 7581) assign FE_PSE_PORT_CDM1 to +PPE1 and FE_PSE_PORT_CDM2 to PPE2. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-10-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + 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 +@@ -531,25 +531,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); + +@@ -1761,8 +1742,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); + +@@ -1775,16 +1758,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.12/099-10-v6.19-net-airoha-Refactor-src-port-configuration-in-airhoh.patch b/target/linux/airoha/patches-6.12/099-10-v6.19-net-airoha-Refactor-src-port-configuration-in-airhoh.patch new file mode 100644 index 0000000000..cec079845c --- /dev/null +++ b/target/linux/airoha/patches-6.12/099-10-v6.19-net-airoha-Refactor-src-port-configuration-in-airhoh.patch @@ -0,0 +1,202 @@ +From 9d5b5219f672c80bed4d4e15f0068e648cdca43b Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:20 +0200 +Subject: [PATCH 10/12] net: airoha: Refactor src port configuration in + airhoha_set_gdm2_loopback + +AN7583 chipset relies on different definitions for source-port +identifier used for hw offloading. In order to support hw offloading +in AN7583 controller, refactor src port configuration in +airhoha_set_gdm2_loopback routine and introduce get_src_port_id +callback. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-11-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 82 ++++++++++++++++------- + drivers/net/ethernet/airoha/airoha_eth.h | 18 +++-- + drivers/net/ethernet/airoha/airoha_regs.h | 6 +- + 3 files changed, 73 insertions(+), 33 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1687,13 +1687,17 @@ static int airoha_dev_set_macaddr(struct + return 0; + } + +-static void airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) ++static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) + { +- u32 pse_port = port->id == 3 ? FE_PSE_PORT_GDM3 : FE_PSE_PORT_GDM4; ++ u32 val, pse_port, chan = port->id == AIROHA_GDM3_IDX ? 4 : 0; + struct airoha_eth *eth = port->qdma->eth; +- u32 chan = port->id == 3 ? 4 : 0; ++ /* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */ ++ u32 nbq = port->id == AIROHA_GDM3_IDX ? 4 : 0; ++ int src_port; + + /* Forward the traffic to the proper GDM port */ ++ pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3 ++ : FE_PSE_PORT_GDM4; + airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port); + airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC); + +@@ -1714,29 +1718,25 @@ 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 */ ++ src_port = eth->soc->ops.get_src_port_id(port, nbq); ++ if (src_port < 0) ++ return src_port; ++ ++ airoha_fe_rmw(eth, REG_FE_WAN_PORT, ++ WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, ++ FIELD_PREP(WAN0_MASK, src_port)); ++ val = src_port & SP_CPORT_DFT_MASK; ++ airoha_fe_rmw(eth, ++ REG_SP_DFT_CPORT(src_port >> fls(SP_CPORT_DFT_MASK)), ++ SP_CPORT_MASK(val), ++ FE_PSE_PORT_CDM2 << __ffs(SP_CPORT_MASK(val))); ++ ++ if (port->id != AIROHA_GDM3_IDX) + 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)); +- } ++ ++ return 0; + } + + static int airoha_dev_init(struct net_device *dev) +@@ -1753,8 +1753,13 @@ static int airoha_dev_init(struct net_de + case 3: + case 4: + /* If GDM2 is active we can't enable loopback */ +- if (!eth->ports[1]) +- airhoha_set_gdm2_loopback(port); ++ if (!eth->ports[1]) { ++ int err; ++ ++ err = airhoha_set_gdm2_loopback(port); ++ if (err) ++ return err; ++ } + fallthrough; + case 2: + if (airoha_ppe_is_enabled(eth, 1)) { +@@ -3073,11 +3078,38 @@ static const char * const en7581_xsi_rst + "xfp-mac", + }; + ++static int airoha_en7581_get_src_port_id(struct airoha_gdm_port *port, int nbq) ++{ ++ switch (port->id) { ++ case 3: ++ /* 7581 SoC supports PCIe serdes on GDM3 port */ ++ if (nbq == 4) ++ return HSGMII_LAN_7581_PCIE0_SRCPORT; ++ if (nbq == 5) ++ return HSGMII_LAN_7581_PCIE1_SRCPORT; ++ break; ++ case 4: ++ /* 7581 SoC supports eth and usb serdes on GDM4 port */ ++ if (!nbq) ++ return HSGMII_LAN_7581_ETH_SRCPORT; ++ if (nbq == 1) ++ return HSGMII_LAN_7581_USB_SRCPORT; ++ break; ++ default: ++ break; ++ } ++ ++ return -EINVAL; ++} ++ + 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, ++ .ops = { ++ .get_src_port_id = airoha_en7581_get_src_port_id, ++ }, + }; + + static const struct of_device_id of_airoha_match[] = { +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -67,10 +67,10 @@ enum { + }; + + enum { +- HSGMII_LAN_PCIE0_SRCPORT = 0x16, +- HSGMII_LAN_PCIE1_SRCPORT, +- HSGMII_LAN_ETH_SRCPORT, +- HSGMII_LAN_USB_SRCPORT, ++ HSGMII_LAN_7581_PCIE0_SRCPORT = 0x16, ++ HSGMII_LAN_7581_PCIE1_SRCPORT, ++ HSGMII_LAN_7581_ETH_SRCPORT, ++ HSGMII_LAN_7581_USB_SRCPORT, + }; + + enum { +@@ -99,6 +99,13 @@ enum { + CRSN_25 = 0x19, + }; + ++enum airoha_gdm_index { ++ AIROHA_GDM1_IDX = 1, ++ AIROHA_GDM2_IDX = 2, ++ AIROHA_GDM3_IDX = 3, ++ AIROHA_GDM4_IDX = 4, ++}; ++ + enum { + FE_PSE_PORT_CDM1, + FE_PSE_PORT_GDM1, +@@ -555,6 +562,9 @@ struct airoha_eth_soc_data { + const char * const *xsi_rsts_names; + int num_xsi_rsts; + int num_ppe; ++ struct { ++ int (*get_src_port_id)(struct airoha_gdm_port *port, int nbq); ++ } ops; + }; + + struct airoha_eth { +--- a/drivers/net/ethernet/airoha/airoha_regs.h ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -383,10 +383,8 @@ + #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_DFT_MASK GENMASK(2, 0) ++#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.12/099-11-v6.19-net-airoha-ppe-Do-not-use-magic-numbers-in-airoha_pp.patch b/target/linux/airoha/patches-6.12/099-11-v6.19-net-airoha-ppe-Do-not-use-magic-numbers-in-airoha_pp.patch new file mode 100644 index 0000000000..93e7f5e592 --- /dev/null +++ b/target/linux/airoha/patches-6.12/099-11-v6.19-net-airoha-ppe-Do-not-use-magic-numbers-in-airoha_pp.patch @@ -0,0 +1,29 @@ +From 63f283d36b1fb06b55ae609a1f679544f5f66057 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:21 +0200 +Subject: [PATCH 11/12] net: airoha: ppe: Do not use magic numbers in + airoha_ppe_foe_get_entry_locked() + +Explicit the size of entries pointed by hwe pointer in +airoha_ppe_foe_get_entry_locked routine + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-12-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_ppe.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -619,7 +619,8 @@ airoha_ppe_foe_get_entry_locked(struct a + REG_PPE_RAM_CTRL(ppe2))) + return NULL; + +- for (i = 0; i < sizeof(struct airoha_foe_entry) / 4; i++) ++ for (i = 0; i < sizeof(struct airoha_foe_entry) / sizeof(*hwe); ++ i++) + hwe[i] = airoha_fe_rr(eth, + REG_PPE_RAM_ENTRY(ppe2, i)); + } diff --git a/target/linux/airoha/patches-6.12/099-12-v6.19-net-airoha-Add-AN7583-SoC-support.patch b/target/linux/airoha/patches-6.12/099-12-v6.19-net-airoha-Add-AN7583-SoC-support.patch new file mode 100644 index 0000000000..7f34a05ab5 --- /dev/null +++ b/target/linux/airoha/patches-6.12/099-12-v6.19-net-airoha-Add-AN7583-SoC-support.patch @@ -0,0 +1,185 @@ +From e4e5ce823bdd4601bd75ae7c206ae35e7c2fa60b Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 17 Oct 2025 11:06:22 +0200 +Subject: [PATCH 12/12] net: airoha: Add AN7583 SoC support + +Introduce support for AN7583 ethernet controller to airoha-eth dirver. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-13-f28319666667@kernel.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 68 ++++++++++++++++++++++-- + drivers/net/ethernet/airoha/airoha_eth.h | 11 ++++ + drivers/net/ethernet/airoha/airoha_ppe.c | 3 ++ + 3 files changed, 77 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1689,10 +1689,8 @@ static int airoha_dev_set_macaddr(struct + + static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) + { +- u32 val, pse_port, chan = port->id == AIROHA_GDM3_IDX ? 4 : 0; + struct airoha_eth *eth = port->qdma->eth; +- /* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */ +- u32 nbq = port->id == AIROHA_GDM3_IDX ? 4 : 0; ++ u32 val, pse_port, chan, nbq; + int src_port; + + /* Forward the traffic to the proper GDM port */ +@@ -1704,6 +1702,8 @@ static int airhoha_set_gdm2_loopback(str + /* 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 == AIROHA_GDM3_IDX ? 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) | +@@ -1718,6 +1718,8 @@ static int airhoha_set_gdm2_loopback(str + airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2)); + airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2)); + ++ /* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */ ++ nbq = port->id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0; + src_port = eth->soc->ops.get_src_port_id(port, nbq); + if (src_port < 0) + return src_port; +@@ -1731,7 +1733,7 @@ static int airhoha_set_gdm2_loopback(str + SP_CPORT_MASK(val), + FE_PSE_PORT_CDM2 << __ffs(SP_CPORT_MASK(val))); + +- if (port->id != AIROHA_GDM3_IDX) ++ if (port->id != AIROHA_GDM3_IDX && 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)); +@@ -1900,6 +1902,22 @@ static bool airoha_dev_tx_queue_busy(str + return index >= tail; + } + ++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 == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3 ++ : port->id; ++ case 0x7581: ++ default: ++ return port->id == AIROHA_GDM4_IDX ? FE_PSE_PORT_GDM4 ++ : port->id; ++ } ++} ++ + static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, + struct net_device *dev) + { +@@ -1940,7 +1958,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); + +@@ -3102,6 +3120,35 @@ static int airoha_en7581_get_src_port_id + return -EINVAL; + } + ++static const char * const an7583_xsi_rsts_names[] = { ++ "xsi-mac", ++ "hsi0-mac", ++ "hsi1-mac", ++ "xfp-mac", ++}; ++ ++static int airoha_an7583_get_src_port_id(struct airoha_gdm_port *port, int nbq) ++{ ++ switch (port->id) { ++ case 3: ++ /* 7583 SoC supports eth serdes on GDM3 port */ ++ if (!nbq) ++ return HSGMII_LAN_7583_ETH_SRCPORT; ++ break; ++ case 4: ++ /* 7583 SoC supports PCIe and USB serdes on GDM4 port */ ++ if (!nbq) ++ return HSGMII_LAN_7583_PCIE_SRCPORT; ++ if (nbq == 1) ++ return HSGMII_LAN_7583_USB_SRCPORT; ++ break; ++ default: ++ break; ++ } ++ ++ return -EINVAL; ++} ++ + static const struct airoha_eth_soc_data en7581_soc_data = { + .version = 0x7581, + .xsi_rsts_names = en7581_xsi_rsts_names, +@@ -3112,8 +3159,19 @@ static const struct airoha_eth_soc_data + }, + }; + ++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, ++ .ops = { ++ .get_src_port_id = airoha_an7583_get_src_port_id, ++ }, ++}; ++ + 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 +@@ -74,6 +74,12 @@ enum { + }; + + enum { ++ HSGMII_LAN_7583_ETH_SRCPORT = 0x16, ++ HSGMII_LAN_7583_PCIE_SRCPORT = 0x18, ++ HSGMII_LAN_7583_USB_SRCPORT, ++}; ++ ++enum { + XSI_PCIE0_VIP_PORT_MASK = BIT(22), + XSI_PCIE1_VIP_PORT_MASK = BIT(23), + XSI_USB_VIP_PORT_MASK = BIT(25), +@@ -629,6 +635,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 +@@ -37,6 +37,9 @@ static int airoha_ppe_get_num_stats_entr + if (!IS_ENABLED(CONFIG_NET_AIROHA_FLOW_STATS)) + return -EOPNOTSUPP; + ++ if (airoha_is_7583(ppe->eth)) ++ return -EOPNOTSUPP; ++ + return PPE_STATS_NUM_ENTRIES; + } + diff --git a/target/linux/airoha/patches-6.12/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch b/target/linux/airoha/patches-6.12/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch index 7537f659f9..85af65e3b4 100644 --- a/target/linux/airoha/patches-6.12/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch +++ b/target/linux/airoha/patches-6.12/116-02-net-airoha-deassert-XSI-line-on-hw-init.patch @@ -13,11 +13,11 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1401,6 +1401,10 @@ static int airoha_hw_init(struct platfor +@@ -1388,6 +1388,10 @@ 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; + diff --git a/target/linux/airoha/patches-6.12/116-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch b/target/linux/airoha/patches-6.12/116-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch index b620ec62b9..cf6520dd53 100644 --- a/target/linux/airoha/patches-6.12/116-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch +++ b/target/linux/airoha/patches-6.12/116-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch @@ -16,7 +16,7 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -605,8 +605,11 @@ static int airoha_qdma_get_gdm_port(stru +@@ -593,8 +593,11 @@ static int airoha_qdma_get_gdm_port(stru sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1); switch (sport) { diff --git a/target/linux/airoha/patches-6.12/116-05-net-airoha-drop-redundant-GDM3-4-define.patch b/target/linux/airoha/patches-6.12/116-05-net-airoha-drop-redundant-GDM3-4-define.patch index 4cc1d6c6fc..a52ee91ed9 100644 --- a/target/linux/airoha/patches-6.12/116-05-net-airoha-drop-redundant-GDM3-4-define.patch +++ b/target/linux/airoha/patches-6.12/116-05-net-airoha-drop-redundant-GDM3-4-define.patch @@ -15,7 +15,7 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -507,8 +507,8 @@ static int airoha_fe_init(struct airoha_ +@@ -514,8 +514,8 @@ static int airoha_fe_init(struct airoha_ FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) | FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22)); @@ -36,7 +36,7 @@ Signed-off-by: Christian Marangi #define GDM_DROP_CRC_ERR BIT(23) #define GDM_IP4_CKSUM BIT(22) #define GDM_TCP_CKSUM BIT(21) -@@ -349,13 +350,6 @@ +@@ -352,13 +353,6 @@ #define MBI_RX_AGE_SEL_MASK GENMASK(26, 25) #define MBI_TX_AGE_SEL_MASK GENMASK(18, 17) diff --git a/target/linux/airoha/patches-6.12/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch b/target/linux/airoha/patches-6.12/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch index 4af0275688..7e3ee7a9e8 100644 --- a/target/linux/airoha/patches-6.12/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch +++ b/target/linux/airoha/patches-6.12/116-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch @@ -15,7 +15,7 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -507,8 +507,10 @@ static int airoha_fe_init(struct airoha_ +@@ -514,8 +514,10 @@ static int airoha_fe_init(struct airoha_ FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) | FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22)); @@ -28,7 +28,7 @@ Signed-off-by: Christian Marangi airoha_fe_crsn_qsel_init(eth); -@@ -1643,7 +1645,8 @@ static int airoha_dev_open(struct net_de +@@ -1630,7 +1632,8 @@ static int airoha_dev_open(struct net_de if (err) return err; diff --git a/target/linux/airoha/patches-6.12/116-07-airoha-ethernet-drop-xsi-mac-reset.patch b/target/linux/airoha/patches-6.12/116-07-airoha-ethernet-drop-xsi-mac-reset.patch index 3e9a92db6b..be23e27ce0 100644 --- a/target/linux/airoha/patches-6.12/116-07-airoha-ethernet-drop-xsi-mac-reset.patch +++ b/target/linux/airoha/patches-6.12/116-07-airoha-ethernet-drop-xsi-mac-reset.patch @@ -15,30 +15,19 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2948,11 +2948,10 @@ static int airoha_probe(struct platform_ - return err; - } +@@ -3099,7 +3099,6 @@ static void airoha_remove(struct platfor + } -- eth->xsi_rsts[0].id = "xsi-mac"; -- eth->xsi_rsts[1].id = "hsi0-mac"; -- eth->xsi_rsts[2].id = "hsi1-mac"; -- eth->xsi_rsts[3].id = "hsi-mac"; -- eth->xsi_rsts[4].id = "xfp-mac"; -+ 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"; - err = devm_reset_control_bulk_get_exclusive(eth->dev, - ARRAY_SIZE(eth->xsi_rsts), - eth->xsi_rsts); ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -21,7 +21,7 @@ - #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 5 -+#define AIROHA_MAX_NUM_XSI_RSTS 4 - #define AIROHA_MAX_MTU 9216 - #define AIROHA_MAX_PACKET_SIZE 2048 - #define AIROHA_NUM_QOS_CHANNELS 4 + static const char * const en7581_xsi_rsts_names[] = { +- "xsi-mac", + "hsi0-mac", + "hsi1-mac", + "hsi-mac", +@@ -3131,7 +3130,6 @@ static int airoha_en7581_get_src_port_id + } + + static const char * const an7583_xsi_rsts_names[] = { +- "xsi-mac", + "hsi0-mac", + "hsi1-mac", + "xfp-mac", diff --git a/target/linux/airoha/patches-6.12/116-08-net-phylink-add-.pcs_link_down-PCS-OP.patch b/target/linux/airoha/patches-6.12/116-08-net-phylink-add-.pcs_link_down-PCS-OP.patch index 151decb8a8..7f5dcc7bd3 100644 --- a/target/linux/airoha/patches-6.12/116-08-net-phylink-add-.pcs_link_down-PCS-OP.patch +++ b/target/linux/airoha/patches-6.12/116-08-net-phylink-add-.pcs_link_down-PCS-OP.patch @@ -22,8 +22,8 @@ Signed-off-by: Christian Marangi --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c -@@ -1041,6 +1041,12 @@ static void phylink_pcs_link_up(struct p - pcs->ops->pcs_link_up(pcs, neg_mode, interface, speed, duplex); +@@ -1088,6 +1088,12 @@ static unsigned int phylink_inband_caps( + return phylink_pcs_inband_caps(pcs, interface); } +static void phylink_pcs_link_down(struct phylink_pcs *pcs) @@ -35,18 +35,18 @@ Signed-off-by: Christian Marangi static void phylink_pcs_poll_stop(struct phylink *pl) { if (pl->cfg_link_an_mode == MLO_AN_INBAND) -@@ -1454,6 +1460,8 @@ static void phylink_link_down(struct phy +@@ -1642,6 +1648,8 @@ static void phylink_link_down(struct phy if (ndev) netif_carrier_off(ndev); + phylink_pcs_link_down(pl->pcs); + - pl->mac_ops->mac_link_down(pl->config, pl->cur_link_an_mode, + pl->mac_ops->mac_link_down(pl->config, pl->act_link_an_mode, pl->cur_interface); phylink_info(pl, "Link is Down\n"); --- a/include/linux/phylink.h +++ b/include/linux/phylink.h -@@ -430,6 +430,7 @@ struct phylink_pcs { +@@ -431,6 +431,7 @@ struct phylink_pcs { * (where necessary). * @pcs_pre_init: configure PCS components necessary for MAC hardware * initialization e.g. RX clock for stmmac. @@ -54,7 +54,7 @@ Signed-off-by: Christian Marangi */ struct phylink_pcs_ops { int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported, -@@ -450,6 +451,7 @@ struct phylink_pcs_ops { +@@ -453,6 +454,7 @@ struct phylink_pcs_ops { void (*pcs_link_up)(struct phylink_pcs *pcs, unsigned int neg_mode, phy_interface_t interface, int speed, int duplex); int (*pcs_pre_init)(struct phylink_pcs *pcs); diff --git a/target/linux/airoha/patches-6.12/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch b/target/linux/airoha/patches-6.12/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch index 68671eb496..fd01dcda99 100644 --- a/target/linux/airoha/patches-6.12/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch +++ b/target/linux/airoha/patches-6.12/116-10-net-airoha-add-phylink-support-for-GDM2-4.patch @@ -35,7 +35,7 @@ Signed-off-by: Christian Marangi static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr) { struct airoha_eth *eth = port->qdma->eth; -@@ -1640,6 +1646,17 @@ static int airoha_dev_open(struct net_de +@@ -1627,6 +1633,17 @@ static int airoha_dev_open(struct net_de struct airoha_gdm_port *port = netdev_priv(dev); struct airoha_qdma *qdma = port->qdma; @@ -53,7 +53,7 @@ Signed-off-by: Christian Marangi netif_tx_start_all_queues(dev); err = airoha_set_vip_for_gdm_port(port, true); if (err) -@@ -1693,6 +1710,11 @@ static int airoha_dev_stop(struct net_de +@@ -1680,6 +1697,11 @@ static int airoha_dev_stop(struct net_de } } @@ -65,8 +65,8 @@ Signed-off-by: Christian Marangi return 0; } -@@ -2781,6 +2803,20 @@ static const struct ethtool_ops airoha_e - .get_rmon_stats = airoha_ethtool_get_rmon_stats, +@@ -2828,6 +2850,20 @@ static const struct ethtool_ops airoha_e + .get_link = ethtool_op_get_link, }; +static struct phylink_pcs *airoha_phylink_mac_select_pcs(struct phylink_config *config, @@ -86,7 +86,7 @@ Signed-off-by: Christian Marangi static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port) { int i; -@@ -2825,6 +2861,99 @@ bool airoha_is_valid_gdm_port(struct air +@@ -2872,6 +2908,99 @@ bool airoha_is_valid_gdm_port(struct air return false; } @@ -186,7 +186,7 @@ Signed-off-by: Christian Marangi static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np, int index) { -@@ -2903,6 +3032,12 @@ static int airoha_alloc_gdm_port(struct +@@ -2950,6 +3079,12 @@ static int airoha_alloc_gdm_port(struct if (err) return err; @@ -199,7 +199,7 @@ Signed-off-by: Christian Marangi err = register_netdev(dev); if (err) goto free_metadata_dst; -@@ -3006,6 +3141,10 @@ error_hw_cleanup: +@@ -3064,6 +3199,10 @@ error_hw_cleanup: if (port && port->dev->reg_state == NETREG_REGISTERED) { unregister_netdev(port->dev); airoha_metadata_dst_free(port); @@ -210,7 +210,7 @@ Signed-off-by: Christian Marangi } } free_netdev(eth->napi_dev); -@@ -3033,6 +3172,10 @@ static void airoha_remove(struct platfor +@@ -3091,6 +3230,10 @@ static void airoha_remove(struct platfor airoha_dev_stop(port->dev); unregister_netdev(port->dev); airoha_metadata_dst_free(port); @@ -223,7 +223,7 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.h +++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -528,6 +528,10 @@ struct airoha_gdm_port { +@@ -531,6 +531,10 @@ struct airoha_gdm_port { struct net_device *dev; int id; @@ -236,7 +236,7 @@ Signed-off-by: Christian Marangi DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS); --- a/drivers/net/ethernet/airoha/airoha_regs.h +++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -361,6 +361,18 @@ +@@ -364,6 +364,18 @@ #define IP_FRAGMENT_PORT_MASK GENMASK(8, 5) #define IP_FRAGMENT_NBQ_MASK GENMASK(4, 0) diff --git a/target/linux/airoha/patches-6.12/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch b/target/linux/airoha/patches-6.12/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch index 0fa14de3ee..5270c26e99 100644 --- a/target/linux/airoha/patches-6.12/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch +++ b/target/linux/airoha/patches-6.12/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch @@ -14,7 +14,7 @@ Signed-off-by: Christian Marangi --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -616,6 +616,9 @@ static int airoha_qdma_get_gdm_port(stru +@@ -604,6 +604,9 @@ static int airoha_qdma_get_gdm_port(stru case 0x18: port = 3; /* GDM4 */ break; diff --git a/target/linux/airoha/patches-6.12/606-net-airoha-disable-external-phy-code-if-PCS_AIROHA-i.patch b/target/linux/airoha/patches-6.12/606-net-airoha-disable-external-phy-code-if-PCS_AIROHA-i.patch index 370e9a7550..563ef641a5 100644 --- a/target/linux/airoha/patches-6.12/606-net-airoha-disable-external-phy-code-if-PCS_AIROHA-i.patch +++ b/target/linux/airoha/patches-6.12/606-net-airoha-disable-external-phy-code-if-PCS_AIROHA-i.patch @@ -28,7 +28,7 @@ Signed-off-by: Mikhail Kshevetskiy static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr) { -@@ -1649,6 +1651,7 @@ static int airoha_dev_open(struct net_de +@@ -1636,6 +1638,7 @@ static int airoha_dev_open(struct net_de struct airoha_gdm_port *port = netdev_priv(dev); struct airoha_qdma *qdma = port->qdma; @@ -36,7 +36,7 @@ Signed-off-by: Mikhail Kshevetskiy if (airhoa_is_phy_external(port)) { err = phylink_of_phy_connect(port->phylink, dev->dev.of_node, 0); if (err) { -@@ -1659,6 +1662,7 @@ static int airoha_dev_open(struct net_de +@@ -1646,6 +1649,7 @@ static int airoha_dev_open(struct net_de phylink_start(port->phylink); } @@ -44,7 +44,7 @@ Signed-off-by: Mikhail Kshevetskiy netif_tx_start_all_queues(dev); err = airoha_set_vip_for_gdm_port(port, true); -@@ -1713,10 +1717,12 @@ static int airoha_dev_stop(struct net_de +@@ -1700,10 +1704,12 @@ static int airoha_dev_stop(struct net_de } } @@ -57,15 +57,15 @@ Signed-off-by: Mikhail Kshevetskiy return 0; } -@@ -2806,6 +2812,7 @@ static const struct ethtool_ops airoha_e - .get_rmon_stats = airoha_ethtool_get_rmon_stats, +@@ -2853,6 +2859,7 @@ static const struct ethtool_ops airoha_e + .get_link = ethtool_op_get_link, }; +#if defined(CONFIG_PCS_AIROHA) static struct phylink_pcs *airoha_phylink_mac_select_pcs(struct phylink_config *config, phy_interface_t interface) { -@@ -2819,6 +2826,7 @@ static void airoha_mac_config(struct phy +@@ -2866,6 +2873,7 @@ static void airoha_mac_config(struct phy const struct phylink_link_state *state) { } @@ -73,7 +73,7 @@ Signed-off-by: Mikhail Kshevetskiy static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port) { -@@ -2864,6 +2872,7 @@ bool airoha_is_valid_gdm_port(struct air +@@ -2911,6 +2919,7 @@ bool airoha_is_valid_gdm_port(struct air return false; } @@ -81,7 +81,7 @@ Signed-off-by: Mikhail Kshevetskiy static void airoha_mac_link_up(struct phylink_config *config, struct phy_device *phy, unsigned int mode, phy_interface_t interface, int speed, int duplex, bool tx_pause, bool rx_pause) -@@ -2956,6 +2965,7 @@ static int airoha_setup_phylink(struct n +@@ -3003,6 +3012,7 @@ static int airoha_setup_phylink(struct n return 0; } @@ -89,7 +89,7 @@ Signed-off-by: Mikhail Kshevetskiy static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np, int index) -@@ -3035,11 +3045,13 @@ static int airoha_alloc_gdm_port(struct +@@ -3082,11 +3092,13 @@ static int airoha_alloc_gdm_port(struct if (err) return err; @@ -103,7 +103,7 @@ Signed-off-by: Mikhail Kshevetskiy err = register_netdev(dev); if (err) -@@ -3144,10 +3156,12 @@ error_hw_cleanup: +@@ -3202,10 +3214,12 @@ error_hw_cleanup: if (port && port->dev->reg_state == NETREG_REGISTERED) { unregister_netdev(port->dev); airoha_metadata_dst_free(port); @@ -116,7 +116,7 @@ Signed-off-by: Mikhail Kshevetskiy } } free_netdev(eth->napi_dev); -@@ -3175,10 +3189,12 @@ static void airoha_remove(struct platfor +@@ -3233,10 +3247,12 @@ static void airoha_remove(struct platfor airoha_dev_stop(port->dev); unregister_netdev(port->dev); airoha_metadata_dst_free(port); @@ -131,7 +131,7 @@ Signed-off-by: Mikhail Kshevetskiy --- a/drivers/net/ethernet/airoha/airoha_eth.h +++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -528,9 +528,11 @@ struct airoha_gdm_port { +@@ -531,9 +531,11 @@ struct airoha_gdm_port { struct net_device *dev; int id;