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

Merge branch 'add-the-capability-to-consume-sram-for-hwfd-descriptor-queue-in-airoha_eth-driver'

Lorenzo Bianconi says:

====================
Add the capability to consume SRAM for hwfd descriptor queue in airoha_eth driver

In order to improve packet processing and packet forwarding
performances, EN7581 SoC supports consuming SRAM instead of DRAM for hw
forwarding descriptors queue. For downlink hw accelerated traffic
request to consume SRAM memory for hw forwarding descriptors queue.
Moreover, in some configurations QDMA blocks require a contiguous block
of system memory for hwfd buffers queue. Introduce the capability to
allocate hw buffers forwarding queue via the reserved-memory DTS
property instead of running dmam_alloc_coherent().

v2: https://lore.kernel.org/r/20250509-airopha-desc-sram-v2-0-9dc3d8076dfb@kernel.org
v1: https://lore.kernel.org/r/20250507-airopha-desc-sram-v1-0-d42037431bfa@kernel.org
====================

Link: https://patch.msgid.link/20250521-airopha-desc-sram-v3-0-a6e9b085b4f0@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

Paolo Abeni 31eaaa5c e272bbc9

+60 -24
+13
Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
··· 57 57 - const: hsi-mac 58 58 - const: xfp-mac 59 59 60 + memory-region: 61 + items: 62 + - description: QDMA0 buffer memory 63 + - description: QDMA1 buffer memory 64 + 65 + memory-region-names: 66 + items: 67 + - const: qdma0-buf 68 + - const: qdma1-buf 69 + 60 70 "#address-cells": 61 71 const: 1 62 72 ··· 149 139 <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>, 150 140 <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>, 151 141 <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; 142 + 143 + memory-region = <&qdma0_buf>, <&qdma1_buf>; 144 + memory-region-names = "qdma0-buf", "qdma1-buf"; 152 145 153 146 airoha,npu = <&npu>; 154 147
+32 -18
drivers/net/ethernet/airoha/airoha_eth.c
··· 5 5 */ 6 6 #include <linux/of.h> 7 7 #include <linux/of_net.h> 8 + #include <linux/of_reserved_mem.h> 8 9 #include <linux/platform_device.h> 9 10 #include <linux/tcp.h> 10 11 #include <linux/u64_stats_sync.h> ··· 69 68 int index, u32 mask) 70 69 { 71 70 airoha_qdma_set_irqmask(irq_bank, index, mask, 0); 72 - } 73 - 74 - static bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port) 75 - { 76 - /* GDM1 port on EN7581 SoC is connected to the lan dsa switch. 77 - * GDM{2,3,4} can be used as wan port connected to an external 78 - * phy module. 79 - */ 80 - return port->id == 1; 81 71 } 82 72 83 73 static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr) ··· 1064 1072 static int airoha_qdma_init_hfwd_queues(struct airoha_qdma *qdma) 1065 1073 { 1066 1074 struct airoha_eth *eth = qdma->eth; 1075 + int id = qdma - &eth->qdma[0]; 1067 1076 dma_addr_t dma_addr; 1077 + const char *name; 1078 + int size, index; 1068 1079 u32 status; 1069 - int size; 1070 1080 1071 1081 size = HW_DSCP_NUM * sizeof(struct airoha_qdma_fwd_desc); 1072 - qdma->hfwd.desc = dmam_alloc_coherent(eth->dev, size, &dma_addr, 1073 - GFP_KERNEL); 1074 - if (!qdma->hfwd.desc) 1082 + if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, GFP_KERNEL)) 1075 1083 return -ENOMEM; 1076 1084 1077 1085 airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr); 1078 1086 1079 - size = AIROHA_MAX_PACKET_SIZE * HW_DSCP_NUM; 1080 - qdma->hfwd.q = dmam_alloc_coherent(eth->dev, size, &dma_addr, 1081 - GFP_KERNEL); 1082 - if (!qdma->hfwd.q) 1087 + name = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d-buf", id); 1088 + if (!name) 1083 1089 return -ENOMEM; 1090 + 1091 + index = of_property_match_string(eth->dev->of_node, 1092 + "memory-region-names", name); 1093 + if (index >= 0) { 1094 + struct reserved_mem *rmem; 1095 + struct device_node *np; 1096 + 1097 + /* Consume reserved memory for hw forwarding buffers queue if 1098 + * available in the DTS 1099 + */ 1100 + np = of_parse_phandle(eth->dev->of_node, "memory-region", 1101 + index); 1102 + if (!np) 1103 + return -ENODEV; 1104 + 1105 + rmem = of_reserved_mem_lookup(np); 1106 + of_node_put(np); 1107 + dma_addr = rmem->base; 1108 + } else { 1109 + size = AIROHA_MAX_PACKET_SIZE * HW_DSCP_NUM; 1110 + if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, 1111 + GFP_KERNEL)) 1112 + return -ENOMEM; 1113 + } 1084 1114 1085 1115 airoha_qdma_wr(qdma, REG_FWD_BUF_BASE, dma_addr); 1086 1116 ··· 1115 1101 LMGR_INIT_START | LMGR_SRAM_MODE_MASK | 1116 1102 HW_FWD_DESC_NUM_MASK, 1117 1103 FIELD_PREP(HW_FWD_DESC_NUM_MASK, HW_DSCP_NUM) | 1118 - LMGR_INIT_START); 1104 + LMGR_INIT_START | LMGR_SRAM_MODE_MASK); 1119 1105 1120 1106 return read_poll_timeout(airoha_qdma_rr, status, 1121 1107 !(status & LMGR_INIT_START), USEC_PER_MSEC,
+9 -6
drivers/net/ethernet/airoha/airoha_eth.h
··· 513 513 514 514 struct airoha_queue q_tx[AIROHA_NUM_TX_RING]; 515 515 struct airoha_queue q_rx[AIROHA_NUM_RX_RING]; 516 - 517 - /* descriptor and packet buffers for qdma hw forward */ 518 - struct { 519 - void *desc; 520 - void *q; 521 - } hfwd; 522 516 }; 523 517 524 518 struct airoha_gdm_port { ··· 596 602 airoha_rmw((qdma)->regs, (offset), 0, (val)) 597 603 #define airoha_qdma_clear(qdma, offset, val) \ 598 604 airoha_rmw((qdma)->regs, (offset), (val), 0) 605 + 606 + static inline bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port) 607 + { 608 + /* GDM1 port on EN7581 SoC is connected to the lan dsa switch. 609 + * GDM{2,3,4} can be used as wan port connected to an external 610 + * phy module. 611 + */ 612 + return port->id == 1; 613 + } 599 614 600 615 bool airoha_is_valid_gdm_port(struct airoha_eth *eth, 601 616 struct airoha_gdm_port *port);
+6
drivers/net/ethernet/airoha/airoha_ppe.c
··· 251 251 else 252 252 pse_port = 2; /* uplink relies on GDM2 loopback */ 253 253 val |= FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, pse_port); 254 + 255 + /* For downlink traffic consume SRAM memory for hw forwarding 256 + * descriptors queue. 257 + */ 258 + if (airhoa_is_lan_gdm_port(port)) 259 + val |= AIROHA_FOE_IB2_FAST_PATH; 254 260 } 255 261 256 262 if (is_multicast_ether_addr(data->eth.h_dest))