Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: airoha: Reset PPE cpu port configuration in airoha_ppe_hw_init()

Before this patch, the PPE cpu port configuration used for a specific GDM
device was set just running ndo_init() callback during the device
initialization. The selected PPE cpu port configuration depends on the QDMA
block assigned to the GDM port. The QDMA block is selected according to
the GDM port LAN/WAN configuration as specified in the commit
'8737d7194d6d ("net: airoha: select QDMA block according LAN/WAN
configuration"). However, the user selected PPE cpu port configuration can
be different with respect to the one hardcoded in the NPU firmware binary.
The hardcoded NPU PPE cpu port configuration is loaded initializing the PPE
engine running the NPU ops ppe_init() callback in airoha_ppe_offload_setup
routine (this is executed at runtime by the netfilter flowtable
infrastructure during flow offloading).
Reset the PPE cpu port configuration in airoha_ppe_hw_init routine in
order to apply the user requested setup according to the device DTS.
Please note this patch is fixing an issue not visible to the user (so we
do not need to backport it) since airoha_eth driver currently supports just
the internal phy available via the MT7530 DSA switch and there are no WAN
interfaces officially supported since PCS/external phy is not merged
mainline yet (it will be posted with following patches).

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260317-airoha-fix-ppe-def-cpu-v1-1-338533d8e234@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Lorenzo Bianconi and committed by
Jakub Kicinski
f44218cd 6b5f4917

+33 -27
+6 -22
drivers/net/ethernet/airoha/airoha_eth.c
··· 1755 1755 { 1756 1756 struct airoha_gdm_port *port = netdev_priv(dev); 1757 1757 struct airoha_eth *eth = port->eth; 1758 - u32 fe_cpu_port; 1759 - u8 ppe_id; 1758 + int i; 1760 1759 1761 1760 /* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */ 1762 1761 port->qdma = &eth->qdma[!airoha_is_lan_gdm_port(port)]; ··· 1773 1774 if (err) 1774 1775 return err; 1775 1776 } 1776 - fallthrough; 1777 - case AIROHA_GDM2_IDX: 1778 - if (airoha_ppe_is_enabled(eth, 1)) { 1779 - /* For PPE2 always use secondary cpu port. */ 1780 - fe_cpu_port = FE_PSE_PORT_CDM2; 1781 - ppe_id = 1; 1782 - break; 1783 - } 1784 - fallthrough; 1785 - default: { 1786 - u8 qdma_id = port->qdma - &eth->qdma[0]; 1787 - 1788 - /* For PPE1 select cpu port according to the running QDMA. */ 1789 - fe_cpu_port = qdma_id ? FE_PSE_PORT_CDM2 : FE_PSE_PORT_CDM1; 1790 - ppe_id = 0; 1777 + break; 1778 + default: 1791 1779 break; 1792 1780 } 1793 - } 1794 1781 1795 - airoha_fe_rmw(eth, REG_PPE_DFT_CPORT0(ppe_id), 1796 - DFT_CPORT_MASK(port->id), 1797 - __field_prep(DFT_CPORT_MASK(port->id), fe_cpu_port)); 1782 + for (i = 0; i < eth->soc->num_ppe; i++) 1783 + airoha_ppe_set_cpu_port(port, i); 1798 1784 1799 1785 return 0; 1800 1786 } ··· 1882 1898 #endif 1883 1899 } 1884 1900 1885 - static int airoha_get_fe_port(struct airoha_gdm_port *port) 1901 + int airoha_get_fe_port(struct airoha_gdm_port *port) 1886 1902 { 1887 1903 struct airoha_qdma *qdma = port->qdma; 1888 1904 struct airoha_eth *eth = qdma->eth;
+2
drivers/net/ethernet/airoha/airoha_eth.h
··· 646 646 return eth->soc->version == 0x7583; 647 647 } 648 648 649 + int airoha_get_fe_port(struct airoha_gdm_port *port); 649 650 bool airoha_is_valid_gdm_port(struct airoha_eth *eth, 650 651 struct airoha_gdm_port *port); 651 652 653 + void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id); 652 654 bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index); 653 655 void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb, 654 656 u16 hash, bool rx_wlan);
+22 -1
drivers/net/ethernet/airoha/airoha_ppe.c
··· 85 85 return FIELD_GET(AIROHA_FOE_IB1_BIND_TIMESTAMP, timestamp); 86 86 } 87 87 88 + void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id) 89 + { 90 + struct airoha_qdma *qdma = port->qdma; 91 + u8 fport = airoha_get_fe_port(port); 92 + struct airoha_eth *eth = qdma->eth; 93 + u8 qdma_id = qdma - &eth->qdma[0]; 94 + u32 fe_cpu_port; 95 + 96 + fe_cpu_port = qdma_id ? FE_PSE_PORT_CDM2 : FE_PSE_PORT_CDM1; 97 + airoha_fe_rmw(eth, REG_PPE_DFT_CPORT(ppe_id, fport), 98 + DFT_CPORT_MASK(fport), 99 + __field_prep(DFT_CPORT_MASK(fport), fe_cpu_port)); 100 + } 101 + 88 102 static void airoha_ppe_hw_init(struct airoha_ppe *ppe) 89 103 { 90 104 u32 sram_ppe_num_data_entries = PPE_SRAM_NUM_ENTRIES, sram_num_entries; ··· 161 147 162 148 airoha_fe_wr(eth, REG_PPE_HASH_SEED(i), PPE_HASH_SEED); 163 149 164 - for (p = 0; p < ARRAY_SIZE(eth->ports); p++) 150 + for (p = 0; p < ARRAY_SIZE(eth->ports); p++) { 151 + struct airoha_gdm_port *port = eth->ports[p]; 152 + 165 153 airoha_fe_rmw(eth, REG_PPE_MTU(i, p), 166 154 FP0_EGRESS_MTU_MASK | 167 155 FP1_EGRESS_MTU_MASK, ··· 171 155 AIROHA_MAX_MTU) | 172 156 FIELD_PREP(FP1_EGRESS_MTU_MASK, 173 157 AIROHA_MAX_MTU)); 158 + if (!port) 159 + continue; 160 + 161 + airoha_ppe_set_cpu_port(port, i); 162 + } 174 163 } 175 164 } 176 165
+3 -4
drivers/net/ethernet/airoha/airoha_regs.h
··· 312 312 #define REG_PPE_HASH_SEED(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x244) 313 313 #define PPE_HASH_SEED 0x12345678 314 314 315 - #define REG_PPE_DFT_CPORT0(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x248) 316 - #define DFT_CPORT_MASK(_n) GENMASK(3 + ((_n) << 2), ((_n) << 2)) 317 - 318 - #define REG_PPE_DFT_CPORT1(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x24c) 315 + #define REG_PPE_DFT_CPORT_BASE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x248) 316 + #define REG_PPE_DFT_CPORT(_m, _n) (REG_PPE_DFT_CPORT_BASE(_m) + (((_n) / 8) << 2)) 317 + #define DFT_CPORT_MASK(_n) GENMASK(3 + (((_n) % 8) << 2), (((_n) % 8) << 2)) 319 318 320 319 #define REG_PPE_TB_HASH_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x250) 321 320 #define PPE_DRAM_HASH1_MODE_MASK GENMASK(31, 28)