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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'introduce-flowtable-hw-offloading-in-airoha_eth-driver'

Lorenzo Bianconi says:

====================
Introduce flowtable hw offloading in airoha_eth driver

Introduce netfilter flowtable integration in airoha_eth driver to
offload 5-tuple flower rules learned by the PPE module if the user
accelerates them using a nft configuration similar to the one reported
below:

table inet filter {
flowtable ft {
hook ingress priority filter
devices = { lan1, lan2, lan3, lan4, eth1 }
flags offload;
}
chain forward {
type filter hook forward priority filter; policy accept;
meta l4proto { tcp, udp } flow add @ft
}
}

Packet Processor Engine (PPE) module available on EN7581 SoC populates
the PPE table with 5-tuples flower rules learned from traffic forwarded
between the GDM ports connected to the Packet Switch Engine (PSE) module.
airoha_eth driver configures and collects data from the PPE module via a
Network Processor Unit (NPU) RISC-V module available on the EN7581 SoC.
Move airoha_eth driver in a dedicated folder
(drivers/net/ethernet/airoha).

v7: https://lore.kernel.org/r/20250224-airoha-en7581-flowtable-offload-v7-0-b4a22ad8364e@kernel.org
v6: https://lore.kernel.org/r/20250221-airoha-en7581-flowtable-offload-v6-0-d593af0e9487@kernel.org
v5: https://lore.kernel.org/r/20250217-airoha-en7581-flowtable-offload-v5-0-28be901cb735@kernel.org
v4: https://lore.kernel.org/r/20250213-airoha-en7581-flowtable-offload-v4-0-b69ca16d74db@kernel.org
v3: https://lore.kernel.org/r/20250209-airoha-en7581-flowtable-offload-v3-0-dba60e755563@kernel.org
v2: https://lore.kernel.org/r/20250207-airoha-en7581-flowtable-offload-v2-0-3a2239692a67@kernel.org
v1: https://lore.kernel.org/r/20250205-airoha-en7581-flowtable-offload-v1-0-d362cfa97b01@kernel.org
====================

