|
| 1 | +From df8e1e4a2eb5f8ecdef36c502601e8afbc6ad891 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Lorenzo Bianconi <lorenzo@kernel.org> |
| 3 | +Date: Wed, 24 Dec 2025 17:29:33 +0100 |
| 4 | +Subject: [PATCH] net: airoha: Reset PPE default cput port in |
| 5 | + airoha_ppe_hw_init() |
| 6 | + |
| 7 | +Before this patch the default PPE cpu port used for a specific GDM |
| 8 | +device was set running ndo_init() callback during device initialization. |
| 9 | +The selected PPE cpu port configured for the specific GDM device depends |
| 10 | +on the QDMA block assigned to the GDM device. The selected QDMA block |
| 11 | +depends on LAN/WAN configuration as specified in commmit XXXX. |
| 12 | +However, the user selected PPE cpu port can be different with respect to |
| 13 | +the one hardcoded in the NPU firmware binary. The hardcoded PPE cput port |
| 14 | +value is loaded initializing the PPE engine running npu ops ppe_init() |
| 15 | +callback in airoha_ppe_offload_setup routine. |
| 16 | +Reset the default value for PPE cpu ports in airoha_ppe_hw_init routine |
| 17 | +in order to apply the user requested configuration according to the device |
| 18 | +DTS setup. |
| 19 | +Please note this patch is fixing an issue not visible to the user (so we |
| 20 | +do not need to backport it) since airoha_eth driver currently supports just |
| 21 | +the internal phy available via the MT7530 DSA switch and there are no WAN |
| 22 | +interfaces officially supporte since PCS/external phy is not merged mainline |
| 23 | +yet (it will be posted with following patches). |
| 24 | + |
| 25 | +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> |
| 26 | +--- |
| 27 | + drivers/net/ethernet/airoha/airoha_eth.c | 28 +++++------------------ |
| 28 | + drivers/net/ethernet/airoha/airoha_eth.h | 2 ++ |
| 29 | + drivers/net/ethernet/airoha/airoha_ppe.c | 23 ++++++++++++++++++- |
| 30 | + drivers/net/ethernet/airoha/airoha_regs.h | 7 +++--- |
| 31 | + 4 files changed, 33 insertions(+), 27 deletions(-) |
| 32 | + |
| 33 | +--- a/drivers/net/ethernet/airoha/airoha_eth.c |
| 34 | ++++ b/drivers/net/ethernet/airoha/airoha_eth.c |
| 35 | +@@ -1755,8 +1755,7 @@ static int airoha_dev_init(struct net_de |
| 36 | + { |
| 37 | + struct airoha_gdm_port *port = netdev_priv(dev); |
| 38 | + struct airoha_eth *eth = port->eth; |
| 39 | +- u32 fe_cpu_port; |
| 40 | +- u8 ppe_id; |
| 41 | ++ int i; |
| 42 | + |
| 43 | + /* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */ |
| 44 | + port->qdma = ð->qdma[!airoha_is_lan_gdm_port(port)]; |
| 45 | +@@ -1774,28 +1773,13 @@ static int airoha_dev_init(struct net_de |
| 46 | + if (err) |
| 47 | + return err; |
| 48 | + } |
| 49 | +- fallthrough; |
| 50 | +- case AIROHA_GDM2_IDX: |
| 51 | +- if (airoha_ppe_is_enabled(eth, 1)) { |
| 52 | +- /* For PPE2 always use secondary cpu port. */ |
| 53 | +- fe_cpu_port = FE_PSE_PORT_CDM2; |
| 54 | +- ppe_id = 1; |
| 55 | +- break; |
| 56 | +- } |
| 57 | +- fallthrough; |
| 58 | +- default: { |
| 59 | +- u8 qdma_id = port->qdma - ð->qdma[0]; |
| 60 | +- |
| 61 | +- /* For PPE1 select cpu port according to the running QDMA. */ |
| 62 | +- fe_cpu_port = qdma_id ? FE_PSE_PORT_CDM2 : FE_PSE_PORT_CDM1; |
| 63 | +- ppe_id = 0; |
| 64 | + break; |
| 65 | +- } |
| 66 | ++ default: |
| 67 | ++ break; |
| 68 | + } |
| 69 | + |
| 70 | +- airoha_fe_rmw(eth, REG_PPE_DFT_CPORT0(ppe_id), |
| 71 | +- DFT_CPORT_MASK(port->id), |
| 72 | +- __field_prep(DFT_CPORT_MASK(port->id), fe_cpu_port)); |
| 73 | ++ for (i = 0; i < eth->soc->num_ppe; i++) |
| 74 | ++ airoha_ppe_set_cpu_port(port, i); |
| 75 | + |
| 76 | + return 0; |
| 77 | + } |
| 78 | +@@ -1898,7 +1882,7 @@ static u32 airoha_get_dsa_tag(struct sk_ |
| 79 | + #endif |
| 80 | + } |
| 81 | + |
| 82 | +-static int airoha_get_fe_port(struct airoha_gdm_port *port) |
| 83 | ++int airoha_get_fe_port(struct airoha_gdm_port *port) |
| 84 | + { |
| 85 | + struct airoha_qdma *qdma = port->qdma; |
| 86 | + struct airoha_eth *eth = qdma->eth; |
| 87 | +--- a/drivers/net/ethernet/airoha/airoha_eth.h |
| 88 | ++++ b/drivers/net/ethernet/airoha/airoha_eth.h |
| 89 | +@@ -646,9 +646,11 @@ static inline bool airoha_is_7583(struct |
| 90 | + return eth->soc->version == 0x7583; |
| 91 | + } |
| 92 | + |
| 93 | ++int airoha_get_fe_port(struct airoha_gdm_port *port); |
| 94 | + bool airoha_is_valid_gdm_port(struct airoha_eth *eth, |
| 95 | + struct airoha_gdm_port *port); |
| 96 | + |
| 97 | ++void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id); |
| 98 | + bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index); |
| 99 | + void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb, |
| 100 | + u16 hash, bool rx_wlan); |
| 101 | +--- a/drivers/net/ethernet/airoha/airoha_ppe.c |
| 102 | ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c |
| 103 | +@@ -85,6 +85,20 @@ static u32 airoha_ppe_get_timestamp(stru |
| 104 | + return FIELD_GET(AIROHA_FOE_IB1_BIND_TIMESTAMP, timestamp); |
| 105 | + } |
| 106 | + |
| 107 | ++void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id) |
| 108 | ++{ |
| 109 | ++ struct airoha_qdma *qdma = port->qdma; |
| 110 | ++ u8 fport = airoha_get_fe_port(port); |
| 111 | ++ struct airoha_eth *eth = qdma->eth; |
| 112 | ++ u8 qdma_id = qdma - ð->qdma[0]; |
| 113 | ++ u32 fe_cpu_port; |
| 114 | ++ |
| 115 | ++ fe_cpu_port = qdma_id ? FE_PSE_PORT_CDM2 : FE_PSE_PORT_CDM1; |
| 116 | ++ airoha_fe_rmw(eth, REG_PPE_DFT_CPORT(ppe_id, fport), |
| 117 | ++ DFT_CPORT_MASK(fport), |
| 118 | ++ __field_prep(DFT_CPORT_MASK(fport), fe_cpu_port)); |
| 119 | ++} |
| 120 | ++ |
| 121 | + static void airoha_ppe_hw_init(struct airoha_ppe *ppe) |
| 122 | + { |
| 123 | + u32 sram_ppe_num_data_entries = PPE_SRAM_NUM_ENTRIES, sram_num_entries; |
| 124 | +@@ -147,7 +161,9 @@ static void airoha_ppe_hw_init(struct ai |
| 125 | + |
| 126 | + airoha_fe_wr(eth, REG_PPE_HASH_SEED(i), PPE_HASH_SEED); |
| 127 | + |
| 128 | +- for (p = 0; p < ARRAY_SIZE(eth->ports); p++) |
| 129 | ++ for (p = 0; p < ARRAY_SIZE(eth->ports); p++) { |
| 130 | ++ struct airoha_gdm_port *port = eth->ports[p]; |
| 131 | ++ |
| 132 | + airoha_fe_rmw(eth, REG_PPE_MTU(i, p), |
| 133 | + FP0_EGRESS_MTU_MASK | |
| 134 | + FP1_EGRESS_MTU_MASK, |
| 135 | +@@ -155,6 +171,11 @@ static void airoha_ppe_hw_init(struct ai |
| 136 | + AIROHA_MAX_MTU) | |
| 137 | + FIELD_PREP(FP1_EGRESS_MTU_MASK, |
| 138 | + AIROHA_MAX_MTU)); |
| 139 | ++ if (!port) |
| 140 | ++ continue; |
| 141 | ++ |
| 142 | ++ airoha_ppe_set_cpu_port(port, i); |
| 143 | ++ } |
| 144 | + } |
| 145 | + } |
| 146 | + |
| 147 | +--- a/drivers/net/ethernet/airoha/airoha_regs.h |
| 148 | ++++ b/drivers/net/ethernet/airoha/airoha_regs.h |
| 149 | +@@ -312,10 +312,9 @@ |
| 150 | + #define REG_PPE_HASH_SEED(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x244) |
| 151 | + #define PPE_HASH_SEED 0x12345678 |
| 152 | + |
| 153 | +-#define REG_PPE_DFT_CPORT0(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x248) |
| 154 | +-#define DFT_CPORT_MASK(_n) GENMASK(3 + ((_n) << 2), ((_n) << 2)) |
| 155 | +- |
| 156 | +-#define REG_PPE_DFT_CPORT1(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x24c) |
| 157 | ++#define REG_PPE_DFT_CPORT_BASE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x248) |
| 158 | ++#define REG_PPE_DFT_CPORT(_m, _n) (REG_PPE_DFT_CPORT_BASE(_m) + (((_n) / 8) << 2)) |
| 159 | ++#define DFT_CPORT_MASK(_n) GENMASK(3 + (((_n) % 8) << 2), (((_n) % 8) << 2)) |
| 160 | + |
| 161 | + #define REG_PPE_TB_HASH_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x250) |
| 162 | + #define PPE_DRAM_HASH1_MODE_MASK GENMASK(31, 28) |
0 commit comments