Link: https://patch.msgid.link/20250228-airoha-en7581-flowtable-offload-v8-0-01dc1653f46e@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+3423 -1001
+10
Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
··· 63 63 "#size-cells": 64 64 const: 0 65 65 66 + airoha,npu: 67 + $ref: /schemas/types.yaml#/definitions/phandle 68 + description: 69 + Phandle to the node used to configure the NPU module. 70 + The Airoha Network Processor Unit (NPU) provides a configuration 71 + interface to implement hardware flow offloading programming Packet 72 + Processor Engine (PPE) flow table. 73 + 66 74 patternProperties: 67 75 "^ethernet@[1-4]$": 68 76 type: object ··· 139 131 <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>, 140 132 <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>, 141 133 <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; 134 + 135 + airoha,npu = <&npu>; 142 136 143 137 #address-cells = <1>; 144 138 #size-cells = <0>;
+84
Documentation/devicetree/bindings/net/airoha,en7581-npu.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/net/airoha,en7581-npu.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Airoha Network Processor Unit for EN7581 SoC 8 + 9 + maintainers: 10 + - Lorenzo Bianconi <lorenzo@kernel.org> 11 + 12 + description: 13 + The Airoha Network Processor Unit (NPU) provides a configuration interface 14 + to implement wired and wireless hardware flow offloading programming Packet 15 + Processor Engine (PPE) flow table. 16 + 17 + properties: 18 + compatible: 19 + enum: 20 + - airoha,en7581-npu 21 + 22 + reg: 23 + maxItems: 1 24 + 25 + interrupts: 26 + items: 27 + - description: mbox host irq line 28 + - description: watchdog0 irq line 29 + - description: watchdog1 irq line 30 + - description: watchdog2 irq line 31 + - description: watchdog3 irq line 32 + - description: watchdog4 irq line 33 + - description: watchdog5 irq line 34 + - description: watchdog6 irq line 35 + - description: watchdog7 irq line 36 + - description: wlan irq line0 37 + - description: wlan irq line1 38 + - description: wlan irq line2 39 + - description: wlan irq line3 40 + - description: wlan irq line4 41 + - description: wlan irq line5 42 + 43 + memory-region: 44 + maxItems: 1 45 + description: 46 + Memory used to store NPU firmware binary. 47 + 48 + required: 49 + - compatible 50 + - reg 51 + - interrupts 52 + - memory-region 53 + 54 + additionalProperties: false 55 + 56 + examples: 57 + - | 58 + #include <dt-bindings/interrupt-controller/arm-gic.h> 59 + #include <dt-bindings/interrupt-controller/irq.h> 60 + soc { 61 + #address-cells = <2>; 62 + #size-cells = <2>; 63 + 64 + npu@1e900000 { 65 + compatible = "airoha,en7581-npu"; 66 + reg = <0 0x1e900000 0 0x313000>; 67 + interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>, 68 + <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>, 69 + <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>, 70 + <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>, 71 + <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>, 72 + <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>, 73 + <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>, 74 + <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, 75 + <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>, 76 + <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, 77 + <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>, 78 + <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>, 79 + <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>, 80 + <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>, 81 + <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>; 82 + memory-region = <&npu_binary>; 83 + }; 84 + };
+5
drivers/net/dsa/mt7530.c
··· 2586 2586 /* Allow mirroring frames received on the local port (monitor port). */ 2587 2587 mt7530_set(priv, MT753X_AGC, LOCAL_EN); 2588 2588 2589 + /* Enable Special Tag for rx frames */ 2590 + if (priv->id == ID_EN7581) 2591 + mt7530_write(priv, MT753X_CPORT_SPTAG_CFG, 2592 + CPORT_SW2FE_STAG_EN | CPORT_FE2SW_STAG_EN); 2593 + 2589 2594 /* Flush the FDB table */ 2590 2595 ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL); 2591 2596 if (ret < 0)
+4
drivers/net/dsa/mt7530.h
··· 627 627 #define MT7531_GPIO12_RG_RXD3_MASK GENMASK(19, 16) 628 628 #define MT7531_EXT_P_MDIO_12 (2 << 16) 629 629 630 + #define MT753X_CPORT_SPTAG_CFG 0x7c10 631 + #define CPORT_SW2FE_STAG_EN BIT(1) 632 + #define CPORT_FE2SW_STAG_EN BIT(0) 633 + 630 634 /* Registers for LED GPIO control (MT7530 only) 631 635 * All registers follow this pattern: 632 636 * [ 2: 0] port 0
+2
drivers/net/ethernet/Kconfig
··· 20 20 source "drivers/net/ethernet/adaptec/Kconfig" 21 21 source "drivers/net/ethernet/aeroflex/Kconfig" 22 22 source "drivers/net/ethernet/agere/Kconfig" 23 + source "drivers/net/ethernet/airoha/Kconfig" 24 + source "drivers/net/ethernet/mellanox/Kconfig" 23 25 source "drivers/net/ethernet/alacritech/Kconfig" 24 26 source "drivers/net/ethernet/allwinner/Kconfig" 25 27 source "drivers/net/ethernet/alteon/Kconfig"
+1
drivers/net/ethernet/Makefile
··· 10 10 obj-$(CONFIG_GRETH) += aeroflex/ 11 11 obj-$(CONFIG_NET_VENDOR_ADI) += adi/ 12 12 obj-$(CONFIG_NET_VENDOR_AGERE) += agere/ 13 + obj-$(CONFIG_NET_VENDOR_AIROHA) += airoha/ 13 14 obj-$(CONFIG_NET_VENDOR_ALACRITECH) += alacritech/ 14 15 obj-$(CONFIG_NET_VENDOR_ALLWINNER) += allwinner/ 15 16 obj-$(CONFIG_NET_VENDOR_ALTEON) += alteon/
+27
drivers/net/ethernet/airoha/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + config NET_VENDOR_AIROHA 3 + bool "Airoha devices" 4 + depends on ARCH_AIROHA || COMPILE_TEST 5 + help 6 + If you have a Airoha SoC with ethernet, say Y. 7 + 8 + if NET_VENDOR_AIROHA 9 + 10 + config NET_AIROHA_NPU 11 + tristate "Airoha NPU support" 12 + select WANT_DEV_COREDUMP 13 + select REGMAP_MMIO 14 + help 15 + This driver supports Airoha Network Processor (NPU) available 16 + on the Airoha Soc family. 17 + 18 + config NET_AIROHA 19 + tristate "Airoha SoC Gigabit Ethernet support" 20 + depends on NET_DSA || !NET_DSA 21 + select NET_AIROHA_NPU 22 + select PAGE_POOL 23 + help 24 + This driver supports the gigabit ethernet MACs in the 25 + Airoha SoC family. 26 + 27 + endif #NET_VENDOR_AIROHA
+9
drivers/net/ethernet/airoha/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + # 3 + # Airoha for the Mediatek SoCs built-in ethernet macs 4 + # 5 + 6 + obj-$(CONFIG_NET_AIROHA) += airoha-eth.o 7 + airoha-eth-y := airoha_eth.o airoha_ppe.o 8 + airoha-eth-$(CONFIG_DEBUG_FS) += airoha_ppe_debugfs.o 9 + obj-$(CONFIG_NET_AIROHA_NPU) += airoha_npu.o
+551
drivers/net/ethernet/airoha/airoha_eth.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (c) 2024 AIROHA Inc 4 + * Author: Lorenzo Bianconi <lorenzo@kernel.org> 5 + */ 6 + 7 + #ifndef AIROHA_ETH_H 8 + #define AIROHA_ETH_H 9 + 10 + #include <linux/debugfs.h> 11 + #include <linux/etherdevice.h> 12 + #include <linux/iopoll.h> 13 + #include <linux/kernel.h> 14 + #include <linux/netdevice.h> 15 + #include <linux/reset.h> 16 + #include <net/dsa.h> 17 + 18 + #define AIROHA_MAX_NUM_GDM_PORTS 4 19 + #define AIROHA_MAX_NUM_QDMA 2 20 + #define AIROHA_MAX_DSA_PORTS 7 21 + #define AIROHA_MAX_NUM_RSTS 3 22 + #define AIROHA_MAX_NUM_XSI_RSTS 5 23 + #define AIROHA_MAX_MTU 2000 24 + #define AIROHA_MAX_PACKET_SIZE 2048 25 + #define AIROHA_NUM_QOS_CHANNELS 4 26 + #define AIROHA_NUM_QOS_QUEUES 8 27 + #define AIROHA_NUM_TX_RING 32 28 + #define AIROHA_NUM_RX_RING 32 29 + #define AIROHA_NUM_NETDEV_TX_RINGS (AIROHA_NUM_TX_RING + \ 30 + AIROHA_NUM_QOS_CHANNELS) 31 + #define AIROHA_FE_MC_MAX_VLAN_TABLE 64 32 + #define AIROHA_FE_MC_MAX_VLAN_PORT 16 33 + #define AIROHA_NUM_TX_IRQ 2 34 + #define HW_DSCP_NUM 2048 35 + #define IRQ_QUEUE_LEN(_n) ((_n) ? 1024 : 2048) 36 + #define TX_DSCP_NUM 1024 37 + #define RX_DSCP_NUM(_n) \ 38 + ((_n) == 2 ? 128 : \ 39 + (_n) == 11 ? 128 : \ 40 + (_n) == 15 ? 128 : \ 41 + (_n) == 0 ? 1024 : 16) 42 + 43 + #define PSE_RSV_PAGES 128 44 + #define PSE_QUEUE_RSV_PAGES 64 45 + 46 + #define QDMA_METER_IDX(_n) ((_n) & 0xff) 47 + #define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3) 48 + 49 + #define PPE_NUM 2 50 + #define PPE1_SRAM_NUM_ENTRIES (8 * 1024) 51 + #define PPE_SRAM_NUM_ENTRIES (2 * PPE1_SRAM_NUM_ENTRIES) 52 + #define PPE_DRAM_NUM_ENTRIES (16 * 1024) 53 + #define PPE_NUM_ENTRIES (PPE_SRAM_NUM_ENTRIES + PPE_DRAM_NUM_ENTRIES) 54 + #define PPE_HASH_MASK (PPE_NUM_ENTRIES - 1) 55 + #define PPE_ENTRY_SIZE 80 56 + #define PPE_RAM_NUM_ENTRIES_SHIFT(_n) (__ffs((_n) >> 10)) 57 + 58 + #define MTK_HDR_LEN 4 59 + #define MTK_HDR_XMIT_TAGGED_TPID_8100 1 60 + #define MTK_HDR_XMIT_TAGGED_TPID_88A8 2 61 + 62 + enum { 63 + QDMA_INT_REG_IDX0, 64 + QDMA_INT_REG_IDX1, 65 + QDMA_INT_REG_IDX2, 66 + QDMA_INT_REG_IDX3, 67 + QDMA_INT_REG_IDX4, 68 + QDMA_INT_REG_MAX 69 + }; 70 + 71 + enum { 72 + HSGMII_LAN_PCIE0_SRCPORT = 0x16, 73 + HSGMII_LAN_PCIE1_SRCPORT, 74 + HSGMII_LAN_ETH_SRCPORT, 75 + HSGMII_LAN_USB_SRCPORT, 76 + }; 77 + 78 + enum { 79 + XSI_PCIE0_VIP_PORT_MASK = BIT(22), 80 + XSI_PCIE1_VIP_PORT_MASK = BIT(23), 81 + XSI_USB_VIP_PORT_MASK = BIT(25), 82 + XSI_ETH_VIP_PORT_MASK = BIT(24), 83 + }; 84 + 85 + enum { 86 + DEV_STATE_INITIALIZED, 87 + }; 88 + 89 + enum { 90 + CDM_CRSN_QSEL_Q1 = 1, 91 + CDM_CRSN_QSEL_Q5 = 5, 92 + CDM_CRSN_QSEL_Q6 = 6, 93 + CDM_CRSN_QSEL_Q15 = 15, 94 + }; 95 + 96 + enum { 97 + CRSN_08 = 0x8, 98 + CRSN_21 = 0x15, /* KA */ 99 + CRSN_22 = 0x16, /* hit bind and force route to CPU */ 100 + CRSN_24 = 0x18, 101 + CRSN_25 = 0x19, 102 + }; 103 + 104 + enum { 105 + FE_PSE_PORT_CDM1, 106 + FE_PSE_PORT_GDM1, 107 + FE_PSE_PORT_GDM2, 108 + FE_PSE_PORT_GDM3, 109 + FE_PSE_PORT_PPE1, 110 + FE_PSE_PORT_CDM2, 111 + FE_PSE_PORT_CDM3, 112 + FE_PSE_PORT_CDM4, 113 + FE_PSE_PORT_PPE2, 114 + FE_PSE_PORT_GDM4, 115 + FE_PSE_PORT_CDM5, 116 + FE_PSE_PORT_DROP = 0xf, 117 + }; 118 + 119 + enum tx_sched_mode { 120 + TC_SCH_WRR8, 121 + TC_SCH_SP, 122 + TC_SCH_WRR7, 123 + TC_SCH_WRR6, 124 + TC_SCH_WRR5, 125 + TC_SCH_WRR4, 126 + TC_SCH_WRR3, 127 + TC_SCH_WRR2, 128 + }; 129 + 130 + enum trtcm_param_type { 131 + TRTCM_MISC_MODE, /* meter_en, pps_mode, tick_sel */ 132 + TRTCM_TOKEN_RATE_MODE, 133 + TRTCM_BUCKETSIZE_SHIFT_MODE, 134 + TRTCM_BUCKET_COUNTER_MODE, 135 + }; 136 + 137 + enum trtcm_mode_type { 138 + TRTCM_COMMIT_MODE, 139 + TRTCM_PEAK_MODE, 140 + }; 141 + 142 + enum trtcm_param { 143 + TRTCM_TICK_SEL = BIT(0), 144 + TRTCM_PKT_MODE = BIT(1), 145 + TRTCM_METER_MODE = BIT(2), 146 + }; 147 + 148 + #define MIN_TOKEN_SIZE 4096 149 + #define MAX_TOKEN_SIZE_OFFSET 17 150 + #define TRTCM_TOKEN_RATE_MASK GENMASK(23, 6) 151 + #define TRTCM_TOKEN_RATE_FRACTION_MASK GENMASK(5, 0) 152 + 153 + struct airoha_queue_entry { 154 + union { 155 + void *buf; 156 + struct sk_buff *skb; 157 + }; 158 + dma_addr_t dma_addr; 159 + u16 dma_len; 160 + }; 161 + 162 + struct airoha_queue { 163 + struct airoha_qdma *qdma; 164 + 165 + /* protect concurrent queue accesses */ 166 + spinlock_t lock; 167 + struct airoha_queue_entry *entry; 168 + struct airoha_qdma_desc *desc; 169 + u16 head; 170 + u16 tail; 171 + 172 + int queued; 173 + int ndesc; 174 + int free_thr; 175 + int buf_size; 176 + 177 + struct napi_struct napi; 178 + struct page_pool *page_pool; 179 + }; 180 + 181 + struct airoha_tx_irq_queue { 182 + struct airoha_qdma *qdma; 183 + 184 + struct napi_struct napi; 185 + 186 + int size; 187 + u32 *q; 188 + }; 189 + 190 + struct airoha_hw_stats { 191 + /* protect concurrent hw_stats accesses */ 192 + spinlock_t lock; 193 + struct u64_stats_sync syncp; 194 + 195 + /* get_stats64 */ 196 + u64 rx_ok_pkts; 197 + u64 tx_ok_pkts; 198 + u64 rx_ok_bytes; 199 + u64 tx_ok_bytes; 200 + u64 rx_multicast; 201 + u64 rx_errors; 202 + u64 rx_drops; 203 + u64 tx_drops; 204 + u64 rx_crc_error; 205 + u64 rx_over_errors; 206 + /* ethtool stats */ 207 + u64 tx_broadcast; 208 + u64 tx_multicast; 209 + u64 tx_len[7]; 210 + u64 rx_broadcast; 211 + u64 rx_fragment; 212 + u64 rx_jabber; 213 + u64 rx_len[7]; 214 + }; 215 + 216 + enum { 217 + PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED = 0x0f, 218 + }; 219 + 220 + enum { 221 + AIROHA_FOE_STATE_INVALID, 222 + AIROHA_FOE_STATE_UNBIND, 223 + AIROHA_FOE_STATE_BIND, 224 + AIROHA_FOE_STATE_FIN 225 + }; 226 + 227 + enum { 228 + PPE_PKT_TYPE_IPV4_HNAPT = 0, 229 + PPE_PKT_TYPE_IPV4_ROUTE = 1, 230 + PPE_PKT_TYPE_BRIDGE = 2, 231 + PPE_PKT_TYPE_IPV4_DSLITE = 3, 232 + PPE_PKT_TYPE_IPV6_ROUTE_3T = 4, 233 + PPE_PKT_TYPE_IPV6_ROUTE_5T = 5, 234 + PPE_PKT_TYPE_IPV6_6RD = 7, 235 + }; 236 + 237 + #define AIROHA_FOE_MAC_SMAC_ID GENMASK(20, 16) 238 + #define AIROHA_FOE_MAC_PPPOE_ID GENMASK(15, 0) 239 + 240 + struct airoha_foe_mac_info_common { 241 + u16 vlan1; 242 + u16 etype; 243 + 244 + u32 dest_mac_hi; 245 + 246 + u16 vlan2; 247 + u16 dest_mac_lo; 248 + 249 + u32 src_mac_hi; 250 + }; 251 + 252 + struct airoha_foe_mac_info { 253 + struct airoha_foe_mac_info_common common; 254 + 255 + u16 pppoe_id; 256 + u16 src_mac_lo; 257 + }; 258 + 259 + #define AIROHA_FOE_IB1_UNBIND_PREBIND BIT(24) 260 + #define AIROHA_FOE_IB1_UNBIND_PACKETS GENMASK(23, 8) 261 + #define AIROHA_FOE_IB1_UNBIND_TIMESTAMP GENMASK(7, 0) 262 + 263 + #define AIROHA_FOE_IB1_BIND_STATIC BIT(31) 264 + #define AIROHA_FOE_IB1_BIND_UDP BIT(30) 265 + #define AIROHA_FOE_IB1_BIND_STATE GENMASK(29, 28) 266 + #define AIROHA_FOE_IB1_BIND_PACKET_TYPE GENMASK(27, 25) 267 + #define AIROHA_FOE_IB1_BIND_TTL BIT(24) 268 + #define AIROHA_FOE_IB1_BIND_TUNNEL_DECAP BIT(23) 269 + #define AIROHA_FOE_IB1_BIND_PPPOE BIT(22) 270 + #define AIROHA_FOE_IB1_BIND_VPM GENMASK(21, 20) 271 + #define AIROHA_FOE_IB1_BIND_VLAN_LAYER GENMASK(19, 16) 272 + #define AIROHA_FOE_IB1_BIND_KEEPALIVE BIT(15) 273 + #define AIROHA_FOE_IB1_BIND_TIMESTAMP GENMASK(14, 0) 274 + 275 + #define AIROHA_FOE_IB2_DSCP GENMASK(31, 24) 276 + #define AIROHA_FOE_IB2_PORT_AG GENMASK(23, 13) 277 + #define AIROHA_FOE_IB2_PCP BIT(12) 278 + #define AIROHA_FOE_IB2_MULTICAST BIT(11) 279 + #define AIROHA_FOE_IB2_FAST_PATH BIT(10) 280 + #define AIROHA_FOE_IB2_PSE_QOS BIT(9) 281 + #define AIROHA_FOE_IB2_PSE_PORT GENMASK(8, 5) 282 + #define AIROHA_FOE_IB2_NBQ GENMASK(4, 0) 283 + 284 + #define AIROHA_FOE_ACTDP GENMASK(31, 24) 285 + #define AIROHA_FOE_SHAPER_ID GENMASK(23, 16) 286 + #define AIROHA_FOE_CHANNEL GENMASK(15, 11) 287 + #define AIROHA_FOE_QID GENMASK(10, 8) 288 + #define AIROHA_FOE_DPI BIT(7) 289 + #define AIROHA_FOE_TUNNEL BIT(6) 290 + #define AIROHA_FOE_TUNNEL_ID GENMASK(5, 0) 291 + 292 + struct airoha_foe_bridge { 293 + u32 dest_mac_hi; 294 + 295 + u16 src_mac_hi; 296 + u16 dest_mac_lo; 297 + 298 + u32 src_mac_lo; 299 + 300 + u32 ib2; 301 + 302 + u32 rsv[5]; 303 + 304 + u32 data; 305 + 306 + struct airoha_foe_mac_info l2; 307 + }; 308 + 309 + struct airoha_foe_ipv4_tuple { 310 + u32 src_ip; 311 + u32 dest_ip; 312 + union { 313 + struct { 314 + u16 dest_port; 315 + u16 src_port; 316 + }; 317 + struct { 318 + u8 protocol; 319 + u8 _pad[3]; /* fill with 0xa5a5a5 */ 320 + }; 321 + u32 ports; 322 + }; 323 + }; 324 + 325 + struct airoha_foe_ipv4 { 326 + struct airoha_foe_ipv4_tuple orig_tuple; 327 + 328 + u32 ib2; 329 + 330 + struct airoha_foe_ipv4_tuple new_tuple; 331 + 332 + u32 rsv[2]; 333 + 334 + u32 data; 335 + 336 + struct airoha_foe_mac_info l2; 337 + }; 338 + 339 + struct airoha_foe_ipv4_dslite { 340 + struct airoha_foe_ipv4_tuple ip4; 341 + 342 + u32 ib2; 343 + 344 + u8 flow_label[3]; 345 + u8 priority; 346 + 347 + u32 rsv[4]; 348 + 349 + u32 data; 350 + 351 + struct airoha_foe_mac_info l2; 352 + }; 353 + 354 + struct airoha_foe_ipv6 { 355 + u32 src_ip[4]; 356 + u32 dest_ip[4]; 357 + 358 + union { 359 + struct { 360 + u16 dest_port; 361 + u16 src_port; 362 + }; 363 + struct { 364 + u8 protocol; 365 + u8 pad[3]; 366 + }; 367 + u32 ports; 368 + }; 369 + 370 + u32 data; 371 + 372 + u32 ib2; 373 + 374 + struct airoha_foe_mac_info_common l2; 375 + }; 376 + 377 + struct airoha_foe_entry { 378 + union { 379 + struct { 380 + u32 ib1; 381 + union { 382 + struct airoha_foe_bridge bridge; 383 + struct airoha_foe_ipv4 ipv4; 384 + struct airoha_foe_ipv4_dslite dslite; 385 + struct airoha_foe_ipv6 ipv6; 386 + DECLARE_FLEX_ARRAY(u32, d); 387 + }; 388 + }; 389 + u8 data[PPE_ENTRY_SIZE]; 390 + }; 391 + }; 392 + 393 + struct airoha_flow_data { 394 + struct ethhdr eth; 395 + 396 + union { 397 + struct { 398 + __be32 src_addr; 399 + __be32 dst_addr; 400 + } v4; 401 + 402 + struct { 403 + struct in6_addr src_addr; 404 + struct in6_addr dst_addr; 405 + } v6; 406 + }; 407 + 408 + __be16 src_port; 409 + __be16 dst_port; 410 + 411 + struct { 412 + struct { 413 + u16 id; 414 + __be16 proto; 415 + } hdr[2]; 416 + u8 num; 417 + } vlan; 418 + struct { 419 + u16 sid; 420 + u8 num; 421 + } pppoe; 422 + }; 423 + 424 + struct airoha_flow_table_entry { 425 + struct hlist_node list; 426 + 427 + struct airoha_foe_entry data; 428 + u32 hash; 429 + 430 + struct rhash_head node; 431 + unsigned long cookie; 432 + }; 433 + 434 + struct airoha_qdma { 435 + struct airoha_eth *eth; 436 + void __iomem *regs; 437 + 438 + /* protect concurrent irqmask accesses */ 439 + spinlock_t irq_lock; 440 + u32 irqmask[QDMA_INT_REG_MAX]; 441 + int irq; 442 + 443 + atomic_t users; 444 + 445 + struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ]; 446 + 447 + struct airoha_queue q_tx[AIROHA_NUM_TX_RING]; 448 + struct airoha_queue q_rx[AIROHA_NUM_RX_RING]; 449 + 450 + /* descriptor and packet buffers for qdma hw forward */ 451 + struct { 452 + void *desc; 453 + void *q; 454 + } hfwd; 455 + }; 456 + 457 + struct airoha_gdm_port { 458 + struct airoha_qdma *qdma; 459 + struct net_device *dev; 460 + int id; 461 + 462 + struct airoha_hw_stats stats; 463 + 464 + DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS); 465 + 466 + /* qos stats counters */ 467 + u64 cpu_tx_packets; 468 + u64 fwd_tx_packets; 469 + 470 + struct metadata_dst *dsa_meta[AIROHA_MAX_DSA_PORTS]; 471 + }; 472 + 473 + #define AIROHA_RXD4_PPE_CPU_REASON GENMASK(20, 16) 474 + #define AIROHA_RXD4_FOE_ENTRY GENMASK(15, 0) 475 + 476 + struct airoha_ppe { 477 + struct airoha_eth *eth; 478 + 479 + void *foe; 480 + dma_addr_t foe_dma; 481 + 482 + struct hlist_head *foe_flow; 483 + u16 foe_check_time[PPE_NUM_ENTRIES]; 484 + 485 + struct dentry *debugfs_dir; 486 + }; 487 + 488 + struct airoha_eth { 489 + struct device *dev; 490 + 491 + unsigned long state; 492 + void __iomem *fe_regs; 493 + 494 + struct airoha_npu __rcu *npu; 495 + 496 + struct airoha_ppe *ppe; 497 + struct rhashtable flow_table; 498 + 499 + struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS]; 500 + struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS]; 501 + 502 + struct net_device *napi_dev; 503 + 504 + struct airoha_qdma qdma[AIROHA_MAX_NUM_QDMA]; 505 + struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS]; 506 + }; 507 + 508 + u32 airoha_rr(void __iomem *base, u32 offset); 509 + void airoha_wr(void __iomem *base, u32 offset, u32 val); 510 + u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val); 511 + 512 + #define airoha_fe_rr(eth, offset) \ 513 + airoha_rr((eth)->fe_regs, (offset)) 514 + #define airoha_fe_wr(eth, offset, val) \ 515 + airoha_wr((eth)->fe_regs, (offset), (val)) 516 + #define airoha_fe_rmw(eth, offset, mask, val) \ 517 + airoha_rmw((eth)->fe_regs, (offset), (mask), (val)) 518 + #define airoha_fe_set(eth, offset, val) \ 519 + airoha_rmw((eth)->fe_regs, (offset), 0, (val)) 520 + #define airoha_fe_clear(eth, offset, val) \ 521 + airoha_rmw((eth)->fe_regs, (offset), (val), 0) 522 + 523 + #define airoha_qdma_rr(qdma, offset) \ 524 + airoha_rr((qdma)->regs, (offset)) 525 + #define airoha_qdma_wr(qdma, offset, val) \ 526 + airoha_wr((qdma)->regs, (offset), (val)) 527 + #define airoha_qdma_rmw(qdma, offset, mask, val) \ 528 + airoha_rmw((qdma)->regs, (offset), (mask), (val)) 529 + #define airoha_qdma_set(qdma, offset, val) \ 530 + airoha_rmw((qdma)->regs, (offset), 0, (val)) 531 + #define airoha_qdma_clear(qdma, offset, val) \ 532 + airoha_rmw((qdma)->regs, (offset), (val), 0) 533 + 534 + void airoha_ppe_check_skb(struct airoha_ppe *ppe, u16 hash); 535 + int airoha_ppe_setup_tc_block_cb(enum tc_setup_type type, void *type_data, 536 + void *cb_priv); 537 + int airoha_ppe_init(struct airoha_eth *eth); 538 + void airoha_ppe_deinit(struct airoha_eth *eth); 539 + struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, 540 + u32 hash); 541 + 542 + #if CONFIG_DEBUG_FS 543 + int airoha_ppe_debugfs_init(struct airoha_ppe *ppe); 544 + #else 545 + static inline int airoha_ppe_debugfs_init(struct airoha_ppe *ppe) 546 + { 547 + return 0; 548 + } 549 + #endif 550 + 551 + #endif /* AIROHA_ETH_H */
+520
drivers/net/ethernet/airoha/airoha_npu.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2025 AIROHA Inc 4 + * Author: Lorenzo Bianconi <lorenzo@kernel.org> 5 + */ 6 + 7 + #include <linux/devcoredump.h> 8 + #include <linux/firmware.h> 9 + #include <linux/platform_device.h> 10 + #include <linux/of_net.h> 11 + #include <linux/of_platform.h> 12 + #include <linux/of_reserved_mem.h> 13 + #include <linux/regmap.h> 14 + 15 + #include "airoha_npu.h" 16 + 17 + #define NPU_EN7581_FIRMWARE_DATA "airoha/en7581_npu_data.bin" 18 + #define NPU_EN7581_FIRMWARE_RV32 "airoha/en7581_npu_rv32.bin" 19 + #define NPU_EN7581_FIRMWARE_RV32_MAX_SIZE 0x200000 20 + #define NPU_EN7581_FIRMWARE_DATA_MAX_SIZE 0x10000 21 + #define NPU_DUMP_SIZE 512 22 + 23 + #define REG_NPU_LOCAL_SRAM 0x0 24 + 25 + #define NPU_PC_BASE_ADDR 0x305000 26 + #define REG_PC_DBG(_n) (0x305000 + ((_n) * 0x100)) 27 + 28 + #define NPU_CLUSTER_BASE_ADDR 0x306000 29 + 30 + #define REG_CR_BOOT_TRIGGER (NPU_CLUSTER_BASE_ADDR + 0x000) 31 + #define REG_CR_BOOT_CONFIG (NPU_CLUSTER_BASE_ADDR + 0x004) 32 + #define REG_CR_BOOT_BASE(_n) (NPU_CLUSTER_BASE_ADDR + 0x020 + ((_n) << 2)) 33 + 34 + #define NPU_MBOX_BASE_ADDR 0x30c000 35 + 36 + #define REG_CR_MBOX_INT_STATUS (NPU_MBOX_BASE_ADDR + 0x000) 37 + #define MBOX_INT_STATUS_MASK BIT(8) 38 + 39 + #define REG_CR_MBOX_INT_MASK(_n) (NPU_MBOX_BASE_ADDR + 0x004 + ((_n) << 2)) 40 + #define REG_CR_MBQ0_CTRL(_n) (NPU_MBOX_BASE_ADDR + 0x030 + ((_n) << 2)) 41 + #define REG_CR_MBQ8_CTRL(_n) (NPU_MBOX_BASE_ADDR + 0x0b0 + ((_n) << 2)) 42 + #define REG_CR_NPU_MIB(_n) (NPU_MBOX_BASE_ADDR + 0x140 + ((_n) << 2)) 43 + 44 + #define NPU_TIMER_BASE_ADDR 0x310100 45 + #define REG_WDT_TIMER_CTRL(_n) (NPU_TIMER_BASE_ADDR + ((_n) * 0x100)) 46 + #define WDT_EN_MASK BIT(25) 47 + #define WDT_INTR_MASK BIT(21) 48 + 49 + enum { 50 + NPU_OP_SET = 1, 51 + NPU_OP_SET_NO_WAIT, 52 + NPU_OP_GET, 53 + NPU_OP_GET_NO_WAIT, 54 + }; 55 + 56 + enum { 57 + NPU_FUNC_WIFI, 58 + NPU_FUNC_TUNNEL, 59 + NPU_FUNC_NOTIFY, 60 + NPU_FUNC_DBA, 61 + NPU_FUNC_TR471, 62 + NPU_FUNC_PPE, 63 + }; 64 + 65 + enum { 66 + NPU_MBOX_ERROR, 67 + NPU_MBOX_SUCCESS, 68 + }; 69 + 70 + enum { 71 + PPE_FUNC_SET_WAIT, 72 + PPE_FUNC_SET_WAIT_HWNAT_INIT, 73 + PPE_FUNC_SET_WAIT_HWNAT_DEINIT, 74 + PPE_FUNC_SET_WAIT_API, 75 + }; 76 + 77 + enum { 78 + PPE2_SRAM_SET_ENTRY, 79 + PPE_SRAM_SET_ENTRY, 80 + PPE_SRAM_SET_VAL, 81 + PPE_SRAM_RESET_VAL, 82 + }; 83 + 84 + enum { 85 + QDMA_WAN_ETHER = 1, 86 + QDMA_WAN_PON_XDSL, 87 + }; 88 + 89 + #define MBOX_MSG_FUNC_ID GENMASK(14, 11) 90 + #define MBOX_MSG_STATIC_BUF BIT(5) 91 + #define MBOX_MSG_STATUS GENMASK(4, 2) 92 + #define MBOX_MSG_DONE BIT(1) 93 + #define MBOX_MSG_WAIT_RSP BIT(0) 94 + 95 + #define PPE_TYPE_L2B_IPV4 2 96 + #define PPE_TYPE_L2B_IPV4_IPV6 3 97 + 98 + struct ppe_mbox_data { 99 + u32 func_type; 100 + u32 func_id; 101 + union { 102 + struct { 103 + u8 cds; 104 + u8 xpon_hal_api; 105 + u8 wan_xsi; 106 + u8 ct_joyme4; 107 + int ppe_type; 108 + int wan_mode; 109 + int wan_sel; 110 + } init_info; 111 + struct { 112 + int func_id; 113 + u32 size; 114 + u32 data; 115 + } set_info; 116 + }; 117 + }; 118 + 119 + static int airoha_npu_send_msg(struct airoha_npu *npu, int func_id, 120 + void *p, int size) 121 + { 122 + u16 core = 0; /* FIXME */ 123 + u32 val, offset = core << 4; 124 + dma_addr_t dma_addr; 125 + void *addr; 126 + int ret; 127 + 128 + addr = kmemdup(p, size, GFP_ATOMIC); 129 + if (!addr) 130 + return -ENOMEM; 131 + 132 + dma_addr = dma_map_single(npu->dev, addr, size, DMA_TO_DEVICE); 133 + ret = dma_mapping_error(npu->dev, dma_addr); 134 + if (ret) 135 + goto out; 136 + 137 + spin_lock_bh(&npu->cores[core].lock); 138 + 139 + regmap_write(npu->regmap, REG_CR_MBQ0_CTRL(0) + offset, dma_addr); 140 + regmap_write(npu->regmap, REG_CR_MBQ0_CTRL(1) + offset, size); 141 + regmap_read(npu->regmap, REG_CR_MBQ0_CTRL(2) + offset, &val); 142 + regmap_write(npu->regmap, REG_CR_MBQ0_CTRL(2) + offset, val + 1); 143 + val = FIELD_PREP(MBOX_MSG_FUNC_ID, func_id) | MBOX_MSG_WAIT_RSP; 144 + regmap_write(npu->regmap, REG_CR_MBQ0_CTRL(3) + offset, val); 145 + 146 + ret = regmap_read_poll_timeout_atomic(npu->regmap, 147 + REG_CR_MBQ0_CTRL(3) + offset, 148 + val, (val & MBOX_MSG_DONE), 149 + 100, 100 * MSEC_PER_SEC); 150 + if (!ret && FIELD_GET(MBOX_MSG_STATUS, val) != NPU_MBOX_SUCCESS) 151 + ret = -EINVAL; 152 + 153 + spin_unlock_bh(&npu->cores[core].lock); 154 + 155 + dma_unmap_single(npu->dev, dma_addr, size, DMA_TO_DEVICE); 156 + out: 157 + kfree(addr); 158 + 159 + return ret; 160 + } 161 + 162 + static int airoha_npu_run_firmware(struct device *dev, void __iomem *base, 163 + struct reserved_mem *rmem) 164 + { 165 + const struct firmware *fw; 166 + void __iomem *addr; 167 + int ret; 168 + 169 + ret = request_firmware(&fw, NPU_EN7581_FIRMWARE_RV32, dev); 170 + if (ret) 171 + return ret == -ENOENT ? -EPROBE_DEFER : ret; 172 + 173 + if (fw->size > NPU_EN7581_FIRMWARE_RV32_MAX_SIZE) { 174 + dev_err(dev, "%s: fw size too overlimit (%zu)\n", 175 + NPU_EN7581_FIRMWARE_RV32, fw->size); 176 + ret = -E2BIG; 177 + goto out; 178 + } 179 + 180 + addr = devm_ioremap(dev, rmem->base, rmem->size); 181 + if (!addr) { 182 + ret = -ENOMEM; 183 + goto out; 184 + } 185 + 186 + memcpy_toio(addr, fw->data, fw->size); 187 + release_firmware(fw); 188 + 189 + ret = request_firmware(&fw, NPU_EN7581_FIRMWARE_DATA, dev); 190 + if (ret) 191 + return ret == -ENOENT ? -EPROBE_DEFER : ret; 192 + 193 + if (fw->size > NPU_EN7581_FIRMWARE_DATA_MAX_SIZE) { 194 + dev_err(dev, "%s: fw size too overlimit (%zu)\n", 195 + NPU_EN7581_FIRMWARE_DATA, fw->size); 196 + ret = -E2BIG; 197 + goto out; 198 + } 199 + 200 + memcpy_toio(base + REG_NPU_LOCAL_SRAM, fw->data, fw->size); 201 + out: 202 + release_firmware(fw); 203 + 204 + return ret; 205 + } 206 + 207 + static irqreturn_t airoha_npu_mbox_handler(int irq, void *npu_instance) 208 + { 209 + struct airoha_npu *npu = npu_instance; 210 + 211 + /* clear mbox interrupt status */ 212 + regmap_write(npu->regmap, REG_CR_MBOX_INT_STATUS, 213 + MBOX_INT_STATUS_MASK); 214 + 215 + /* acknowledge npu */ 216 + regmap_update_bits(npu->regmap, REG_CR_MBQ8_CTRL(3), 217 + MBOX_MSG_STATUS | MBOX_MSG_DONE, MBOX_MSG_DONE); 218 + 219 + return IRQ_HANDLED; 220 + } 221 + 222 + static void airoha_npu_wdt_work(struct work_struct *work) 223 + { 224 + struct airoha_npu_core *core; 225 + struct airoha_npu *npu; 226 + void *dump; 227 + u32 val[3]; 228 + int c; 229 + 230 + core = container_of(work, struct airoha_npu_core, wdt_work); 231 + npu = core->npu; 232 + 233 + dump = vzalloc(NPU_DUMP_SIZE); 234 + if (!dump) 235 + return; 236 + 237 + c = core - &npu->cores[0]; 238 + regmap_bulk_read(npu->regmap, REG_PC_DBG(c), val, ARRAY_SIZE(val)); 239 + snprintf(dump, NPU_DUMP_SIZE, "PC: %08x SP: %08x LR: %08x\n", 240 + val[0], val[1], val[2]); 241 + 242 + dev_coredumpv(npu->dev, dump, NPU_DUMP_SIZE, GFP_KERNEL); 243 + } 244 + 245 + static irqreturn_t airoha_npu_wdt_handler(int irq, void *core_instance) 246 + { 247 + struct airoha_npu_core *core = core_instance; 248 + struct airoha_npu *npu = core->npu; 249 + int c = core - &npu->cores[0]; 250 + u32 val; 251 + 252 + regmap_set_bits(npu->regmap, REG_WDT_TIMER_CTRL(c), WDT_INTR_MASK); 253 + if (!regmap_read(npu->regmap, REG_WDT_TIMER_CTRL(c), &val) && 254 + FIELD_GET(WDT_EN_MASK, val)) 255 + schedule_work(&core->wdt_work); 256 + 257 + return IRQ_HANDLED; 258 + } 259 + 260 + static int airoha_npu_ppe_init(struct airoha_npu *npu) 261 + { 262 + struct ppe_mbox_data ppe_data = { 263 + .func_type = NPU_OP_SET, 264 + .func_id = PPE_FUNC_SET_WAIT_HWNAT_INIT, 265 + .init_info = { 266 + .ppe_type = PPE_TYPE_L2B_IPV4_IPV6, 267 + .wan_mode = QDMA_WAN_ETHER, 268 + }, 269 + }; 270 + 271 + return airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, 272 + sizeof(struct ppe_mbox_data)); 273 + } 274 + 275 + static int airoha_npu_ppe_deinit(struct airoha_npu *npu) 276 + { 277 + struct ppe_mbox_data ppe_data = { 278 + .func_type = NPU_OP_SET, 279 + .func_id = PPE_FUNC_SET_WAIT_HWNAT_DEINIT, 280 + }; 281 + 282 + return airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, 283 + sizeof(struct ppe_mbox_data)); 284 + } 285 + 286 + static int airoha_npu_ppe_flush_sram_entries(struct airoha_npu *npu, 287 + dma_addr_t foe_addr, 288 + int sram_num_entries) 289 + { 290 + struct ppe_mbox_data ppe_data = { 291 + .func_type = NPU_OP_SET, 292 + .func_id = PPE_FUNC_SET_WAIT_API, 293 + .set_info = { 294 + .func_id = PPE_SRAM_RESET_VAL, 295 + .data = foe_addr, 296 + .size = sram_num_entries, 297 + }, 298 + }; 299 + 300 + return airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, 301 + sizeof(struct ppe_mbox_data)); 302 + } 303 + 304 + static int airoha_npu_foe_commit_entry(struct airoha_npu *npu, 305 + dma_addr_t foe_addr, 306 + u32 entry_size, u32 hash, bool ppe2) 307 + { 308 + struct ppe_mbox_data ppe_data = { 309 + .func_type = NPU_OP_SET, 310 + .func_id = PPE_FUNC_SET_WAIT_API, 311 + .set_info = { 312 + .data = foe_addr, 313 + .size = entry_size, 314 + }, 315 + }; 316 + int err; 317 + 318 + ppe_data.set_info.func_id = ppe2 ? PPE2_SRAM_SET_ENTRY 319 + : PPE_SRAM_SET_ENTRY; 320 + 321 + err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, 322 + sizeof(struct ppe_mbox_data)); 323 + if (err) 324 + return err; 325 + 326 + ppe_data.set_info.func_id = PPE_SRAM_SET_VAL; 327 + ppe_data.set_info.data = hash; 328 + ppe_data.set_info.size = sizeof(u32); 329 + 330 + return airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, 331 + sizeof(struct ppe_mbox_data)); 332 + } 333 + 334 + struct airoha_npu *airoha_npu_get(struct device *dev) 335 + { 336 + struct platform_device *pdev; 337 + struct device_node *np; 338 + struct airoha_npu *npu; 339 + 340 + np = of_parse_phandle(dev->of_node, "airoha,npu", 0); 341 + if (!np) 342 + return ERR_PTR(-ENODEV); 343 + 344 + pdev = of_find_device_by_node(np); 345 + of_node_put(np); 346 + 347 + if (!pdev) { 348 + dev_err(dev, "cannot find device node %s\n", np->name); 349 + return ERR_PTR(-ENODEV); 350 + } 351 + 352 + if (!try_module_get(THIS_MODULE)) { 353 + dev_err(dev, "failed to get the device driver module\n"); 354 + npu = ERR_PTR(-ENODEV); 355 + goto error_pdev_put; 356 + } 357 + 358 + npu = platform_get_drvdata(pdev); 359 + if (!npu) { 360 + npu = ERR_PTR(-ENODEV); 361 + goto error_module_put; 362 + } 363 + 364 + if (!device_link_add(dev, &pdev->dev, DL_FLAG_AUTOREMOVE_SUPPLIER)) { 365 + dev_err(&pdev->dev, 366 + "failed to create device link to consumer %s\n", 367 + dev_name(dev)); 368 + npu = ERR_PTR(-EINVAL); 369 + goto error_module_put; 370 + } 371 + 372 + return npu; 373 + 374 + error_module_put: 375 + module_put(THIS_MODULE); 376 + error_pdev_put: 377 + platform_device_put(pdev); 378 + 379 + return npu; 380 + } 381 + EXPORT_SYMBOL_GPL(airoha_npu_get); 382 + 383 + void airoha_npu_put(struct airoha_npu *npu) 384 + { 385 + module_put(THIS_MODULE); 386 + put_device(npu->dev); 387 + } 388 + EXPORT_SYMBOL_GPL(airoha_npu_put); 389 + 390 + static const struct of_device_id of_airoha_npu_match[] = { 391 + { .compatible = "airoha,en7581-npu" }, 392 + { /* sentinel */ } 393 + }; 394 + MODULE_DEVICE_TABLE(of, of_airoha_npu_match); 395 + 396 + static const struct regmap_config regmap_config = { 397 + .name = "npu", 398 + .reg_bits = 32, 399 + .val_bits = 32, 400 + .reg_stride = 4, 401 + .disable_locking = true, 402 + }; 403 + 404 + static int airoha_npu_probe(struct platform_device *pdev) 405 + { 406 + struct device *dev = &pdev->dev; 407 + struct reserved_mem *rmem; 408 + struct airoha_npu *npu; 409 + struct device_node *np; 410 + void __iomem *base; 411 + int i, irq, err; 412 + 413 + base = devm_platform_ioremap_resource(pdev, 0); 414 + if (IS_ERR(base)) 415 + return PTR_ERR(base); 416 + 417 + npu = devm_kzalloc(dev, sizeof(*npu), GFP_KERNEL); 418 + if (!npu) 419 + return -ENOMEM; 420 + 421 + npu->dev = dev; 422 + npu->ops.ppe_init = airoha_npu_ppe_init; 423 + npu->ops.ppe_deinit = airoha_npu_ppe_deinit; 424 + npu->ops.ppe_flush_sram_entries = airoha_npu_ppe_flush_sram_entries; 425 + npu->ops.ppe_foe_commit_entry = airoha_npu_foe_commit_entry; 426 + 427 + npu->regmap = devm_regmap_init_mmio(dev, base, &regmap_config); 428 + if (IS_ERR(npu->regmap)) 429 + return PTR_ERR(npu->regmap); 430 + 431 + np = of_parse_phandle(dev->of_node, "memory-region", 0); 432 + if (!np) 433 + return -ENODEV; 434 + 435 + rmem = of_reserved_mem_lookup(np); 436 + of_node_put(np); 437 + 438 + if (!rmem) 439 + return -ENODEV; 440 + 441 + irq = platform_get_irq(pdev, 0); 442 + if (irq < 0) 443 + return irq; 444 + 445 + err = devm_request_irq(dev, irq, airoha_npu_mbox_handler, 446 + IRQF_SHARED, "airoha-npu-mbox", npu); 447 + if (err) 448 + return err; 449 + 450 + for (i = 0; i < ARRAY_SIZE(npu->cores); i++) { 451 + struct airoha_npu_core *core = &npu->cores[i]; 452 + 453 + spin_lock_init(&core->lock); 454 + core->npu = npu; 455 + 456 + irq = platform_get_irq(pdev, i + 1); 457 + if (irq < 0) 458 + return irq; 459 + 460 + err = devm_request_irq(dev, irq, airoha_npu_wdt_handler, 461 + IRQF_SHARED, "airoha-npu-wdt", core); 462 + if (err) 463 + return err; 464 + 465 + INIT_WORK(&core->wdt_work, airoha_npu_wdt_work); 466 + } 467 + 468 + err = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); 469 + if (err) 470 + return err; 471 + 472 + err = airoha_npu_run_firmware(dev, base, rmem); 473 + if (err) 474 + return dev_err_probe(dev, err, "failed to run npu firmware\n"); 475 + 476 + regmap_write(npu->regmap, REG_CR_NPU_MIB(10), 477 + rmem->base + NPU_EN7581_FIRMWARE_RV32_MAX_SIZE); 478 + regmap_write(npu->regmap, REG_CR_NPU_MIB(11), 0x40000); /* SRAM 256K */ 479 + regmap_write(npu->regmap, REG_CR_NPU_MIB(12), 0); 480 + regmap_write(npu->regmap, REG_CR_NPU_MIB(21), 1); 481 + msleep(100); 482 + 483 + /* setting booting address */ 484 + for (i = 0; i < NPU_NUM_CORES; i++) 485 + regmap_write(npu->regmap, REG_CR_BOOT_BASE(i), rmem->base); 486 + usleep_range(1000, 2000); 487 + 488 + /* enable NPU cores */ 489 + /* do not start core3 since it is used for WiFi offloading */ 490 + regmap_write(npu->regmap, REG_CR_BOOT_CONFIG, 0xf7); 491 + regmap_write(npu->regmap, REG_CR_BOOT_TRIGGER, 0x1); 492 + msleep(100); 493 + 494 + platform_set_drvdata(pdev, npu); 495 + 496 + return 0; 497 + } 498 + 499 + static void airoha_npu_remove(struct platform_device *pdev) 500 + { 501 + struct airoha_npu *npu = platform_get_drvdata(pdev); 502 + int i; 503 + 504 + for (i = 0; i < ARRAY_SIZE(npu->cores); i++) 505 + cancel_work_sync(&npu->cores[i].wdt_work); 506 + } 507 + 508 + static struct platform_driver airoha_npu_driver = { 509 + .probe = airoha_npu_probe, 510 + .remove = airoha_npu_remove, 511 + .driver = { 512 + .name = "airoha-npu", 513 + .of_match_table = of_airoha_npu_match, 514 + }, 515 + }; 516 + module_platform_driver(airoha_npu_driver); 517 + 518 + MODULE_LICENSE("GPL"); 519 + MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); 520 + MODULE_DESCRIPTION("Airoha Network Processor Unit driver");
+34
drivers/net/ethernet/airoha/airoha_npu.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (c) 2025 AIROHA Inc 4 + * Author: Lorenzo Bianconi <lorenzo@kernel.org> 5 + */ 6 + 7 + #define NPU_NUM_CORES 8 8 + 9 + struct airoha_npu { 10 + struct device *dev; 11 + struct regmap *regmap; 12 + 13 + struct airoha_npu_core { 14 + struct airoha_npu *npu; 15 + /* protect concurrent npu memory accesses */ 16 + spinlock_t lock; 17 + struct work_struct wdt_work; 18 + } cores[NPU_NUM_CORES]; 19 + 20 + struct { 21 + int (*ppe_init)(struct airoha_npu *npu); 22 + int (*ppe_deinit)(struct airoha_npu *npu); 23 + int (*ppe_flush_sram_entries)(struct airoha_npu *npu, 24 + dma_addr_t foe_addr, 25 + int sram_num_entries); 26 + int (*ppe_foe_commit_entry)(struct airoha_npu *npu, 27 + dma_addr_t foe_addr, 28 + u32 entry_size, u32 hash, 29 + bool ppe2); 30 + } ops; 31 + }; 32 + 33 + struct airoha_npu *airoha_npu_get(struct device *dev); 34 + void airoha_npu_put(struct airoha_npu *npu);
+910
drivers/net/ethernet/airoha/airoha_ppe.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2025 AIROHA Inc 4 + * Author: Lorenzo Bianconi <lorenzo@kernel.org> 5 + */ 6 + 7 + #include <linux/ip.h> 8 + #include <linux/ipv6.h> 9 + #include <linux/rhashtable.h> 10 + #include <net/ipv6.h> 11 + #include <net/pkt_cls.h> 12 + 13 + #include "airoha_npu.h" 14 + #include "airoha_regs.h" 15 + #include "airoha_eth.h" 16 + 17 + static DEFINE_MUTEX(flow_offload_mutex); 18 + static DEFINE_SPINLOCK(ppe_lock); 19 + 20 + static const struct rhashtable_params airoha_flow_table_params = { 21 + .head_offset = offsetof(struct airoha_flow_table_entry, node), 22 + .key_offset = offsetof(struct airoha_flow_table_entry, cookie), 23 + .key_len = sizeof(unsigned long), 24 + .automatic_shrinking = true, 25 + }; 26 + 27 + static bool airoha_ppe2_is_enabled(struct airoha_eth *eth) 28 + { 29 + return airoha_fe_rr(eth, REG_PPE_GLO_CFG(1)) & PPE_GLO_CFG_EN_MASK; 30 + } 31 + 32 + static u32 airoha_ppe_get_timestamp(struct airoha_ppe *ppe) 33 + { 34 + u16 timestamp = airoha_fe_rr(ppe->eth, REG_FE_FOE_TS); 35 + 36 + return FIELD_GET(AIROHA_FOE_IB1_BIND_TIMESTAMP, timestamp); 37 + } 38 + 39 + static void airoha_ppe_hw_init(struct airoha_ppe *ppe) 40 + { 41 + u32 sram_tb_size, sram_num_entries, dram_num_entries; 42 + struct airoha_eth *eth = ppe->eth; 43 + int i; 44 + 45 + sram_tb_size = PPE_SRAM_NUM_ENTRIES * sizeof(struct airoha_foe_entry); 46 + dram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(PPE_DRAM_NUM_ENTRIES); 47 + 48 + for (i = 0; i < PPE_NUM; i++) { 49 + int p; 50 + 51 + airoha_fe_wr(eth, REG_PPE_TB_BASE(i), 52 + ppe->foe_dma + sram_tb_size); 53 + 54 + airoha_fe_rmw(eth, REG_PPE_BND_AGE0(i), 55 + PPE_BIND_AGE0_DELTA_NON_L4 | 56 + PPE_BIND_AGE0_DELTA_UDP, 57 + FIELD_PREP(PPE_BIND_AGE0_DELTA_NON_L4, 1) | 58 + FIELD_PREP(PPE_BIND_AGE0_DELTA_UDP, 12)); 59 + airoha_fe_rmw(eth, REG_PPE_BND_AGE1(i), 60 + PPE_BIND_AGE1_DELTA_TCP_FIN | 61 + PPE_BIND_AGE1_DELTA_TCP, 62 + FIELD_PREP(PPE_BIND_AGE1_DELTA_TCP_FIN, 1) | 63 + FIELD_PREP(PPE_BIND_AGE1_DELTA_TCP, 7)); 64 + 65 + airoha_fe_rmw(eth, REG_PPE_TB_HASH_CFG(i), 66 + PPE_SRAM_TABLE_EN_MASK | 67 + PPE_SRAM_HASH1_EN_MASK | 68 + PPE_DRAM_TABLE_EN_MASK | 69 + PPE_SRAM_HASH0_MODE_MASK | 70 + PPE_SRAM_HASH1_MODE_MASK | 71 + PPE_DRAM_HASH0_MODE_MASK | 72 + PPE_DRAM_HASH1_MODE_MASK, 73 + FIELD_PREP(PPE_SRAM_TABLE_EN_MASK, 1) | 74 + FIELD_PREP(PPE_SRAM_HASH1_EN_MASK, 1) | 75 + FIELD_PREP(PPE_SRAM_HASH1_MODE_MASK, 1) | 76 + FIELD_PREP(PPE_DRAM_HASH1_MODE_MASK, 3)); 77 + 78 + airoha_fe_rmw(eth, REG_PPE_TB_CFG(i), 79 + PPE_TB_CFG_SEARCH_MISS_MASK | 80 + PPE_TB_ENTRY_SIZE_MASK, 81 + FIELD_PREP(PPE_TB_CFG_SEARCH_MISS_MASK, 3) | 82 + FIELD_PREP(PPE_TB_ENTRY_SIZE_MASK, 0)); 83 + 84 + airoha_fe_wr(eth, REG_PPE_HASH_SEED(i), PPE_HASH_SEED); 85 + 86 + for (p = 0; p < ARRAY_SIZE(eth->ports); p++) 87 + airoha_fe_rmw(eth, REG_PPE_MTU(i, p), 88 + FP0_EGRESS_MTU_MASK | 89 + FP1_EGRESS_MTU_MASK, 90 + FIELD_PREP(FP0_EGRESS_MTU_MASK, 91 + AIROHA_MAX_MTU) | 92 + FIELD_PREP(FP1_EGRESS_MTU_MASK, 93 + AIROHA_MAX_MTU)); 94 + } 95 + 96 + if (airoha_ppe2_is_enabled(eth)) { 97 + sram_num_entries = 98 + PPE_RAM_NUM_ENTRIES_SHIFT(PPE1_SRAM_NUM_ENTRIES); 99 + airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), 100 + PPE_SRAM_TB_NUM_ENTRY_MASK | 101 + PPE_DRAM_TB_NUM_ENTRY_MASK, 102 + FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, 103 + sram_num_entries) | 104 + FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, 105 + dram_num_entries)); 106 + airoha_fe_rmw(eth, REG_PPE_TB_CFG(1), 107 + PPE_SRAM_TB_NUM_ENTRY_MASK | 108 + PPE_DRAM_TB_NUM_ENTRY_MASK, 109 + FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, 110 + sram_num_entries) | 111 + FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, 112 + dram_num_entries)); 113 + } else { 114 + sram_num_entries = 115 + PPE_RAM_NUM_ENTRIES_SHIFT(PPE_SRAM_NUM_ENTRIES); 116 + airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), 117 + PPE_SRAM_TB_NUM_ENTRY_MASK | 118 + PPE_DRAM_TB_NUM_ENTRY_MASK, 119 + FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, 120 + sram_num_entries) | 121 + FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, 122 + dram_num_entries)); 123 + } 124 + } 125 + 126 + static void airoha_ppe_flow_mangle_eth(const struct flow_action_entry *act, void *eth) 127 + { 128 + void *dest = eth + act->mangle.offset; 129 + const void *src = &act->mangle.val; 130 + 131 + if (act->mangle.offset > 8) 132 + return; 133 + 134 + if (act->mangle.mask == 0xffff) { 135 + src += 2; 136 + dest += 2; 137 + } 138 + 139 + memcpy(dest, src, act->mangle.mask ? 2 : 4); 140 + } 141 + 142 + static int airoha_ppe_flow_mangle_ports(const struct flow_action_entry *act, 143 + struct airoha_flow_data *data) 144 + { 145 + u32 val = be32_to_cpu((__force __be32)act->mangle.val); 146 + 147 + switch (act->mangle.offset) { 148 + case 0: 149 + if ((__force __be32)act->mangle.mask == ~cpu_to_be32(0xffff)) 150 + data->dst_port = cpu_to_be16(val); 151 + else 152 + data->src_port = cpu_to_be16(val >> 16); 153 + break; 154 + case 2: 155 + data->dst_port = cpu_to_be16(val); 156 + break; 157 + default: 158 + return -EINVAL; 159 + } 160 + 161 + return 0; 162 + } 163 + 164 + static int airoha_ppe_flow_mangle_ipv4(const struct flow_action_entry *act, 165 + struct airoha_flow_data *data) 166 + { 167 + __be32 *dest; 168 + 169 + switch (act->mangle.offset) { 170 + case offsetof(struct iphdr, saddr): 171 + dest = &data->v4.src_addr; 172 + break; 173 + case offsetof(struct iphdr, daddr): 174 + dest = &data->v4.dst_addr; 175 + break; 176 + default: 177 + return -EINVAL; 178 + } 179 + 180 + memcpy(dest, &act->mangle.val, sizeof(u32)); 181 + 182 + return 0; 183 + } 184 + 185 + static int airoha_get_dsa_port(struct net_device **dev) 186 + { 187 + #if IS_ENABLED(CONFIG_NET_DSA) 188 + struct dsa_port *dp = dsa_port_from_netdev(*dev); 189 + 190 + if (IS_ERR(dp)) 191 + return -ENODEV; 192 + 193 + *dev = dsa_port_to_conduit(dp); 194 + return dp->index; 195 + #else 196 + return -ENODEV; 197 + #endif 198 + } 199 + 200 + static int airoha_ppe_foe_entry_prepare(struct airoha_foe_entry *hwe, 201 + struct net_device *dev, int type, 202 + struct airoha_flow_data *data, 203 + int l4proto) 204 + { 205 + int dsa_port = airoha_get_dsa_port(&dev); 206 + struct airoha_foe_mac_info_common *l2; 207 + u32 qdata, ports_pad, val; 208 + 209 + memset(hwe, 0, sizeof(*hwe)); 210 + 211 + val = FIELD_PREP(AIROHA_FOE_IB1_BIND_STATE, AIROHA_FOE_STATE_BIND) | 212 + FIELD_PREP(AIROHA_FOE_IB1_BIND_PACKET_TYPE, type) | 213 + FIELD_PREP(AIROHA_FOE_IB1_BIND_UDP, l4proto == IPPROTO_UDP) | 214 + FIELD_PREP(AIROHA_FOE_IB1_BIND_VLAN_LAYER, data->vlan.num) | 215 + FIELD_PREP(AIROHA_FOE_IB1_BIND_VPM, data->vlan.num) | 216 + AIROHA_FOE_IB1_BIND_TTL; 217 + hwe->ib1 = val; 218 + 219 + val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f) | 220 + AIROHA_FOE_IB2_PSE_QOS; 221 + if (dsa_port >= 0) 222 + val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, dsa_port); 223 + 224 + if (dev) { 225 + struct airoha_gdm_port *port = netdev_priv(dev); 226 + u8 pse_port; 227 + 228 + if (dsa_port >= 0) 229 + pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; 230 + else 231 + pse_port = 2; /* uplink relies on GDM2 loopback */ 232 + val |= FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, pse_port); 233 + } 234 + 235 + if (is_multicast_ether_addr(data->eth.h_dest)) 236 + val |= AIROHA_FOE_IB2_MULTICAST; 237 + 238 + ports_pad = 0xa5a5a500 | (l4proto & 0xff); 239 + if (type == PPE_PKT_TYPE_IPV4_ROUTE) 240 + hwe->ipv4.orig_tuple.ports = ports_pad; 241 + if (type == PPE_PKT_TYPE_IPV6_ROUTE_3T) 242 + hwe->ipv6.ports = ports_pad; 243 + 244 + qdata = FIELD_PREP(AIROHA_FOE_SHAPER_ID, 0x7f); 245 + if (type == PPE_PKT_TYPE_BRIDGE) { 246 + hwe->bridge.dest_mac_hi = get_unaligned_be32(data->eth.h_dest); 247 + hwe->bridge.dest_mac_lo = 248 + get_unaligned_be16(data->eth.h_dest + 4); 249 + hwe->bridge.src_mac_hi = 250 + get_unaligned_be16(data->eth.h_source); 251 + hwe->bridge.src_mac_lo = 252 + get_unaligned_be32(data->eth.h_source + 2); 253 + hwe->bridge.data = qdata; 254 + hwe->bridge.ib2 = val; 255 + l2 = &hwe->bridge.l2.common; 256 + } else if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T) { 257 + hwe->ipv6.data = qdata; 258 + hwe->ipv6.ib2 = val; 259 + l2 = &hwe->ipv6.l2; 260 + } else { 261 + hwe->ipv4.data = qdata; 262 + hwe->ipv4.ib2 = val; 263 + l2 = &hwe->ipv4.l2.common; 264 + } 265 + 266 + l2->dest_mac_hi = get_unaligned_be32(data->eth.h_dest); 267 + l2->dest_mac_lo = get_unaligned_be16(data->eth.h_dest + 4); 268 + if (type <= PPE_PKT_TYPE_IPV4_DSLITE) { 269 + l2->src_mac_hi = get_unaligned_be32(data->eth.h_source); 270 + hwe->ipv4.l2.src_mac_lo = 271 + get_unaligned_be16(data->eth.h_source + 4); 272 + } else { 273 + l2->src_mac_hi = FIELD_PREP(AIROHA_FOE_MAC_SMAC_ID, 0xf); 274 + } 275 + 276 + if (data->vlan.num) { 277 + l2->etype = dsa_port >= 0 ? BIT(dsa_port) : 0; 278 + l2->vlan1 = data->vlan.hdr[0].id; 279 + if (data->vlan.num == 2) 280 + l2->vlan2 = data->vlan.hdr[1].id; 281 + } else if (dsa_port >= 0) { 282 + l2->etype = BIT(15) | BIT(dsa_port); 283 + } else if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T) { 284 + l2->etype = ETH_P_IPV6; 285 + } else { 286 + l2->etype = ETH_P_IP; 287 + } 288 + 289 + return 0; 290 + } 291 + 292 + static int airoha_ppe_foe_entry_set_ipv4_tuple(struct airoha_foe_entry *hwe, 293 + struct airoha_flow_data *data, 294 + bool egress) 295 + { 296 + int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); 297 + struct airoha_foe_ipv4_tuple *t; 298 + 299 + switch (type) { 300 + case PPE_PKT_TYPE_IPV4_HNAPT: 301 + if (egress) { 302 + t = &hwe->ipv4.new_tuple; 303 + break; 304 + } 305 + fallthrough; 306 + case PPE_PKT_TYPE_IPV4_DSLITE: 307 + case PPE_PKT_TYPE_IPV4_ROUTE: 308 + t = &hwe->ipv4.orig_tuple; 309 + break; 310 + default: 311 + WARN_ON_ONCE(1); 312 + return -EINVAL; 313 + } 314 + 315 + t->src_ip = be32_to_cpu(data->v4.src_addr); 316 + t->dest_ip = be32_to_cpu(data->v4.dst_addr); 317 + 318 + if (type != PPE_PKT_TYPE_IPV4_ROUTE) { 319 + t->src_port = be16_to_cpu(data->src_port); 320 + t->dest_port = be16_to_cpu(data->dst_port); 321 + } 322 + 323 + return 0; 324 + } 325 + 326 + static int airoha_ppe_foe_entry_set_ipv6_tuple(struct airoha_foe_entry *hwe, 327 + struct airoha_flow_data *data) 328 + 329 + { 330 + int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); 331 + u32 *src, *dest; 332 + 333 + switch (type) { 334 + case PPE_PKT_TYPE_IPV6_ROUTE_5T: 335 + case PPE_PKT_TYPE_IPV6_6RD: 336 + hwe->ipv6.src_port = be16_to_cpu(data->src_port); 337 + hwe->ipv6.dest_port = be16_to_cpu(data->dst_port); 338 + fallthrough; 339 + case PPE_PKT_TYPE_IPV6_ROUTE_3T: 340 + src = hwe->ipv6.src_ip; 341 + dest = hwe->ipv6.dest_ip; 342 + break; 343 + default: 344 + WARN_ON_ONCE(1); 345 + return -EINVAL; 346 + } 347 + 348 + ipv6_addr_be32_to_cpu(src, data->v6.src_addr.s6_addr32); 349 + ipv6_addr_be32_to_cpu(dest, data->v6.dst_addr.s6_addr32); 350 + 351 + return 0; 352 + } 353 + 354 + static u32 airoha_ppe_foe_get_entry_hash(struct airoha_foe_entry *hwe) 355 + { 356 + int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); 357 + u32 hash, hv1, hv2, hv3; 358 + 359 + switch (type) { 360 + case PPE_PKT_TYPE_IPV4_ROUTE: 361 + case PPE_PKT_TYPE_IPV4_HNAPT: 362 + hv1 = hwe->ipv4.orig_tuple.ports; 363 + hv2 = hwe->ipv4.orig_tuple.dest_ip; 364 + hv3 = hwe->ipv4.orig_tuple.src_ip; 365 + break; 366 + case PPE_PKT_TYPE_IPV6_ROUTE_3T: 367 + case PPE_PKT_TYPE_IPV6_ROUTE_5T: 368 + hv1 = hwe->ipv6.src_ip[3] ^ hwe->ipv6.dest_ip[3]; 369 + hv1 ^= hwe->ipv6.ports; 370 + 371 + hv2 = hwe->ipv6.src_ip[2] ^ hwe->ipv6.dest_ip[2]; 372 + hv2 ^= hwe->ipv6.dest_ip[0]; 373 + 374 + hv3 = hwe->ipv6.src_ip[1] ^ hwe->ipv6.dest_ip[1]; 375 + hv3 ^= hwe->ipv6.src_ip[0]; 376 + break; 377 + case PPE_PKT_TYPE_IPV4_DSLITE: 378 + case PPE_PKT_TYPE_IPV6_6RD: 379 + default: 380 + WARN_ON_ONCE(1); 381 + return PPE_HASH_MASK; 382 + } 383 + 384 + hash = (hv1 & hv2) | ((~hv1) & hv3); 385 + hash = (hash >> 24) | ((hash & 0xffffff) << 8); 386 + hash ^= hv1 ^ hv2 ^ hv3; 387 + hash ^= hash >> 16; 388 + hash &= PPE_NUM_ENTRIES - 1; 389 + 390 + return hash; 391 + } 392 + 393 + struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, 394 + u32 hash) 395 + { 396 + if (hash < PPE_SRAM_NUM_ENTRIES) { 397 + u32 *hwe = ppe->foe + hash * sizeof(struct airoha_foe_entry); 398 + struct airoha_eth *eth = ppe->eth; 399 + bool ppe2; 400 + u32 val; 401 + int i; 402 + 403 + ppe2 = airoha_ppe2_is_enabled(ppe->eth) && 404 + hash >= PPE1_SRAM_NUM_ENTRIES; 405 + airoha_fe_wr(ppe->eth, REG_PPE_RAM_CTRL(ppe2), 406 + FIELD_PREP(PPE_SRAM_CTRL_ENTRY_MASK, hash) | 407 + PPE_SRAM_CTRL_REQ_MASK); 408 + if (read_poll_timeout_atomic(airoha_fe_rr, val, 409 + val & PPE_SRAM_CTRL_ACK_MASK, 410 + 10, 100, false, eth, 411 + REG_PPE_RAM_CTRL(ppe2))) 412 + return NULL; 413 + 414 + for (i = 0; i < sizeof(struct airoha_foe_entry) / 4; i++) 415 + hwe[i] = airoha_fe_rr(eth, 416 + REG_PPE_RAM_ENTRY(ppe2, i)); 417 + } 418 + 419 + return ppe->foe + hash * sizeof(struct airoha_foe_entry); 420 + } 421 + 422 + static bool airoha_ppe_foe_compare_entry(struct airoha_flow_table_entry *e, 423 + struct airoha_foe_entry *hwe) 424 + { 425 + int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, e->data.ib1); 426 + int len; 427 + 428 + if ((hwe->ib1 ^ e->data.ib1) & AIROHA_FOE_IB1_BIND_UDP) 429 + return false; 430 + 431 + if (type > PPE_PKT_TYPE_IPV4_DSLITE) 432 + len = offsetof(struct airoha_foe_entry, ipv6.data); 433 + else 434 + len = offsetof(struct airoha_foe_entry, ipv4.ib2); 435 + 436 + return !memcmp(&e->data.d, &hwe->d, len - sizeof(hwe->ib1)); 437 + } 438 + 439 + static int airoha_ppe_foe_commit_entry(struct airoha_ppe *ppe, 440 + struct airoha_foe_entry *e, 441 + u32 hash) 442 + { 443 + struct airoha_foe_entry *hwe = ppe->foe + hash * sizeof(*hwe); 444 + u32 ts = airoha_ppe_get_timestamp(ppe); 445 + struct airoha_eth *eth = ppe->eth; 446 + 447 + memcpy(&hwe->d, &e->d, sizeof(*hwe) - sizeof(hwe->ib1)); 448 + wmb(); 449 + 450 + e->ib1 &= ~AIROHA_FOE_IB1_BIND_TIMESTAMP; 451 + e->ib1 |= FIELD_PREP(AIROHA_FOE_IB1_BIND_TIMESTAMP, ts); 452 + hwe->ib1 = e->ib1; 453 + 454 + if (hash < PPE_SRAM_NUM_ENTRIES) { 455 + dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe); 456 + bool ppe2 = airoha_ppe2_is_enabled(eth) && 457 + hash >= PPE1_SRAM_NUM_ENTRIES; 458 + struct airoha_npu *npu; 459 + int err = -ENODEV; 460 + 461 + rcu_read_lock(); 462 + npu = rcu_dereference(eth->npu); 463 + if (npu) 464 + err = npu->ops.ppe_foe_commit_entry(npu, addr, 465 + sizeof(*hwe), hash, 466 + ppe2); 467 + rcu_read_unlock(); 468 + 469 + return err; 470 + } 471 + 472 + return 0; 473 + } 474 + 475 + static void airoha_ppe_foe_insert_entry(struct airoha_ppe *ppe, u32 hash) 476 + { 477 + struct airoha_flow_table_entry *e; 478 + struct airoha_foe_entry *hwe; 479 + struct hlist_node *n; 480 + u32 index, state; 481 + 482 + spin_lock_bh(&ppe_lock); 483 + 484 + hwe = airoha_ppe_foe_get_entry(ppe, hash); 485 + if (!hwe) 486 + goto unlock; 487 + 488 + state = FIELD_GET(AIROHA_FOE_IB1_BIND_STATE, hwe->ib1); 489 + if (state == AIROHA_FOE_STATE_BIND) 490 + goto unlock; 491 + 492 + index = airoha_ppe_foe_get_entry_hash(hwe); 493 + hlist_for_each_entry_safe(e, n, &ppe->foe_flow[index], list) { 494 + if (airoha_ppe_foe_compare_entry(e, hwe)) { 495 + airoha_ppe_foe_commit_entry(ppe, &e->data, hash); 496 + e->hash = hash; 497 + break; 498 + } 499 + } 500 + unlock: 501 + spin_unlock_bh(&ppe_lock); 502 + } 503 + 504 + static int airoha_ppe_foe_flow_commit_entry(struct airoha_ppe *ppe, 505 + struct airoha_flow_table_entry *e) 506 + { 507 + u32 hash = airoha_ppe_foe_get_entry_hash(&e->data); 508 + 509 + e->hash = 0xffff; 510 + 511 + spin_lock_bh(&ppe_lock); 512 + hlist_add_head(&e->list, &ppe->foe_flow[hash]); 513 + spin_unlock_bh(&ppe_lock); 514 + 515 + return 0; 516 + } 517 + 518 + static void airoha_ppe_foe_flow_remove_entry(struct airoha_ppe *ppe, 519 + struct airoha_flow_table_entry *e) 520 + { 521 + spin_lock_bh(&ppe_lock); 522 + 523 + hlist_del_init(&e->list); 524 + if (e->hash != 0xffff) { 525 + e->data.ib1 &= ~AIROHA_FOE_IB1_BIND_STATE; 526 + e->data.ib1 |= FIELD_PREP(AIROHA_FOE_IB1_BIND_STATE, 527 + AIROHA_FOE_STATE_INVALID); 528 + airoha_ppe_foe_commit_entry(ppe, &e->data, e->hash); 529 + e->hash = 0xffff; 530 + } 531 + 532 + spin_unlock_bh(&ppe_lock); 533 + } 534 + 535 + static int airoha_ppe_flow_offload_replace(struct airoha_gdm_port *port, 536 + struct flow_cls_offload *f) 537 + { 538 + struct flow_rule *rule = flow_cls_offload_flow_rule(f); 539 + struct airoha_eth *eth = port->qdma->eth; 540 + struct airoha_flow_table_entry *e; 541 + struct airoha_flow_data data = {}; 542 + struct net_device *odev = NULL; 543 + struct flow_action_entry *act; 544 + struct airoha_foe_entry hwe; 545 + int err, i, offload_type; 546 + u16 addr_type = 0; 547 + u8 l4proto = 0; 548 + 549 + if (rhashtable_lookup(&eth->flow_table, &f->cookie, 550 + airoha_flow_table_params)) 551 + return -EEXIST; 552 + 553 + if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_META)) 554 + return -EOPNOTSUPP; 555 + 556 + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) { 557 + struct flow_match_control match; 558 + 559 + flow_rule_match_control(rule, &match); 560 + addr_type = match.key->addr_type; 561 + if (flow_rule_has_control_flags(match.mask->flags, 562 + f->common.extack)) 563 + return -EOPNOTSUPP; 564 + } else { 565 + return -EOPNOTSUPP; 566 + } 567 + 568 + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) { 569 + struct flow_match_basic match; 570 + 571 + flow_rule_match_basic(rule, &match); 572 + l4proto = match.key->ip_proto; 573 + } else { 574 + return -EOPNOTSUPP; 575 + } 576 + 577 + switch (addr_type) { 578 + case 0: 579 + offload_type = PPE_PKT_TYPE_BRIDGE; 580 + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) { 581 + struct flow_match_eth_addrs match; 582 + 583 + flow_rule_match_eth_addrs(rule, &match); 584 + memcpy(data.eth.h_dest, match.key->dst, ETH_ALEN); 585 + memcpy(data.eth.h_source, match.key->src, ETH_ALEN); 586 + } else { 587 + return -EOPNOTSUPP; 588 + } 589 + break; 590 + case FLOW_DISSECTOR_KEY_IPV4_ADDRS: 591 + offload_type = PPE_PKT_TYPE_IPV4_HNAPT; 592 + break; 593 + case FLOW_DISSECTOR_KEY_IPV6_ADDRS: 594 + offload_type = PPE_PKT_TYPE_IPV6_ROUTE_5T; 595 + break; 596 + default: 597 + return -EOPNOTSUPP; 598 + } 599 + 600 + flow_action_for_each(i, act, &rule->action) { 601 + switch (act->id) { 602 + case FLOW_ACTION_MANGLE: 603 + if (offload_type == PPE_PKT_TYPE_BRIDGE) 604 + return -EOPNOTSUPP; 605 + 606 + if (act->mangle.htype == FLOW_ACT_MANGLE_HDR_TYPE_ETH) 607 + airoha_ppe_flow_mangle_eth(act, &data.eth); 608 + break; 609 + case FLOW_ACTION_REDIRECT: 610 + odev = act->dev; 611 + break; 612 + case FLOW_ACTION_CSUM: 613 + break; 614 + case FLOW_ACTION_VLAN_PUSH: 615 + if (data.vlan.num == 2 || 616 + act->vlan.proto != htons(ETH_P_8021Q)) 617 + return -EOPNOTSUPP; 618 + 619 + data.vlan.hdr[data.vlan.num].id = act->vlan.vid; 620 + data.vlan.hdr[data.vlan.num].proto = act->vlan.proto; 621 + data.vlan.num++; 622 + break; 623 + case FLOW_ACTION_VLAN_POP: 624 + break; 625 + case FLOW_ACTION_PPPOE_PUSH: 626 + break; 627 + default: 628 + return -EOPNOTSUPP; 629 + } 630 + } 631 + 632 + if (!is_valid_ether_addr(data.eth.h_source) || 633 + !is_valid_ether_addr(data.eth.h_dest)) 634 + return -EINVAL; 635 + 636 + err = airoha_ppe_foe_entry_prepare(&hwe, odev, offload_type, 637 + &data, l4proto); 638 + if (err) 639 + return err; 640 + 641 + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) { 642 + struct flow_match_ports ports; 643 + 644 + if (offload_type == PPE_PKT_TYPE_BRIDGE) 645 + return -EOPNOTSUPP; 646 + 647 + flow_rule_match_ports(rule, &ports); 648 + data.src_port = ports.key->src; 649 + data.dst_port = ports.key->dst; 650 + } else if (offload_type != PPE_PKT_TYPE_BRIDGE) { 651 + return -EOPNOTSUPP; 652 + } 653 + 654 + if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) { 655 + struct flow_match_ipv4_addrs addrs; 656 + 657 + flow_rule_match_ipv4_addrs(rule, &addrs); 658 + data.v4.src_addr = addrs.key->src; 659 + data.v4.dst_addr = addrs.key->dst; 660 + airoha_ppe_foe_entry_set_ipv4_tuple(&hwe, &data, false); 661 + } 662 + 663 + if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) { 664 + struct flow_match_ipv6_addrs addrs; 665 + 666 + flow_rule_match_ipv6_addrs(rule, &addrs); 667 + 668 + data.v6.src_addr = addrs.key->src; 669 + data.v6.dst_addr = addrs.key->dst; 670 + airoha_ppe_foe_entry_set_ipv6_tuple(&hwe, &data); 671 + } 672 + 673 + flow_action_for_each(i, act, &rule->action) { 674 + if (act->id != FLOW_ACTION_MANGLE) 675 + continue; 676 + 677 + if (offload_type == PPE_PKT_TYPE_BRIDGE) 678 + return -EOPNOTSUPP; 679 + 680 + switch (act->mangle.htype) { 681 + case FLOW_ACT_MANGLE_HDR_TYPE_TCP: 682 + case FLOW_ACT_MANGLE_HDR_TYPE_UDP: 683 + err = airoha_ppe_flow_mangle_ports(act, &data); 684 + break; 685 + case FLOW_ACT_MANGLE_HDR_TYPE_IP4: 686 + err = airoha_ppe_flow_mangle_ipv4(act, &data); 687 + break; 688 + case FLOW_ACT_MANGLE_HDR_TYPE_ETH: 689 + /* handled earlier */ 690 + break; 691 + default: 692 + return -EOPNOTSUPP; 693 + } 694 + 695 + if (err) 696 + return err; 697 + } 698 + 699 + if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) { 700 + err = airoha_ppe_foe_entry_set_ipv4_tuple(&hwe, &data, true); 701 + if (err) 702 + return err; 703 + } 704 + 705 + e = kzalloc(sizeof(*e), GFP_KERNEL); 706 + if (!e) 707 + return -ENOMEM; 708 + 709 + e->cookie = f->cookie; 710 + memcpy(&e->data, &hwe, sizeof(e->data)); 711 + 712 + err = airoha_ppe_foe_flow_commit_entry(eth->ppe, e); 713 + if (err) 714 + goto free_entry; 715 + 716 + err = rhashtable_insert_fast(&eth->flow_table, &e->node, 717 + airoha_flow_table_params); 718 + if (err < 0) 719 + goto remove_foe_entry; 720 + 721 + return 0; 722 + 723 + remove_foe_entry: 724 + airoha_ppe_foe_flow_remove_entry(eth->ppe, e); 725 + free_entry: 726 + kfree(e); 727 + 728 + return err; 729 + } 730 + 731 + static int airoha_ppe_flow_offload_destroy(struct airoha_gdm_port *port, 732 + struct flow_cls_offload *f) 733 + { 734 + struct airoha_eth *eth = port->qdma->eth; 735 + struct airoha_flow_table_entry *e; 736 + 737 + e = rhashtable_lookup(&eth->flow_table, &f->cookie, 738 + airoha_flow_table_params); 739 + if (!e) 740 + return -ENOENT; 741 + 742 + airoha_ppe_foe_flow_remove_entry(eth->ppe, e); 743 + rhashtable_remove_fast(&eth->flow_table, &e->node, 744 + airoha_flow_table_params); 745 + kfree(e); 746 + 747 + return 0; 748 + } 749 + 750 + static int airoha_ppe_flow_offload_cmd(struct airoha_gdm_port *port, 751 + struct flow_cls_offload *f) 752 + { 753 + switch (f->command) { 754 + case FLOW_CLS_REPLACE: 755 + return airoha_ppe_flow_offload_replace(port, f); 756 + case FLOW_CLS_DESTROY: 757 + return airoha_ppe_flow_offload_destroy(port, f); 758 + default: 759 + break; 760 + } 761 + 762 + return -EOPNOTSUPP; 763 + } 764 + 765 + static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe, 766 + struct airoha_npu *npu) 767 + { 768 + int i, sram_num_entries = PPE_SRAM_NUM_ENTRIES; 769 + struct airoha_foe_entry *hwe = ppe->foe; 770 + 771 + if (airoha_ppe2_is_enabled(ppe->eth)) 772 + sram_num_entries = sram_num_entries / 2; 773 + 774 + for (i = 0; i < sram_num_entries; i++) 775 + memset(&hwe[i], 0, sizeof(*hwe)); 776 + 777 + return npu->ops.ppe_flush_sram_entries(npu, ppe->foe_dma, 778 + PPE_SRAM_NUM_ENTRIES); 779 + } 780 + 781 + static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth) 782 + { 783 + struct airoha_npu *npu = airoha_npu_get(eth->dev); 784 + 785 + if (IS_ERR(npu)) { 786 + request_module("airoha-npu"); 787 + npu = airoha_npu_get(eth->dev); 788 + } 789 + 790 + return npu; 791 + } 792 + 793 + static int airoha_ppe_offload_setup(struct airoha_eth *eth) 794 + { 795 + struct airoha_npu *npu = airoha_ppe_npu_get(eth); 796 + int err; 797 + 798 + if (IS_ERR(npu)) 799 + return PTR_ERR(npu); 800 + 801 + err = npu->ops.ppe_init(npu); 802 + if (err) 803 + goto error_npu_put; 804 + 805 + airoha_ppe_hw_init(eth->ppe); 806 + err = airoha_ppe_flush_sram_entries(eth->ppe, npu); 807 + if (err) 808 + goto error_npu_put; 809 + 810 + rcu_assign_pointer(eth->npu, npu); 811 + synchronize_rcu(); 812 + 813 + return 0; 814 + 815 + error_npu_put: 816 + airoha_npu_put(npu); 817 + 818 + return err; 819 + } 820 + 821 + int airoha_ppe_setup_tc_block_cb(enum tc_setup_type type, void *type_data, 822 + void *cb_priv) 823 + { 824 + struct flow_cls_offload *cls = type_data; 825 + struct net_device *dev = cb_priv; 826 + struct airoha_gdm_port *port = netdev_priv(dev); 827 + struct airoha_eth *eth = port->qdma->eth; 828 + int err = 0; 829 + 830 + if (!tc_can_offload(dev) || type != TC_SETUP_CLSFLOWER) 831 + return -EOPNOTSUPP; 832 + 833 + mutex_lock(&flow_offload_mutex); 834 + 835 + if (!eth->npu) 836 + err = airoha_ppe_offload_setup(eth); 837 + if (!err) 838 + err = airoha_ppe_flow_offload_cmd(port, cls); 839 + 840 + mutex_unlock(&flow_offload_mutex); 841 + 842 + return err; 843 + } 844 + 845 + void airoha_ppe_check_skb(struct airoha_ppe *ppe, u16 hash) 846 + { 847 + u16 now, diff; 848 + 849 + if (hash > PPE_HASH_MASK) 850 + return; 851 + 852 + now = (u16)jiffies; 853 + diff = now - ppe->foe_check_time[hash]; 854 + if (diff < HZ / 10) 855 + return; 856 + 857 + ppe->foe_check_time[hash] = now; 858 + airoha_ppe_foe_insert_entry(ppe, hash); 859 + } 860 + 861 + int airoha_ppe_init(struct airoha_eth *eth) 862 + { 863 + struct airoha_ppe *ppe; 864 + int foe_size, err; 865 + 866 + ppe = devm_kzalloc(eth->dev, sizeof(*ppe), GFP_KERNEL); 867 + if (!ppe) 868 + return -ENOMEM; 869 + 870 + foe_size = PPE_NUM_ENTRIES * sizeof(struct airoha_foe_entry); 871 + ppe->foe = dmam_alloc_coherent(eth->dev, foe_size, &ppe->foe_dma, 872 + GFP_KERNEL); 873 + if (!ppe->foe) 874 + return -ENOMEM; 875 + 876 + ppe->eth = eth; 877 + eth->ppe = ppe; 878 + 879 + ppe->foe_flow = devm_kzalloc(eth->dev, 880 + PPE_NUM_ENTRIES * sizeof(*ppe->foe_flow), 881 + GFP_KERNEL); 882 + if (!ppe->foe_flow) 883 + return -ENOMEM; 884 + 885 + err = rhashtable_init(&eth->flow_table, &airoha_flow_table_params); 886 + if (err) 887 + return err; 888 + 889 + err = airoha_ppe_debugfs_init(ppe); 890 + if (err) 891 + rhashtable_destroy(&eth->flow_table); 892 + 893 + return err; 894 + } 895 + 896 + void airoha_ppe_deinit(struct airoha_eth *eth) 897 + { 898 + struct airoha_npu *npu; 899 + 900 + rcu_read_lock(); 901 + npu = rcu_dereference(eth->npu); 902 + if (npu) { 903 + npu->ops.ppe_deinit(npu); 904 + airoha_npu_put(npu); 905 + } 906 + rcu_read_unlock(); 907 + 908 + rhashtable_destroy(&eth->flow_table); 909 + debugfs_remove(eth->ppe->debugfs_dir); 910 + }
+181
drivers/net/ethernet/airoha/airoha_ppe_debugfs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2025 AIROHA Inc 4 + * Author: Lorenzo Bianconi <lorenzo@kernel.org> 5 + */ 6 + 7 + #include "airoha_eth.h" 8 + 9 + static void airoha_debugfs_ppe_print_tuple(struct seq_file *m, 10 + void *src_addr, void *dest_addr, 11 + u16 *src_port, u16 *dest_port, 12 + bool ipv6) 13 + { 14 + __be32 n_addr[IPV6_ADDR_WORDS]; 15 + 16 + if (ipv6) { 17 + ipv6_addr_cpu_to_be32(n_addr, src_addr); 18 + seq_printf(m, "%pI6", n_addr); 19 + } else { 20 + seq_printf(m, "%pI4h", src_addr); 21 + } 22 + if (src_port) 23 + seq_printf(m, ":%d", *src_port); 24 + 25 + seq_puts(m, "->"); 26 + 27 + if (ipv6) { 28 + ipv6_addr_cpu_to_be32(n_addr, dest_addr); 29 + seq_printf(m, "%pI6", n_addr); 30 + } else { 31 + seq_printf(m, "%pI4h", dest_addr); 32 + } 33 + if (dest_port) 34 + seq_printf(m, ":%d", *dest_port); 35 + } 36 + 37 + static int airoha_ppe_debugfs_foe_show(struct seq_file *m, void *private, 38 + bool bind) 39 + { 40 + static const char *const ppe_type_str[] = { 41 + [PPE_PKT_TYPE_IPV4_HNAPT] = "IPv4 5T", 42 + [PPE_PKT_TYPE_IPV4_ROUTE] = "IPv4 3T", 43 + [PPE_PKT_TYPE_BRIDGE] = "L2B", 44 + [PPE_PKT_TYPE_IPV4_DSLITE] = "DS-LITE", 45 + [PPE_PKT_TYPE_IPV6_ROUTE_3T] = "IPv6 3T", 46 + [PPE_PKT_TYPE_IPV6_ROUTE_5T] = "IPv6 5T", 47 + [PPE_PKT_TYPE_IPV6_6RD] = "6RD", 48 + }; 49 + static const char *const ppe_state_str[] = { 50 + [AIROHA_FOE_STATE_INVALID] = "INV", 51 + [AIROHA_FOE_STATE_UNBIND] = "UNB", 52 + [AIROHA_FOE_STATE_BIND] = "BND", 53 + [AIROHA_FOE_STATE_FIN] = "FIN", 54 + }; 55 + struct airoha_ppe *ppe = m->private; 56 + int i; 57 + 58 + for (i = 0; i < PPE_NUM_ENTRIES; i++) { 59 + const char *state_str, *type_str = "UNKNOWN"; 60 + void *src_addr = NULL, *dest_addr = NULL; 61 + u16 *src_port = NULL, *dest_port = NULL; 62 + struct airoha_foe_mac_info_common *l2; 63 + unsigned char h_source[ETH_ALEN] = {}; 64 + unsigned char h_dest[ETH_ALEN]; 65 + struct airoha_foe_entry *hwe; 66 + u32 type, state, ib2, data; 67 + bool ipv6 = false; 68 + 69 + hwe = airoha_ppe_foe_get_entry(ppe, i); 70 + if (!hwe) 71 + continue; 72 + 73 + state = FIELD_GET(AIROHA_FOE_IB1_BIND_STATE, hwe->ib1); 74 + if (!state) 75 + continue; 76 + 77 + if (bind && state != AIROHA_FOE_STATE_BIND) 78 + continue; 79 + 80 + state_str = ppe_state_str[state % ARRAY_SIZE(ppe_state_str)]; 81 + type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); 82 + if (type < ARRAY_SIZE(ppe_type_str) && ppe_type_str[type]) 83 + type_str = ppe_type_str[type]; 84 + 85 + seq_printf(m, "%05x %s %7s", i, state_str, type_str); 86 + 87 + switch (type) { 88 + case PPE_PKT_TYPE_IPV4_HNAPT: 89 + case PPE_PKT_TYPE_IPV4_DSLITE: 90 + src_port = &hwe->ipv4.orig_tuple.src_port; 91 + dest_port = &hwe->ipv4.orig_tuple.dest_port; 92 + fallthrough; 93 + case PPE_PKT_TYPE_IPV4_ROUTE: 94 + src_addr = &hwe->ipv4.orig_tuple.src_ip; 95 + dest_addr = &hwe->ipv4.orig_tuple.dest_ip; 96 + break; 97 + case PPE_PKT_TYPE_IPV6_ROUTE_5T: 98 + src_port = &hwe->ipv6.src_port; 99 + dest_port = &hwe->ipv6.dest_port; 100 + fallthrough; 101 + case PPE_PKT_TYPE_IPV6_ROUTE_3T: 102 + case PPE_PKT_TYPE_IPV6_6RD: 103 + src_addr = &hwe->ipv6.src_ip; 104 + dest_addr = &hwe->ipv6.dest_ip; 105 + ipv6 = true; 106 + break; 107 + default: 108 + break; 109 + } 110 + 111 + if (src_addr && dest_addr) { 112 + seq_puts(m, " orig="); 113 + airoha_debugfs_ppe_print_tuple(m, src_addr, dest_addr, 114 + src_port, dest_port, ipv6); 115 + } 116 + 117 + switch (type) { 118 + case PPE_PKT_TYPE_IPV4_HNAPT: 119 + case PPE_PKT_TYPE_IPV4_DSLITE: 120 + src_port = &hwe->ipv4.new_tuple.src_port; 121 + dest_port = &hwe->ipv4.new_tuple.dest_port; 122 + fallthrough; 123 + case PPE_PKT_TYPE_IPV4_ROUTE: 124 + src_addr = &hwe->ipv4.new_tuple.src_ip; 125 + dest_addr = &hwe->ipv4.new_tuple.dest_ip; 126 + seq_puts(m, " new="); 127 + airoha_debugfs_ppe_print_tuple(m, src_addr, dest_addr, 128 + src_port, dest_port, 129 + ipv6); 130 + break; 131 + default: 132 + break; 133 + } 134 + 135 + if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T) { 136 + data = hwe->ipv6.data; 137 + ib2 = hwe->ipv6.ib2; 138 + l2 = &hwe->ipv6.l2; 139 + } else { 140 + data = hwe->ipv4.data; 141 + ib2 = hwe->ipv4.ib2; 142 + l2 = &hwe->ipv4.l2.common; 143 + *((__be16 *)&h_source[4]) = 144 + cpu_to_be16(hwe->ipv4.l2.src_mac_lo); 145 + } 146 + 147 + *((__be32 *)h_dest) = cpu_to_be32(l2->dest_mac_hi); 148 + *((__be16 *)&h_dest[4]) = cpu_to_be16(l2->dest_mac_lo); 149 + *((__be32 *)h_source) = cpu_to_be32(l2->src_mac_hi); 150 + 151 + seq_printf(m, " eth=%pM->%pM etype=%04x data=%08x" 152 + " vlan=%d,%d ib1=%08x ib2=%08x\n", 153 + h_source, h_dest, l2->etype, data, 154 + l2->vlan1, l2->vlan2, hwe->ib1, ib2); 155 + } 156 + 157 + return 0; 158 + } 159 + 160 + static int airoha_ppe_debugfs_foe_all_show(struct seq_file *m, void *private) 161 + { 162 + return airoha_ppe_debugfs_foe_show(m, private, false); 163 + } 164 + DEFINE_SHOW_ATTRIBUTE(airoha_ppe_debugfs_foe_all); 165 + 166 + static int airoha_ppe_debugfs_foe_bind_show(struct seq_file *m, void *private) 167 + { 168 + return airoha_ppe_debugfs_foe_show(m, private, true); 169 + } 170 + DEFINE_SHOW_ATTRIBUTE(airoha_ppe_debugfs_foe_bind); 171 + 172 + int airoha_ppe_debugfs_init(struct airoha_ppe *ppe) 173 + { 174 + ppe->debugfs_dir = debugfs_create_dir("ppe", NULL); 175 + debugfs_create_file("entries", 0444, ppe->debugfs_dir, ppe, 176 + &airoha_ppe_debugfs_foe_all_fops); 177 + debugfs_create_file("bind", 0444, ppe->debugfs_dir, ppe, 178 + &airoha_ppe_debugfs_foe_bind_fops); 179 + 180 + return 0; 181 + }
+798
drivers/net/ethernet/airoha/airoha_regs.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (c) 2024 AIROHA Inc 4 + * Author: Lorenzo Bianconi <lorenzo@kernel.org> 5 + */ 6 + 7 + #ifndef AIROHA_REGS_H 8 + #define AIROHA_REGS_H 9 + 10 + #include <linux/types.h> 11 + 12 + /* FE */ 13 + #define PSE_BASE 0x0100 14 + #define CSR_IFC_BASE 0x0200 15 + #define CDM1_BASE 0x0400 16 + #define GDM1_BASE 0x0500 17 + #define PPE1_BASE 0x0c00 18 + #define PPE2_BASE 0x1c00 19 + 20 + #define CDM2_BASE 0x1400 21 + #define GDM2_BASE 0x1500 22 + 23 + #define GDM3_BASE 0x1100 24 + #define GDM4_BASE 0x2500 25 + 26 + #define GDM_BASE(_n) \ 27 + ((_n) == 4 ? GDM4_BASE : \ 28 + (_n) == 3 ? GDM3_BASE : \ 29 + (_n) == 2 ? GDM2_BASE : GDM1_BASE) 30 + 31 + #define REG_FE_DMA_GLO_CFG 0x0000 32 + #define FE_DMA_GLO_L2_SPACE_MASK GENMASK(7, 4) 33 + #define FE_DMA_GLO_PG_SZ_MASK BIT(3) 34 + 35 + #define REG_FE_RST_GLO_CFG 0x0004 36 + #define FE_RST_GDM4_MBI_ARB_MASK BIT(3) 37 + #define FE_RST_GDM3_MBI_ARB_MASK BIT(2) 38 + #define FE_RST_CORE_MASK BIT(0) 39 + 40 + #define REG_FE_FOE_TS 0x0010 41 + 42 + #define REG_FE_WAN_PORT 0x0024 43 + #define WAN1_EN_MASK BIT(16) 44 + #define WAN1_MASK GENMASK(12, 8) 45 + #define WAN0_MASK GENMASK(4, 0) 46 + 47 + #define REG_FE_WAN_MAC_H 0x0030 48 + #define REG_FE_LAN_MAC_H 0x0040 49 + 50 + #define REG_FE_MAC_LMIN(_n) ((_n) + 0x04) 51 + #define REG_FE_MAC_LMAX(_n) ((_n) + 0x08) 52 + 53 + #define REG_FE_CDM1_OQ_MAP0 0x0050 54 + #define REG_FE_CDM1_OQ_MAP1 0x0054 55 + #define REG_FE_CDM1_OQ_MAP2 0x0058 56 + #define REG_FE_CDM1_OQ_MAP3 0x005c 57 + 58 + #define REG_FE_PCE_CFG 0x0070 59 + #define PCE_DPI_EN_MASK BIT(2) 60 + #define PCE_KA_EN_MASK BIT(1) 61 + #define PCE_MC_EN_MASK BIT(0) 62 + 63 + #define REG_FE_PSE_QUEUE_CFG_WR 0x0080 64 + #define PSE_CFG_PORT_ID_MASK GENMASK(27, 24) 65 + #define PSE_CFG_QUEUE_ID_MASK GENMASK(20, 16) 66 + #define PSE_CFG_WR_EN_MASK BIT(8) 67 + #define PSE_CFG_OQRSV_SEL_MASK BIT(0) 68 + 69 + #define REG_FE_PSE_QUEUE_CFG_VAL 0x0084 70 + #define PSE_CFG_OQ_RSV_MASK GENMASK(13, 0) 71 + 72 + #define PSE_FQ_CFG 0x008c 73 + #define PSE_FQ_LIMIT_MASK GENMASK(14, 0) 74 + 75 + #define REG_FE_PSE_BUF_SET 0x0090 76 + #define PSE_SHARE_USED_LTHD_MASK GENMASK(31, 16) 77 + #define PSE_ALLRSV_MASK GENMASK(14, 0) 78 + 79 + #define REG_PSE_SHARE_USED_THD 0x0094 80 + #define PSE_SHARE_USED_MTHD_MASK GENMASK(31, 16) 81 + #define PSE_SHARE_USED_HTHD_MASK GENMASK(15, 0) 82 + 83 + #define REG_GDM_MISC_CFG 0x0148 84 + #define GDM2_RDM_ACK_WAIT_PREF_MASK BIT(9) 85 + #define GDM2_CHN_VLD_MODE_MASK BIT(5) 86 + 87 + #define REG_FE_CSR_IFC_CFG CSR_IFC_BASE 88 + #define FE_IFC_EN_MASK BIT(0) 89 + 90 + #define REG_FE_VIP_PORT_EN 0x01f0 91 + #define REG_FE_IFC_PORT_EN 0x01f4 92 + 93 + #define REG_PSE_IQ_REV1 (PSE_BASE + 0x08) 94 + #define PSE_IQ_RES1_P2_MASK GENMASK(23, 16) 95 + 96 + #define REG_PSE_IQ_REV2 (PSE_BASE + 0x0c) 97 + #define PSE_IQ_RES2_P5_MASK GENMASK(15, 8) 98 + #define PSE_IQ_RES2_P4_MASK GENMASK(7, 0) 99 + 100 + #define REG_FE_VIP_EN(_n) (0x0300 + ((_n) << 3)) 101 + #define PATN_FCPU_EN_MASK BIT(7) 102 + #define PATN_SWP_EN_MASK BIT(6) 103 + #define PATN_DP_EN_MASK BIT(5) 104 + #define PATN_SP_EN_MASK BIT(4) 105 + #define PATN_TYPE_MASK GENMASK(3, 1) 106 + #define PATN_EN_MASK BIT(0) 107 + 108 + #define REG_FE_VIP_PATN(_n) (0x0304 + ((_n) << 3)) 109 + #define PATN_DP_MASK GENMASK(31, 16) 110 + #define PATN_SP_MASK GENMASK(15, 0) 111 + 112 + #define REG_CDM1_VLAN_CTRL CDM1_BASE 113 + #define CDM1_VLAN_MASK GENMASK(31, 16) 114 + 115 + #define REG_CDM1_FWD_CFG (CDM1_BASE + 0x08) 116 + #define CDM1_VIP_QSEL_MASK GENMASK(24, 20) 117 + 118 + #define REG_CDM1_CRSN_QSEL(_n) (CDM1_BASE + 0x10 + ((_n) << 2)) 119 + #define CDM1_CRSN_QSEL_REASON_MASK(_n) \ 120 + GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) 121 + 122 + #define REG_CDM2_FWD_CFG (CDM2_BASE + 0x08) 123 + #define CDM2_OAM_QSEL_MASK GENMASK(31, 27) 124 + #define CDM2_VIP_QSEL_MASK GENMASK(24, 20) 125 + 126 + #define REG_CDM2_CRSN_QSEL(_n) (CDM2_BASE + 0x10 + ((_n) << 2)) 127 + #define CDM2_CRSN_QSEL_REASON_MASK(_n) \ 128 + GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) 129 + 130 + #define REG_GDM_FWD_CFG(_n) GDM_BASE(_n) 131 + #define GDM_DROP_CRC_ERR BIT(23) 132 + #define GDM_IP4_CKSUM BIT(22) 133 + #define GDM_TCP_CKSUM BIT(21) 134 + #define GDM_UDP_CKSUM BIT(20) 135 + #define GDM_STRIP_CRC BIT(16) 136 + #define GDM_UCFQ_MASK GENMASK(15, 12) 137 + #define GDM_BCFQ_MASK GENMASK(11, 8) 138 + #define GDM_MCFQ_MASK GENMASK(7, 4) 139 + #define GDM_OCFQ_MASK GENMASK(3, 0) 140 + 141 + #define REG_GDM_INGRESS_CFG(_n) (GDM_BASE(_n) + 0x10) 142 + #define GDM_INGRESS_FC_EN_MASK BIT(1) 143 + #define GDM_STAG_EN_MASK BIT(0) 144 + 145 + #define REG_GDM_LEN_CFG(_n) (GDM_BASE(_n) + 0x14) 146 + #define GDM_SHORT_LEN_MASK GENMASK(13, 0) 147 + #define GDM_LONG_LEN_MASK GENMASK(29, 16) 148 + 149 + #define REG_GDM_LPBK_CFG(_n) (GDM_BASE(_n) + 0x1c) 150 + #define LPBK_GAP_MASK GENMASK(31, 24) 151 + #define LPBK_LEN_MASK GENMASK(23, 10) 152 + #define LPBK_CHAN_MASK GENMASK(8, 4) 153 + #define LPBK_MODE_MASK GENMASK(3, 1) 154 + #define LPBK_EN_MASK BIT(0) 155 + 156 + #define REG_GDM_TXCHN_EN(_n) (GDM_BASE(_n) + 0x24) 157 + #define REG_GDM_RXCHN_EN(_n) (GDM_BASE(_n) + 0x28) 158 + 159 + #define REG_FE_CPORT_CFG (GDM1_BASE + 0x40) 160 + #define FE_CPORT_PAD BIT(26) 161 + #define FE_CPORT_PORT_XFC_MASK BIT(25) 162 + #define FE_CPORT_QUEUE_XFC_MASK BIT(24) 163 + 164 + #define REG_FE_GDM_MIB_CLEAR(_n) (GDM_BASE(_n) + 0xf0) 165 + #define FE_GDM_MIB_RX_CLEAR_MASK BIT(1) 166 + #define FE_GDM_MIB_TX_CLEAR_MASK BIT(0) 167 + 168 + #define REG_FE_GDM1_MIB_CFG (GDM1_BASE + 0xf4) 169 + #define FE_STRICT_RFC2819_MODE_MASK BIT(31) 170 + #define FE_GDM1_TX_MIB_SPLIT_EN_MASK BIT(17) 171 + #define FE_GDM1_RX_MIB_SPLIT_EN_MASK BIT(16) 172 + #define FE_TX_MIB_ID_MASK GENMASK(15, 8) 173 + #define FE_RX_MIB_ID_MASK GENMASK(7, 0) 174 + 175 + #define REG_FE_GDM_TX_OK_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x104) 176 + #define REG_FE_GDM_TX_OK_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x10c) 177 + #define REG_FE_GDM_TX_ETH_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x110) 178 + #define REG_FE_GDM_TX_ETH_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x114) 179 + #define REG_FE_GDM_TX_ETH_DROP_CNT(_n) (GDM_BASE(_n) + 0x118) 180 + #define REG_FE_GDM_TX_ETH_BC_CNT(_n) (GDM_BASE(_n) + 0x11c) 181 + #define REG_FE_GDM_TX_ETH_MC_CNT(_n) (GDM_BASE(_n) + 0x120) 182 + #define REG_FE_GDM_TX_ETH_RUNT_CNT(_n) (GDM_BASE(_n) + 0x124) 183 + #define REG_FE_GDM_TX_ETH_LONG_CNT(_n) (GDM_BASE(_n) + 0x128) 184 + #define REG_FE_GDM_TX_ETH_E64_CNT_L(_n) (GDM_BASE(_n) + 0x12c) 185 + #define REG_FE_GDM_TX_ETH_L64_CNT_L(_n) (GDM_BASE(_n) + 0x130) 186 + #define REG_FE_GDM_TX_ETH_L127_CNT_L(_n) (GDM_BASE(_n) + 0x134) 187 + #define REG_FE_GDM_TX_ETH_L255_CNT_L(_n) (GDM_BASE(_n) + 0x138) 188 + #define REG_FE_GDM_TX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x13c) 189 + #define REG_FE_GDM_TX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x140) 190 + 191 + #define REG_FE_GDM_RX_OK_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x148) 192 + #define REG_FE_GDM_RX_FC_DROP_CNT(_n) (GDM_BASE(_n) + 0x14c) 193 + #define REG_FE_GDM_RX_RC_DROP_CNT(_n) (GDM_BASE(_n) + 0x150) 194 + #define REG_FE_GDM_RX_OVERFLOW_DROP_CNT(_n) (GDM_BASE(_n) + 0x154) 195 + #define REG_FE_GDM_RX_ERROR_DROP_CNT(_n) (GDM_BASE(_n) + 0x158) 196 + #define REG_FE_GDM_RX_OK_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x15c) 197 + #define REG_FE_GDM_RX_ETH_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x160) 198 + #define REG_FE_GDM_RX_ETH_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x164) 199 + #define REG_FE_GDM_RX_ETH_DROP_CNT(_n) (GDM_BASE(_n) + 0x168) 200 + #define REG_FE_GDM_RX_ETH_BC_CNT(_n) (GDM_BASE(_n) + 0x16c) 201 + #define REG_FE_GDM_RX_ETH_MC_CNT(_n) (GDM_BASE(_n) + 0x170) 202 + #define REG_FE_GDM_RX_ETH_CRC_ERR_CNT(_n) (GDM_BASE(_n) + 0x174) 203 + #define REG_FE_GDM_RX_ETH_FRAG_CNT(_n) (GDM_BASE(_n) + 0x178) 204 + #define REG_FE_GDM_RX_ETH_JABBER_CNT(_n) (GDM_BASE(_n) + 0x17c) 205 + #define REG_FE_GDM_RX_ETH_RUNT_CNT(_n) (GDM_BASE(_n) + 0x180) 206 + #define REG_FE_GDM_RX_ETH_LONG_CNT(_n) (GDM_BASE(_n) + 0x184) 207 + #define REG_FE_GDM_RX_ETH_E64_CNT_L(_n) (GDM_BASE(_n) + 0x188) 208 + #define REG_FE_GDM_RX_ETH_L64_CNT_L(_n) (GDM_BASE(_n) + 0x18c) 209 + #define REG_FE_GDM_RX_ETH_L127_CNT_L(_n) (GDM_BASE(_n) + 0x190) 210 + #define REG_FE_GDM_RX_ETH_L255_CNT_L(_n) (GDM_BASE(_n) + 0x194) 211 + #define REG_FE_GDM_RX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x198) 212 + #define REG_FE_GDM_RX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x19c) 213 + 214 + #define REG_PPE_GLO_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x200) 215 + #define PPE_GLO_CFG_BUSY_MASK BIT(31) 216 + #define PPE_GLO_CFG_FLOW_DROP_UPDATE_MASK BIT(9) 217 + #define PPE_GLO_CFG_PSE_HASH_OFS_MASK BIT(6) 218 + #define PPE_GLO_CFG_PPE_BSWAP_MASK BIT(5) 219 + #define PPE_GLO_CFG_TTL_DROP_MASK BIT(4) 220 + #define PPE_GLO_CFG_IP4_CS_DROP_MASK BIT(3) 221 + #define PPE_GLO_CFG_IP4_L4_CS_DROP_MASK BIT(2) 222 + #define PPE_GLO_CFG_EN_MASK BIT(0) 223 + 224 + #define REG_PPE_PPE_FLOW_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x204) 225 + #define PPE_FLOW_CFG_IP6_HASH_GRE_KEY_MASK BIT(20) 226 + #define PPE_FLOW_CFG_IP4_HASH_GRE_KEY_MASK BIT(19) 227 + #define PPE_FLOW_CFG_IP4_HASH_FLOW_LABEL_MASK BIT(18) 228 + #define PPE_FLOW_CFG_IP4_NAT_FRAG_MASK BIT(17) 229 + #define PPE_FLOW_CFG_IP_PROTO_BLACKLIST_MASK BIT(16) 230 + #define PPE_FLOW_CFG_IP4_DSLITE_MASK BIT(14) 231 + #define PPE_FLOW_CFG_IP4_NAPT_MASK BIT(13) 232 + #define PPE_FLOW_CFG_IP4_NAT_MASK BIT(12) 233 + #define PPE_FLOW_CFG_IP6_6RD_MASK BIT(10) 234 + #define PPE_FLOW_CFG_IP6_5T_ROUTE_MASK BIT(9) 235 + #define PPE_FLOW_CFG_IP6_3T_ROUTE_MASK BIT(8) 236 + #define PPE_FLOW_CFG_IP4_UDP_FRAG_MASK BIT(7) 237 + #define PPE_FLOW_CFG_IP4_TCP_FRAG_MASK BIT(6) 238 + 239 + #define REG_PPE_IP_PROTO_CHK(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x208) 240 + #define PPE_IP_PROTO_CHK_IPV4_MASK GENMASK(15, 0) 241 + #define PPE_IP_PROTO_CHK_IPV6_MASK GENMASK(31, 16) 242 + 243 + #define REG_PPE_TB_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x21c) 244 + #define PPE_SRAM_TB_NUM_ENTRY_MASK GENMASK(26, 24) 245 + #define PPE_TB_CFG_KEEPALIVE_MASK GENMASK(13, 12) 246 + #define PPE_TB_CFG_AGE_TCP_FIN_MASK BIT(11) 247 + #define PPE_TB_CFG_AGE_UDP_MASK BIT(10) 248 + #define PPE_TB_CFG_AGE_TCP_MASK BIT(9) 249 + #define PPE_TB_CFG_AGE_UNBIND_MASK BIT(8) 250 + #define PPE_TB_CFG_AGE_NON_L4_MASK BIT(7) 251 + #define PPE_TB_CFG_AGE_PREBIND_MASK BIT(6) 252 + #define PPE_TB_CFG_SEARCH_MISS_MASK GENMASK(5, 4) 253 + #define PPE_TB_ENTRY_SIZE_MASK BIT(3) 254 + #define PPE_DRAM_TB_NUM_ENTRY_MASK GENMASK(2, 0) 255 + 256 + #define REG_PPE_TB_BASE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x220) 257 + 258 + #define REG_PPE_BIND_RATE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x228) 259 + #define PPE_BIND_RATE_L2B_BIND_MASK GENMASK(31, 16) 260 + #define PPE_BIND_RATE_BIND_MASK GENMASK(15, 0) 261 + 262 + #define REG_PPE_BIND_LIMIT0(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x22c) 263 + #define PPE_BIND_LIMIT0_HALF_MASK GENMASK(29, 16) 264 + #define PPE_BIND_LIMIT0_QUARTER_MASK GENMASK(13, 0) 265 + 266 + #define REG_PPE_BIND_LIMIT1(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x230) 267 + #define PPE_BIND_LIMIT1_NON_L4_MASK GENMASK(23, 16) 268 + #define PPE_BIND_LIMIT1_FULL_MASK GENMASK(13, 0) 269 + 270 + #define REG_PPE_BND_AGE0(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x23c) 271 + #define PPE_BIND_AGE0_DELTA_NON_L4 GENMASK(30, 16) 272 + #define PPE_BIND_AGE0_DELTA_UDP GENMASK(14, 0) 273 + 274 + #define REG_PPE_UNBIND_AGE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x238) 275 + #define PPE_UNBIND_AGE_MIN_PACKETS_MASK GENMASK(31, 16) 276 + #define PPE_UNBIND_AGE_DELTA_MASK GENMASK(7, 0) 277 + 278 + #define REG_PPE_BND_AGE1(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x240) 279 + #define PPE_BIND_AGE1_DELTA_TCP_FIN GENMASK(30, 16) 280 + #define PPE_BIND_AGE1_DELTA_TCP GENMASK(14, 0) 281 + 282 + #define REG_PPE_HASH_SEED(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x244) 283 + #define PPE_HASH_SEED 0x12345678 284 + 285 + #define REG_PPE_DFT_CPORT0(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x248) 286 + 287 + #define REG_PPE_DFT_CPORT1(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x24c) 288 + 289 + #define REG_PPE_TB_HASH_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x250) 290 + #define PPE_DRAM_HASH1_MODE_MASK GENMASK(31, 28) 291 + #define PPE_DRAM_HASH1_EN_MASK BIT(24) 292 + #define PPE_DRAM_HASH0_MODE_MASK GENMASK(23, 20) 293 + #define PPE_DRAM_TABLE_EN_MASK BIT(16) 294 + #define PPE_SRAM_HASH1_MODE_MASK GENMASK(15, 12) 295 + #define PPE_SRAM_HASH1_EN_MASK BIT(8) 296 + #define PPE_SRAM_HASH0_MODE_MASK GENMASK(7, 4) 297 + #define PPE_SRAM_TABLE_EN_MASK BIT(0) 298 + 299 + #define REG_PPE_MTU_BASE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x304) 300 + #define REG_PPE_MTU(_m, _n) (REG_PPE_MTU_BASE(_m) + ((_n) << 2)) 301 + #define FP1_EGRESS_MTU_MASK GENMASK(29, 16) 302 + #define FP0_EGRESS_MTU_MASK GENMASK(13, 0) 303 + 304 + #define REG_PPE_RAM_CTRL(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x31c) 305 + #define PPE_SRAM_CTRL_ACK_MASK BIT(31) 306 + #define PPE_SRAM_CTRL_DUAL_SUCESS_MASK BIT(30) 307 + #define PPE_SRAM_CTRL_ENTRY_MASK GENMASK(23, 8) 308 + #define PPE_SRAM_WR_DUAL_DIRECTION_MASK BIT(2) 309 + #define PPE_SRAM_CTRL_WR_MASK BIT(1) 310 + #define PPE_SRAM_CTRL_REQ_MASK BIT(0) 311 + 312 + #define REG_PPE_RAM_BASE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x320) 313 + #define REG_PPE_RAM_ENTRY(_m, _n) (REG_PPE_RAM_BASE(_m) + ((_n) << 2)) 314 + 315 + #define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280) 316 + #define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284) 317 + #define REG_FE_GDM_TX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x288) 318 + #define REG_FE_GDM_TX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x28c) 319 + 320 + #define REG_FE_GDM_RX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x290) 321 + #define REG_FE_GDM_RX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x294) 322 + #define REG_FE_GDM_RX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x298) 323 + #define REG_FE_GDM_RX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x29c) 324 + #define REG_FE_GDM_TX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2b8) 325 + #define REG_FE_GDM_TX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2bc) 326 + #define REG_FE_GDM_TX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2c0) 327 + #define REG_FE_GDM_TX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2c4) 328 + #define REG_FE_GDM_TX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2c8) 329 + #define REG_FE_GDM_TX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2cc) 330 + #define REG_FE_GDM_RX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2e8) 331 + #define REG_FE_GDM_RX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2ec) 332 + #define REG_FE_GDM_RX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2f0) 333 + #define REG_FE_GDM_RX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2f4) 334 + #define REG_FE_GDM_RX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2f8) 335 + #define REG_FE_GDM_RX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2fc) 336 + 337 + #define REG_GDM2_CHN_RLS (GDM2_BASE + 0x20) 338 + #define MBI_RX_AGE_SEL_MASK GENMASK(26, 25) 339 + #define MBI_TX_AGE_SEL_MASK GENMASK(18, 17) 340 + 341 + #define REG_GDM3_FWD_CFG GDM3_BASE 342 + #define GDM3_PAD_EN_MASK BIT(28) 343 + 344 + #define REG_GDM4_FWD_CFG GDM4_BASE 345 + #define GDM4_PAD_EN_MASK BIT(28) 346 + #define GDM4_SPORT_OFFSET0_MASK GENMASK(11, 8) 347 + 348 + #define REG_GDM4_SRC_PORT_SET (GDM4_BASE + 0x23c) 349 + #define GDM4_SPORT_OFF2_MASK GENMASK(19, 16) 350 + #define GDM4_SPORT_OFF1_MASK GENMASK(15, 12) 351 + #define GDM4_SPORT_OFF0_MASK GENMASK(11, 8) 352 + 353 + #define REG_IP_FRAG_FP 0x2010 354 + #define IP_ASSEMBLE_PORT_MASK GENMASK(24, 21) 355 + #define IP_ASSEMBLE_NBQ_MASK GENMASK(20, 16) 356 + #define IP_FRAGMENT_PORT_MASK GENMASK(8, 5) 357 + #define IP_FRAGMENT_NBQ_MASK GENMASK(4, 0) 358 + 359 + #define REG_MC_VLAN_EN 0x2100 360 + #define MC_VLAN_EN_MASK BIT(0) 361 + 362 + #define REG_MC_VLAN_CFG 0x2104 363 + #define MC_VLAN_CFG_CMD_DONE_MASK BIT(31) 364 + #define MC_VLAN_CFG_TABLE_ID_MASK GENMASK(21, 16) 365 + #define MC_VLAN_CFG_PORT_ID_MASK GENMASK(11, 8) 366 + #define MC_VLAN_CFG_TABLE_SEL_MASK BIT(4) 367 + #define MC_VLAN_CFG_RW_MASK BIT(0) 368 + 369 + #define REG_MC_VLAN_DATA 0x2108 370 + 371 + #define REG_SP_DFT_CPORT(_n) (0x20e0 + ((_n) << 2)) 372 + #define SP_CPORT_PCIE1_MASK GENMASK(31, 28) 373 + #define SP_CPORT_PCIE0_MASK GENMASK(27, 24) 374 + #define SP_CPORT_USB_MASK GENMASK(7, 4) 375 + #define SP_CPORT_ETH_MASK GENMASK(7, 4) 376 + 377 + #define REG_SRC_PORT_FC_MAP6 0x2298 378 + #define FC_ID_OF_SRC_PORT27_MASK GENMASK(28, 24) 379 + #define FC_ID_OF_SRC_PORT26_MASK GENMASK(20, 16) 380 + #define FC_ID_OF_SRC_PORT25_MASK GENMASK(12, 8) 381 + #define FC_ID_OF_SRC_PORT24_MASK GENMASK(4, 0) 382 + 383 + #define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4 384 + 385 + /* QDMA */ 386 + #define REG_QDMA_GLOBAL_CFG 0x0004 387 + #define GLOBAL_CFG_RX_2B_OFFSET_MASK BIT(31) 388 + #define GLOBAL_CFG_DMA_PREFERENCE_MASK GENMASK(30, 29) 389 + #define GLOBAL_CFG_CPU_TXR_RR_MASK BIT(28) 390 + #define GLOBAL_CFG_DSCP_BYTE_SWAP_MASK BIT(27) 391 + #define GLOBAL_CFG_PAYLOAD_BYTE_SWAP_MASK BIT(26) 392 + #define GLOBAL_CFG_MULTICAST_MODIFY_FP_MASK BIT(25) 393 + #define GLOBAL_CFG_OAM_MODIFY_MASK BIT(24) 394 + #define GLOBAL_CFG_RESET_MASK BIT(23) 395 + #define GLOBAL_CFG_RESET_DONE_MASK BIT(22) 396 + #define GLOBAL_CFG_MULTICAST_EN_MASK BIT(21) 397 + #define GLOBAL_CFG_IRQ1_EN_MASK BIT(20) 398 + #define GLOBAL_CFG_IRQ0_EN_MASK BIT(19) 399 + #define GLOBAL_CFG_LOOPCNT_EN_MASK BIT(18) 400 + #define GLOBAL_CFG_RD_BYPASS_WR_MASK BIT(17) 401 + #define GLOBAL_CFG_QDMA_LOOPBACK_MASK BIT(16) 402 + #define GLOBAL_CFG_LPBK_RXQ_SEL_MASK GENMASK(13, 8) 403 + #define GLOBAL_CFG_CHECK_DONE_MASK BIT(7) 404 + #define GLOBAL_CFG_TX_WB_DONE_MASK BIT(6) 405 + #define GLOBAL_CFG_MAX_ISSUE_NUM_MASK GENMASK(5, 4) 406 + #define GLOBAL_CFG_RX_DMA_BUSY_MASK BIT(3) 407 + #define GLOBAL_CFG_RX_DMA_EN_MASK BIT(2) 408 + #define GLOBAL_CFG_TX_DMA_BUSY_MASK BIT(1) 409 + #define GLOBAL_CFG_TX_DMA_EN_MASK BIT(0) 410 + 411 + #define REG_FWD_DSCP_BASE 0x0010 412 + #define REG_FWD_BUF_BASE 0x0014 413 + 414 + #define REG_HW_FWD_DSCP_CFG 0x0018 415 + #define HW_FWD_DSCP_PAYLOAD_SIZE_MASK GENMASK(29, 28) 416 + #define HW_FWD_DSCP_SCATTER_LEN_MASK GENMASK(17, 16) 417 + #define HW_FWD_DSCP_MIN_SCATTER_LEN_MASK GENMASK(15, 0) 418 + 419 + #define REG_INT_STATUS(_n) \ 420 + (((_n) == 4) ? 0x0730 : \ 421 + ((_n) == 3) ? 0x0724 : \ 422 + ((_n) == 2) ? 0x0720 : \ 423 + ((_n) == 1) ? 0x0024 : 0x0020) 424 + 425 + #define REG_INT_ENABLE(_n) \ 426 + (((_n) == 4) ? 0x0750 : \ 427 + ((_n) == 3) ? 0x0744 : \ 428 + ((_n) == 2) ? 0x0740 : \ 429 + ((_n) == 1) ? 0x002c : 0x0028) 430 + 431 + /* QDMA_CSR_INT_ENABLE1 */ 432 + #define RX15_COHERENT_INT_MASK BIT(31) 433 + #define RX14_COHERENT_INT_MASK BIT(30) 434 + #define RX13_COHERENT_INT_MASK BIT(29) 435 + #define RX12_COHERENT_INT_MASK BIT(28) 436 + #define RX11_COHERENT_INT_MASK BIT(27) 437 + #define RX10_COHERENT_INT_MASK BIT(26) 438 + #define RX9_COHERENT_INT_MASK BIT(25) 439 + #define RX8_COHERENT_INT_MASK BIT(24) 440 + #define RX7_COHERENT_INT_MASK BIT(23) 441 + #define RX6_COHERENT_INT_MASK BIT(22) 442 + #define RX5_COHERENT_INT_MASK BIT(21) 443 + #define RX4_COHERENT_INT_MASK BIT(20) 444 + #define RX3_COHERENT_INT_MASK BIT(19) 445 + #define RX2_COHERENT_INT_MASK BIT(18) 446 + #define RX1_COHERENT_INT_MASK BIT(17) 447 + #define RX0_COHERENT_INT_MASK BIT(16) 448 + #define TX7_COHERENT_INT_MASK BIT(15) 449 + #define TX6_COHERENT_INT_MASK BIT(14) 450 + #define TX5_COHERENT_INT_MASK BIT(13) 451 + #define TX4_COHERENT_INT_MASK BIT(12) 452 + #define TX3_COHERENT_INT_MASK BIT(11) 453 + #define TX2_COHERENT_INT_MASK BIT(10) 454 + #define TX1_COHERENT_INT_MASK BIT(9) 455 + #define TX0_COHERENT_INT_MASK BIT(8) 456 + #define CNT_OVER_FLOW_INT_MASK BIT(7) 457 + #define IRQ1_FULL_INT_MASK BIT(5) 458 + #define IRQ1_INT_MASK BIT(4) 459 + #define HWFWD_DSCP_LOW_INT_MASK BIT(3) 460 + #define HWFWD_DSCP_EMPTY_INT_MASK BIT(2) 461 + #define IRQ0_FULL_INT_MASK BIT(1) 462 + #define IRQ0_INT_MASK BIT(0) 463 + 464 + #define TX_DONE_INT_MASK(_n) \ 465 + ((_n) ? IRQ1_INT_MASK | IRQ1_FULL_INT_MASK \ 466 + : IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) 467 + 468 + #define INT_TX_MASK \ 469 + (IRQ1_INT_MASK | IRQ1_FULL_INT_MASK | \ 470 + IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) 471 + 472 + #define INT_IDX0_MASK \ 473 + (TX0_COHERENT_INT_MASK | TX1_COHERENT_INT_MASK | \ 474 + TX2_COHERENT_INT_MASK | TX3_COHERENT_INT_MASK | \ 475 + TX4_COHERENT_INT_MASK | TX5_COHERENT_INT_MASK | \ 476 + TX6_COHERENT_INT_MASK | TX7_COHERENT_INT_MASK | \ 477 + RX0_COHERENT_INT_MASK | RX1_COHERENT_INT_MASK | \ 478 + RX2_COHERENT_INT_MASK | RX3_COHERENT_INT_MASK | \ 479 + RX4_COHERENT_INT_MASK | RX7_COHERENT_INT_MASK | \ 480 + RX8_COHERENT_INT_MASK | RX9_COHERENT_INT_MASK | \ 481 + RX15_COHERENT_INT_MASK | INT_TX_MASK) 482 + 483 + /* QDMA_CSR_INT_ENABLE2 */ 484 + #define RX15_NO_CPU_DSCP_INT_MASK BIT(31) 485 + #define RX14_NO_CPU_DSCP_INT_MASK BIT(30) 486 + #define RX13_NO_CPU_DSCP_INT_MASK BIT(29) 487 + #define RX12_NO_CPU_DSCP_INT_MASK BIT(28) 488 + #define RX11_NO_CPU_DSCP_INT_MASK BIT(27) 489 + #define RX10_NO_CPU_DSCP_INT_MASK BIT(26) 490 + #define RX9_NO_CPU_DSCP_INT_MASK BIT(25) 491 + #define RX8_NO_CPU_DSCP_INT_MASK BIT(24) 492 + #define RX7_NO_CPU_DSCP_INT_MASK BIT(23) 493 + #define RX6_NO_CPU_DSCP_INT_MASK BIT(22) 494 + #define RX5_NO_CPU_DSCP_INT_MASK BIT(21) 495 + #define RX4_NO_CPU_DSCP_INT_MASK BIT(20) 496 + #define RX3_NO_CPU_DSCP_INT_MASK BIT(19) 497 + #define RX2_NO_CPU_DSCP_INT_MASK BIT(18) 498 + #define RX1_NO_CPU_DSCP_INT_MASK BIT(17) 499 + #define RX0_NO_CPU_DSCP_INT_MASK BIT(16) 500 + #define RX15_DONE_INT_MASK BIT(15) 501 + #define RX14_DONE_INT_MASK BIT(14) 502 + #define RX13_DONE_INT_MASK BIT(13) 503 + #define RX12_DONE_INT_MASK BIT(12) 504 + #define RX11_DONE_INT_MASK BIT(11) 505 + #define RX10_DONE_INT_MASK BIT(10) 506 + #define RX9_DONE_INT_MASK BIT(9) 507 + #define RX8_DONE_INT_MASK BIT(8) 508 + #define RX7_DONE_INT_MASK BIT(7) 509 + #define RX6_DONE_INT_MASK BIT(6) 510 + #define RX5_DONE_INT_MASK BIT(5) 511 + #define RX4_DONE_INT_MASK BIT(4) 512 + #define RX3_DONE_INT_MASK BIT(3) 513 + #define RX2_DONE_INT_MASK BIT(2) 514 + #define RX1_DONE_INT_MASK BIT(1) 515 + #define RX0_DONE_INT_MASK BIT(0) 516 + 517 + #define RX_DONE_INT_MASK \ 518 + (RX0_DONE_INT_MASK | RX1_DONE_INT_MASK | \ 519 + RX2_DONE_INT_MASK | RX3_DONE_INT_MASK | \ 520 + RX4_DONE_INT_MASK | RX7_DONE_INT_MASK | \ 521 + RX8_DONE_INT_MASK | RX9_DONE_INT_MASK | \ 522 + RX15_DONE_INT_MASK) 523 + #define INT_IDX1_MASK \ 524 + (RX_DONE_INT_MASK | \ 525 + RX0_NO_CPU_DSCP_INT_MASK | RX1_NO_CPU_DSCP_INT_MASK | \ 526 + RX2_NO_CPU_DSCP_INT_MASK | RX3_NO_CPU_DSCP_INT_MASK | \ 527 + RX4_NO_CPU_DSCP_INT_MASK | RX7_NO_CPU_DSCP_INT_MASK | \ 528 + RX8_NO_CPU_DSCP_INT_MASK | RX9_NO_CPU_DSCP_INT_MASK | \ 529 + RX15_NO_CPU_DSCP_INT_MASK) 530 + 531 + /* QDMA_CSR_INT_ENABLE5 */ 532 + #define TX31_COHERENT_INT_MASK BIT(31) 533 + #define TX30_COHERENT_INT_MASK BIT(30) 534 + #define TX29_COHERENT_INT_MASK BIT(29) 535 + #define TX28_COHERENT_INT_MASK BIT(28) 536 + #define TX27_COHERENT_INT_MASK BIT(27) 537 + #define TX26_COHERENT_INT_MASK BIT(26) 538 + #define TX25_COHERENT_INT_MASK BIT(25) 539 + #define TX24_COHERENT_INT_MASK BIT(24) 540 + #define TX23_COHERENT_INT_MASK BIT(23) 541 + #define TX22_COHERENT_INT_MASK BIT(22) 542 + #define TX21_COHERENT_INT_MASK BIT(21) 543 + #define TX20_COHERENT_INT_MASK BIT(20) 544 + #define TX19_COHERENT_INT_MASK BIT(19) 545 + #define TX18_COHERENT_INT_MASK BIT(18) 546 + #define TX17_COHERENT_INT_MASK BIT(17) 547 + #define TX16_COHERENT_INT_MASK BIT(16) 548 + #define TX15_COHERENT_INT_MASK BIT(15) 549 + #define TX14_COHERENT_INT_MASK BIT(14) 550 + #define TX13_COHERENT_INT_MASK BIT(13) 551 + #define TX12_COHERENT_INT_MASK BIT(12) 552 + #define TX11_COHERENT_INT_MASK BIT(11) 553 + #define TX10_COHERENT_INT_MASK BIT(10) 554 + #define TX9_COHERENT_INT_MASK BIT(9) 555 + #define TX8_COHERENT_INT_MASK BIT(8) 556 + 557 + #define INT_IDX4_MASK \ 558 + (TX8_COHERENT_INT_MASK | TX9_COHERENT_INT_MASK | \ 559 + TX10_COHERENT_INT_MASK | TX11_COHERENT_INT_MASK | \ 560 + TX12_COHERENT_INT_MASK | TX13_COHERENT_INT_MASK | \ 561 + TX14_COHERENT_INT_MASK | TX15_COHERENT_INT_MASK | \ 562 + TX16_COHERENT_INT_MASK | TX17_COHERENT_INT_MASK | \ 563 + TX18_COHERENT_INT_MASK | TX19_COHERENT_INT_MASK | \ 564 + TX20_COHERENT_INT_MASK | TX21_COHERENT_INT_MASK | \ 565 + TX22_COHERENT_INT_MASK | TX23_COHERENT_INT_MASK | \ 566 + TX24_COHERENT_INT_MASK | TX25_COHERENT_INT_MASK | \ 567 + TX26_COHERENT_INT_MASK | TX27_COHERENT_INT_MASK | \ 568 + TX28_COHERENT_INT_MASK | TX29_COHERENT_INT_MASK | \ 569 + TX30_COHERENT_INT_MASK | TX31_COHERENT_INT_MASK) 570 + 571 + #define REG_TX_IRQ_BASE(_n) ((_n) ? 0x0048 : 0x0050) 572 + 573 + #define REG_TX_IRQ_CFG(_n) ((_n) ? 0x004c : 0x0054) 574 + #define TX_IRQ_THR_MASK GENMASK(27, 16) 575 + #define TX_IRQ_DEPTH_MASK GENMASK(11, 0) 576 + 577 + #define REG_IRQ_CLEAR_LEN(_n) ((_n) ? 0x0064 : 0x0058) 578 + #define IRQ_CLEAR_LEN_MASK GENMASK(7, 0) 579 + 580 + #define REG_IRQ_STATUS(_n) ((_n) ? 0x0068 : 0x005c) 581 + #define IRQ_ENTRY_LEN_MASK GENMASK(27, 16) 582 + #define IRQ_HEAD_IDX_MASK GENMASK(11, 0) 583 + 584 + #define REG_TX_RING_BASE(_n) \ 585 + (((_n) < 8) ? 0x0100 + ((_n) << 5) : 0x0b00 + (((_n) - 8) << 5)) 586 + 587 + #define REG_TX_RING_BLOCKING(_n) \ 588 + (((_n) < 8) ? 0x0104 + ((_n) << 5) : 0x0b04 + (((_n) - 8) << 5)) 589 + 590 + #define TX_RING_IRQ_BLOCKING_MAP_MASK BIT(6) 591 + #define TX_RING_IRQ_BLOCKING_CFG_MASK BIT(4) 592 + #define TX_RING_IRQ_BLOCKING_TX_DROP_EN_MASK BIT(2) 593 + #define TX_RING_IRQ_BLOCKING_MAX_TH_TXRING_EN_MASK BIT(1) 594 + #define TX_RING_IRQ_BLOCKING_MIN_TH_TXRING_EN_MASK BIT(0) 595 + 596 + #define REG_TX_CPU_IDX(_n) \ 597 + (((_n) < 8) ? 0x0108 + ((_n) << 5) : 0x0b08 + (((_n) - 8) << 5)) 598 + 599 + #define TX_RING_CPU_IDX_MASK GENMASK(15, 0) 600 + 601 + #define REG_TX_DMA_IDX(_n) \ 602 + (((_n) < 8) ? 0x010c + ((_n) << 5) : 0x0b0c + (((_n) - 8) << 5)) 603 + 604 + #define TX_RING_DMA_IDX_MASK GENMASK(15, 0) 605 + 606 + #define IRQ_RING_IDX_MASK GENMASK(20, 16) 607 + #define IRQ_DESC_IDX_MASK GENMASK(15, 0) 608 + 609 + #define REG_RX_RING_BASE(_n) \ 610 + (((_n) < 16) ? 0x0200 + ((_n) << 5) : 0x0e00 + (((_n) - 16) << 5)) 611 + 612 + #define REG_RX_RING_SIZE(_n) \ 613 + (((_n) < 16) ? 0x0204 + ((_n) << 5) : 0x0e04 + (((_n) - 16) << 5)) 614 + 615 + #define RX_RING_THR_MASK GENMASK(31, 16) 616 + #define RX_RING_SIZE_MASK GENMASK(15, 0) 617 + 618 + #define REG_RX_CPU_IDX(_n) \ 619 + (((_n) < 16) ? 0x0208 + ((_n) << 5) : 0x0e08 + (((_n) - 16) << 5)) 620 + 621 + #define RX_RING_CPU_IDX_MASK GENMASK(15, 0) 622 + 623 + #define REG_RX_DMA_IDX(_n) \ 624 + (((_n) < 16) ? 0x020c + ((_n) << 5) : 0x0e0c + (((_n) - 16) << 5)) 625 + 626 + #define REG_RX_DELAY_INT_IDX(_n) \ 627 + (((_n) < 16) ? 0x0210 + ((_n) << 5) : 0x0e10 + (((_n) - 16) << 5)) 628 + 629 + #define RX_DELAY_INT_MASK GENMASK(15, 0) 630 + 631 + #define RX_RING_DMA_IDX_MASK GENMASK(15, 0) 632 + 633 + #define REG_INGRESS_TRTCM_CFG 0x0070 634 + #define INGRESS_TRTCM_EN_MASK BIT(31) 635 + #define INGRESS_TRTCM_MODE_MASK BIT(30) 636 + #define INGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) 637 + #define INGRESS_FAST_TICK_MASK GENMASK(15, 0) 638 + 639 + #define REG_QUEUE_CLOSE_CFG(_n) (0x00a0 + ((_n) & 0xfc)) 640 + #define TXQ_DISABLE_CHAN_QUEUE_MASK(_n, _m) BIT((_m) + (((_n) & 0x3) << 3)) 641 + 642 + #define REG_TXQ_DIS_CFG_BASE(_n) ((_n) ? 0x20a0 : 0x00a0) 643 + #define REG_TXQ_DIS_CFG(_n, _m) (REG_TXQ_DIS_CFG_BASE((_n)) + (_m) << 2) 644 + 645 + #define REG_CNTR_CFG(_n) (0x0400 + ((_n) << 3)) 646 + #define CNTR_EN_MASK BIT(31) 647 + #define CNTR_ALL_CHAN_EN_MASK BIT(30) 648 + #define CNTR_ALL_QUEUE_EN_MASK BIT(29) 649 + #define CNTR_ALL_DSCP_RING_EN_MASK BIT(28) 650 + #define CNTR_SRC_MASK GENMASK(27, 24) 651 + #define CNTR_DSCP_RING_MASK GENMASK(20, 16) 652 + #define CNTR_CHAN_MASK GENMASK(7, 3) 653 + #define CNTR_QUEUE_MASK GENMASK(2, 0) 654 + 655 + #define REG_CNTR_VAL(_n) (0x0404 + ((_n) << 3)) 656 + 657 + #define REG_LMGR_INIT_CFG 0x1000 658 + #define LMGR_INIT_START BIT(31) 659 + #define LMGR_SRAM_MODE_MASK BIT(30) 660 + #define HW_FWD_PKTSIZE_OVERHEAD_MASK GENMASK(27, 20) 661 + #define HW_FWD_DESC_NUM_MASK GENMASK(16, 0) 662 + 663 + #define REG_FWD_DSCP_LOW_THR 0x1004 664 + #define FWD_DSCP_LOW_THR_MASK GENMASK(17, 0) 665 + 666 + #define REG_EGRESS_RATE_METER_CFG 0x100c 667 + #define EGRESS_RATE_METER_EN_MASK BIT(31) 668 + #define EGRESS_RATE_METER_EQ_RATE_EN_MASK BIT(17) 669 + #define EGRESS_RATE_METER_WINDOW_SZ_MASK GENMASK(16, 12) 670 + #define EGRESS_RATE_METER_TIMESLICE_MASK GENMASK(10, 0) 671 + 672 + #define REG_EGRESS_TRTCM_CFG 0x1010 673 + #define EGRESS_TRTCM_EN_MASK BIT(31) 674 + #define EGRESS_TRTCM_MODE_MASK BIT(30) 675 + #define EGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) 676 + #define EGRESS_FAST_TICK_MASK GENMASK(15, 0) 677 + 678 + #define TRTCM_PARAM_RW_MASK BIT(31) 679 + #define TRTCM_PARAM_RW_DONE_MASK BIT(30) 680 + #define TRTCM_PARAM_TYPE_MASK GENMASK(29, 28) 681 + #define TRTCM_METER_GROUP_MASK GENMASK(27, 26) 682 + #define TRTCM_PARAM_INDEX_MASK GENMASK(23, 17) 683 + #define TRTCM_PARAM_RATE_TYPE_MASK BIT(16) 684 + 685 + #define REG_TRTCM_CFG_PARAM(_n) ((_n) + 0x4) 686 + #define REG_TRTCM_DATA_LOW(_n) ((_n) + 0x8) 687 + #define REG_TRTCM_DATA_HIGH(_n) ((_n) + 0xc) 688 + 689 + #define REG_TXWRR_MODE_CFG 0x1020 690 + #define TWRR_WEIGHT_SCALE_MASK BIT(31) 691 + #define TWRR_WEIGHT_BASE_MASK BIT(3) 692 + 693 + #define REG_TXWRR_WEIGHT_CFG 0x1024 694 + #define TWRR_RW_CMD_MASK BIT(31) 695 + #define TWRR_RW_CMD_DONE BIT(30) 696 + #define TWRR_CHAN_IDX_MASK GENMASK(23, 19) 697 + #define TWRR_QUEUE_IDX_MASK GENMASK(18, 16) 698 + #define TWRR_VALUE_MASK GENMASK(15, 0) 699 + 700 + #define REG_PSE_BUF_USAGE_CFG 0x1028 701 + #define PSE_BUF_ESTIMATE_EN_MASK BIT(29) 702 + 703 + #define REG_CHAN_QOS_MODE(_n) (0x1040 + ((_n) << 2)) 704 + #define CHAN_QOS_MODE_MASK(_n) GENMASK(2 + ((_n) << 2), (_n) << 2) 705 + 706 + #define REG_GLB_TRTCM_CFG 0x1080 707 + #define GLB_TRTCM_EN_MASK BIT(31) 708 + #define GLB_TRTCM_MODE_MASK BIT(30) 709 + #define GLB_SLOW_TICK_RATIO_MASK GENMASK(29, 16) 710 + #define GLB_FAST_TICK_MASK GENMASK(15, 0) 711 + 712 + #define REG_TXQ_CNGST_CFG 0x10a0 713 + #define TXQ_CNGST_DROP_EN BIT(31) 714 + #define TXQ_CNGST_DEI_DROP_EN BIT(30) 715 + 716 + #define REG_SLA_TRTCM_CFG 0x1150 717 + #define SLA_TRTCM_EN_MASK BIT(31) 718 + #define SLA_TRTCM_MODE_MASK BIT(30) 719 + #define SLA_SLOW_TICK_RATIO_MASK GENMASK(29, 16) 720 + #define SLA_FAST_TICK_MASK GENMASK(15, 0) 721 + 722 + /* CTRL */ 723 + #define QDMA_DESC_DONE_MASK BIT(31) 724 + #define QDMA_DESC_DROP_MASK BIT(30) /* tx: drop - rx: overflow */ 725 + #define QDMA_DESC_MORE_MASK BIT(29) /* more SG elements */ 726 + #define QDMA_DESC_DEI_MASK BIT(25) 727 + #define QDMA_DESC_NO_DROP_MASK BIT(24) 728 + #define QDMA_DESC_LEN_MASK GENMASK(15, 0) 729 + /* DATA */ 730 + #define QDMA_DESC_NEXT_ID_MASK GENMASK(15, 0) 731 + /* TX MSG0 */ 732 + #define QDMA_ETH_TXMSG_MIC_IDX_MASK BIT(30) 733 + #define QDMA_ETH_TXMSG_SP_TAG_MASK GENMASK(29, 14) 734 + #define QDMA_ETH_TXMSG_ICO_MASK BIT(13) 735 + #define QDMA_ETH_TXMSG_UCO_MASK BIT(12) 736 + #define QDMA_ETH_TXMSG_TCO_MASK BIT(11) 737 + #define QDMA_ETH_TXMSG_TSO_MASK BIT(10) 738 + #define QDMA_ETH_TXMSG_FAST_MASK BIT(9) 739 + #define QDMA_ETH_TXMSG_OAM_MASK BIT(8) 740 + #define QDMA_ETH_TXMSG_CHAN_MASK GENMASK(7, 3) 741 + #define QDMA_ETH_TXMSG_QUEUE_MASK GENMASK(2, 0) 742 + /* TX MSG1 */ 743 + #define QDMA_ETH_TXMSG_NO_DROP BIT(31) 744 + #define QDMA_ETH_TXMSG_METER_MASK GENMASK(30, 24) /* 0x7f no meters */ 745 + #define QDMA_ETH_TXMSG_FPORT_MASK GENMASK(23, 20) 746 + #define QDMA_ETH_TXMSG_NBOQ_MASK GENMASK(19, 15) 747 + #define QDMA_ETH_TXMSG_HWF_MASK BIT(14) 748 + #define QDMA_ETH_TXMSG_HOP_MASK BIT(13) 749 + #define QDMA_ETH_TXMSG_PTP_MASK BIT(12) 750 + #define QDMA_ETH_TXMSG_ACNT_G1_MASK GENMASK(10, 6) /* 0x1f do not count */ 751 + #define QDMA_ETH_TXMSG_ACNT_G0_MASK GENMASK(5, 0) /* 0x3f do not count */ 752 + 753 + /* RX MSG0 */ 754 + #define QDMA_ETH_RXMSG_SPTAG GENMASK(21, 14) 755 + /* RX MSG1 */ 756 + #define QDMA_ETH_RXMSG_DEI_MASK BIT(31) 757 + #define QDMA_ETH_RXMSG_IP6_MASK BIT(30) 758 + #define QDMA_ETH_RXMSG_IP4_MASK BIT(29) 759 + #define QDMA_ETH_RXMSG_IP4F_MASK BIT(28) 760 + #define QDMA_ETH_RXMSG_L4_VALID_MASK BIT(27) 761 + #define QDMA_ETH_RXMSG_L4F_MASK BIT(26) 762 + #define QDMA_ETH_RXMSG_SPORT_MASK GENMASK(25, 21) 763 + #define QDMA_ETH_RXMSG_CRSN_MASK GENMASK(20, 16) 764 + #define QDMA_ETH_RXMSG_PPE_ENTRY_MASK GENMASK(15, 0) 765 + 766 + struct airoha_qdma_desc { 767 + __le32 rsv; 768 + __le32 ctrl; 769 + __le32 addr; 770 + __le32 data; 771 + __le32 msg0; 772 + __le32 msg1; 773 + __le32 msg2; 774 + __le32 msg3; 775 + }; 776 + 777 + /* CTRL0 */ 778 + #define QDMA_FWD_DESC_CTX_MASK BIT(31) 779 + #define QDMA_FWD_DESC_RING_MASK GENMASK(30, 28) 780 + #define QDMA_FWD_DESC_IDX_MASK GENMASK(27, 16) 781 + #define QDMA_FWD_DESC_LEN_MASK GENMASK(15, 0) 782 + /* CTRL1 */ 783 + #define QDMA_FWD_DESC_FIRST_IDX_MASK GENMASK(15, 0) 784 + /* CTRL2 */ 785 + #define QDMA_FWD_DESC_MORE_PKT_NUM_MASK GENMASK(2, 0) 786 + 787 + struct airoha_qdma_fwd_desc { 788 + __le32 addr; 789 + __le32 ctrl0; 790 + __le32 ctrl1; 791 + __le32 ctrl2; 792 + __le32 msg0; 793 + __le32 msg1; 794 + __le32 rsv0; 795 + __le32 rsv1; 796 + }; 797 + 798 + #endif /* AIROHA_REGS_H */
-8
drivers/net/ethernet/mediatek/Kconfig
··· 7 7 8 8 if NET_VENDOR_MEDIATEK 9 9 10 - config NET_AIROHA 11 - tristate "Airoha SoC Gigabit Ethernet support" 12 - depends on NET_DSA || !NET_DSA 13 - select PAGE_POOL 14 - help 15 - This driver supports the gigabit ethernet MACs in the 16 - Airoha SoC family. 17 - 18 10 config NET_MEDIATEK_SOC_WED 19 11 depends on ARCH_MEDIATEK || COMPILE_TEST 20 12 def_bool NET_MEDIATEK_SOC != n
-1
drivers/net/ethernet/mediatek/Makefile
··· 11 11 endif 12 12 obj-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_ops.o 13 13 obj-$(CONFIG_NET_MEDIATEK_STAR_EMAC) += mtk_star_emac.o 14 - obj-$(CONFIG_NET_AIROHA) += airoha_eth.o
+287 -992
drivers/net/ethernet/mediatek/airoha_eth.c drivers/net/ethernet/airoha/airoha_eth.c
··· 3 3 * Copyright (c) 2024 AIROHA Inc 4 4 * Author: Lorenzo Bianconi <lorenzo@kernel.org> 5 5 */ 6 - #include <linux/etherdevice.h> 7 - #include <linux/iopoll.h> 8 - #include <linux/kernel.h> 9 - #include <linux/netdevice.h> 10 6 #include <linux/of.h> 11 7 #include <linux/of_net.h> 12 8 #include <linux/platform_device.h> 13 - #include <linux/reset.h> 14 9 #include <linux/tcp.h> 15 10 #include <linux/u64_stats_sync.h> 16 - #include <net/dsa.h> 11 + #include <net/dst_metadata.h> 17 12 #include <net/page_pool/helpers.h> 18 13 #include <net/pkt_cls.h> 19 14 #include <uapi/linux/ppp_defs.h> 20 15 21 - #define AIROHA_MAX_NUM_GDM_PORTS 1 22 - #define AIROHA_MAX_NUM_QDMA 2 23 - #define AIROHA_MAX_NUM_RSTS 3 24 - #define AIROHA_MAX_NUM_XSI_RSTS 5 25 - #define AIROHA_MAX_MTU 2000 26 - #define AIROHA_MAX_PACKET_SIZE 2048 27 - #define AIROHA_NUM_QOS_CHANNELS 4 28 - #define AIROHA_NUM_QOS_QUEUES 8 29 - #define AIROHA_NUM_TX_RING 32 30 - #define AIROHA_NUM_RX_RING 32 31 - #define AIROHA_NUM_NETDEV_TX_RINGS (AIROHA_NUM_TX_RING + \ 32 - AIROHA_NUM_QOS_CHANNELS) 33 - #define AIROHA_FE_MC_MAX_VLAN_TABLE 64 34 - #define AIROHA_FE_MC_MAX_VLAN_PORT 16 35 - #define AIROHA_NUM_TX_IRQ 2 36 - #define HW_DSCP_NUM 2048 37 - #define IRQ_QUEUE_LEN(_n) ((_n) ? 1024 : 2048) 38 - #define TX_DSCP_NUM 1024 39 - #define RX_DSCP_NUM(_n) \ 40 - ((_n) == 2 ? 128 : \ 41 - (_n) == 11 ? 128 : \ 42 - (_n) == 15 ? 128 : \ 43 - (_n) == 0 ? 1024 : 16) 16 + #include "airoha_regs.h" 17 + #include "airoha_eth.h" 44 18 45 - #define PSE_RSV_PAGES 128 46 - #define PSE_QUEUE_RSV_PAGES 64 47 - 48 - #define QDMA_METER_IDX(_n) ((_n) & 0xff) 49 - #define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3) 50 - 51 - /* FE */ 52 - #define PSE_BASE 0x0100 53 - #define CSR_IFC_BASE 0x0200 54 - #define CDM1_BASE 0x0400 55 - #define GDM1_BASE 0x0500 56 - #define PPE1_BASE 0x0c00 57 - 58 - #define CDM2_BASE 0x1400 59 - #define GDM2_BASE 0x1500 60 - 61 - #define GDM3_BASE 0x1100 62 - #define GDM4_BASE 0x2500 63 - 64 - #define GDM_BASE(_n) \ 65 - ((_n) == 4 ? GDM4_BASE : \ 66 - (_n) == 3 ? GDM3_BASE : \ 67 - (_n) == 2 ? GDM2_BASE : GDM1_BASE) 68 - 69 - #define REG_FE_DMA_GLO_CFG 0x0000 70 - #define FE_DMA_GLO_L2_SPACE_MASK GENMASK(7, 4) 71 - #define FE_DMA_GLO_PG_SZ_MASK BIT(3) 72 - 73 - #define REG_FE_RST_GLO_CFG 0x0004 74 - #define FE_RST_GDM4_MBI_ARB_MASK BIT(3) 75 - #define FE_RST_GDM3_MBI_ARB_MASK BIT(2) 76 - #define FE_RST_CORE_MASK BIT(0) 77 - 78 - #define REG_FE_WAN_MAC_H 0x0030 79 - #define REG_FE_LAN_MAC_H 0x0040 80 - 81 - #define REG_FE_MAC_LMIN(_n) ((_n) + 0x04) 82 - #define REG_FE_MAC_LMAX(_n) ((_n) + 0x08) 83 - 84 - #define REG_FE_CDM1_OQ_MAP0 0x0050 85 - #define REG_FE_CDM1_OQ_MAP1 0x0054 86 - #define REG_FE_CDM1_OQ_MAP2 0x0058 87 - #define REG_FE_CDM1_OQ_MAP3 0x005c 88 - 89 - #define REG_FE_PCE_CFG 0x0070 90 - #define PCE_DPI_EN_MASK BIT(2) 91 - #define PCE_KA_EN_MASK BIT(1) 92 - #define PCE_MC_EN_MASK BIT(0) 93 - 94 - #define REG_FE_PSE_QUEUE_CFG_WR 0x0080 95 - #define PSE_CFG_PORT_ID_MASK GENMASK(27, 24) 96 - #define PSE_CFG_QUEUE_ID_MASK GENMASK(20, 16) 97 - #define PSE_CFG_WR_EN_MASK BIT(8) 98 - #define PSE_CFG_OQRSV_SEL_MASK BIT(0) 99 - 100 - #define REG_FE_PSE_QUEUE_CFG_VAL 0x0084 101 - #define PSE_CFG_OQ_RSV_MASK GENMASK(13, 0) 102 - 103 - #define PSE_FQ_CFG 0x008c 104 - #define PSE_FQ_LIMIT_MASK GENMASK(14, 0) 105 - 106 - #define REG_FE_PSE_BUF_SET 0x0090 107 - #define PSE_SHARE_USED_LTHD_MASK GENMASK(31, 16) 108 - #define PSE_ALLRSV_MASK GENMASK(14, 0) 109 - 110 - #define REG_PSE_SHARE_USED_THD 0x0094 111 - #define PSE_SHARE_USED_MTHD_MASK GENMASK(31, 16) 112 - #define PSE_SHARE_USED_HTHD_MASK GENMASK(15, 0) 113 - 114 - #define REG_GDM_MISC_CFG 0x0148 115 - #define GDM2_RDM_ACK_WAIT_PREF_MASK BIT(9) 116 - #define GDM2_CHN_VLD_MODE_MASK BIT(5) 117 - 118 - #define REG_FE_CSR_IFC_CFG CSR_IFC_BASE 119 - #define FE_IFC_EN_MASK BIT(0) 120 - 121 - #define REG_FE_VIP_PORT_EN 0x01f0 122 - #define REG_FE_IFC_PORT_EN 0x01f4 123 - 124 - #define REG_PSE_IQ_REV1 (PSE_BASE + 0x08) 125 - #define PSE_IQ_RES1_P2_MASK GENMASK(23, 16) 126 - 127 - #define REG_PSE_IQ_REV2 (PSE_BASE + 0x0c) 128 - #define PSE_IQ_RES2_P5_MASK GENMASK(15, 8) 129 - #define PSE_IQ_RES2_P4_MASK GENMASK(7, 0) 130 - 131 - #define REG_FE_VIP_EN(_n) (0x0300 + ((_n) << 3)) 132 - #define PATN_FCPU_EN_MASK BIT(7) 133 - #define PATN_SWP_EN_MASK BIT(6) 134 - #define PATN_DP_EN_MASK BIT(5) 135 - #define PATN_SP_EN_MASK BIT(4) 136 - #define PATN_TYPE_MASK GENMASK(3, 1) 137 - #define PATN_EN_MASK BIT(0) 138 - 139 - #define REG_FE_VIP_PATN(_n) (0x0304 + ((_n) << 3)) 140 - #define PATN_DP_MASK GENMASK(31, 16) 141 - #define PATN_SP_MASK GENMASK(15, 0) 142 - 143 - #define REG_CDM1_VLAN_CTRL CDM1_BASE 144 - #define CDM1_VLAN_MASK GENMASK(31, 16) 145 - 146 - #define REG_CDM1_FWD_CFG (CDM1_BASE + 0x08) 147 - #define CDM1_VIP_QSEL_MASK GENMASK(24, 20) 148 - 149 - #define REG_CDM1_CRSN_QSEL(_n) (CDM1_BASE + 0x10 + ((_n) << 2)) 150 - #define CDM1_CRSN_QSEL_REASON_MASK(_n) \ 151 - GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) 152 - 153 - #define REG_CDM2_FWD_CFG (CDM2_BASE + 0x08) 154 - #define CDM2_OAM_QSEL_MASK GENMASK(31, 27) 155 - #define CDM2_VIP_QSEL_MASK GENMASK(24, 20) 156 - 157 - #define REG_CDM2_CRSN_QSEL(_n) (CDM2_BASE + 0x10 + ((_n) << 2)) 158 - #define CDM2_CRSN_QSEL_REASON_MASK(_n) \ 159 - GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) 160 - 161 - #define REG_GDM_FWD_CFG(_n) GDM_BASE(_n) 162 - #define GDM_DROP_CRC_ERR BIT(23) 163 - #define GDM_IP4_CKSUM BIT(22) 164 - #define GDM_TCP_CKSUM BIT(21) 165 - #define GDM_UDP_CKSUM BIT(20) 166 - #define GDM_UCFQ_MASK GENMASK(15, 12) 167 - #define GDM_BCFQ_MASK GENMASK(11, 8) 168 - #define GDM_MCFQ_MASK GENMASK(7, 4) 169 - #define GDM_OCFQ_MASK GENMASK(3, 0) 170 - 171 - #define REG_GDM_INGRESS_CFG(_n) (GDM_BASE(_n) + 0x10) 172 - #define GDM_INGRESS_FC_EN_MASK BIT(1) 173 - #define GDM_STAG_EN_MASK BIT(0) 174 - 175 - #define REG_GDM_LEN_CFG(_n) (GDM_BASE(_n) + 0x14) 176 - #define GDM_SHORT_LEN_MASK GENMASK(13, 0) 177 - #define GDM_LONG_LEN_MASK GENMASK(29, 16) 178 - 179 - #define REG_FE_CPORT_CFG (GDM1_BASE + 0x40) 180 - #define FE_CPORT_PAD BIT(26) 181 - #define FE_CPORT_PORT_XFC_MASK BIT(25) 182 - #define FE_CPORT_QUEUE_XFC_MASK BIT(24) 183 - 184 - #define REG_FE_GDM_MIB_CLEAR(_n) (GDM_BASE(_n) + 0xf0) 185 - #define FE_GDM_MIB_RX_CLEAR_MASK BIT(1) 186 - #define FE_GDM_MIB_TX_CLEAR_MASK BIT(0) 187 - 188 - #define REG_FE_GDM1_MIB_CFG (GDM1_BASE + 0xf4) 189 - #define FE_STRICT_RFC2819_MODE_MASK BIT(31) 190 - #define FE_GDM1_TX_MIB_SPLIT_EN_MASK BIT(17) 191 - #define FE_GDM1_RX_MIB_SPLIT_EN_MASK BIT(16) 192 - #define FE_TX_MIB_ID_MASK GENMASK(15, 8) 193 - #define FE_RX_MIB_ID_MASK GENMASK(7, 0) 194 - 195 - #define REG_FE_GDM_TX_OK_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x104) 196 - #define REG_FE_GDM_TX_OK_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x10c) 197 - #define REG_FE_GDM_TX_ETH_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x110) 198 - #define REG_FE_GDM_TX_ETH_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x114) 199 - #define REG_FE_GDM_TX_ETH_DROP_CNT(_n) (GDM_BASE(_n) + 0x118) 200 - #define REG_FE_GDM_TX_ETH_BC_CNT(_n) (GDM_BASE(_n) + 0x11c) 201 - #define REG_FE_GDM_TX_ETH_MC_CNT(_n) (GDM_BASE(_n) + 0x120) 202 - #define REG_FE_GDM_TX_ETH_RUNT_CNT(_n) (GDM_BASE(_n) + 0x124) 203 - #define REG_FE_GDM_TX_ETH_LONG_CNT(_n) (GDM_BASE(_n) + 0x128) 204 - #define REG_FE_GDM_TX_ETH_E64_CNT_L(_n) (GDM_BASE(_n) + 0x12c) 205 - #define REG_FE_GDM_TX_ETH_L64_CNT_L(_n) (GDM_BASE(_n) + 0x130) 206 - #define REG_FE_GDM_TX_ETH_L127_CNT_L(_n) (GDM_BASE(_n) + 0x134) 207 - #define REG_FE_GDM_TX_ETH_L255_CNT_L(_n) (GDM_BASE(_n) + 0x138) 208 - #define REG_FE_GDM_TX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x13c) 209 - #define REG_FE_GDM_TX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x140) 210 - 211 - #define REG_FE_GDM_RX_OK_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x148) 212 - #define REG_FE_GDM_RX_FC_DROP_CNT(_n) (GDM_BASE(_n) + 0x14c) 213 - #define REG_FE_GDM_RX_RC_DROP_CNT(_n) (GDM_BASE(_n) + 0x150) 214 - #define REG_FE_GDM_RX_OVERFLOW_DROP_CNT(_n) (GDM_BASE(_n) + 0x154) 215 - #define REG_FE_GDM_RX_ERROR_DROP_CNT(_n) (GDM_BASE(_n) + 0x158) 216 - #define REG_FE_GDM_RX_OK_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x15c) 217 - #define REG_FE_GDM_RX_ETH_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x160) 218 - #define REG_FE_GDM_RX_ETH_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x164) 219 - #define REG_FE_GDM_RX_ETH_DROP_CNT(_n) (GDM_BASE(_n) + 0x168) 220 - #define REG_FE_GDM_RX_ETH_BC_CNT(_n) (GDM_BASE(_n) + 0x16c) 221 - #define REG_FE_GDM_RX_ETH_MC_CNT(_n) (GDM_BASE(_n) + 0x170) 222 - #define REG_FE_GDM_RX_ETH_CRC_ERR_CNT(_n) (GDM_BASE(_n) + 0x174) 223 - #define REG_FE_GDM_RX_ETH_FRAG_CNT(_n) (GDM_BASE(_n) + 0x178) 224 - #define REG_FE_GDM_RX_ETH_JABBER_CNT(_n) (GDM_BASE(_n) + 0x17c) 225 - #define REG_FE_GDM_RX_ETH_RUNT_CNT(_n) (GDM_BASE(_n) + 0x180) 226 - #define REG_FE_GDM_RX_ETH_LONG_CNT(_n) (GDM_BASE(_n) + 0x184) 227 - #define REG_FE_GDM_RX_ETH_E64_CNT_L(_n) (GDM_BASE(_n) + 0x188) 228 - #define REG_FE_GDM_RX_ETH_L64_CNT_L(_n) (GDM_BASE(_n) + 0x18c) 229 - #define REG_FE_GDM_RX_ETH_L127_CNT_L(_n) (GDM_BASE(_n) + 0x190) 230 - #define REG_FE_GDM_RX_ETH_L255_CNT_L(_n) (GDM_BASE(_n) + 0x194) 231 - #define REG_FE_GDM_RX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x198) 232 - #define REG_FE_GDM_RX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x19c) 233 - 234 - #define REG_PPE1_TB_HASH_CFG (PPE1_BASE + 0x250) 235 - #define PPE1_SRAM_TABLE_EN_MASK BIT(0) 236 - #define PPE1_SRAM_HASH1_EN_MASK BIT(8) 237 - #define PPE1_DRAM_TABLE_EN_MASK BIT(16) 238 - #define PPE1_DRAM_HASH1_EN_MASK BIT(24) 239 - 240 - #define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280) 241 - #define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284) 242 - #define REG_FE_GDM_TX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x288) 243 - #define REG_FE_GDM_TX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x28c) 244 - 245 - #define REG_FE_GDM_RX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x290) 246 - #define REG_FE_GDM_RX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x294) 247 - #define REG_FE_GDM_RX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x298) 248 - #define REG_FE_GDM_RX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x29c) 249 - #define REG_FE_GDM_TX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2b8) 250 - #define REG_FE_GDM_TX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2bc) 251 - #define REG_FE_GDM_TX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2c0) 252 - #define REG_FE_GDM_TX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2c4) 253 - #define REG_FE_GDM_TX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2c8) 254 - #define REG_FE_GDM_TX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2cc) 255 - #define REG_FE_GDM_RX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2e8) 256 - #define REG_FE_GDM_RX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2ec) 257 - #define REG_FE_GDM_RX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2f0) 258 - #define REG_FE_GDM_RX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2f4) 259 - #define REG_FE_GDM_RX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2f8) 260 - #define REG_FE_GDM_RX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2fc) 261 - 262 - #define REG_GDM2_CHN_RLS (GDM2_BASE + 0x20) 263 - #define MBI_RX_AGE_SEL_MASK GENMASK(26, 25) 264 - #define MBI_TX_AGE_SEL_MASK GENMASK(18, 17) 265 - 266 - #define REG_GDM3_FWD_CFG GDM3_BASE 267 - #define GDM3_PAD_EN_MASK BIT(28) 268 - 269 - #define REG_GDM4_FWD_CFG GDM4_BASE 270 - #define GDM4_PAD_EN_MASK BIT(28) 271 - #define GDM4_SPORT_OFFSET0_MASK GENMASK(11, 8) 272 - 273 - #define REG_GDM4_SRC_PORT_SET (GDM4_BASE + 0x23c) 274 - #define GDM4_SPORT_OFF2_MASK GENMASK(19, 16) 275 - #define GDM4_SPORT_OFF1_MASK GENMASK(15, 12) 276 - #define GDM4_SPORT_OFF0_MASK GENMASK(11, 8) 277 - 278 - #define REG_IP_FRAG_FP 0x2010 279 - #define IP_ASSEMBLE_PORT_MASK GENMASK(24, 21) 280 - #define IP_ASSEMBLE_NBQ_MASK GENMASK(20, 16) 281 - #define IP_FRAGMENT_PORT_MASK GENMASK(8, 5) 282 - #define IP_FRAGMENT_NBQ_MASK GENMASK(4, 0) 283 - 284 - #define REG_MC_VLAN_EN 0x2100 285 - #define MC_VLAN_EN_MASK BIT(0) 286 - 287 - #define REG_MC_VLAN_CFG 0x2104 288 - #define MC_VLAN_CFG_CMD_DONE_MASK BIT(31) 289 - #define MC_VLAN_CFG_TABLE_ID_MASK GENMASK(21, 16) 290 - #define MC_VLAN_CFG_PORT_ID_MASK GENMASK(11, 8) 291 - #define MC_VLAN_CFG_TABLE_SEL_MASK BIT(4) 292 - #define MC_VLAN_CFG_RW_MASK BIT(0) 293 - 294 - #define REG_MC_VLAN_DATA 0x2108 295 - 296 - #define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4 297 - 298 - /* QDMA */ 299 - #define REG_QDMA_GLOBAL_CFG 0x0004 300 - #define GLOBAL_CFG_RX_2B_OFFSET_MASK BIT(31) 301 - #define GLOBAL_CFG_DMA_PREFERENCE_MASK GENMASK(30, 29) 302 - #define GLOBAL_CFG_CPU_TXR_RR_MASK BIT(28) 303 - #define GLOBAL_CFG_DSCP_BYTE_SWAP_MASK BIT(27) 304 - #define GLOBAL_CFG_PAYLOAD_BYTE_SWAP_MASK BIT(26) 305 - #define GLOBAL_CFG_MULTICAST_MODIFY_FP_MASK BIT(25) 306 - #define GLOBAL_CFG_OAM_MODIFY_MASK BIT(24) 307 - #define GLOBAL_CFG_RESET_MASK BIT(23) 308 - #define GLOBAL_CFG_RESET_DONE_MASK BIT(22) 309 - #define GLOBAL_CFG_MULTICAST_EN_MASK BIT(21) 310 - #define GLOBAL_CFG_IRQ1_EN_MASK BIT(20) 311 - #define GLOBAL_CFG_IRQ0_EN_MASK BIT(19) 312 - #define GLOBAL_CFG_LOOPCNT_EN_MASK BIT(18) 313 - #define GLOBAL_CFG_RD_BYPASS_WR_MASK BIT(17) 314 - #define GLOBAL_CFG_QDMA_LOOPBACK_MASK BIT(16) 315 - #define GLOBAL_CFG_LPBK_RXQ_SEL_MASK GENMASK(13, 8) 316 - #define GLOBAL_CFG_CHECK_DONE_MASK BIT(7) 317 - #define GLOBAL_CFG_TX_WB_DONE_MASK BIT(6) 318 - #define GLOBAL_CFG_MAX_ISSUE_NUM_MASK GENMASK(5, 4) 319 - #define GLOBAL_CFG_RX_DMA_BUSY_MASK BIT(3) 320 - #define GLOBAL_CFG_RX_DMA_EN_MASK BIT(2) 321 - #define GLOBAL_CFG_TX_DMA_BUSY_MASK BIT(1) 322 - #define GLOBAL_CFG_TX_DMA_EN_MASK BIT(0) 323 - 324 - #define REG_FWD_DSCP_BASE 0x0010 325 - #define REG_FWD_BUF_BASE 0x0014 326 - 327 - #define REG_HW_FWD_DSCP_CFG 0x0018 328 - #define HW_FWD_DSCP_PAYLOAD_SIZE_MASK GENMASK(29, 28) 329 - #define HW_FWD_DSCP_SCATTER_LEN_MASK GENMASK(17, 16) 330 - #define HW_FWD_DSCP_MIN_SCATTER_LEN_MASK GENMASK(15, 0) 331 - 332 - #define REG_INT_STATUS(_n) \ 333 - (((_n) == 4) ? 0x0730 : \ 334 - ((_n) == 3) ? 0x0724 : \ 335 - ((_n) == 2) ? 0x0720 : \ 336 - ((_n) == 1) ? 0x0024 : 0x0020) 337 - 338 - #define REG_INT_ENABLE(_n) \ 339 - (((_n) == 4) ? 0x0750 : \ 340 - ((_n) == 3) ? 0x0744 : \ 341 - ((_n) == 2) ? 0x0740 : \ 342 - ((_n) == 1) ? 0x002c : 0x0028) 343 - 344 - /* QDMA_CSR_INT_ENABLE1 */ 345 - #define RX15_COHERENT_INT_MASK BIT(31) 346 - #define RX14_COHERENT_INT_MASK BIT(30) 347 - #define RX13_COHERENT_INT_MASK BIT(29) 348 - #define RX12_COHERENT_INT_MASK BIT(28) 349 - #define RX11_COHERENT_INT_MASK BIT(27) 350 - #define RX10_COHERENT_INT_MASK BIT(26) 351 - #define RX9_COHERENT_INT_MASK BIT(25) 352 - #define RX8_COHERENT_INT_MASK BIT(24) 353 - #define RX7_COHERENT_INT_MASK BIT(23) 354 - #define RX6_COHERENT_INT_MASK BIT(22) 355 - #define RX5_COHERENT_INT_MASK BIT(21) 356 - #define RX4_COHERENT_INT_MASK BIT(20) 357 - #define RX3_COHERENT_INT_MASK BIT(19) 358 - #define RX2_COHERENT_INT_MASK BIT(18) 359 - #define RX1_COHERENT_INT_MASK BIT(17) 360 - #define RX0_COHERENT_INT_MASK BIT(16) 361 - #define TX7_COHERENT_INT_MASK BIT(15) 362 - #define TX6_COHERENT_INT_MASK BIT(14) 363 - #define TX5_COHERENT_INT_MASK BIT(13) 364 - #define TX4_COHERENT_INT_MASK BIT(12) 365 - #define TX3_COHERENT_INT_MASK BIT(11) 366 - #define TX2_COHERENT_INT_MASK BIT(10) 367 - #define TX1_COHERENT_INT_MASK BIT(9) 368 - #define TX0_COHERENT_INT_MASK BIT(8) 369 - #define CNT_OVER_FLOW_INT_MASK BIT(7) 370 - #define IRQ1_FULL_INT_MASK BIT(5) 371 - #define IRQ1_INT_MASK BIT(4) 372 - #define HWFWD_DSCP_LOW_INT_MASK BIT(3) 373 - #define HWFWD_DSCP_EMPTY_INT_MASK BIT(2) 374 - #define IRQ0_FULL_INT_MASK BIT(1) 375 - #define IRQ0_INT_MASK BIT(0) 376 - 377 - #define TX_DONE_INT_MASK(_n) \ 378 - ((_n) ? IRQ1_INT_MASK | IRQ1_FULL_INT_MASK \ 379 - : IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) 380 - 381 - #define INT_TX_MASK \ 382 - (IRQ1_INT_MASK | IRQ1_FULL_INT_MASK | \ 383 - IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) 384 - 385 - #define INT_IDX0_MASK \ 386 - (TX0_COHERENT_INT_MASK | TX1_COHERENT_INT_MASK | \ 387 - TX2_COHERENT_INT_MASK | TX3_COHERENT_INT_MASK | \ 388 - TX4_COHERENT_INT_MASK | TX5_COHERENT_INT_MASK | \ 389 - TX6_COHERENT_INT_MASK | TX7_COHERENT_INT_MASK | \ 390 - RX0_COHERENT_INT_MASK | RX1_COHERENT_INT_MASK | \ 391 - RX2_COHERENT_INT_MASK | RX3_COHERENT_INT_MASK | \ 392 - RX4_COHERENT_INT_MASK | RX7_COHERENT_INT_MASK | \ 393 - RX8_COHERENT_INT_MASK | RX9_COHERENT_INT_MASK | \ 394 - RX15_COHERENT_INT_MASK | INT_TX_MASK) 395 - 396 - /* QDMA_CSR_INT_ENABLE2 */ 397 - #define RX15_NO_CPU_DSCP_INT_MASK BIT(31) 398 - #define RX14_NO_CPU_DSCP_INT_MASK BIT(30) 399 - #define RX13_NO_CPU_DSCP_INT_MASK BIT(29) 400 - #define RX12_NO_CPU_DSCP_INT_MASK BIT(28) 401 - #define RX11_NO_CPU_DSCP_INT_MASK BIT(27) 402 - #define RX10_NO_CPU_DSCP_INT_MASK BIT(26) 403 - #define RX9_NO_CPU_DSCP_INT_MASK BIT(25) 404 - #define RX8_NO_CPU_DSCP_INT_MASK BIT(24) 405 - #define RX7_NO_CPU_DSCP_INT_MASK BIT(23) 406 - #define RX6_NO_CPU_DSCP_INT_MASK BIT(22) 407 - #define RX5_NO_CPU_DSCP_INT_MASK BIT(21) 408 - #define RX4_NO_CPU_DSCP_INT_MASK BIT(20) 409 - #define RX3_NO_CPU_DSCP_INT_MASK BIT(19) 410 - #define RX2_NO_CPU_DSCP_INT_MASK BIT(18) 411 - #define RX1_NO_CPU_DSCP_INT_MASK BIT(17) 412 - #define RX0_NO_CPU_DSCP_INT_MASK BIT(16) 413 - #define RX15_DONE_INT_MASK BIT(15) 414 - #define RX14_DONE_INT_MASK BIT(14) 415 - #define RX13_DONE_INT_MASK BIT(13) 416 - #define RX12_DONE_INT_MASK BIT(12) 417 - #define RX11_DONE_INT_MASK BIT(11) 418 - #define RX10_DONE_INT_MASK BIT(10) 419 - #define RX9_DONE_INT_MASK BIT(9) 420 - #define RX8_DONE_INT_MASK BIT(8) 421 - #define RX7_DONE_INT_MASK BIT(7) 422 - #define RX6_DONE_INT_MASK BIT(6) 423 - #define RX5_DONE_INT_MASK BIT(5) 424 - #define RX4_DONE_INT_MASK BIT(4) 425 - #define RX3_DONE_INT_MASK BIT(3) 426 - #define RX2_DONE_INT_MASK BIT(2) 427 - #define RX1_DONE_INT_MASK BIT(1) 428 - #define RX0_DONE_INT_MASK BIT(0) 429 - 430 - #define RX_DONE_INT_MASK \ 431 - (RX0_DONE_INT_MASK | RX1_DONE_INT_MASK | \ 432 - RX2_DONE_INT_MASK | RX3_DONE_INT_MASK | \ 433 - RX4_DONE_INT_MASK | RX7_DONE_INT_MASK | \ 434 - RX8_DONE_INT_MASK | RX9_DONE_INT_MASK | \ 435 - RX15_DONE_INT_MASK) 436 - #define INT_IDX1_MASK \ 437 - (RX_DONE_INT_MASK | \ 438 - RX0_NO_CPU_DSCP_INT_MASK | RX1_NO_CPU_DSCP_INT_MASK | \ 439 - RX2_NO_CPU_DSCP_INT_MASK | RX3_NO_CPU_DSCP_INT_MASK | \ 440 - RX4_NO_CPU_DSCP_INT_MASK | RX7_NO_CPU_DSCP_INT_MASK | \ 441 - RX8_NO_CPU_DSCP_INT_MASK | RX9_NO_CPU_DSCP_INT_MASK | \ 442 - RX15_NO_CPU_DSCP_INT_MASK) 443 - 444 - /* QDMA_CSR_INT_ENABLE5 */ 445 - #define TX31_COHERENT_INT_MASK BIT(31) 446 - #define TX30_COHERENT_INT_MASK BIT(30) 447 - #define TX29_COHERENT_INT_MASK BIT(29) 448 - #define TX28_COHERENT_INT_MASK BIT(28) 449 - #define TX27_COHERENT_INT_MASK BIT(27) 450 - #define TX26_COHERENT_INT_MASK BIT(26) 451 - #define TX25_COHERENT_INT_MASK BIT(25) 452 - #define TX24_COHERENT_INT_MASK BIT(24) 453 - #define TX23_COHERENT_INT_MASK BIT(23) 454 - #define TX22_COHERENT_INT_MASK BIT(22) 455 - #define TX21_COHERENT_INT_MASK BIT(21) 456 - #define TX20_COHERENT_INT_MASK BIT(20) 457 - #define TX19_COHERENT_INT_MASK BIT(19) 458 - #define TX18_COHERENT_INT_MASK BIT(18) 459 - #define TX17_COHERENT_INT_MASK BIT(17) 460 - #define TX16_COHERENT_INT_MASK BIT(16) 461 - #define TX15_COHERENT_INT_MASK BIT(15) 462 - #define TX14_COHERENT_INT_MASK BIT(14) 463 - #define TX13_COHERENT_INT_MASK BIT(13) 464 - #define TX12_COHERENT_INT_MASK BIT(12) 465 - #define TX11_COHERENT_INT_MASK BIT(11) 466 - #define TX10_COHERENT_INT_MASK BIT(10) 467 - #define TX9_COHERENT_INT_MASK BIT(9) 468 - #define TX8_COHERENT_INT_MASK BIT(8) 469 - 470 - #define INT_IDX4_MASK \ 471 - (TX8_COHERENT_INT_MASK | TX9_COHERENT_INT_MASK | \ 472 - TX10_COHERENT_INT_MASK | TX11_COHERENT_INT_MASK | \ 473 - TX12_COHERENT_INT_MASK | TX13_COHERENT_INT_MASK | \ 474 - TX14_COHERENT_INT_MASK | TX15_COHERENT_INT_MASK | \ 475 - TX16_COHERENT_INT_MASK | TX17_COHERENT_INT_MASK | \ 476 - TX18_COHERENT_INT_MASK | TX19_COHERENT_INT_MASK | \ 477 - TX20_COHERENT_INT_MASK | TX21_COHERENT_INT_MASK | \ 478 - TX22_COHERENT_INT_MASK | TX23_COHERENT_INT_MASK | \ 479 - TX24_COHERENT_INT_MASK | TX25_COHERENT_INT_MASK | \ 480 - TX26_COHERENT_INT_MASK | TX27_COHERENT_INT_MASK | \ 481 - TX28_COHERENT_INT_MASK | TX29_COHERENT_INT_MASK | \ 482 - TX30_COHERENT_INT_MASK | TX31_COHERENT_INT_MASK) 483 - 484 - #define REG_TX_IRQ_BASE(_n) ((_n) ? 0x0048 : 0x0050) 485 - 486 - #define REG_TX_IRQ_CFG(_n) ((_n) ? 0x004c : 0x0054) 487 - #define TX_IRQ_THR_MASK GENMASK(27, 16) 488 - #define TX_IRQ_DEPTH_MASK GENMASK(11, 0) 489 - 490 - #define REG_IRQ_CLEAR_LEN(_n) ((_n) ? 0x0064 : 0x0058) 491 - #define IRQ_CLEAR_LEN_MASK GENMASK(7, 0) 492 - 493 - #define REG_IRQ_STATUS(_n) ((_n) ? 0x0068 : 0x005c) 494 - #define IRQ_ENTRY_LEN_MASK GENMASK(27, 16) 495 - #define IRQ_HEAD_IDX_MASK GENMASK(11, 0) 496 - 497 - #define REG_TX_RING_BASE(_n) \ 498 - (((_n) < 8) ? 0x0100 + ((_n) << 5) : 0x0b00 + (((_n) - 8) << 5)) 499 - 500 - #define REG_TX_RING_BLOCKING(_n) \ 501 - (((_n) < 8) ? 0x0104 + ((_n) << 5) : 0x0b04 + (((_n) - 8) << 5)) 502 - 503 - #define TX_RING_IRQ_BLOCKING_MAP_MASK BIT(6) 504 - #define TX_RING_IRQ_BLOCKING_CFG_MASK BIT(4) 505 - #define TX_RING_IRQ_BLOCKING_TX_DROP_EN_MASK BIT(2) 506 - #define TX_RING_IRQ_BLOCKING_MAX_TH_TXRING_EN_MASK BIT(1) 507 - #define TX_RING_IRQ_BLOCKING_MIN_TH_TXRING_EN_MASK BIT(0) 508 - 509 - #define REG_TX_CPU_IDX(_n) \ 510 - (((_n) < 8) ? 0x0108 + ((_n) << 5) : 0x0b08 + (((_n) - 8) << 5)) 511 - 512 - #define TX_RING_CPU_IDX_MASK GENMASK(15, 0) 513 - 514 - #define REG_TX_DMA_IDX(_n) \ 515 - (((_n) < 8) ? 0x010c + ((_n) << 5) : 0x0b0c + (((_n) - 8) << 5)) 516 - 517 - #define TX_RING_DMA_IDX_MASK GENMASK(15, 0) 518 - 519 - #define IRQ_RING_IDX_MASK GENMASK(20, 16) 520 - #define IRQ_DESC_IDX_MASK GENMASK(15, 0) 521 - 522 - #define REG_RX_RING_BASE(_n) \ 523 - (((_n) < 16) ? 0x0200 + ((_n) << 5) : 0x0e00 + (((_n) - 16) << 5)) 524 - 525 - #define REG_RX_RING_SIZE(_n) \ 526 - (((_n) < 16) ? 0x0204 + ((_n) << 5) : 0x0e04 + (((_n) - 16) << 5)) 527 - 528 - #define RX_RING_THR_MASK GENMASK(31, 16) 529 - #define RX_RING_SIZE_MASK GENMASK(15, 0) 530 - 531 - #define REG_RX_CPU_IDX(_n) \ 532 - (((_n) < 16) ? 0x0208 + ((_n) << 5) : 0x0e08 + (((_n) - 16) << 5)) 533 - 534 - #define RX_RING_CPU_IDX_MASK GENMASK(15, 0) 535 - 536 - #define REG_RX_DMA_IDX(_n) \ 537 - (((_n) < 16) ? 0x020c + ((_n) << 5) : 0x0e0c + (((_n) - 16) << 5)) 538 - 539 - #define REG_RX_DELAY_INT_IDX(_n) \ 540 - (((_n) < 16) ? 0x0210 + ((_n) << 5) : 0x0e10 + (((_n) - 16) << 5)) 541 - 542 - #define RX_DELAY_INT_MASK GENMASK(15, 0) 543 - 544 - #define RX_RING_DMA_IDX_MASK GENMASK(15, 0) 545 - 546 - #define REG_INGRESS_TRTCM_CFG 0x0070 547 - #define INGRESS_TRTCM_EN_MASK BIT(31) 548 - #define INGRESS_TRTCM_MODE_MASK BIT(30) 549 - #define INGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) 550 - #define INGRESS_FAST_TICK_MASK GENMASK(15, 0) 551 - 552 - #define REG_QUEUE_CLOSE_CFG(_n) (0x00a0 + ((_n) & 0xfc)) 553 - #define TXQ_DISABLE_CHAN_QUEUE_MASK(_n, _m) BIT((_m) + (((_n) & 0x3) << 3)) 554 - 555 - #define REG_TXQ_DIS_CFG_BASE(_n) ((_n) ? 0x20a0 : 0x00a0) 556 - #define REG_TXQ_DIS_CFG(_n, _m) (REG_TXQ_DIS_CFG_BASE((_n)) + (_m) << 2) 557 - 558 - #define REG_CNTR_CFG(_n) (0x0400 + ((_n) << 3)) 559 - #define CNTR_EN_MASK BIT(31) 560 - #define CNTR_ALL_CHAN_EN_MASK BIT(30) 561 - #define CNTR_ALL_QUEUE_EN_MASK BIT(29) 562 - #define CNTR_ALL_DSCP_RING_EN_MASK BIT(28) 563 - #define CNTR_SRC_MASK GENMASK(27, 24) 564 - #define CNTR_DSCP_RING_MASK GENMASK(20, 16) 565 - #define CNTR_CHAN_MASK GENMASK(7, 3) 566 - #define CNTR_QUEUE_MASK GENMASK(2, 0) 567 - 568 - #define REG_CNTR_VAL(_n) (0x0404 + ((_n) << 3)) 569 - 570 - #define REG_LMGR_INIT_CFG 0x1000 571 - #define LMGR_INIT_START BIT(31) 572 - #define LMGR_SRAM_MODE_MASK BIT(30) 573 - #define HW_FWD_PKTSIZE_OVERHEAD_MASK GENMASK(27, 20) 574 - #define HW_FWD_DESC_NUM_MASK GENMASK(16, 0) 575 - 576 - #define REG_FWD_DSCP_LOW_THR 0x1004 577 - #define FWD_DSCP_LOW_THR_MASK GENMASK(17, 0) 578 - 579 - #define REG_EGRESS_RATE_METER_CFG 0x100c 580 - #define EGRESS_RATE_METER_EN_MASK BIT(31) 581 - #define EGRESS_RATE_METER_EQ_RATE_EN_MASK BIT(17) 582 - #define EGRESS_RATE_METER_WINDOW_SZ_MASK GENMASK(16, 12) 583 - #define EGRESS_RATE_METER_TIMESLICE_MASK GENMASK(10, 0) 584 - 585 - #define REG_EGRESS_TRTCM_CFG 0x1010 586 - #define EGRESS_TRTCM_EN_MASK BIT(31) 587 - #define EGRESS_TRTCM_MODE_MASK BIT(30) 588 - #define EGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) 589 - #define EGRESS_FAST_TICK_MASK GENMASK(15, 0) 590 - 591 - #define TRTCM_PARAM_RW_MASK BIT(31) 592 - #define TRTCM_PARAM_RW_DONE_MASK BIT(30) 593 - #define TRTCM_PARAM_TYPE_MASK GENMASK(29, 28) 594 - #define TRTCM_METER_GROUP_MASK GENMASK(27, 26) 595 - #define TRTCM_PARAM_INDEX_MASK GENMASK(23, 17) 596 - #define TRTCM_PARAM_RATE_TYPE_MASK BIT(16) 597 - 598 - #define REG_TRTCM_CFG_PARAM(_n) ((_n) + 0x4) 599 - #define REG_TRTCM_DATA_LOW(_n) ((_n) + 0x8) 600 - #define REG_TRTCM_DATA_HIGH(_n) ((_n) + 0xc) 601 - 602 - #define REG_TXWRR_MODE_CFG 0x1020 603 - #define TWRR_WEIGHT_SCALE_MASK BIT(31) 604 - #define TWRR_WEIGHT_BASE_MASK BIT(3) 605 - 606 - #define REG_TXWRR_WEIGHT_CFG 0x1024 607 - #define TWRR_RW_CMD_MASK BIT(31) 608 - #define TWRR_RW_CMD_DONE BIT(30) 609 - #define TWRR_CHAN_IDX_MASK GENMASK(23, 19) 610 - #define TWRR_QUEUE_IDX_MASK GENMASK(18, 16) 611 - #define TWRR_VALUE_MASK GENMASK(15, 0) 612 - 613 - #define REG_PSE_BUF_USAGE_CFG 0x1028 614 - #define PSE_BUF_ESTIMATE_EN_MASK BIT(29) 615 - 616 - #define REG_CHAN_QOS_MODE(_n) (0x1040 + ((_n) << 2)) 617 - #define CHAN_QOS_MODE_MASK(_n) GENMASK(2 + ((_n) << 2), (_n) << 2) 618 - 619 - #define REG_GLB_TRTCM_CFG 0x1080 620 - #define GLB_TRTCM_EN_MASK BIT(31) 621 - #define GLB_TRTCM_MODE_MASK BIT(30) 622 - #define GLB_SLOW_TICK_RATIO_MASK GENMASK(29, 16) 623 - #define GLB_FAST_TICK_MASK GENMASK(15, 0) 624 - 625 - #define REG_TXQ_CNGST_CFG 0x10a0 626 - #define TXQ_CNGST_DROP_EN BIT(31) 627 - #define TXQ_CNGST_DEI_DROP_EN BIT(30) 628 - 629 - #define REG_SLA_TRTCM_CFG 0x1150 630 - #define SLA_TRTCM_EN_MASK BIT(31) 631 - #define SLA_TRTCM_MODE_MASK BIT(30) 632 - #define SLA_SLOW_TICK_RATIO_MASK GENMASK(29, 16) 633 - #define SLA_FAST_TICK_MASK GENMASK(15, 0) 634 - 635 - /* CTRL */ 636 - #define QDMA_DESC_DONE_MASK BIT(31) 637 - #define QDMA_DESC_DROP_MASK BIT(30) /* tx: drop - rx: overflow */ 638 - #define QDMA_DESC_MORE_MASK BIT(29) /* more SG elements */ 639 - #define QDMA_DESC_DEI_MASK BIT(25) 640 - #define QDMA_DESC_NO_DROP_MASK BIT(24) 641 - #define QDMA_DESC_LEN_MASK GENMASK(15, 0) 642 - /* DATA */ 643 - #define QDMA_DESC_NEXT_ID_MASK GENMASK(15, 0) 644 - /* TX MSG0 */ 645 - #define QDMA_ETH_TXMSG_MIC_IDX_MASK BIT(30) 646 - #define QDMA_ETH_TXMSG_SP_TAG_MASK GENMASK(29, 14) 647 - #define QDMA_ETH_TXMSG_ICO_MASK BIT(13) 648 - #define QDMA_ETH_TXMSG_UCO_MASK BIT(12) 649 - #define QDMA_ETH_TXMSG_TCO_MASK BIT(11) 650 - #define QDMA_ETH_TXMSG_TSO_MASK BIT(10) 651 - #define QDMA_ETH_TXMSG_FAST_MASK BIT(9) 652 - #define QDMA_ETH_TXMSG_OAM_MASK BIT(8) 653 - #define QDMA_ETH_TXMSG_CHAN_MASK GENMASK(7, 3) 654 - #define QDMA_ETH_TXMSG_QUEUE_MASK GENMASK(2, 0) 655 - /* TX MSG1 */ 656 - #define QDMA_ETH_TXMSG_NO_DROP BIT(31) 657 - #define QDMA_ETH_TXMSG_METER_MASK GENMASK(30, 24) /* 0x7f no meters */ 658 - #define QDMA_ETH_TXMSG_FPORT_MASK GENMASK(23, 20) 659 - #define QDMA_ETH_TXMSG_NBOQ_MASK GENMASK(19, 15) 660 - #define QDMA_ETH_TXMSG_HWF_MASK BIT(14) 661 - #define QDMA_ETH_TXMSG_HOP_MASK BIT(13) 662 - #define QDMA_ETH_TXMSG_PTP_MASK BIT(12) 663 - #define QDMA_ETH_TXMSG_ACNT_G1_MASK GENMASK(10, 6) /* 0x1f do not count */ 664 - #define QDMA_ETH_TXMSG_ACNT_G0_MASK GENMASK(5, 0) /* 0x3f do not count */ 665 - 666 - /* RX MSG1 */ 667 - #define QDMA_ETH_RXMSG_DEI_MASK BIT(31) 668 - #define QDMA_ETH_RXMSG_IP6_MASK BIT(30) 669 - #define QDMA_ETH_RXMSG_IP4_MASK BIT(29) 670 - #define QDMA_ETH_RXMSG_IP4F_MASK BIT(28) 671 - #define QDMA_ETH_RXMSG_L4_VALID_MASK BIT(27) 672 - #define QDMA_ETH_RXMSG_L4F_MASK BIT(26) 673 - #define QDMA_ETH_RXMSG_SPORT_MASK GENMASK(25, 21) 674 - #define QDMA_ETH_RXMSG_CRSN_MASK GENMASK(20, 16) 675 - #define QDMA_ETH_RXMSG_PPE_ENTRY_MASK GENMASK(15, 0) 676 - 677 - struct airoha_qdma_desc { 678 - __le32 rsv; 679 - __le32 ctrl; 680 - __le32 addr; 681 - __le32 data; 682 - __le32 msg0; 683 - __le32 msg1; 684 - __le32 msg2; 685 - __le32 msg3; 686 - }; 687 - 688 - /* CTRL0 */ 689 - #define QDMA_FWD_DESC_CTX_MASK BIT(31) 690 - #define QDMA_FWD_DESC_RING_MASK GENMASK(30, 28) 691 - #define QDMA_FWD_DESC_IDX_MASK GENMASK(27, 16) 692 - #define QDMA_FWD_DESC_LEN_MASK GENMASK(15, 0) 693 - /* CTRL1 */ 694 - #define QDMA_FWD_DESC_FIRST_IDX_MASK GENMASK(15, 0) 695 - /* CTRL2 */ 696 - #define QDMA_FWD_DESC_MORE_PKT_NUM_MASK GENMASK(2, 0) 697 - 698 - struct airoha_qdma_fwd_desc { 699 - __le32 addr; 700 - __le32 ctrl0; 701 - __le32 ctrl1; 702 - __le32 ctrl2; 703 - __le32 msg0; 704 - __le32 msg1; 705 - __le32 rsv0; 706 - __le32 rsv1; 707 - }; 708 - 709 - enum { 710 - QDMA_INT_REG_IDX0, 711 - QDMA_INT_REG_IDX1, 712 - QDMA_INT_REG_IDX2, 713 - QDMA_INT_REG_IDX3, 714 - QDMA_INT_REG_IDX4, 715 - QDMA_INT_REG_MAX 716 - }; 717 - 718 - enum { 719 - XSI_PCIE0_PORT, 720 - XSI_PCIE1_PORT, 721 - XSI_USB_PORT, 722 - XSI_AE_PORT, 723 - XSI_ETH_PORT, 724 - }; 725 - 726 - enum { 727 - XSI_PCIE0_VIP_PORT_MASK = BIT(22), 728 - XSI_PCIE1_VIP_PORT_MASK = BIT(23), 729 - XSI_USB_VIP_PORT_MASK = BIT(25), 730 - XSI_ETH_VIP_PORT_MASK = BIT(24), 731 - }; 732 - 733 - enum { 734 - DEV_STATE_INITIALIZED, 735 - }; 736 - 737 - enum { 738 - CDM_CRSN_QSEL_Q1 = 1, 739 - CDM_CRSN_QSEL_Q5 = 5, 740 - CDM_CRSN_QSEL_Q6 = 6, 741 - CDM_CRSN_QSEL_Q15 = 15, 742 - }; 743 - 744 - enum { 745 - CRSN_08 = 0x8, 746 - CRSN_21 = 0x15, /* KA */ 747 - CRSN_22 = 0x16, /* hit bind and force route to CPU */ 748 - CRSN_24 = 0x18, 749 - CRSN_25 = 0x19, 750 - }; 751 - 752 - enum { 753 - FE_PSE_PORT_CDM1, 754 - FE_PSE_PORT_GDM1, 755 - FE_PSE_PORT_GDM2, 756 - FE_PSE_PORT_GDM3, 757 - FE_PSE_PORT_PPE1, 758 - FE_PSE_PORT_CDM2, 759 - FE_PSE_PORT_CDM3, 760 - FE_PSE_PORT_CDM4, 761 - FE_PSE_PORT_PPE2, 762 - FE_PSE_PORT_GDM4, 763 - FE_PSE_PORT_CDM5, 764 - FE_PSE_PORT_DROP = 0xf, 765 - }; 766 - 767 - enum tx_sched_mode { 768 - TC_SCH_WRR8, 769 - TC_SCH_SP, 770 - TC_SCH_WRR7, 771 - TC_SCH_WRR6, 772 - TC_SCH_WRR5, 773 - TC_SCH_WRR4, 774 - TC_SCH_WRR3, 775 - TC_SCH_WRR2, 776 - }; 777 - 778 - enum trtcm_param_type { 779 - TRTCM_MISC_MODE, /* meter_en, pps_mode, tick_sel */ 780 - TRTCM_TOKEN_RATE_MODE, 781 - TRTCM_BUCKETSIZE_SHIFT_MODE, 782 - TRTCM_BUCKET_COUNTER_MODE, 783 - }; 784 - 785 - enum trtcm_mode_type { 786 - TRTCM_COMMIT_MODE, 787 - TRTCM_PEAK_MODE, 788 - }; 789 - 790 - enum trtcm_param { 791 - TRTCM_TICK_SEL = BIT(0), 792 - TRTCM_PKT_MODE = BIT(1), 793 - TRTCM_METER_MODE = BIT(2), 794 - }; 795 - 796 - #define MIN_TOKEN_SIZE 4096 797 - #define MAX_TOKEN_SIZE_OFFSET 17 798 - #define TRTCM_TOKEN_RATE_MASK GENMASK(23, 6) 799 - #define TRTCM_TOKEN_RATE_FRACTION_MASK GENMASK(5, 0) 800 - 801 - struct airoha_queue_entry { 802 - union { 803 - void *buf; 804 - struct sk_buff *skb; 805 - }; 806 - dma_addr_t dma_addr; 807 - u16 dma_len; 808 - }; 809 - 810 - struct airoha_queue { 811 - struct airoha_qdma *qdma; 812 - 813 - /* protect concurrent queue accesses */ 814 - spinlock_t lock; 815 - struct airoha_queue_entry *entry; 816 - struct airoha_qdma_desc *desc; 817 - u16 head; 818 - u16 tail; 819 - 820 - int queued; 821 - int ndesc; 822 - int free_thr; 823 - int buf_size; 824 - 825 - struct napi_struct napi; 826 - struct page_pool *page_pool; 827 - }; 828 - 829 - struct airoha_tx_irq_queue { 830 - struct airoha_qdma *qdma; 831 - 832 - struct napi_struct napi; 833 - 834 - int size; 835 - u32 *q; 836 - }; 837 - 838 - struct airoha_hw_stats { 839 - /* protect concurrent hw_stats accesses */ 840 - spinlock_t lock; 841 - struct u64_stats_sync syncp; 842 - 843 - /* get_stats64 */ 844 - u64 rx_ok_pkts; 845 - u64 tx_ok_pkts; 846 - u64 rx_ok_bytes; 847 - u64 tx_ok_bytes; 848 - u64 rx_multicast; 849 - u64 rx_errors; 850 - u64 rx_drops; 851 - u64 tx_drops; 852 - u64 rx_crc_error; 853 - u64 rx_over_errors; 854 - /* ethtool stats */ 855 - u64 tx_broadcast; 856 - u64 tx_multicast; 857 - u64 tx_len[7]; 858 - u64 rx_broadcast; 859 - u64 rx_fragment; 860 - u64 rx_jabber; 861 - u64 rx_len[7]; 862 - }; 863 - 864 - struct airoha_qdma { 865 - struct airoha_eth *eth; 866 - void __iomem *regs; 867 - 868 - /* protect concurrent irqmask accesses */ 869 - spinlock_t irq_lock; 870 - u32 irqmask[QDMA_INT_REG_MAX]; 871 - int irq; 872 - 873 - struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ]; 874 - 875 - struct airoha_queue q_tx[AIROHA_NUM_TX_RING]; 876 - struct airoha_queue q_rx[AIROHA_NUM_RX_RING]; 877 - 878 - /* descriptor and packet buffers for qdma hw forward */ 879 - struct { 880 - void *desc; 881 - void *q; 882 - } hfwd; 883 - }; 884 - 885 - struct airoha_gdm_port { 886 - struct airoha_qdma *qdma; 887 - struct net_device *dev; 888 - int id; 889 - 890 - struct airoha_hw_stats stats; 891 - 892 - DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS); 893 - 894 - /* qos stats counters */ 895 - u64 cpu_tx_packets; 896 - u64 fwd_tx_packets; 897 - }; 898 - 899 - struct airoha_eth { 900 - struct device *dev; 901 - 902 - unsigned long state; 903 - void __iomem *fe_regs; 904 - 905 - struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS]; 906 - struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS]; 907 - 908 - struct net_device *napi_dev; 909 - 910 - struct airoha_qdma qdma[AIROHA_MAX_NUM_QDMA]; 911 - struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS]; 912 - }; 913 - 914 - static u32 airoha_rr(void __iomem *base, u32 offset) 19 + u32 airoha_rr(void __iomem *base, u32 offset) 915 20 { 916 21 return readl(base + offset); 917 22 } 918 23 919 - static void airoha_wr(void __iomem *base, u32 offset, u32 val) 24 + void airoha_wr(void __iomem *base, u32 offset, u32 val) 920 25 { 921 26 writel(val, base + offset); 922 27 } 923 28 924 - static u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val) 29 + u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val) 925 30 { 926 31 val |= (airoha_rr(base, offset) & ~mask); 927 32 airoha_wr(base, offset, val); 928 33 929 34 return val; 930 35 } 931 - 932 - #define airoha_fe_rr(eth, offset) \ 933 - airoha_rr((eth)->fe_regs, (offset)) 934 - #define airoha_fe_wr(eth, offset, val) \ 935 - airoha_wr((eth)->fe_regs, (offset), (val)) 936 - #define airoha_fe_rmw(eth, offset, mask, val) \ 937 - airoha_rmw((eth)->fe_regs, (offset), (mask), (val)) 938 - #define airoha_fe_set(eth, offset, val) \ 939 - airoha_rmw((eth)->fe_regs, (offset), 0, (val)) 940 - #define airoha_fe_clear(eth, offset, val) \ 941 - airoha_rmw((eth)->fe_regs, (offset), (val), 0) 942 - 943 - #define airoha_qdma_rr(qdma, offset) \ 944 - airoha_rr((qdma)->regs, (offset)) 945 - #define airoha_qdma_wr(qdma, offset, val) \ 946 - airoha_wr((qdma)->regs, (offset), (val)) 947 - #define airoha_qdma_rmw(qdma, offset, mask, val) \ 948 - airoha_rmw((qdma)->regs, (offset), (mask), (val)) 949 - #define airoha_qdma_set(qdma, offset, val) \ 950 - airoha_rmw((qdma)->regs, (offset), 0, (val)) 951 - #define airoha_qdma_clear(qdma, offset, val) \ 952 - airoha_rmw((qdma)->regs, (offset), (val), 0) 953 36 954 37 static void airoha_qdma_set_irqmask(struct airoha_qdma *qdma, int index, 955 38 u32 clear, u32 set) ··· 104 1021 FIELD_PREP(GDM_UCFQ_MASK, val)); 105 1022 } 106 1023 107 - static int airoha_set_gdm_port(struct airoha_eth *eth, int port, bool enable) 1024 + static int airoha_set_vip_for_gdm_port(struct airoha_gdm_port *port, 1025 + bool enable) 108 1026 { 109 - u32 val = enable ? FE_PSE_PORT_PPE1 : FE_PSE_PORT_DROP; 110 - u32 vip_port, cfg_addr; 1027 + struct airoha_eth *eth = port->qdma->eth; 1028 + u32 vip_port; 111 1029 112 - switch (port) { 113 - case XSI_PCIE0_PORT: 1030 + switch (port->id) { 1031 + case 3: 1032 + /* FIXME: handle XSI_PCIE1_PORT */ 114 1033 vip_port = XSI_PCIE0_VIP_PORT_MASK; 115 - cfg_addr = REG_GDM_FWD_CFG(3); 116 1034 break; 117 - case XSI_PCIE1_PORT: 118 - vip_port = XSI_PCIE1_VIP_PORT_MASK; 119 - cfg_addr = REG_GDM_FWD_CFG(3); 120 - break; 121 - case XSI_USB_PORT: 122 - vip_port = XSI_USB_VIP_PORT_MASK; 123 - cfg_addr = REG_GDM_FWD_CFG(4); 124 - break; 125 - case XSI_ETH_PORT: 1035 + case 4: 1036 + /* FIXME: handle XSI_USB_PORT */ 126 1037 vip_port = XSI_ETH_VIP_PORT_MASK; 127 - cfg_addr = REG_GDM_FWD_CFG(4); 128 1038 break; 129 1039 default: 130 - return -EINVAL; 1040 + return 0; 131 1041 } 132 1042 133 1043 if (enable) { ··· 131 1055 airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, vip_port); 132 1056 } 133 1057 134 - airoha_set_gdm_port_fwd_cfg(eth, cfg_addr, val); 135 - 136 1058 return 0; 137 - } 138 - 139 - static int airoha_set_gdm_ports(struct airoha_eth *eth, bool enable) 140 - { 141 - const int port_list[] = { 142 - XSI_PCIE0_PORT, 143 - XSI_PCIE1_PORT, 144 - XSI_USB_PORT, 145 - XSI_ETH_PORT 146 - }; 147 - int i, err; 148 - 149 - for (i = 0; i < ARRAY_SIZE(port_list); i++) { 150 - err = airoha_set_gdm_port(eth, port_list[i], enable); 151 - if (err) 152 - goto error; 153 - } 154 - 155 - return 0; 156 - 157 - error: 158 - for (i--; i >= 0; i--) 159 - airoha_set_gdm_port(eth, port_list[i], false); 160 - 161 - return err; 162 1059 } 163 1060 164 1061 static void airoha_fe_maccr_init(struct airoha_eth *eth) ··· 142 1093 airoha_fe_set(eth, REG_GDM_FWD_CFG(p), 143 1094 GDM_TCP_CKSUM | GDM_UDP_CKSUM | GDM_IP4_CKSUM | 144 1095 GDM_DROP_CRC_ERR); 145 - airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(p), 146 - FE_PSE_PORT_CDM1); 147 1096 airoha_fe_rmw(eth, REG_GDM_LEN_CFG(p), 148 1097 GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, 149 1098 FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | ··· 618 1571 while (done < budget) { 619 1572 struct airoha_queue_entry *e = &q->entry[q->tail]; 620 1573 struct airoha_qdma_desc *desc = &q->desc[q->tail]; 1574 + u32 hash, reason, msg1 = le32_to_cpu(desc->msg1); 621 1575 dma_addr_t dma_addr = le32_to_cpu(desc->addr); 622 1576 u32 desc_ctrl = le32_to_cpu(desc->ctrl); 1577 + struct airoha_gdm_port *port; 623 1578 struct sk_buff *skb; 624 1579 int len, p; 625 1580 ··· 649 1600 continue; 650 1601 } 651 1602 1603 + port = eth->ports[p]; 652 1604 skb = napi_build_skb(e->buf, q->buf_size); 653 1605 if (!skb) { 654 1606 page_pool_put_full_page(q->page_pool, ··· 661 1611 skb_reserve(skb, 2); 662 1612 __skb_put(skb, len); 663 1613 skb_mark_for_recycle(skb); 664 - skb->dev = eth->ports[p]->dev; 1614 + skb->dev = port->dev; 665 1615 skb->protocol = eth_type_trans(skb, skb->dev); 666 1616 skb->ip_summed = CHECKSUM_UNNECESSARY; 667 1617 skb_record_rx_queue(skb, qid); 1618 + 1619 + if (netdev_uses_dsa(port->dev)) { 1620 + /* PPE module requires untagged packets to work 1621 + * properly and it provides DSA port index via the 1622 + * DMA descriptor. Report DSA tag to the DSA stack 1623 + * via skb dst info. 1624 + */ 1625 + u32 sptag = FIELD_GET(QDMA_ETH_RXMSG_SPTAG, 1626 + le32_to_cpu(desc->msg0)); 1627 + 1628 + if (sptag < ARRAY_SIZE(port->dsa_meta) && 1629 + port->dsa_meta[sptag]) 1630 + skb_dst_set_noref(skb, 1631 + &port->dsa_meta[sptag]->dst); 1632 + } 1633 + 1634 + hash = FIELD_GET(AIROHA_RXD4_FOE_ENTRY, msg1); 1635 + if (hash != AIROHA_RXD4_FOE_ENTRY) 1636 + skb_set_hash(skb, jhash_1word(hash, 0), 1637 + PKT_HASH_TYPE_L4); 1638 + 1639 + reason = FIELD_GET(AIROHA_RXD4_PPE_CPU_REASON, msg1); 1640 + if (reason == PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) 1641 + airoha_ppe_check_skb(eth->ppe, hash); 1642 + 668 1643 napi_gro_receive(&q->napi, skb); 669 1644 670 1645 done++; ··· 1310 2235 return err; 1311 2236 } 1312 2237 2238 + err = airoha_ppe_init(eth); 2239 + if (err) 2240 + return err; 2241 + 1313 2242 set_bit(DEV_STATE_INITIALIZED, &eth->state); 1314 2243 1315 2244 return 0; ··· 1525 2446 int err; 1526 2447 1527 2448 netif_tx_start_all_queues(dev); 1528 - err = airoha_set_gdm_ports(qdma->eth, true); 2449 + err = airoha_set_vip_for_gdm_port(port, true); 1529 2450 if (err) 1530 2451 return err; 1531 2452 ··· 1539 2460 airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG, 1540 2461 GLOBAL_CFG_TX_DMA_EN_MASK | 1541 2462 GLOBAL_CFG_RX_DMA_EN_MASK); 2463 + atomic_inc(&qdma->users); 1542 2464 1543 2465 return 0; 1544 2466 } ··· 1551 2471 int i, err; 1552 2472 1553 2473 netif_tx_disable(dev); 1554 - err = airoha_set_gdm_ports(qdma->eth, false); 2474 + err = airoha_set_vip_for_gdm_port(port, false); 1555 2475 if (err) 1556 2476 return err; 1557 2477 1558 - airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG, 1559 - GLOBAL_CFG_TX_DMA_EN_MASK | 1560 - GLOBAL_CFG_RX_DMA_EN_MASK); 1561 - 1562 - for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { 1563 - if (!qdma->q_tx[i].ndesc) 1564 - continue; 1565 - 1566 - airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); 2478 + for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) 1567 2479 netdev_tx_reset_subqueue(dev, i); 2480 + 2481 + if (atomic_dec_and_test(&qdma->users)) { 2482 + airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG, 2483 + GLOBAL_CFG_TX_DMA_EN_MASK | 2484 + GLOBAL_CFG_RX_DMA_EN_MASK); 2485 + 2486 + for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { 2487 + if (!qdma->q_tx[i].ndesc) 2488 + continue; 2489 + 2490 + airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); 2491 + } 1568 2492 } 1569 2493 1570 2494 return 0; ··· 1588 2504 return 0; 1589 2505 } 1590 2506 2507 + static void airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) 2508 + { 2509 + u32 pse_port = port->id == 3 ? FE_PSE_PORT_GDM3 : FE_PSE_PORT_GDM4; 2510 + struct airoha_eth *eth = port->qdma->eth; 2511 + u32 chan = port->id == 3 ? 4 : 0; 2512 + 2513 + /* Forward the traffic to the proper GDM port */ 2514 + airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port); 2515 + airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC); 2516 + 2517 + /* Enable GDM2 loopback */ 2518 + airoha_fe_wr(eth, REG_GDM_TXCHN_EN(2), 0xffffffff); 2519 + airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff); 2520 + airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2), 2521 + LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK, 2522 + FIELD_PREP(LPBK_CHAN_MASK, chan) | LPBK_EN_MASK); 2523 + airoha_fe_rmw(eth, REG_GDM_LEN_CFG(2), 2524 + GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, 2525 + FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | 2526 + FIELD_PREP(GDM_LONG_LEN_MASK, AIROHA_MAX_MTU)); 2527 + 2528 + /* Disable VIP and IFC for GDM2 */ 2529 + airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2)); 2530 + airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2)); 2531 + 2532 + if (port->id == 3) { 2533 + /* FIXME: handle XSI_PCE1_PORT */ 2534 + airoha_fe_wr(eth, REG_PPE_DFT_CPORT0(0), 0x5500); 2535 + airoha_fe_rmw(eth, REG_FE_WAN_PORT, 2536 + WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, 2537 + FIELD_PREP(WAN0_MASK, HSGMII_LAN_PCIE0_SRCPORT)); 2538 + airoha_fe_rmw(eth, 2539 + REG_SP_DFT_CPORT(HSGMII_LAN_PCIE0_SRCPORT >> 3), 2540 + SP_CPORT_PCIE0_MASK, 2541 + FIELD_PREP(SP_CPORT_PCIE0_MASK, 2542 + FE_PSE_PORT_CDM2)); 2543 + } else { 2544 + /* FIXME: handle XSI_USB_PORT */ 2545 + airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, 2546 + FC_ID_OF_SRC_PORT24_MASK, 2547 + FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2)); 2548 + airoha_fe_rmw(eth, REG_FE_WAN_PORT, 2549 + WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, 2550 + FIELD_PREP(WAN0_MASK, HSGMII_LAN_ETH_SRCPORT)); 2551 + airoha_fe_rmw(eth, 2552 + REG_SP_DFT_CPORT(HSGMII_LAN_ETH_SRCPORT >> 3), 2553 + SP_CPORT_ETH_MASK, 2554 + FIELD_PREP(SP_CPORT_ETH_MASK, FE_PSE_PORT_CDM2)); 2555 + } 2556 + } 2557 + 1591 2558 static int airoha_dev_init(struct net_device *dev) 1592 2559 { 1593 2560 struct airoha_gdm_port *port = netdev_priv(dev); 2561 + struct airoha_eth *eth = port->qdma->eth; 2562 + u32 pse_port; 1594 2563 1595 2564 airoha_set_macaddr(port, dev->dev_addr); 2565 + 2566 + switch (port->id) { 2567 + case 3: 2568 + case 4: 2569 + /* If GDM2 is active we can't enable loopback */ 2570 + if (!eth->ports[1]) 2571 + airhoha_set_gdm2_loopback(port); 2572 + fallthrough; 2573 + case 2: 2574 + pse_port = FE_PSE_PORT_PPE2; 2575 + break; 2576 + default: 2577 + pse_port = FE_PSE_PORT_PPE1; 2578 + break; 2579 + } 2580 + 2581 + airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id), pse_port); 1596 2582 1597 2583 return 0; 1598 2584 } ··· 1707 2553 return queue < dev->num_tx_queues ? queue : 0; 1708 2554 } 1709 2555 2556 + static u32 airoha_get_dsa_tag(struct sk_buff *skb, struct net_device *dev) 2557 + { 2558 + #if IS_ENABLED(CONFIG_NET_DSA) 2559 + struct ethhdr *ehdr; 2560 + struct dsa_port *dp; 2561 + u8 xmit_tpid; 2562 + u16 tag; 2563 + 2564 + if (!netdev_uses_dsa(dev)) 2565 + return 0; 2566 + 2567 + dp = dev->dsa_ptr; 2568 + if (IS_ERR(dp)) 2569 + return 0; 2570 + 2571 + if (dp->tag_ops->proto != DSA_TAG_PROTO_MTK) 2572 + return 0; 2573 + 2574 + if (skb_cow_head(skb, 0)) 2575 + return 0; 2576 + 2577 + ehdr = (struct ethhdr *)skb->data; 2578 + tag = be16_to_cpu(ehdr->h_proto); 2579 + xmit_tpid = tag >> 8; 2580 + 2581 + switch (xmit_tpid) { 2582 + case MTK_HDR_XMIT_TAGGED_TPID_8100: 2583 + ehdr->h_proto = cpu_to_be16(ETH_P_8021Q); 2584 + tag &= ~(MTK_HDR_XMIT_TAGGED_TPID_8100 << 8); 2585 + break; 2586 + case MTK_HDR_XMIT_TAGGED_TPID_88A8: 2587 + ehdr->h_proto = cpu_to_be16(ETH_P_8021AD); 2588 + tag &= ~(MTK_HDR_XMIT_TAGGED_TPID_88A8 << 8); 2589 + break; 2590 + default: 2591 + /* PPE module requires untagged DSA packets to work properly, 2592 + * so move DSA tag to DMA descriptor. 2593 + */ 2594 + memmove(skb->data + MTK_HDR_LEN, skb->data, 2 * ETH_ALEN); 2595 + __skb_pull(skb, MTK_HDR_LEN); 2596 + break; 2597 + } 2598 + 2599 + return tag; 2600 + #else 2601 + return 0; 2602 + #endif 2603 + } 2604 + 1710 2605 static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, 1711 2606 struct net_device *dev) 1712 2607 { 1713 2608 struct airoha_gdm_port *port = netdev_priv(dev); 1714 - u32 nr_frags = 1 + skb_shinfo(skb)->nr_frags; 1715 - u32 msg0, msg1, len = skb_headlen(skb); 1716 2609 struct airoha_qdma *qdma = port->qdma; 2610 + u32 nr_frags, tag, msg0, msg1, len; 1717 2611 struct netdev_queue *txq; 1718 2612 struct airoha_queue *q; 1719 - void *data = skb->data; 2613 + void *data; 1720 2614 int i, qid; 1721 2615 u16 index; 1722 2616 u8 fport; 1723 2617 1724 2618 qid = skb_get_queue_mapping(skb) % ARRAY_SIZE(qdma->q_tx); 2619 + tag = airoha_get_dsa_tag(skb, dev); 2620 + 1725 2621 msg0 = FIELD_PREP(QDMA_ETH_TXMSG_CHAN_MASK, 1726 2622 qid / AIROHA_NUM_QOS_QUEUES) | 1727 2623 FIELD_PREP(QDMA_ETH_TXMSG_QUEUE_MASK, 1728 - qid % AIROHA_NUM_QOS_QUEUES); 2624 + qid % AIROHA_NUM_QOS_QUEUES) | 2625 + FIELD_PREP(QDMA_ETH_TXMSG_SP_TAG_MASK, tag); 1729 2626 if (skb->ip_summed == CHECKSUM_PARTIAL) 1730 2627 msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TCO_MASK, 1) | 1731 2628 FIELD_PREP(QDMA_ETH_TXMSG_UCO_MASK, 1) | ··· 1807 2602 spin_lock_bh(&q->lock); 1808 2603 1809 2604 txq = netdev_get_tx_queue(dev, qid); 2605 + nr_frags = 1 + skb_shinfo(skb)->nr_frags; 2606 + 1810 2607 if (q->queued + nr_frags > q->ndesc) { 1811 2608 /* not enough space in the queue */ 1812 2609 netif_tx_stop_queue(txq); ··· 1816 2609 return NETDEV_TX_BUSY; 1817 2610 } 1818 2611 2612 + len = skb_headlen(skb); 2613 + data = skb->data; 1819 2614 index = q->head; 2615 + 1820 2616 for (i = 0; i < nr_frags; i++) { 1821 2617 struct airoha_qdma_desc *desc = &q->desc[index]; 1822 2618 struct airoha_queue_entry *e = &q->entry[index]; ··· 2248 3038 return 0; 2249 3039 } 2250 3040 3041 + static int airoha_dev_setup_tc_block(struct airoha_gdm_port *port, 3042 + struct flow_block_offload *f) 3043 + { 3044 + flow_setup_cb_t *cb = airoha_ppe_setup_tc_block_cb; 3045 + static LIST_HEAD(block_cb_list); 3046 + struct flow_block_cb *block_cb; 3047 + 3048 + if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) 3049 + return -EOPNOTSUPP; 3050 + 3051 + f->driver_block_list = &block_cb_list; 3052 + switch (f->command) { 3053 + case FLOW_BLOCK_BIND: 3054 + block_cb = flow_block_cb_lookup(f->block, cb, port->dev); 3055 + if (block_cb) { 3056 + flow_block_cb_incref(block_cb); 3057 + return 0; 3058 + } 3059 + block_cb = flow_block_cb_alloc(cb, port->dev, port->dev, NULL); 3060 + if (IS_ERR(block_cb)) 3061 + return PTR_ERR(block_cb); 3062 + 3063 + flow_block_cb_incref(block_cb); 3064 + flow_block_cb_add(block_cb, f); 3065 + list_add_tail(&block_cb->driver_list, &block_cb_list); 3066 + return 0; 3067 + case FLOW_BLOCK_UNBIND: 3068 + block_cb = flow_block_cb_lookup(f->block, cb, port->dev); 3069 + if (!block_cb) 3070 + return -ENOENT; 3071 + 3072 + if (!flow_block_cb_decref(block_cb)) { 3073 + flow_block_cb_remove(block_cb, f); 3074 + list_del(&block_cb->driver_list); 3075 + } 3076 + return 0; 3077 + default: 3078 + return -EOPNOTSUPP; 3079 + } 3080 + } 3081 + 2251 3082 static void airoha_tc_remove_htb_queue(struct airoha_gdm_port *port, int queue) 2252 3083 { 2253 3084 struct net_device *dev = port->dev; ··· 2372 3121 return airoha_tc_setup_qdisc_ets(port, type_data); 2373 3122 case TC_SETUP_QDISC_HTB: 2374 3123 return airoha_tc_setup_qdisc_htb(port, type_data); 3124 + case TC_SETUP_BLOCK: 3125 + case TC_SETUP_FT: 3126 + return airoha_dev_setup_tc_block(port, type_data); 2375 3127 default: 2376 3128 return -EOPNOTSUPP; 2377 3129 } ··· 2397 3143 .get_rmon_stats = airoha_ethtool_get_rmon_stats, 2398 3144 }; 2399 3145 2400 - static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np) 3146 + static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port) 3147 + { 3148 + int i; 3149 + 3150 + for (i = 0; i < ARRAY_SIZE(port->dsa_meta); i++) { 3151 + struct metadata_dst *md_dst; 3152 + 3153 + md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, 3154 + GFP_KERNEL); 3155 + if (!md_dst) 3156 + return -ENOMEM; 3157 + 3158 + md_dst->u.port_info.port_id = i; 3159 + port->dsa_meta[i] = md_dst; 3160 + } 3161 + 3162 + return 0; 3163 + } 3164 + 3165 + static void airoha_metadata_dst_free(struct airoha_gdm_port *port) 3166 + { 3167 + int i; 3168 + 3169 + for (i = 0; i < ARRAY_SIZE(port->dsa_meta); i++) { 3170 + if (!port->dsa_meta[i]) 3171 + continue; 3172 + 3173 + metadata_dst_free(port->dsa_meta[i]); 3174 + } 3175 + } 3176 + 3177 + static int airoha_alloc_gdm_port(struct airoha_eth *eth, 3178 + struct device_node *np, int index) 2401 3179 { 2402 3180 const __be32 *id_ptr = of_get_property(np, "reg", NULL); 2403 3181 struct airoha_gdm_port *port; 2404 3182 struct airoha_qdma *qdma; 2405 3183 struct net_device *dev; 2406 - int err, index; 3184 + int err, p; 2407 3185 u32 id; 2408 3186 2409 3187 if (!id_ptr) { ··· 2444 3158 } 2445 3159 2446 3160 id = be32_to_cpup(id_ptr); 2447 - index = id - 1; 3161 + p = id - 1; 2448 3162 2449 3163 if (!id || id > ARRAY_SIZE(eth->ports)) { 2450 3164 dev_err(eth->dev, "invalid gdm port id: %d\n", id); 2451 3165 return -EINVAL; 2452 3166 } 2453 3167 2454 - if (eth->ports[index]) { 3168 + if (eth->ports[p]) { 2455 3169 dev_err(eth->dev, "duplicate gdm port id: %d\n", id); 2456 3170 return -EINVAL; 2457 3171 } ··· 2499 3213 port->qdma = qdma; 2500 3214 port->dev = dev; 2501 3215 port->id = id; 2502 - eth->ports[index] = port; 3216 + eth->ports[p] = port; 3217 + 3218 + err = airoha_metadata_dst_alloc(port); 3219 + if (err) 3220 + return err; 2503 3221 2504 3222 return register_netdev(dev); 2505 3223 } ··· 2571 3281 for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) 2572 3282 airoha_qdma_start_napi(&eth->qdma[i]); 2573 3283 3284 + i = 0; 2574 3285 for_each_child_of_node(pdev->dev.of_node, np) { 2575 3286 if (!of_device_is_compatible(np, "airoha,eth-mac")) 2576 3287 continue; ··· 2579 3288 if (!of_device_is_available(np)) 2580 3289 continue; 2581 3290 2582 - err = airoha_alloc_gdm_port(eth, np); 3291 + err = airoha_alloc_gdm_port(eth, np, i++); 2583 3292 if (err) { 2584 3293 of_node_put(np); 2585 3294 goto error_napi_stop; ··· 2598 3307 for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { 2599 3308 struct airoha_gdm_port *port = eth->ports[i]; 2600 3309 2601 - if (port && port->dev->reg_state == NETREG_REGISTERED) 3310 + if (port && port->dev->reg_state == NETREG_REGISTERED) { 2602 3311 unregister_netdev(port->dev); 3312 + airoha_metadata_dst_free(port); 3313 + } 2603 3314 } 2604 3315 free_netdev(eth->napi_dev); 2605 3316 platform_set_drvdata(pdev, NULL); ··· 2627 3334 2628 3335 airoha_dev_stop(port->dev); 2629 3336 unregister_netdev(port->dev); 3337 + airoha_metadata_dst_free(port); 2630 3338 } 2631 3339 free_netdev(eth->napi_dev); 2632 3340 3341 + airoha_ppe_deinit(eth); 2633 3342 platform_set_drvdata(pdev, NULL); 2634 3343 } 2635 3344