From b0534d0d41808c213e6c1709dcfc37d22b7e9a02 Mon Sep 17 00:00:00 2001 From: Alexandru Gagniuc Date: Sat, 10 Jan 2026 16:12:11 -0600 Subject: [PATCH] qualcommbe: remove upstreamed patches Remove patches that are upstream in v6.18, but were not identified as upstreamed in the patch naming. Signed-off-by: Alexandru Gagniuc Link: https://github.com/openwrt/openwrt/pull/21506 Signed-off-by: Robert Marko --- ...rm64-dts-qcom-ipq9574-Add-nsscc-node.patch | 54 - ...pq9574-fix-the-msi-interrupt-numbers.patch | 44 - ...ts-qcom-ipq9574-Add-SPI-nand-support.patch | 50 - ...-ipq9574-Enable-SPI-NAND-for-ipq9574.patch | 68 -- ...64-dts-qcom-ipq9574-Remove-eMMC-node.patch | 37 - ...net-Add-PPE-for-Qualcomm-IPQ9574-SoC.patch | 432 ------- ...Add-PPE-driver-documentation-for-Qua.patch | 227 ---- ...lcomm-Add-PPE-driver-for-IPQ9574-SoC.patch | 339 ------ ...lcomm-Initialize-PPE-buffer-manageme.patch | 328 ------ ...lcomm-Initialize-PPE-queue-managemen.patch | 320 ------ ...lcomm-Initialize-the-PPE-scheduler-s.patch | 1000 ----------------- ...alcomm-Initialize-PPE-queue-settings.patch | 522 --------- ...lcomm-Initialize-PPE-service-code-se.patch | 384 ------- ...lcomm-Initialize-PPE-port-control-se.patch | 215 ---- ...lcomm-Initialize-PPE-RSS-hash-settin.patch | 344 ------ ...lcomm-Initialize-PPE-queue-to-Ethern.patch | 122 -- ...lcomm-Initialize-PPE-L2-bridge-setti.patch | 193 ---- ...lcomm-Add-PPE-debugfs-support-for-PP.patch | 950 ---------------- 18 files changed, 5629 deletions(-) delete mode 100644 target/linux/qualcommbe/patches-6.18/0100-arm64-dts-qcom-ipq9574-Add-nsscc-node.patch delete mode 100644 target/linux/qualcommbe/patches-6.18/0101-arm64-dts-qcom-ipq9574-fix-the-msi-interrupt-numbers.patch delete mode 100644 target/linux/qualcommbe/patches-6.18/0103-arm64-dts-qcom-ipq9574-Add-SPI-nand-support.patch delete mode 100644 target/linux/qualcommbe/patches-6.18/0104-arm64-dts-qcom-ipq9574-Enable-SPI-NAND-for-ipq9574.patch delete mode 100644 target/linux/qualcommbe/patches-6.18/0105-arm64-dts-qcom-ipq9574-Remove-eMMC-node.patch delete mode 100644 target/linux/qualcommbe/patches-6.18/0323-dt-bindings-net-Add-PPE-for-Qualcomm-IPQ9574-SoC.patch delete mode 100644 target/linux/qualcommbe/patches-6.18/0324-docs-networking-Add-PPE-driver-documentation-for-Qua.patch delete mode 100644 target/linux/qualcommbe/patches-6.18/0325-net-ethernet-qualcomm-Add-PPE-driver-for-IPQ9574-SoC.patch delete mode 100644 target/linux/qualcommbe/patches-6.18/0326-net-ethernet-qualcomm-Initialize-PPE-buffer-manageme.patch delete mode 100644 target/linux/qualcommbe/patches-6.18/0327-net-ethernet-qualcomm-Initialize-PPE-queue-managemen.patch delete mode 100644 target/linux/qualcommbe/patches-6.18/0328-net-ethernet-qualcomm-Initialize-the-PPE-scheduler-s.patch delete mode 100644 target/linux/qualcommbe/patches-6.18/0329-net-ethernet-qualcomm-Initialize-PPE-queue-settings.patch delete mode 100644 target/linux/qualcommbe/patches-6.18/0330-net-ethernet-qualcomm-Initialize-PPE-service-code-se.patch delete mode 100644 target/linux/qualcommbe/patches-6.18/0331-net-ethernet-qualcomm-Initialize-PPE-port-control-se.patch delete mode 100644 target/linux/qualcommbe/patches-6.18/0332-net-ethernet-qualcomm-Initialize-PPE-RSS-hash-settin.patch delete mode 100644 target/linux/qualcommbe/patches-6.18/0333-net-ethernet-qualcomm-Initialize-PPE-queue-to-Ethern.patch delete mode 100644 target/linux/qualcommbe/patches-6.18/0334-net-ethernet-qualcomm-Initialize-PPE-L2-bridge-setti.patch delete mode 100644 target/linux/qualcommbe/patches-6.18/0335-net-ethernet-qualcomm-Add-PPE-debugfs-support-for-PP.patch diff --git a/target/linux/qualcommbe/patches-6.18/0100-arm64-dts-qcom-ipq9574-Add-nsscc-node.patch b/target/linux/qualcommbe/patches-6.18/0100-arm64-dts-qcom-ipq9574-Add-nsscc-node.patch deleted file mode 100644 index c38a7eb09f..0000000000 --- a/target/linux/qualcommbe/patches-6.18/0100-arm64-dts-qcom-ipq9574-Add-nsscc-node.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 52ebd52aa1906961142a2aba55d47a53b956847c Mon Sep 17 00:00:00 2001 -From: Devi Priya -Date: Thu, 13 Mar 2025 16:33:58 +0530 -Subject: [PATCH] arm64: dts: qcom: ipq9574: Add nsscc node - -Add a node for the nss clock controller found on ipq9574 based devices. - -Reviewed-by: Konrad Dybcio -Signed-off-by: Devi Priya -Signed-off-by: Manikanta Mylavarapu -Link: https://lore.kernel.org/r/20250313110359.242491-6-quic_mmanikan@quicinc.com -Signed-off-by: Bjorn Andersson ---- - arch/arm64/boot/dts/qcom/ipq9574.dtsi | 29 +++++++++++++++++++++++++++ - 1 file changed, 29 insertions(+) - ---- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi -+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi -@@ -1195,6 +1195,35 @@ - status = "disabled"; - }; - -+ nsscc: clock-controller@39b00000 { -+ compatible = "qcom,ipq9574-nsscc"; -+ reg = <0x39b00000 0x80000>; -+ clocks = <&xo_board_clk>, -+ <&cmn_pll NSS_1200MHZ_CLK>, -+ <&cmn_pll PPE_353MHZ_CLK>, -+ <&gcc GPLL0_OUT_AUX>, -+ <0>, -+ <0>, -+ <0>, -+ <0>, -+ <0>, -+ <0>, -+ <&gcc GCC_NSSCC_CLK>; -+ clock-names = "xo", -+ "nss_1200", -+ "ppe_353", -+ "gpll0_out", -+ "uniphy0_rx", -+ "uniphy0_tx", -+ "uniphy1_rx", -+ "uniphy1_tx", -+ "uniphy2_rx", -+ "uniphy2_tx", -+ "bus"; -+ #clock-cells = <1>; -+ #reset-cells = <1>; -+ #interconnect-cells = <1>; -+ }; - }; - - thermal-zones { diff --git a/target/linux/qualcommbe/patches-6.18/0101-arm64-dts-qcom-ipq9574-fix-the-msi-interrupt-numbers.patch b/target/linux/qualcommbe/patches-6.18/0101-arm64-dts-qcom-ipq9574-fix-the-msi-interrupt-numbers.patch deleted file mode 100644 index b09fccf32b..0000000000 --- a/target/linux/qualcommbe/patches-6.18/0101-arm64-dts-qcom-ipq9574-fix-the-msi-interrupt-numbers.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 2f2f5ae4d52ea882ba58f6b2fa6373a3d3db2bce Mon Sep 17 00:00:00 2001 -From: Manikanta Mylavarapu -Date: Thu, 13 Mar 2025 12:44:22 +0530 -Subject: [PATCH] arm64: dts: qcom: ipq9574: fix the msi interrupt numbers of - pcie3 - -The MSI interrupt numbers of the PCIe3 controller are incorrect. Due -to this, the functional bring up of the QDSP6 processor on the PCIe -endpoint has failed. Correct the MSI interrupt numbers to properly -bring up the QDSP6 processor on the PCIe endpoint. - -Fixes: d80c7fbfa908 ("arm64: dts: qcom: ipq9574: Add PCIe PHYs and controller nodes") -Signed-off-by: Manikanta Mylavarapu -Link: https://lore.kernel.org/r/20250313071422.510-1-quic_mmanikan@quicinc.com -Signed-off-by: Bjorn Andersson ---- - arch/arm64/boot/dts/qcom/ipq9574.dtsi | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - ---- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi -+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi -@@ -974,14 +974,14 @@ - ranges = <0x01000000 0x0 0x00000000 0x18200000 0x0 0x100000>, - <0x02000000 0x0 0x18300000 0x18300000 0x0 0x7d00000>; - -- interrupts = , -- , -- , -- , -- , -- , -- , -- ; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; - interrupt-names = "msi0", - "msi1", - "msi2", diff --git a/target/linux/qualcommbe/patches-6.18/0103-arm64-dts-qcom-ipq9574-Add-SPI-nand-support.patch b/target/linux/qualcommbe/patches-6.18/0103-arm64-dts-qcom-ipq9574-Add-SPI-nand-support.patch deleted file mode 100644 index 7bec20d943..0000000000 --- a/target/linux/qualcommbe/patches-6.18/0103-arm64-dts-qcom-ipq9574-Add-SPI-nand-support.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 583299efa34c4a484b211f84c63aee78b6c2b469 Mon Sep 17 00:00:00 2001 -From: Md Sadre Alam -Date: Thu, 6 Mar 2025 17:03:55 +0530 -Subject: [PATCH] arm64: dts: qcom: ipq9574: Add SPI nand support - -Add SPI NAND support for ipq9574 SoC. - -Signed-off-by: Md Sadre Alam -Link: https://lore.kernel.org/r/20250306113357.126602-2-quic_mdalam@quicinc.com -Signed-off-by: Bjorn Andersson ---- - arch/arm64/boot/dts/qcom/ipq9574.dtsi | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - ---- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi -+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi -@@ -675,6 +675,33 @@ - status = "disabled"; - }; - -+ qpic_bam: dma-controller@7984000 { -+ compatible = "qcom,bam-v1.7.4", "qcom,bam-v1.7.0"; -+ reg = <0x07984000 0x1c000>; -+ interrupts = ; -+ clocks = <&gcc GCC_QPIC_AHB_CLK>; -+ clock-names = "bam_clk"; -+ #dma-cells = <1>; -+ qcom,ee = <0>; -+ status = "disabled"; -+ }; -+ -+ qpic_nand: spi@79b0000 { -+ compatible = "qcom,ipq9574-snand"; -+ reg = <0x079b0000 0x10000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ clocks = <&gcc GCC_QPIC_CLK>, -+ <&gcc GCC_QPIC_AHB_CLK>, -+ <&gcc GCC_QPIC_IO_MACRO_CLK>; -+ clock-names = "core", "aon", "iom"; -+ dmas = <&qpic_bam 0>, -+ <&qpic_bam 1>, -+ <&qpic_bam 2>; -+ dma-names = "tx", "rx", "cmd"; -+ status = "disabled"; -+ }; -+ - usb_0_qusbphy: phy@7b000 { - compatible = "qcom,ipq9574-qusb2-phy"; - reg = <0x0007b000 0x180>; diff --git a/target/linux/qualcommbe/patches-6.18/0104-arm64-dts-qcom-ipq9574-Enable-SPI-NAND-for-ipq9574.patch b/target/linux/qualcommbe/patches-6.18/0104-arm64-dts-qcom-ipq9574-Enable-SPI-NAND-for-ipq9574.patch deleted file mode 100644 index 393923a343..0000000000 --- a/target/linux/qualcommbe/patches-6.18/0104-arm64-dts-qcom-ipq9574-Enable-SPI-NAND-for-ipq9574.patch +++ /dev/null @@ -1,68 +0,0 @@ -From a7c88bc81632974c0708308493aefb1f871b65fa Mon Sep 17 00:00:00 2001 -From: Md Sadre Alam -Date: Thu, 6 Mar 2025 17:03:56 +0530 -Subject: [PATCH] arm64: dts: qcom: ipq9574: Enable SPI NAND for ipq9574 - -Enable SPI NAND support for ipq9574 SoC. - -Reviewed-by: Konrad Dybcio -Signed-off-by: Md Sadre Alam -Link: https://lore.kernel.org/r/20250306113357.126602-3-quic_mdalam@quicinc.com -Signed-off-by: Bjorn Andersson ---- - .../boot/dts/qcom/ipq9574-rdp-common.dtsi | 44 +++++++++++++++++++ - 1 file changed, 44 insertions(+) - ---- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi -+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi -@@ -146,6 +146,50 @@ - drive-strength = <8>; - bias-pull-up; - }; -+ -+ qpic_snand_default_state: qpic-snand-default-state { -+ clock-pins { -+ pins = "gpio5"; -+ function = "qspi_clk"; -+ drive-strength = <8>; -+ bias-disable; -+ }; -+ -+ cs-pins { -+ pins = "gpio4"; -+ function = "qspi_cs"; -+ drive-strength = <8>; -+ bias-disable; -+ }; -+ -+ data-pins { -+ pins = "gpio0", "gpio1", "gpio2", "gpio3"; -+ function = "qspi_data"; -+ drive-strength = <8>; -+ bias-disable; -+ }; -+ }; -+}; -+ -+&qpic_bam { -+ status = "okay"; -+}; -+ -+&qpic_nand { -+ pinctrl-0 = <&qpic_snand_default_state>; -+ pinctrl-names = "default"; -+ -+ status = "okay"; -+ -+ flash@0 { -+ compatible = "spi-nand"; -+ reg = <0>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ nand-ecc-engine = <&qpic_nand>; -+ nand-ecc-strength = <4>; -+ nand-ecc-step-size = <512>; -+ }; - }; - - &usb_0_dwc3 { diff --git a/target/linux/qualcommbe/patches-6.18/0105-arm64-dts-qcom-ipq9574-Remove-eMMC-node.patch b/target/linux/qualcommbe/patches-6.18/0105-arm64-dts-qcom-ipq9574-Remove-eMMC-node.patch deleted file mode 100644 index d188539aaa..0000000000 --- a/target/linux/qualcommbe/patches-6.18/0105-arm64-dts-qcom-ipq9574-Remove-eMMC-node.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0156e327aa854be5eb9cbec9d020be1026b5b446 Mon Sep 17 00:00:00 2001 -From: Md Sadre Alam -Date: Thu, 6 Mar 2025 17:03:57 +0530 -Subject: [PATCH] arm64: dts: qcom: ipq9574: Remove eMMC node - -Remove eMMC node for rdp433, since rdp433 -default boot mode is norplusnand - -Reviewed-by: Konrad Dybcio -Signed-off-by: Md Sadre Alam -Link: https://lore.kernel.org/r/20250306113357.126602-4-quic_mdalam@quicinc.com -Signed-off-by: Bjorn Andersson ---- - arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts | 12 ------------ - 1 file changed, 12 deletions(-) - ---- a/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts -+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts -@@ -55,18 +55,6 @@ - status = "okay"; - }; - --&sdhc_1 { -- pinctrl-0 = <&sdc_default_state>; -- pinctrl-names = "default"; -- mmc-ddr-1_8v; -- mmc-hs200-1_8v; -- mmc-hs400-1_8v; -- mmc-hs400-enhanced-strobe; -- max-frequency = <384000000>; -- bus-width = <8>; -- status = "okay"; --}; -- - &tlmm { - - pcie1_default: pcie1-default-state { diff --git a/target/linux/qualcommbe/patches-6.18/0323-dt-bindings-net-Add-PPE-for-Qualcomm-IPQ9574-SoC.patch b/target/linux/qualcommbe/patches-6.18/0323-dt-bindings-net-Add-PPE-for-Qualcomm-IPQ9574-SoC.patch deleted file mode 100644 index 89c09ff9ea..0000000000 --- a/target/linux/qualcommbe/patches-6.18/0323-dt-bindings-net-Add-PPE-for-Qualcomm-IPQ9574-SoC.patch +++ /dev/null @@ -1,432 +0,0 @@ -From 48dc6d2fe28865a5c3d271aeb966b984a8085e7c Mon Sep 17 00:00:00 2001 -From: Luo Jie -Date: Sun, 9 Feb 2025 22:29:35 +0800 -Subject: [PATCH] dt-bindings: net: Add PPE for Qualcomm IPQ9574 SoC - -The PPE (packet process engine) hardware block is available in Qualcomm -IPQ chipsets that support PPE architecture, such as IPQ9574. The PPE in -the IPQ9574 SoC includes six ethernet ports (6 GMAC and 6 XGMAC), which -are used to connect with external PHY devices by PCS. It includes an L2 -switch function for bridging packets among the 6 ethernet ports and the -CPU port. The CPU port enables packet transfer between the ethernet -ports and the ARM cores in the SoC, using the ethernet DMA. - -The PPE also includes packet processing offload capabilities for various -networking functions such as route and bridge flows, VLANs, different -tunnel protocols and VPN. - -Signed-off-by: Luo Jie ---- - .../bindings/net/qcom,ipq9574-ppe.yaml | 406 ++++++++++++++++++ - 1 file changed, 406 insertions(+) - create mode 100644 Documentation/devicetree/bindings/net/qcom,ipq9574-ppe.yaml - ---- /dev/null -+++ b/Documentation/devicetree/bindings/net/qcom,ipq9574-ppe.yaml -@@ -0,0 +1,406 @@ -+# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/net/qcom,ipq9574-ppe.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Qualcomm IPQ packet process engine (PPE) -+ -+maintainers: -+ - Luo Jie -+ - Lei Wei -+ - Suruchi Agarwal -+ - Pavithra R > -+ -+description: -+ The Ethernet functionality in the PPE (Packet Process Engine) is comprised -+ of three components, the switch core, port wrapper and Ethernet DMA. -+ -+ The Switch core in the IPQ9574 PPE has maximum of 6 front panel ports and -+ two FIFO interfaces. One of the two FIFO interfaces is used for Ethernet -+ port to host CPU communication using Ethernet DMA. The other is used -+ communicating to the EIP engine which is used for IPsec offload. On the -+ IPQ9574, the PPE includes 6 GMAC/XGMACs that can be connected with external -+ Ethernet PHY. Switch core also includes BM (Buffer Management), QM (Queue -+ Management) and SCH (Scheduler) modules for supporting the packet processing. -+ -+ The port wrapper provides connections from the 6 GMAC/XGMACS to UNIPHY (PCS) -+ supporting various modes such as SGMII/QSGMII/PSGMII/USXGMII/10G-BASER. There -+ are 3 UNIPHY (PCS) instances supported on the IPQ9574. -+ -+ Ethernet DMA is used to transmit and receive packets between the six Ethernet -+ ports and ARM host CPU. -+ -+ The follow diagram shows the PPE hardware block along with its connectivity -+ to the external hardware blocks such clock hardware blocks (CMNPLL, GCC, -+ NSS clock controller) and ethernet PCS/PHY blocks. For depicting the PHY -+ connectivity, one 4x1 Gbps PHY (QCA8075) and two 10 GBps PHYs are used as an -+ example. -+ - | -+ +---------+ -+ | 48 MHZ | -+ +----+----+ -+ |(clock) -+ v -+ +----+----+ -+ +------| CMN PLL | -+ | +----+----+ -+ | |(clock) -+ | v -+ | +----+----+ +----+----+ (clock) +----+----+ -+ | +---| NSSCC | | GCC |--------->| MDIO | -+ | | +----+----+ +----+----+ +----+----+ -+ | | |(clock & reset) |(clock) -+ | | v v -+ | | +-----------------------------+----------+----------+---------+ -+ | | | +-----+ |EDMA FIFO | | EIP FIFO| -+ | | | | SCH | +----------+ +---------+ -+ | | | +-----+ | | | -+ | | | +------+ +------+ +-------------------+ | -+ | | | | BM | | QM | IPQ9574-PPE | L2/L3 Process | | -+ | | | +------+ +------+ +-------------------+ | -+ | | | | | -+ | | | +-------+ +-------+ +-------+ +-------+ +-------+ +-------+ | -+ | | | | MAC0 | | MAC1 | | MAC2 | | MAC3 | | XGMAC4| |XGMAC5 | | -+ | | | +---+---+ +---+---+ +---+---+ +---+---+ +---+---+ +---+---+ | -+ | | | | | | | | | | -+ | | +-----+---------+---------+---------+---------+---------+-----+ -+ | | | | | | | | -+ | | +---+---------+---------+---------+---+ +---+---+ +---+---+ -+ +--+---->| PCS0 | | PCS1 | | PCS2 | -+ |(clock) +---+---------+---------+---------+---+ +---+---+ +---+---+ -+ | | | | | | | -+ | +---+---------+---------+---------+---+ +---+---+ +---+---+ -+ +------->| QCA8075 PHY | | PHY4 | | PHY5 | -+ (clock) +-------------------------------------+ +-------+ +-------+ -+ -+properties: -+ compatible: -+ enum: -+ - qcom,ipq9574-ppe -+ -+ reg: -+ maxItems: 1 -+ -+ clocks: -+ items: -+ - description: PPE core clock from NSS clock controller -+ - description: PPE APB (Advanced Peripheral Bus) clock from NSS clock controller -+ - description: PPE ingress process engine clock from NSS clock controller -+ - description: PPE BM, QM and scheduler clock from NSS clock controller -+ -+ clock-names: -+ items: -+ - const: ppe -+ - const: apb -+ - const: ipe -+ - const: btq -+ -+ resets: -+ maxItems: 1 -+ description: PPE reset, which is necessary before configuring PPE hardware -+ -+ interconnects: -+ items: -+ - description: Clock path leading to PPE switch core function -+ - description: Clock path leading to PPE register access -+ - description: Clock path leading to QoS generation -+ - description: Clock path leading to timeout reference -+ - description: Clock path leading to NSS NOC from memory NOC -+ - description: Clock path leading to memory NOC from NSS NOC -+ - description: Clock path leading to enhanced memory NOC from NSS NOC -+ -+ interconnect-names: -+ items: -+ - const: ppe -+ - const: ppe_cfg -+ - const: qos_gen -+ - const: timeout_ref -+ - const: nssnoc_memnoc -+ - const: memnoc_nssnoc -+ - const: memnoc_nssnoc_1 -+ -+ ethernet-dma: -+ type: object -+ additionalProperties: false -+ description: -+ EDMA (Ethernet DMA) is used to transmit packets between PPE and ARM -+ host CPU. There are 32 TX descriptor rings, 32 TX completion rings, -+ 24 RX descriptor rings and 8 RX fill rings supported. -+ -+ properties: -+ clocks: -+ items: -+ - description: EDMA system clock from NSS Clock Controller -+ - description: EDMA APB (Advanced Peripheral Bus) clock from -+ NSS Clock Controller -+ -+ clock-names: -+ items: -+ - const: sys -+ - const: apb -+ -+ resets: -+ maxItems: 1 -+ description: EDMA reset from NSS clock controller -+ -+ interrupts: -+ minItems: 29 -+ maxItems: 57 -+ -+ interrupt-names: -+ minItems: 29 -+ maxItems: 57 -+ items: -+ pattern: '^(txcmpl_([0-9]|[1-2][0-9]|3[0-1])|rxdesc_([0-9]|1[0-9]|2[0-3])|misc)$' -+ description: -+ Interrupts "txcmpl_[0-31]" are the Ethernet DMA Tx completion ring interrupts. -+ Interrupts "rxdesc_[0-23]" are the Ethernet DMA Rx Descriptor ring interrupts. -+ Interrupt "misc" is the Ethernet DMA miscellaneous error interrupt. -+ -+ required: -+ - clocks -+ - clock-names -+ - resets -+ - interrupts -+ - interrupt-names -+ -+required: -+ - compatible -+ - reg -+ - clocks -+ - clock-names -+ - resets -+ - interconnects -+ - interconnect-names -+ - ethernet-dma -+ -+allOf: -+ - $ref: ethernet-switch.yaml -+ -+unevaluatedProperties: false -+ -+examples: -+ - | -+ #include -+ #include -+ #include -+ -+ ethernet-switch@3a000000 { -+ compatible = "qcom,ipq9574-ppe"; -+ reg = <0x3a000000 0xbef800>; -+ clocks = <&nsscc 80>, -+ <&nsscc 79>, -+ <&nsscc 81>, -+ <&nsscc 78>; -+ clock-names = "ppe", -+ "apb", -+ "ipe", -+ "btq"; -+ resets = <&nsscc 108>; -+ interconnects = <&nsscc MASTER_NSSNOC_PPE &nsscc SLAVE_NSSNOC_PPE>, -+ <&nsscc MASTER_NSSNOC_PPE_CFG &nsscc SLAVE_NSSNOC_PPE_CFG>, -+ <&gcc MASTER_NSSNOC_QOSGEN_REF &gcc SLAVE_NSSNOC_QOSGEN_REF>, -+ <&gcc MASTER_NSSNOC_TIMEOUT_REF &gcc SLAVE_NSSNOC_TIMEOUT_REF>, -+ <&gcc MASTER_MEM_NOC_NSSNOC &gcc SLAVE_MEM_NOC_NSSNOC>, -+ <&gcc MASTER_NSSNOC_MEMNOC &gcc SLAVE_NSSNOC_MEMNOC>, -+ <&gcc MASTER_NSSNOC_MEM_NOC_1 &gcc SLAVE_NSSNOC_MEM_NOC_1>; -+ interconnect-names = "ppe", -+ "ppe_cfg", -+ "qos_gen", -+ "timeout_ref", -+ "nssnoc_memnoc", -+ "memnoc_nssnoc", -+ "memnoc_nssnoc_1"; -+ -+ ethernet-dma { -+ clocks = <&nsscc 77>, -+ <&nsscc 76>; -+ clock-names = "sys", -+ "apb"; -+ resets = <&nsscc 0>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ interrupt-names = "txcmpl_8", -+ "txcmpl_9", -+ "txcmpl_10", -+ "txcmpl_11", -+ "txcmpl_12", -+ "txcmpl_13", -+ "txcmpl_14", -+ "txcmpl_15", -+ "txcmpl_16", -+ "txcmpl_17", -+ "txcmpl_18", -+ "txcmpl_19", -+ "txcmpl_20", -+ "txcmpl_21", -+ "txcmpl_22", -+ "txcmpl_23", -+ "txcmpl_24", -+ "txcmpl_25", -+ "txcmpl_26", -+ "txcmpl_27", -+ "txcmpl_28", -+ "txcmpl_29", -+ "txcmpl_30", -+ "txcmpl_31", -+ "rxdesc_20", -+ "rxdesc_21", -+ "rxdesc_22", -+ "rxdesc_23", -+ "misc"; -+ }; -+ -+ ethernet-ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@1 { -+ reg = <1>; -+ phy-mode = "qsgmii"; -+ managed = "in-band-status"; -+ phy-handle = <&phy0>; -+ pcs-handle = <&pcs0_mii0>; -+ clocks = <&nsscc 33>, -+ <&nsscc 34>, -+ <&nsscc 37>; -+ clock-names = "mac", -+ "rx", -+ "tx"; -+ resets = <&nsscc 29>, -+ <&nsscc 96>, -+ <&nsscc 97>; -+ reset-names = "mac", -+ "rx", -+ "tx"; -+ }; -+ -+ port@2 { -+ reg = <2>; -+ phy-mode = "qsgmii"; -+ managed = "in-band-status"; -+ phy-handle = <&phy1>; -+ pcs-handle = <&pcs0_mii1>; -+ clocks = <&nsscc 40>, -+ <&nsscc 41>, -+ <&nsscc 44>; -+ clock-names = "mac", -+ "rx", -+ "tx"; -+ resets = <&nsscc 30>, -+ <&nsscc 98>, -+ <&nsscc 99>; -+ reset-names = "mac", -+ "rx", -+ "tx"; -+ }; -+ -+ port@3 { -+ reg = <3>; -+ phy-mode = "qsgmii"; -+ managed = "in-band-status"; -+ phy-handle = <&phy2>; -+ pcs-handle = <&pcs0_mii2>; -+ clocks = <&nsscc 47>, -+ <&nsscc 48>, -+ <&nsscc 51>; -+ clock-names = "mac", -+ "rx", -+ "tx"; -+ resets = <&nsscc 31>, -+ <&nsscc 100>, -+ <&nsscc 101>; -+ reset-names = "mac", -+ "rx", -+ "tx"; -+ }; -+ -+ port@4 { -+ reg = <4>; -+ phy-mode = "qsgmii"; -+ managed = "in-band-status"; -+ phy-handle = <&phy3>; -+ pcs-handle = <&pcs0_mii3>; -+ clocks = <&nsscc 54>, -+ <&nsscc 55>, -+ <&nsscc 58>; -+ clock-names = "mac", -+ "rx", -+ "tx"; -+ resets = <&nsscc 32>, -+ <&nsscc 102>, -+ <&nsscc 103>; -+ reset-names = "mac", -+ "rx", -+ "tx"; -+ }; -+ -+ port@5 { -+ reg = <5>; -+ phy-mode = "usxgmii"; -+ managed = "in-band-status"; -+ phy-handle = <&phy4>; -+ pcs-handle = <&pcs1_mii0>; -+ clocks = <&nsscc 61>, -+ <&nsscc 62>, -+ <&nsscc 65>; -+ clock-names = "mac", -+ "rx", -+ "tx"; -+ resets = <&nsscc 33>, -+ <&nsscc 104>, -+ <&nsscc 105>; -+ reset-names = "mac", -+ "rx", -+ "tx"; -+ }; -+ -+ port@6 { -+ reg = <6>; -+ phy-mode = "usxgmii"; -+ managed = "in-band-status"; -+ phy-handle = <&phy5>; -+ pcs-handle = <&pcs2_mii0>; -+ clocks = <&nsscc 68>, -+ <&nsscc 69>, -+ <&nsscc 72>; -+ clock-names = "mac", -+ "rx", -+ "tx"; -+ resets = <&nsscc 34>, -+ <&nsscc 106>, -+ <&nsscc 107>; -+ reset-names = "mac", -+ "rx", -+ "tx"; -+ }; -+ }; -+ }; diff --git a/target/linux/qualcommbe/patches-6.18/0324-docs-networking-Add-PPE-driver-documentation-for-Qua.patch b/target/linux/qualcommbe/patches-6.18/0324-docs-networking-Add-PPE-driver-documentation-for-Qua.patch deleted file mode 100644 index 429006c7bc..0000000000 --- a/target/linux/qualcommbe/patches-6.18/0324-docs-networking-Add-PPE-driver-documentation-for-Qua.patch +++ /dev/null @@ -1,227 +0,0 @@ -From 9973b6610830146af1a12fe02d2d6440eb80b0f9 Mon Sep 17 00:00:00 2001 -From: Lei Wei -Date: Sun, 9 Feb 2025 22:29:36 +0800 -Subject: [PATCH] docs: networking: Add PPE driver documentation for Qualcomm - IPQ9574 SoC - -Add description and high-level diagram for PPE, driver overview and -module enable/debug information. - -Signed-off-by: Lei Wei -Signed-off-by: Luo Jie ---- - .../device_drivers/ethernet/index.rst | 1 + - .../ethernet/qualcomm/ppe/ppe.rst | 197 ++++++++++++++++++ - 2 files changed, 198 insertions(+) - create mode 100644 Documentation/networking/device_drivers/ethernet/qualcomm/ppe/ppe.rst - ---- a/Documentation/networking/device_drivers/ethernet/index.rst -+++ b/Documentation/networking/device_drivers/ethernet/index.rst -@@ -49,6 +49,7 @@ Contents: - neterion/s2io - netronome/nfp - pensando/ionic -+ qualcomm/ppe/ppe - smsc/smc9 - stmicro/stmmac - ti/cpsw ---- /dev/null -+++ b/Documentation/networking/device_drivers/ethernet/qualcomm/ppe/ppe.rst -@@ -0,0 +1,197 @@ -+.. SPDX-License-Identifier: GPL-2.0 -+ -+=============================================== -+PPE Ethernet Driver for Qualcomm IPQ SoC Family -+=============================================== -+ -+Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. -+ -+Author: Lei Wei -+ -+ -+Contents -+======== -+ -+- `PPE Overview`_ -+- `PPE Driver Overview`_ -+- `PPE Driver Supported SoCs`_ -+- `Enabling the Driver`_ -+- `Debugging`_ -+ -+ -+PPE Overview -+============ -+ -+IPQ (Qualcomm Internet Processor) SoC (System-on-Chip) series is Qualcomm's series of -+networking SoC for Wi-Fi access points. The PPE (Packet Process Engine) is the Ethernet -+packet process engine in the IPQ SoC. -+ -+Below is a simplified hardware diagram of IPQ9574 SoC which includes the PPE engine and -+other blocks which are in the SoC but outside the PPE engine. These blocks work together -+to enable the Ethernet for the IPQ SoC:: -+ -+ +------+ +------+ +------+ +------+ +------+ +------+ start +-------+ -+ |netdev| |netdev| |netdev| |netdev| |netdev| |netdev|<------|PHYLINK| -+ +------+ +------+ +------+ +------+ +------+ +------+ stop +-+-+-+-+ -+ | | | ^ -+ +-------+ +-------------------------+--------+----------------------+ | | | -+ | GCC | | | EDMA | | | | | -+ +---+---+ | PPE +---+----+ | | | | -+ | clk | | | | | | -+ +------>| +-----------------------+------+-----+---------------+ | | | | -+ | | Switch Core |Port0 | |Port7(EIP FIFO)| | | | | -+ | | +---+--+ +------+--------+ | | | | -+ | | | | | | | | | -+ +-------+ | | +------+---------------+----+ | | | | | -+ |CMN PLL| | | +---+ +---+ +----+ | +--------+ | | | | | | -+ +---+---+ | | |BM | |QM | |SCH | | | L2/L3 | ....... | | | | | | -+ | | | | +---+ +---+ +----+ | +--------+ | | | | | | -+ | | | | +------+--------------------+ | | | | | -+ | | | | | | | | | | -+ | v | | +-----+-+-----+-+-----+-+-+---+--+-----+-+-----+ | | | | | -+ | +------+ | | |Port1| |Port2| |Port3| |Port4| |Port5| |Port6| | | | | | -+ | |NSSCC | | | +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ | | mac| | | -+ | +-+-+--+ | | |MAC0 | |MAC1 | |MAC2 | |MAC3 | |MAC4 | |MAC5 | | |<---+ | | -+ | ^ | |clk | | +-----+-+-----+-+-----+-+-----+--+-----+-+-----+ | | ops | | -+ | | | +---->| +----|------|-------|-------|---------|--------|-----+ | | | -+ | | | +---------------------------------------------------------+ | | -+ | | | | | | | | | | | -+ | | | MII clk | QSGMII USXGMII USXGMII | | -+ | | +------------->| | | | | | | | -+ | | +-------------------------+ +---------+ +---------+ | | -+ | |125/312.5M clk| (PCS0) | | (PCS1) | | (PCS2) | pcs ops | | -+ | +--------------+ UNIPHY0 | | UNIPHY1 | | UNIPHY2 |<--------+ | -+ +--------------->| | | | | | | -+ | 31.25M ref clk +-------------------------+ +---------+ +---------+ | -+ | | | | | | | | -+ | +-----------------------------------------------------+ | -+ |25/50M ref clk| +-------------------------+ +------+ +------+ | link | -+ +------------->| | QUAD PHY | | PHY4 | | PHY5 | |---------+ -+ | +-------------------------+ +------+ +------+ | change -+ | | -+ | MDIO bus | -+ +-----------------------------------------------------+ -+ -+The CMN (Common) PLL, NSSCC (Networking Sub System Clock Controller) and GCC (Global -+Clock Controller) blocks are in the SoC and act as clock providers. -+ -+The UNIPHY block is in the SoC and provides the PCS (Physical Coding Sublayer) and -+XPCS (10-Gigabit Physical Coding Sublayer) functions to support different interface -+modes between the PPE MAC and the external PHY. -+ -+This documentation focuses on the descriptions of PPE engine and the PPE driver. -+ -+The Ethernet functionality in the PPE (Packet Process Engine) is comprised of three -+components: the switch core, port wrapper and Ethernet DMA. -+ -+The Switch core in the IPQ9574 PPE has maximum of 6 front panel ports and two FIFO -+interfaces. One of the two FIFO interfaces is used for Ethernet port to host CPU -+communication using Ethernet DMA. The other is used communicating to the EIP engine -+which is used for IPsec offload. On the IPQ9574, the PPE includes 6 GMAC/XGMACs that -+can be connected with external Ethernet PHY. Switch core also includes BM (Buffer -+Management), QM (Queue Management) and SCH (Scheduler) modules for supporting the -+packet processing. -+ -+The port wrapper provides connections from the 6 GMAC/XGMACS to UNIPHY (PCS) supporting -+various modes such as SGMII/QSGMII/PSGMII/USXGMII/10G-BASER. There are 3 UNIPHY (PCS) -+instances supported on the IPQ9574. -+ -+Ethernet DMA is used to transmit and receive packets between the Ethernet subsystem -+and ARM host CPU. -+ -+The following lists the main blocks in the PPE engine which will be driven by this -+PPE driver: -+ -+- BM -+ BM is the hardware buffer manager for the PPE switch ports. -+- QM -+ Queue Manager for managing the egress hardware queues of the PPE switch ports. -+- SCH -+ The scheduler which manages the hardware traffic scheduling for the PPE switch ports. -+- L2 -+ The L2 block performs the packet bridging in the switch core. The bridge domain is -+ represented by the VSI (Virtual Switch Instance) domain in PPE. FDB learning can be -+ enabled based on the VSI domain and bridge forwarding occurs within the VSI domain. -+- MAC -+ The PPE in the IPQ9574 supports up to six MACs (MAC0 to MAC5) which are corresponding -+ to six switch ports (port1 to port6). The MAC block is connected with external PHY -+ through the UNIPHY PCS block. Each MAC block includes the GMAC and XGMAC blocks and -+ the switch port can select to use GMAC or XMAC through a MUX selection according to -+ the external PHY's capability. -+- EDMA (Ethernet DMA) -+ The Ethernet DMA is used to transmit and receive Ethernet packets between the PPE -+ ports and the ARM cores. -+ -+The received packet on a PPE MAC port can be forwarded to another PPE MAC port. It can -+be also forwarded to internal switch port0 so that the packet can be delivered to the -+ARM cores using the Ethernet DMA (EDMA) engine. The Ethernet DMA driver will deliver the -+packet to the corresponding 'netdevice' interface. -+ -+The software instantiations of the PPE MAC (netdevice), PCS and external PHYs interact -+with the Linux PHYLINK framework to manage the connectivity between the PPE ports and -+the connected PHYs, and the port link states. This is also illustrated in above diagram. -+ -+ -+PPE Driver Overview -+=================== -+PPE driver is Ethernet driver for the Qualcomm IPQ SoC. It is a single platform driver -+which includes the PPE part and Ethernet DMA part. The PPE part initializes and drives the -+various blocks in PPE switch core such as BM/QM/L2 blocks and the PPE MACs. The EDMA part -+drives the Ethernet DMA for packet transfer between PPE ports and ARM cores, and enables -+the netdevice driver for the PPE ports. -+ -+The PPE driver files in drivers/net/ethernet/qualcomm/ppe/ are listed as below: -+ -+- Makefile -+- ppe.c -+- ppe.h -+- ppe_config.c -+- ppe_config.h -+- ppe_debugfs.c -+- ppe_debugfs.h -+- ppe_regs.h -+ -+The ppe.c file contains the main PPE platform driver and undertakes the initialization of -+PPE switch core blocks such as QM, BM and L2. The configuration APIs for these hardware -+blocks are provided in the ppe_config.c file. -+ -+The ppe.h defines the PPE device data structure which will be used by PPE driver functions. -+ -+The ppe_debugfs.c enables the PPE statistics counters such as PPE port Rx and Tx counters, -+CPU code counters and queue counters. -+ -+ -+PPE Driver Supported SoCs -+========================= -+ -+The PPE driver supports the following IPQ SoC: -+ -+- IPQ9574 -+ -+ -+Enabling the Driver -+=================== -+ -+The driver is located in the menu structure at: -+ -+ -> Device Drivers -+ -> Network device support (NETDEVICES [=y]) -+ -> Ethernet driver support -+ -> Qualcomm devices -+ -> Qualcomm Technologies, Inc. PPE Ethernet support -+ -+If this driver is built as a module, we can use below commands to install and remove it: -+ -+- insmod qcom-ppe.ko -+- rmmod qcom-ppe.ko -+ -+The PPE driver functionally depends on the CMN PLL and NSSCC clock controller drivers. -+Please make sure the dependent modules are installed before installing the PPE driver -+module. -+ -+ -+Debugging -+========= -+ -+The PPE hardware counters are available in the debugfs and can be checked by the command -+``cat /sys/kernel/debug/ppe/packet_counters``. diff --git a/target/linux/qualcommbe/patches-6.18/0325-net-ethernet-qualcomm-Add-PPE-driver-for-IPQ9574-SoC.patch b/target/linux/qualcommbe/patches-6.18/0325-net-ethernet-qualcomm-Add-PPE-driver-for-IPQ9574-SoC.patch deleted file mode 100644 index f55879ae48..0000000000 --- a/target/linux/qualcommbe/patches-6.18/0325-net-ethernet-qualcomm-Add-PPE-driver-for-IPQ9574-SoC.patch +++ /dev/null @@ -1,339 +0,0 @@ -From d1158f0282304c89217894aa346fc45364b95542 Mon Sep 17 00:00:00 2001 -From: Luo Jie -Date: Sun, 9 Feb 2025 22:29:37 +0800 -Subject: [PATCH] net: ethernet: qualcomm: Add PPE driver for IPQ9574 SoC - -The PPE (Packet Process Engine) hardware block is available -on Qualcomm IPQ SoC that support PPE architecture, such as -IPQ9574. - -The PPE in IPQ9574 includes six integrated ethernet MAC -(for 6 PPE ports), buffer management, queue management and -scheduler functions. The MACs can connect with the external -PHY or switch devices using the UNIPHY PCS block available -in the SoC. - -The PPE also includes various packet processing offload -capabilities such as L3 routing and L2 bridging, VLAN and -tunnel processing offload. It also includes Ethernet DMA -function for transferring packets between ARM cores and -PPE ethernet ports. - -This patch adds the base source files and Makefiles for -the PPE driver such as platform driver registration, -clock initialization, and PPE reset routines. - -Signed-off-by: Luo Jie ---- - drivers/net/ethernet/qualcomm/Kconfig | 15 ++ - drivers/net/ethernet/qualcomm/Makefile | 1 + - drivers/net/ethernet/qualcomm/ppe/Makefile | 7 + - drivers/net/ethernet/qualcomm/ppe/ppe.c | 218 +++++++++++++++++++++ - drivers/net/ethernet/qualcomm/ppe/ppe.h | 36 ++++ - 5 files changed, 277 insertions(+) - create mode 100644 drivers/net/ethernet/qualcomm/ppe/Makefile - create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe.c - create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe.h - ---- a/drivers/net/ethernet/qualcomm/Kconfig -+++ b/drivers/net/ethernet/qualcomm/Kconfig -@@ -61,6 +61,21 @@ config QCOM_EMAC - low power, Receive-Side Scaling (RSS), and IEEE 1588-2008 - Precision Clock Synchronization Protocol. - -+config QCOM_PPE -+ tristate "Qualcomm Technologies, Inc. PPE Ethernet support" -+ depends on HAS_IOMEM && OF -+ depends on COMMON_CLK -+ select REGMAP_MMIO -+ help -+ This driver supports the Qualcomm Technologies, Inc. packet -+ process engine (PPE) available with IPQ SoC. The PPE includes -+ the ethernet MACs, Ethernet DMA (EDMA) and switch core that -+ supports L3 flow offload, L2 switch function, RSS and tunnel -+ offload. -+ -+ To compile this driver as a module, choose M here. The module -+ will be called qcom-ppe. -+ - source "drivers/net/ethernet/qualcomm/rmnet/Kconfig" - - endif # NET_VENDOR_QUALCOMM ---- a/drivers/net/ethernet/qualcomm/Makefile -+++ b/drivers/net/ethernet/qualcomm/Makefile -@@ -11,4 +11,5 @@ qcauart-objs := qca_uart.o - - obj-y += emac/ - -+obj-$(CONFIG_QCOM_PPE) += ppe/ - obj-$(CONFIG_RMNET) += rmnet/ ---- /dev/null -+++ b/drivers/net/ethernet/qualcomm/ppe/Makefile -@@ -0,0 +1,7 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+# -+# Makefile for the device driver of PPE (Packet Process Engine) in IPQ SoC -+# -+ -+obj-$(CONFIG_QCOM_PPE) += qcom-ppe.o -+qcom-ppe-objs := ppe.o ---- /dev/null -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.c -@@ -0,0 +1,218 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+/* PPE platform device probe, DTSI parser and PPE clock initializations. */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "ppe.h" -+ -+#define PPE_PORT_MAX 8 -+#define PPE_CLK_RATE 353000000 -+ -+/* ICC clocks for enabling PPE device. The avg_bw and peak_bw with value 0 -+ * will be updated by the clock rate of PPE. -+ */ -+static const struct icc_bulk_data ppe_icc_data[] = { -+ { -+ .name = "ppe", -+ .avg_bw = 0, -+ .peak_bw = 0, -+ }, -+ { -+ .name = "ppe_cfg", -+ .avg_bw = 0, -+ .peak_bw = 0, -+ }, -+ { -+ .name = "qos_gen", -+ .avg_bw = 6000, -+ .peak_bw = 6000, -+ }, -+ { -+ .name = "timeout_ref", -+ .avg_bw = 6000, -+ .peak_bw = 6000, -+ }, -+ { -+ .name = "nssnoc_memnoc", -+ .avg_bw = 533333, -+ .peak_bw = 533333, -+ }, -+ { -+ .name = "memnoc_nssnoc", -+ .avg_bw = 533333, -+ .peak_bw = 533333, -+ }, -+ { -+ .name = "memnoc_nssnoc_1", -+ .avg_bw = 533333, -+ .peak_bw = 533333, -+ }, -+}; -+ -+static const struct regmap_range ppe_readable_ranges[] = { -+ regmap_reg_range(0x0, 0x1ff), /* Global */ -+ regmap_reg_range(0x400, 0x5ff), /* LPI CSR */ -+ regmap_reg_range(0x1000, 0x11ff), /* GMAC0 */ -+ regmap_reg_range(0x1200, 0x13ff), /* GMAC1 */ -+ regmap_reg_range(0x1400, 0x15ff), /* GMAC2 */ -+ regmap_reg_range(0x1600, 0x17ff), /* GMAC3 */ -+ regmap_reg_range(0x1800, 0x19ff), /* GMAC4 */ -+ regmap_reg_range(0x1a00, 0x1bff), /* GMAC5 */ -+ regmap_reg_range(0xb000, 0xefff), /* PRX CSR */ -+ regmap_reg_range(0xf000, 0x1efff), /* IPE */ -+ regmap_reg_range(0x20000, 0x5ffff), /* PTX CSR */ -+ regmap_reg_range(0x60000, 0x9ffff), /* IPE L2 CSR */ -+ regmap_reg_range(0xb0000, 0xeffff), /* IPO CSR */ -+ regmap_reg_range(0x100000, 0x17ffff), /* IPE PC */ -+ regmap_reg_range(0x180000, 0x1bffff), /* PRE IPO CSR */ -+ regmap_reg_range(0x1d0000, 0x1dffff), /* Tunnel parser */ -+ regmap_reg_range(0x1e0000, 0x1effff), /* Ingress parse */ -+ regmap_reg_range(0x200000, 0x2fffff), /* IPE L3 */ -+ regmap_reg_range(0x300000, 0x3fffff), /* IPE tunnel */ -+ regmap_reg_range(0x400000, 0x4fffff), /* Scheduler */ -+ regmap_reg_range(0x500000, 0x503fff), /* XGMAC0 */ -+ regmap_reg_range(0x504000, 0x507fff), /* XGMAC1 */ -+ regmap_reg_range(0x508000, 0x50bfff), /* XGMAC2 */ -+ regmap_reg_range(0x50c000, 0x50ffff), /* XGMAC3 */ -+ regmap_reg_range(0x510000, 0x513fff), /* XGMAC4 */ -+ regmap_reg_range(0x514000, 0x517fff), /* XGMAC5 */ -+ regmap_reg_range(0x600000, 0x6fffff), /* BM */ -+ regmap_reg_range(0x800000, 0x9fffff), /* QM */ -+ regmap_reg_range(0xb00000, 0xbef800), /* EDMA */ -+}; -+ -+static const struct regmap_access_table ppe_reg_table = { -+ .yes_ranges = ppe_readable_ranges, -+ .n_yes_ranges = ARRAY_SIZE(ppe_readable_ranges), -+}; -+ -+static const struct regmap_config regmap_config_ipq9574 = { -+ .reg_bits = 32, -+ .reg_stride = 4, -+ .val_bits = 32, -+ .rd_table = &ppe_reg_table, -+ .wr_table = &ppe_reg_table, -+ .max_register = 0xbef800, -+ .fast_io = true, -+}; -+ -+static int ppe_clock_init_and_reset(struct ppe_device *ppe_dev) -+{ -+ unsigned long ppe_rate = ppe_dev->clk_rate; -+ struct device *dev = ppe_dev->dev; -+ struct reset_control *rstc; -+ struct clk_bulk_data *clks; -+ struct clk *clk; -+ int ret, i; -+ -+ for (i = 0; i < ppe_dev->num_icc_paths; i++) { -+ ppe_dev->icc_paths[i].name = ppe_icc_data[i].name; -+ ppe_dev->icc_paths[i].avg_bw = ppe_icc_data[i].avg_bw ? : -+ Bps_to_icc(ppe_rate); -+ ppe_dev->icc_paths[i].peak_bw = ppe_icc_data[i].peak_bw ? : -+ Bps_to_icc(ppe_rate); -+ } -+ -+ ret = devm_of_icc_bulk_get(dev, ppe_dev->num_icc_paths, -+ ppe_dev->icc_paths); -+ if (ret) -+ return ret; -+ -+ ret = icc_bulk_set_bw(ppe_dev->num_icc_paths, ppe_dev->icc_paths); -+ if (ret) -+ return ret; -+ -+ /* The PPE clocks have a common parent clock. Setting the clock -+ * rate of "ppe" ensures the clock rate of all PPE clocks is -+ * configured to the same rate. -+ */ -+ clk = devm_clk_get(dev, "ppe"); -+ if (IS_ERR(clk)) -+ return PTR_ERR(clk); -+ -+ ret = clk_set_rate(clk, ppe_rate); -+ if (ret) -+ return ret; -+ -+ ret = devm_clk_bulk_get_all_enable(dev, &clks); -+ if (ret < 0) -+ return ret; -+ -+ /* Reset the PPE. */ -+ rstc = devm_reset_control_get_exclusive(dev, NULL); -+ if (IS_ERR(rstc)) -+ return PTR_ERR(rstc); -+ -+ ret = reset_control_assert(rstc); -+ if (ret) -+ return ret; -+ -+ /* The delay 10 ms of assert is necessary for resetting PPE. */ -+ usleep_range(10000, 11000); -+ -+ return reset_control_deassert(rstc); -+} -+ -+static int qcom_ppe_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct ppe_device *ppe_dev; -+ void __iomem *base; -+ int ret, num_icc; -+ -+ num_icc = ARRAY_SIZE(ppe_icc_data); -+ ppe_dev = devm_kzalloc(dev, struct_size(ppe_dev, icc_paths, num_icc), -+ GFP_KERNEL); -+ if (!ppe_dev) -+ return -ENOMEM; -+ -+ base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(base)) -+ return dev_err_probe(dev, PTR_ERR(base), "PPE ioremap failed\n"); -+ -+ ppe_dev->regmap = devm_regmap_init_mmio(dev, base, ®map_config_ipq9574); -+ if (IS_ERR(ppe_dev->regmap)) -+ return dev_err_probe(dev, PTR_ERR(ppe_dev->regmap), -+ "PPE initialize regmap failed\n"); -+ ppe_dev->dev = dev; -+ ppe_dev->clk_rate = PPE_CLK_RATE; -+ ppe_dev->num_ports = PPE_PORT_MAX; -+ ppe_dev->num_icc_paths = num_icc; -+ -+ ret = ppe_clock_init_and_reset(ppe_dev); -+ if (ret) -+ return dev_err_probe(dev, ret, "PPE clock config failed\n"); -+ -+ platform_set_drvdata(pdev, ppe_dev); -+ -+ return 0; -+} -+ -+static const struct of_device_id qcom_ppe_of_match[] = { -+ { .compatible = "qcom,ipq9574-ppe" }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, qcom_ppe_of_match); -+ -+static struct platform_driver qcom_ppe_driver = { -+ .driver = { -+ .name = "qcom_ppe", -+ .of_match_table = qcom_ppe_of_match, -+ }, -+ .probe = qcom_ppe_probe, -+}; -+module_platform_driver(qcom_ppe_driver); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Qualcomm Technologies, Inc. IPQ PPE driver"); ---- /dev/null -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.h -@@ -0,0 +1,36 @@ -+/* SPDX-License-Identifier: GPL-2.0-only -+ * -+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __PPE_H__ -+#define __PPE_H__ -+ -+#include -+#include -+ -+struct device; -+struct regmap; -+ -+/** -+ * struct ppe_device - PPE device private data. -+ * @dev: PPE device structure. -+ * @regmap: PPE register map. -+ * @clk_rate: PPE clock rate. -+ * @num_ports: Number of PPE ports. -+ * @num_icc_paths: Number of interconnect paths. -+ * @icc_paths: Interconnect path array. -+ * -+ * PPE device is the instance of PPE hardware, which is used to -+ * configure PPE packet process modules such as BM (buffer management), -+ * QM (queue management), and scheduler. -+ */ -+struct ppe_device { -+ struct device *dev; -+ struct regmap *regmap; -+ unsigned long clk_rate; -+ unsigned int num_ports; -+ unsigned int num_icc_paths; -+ struct icc_bulk_data icc_paths[] __counted_by(num_icc_paths); -+}; -+#endif diff --git a/target/linux/qualcommbe/patches-6.18/0326-net-ethernet-qualcomm-Initialize-PPE-buffer-manageme.patch b/target/linux/qualcommbe/patches-6.18/0326-net-ethernet-qualcomm-Initialize-PPE-buffer-manageme.patch deleted file mode 100644 index 5f38e25b37..0000000000 --- a/target/linux/qualcommbe/patches-6.18/0326-net-ethernet-qualcomm-Initialize-PPE-buffer-manageme.patch +++ /dev/null @@ -1,328 +0,0 @@ -From 6e639ab45348ee7a697db8b481fa6f8555280f58 Mon Sep 17 00:00:00 2001 -From: Luo Jie -Date: Sun, 9 Feb 2025 22:29:38 +0800 -Subject: [PATCH] net: ethernet: qualcomm: Initialize PPE buffer management for - IPQ9574 - -The BM (Buffer Management) config controls the pause frame generated -on the PPE port. There are maximum 15 BM ports and 4 groups supported, -all BM ports are assigned to group 0 by default. The number of hardware -buffers configured for the port influence the threshold of the flow -control for that port. - -Signed-off-by: Luo Jie ---- - drivers/net/ethernet/qualcomm/ppe/Makefile | 2 +- - drivers/net/ethernet/qualcomm/ppe/ppe.c | 5 + - .../net/ethernet/qualcomm/ppe/ppe_config.c | 195 ++++++++++++++++++ - .../net/ethernet/qualcomm/ppe/ppe_config.h | 12 ++ - drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 59 ++++++ - 5 files changed, 272 insertions(+), 1 deletion(-) - create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_config.c - create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_config.h - create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_regs.h - ---- a/drivers/net/ethernet/qualcomm/ppe/Makefile -+++ b/drivers/net/ethernet/qualcomm/ppe/Makefile -@@ -4,4 +4,4 @@ - # - - obj-$(CONFIG_QCOM_PPE) += qcom-ppe.o --qcom-ppe-objs := ppe.o -+qcom-ppe-objs := ppe.o ppe_config.o ---- a/drivers/net/ethernet/qualcomm/ppe/ppe.c -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.c -@@ -15,6 +15,7 @@ - #include - - #include "ppe.h" -+#include "ppe_config.h" - - #define PPE_PORT_MAX 8 - #define PPE_CLK_RATE 353000000 -@@ -194,6 +195,10 @@ static int qcom_ppe_probe(struct platfor - if (ret) - return dev_err_probe(dev, ret, "PPE clock config failed\n"); - -+ ret = ppe_hw_config(ppe_dev); -+ if (ret) -+ return dev_err_probe(dev, ret, "PPE HW config failed\n"); -+ - platform_set_drvdata(pdev, ppe_dev); - - return 0; ---- /dev/null -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c -@@ -0,0 +1,195 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+/* PPE HW initialization configs such as BM(buffer management), -+ * QM(queue management) and scheduler configs. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "ppe.h" -+#include "ppe_config.h" -+#include "ppe_regs.h" -+ -+/** -+ * struct ppe_bm_port_config - PPE BM port configuration. -+ * @port_id_start: The fist BM port ID to configure. -+ * @port_id_end: The last BM port ID to configure. -+ * @pre_alloc: BM port dedicated buffer number. -+ * @in_fly_buf: Buffer number for receiving the packet after pause frame sent. -+ * @ceil: Ceil to generate the back pressure. -+ * @weight: Weight value. -+ * @resume_offset: Resume offset from the threshold value. -+ * @resume_ceil: Ceil to resume from the back pressure state. -+ * @dynamic: Dynamic threshold used or not. -+ * -+ * The is for configuring the threshold that impacts the port -+ * flow control. -+ */ -+struct ppe_bm_port_config { -+ unsigned int port_id_start; -+ unsigned int port_id_end; -+ unsigned int pre_alloc; -+ unsigned int in_fly_buf; -+ unsigned int ceil; -+ unsigned int weight; -+ unsigned int resume_offset; -+ unsigned int resume_ceil; -+ bool dynamic; -+}; -+ -+/* Assign the share buffer number 1550 to group 0 by default. */ -+static const int ipq9574_ppe_bm_group_config = 1550; -+ -+/* The buffer configurations per PPE port. There are 15 BM ports and -+ * 4 BM groups supported by PPE. BM port (0-7) is for EDMA port 0, -+ * BM port (8-13) is for PPE physical port 1-6 and BM port 14 is for -+ * EIP port. -+ */ -+static const struct ppe_bm_port_config ipq9574_ppe_bm_port_config[] = { -+ { -+ /* Buffer configuration for the BM port ID 0 of EDMA. */ -+ .port_id_start = 0, -+ .port_id_end = 0, -+ .pre_alloc = 0, -+ .in_fly_buf = 100, -+ .ceil = 1146, -+ .weight = 7, -+ .resume_offset = 8, -+ .resume_ceil = 0, -+ .dynamic = true, -+ }, -+ { -+ /* Buffer configuration for the BM port ID 1-7 of EDMA. */ -+ .port_id_start = 1, -+ .port_id_end = 7, -+ .pre_alloc = 0, -+ .in_fly_buf = 100, -+ .ceil = 250, -+ .weight = 4, -+ .resume_offset = 36, -+ .resume_ceil = 0, -+ .dynamic = true, -+ }, -+ { -+ /* Buffer configuration for the BM port ID 8-13 of PPE ports. */ -+ .port_id_start = 8, -+ .port_id_end = 13, -+ .pre_alloc = 0, -+ .in_fly_buf = 128, -+ .ceil = 250, -+ .weight = 4, -+ .resume_offset = 36, -+ .resume_ceil = 0, -+ .dynamic = true, -+ }, -+ { -+ /* Buffer configuration for the BM port ID 14 of EIP. */ -+ .port_id_start = 14, -+ .port_id_end = 14, -+ .pre_alloc = 0, -+ .in_fly_buf = 40, -+ .ceil = 250, -+ .weight = 4, -+ .resume_offset = 36, -+ .resume_ceil = 0, -+ .dynamic = true, -+ }, -+}; -+ -+static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id, -+ const struct ppe_bm_port_config port_cfg) -+{ -+ u32 reg, val, bm_fc_val[2]; -+ int ret; -+ -+ reg = PPE_BM_PORT_FC_CFG_TBL_ADDR + PPE_BM_PORT_FC_CFG_TBL_INC * bm_port_id; -+ ret = regmap_bulk_read(ppe_dev->regmap, reg, -+ bm_fc_val, ARRAY_SIZE(bm_fc_val)); -+ if (ret) -+ return ret; -+ -+ /* Configure BM flow control related threshold. */ -+ PPE_BM_PORT_FC_SET_WEIGHT(bm_fc_val, port_cfg.weight); -+ PPE_BM_PORT_FC_SET_RESUME_OFFSET(bm_fc_val, port_cfg.resume_offset); -+ PPE_BM_PORT_FC_SET_RESUME_THRESHOLD(bm_fc_val, port_cfg.resume_ceil); -+ PPE_BM_PORT_FC_SET_DYNAMIC(bm_fc_val, port_cfg.dynamic); -+ PPE_BM_PORT_FC_SET_REACT_LIMIT(bm_fc_val, port_cfg.in_fly_buf); -+ PPE_BM_PORT_FC_SET_PRE_ALLOC(bm_fc_val, port_cfg.pre_alloc); -+ -+ /* Configure low/high bits of the ceiling for the BM port. */ -+ val = FIELD_GET(GENMASK(2, 0), port_cfg.ceil); -+ PPE_BM_PORT_FC_SET_CEILING_LOW(bm_fc_val, val); -+ val = FIELD_GET(GENMASK(10, 3), port_cfg.ceil); -+ PPE_BM_PORT_FC_SET_CEILING_HIGH(bm_fc_val, val); -+ -+ ret = regmap_bulk_write(ppe_dev->regmap, reg, -+ bm_fc_val, ARRAY_SIZE(bm_fc_val)); -+ if (ret) -+ return ret; -+ -+ /* Assign the default group ID 0 to the BM port. */ -+ val = FIELD_PREP(PPE_BM_PORT_GROUP_ID_SHARED_GROUP_ID, 0); -+ reg = PPE_BM_PORT_GROUP_ID_ADDR + PPE_BM_PORT_GROUP_ID_INC * bm_port_id; -+ ret = regmap_update_bits(ppe_dev->regmap, reg, -+ PPE_BM_PORT_GROUP_ID_SHARED_GROUP_ID, -+ val); -+ if (ret) -+ return ret; -+ -+ /* Enable BM port flow control. */ -+ reg = PPE_BM_PORT_FC_MODE_ADDR + PPE_BM_PORT_FC_MODE_INC * bm_port_id; -+ -+ return regmap_set_bits(ppe_dev->regmap, reg, PPE_BM_PORT_FC_MODE_EN); -+} -+ -+/* Configure the buffer threshold for the port flow control function. */ -+static int ppe_config_bm(struct ppe_device *ppe_dev) -+{ -+ const struct ppe_bm_port_config *port_cfg; -+ unsigned int i, bm_port_id, port_cfg_cnt; -+ u32 reg, val; -+ int ret; -+ -+ /* Configure the allocated buffer number only for group 0. -+ * The buffer number of group 1-3 is already cleared to 0 -+ * after PPE reset during the probe of PPE driver. -+ */ -+ reg = PPE_BM_SHARED_GROUP_CFG_ADDR; -+ val = FIELD_PREP(PPE_BM_SHARED_GROUP_CFG_SHARED_LIMIT, -+ ipq9574_ppe_bm_group_config); -+ ret = regmap_update_bits(ppe_dev->regmap, reg, -+ PPE_BM_SHARED_GROUP_CFG_SHARED_LIMIT, -+ val); -+ if (ret) -+ goto bm_config_fail; -+ -+ /* Configure buffer thresholds for the BM ports. */ -+ port_cfg = ipq9574_ppe_bm_port_config; -+ port_cfg_cnt = ARRAY_SIZE(ipq9574_ppe_bm_port_config); -+ for (i = 0; i < port_cfg_cnt; i++) { -+ for (bm_port_id = port_cfg[i].port_id_start; -+ bm_port_id <= port_cfg[i].port_id_end; bm_port_id++) { -+ ret = ppe_config_bm_threshold(ppe_dev, bm_port_id, -+ port_cfg[i]); -+ if (ret) -+ goto bm_config_fail; -+ } -+ } -+ -+ return 0; -+ -+bm_config_fail: -+ dev_err(ppe_dev->dev, "PPE BM config error %d\n", ret); -+ return ret; -+} -+ -+int ppe_hw_config(struct ppe_device *ppe_dev) -+{ -+ return ppe_config_bm(ppe_dev); -+} ---- /dev/null -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h -@@ -0,0 +1,12 @@ -+/* SPDX-License-Identifier: GPL-2.0-only -+ * -+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __PPE_CONFIG_H__ -+#define __PPE_CONFIG_H__ -+ -+#include "ppe.h" -+ -+int ppe_hw_config(struct ppe_device *ppe_dev); -+#endif ---- /dev/null -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h -@@ -0,0 +1,59 @@ -+/* SPDX-License-Identifier: GPL-2.0-only -+ * -+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+/* PPE hardware register and table declarations. */ -+#ifndef __PPE_REGS_H__ -+#define __PPE_REGS_H__ -+ -+#include -+ -+/* There are 15 BM ports and 4 BM groups supported by PPE. -+ * BM port (0-7) is for EDMA port 0, BM port (8-13) is for -+ * PPE physical port 1-6 and BM port 14 is for EIP port. -+ */ -+#define PPE_BM_PORT_FC_MODE_ADDR 0x600100 -+#define PPE_BM_PORT_FC_MODE_ENTRIES 15 -+#define PPE_BM_PORT_FC_MODE_INC 0x4 -+#define PPE_BM_PORT_FC_MODE_EN BIT(0) -+ -+#define PPE_BM_PORT_GROUP_ID_ADDR 0x600180 -+#define PPE_BM_PORT_GROUP_ID_ENTRIES 15 -+#define PPE_BM_PORT_GROUP_ID_INC 0x4 -+#define PPE_BM_PORT_GROUP_ID_SHARED_GROUP_ID GENMASK(1, 0) -+ -+#define PPE_BM_SHARED_GROUP_CFG_ADDR 0x600290 -+#define PPE_BM_SHARED_GROUP_CFG_ENTRIES 4 -+#define PPE_BM_SHARED_GROUP_CFG_INC 0x4 -+#define PPE_BM_SHARED_GROUP_CFG_SHARED_LIMIT GENMASK(10, 0) -+ -+#define PPE_BM_PORT_FC_CFG_TBL_ADDR 0x601000 -+#define PPE_BM_PORT_FC_CFG_TBL_ENTRIES 15 -+#define PPE_BM_PORT_FC_CFG_TBL_INC 0x10 -+#define PPE_BM_PORT_FC_W0_REACT_LIMIT GENMASK(8, 0) -+#define PPE_BM_PORT_FC_W0_RESUME_THRESHOLD GENMASK(17, 9) -+#define PPE_BM_PORT_FC_W0_RESUME_OFFSET GENMASK(28, 18) -+#define PPE_BM_PORT_FC_W0_CEILING_LOW GENMASK(31, 29) -+#define PPE_BM_PORT_FC_W1_CEILING_HIGH GENMASK(7, 0) -+#define PPE_BM_PORT_FC_W1_WEIGHT GENMASK(10, 8) -+#define PPE_BM_PORT_FC_W1_DYNAMIC BIT(11) -+#define PPE_BM_PORT_FC_W1_PRE_ALLOC GENMASK(22, 12) -+ -+#define PPE_BM_PORT_FC_SET_REACT_LIMIT(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_BM_PORT_FC_W0_REACT_LIMIT) -+#define PPE_BM_PORT_FC_SET_RESUME_THRESHOLD(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_BM_PORT_FC_W0_RESUME_THRESHOLD) -+#define PPE_BM_PORT_FC_SET_RESUME_OFFSET(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_BM_PORT_FC_W0_RESUME_OFFSET) -+#define PPE_BM_PORT_FC_SET_CEILING_LOW(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_BM_PORT_FC_W0_CEILING_LOW) -+#define PPE_BM_PORT_FC_SET_CEILING_HIGH(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_CEILING_HIGH) -+#define PPE_BM_PORT_FC_SET_WEIGHT(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_WEIGHT) -+#define PPE_BM_PORT_FC_SET_DYNAMIC(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_DYNAMIC) -+#define PPE_BM_PORT_FC_SET_PRE_ALLOC(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_PRE_ALLOC) -+#endif diff --git a/target/linux/qualcommbe/patches-6.18/0327-net-ethernet-qualcomm-Initialize-PPE-queue-managemen.patch b/target/linux/qualcommbe/patches-6.18/0327-net-ethernet-qualcomm-Initialize-PPE-queue-managemen.patch deleted file mode 100644 index be16222b96..0000000000 --- a/target/linux/qualcommbe/patches-6.18/0327-net-ethernet-qualcomm-Initialize-PPE-queue-managemen.patch +++ /dev/null @@ -1,320 +0,0 @@ -From 9be6c3590ef3c241e6a3cfd05291304a1f973bcf Mon Sep 17 00:00:00 2001 -From: Luo Jie -Date: Sun, 9 Feb 2025 22:29:39 +0800 -Subject: [PATCH] net: ethernet: qualcomm: Initialize PPE queue management for - IPQ9574 - -QM (queue management) configurations decide the length of PPE -queues and the queue depth for these queues which are used to -drop packets in events of congestion. - -There are two types of PPE queues - unicast queues (0-255) and -multicast queues (256-299). These queue types are used to forward -different types of traffic, and are configured with different -lengths. - -Signed-off-by: Luo Jie ---- - .../net/ethernet/qualcomm/ppe/ppe_config.c | 177 +++++++++++++++++- - drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 85 +++++++++ - 2 files changed, 261 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c -@@ -43,6 +43,29 @@ struct ppe_bm_port_config { - bool dynamic; - }; - -+/** -+ * struct ppe_qm_queue_config - PPE queue config. -+ * @queue_start: PPE start of queue ID. -+ * @queue_end: PPE end of queue ID. -+ * @prealloc_buf: Queue dedicated buffer number. -+ * @ceil: Ceil to start drop packet from queue. -+ * @weight: Weight value. -+ * @resume_offset: Resume offset from the threshold. -+ * @dynamic: Threshold value is decided dynamically or statically. -+ * -+ * Queue configuration decides the threshold to drop packet from PPE -+ * hardware queue. -+ */ -+struct ppe_qm_queue_config { -+ unsigned int queue_start; -+ unsigned int queue_end; -+ unsigned int prealloc_buf; -+ unsigned int ceil; -+ unsigned int weight; -+ unsigned int resume_offset; -+ bool dynamic; -+}; -+ - /* Assign the share buffer number 1550 to group 0 by default. */ - static const int ipq9574_ppe_bm_group_config = 1550; - -@@ -102,6 +125,33 @@ static const struct ppe_bm_port_config i - }, - }; - -+/* Default QM group settings for IPQ9754. */ -+static const int ipq9574_ppe_qm_group_config = 2000; -+ -+/* Default QM settings for unicast and multicast queues for IPQ9754. */ -+static const struct ppe_qm_queue_config ipq9574_ppe_qm_queue_config[] = { -+ { -+ /* QM settings for unicast queues 0 to 255. */ -+ .queue_start = 0, -+ .queue_end = 255, -+ .prealloc_buf = 0, -+ .ceil = 1200, -+ .weight = 7, -+ .resume_offset = 36, -+ .dynamic = true, -+ }, -+ { -+ /* QM settings for multicast queues 256 to 299. */ -+ .queue_start = 256, -+ .queue_end = 299, -+ .prealloc_buf = 0, -+ .ceil = 250, -+ .weight = 0, -+ .resume_offset = 36, -+ .dynamic = false, -+ }, -+}; -+ - static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id, - const struct ppe_bm_port_config port_cfg) - { -@@ -189,7 +239,132 @@ bm_config_fail: - return ret; - } - -+/* Configure PPE hardware queue depth, which is decided by the threshold -+ * of queue. -+ */ -+static int ppe_config_qm(struct ppe_device *ppe_dev) -+{ -+ const struct ppe_qm_queue_config *queue_cfg; -+ int ret, i, queue_id, queue_cfg_count; -+ u32 reg, multicast_queue_cfg[5]; -+ u32 unicast_queue_cfg[4]; -+ u32 group_cfg[3]; -+ -+ /* Assign the buffer number to the group 0 by default. */ -+ reg = PPE_AC_GRP_CFG_TBL_ADDR; -+ ret = regmap_bulk_read(ppe_dev->regmap, reg, -+ group_cfg, ARRAY_SIZE(group_cfg)); -+ if (ret) -+ goto qm_config_fail; -+ -+ PPE_AC_GRP_SET_BUF_LIMIT(group_cfg, ipq9574_ppe_qm_group_config); -+ -+ ret = regmap_bulk_write(ppe_dev->regmap, reg, -+ group_cfg, ARRAY_SIZE(group_cfg)); -+ if (ret) -+ goto qm_config_fail; -+ -+ queue_cfg = ipq9574_ppe_qm_queue_config; -+ queue_cfg_count = ARRAY_SIZE(ipq9574_ppe_qm_queue_config); -+ for (i = 0; i < queue_cfg_count; i++) { -+ queue_id = queue_cfg[i].queue_start; -+ -+ /* Configure threshold for dropping packets separately for -+ * unicast and multicast PPE queues. -+ */ -+ while (queue_id <= queue_cfg[i].queue_end) { -+ if (queue_id < PPE_AC_UNICAST_QUEUE_CFG_TBL_ENTRIES) { -+ reg = PPE_AC_UNICAST_QUEUE_CFG_TBL_ADDR + -+ PPE_AC_UNICAST_QUEUE_CFG_TBL_INC * queue_id; -+ -+ ret = regmap_bulk_read(ppe_dev->regmap, reg, -+ unicast_queue_cfg, -+ ARRAY_SIZE(unicast_queue_cfg)); -+ if (ret) -+ goto qm_config_fail; -+ -+ PPE_AC_UNICAST_QUEUE_SET_EN(unicast_queue_cfg, true); -+ PPE_AC_UNICAST_QUEUE_SET_GRP_ID(unicast_queue_cfg, 0); -+ PPE_AC_UNICAST_QUEUE_SET_PRE_LIMIT(unicast_queue_cfg, -+ queue_cfg[i].prealloc_buf); -+ PPE_AC_UNICAST_QUEUE_SET_DYNAMIC(unicast_queue_cfg, -+ queue_cfg[i].dynamic); -+ PPE_AC_UNICAST_QUEUE_SET_WEIGHT(unicast_queue_cfg, -+ queue_cfg[i].weight); -+ PPE_AC_UNICAST_QUEUE_SET_THRESHOLD(unicast_queue_cfg, -+ queue_cfg[i].ceil); -+ PPE_AC_UNICAST_QUEUE_SET_GRN_RESUME(unicast_queue_cfg, -+ queue_cfg[i].resume_offset); -+ -+ ret = regmap_bulk_write(ppe_dev->regmap, reg, -+ unicast_queue_cfg, -+ ARRAY_SIZE(unicast_queue_cfg)); -+ if (ret) -+ goto qm_config_fail; -+ } else { -+ reg = PPE_AC_MULTICAST_QUEUE_CFG_TBL_ADDR + -+ PPE_AC_MULTICAST_QUEUE_CFG_TBL_INC * queue_id; -+ -+ ret = regmap_bulk_read(ppe_dev->regmap, reg, -+ multicast_queue_cfg, -+ ARRAY_SIZE(multicast_queue_cfg)); -+ if (ret) -+ goto qm_config_fail; -+ -+ PPE_AC_MULTICAST_QUEUE_SET_EN(multicast_queue_cfg, true); -+ PPE_AC_MULTICAST_QUEUE_SET_GRN_GRP_ID(multicast_queue_cfg, 0); -+ PPE_AC_MULTICAST_QUEUE_SET_GRN_PRE_LIMIT(multicast_queue_cfg, -+ queue_cfg[i].prealloc_buf); -+ PPE_AC_MULTICAST_QUEUE_SET_GRN_THRESHOLD(multicast_queue_cfg, -+ queue_cfg[i].ceil); -+ PPE_AC_MULTICAST_QUEUE_SET_GRN_RESUME(multicast_queue_cfg, -+ queue_cfg[i].resume_offset); -+ -+ ret = regmap_bulk_write(ppe_dev->regmap, reg, -+ multicast_queue_cfg, -+ ARRAY_SIZE(multicast_queue_cfg)); -+ if (ret) -+ goto qm_config_fail; -+ } -+ -+ /* Enable enqueue. */ -+ reg = PPE_ENQ_OPR_TBL_ADDR + PPE_ENQ_OPR_TBL_INC * queue_id; -+ ret = regmap_clear_bits(ppe_dev->regmap, reg, -+ PPE_ENQ_OPR_TBL_ENQ_DISABLE); -+ if (ret) -+ goto qm_config_fail; -+ -+ /* Enable dequeue. */ -+ reg = PPE_DEQ_OPR_TBL_ADDR + PPE_DEQ_OPR_TBL_INC * queue_id; -+ ret = regmap_clear_bits(ppe_dev->regmap, reg, -+ PPE_DEQ_OPR_TBL_DEQ_DISABLE); -+ if (ret) -+ goto qm_config_fail; -+ -+ queue_id++; -+ } -+ } -+ -+ /* Enable queue counter for all PPE hardware queues. */ -+ ret = regmap_set_bits(ppe_dev->regmap, PPE_EG_BRIDGE_CONFIG_ADDR, -+ PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN); -+ if (ret) -+ goto qm_config_fail; -+ -+ return 0; -+ -+qm_config_fail: -+ dev_err(ppe_dev->dev, "PPE QM config error %d\n", ret); -+ return ret; -+} -+ - int ppe_hw_config(struct ppe_device *ppe_dev) - { -- return ppe_config_bm(ppe_dev); -+ int ret; -+ -+ ret = ppe_config_bm(ppe_dev); -+ if (ret) -+ return ret; -+ -+ return ppe_config_qm(ppe_dev); - } ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h -@@ -9,6 +9,16 @@ - - #include - -+/* PPE queue counters enable/disable control. */ -+#define PPE_EG_BRIDGE_CONFIG_ADDR 0x20044 -+#define PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN BIT(2) -+ -+/* Table addresses for per-queue dequeue setting. */ -+#define PPE_DEQ_OPR_TBL_ADDR 0x430000 -+#define PPE_DEQ_OPR_TBL_ENTRIES 300 -+#define PPE_DEQ_OPR_TBL_INC 0x10 -+#define PPE_DEQ_OPR_TBL_DEQ_DISABLE BIT(0) -+ - /* There are 15 BM ports and 4 BM groups supported by PPE. - * BM port (0-7) is for EDMA port 0, BM port (8-13) is for - * PPE physical port 1-6 and BM port 14 is for EIP port. -@@ -56,4 +66,79 @@ - u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_DYNAMIC) - #define PPE_BM_PORT_FC_SET_PRE_ALLOC(tbl_cfg, value) \ - u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_PRE_ALLOC) -+ -+/* PPE unicast queue (0-255) configurations. */ -+#define PPE_AC_UNICAST_QUEUE_CFG_TBL_ADDR 0x848000 -+#define PPE_AC_UNICAST_QUEUE_CFG_TBL_ENTRIES 256 -+#define PPE_AC_UNICAST_QUEUE_CFG_TBL_INC 0x10 -+#define PPE_AC_UNICAST_QUEUE_CFG_W0_EN BIT(0) -+#define PPE_AC_UNICAST_QUEUE_CFG_W0_WRED_EN BIT(1) -+#define PPE_AC_UNICAST_QUEUE_CFG_W0_FC_EN BIT(2) -+#define PPE_AC_UNICAST_QUEUE_CFG_W0_CLR_AWARE BIT(3) -+#define PPE_AC_UNICAST_QUEUE_CFG_W0_GRP_ID GENMASK(5, 4) -+#define PPE_AC_UNICAST_QUEUE_CFG_W0_PRE_LIMIT GENMASK(16, 6) -+#define PPE_AC_UNICAST_QUEUE_CFG_W0_DYNAMIC BIT(17) -+#define PPE_AC_UNICAST_QUEUE_CFG_W0_WEIGHT GENMASK(20, 18) -+#define PPE_AC_UNICAST_QUEUE_CFG_W0_THRESHOLD GENMASK(31, 21) -+#define PPE_AC_UNICAST_QUEUE_CFG_W3_GRN_RESUME GENMASK(23, 13) -+ -+#define PPE_AC_UNICAST_QUEUE_SET_EN(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNICAST_QUEUE_CFG_W0_EN) -+#define PPE_AC_UNICAST_QUEUE_SET_GRP_ID(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNICAST_QUEUE_CFG_W0_GRP_ID) -+#define PPE_AC_UNICAST_QUEUE_SET_PRE_LIMIT(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNICAST_QUEUE_CFG_W0_PRE_LIMIT) -+#define PPE_AC_UNICAST_QUEUE_SET_DYNAMIC(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNICAST_QUEUE_CFG_W0_DYNAMIC) -+#define PPE_AC_UNICAST_QUEUE_SET_WEIGHT(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNICAST_QUEUE_CFG_W0_WEIGHT) -+#define PPE_AC_UNICAST_QUEUE_SET_THRESHOLD(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNICAST_QUEUE_CFG_W0_THRESHOLD) -+#define PPE_AC_UNICAST_QUEUE_SET_GRN_RESUME(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x3, value, PPE_AC_UNICAST_QUEUE_CFG_W3_GRN_RESUME) -+ -+/* PPE multicast queue (256-299) configurations. */ -+#define PPE_AC_MULTICAST_QUEUE_CFG_TBL_ADDR 0x84a000 -+#define PPE_AC_MULTICAST_QUEUE_CFG_TBL_ENTRIES 44 -+#define PPE_AC_MULTICAST_QUEUE_CFG_TBL_INC 0x10 -+#define PPE_AC_MULTICAST_QUEUE_CFG_W0_EN BIT(0) -+#define PPE_AC_MULTICAST_QUEUE_CFG_W0_FC_EN BIT(1) -+#define PPE_AC_MULTICAST_QUEUE_CFG_W0_CLR_AWARE BIT(2) -+#define PPE_AC_MULTICAST_QUEUE_CFG_W0_GRP_ID GENMASK(4, 3) -+#define PPE_AC_MULTICAST_QUEUE_CFG_W0_PRE_LIMIT GENMASK(15, 5) -+#define PPE_AC_MULTICAST_QUEUE_CFG_W0_THRESHOLD GENMASK(26, 16) -+#define PPE_AC_MULTICAST_QUEUE_CFG_W2_RESUME GENMASK(17, 7) -+ -+#define PPE_AC_MULTICAST_QUEUE_SET_EN(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_MULTICAST_QUEUE_CFG_W0_EN) -+#define PPE_AC_MULTICAST_QUEUE_SET_GRN_GRP_ID(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_MULTICAST_QUEUE_CFG_W0_GRP_ID) -+#define PPE_AC_MULTICAST_QUEUE_SET_GRN_PRE_LIMIT(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_MULTICAST_QUEUE_CFG_W0_PRE_LIMIT) -+#define PPE_AC_MULTICAST_QUEUE_SET_GRN_THRESHOLD(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_MULTICAST_QUEUE_CFG_W0_THRESHOLD) -+#define PPE_AC_MULTICAST_QUEUE_SET_GRN_RESUME(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x2, value, PPE_AC_MULTICAST_QUEUE_CFG_W2_RESUME) -+ -+/* PPE admission control group (0-3) configurations */ -+#define PPE_AC_GRP_CFG_TBL_ADDR 0x84c000 -+#define PPE_AC_GRP_CFG_TBL_ENTRIES 0x4 -+#define PPE_AC_GRP_CFG_TBL_INC 0x10 -+#define PPE_AC_GRP_W0_AC_EN BIT(0) -+#define PPE_AC_GRP_W0_AC_FC_EN BIT(1) -+#define PPE_AC_GRP_W0_CLR_AWARE BIT(2) -+#define PPE_AC_GRP_W0_THRESHOLD_LOW GENMASK(31, 25) -+#define PPE_AC_GRP_W1_THRESHOLD_HIGH GENMASK(3, 0) -+#define PPE_AC_GRP_W1_BUF_LIMIT GENMASK(14, 4) -+#define PPE_AC_GRP_W2_RESUME_GRN GENMASK(15, 5) -+#define PPE_AC_GRP_W2_PRE_ALLOC GENMASK(26, 16) -+ -+#define PPE_AC_GRP_SET_BUF_LIMIT(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_AC_GRP_W1_BUF_LIMIT) -+ -+/* Table addresses for per-queue enqueue setting. */ -+#define PPE_ENQ_OPR_TBL_ADDR 0x85c000 -+#define PPE_ENQ_OPR_TBL_ENTRIES 300 -+#define PPE_ENQ_OPR_TBL_INC 0x10 -+#define PPE_ENQ_OPR_TBL_ENQ_DISABLE BIT(0) - #endif diff --git a/target/linux/qualcommbe/patches-6.18/0328-net-ethernet-qualcomm-Initialize-the-PPE-scheduler-s.patch b/target/linux/qualcommbe/patches-6.18/0328-net-ethernet-qualcomm-Initialize-the-PPE-scheduler-s.patch deleted file mode 100644 index 86949a2f3b..0000000000 --- a/target/linux/qualcommbe/patches-6.18/0328-net-ethernet-qualcomm-Initialize-the-PPE-scheduler-s.patch +++ /dev/null @@ -1,1000 +0,0 @@ -From 333edaf474cd707b0a04c57f255b56bc3c015789 Mon Sep 17 00:00:00 2001 -From: Luo Jie -Date: Sun, 9 Feb 2025 22:29:40 +0800 -Subject: [PATCH] net: ethernet: qualcomm: Initialize the PPE scheduler - settings - -The PPE scheduler settings determine the priority of scheduling the -packet across the different hardware queues per PPE port. - -Signed-off-by: Luo Jie ---- - .../net/ethernet/qualcomm/ppe/ppe_config.c | 788 +++++++++++++++++- - .../net/ethernet/qualcomm/ppe/ppe_config.h | 37 + - drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 97 +++ - 3 files changed, 921 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c -@@ -16,6 +16,8 @@ - #include "ppe_config.h" - #include "ppe_regs.h" - -+#define PPE_QUEUE_SCH_PRI_NUM 8 -+ - /** - * struct ppe_bm_port_config - PPE BM port configuration. - * @port_id_start: The fist BM port ID to configure. -@@ -66,6 +68,66 @@ struct ppe_qm_queue_config { - bool dynamic; - }; - -+/** -+ * struct ppe_scheduler_bm_config - PPE arbitration for buffer config. -+ * @valid: Arbitration entry valid or not. -+ * @is_egress: Arbitration entry for egress or not. -+ * @port: Port ID to use arbitration entry. -+ * @second_valid: Second port valid or not. -+ * @second_port: Second port to use. -+ * -+ * Configure the scheduler settings for accessing and releasing the PPE buffers. -+ */ -+struct ppe_scheduler_bm_config { -+ bool valid; -+ bool is_egress; -+ unsigned int port; -+ bool second_valid; -+ unsigned int second_port; -+}; -+ -+/** -+ * struct ppe_scheduler_qm_config - PPE arbitration for scheduler config. -+ * @ensch_port_bmp: Port bit map for enqueue scheduler. -+ * @ensch_port: Port ID to enqueue scheduler. -+ * @desch_port: Port ID to dequeue scheduler. -+ * @desch_second_valid: Dequeue for the second port valid or not. -+ * @desch_second_port: Second port ID to dequeue scheduler. -+ * -+ * Configure the scheduler settings for enqueuing and dequeuing packets on -+ * the PPE port. -+ */ -+struct ppe_scheduler_qm_config { -+ unsigned int ensch_port_bmp; -+ unsigned int ensch_port; -+ unsigned int desch_port; -+ bool desch_second_valid; -+ unsigned int desch_second_port; -+}; -+ -+/** -+ * struct ppe_scheduler_port_config - PPE port scheduler config. -+ * @port: Port ID to be scheduled. -+ * @flow_level: Scheduler flow level or not. -+ * @node_id: Node ID, for level 0, queue ID is used. -+ * @loop_num: Loop number of scheduler config. -+ * @pri_max: Max priority configured. -+ * @flow_id: Strict priority ID. -+ * @drr_node_id: Node ID for scheduler. -+ * -+ * PPE port scheduler configuration which decides the priority in the -+ * packet scheduler for the egress port. -+ */ -+struct ppe_scheduler_port_config { -+ unsigned int port; -+ bool flow_level; -+ unsigned int node_id; -+ unsigned int loop_num; -+ unsigned int pri_max; -+ unsigned int flow_id; -+ unsigned int drr_node_id; -+}; -+ - /* Assign the share buffer number 1550 to group 0 by default. */ - static const int ipq9574_ppe_bm_group_config = 1550; - -@@ -152,6 +214,599 @@ static const struct ppe_qm_queue_config - }, - }; - -+/* Scheduler configuration for the assigning and releasing buffers for the -+ * packet passing through PPE, which is different per SoC. -+ */ -+static const struct ppe_scheduler_bm_config ipq9574_ppe_sch_bm_config[] = { -+ {1, 0, 0, 0, 0}, -+ {1, 1, 0, 0, 0}, -+ {1, 0, 5, 0, 0}, -+ {1, 1, 5, 0, 0}, -+ {1, 0, 6, 0, 0}, -+ {1, 1, 6, 0, 0}, -+ {1, 0, 1, 0, 0}, -+ {1, 1, 1, 0, 0}, -+ {1, 0, 0, 0, 0}, -+ {1, 1, 0, 0, 0}, -+ {1, 0, 5, 0, 0}, -+ {1, 1, 5, 0, 0}, -+ {1, 0, 6, 0, 0}, -+ {1, 1, 6, 0, 0}, -+ {1, 0, 7, 0, 0}, -+ {1, 1, 7, 0, 0}, -+ {1, 0, 0, 0, 0}, -+ {1, 1, 0, 0, 0}, -+ {1, 0, 1, 0, 0}, -+ {1, 1, 1, 0, 0}, -+ {1, 0, 5, 0, 0}, -+ {1, 1, 5, 0, 0}, -+ {1, 0, 6, 0, 0}, -+ {1, 1, 6, 0, 0}, -+ {1, 0, 2, 0, 0}, -+ {1, 1, 2, 0, 0}, -+ {1, 0, 0, 0, 0}, -+ {1, 1, 0, 0, 0}, -+ {1, 0, 5, 0, 0}, -+ {1, 1, 5, 0, 0}, -+ {1, 0, 6, 0, 0}, -+ {1, 1, 6, 0, 0}, -+ {1, 0, 1, 0, 0}, -+ {1, 1, 1, 0, 0}, -+ {1, 0, 3, 0, 0}, -+ {1, 1, 3, 0, 0}, -+ {1, 0, 0, 0, 0}, -+ {1, 1, 0, 0, 0}, -+ {1, 0, 5, 0, 0}, -+ {1, 1, 5, 0, 0}, -+ {1, 0, 6, 0, 0}, -+ {1, 1, 6, 0, 0}, -+ {1, 0, 7, 0, 0}, -+ {1, 1, 7, 0, 0}, -+ {1, 0, 0, 0, 0}, -+ {1, 1, 0, 0, 0}, -+ {1, 0, 1, 0, 0}, -+ {1, 1, 1, 0, 0}, -+ {1, 0, 5, 0, 0}, -+ {1, 1, 5, 0, 0}, -+ {1, 0, 6, 0, 0}, -+ {1, 1, 6, 0, 0}, -+ {1, 0, 4, 0, 0}, -+ {1, 1, 4, 0, 0}, -+ {1, 0, 0, 0, 0}, -+ {1, 1, 0, 0, 0}, -+ {1, 0, 5, 0, 0}, -+ {1, 1, 5, 0, 0}, -+ {1, 0, 6, 0, 0}, -+ {1, 1, 6, 0, 0}, -+ {1, 0, 1, 0, 0}, -+ {1, 1, 1, 0, 0}, -+ {1, 0, 0, 0, 0}, -+ {1, 1, 0, 0, 0}, -+ {1, 0, 5, 0, 0}, -+ {1, 1, 5, 0, 0}, -+ {1, 0, 6, 0, 0}, -+ {1, 1, 6, 0, 0}, -+ {1, 0, 2, 0, 0}, -+ {1, 1, 2, 0, 0}, -+ {1, 0, 0, 0, 0}, -+ {1, 1, 0, 0, 0}, -+ {1, 0, 7, 0, 0}, -+ {1, 1, 7, 0, 0}, -+ {1, 0, 5, 0, 0}, -+ {1, 1, 5, 0, 0}, -+ {1, 0, 6, 0, 0}, -+ {1, 1, 6, 0, 0}, -+ {1, 0, 1, 0, 0}, -+ {1, 1, 1, 0, 0}, -+ {1, 0, 0, 0, 0}, -+ {1, 1, 0, 0, 0}, -+ {1, 0, 5, 0, 0}, -+ {1, 1, 5, 0, 0}, -+ {1, 0, 6, 0, 0}, -+ {1, 1, 6, 0, 0}, -+ {1, 0, 3, 0, 0}, -+ {1, 1, 3, 0, 0}, -+ {1, 0, 1, 0, 0}, -+ {1, 1, 1, 0, 0}, -+ {1, 0, 0, 0, 0}, -+ {1, 1, 0, 0, 0}, -+ {1, 0, 5, 0, 0}, -+ {1, 1, 5, 0, 0}, -+ {1, 0, 6, 0, 0}, -+ {1, 1, 6, 0, 0}, -+ {1, 0, 4, 0, 0}, -+ {1, 1, 4, 0, 0}, -+ {1, 0, 7, 0, 0}, -+ {1, 1, 7, 0, 0}, -+}; -+ -+/* Scheduler configuration for dispatching packet on PPE queues, which -+ * is different per SoC. -+ */ -+static const struct ppe_scheduler_qm_config ipq9574_ppe_sch_qm_config[] = { -+ {0x98, 6, 0, 1, 1}, -+ {0x94, 5, 6, 1, 3}, -+ {0x86, 0, 5, 1, 4}, -+ {0x8C, 1, 6, 1, 0}, -+ {0x1C, 7, 5, 1, 1}, -+ {0x98, 2, 6, 1, 0}, -+ {0x1C, 5, 7, 1, 1}, -+ {0x34, 3, 6, 1, 0}, -+ {0x8C, 4, 5, 1, 1}, -+ {0x98, 2, 6, 1, 0}, -+ {0x8C, 5, 4, 1, 1}, -+ {0xA8, 0, 6, 1, 2}, -+ {0x98, 5, 1, 1, 0}, -+ {0x98, 6, 5, 1, 2}, -+ {0x89, 1, 6, 1, 4}, -+ {0xA4, 3, 0, 1, 1}, -+ {0x8C, 5, 6, 1, 4}, -+ {0xA8, 0, 2, 1, 1}, -+ {0x98, 6, 5, 1, 0}, -+ {0xC4, 4, 3, 1, 1}, -+ {0x94, 6, 5, 1, 0}, -+ {0x1C, 7, 6, 1, 1}, -+ {0x98, 2, 5, 1, 0}, -+ {0x1C, 6, 7, 1, 1}, -+ {0x1C, 5, 6, 1, 0}, -+ {0x94, 3, 5, 1, 1}, -+ {0x8C, 4, 6, 1, 0}, -+ {0x94, 1, 5, 1, 3}, -+ {0x94, 6, 1, 1, 0}, -+ {0xD0, 3, 5, 1, 2}, -+ {0x98, 6, 0, 1, 1}, -+ {0x94, 5, 6, 1, 3}, -+ {0x94, 1, 5, 1, 0}, -+ {0x98, 2, 6, 1, 1}, -+ {0x8C, 4, 5, 1, 0}, -+ {0x1C, 7, 6, 1, 1}, -+ {0x8C, 0, 5, 1, 4}, -+ {0x89, 1, 6, 1, 2}, -+ {0x98, 5, 0, 1, 1}, -+ {0x94, 6, 5, 1, 3}, -+ {0x92, 0, 6, 1, 2}, -+ {0x98, 1, 5, 1, 0}, -+ {0x98, 6, 2, 1, 1}, -+ {0xD0, 0, 5, 1, 3}, -+ {0x94, 6, 0, 1, 1}, -+ {0x8C, 5, 6, 1, 4}, -+ {0x8C, 1, 5, 1, 0}, -+ {0x1C, 6, 7, 1, 1}, -+ {0x1C, 5, 6, 1, 0}, -+ {0xB0, 2, 3, 1, 1}, -+ {0xC4, 4, 5, 1, 0}, -+ {0x8C, 6, 4, 1, 1}, -+ {0xA4, 3, 6, 1, 0}, -+ {0x1C, 5, 7, 1, 1}, -+ {0x4C, 0, 5, 1, 4}, -+ {0x8C, 6, 0, 1, 1}, -+ {0x34, 7, 6, 1, 3}, -+ {0x94, 5, 0, 1, 1}, -+ {0x98, 6, 5, 1, 2}, -+}; -+ -+static const struct ppe_scheduler_port_config ppe_port_sch_config[] = { -+ { -+ .port = 0, -+ .flow_level = true, -+ .node_id = 0, -+ .loop_num = 1, -+ .pri_max = 1, -+ .flow_id = 0, -+ .drr_node_id = 0, -+ }, -+ { -+ .port = 0, -+ .flow_level = false, -+ .node_id = 0, -+ .loop_num = 8, -+ .pri_max = 8, -+ .flow_id = 0, -+ .drr_node_id = 0, -+ }, -+ { -+ .port = 0, -+ .flow_level = false, -+ .node_id = 8, -+ .loop_num = 8, -+ .pri_max = 8, -+ .flow_id = 0, -+ .drr_node_id = 0, -+ }, -+ { -+ .port = 0, -+ .flow_level = false, -+ .node_id = 16, -+ .loop_num = 8, -+ .pri_max = 8, -+ .flow_id = 0, -+ .drr_node_id = 0, -+ }, -+ { -+ .port = 0, -+ .flow_level = false, -+ .node_id = 24, -+ .loop_num = 8, -+ .pri_max = 8, -+ .flow_id = 0, -+ .drr_node_id = 0, -+ }, -+ { -+ .port = 0, -+ .flow_level = false, -+ .node_id = 32, -+ .loop_num = 8, -+ .pri_max = 8, -+ .flow_id = 0, -+ .drr_node_id = 0, -+ }, -+ { -+ .port = 0, -+ .flow_level = false, -+ .node_id = 40, -+ .loop_num = 8, -+ .pri_max = 8, -+ .flow_id = 0, -+ .drr_node_id = 0, -+ }, -+ { -+ .port = 0, -+ .flow_level = false, -+ .node_id = 48, -+ .loop_num = 8, -+ .pri_max = 8, -+ .flow_id = 0, -+ .drr_node_id = 0, -+ }, -+ { -+ .port = 0, -+ .flow_level = false, -+ .node_id = 56, -+ .loop_num = 8, -+ .pri_max = 8, -+ .flow_id = 0, -+ .drr_node_id = 0, -+ }, -+ { -+ .port = 0, -+ .flow_level = false, -+ .node_id = 256, -+ .loop_num = 8, -+ .pri_max = 8, -+ .flow_id = 0, -+ .drr_node_id = 0, -+ }, -+ { -+ .port = 0, -+ .flow_level = false, -+ .node_id = 264, -+ .loop_num = 8, -+ .pri_max = 8, -+ .flow_id = 0, -+ .drr_node_id = 0, -+ }, -+ { -+ .port = 1, -+ .flow_level = true, -+ .node_id = 36, -+ .loop_num = 2, -+ .pri_max = 0, -+ .flow_id = 1, -+ .drr_node_id = 8, -+ }, -+ { -+ .port = 1, -+ .flow_level = false, -+ .node_id = 144, -+ .loop_num = 16, -+ .pri_max = 8, -+ .flow_id = 36, -+ .drr_node_id = 48, -+ }, -+ { -+ .port = 1, -+ .flow_level = false, -+ .node_id = 272, -+ .loop_num = 4, -+ .pri_max = 4, -+ .flow_id = 36, -+ .drr_node_id = 48, -+ }, -+ { -+ .port = 2, -+ .flow_level = true, -+ .node_id = 40, -+ .loop_num = 2, -+ .pri_max = 0, -+ .flow_id = 2, -+ .drr_node_id = 12, -+ }, -+ { -+ .port = 2, -+ .flow_level = false, -+ .node_id = 160, -+ .loop_num = 16, -+ .pri_max = 8, -+ .flow_id = 40, -+ .drr_node_id = 64, -+ }, -+ { -+ .port = 2, -+ .flow_level = false, -+ .node_id = 276, -+ .loop_num = 4, -+ .pri_max = 4, -+ .flow_id = 40, -+ .drr_node_id = 64, -+ }, -+ { -+ .port = 3, -+ .flow_level = true, -+ .node_id = 44, -+ .loop_num = 2, -+ .pri_max = 0, -+ .flow_id = 3, -+ .drr_node_id = 16, -+ }, -+ { -+ .port = 3, -+ .flow_level = false, -+ .node_id = 176, -+ .loop_num = 16, -+ .pri_max = 8, -+ .flow_id = 44, -+ .drr_node_id = 80, -+ }, -+ { -+ .port = 3, -+ .flow_level = false, -+ .node_id = 280, -+ .loop_num = 4, -+ .pri_max = 4, -+ .flow_id = 44, -+ .drr_node_id = 80, -+ }, -+ { -+ .port = 4, -+ .flow_level = true, -+ .node_id = 48, -+ .loop_num = 2, -+ .pri_max = 0, -+ .flow_id = 4, -+ .drr_node_id = 20, -+ }, -+ { -+ .port = 4, -+ .flow_level = false, -+ .node_id = 192, -+ .loop_num = 16, -+ .pri_max = 8, -+ .flow_id = 48, -+ .drr_node_id = 96, -+ }, -+ { -+ .port = 4, -+ .flow_level = false, -+ .node_id = 284, -+ .loop_num = 4, -+ .pri_max = 4, -+ .flow_id = 48, -+ .drr_node_id = 96, -+ }, -+ { -+ .port = 5, -+ .flow_level = true, -+ .node_id = 52, -+ .loop_num = 2, -+ .pri_max = 0, -+ .flow_id = 5, -+ .drr_node_id = 24, -+ }, -+ { -+ .port = 5, -+ .flow_level = false, -+ .node_id = 208, -+ .loop_num = 16, -+ .pri_max = 8, -+ .flow_id = 52, -+ .drr_node_id = 112, -+ }, -+ { -+ .port = 5, -+ .flow_level = false, -+ .node_id = 288, -+ .loop_num = 4, -+ .pri_max = 4, -+ .flow_id = 52, -+ .drr_node_id = 112, -+ }, -+ { -+ .port = 6, -+ .flow_level = true, -+ .node_id = 56, -+ .loop_num = 2, -+ .pri_max = 0, -+ .flow_id = 6, -+ .drr_node_id = 28, -+ }, -+ { -+ .port = 6, -+ .flow_level = false, -+ .node_id = 224, -+ .loop_num = 16, -+ .pri_max = 8, -+ .flow_id = 56, -+ .drr_node_id = 128, -+ }, -+ { -+ .port = 6, -+ .flow_level = false, -+ .node_id = 292, -+ .loop_num = 4, -+ .pri_max = 4, -+ .flow_id = 56, -+ .drr_node_id = 128, -+ }, -+ { -+ .port = 7, -+ .flow_level = true, -+ .node_id = 60, -+ .loop_num = 2, -+ .pri_max = 0, -+ .flow_id = 7, -+ .drr_node_id = 32, -+ }, -+ { -+ .port = 7, -+ .flow_level = false, -+ .node_id = 240, -+ .loop_num = 16, -+ .pri_max = 8, -+ .flow_id = 60, -+ .drr_node_id = 144, -+ }, -+ { -+ .port = 7, -+ .flow_level = false, -+ .node_id = 296, -+ .loop_num = 4, -+ .pri_max = 4, -+ .flow_id = 60, -+ .drr_node_id = 144, -+ }, -+}; -+ -+/* Set the PPE queue level scheduler configuration. */ -+static int ppe_scheduler_l0_queue_map_set(struct ppe_device *ppe_dev, -+ int node_id, int port, -+ struct ppe_scheduler_cfg scheduler_cfg) -+{ -+ u32 val, reg; -+ int ret; -+ -+ reg = PPE_L0_FLOW_MAP_TBL_ADDR + node_id * PPE_L0_FLOW_MAP_TBL_INC; -+ val = FIELD_PREP(PPE_L0_FLOW_MAP_TBL_FLOW_ID, scheduler_cfg.flow_id); -+ val |= FIELD_PREP(PPE_L0_FLOW_MAP_TBL_C_PRI, scheduler_cfg.pri); -+ val |= FIELD_PREP(PPE_L0_FLOW_MAP_TBL_E_PRI, scheduler_cfg.pri); -+ val |= FIELD_PREP(PPE_L0_FLOW_MAP_TBL_C_NODE_WT, scheduler_cfg.drr_node_wt); -+ val |= FIELD_PREP(PPE_L0_FLOW_MAP_TBL_E_NODE_WT, scheduler_cfg.drr_node_wt); -+ -+ ret = regmap_write(ppe_dev->regmap, reg, val); -+ if (ret) -+ return ret; -+ -+ reg = PPE_L0_C_FLOW_CFG_TBL_ADDR + -+ (scheduler_cfg.flow_id * PPE_QUEUE_SCH_PRI_NUM + scheduler_cfg.pri) * -+ PPE_L0_C_FLOW_CFG_TBL_INC; -+ val = FIELD_PREP(PPE_L0_C_FLOW_CFG_TBL_NODE_ID, scheduler_cfg.drr_node_id); -+ val |= FIELD_PREP(PPE_L0_C_FLOW_CFG_TBL_NODE_CREDIT_UNIT, scheduler_cfg.unit_is_packet); -+ -+ ret = regmap_write(ppe_dev->regmap, reg, val); -+ if (ret) -+ return ret; -+ -+ reg = PPE_L0_E_FLOW_CFG_TBL_ADDR + -+ (scheduler_cfg.flow_id * PPE_QUEUE_SCH_PRI_NUM + scheduler_cfg.pri) * -+ PPE_L0_E_FLOW_CFG_TBL_INC; -+ val = FIELD_PREP(PPE_L0_E_FLOW_CFG_TBL_NODE_ID, scheduler_cfg.drr_node_id); -+ val |= FIELD_PREP(PPE_L0_E_FLOW_CFG_TBL_NODE_CREDIT_UNIT, scheduler_cfg.unit_is_packet); -+ -+ ret = regmap_write(ppe_dev->regmap, reg, val); -+ if (ret) -+ return ret; -+ -+ reg = PPE_L0_FLOW_PORT_MAP_TBL_ADDR + node_id * PPE_L0_FLOW_PORT_MAP_TBL_INC; -+ val = FIELD_PREP(PPE_L0_FLOW_PORT_MAP_TBL_PORT_NUM, port); -+ -+ ret = regmap_write(ppe_dev->regmap, reg, val); -+ if (ret) -+ return ret; -+ -+ reg = PPE_L0_COMP_CFG_TBL_ADDR + node_id * PPE_L0_COMP_CFG_TBL_INC; -+ val = FIELD_PREP(PPE_L0_COMP_CFG_TBL_NODE_METER_LEN, scheduler_cfg.frame_mode); -+ -+ return regmap_update_bits(ppe_dev->regmap, reg, -+ PPE_L0_COMP_CFG_TBL_NODE_METER_LEN, -+ val); -+} -+ -+/* Set the PPE flow level scheduler configuration. */ -+static int ppe_scheduler_l1_queue_map_set(struct ppe_device *ppe_dev, -+ int node_id, int port, -+ struct ppe_scheduler_cfg scheduler_cfg) -+{ -+ u32 val, reg; -+ int ret; -+ -+ val = FIELD_PREP(PPE_L1_FLOW_MAP_TBL_FLOW_ID, scheduler_cfg.flow_id); -+ val |= FIELD_PREP(PPE_L1_FLOW_MAP_TBL_C_PRI, scheduler_cfg.pri); -+ val |= FIELD_PREP(PPE_L1_FLOW_MAP_TBL_E_PRI, scheduler_cfg.pri); -+ val |= FIELD_PREP(PPE_L1_FLOW_MAP_TBL_C_NODE_WT, scheduler_cfg.drr_node_wt); -+ val |= FIELD_PREP(PPE_L1_FLOW_MAP_TBL_E_NODE_WT, scheduler_cfg.drr_node_wt); -+ reg = PPE_L1_FLOW_MAP_TBL_ADDR + node_id * PPE_L1_FLOW_MAP_TBL_INC; -+ -+ ret = regmap_write(ppe_dev->regmap, reg, val); -+ if (ret) -+ return ret; -+ -+ val = FIELD_PREP(PPE_L1_C_FLOW_CFG_TBL_NODE_ID, scheduler_cfg.drr_node_id); -+ val |= FIELD_PREP(PPE_L1_C_FLOW_CFG_TBL_NODE_CREDIT_UNIT, scheduler_cfg.unit_is_packet); -+ reg = PPE_L1_C_FLOW_CFG_TBL_ADDR + -+ (scheduler_cfg.flow_id * PPE_QUEUE_SCH_PRI_NUM + scheduler_cfg.pri) * -+ PPE_L1_C_FLOW_CFG_TBL_INC; -+ -+ ret = regmap_write(ppe_dev->regmap, reg, val); -+ if (ret) -+ return ret; -+ -+ val = FIELD_PREP(PPE_L1_E_FLOW_CFG_TBL_NODE_ID, scheduler_cfg.drr_node_id); -+ val |= FIELD_PREP(PPE_L1_E_FLOW_CFG_TBL_NODE_CREDIT_UNIT, scheduler_cfg.unit_is_packet); -+ reg = PPE_L1_E_FLOW_CFG_TBL_ADDR + -+ (scheduler_cfg.flow_id * PPE_QUEUE_SCH_PRI_NUM + scheduler_cfg.pri) * -+ PPE_L1_E_FLOW_CFG_TBL_INC; -+ -+ ret = regmap_write(ppe_dev->regmap, reg, val); -+ if (ret) -+ return ret; -+ -+ val = FIELD_PREP(PPE_L1_FLOW_PORT_MAP_TBL_PORT_NUM, port); -+ reg = PPE_L1_FLOW_PORT_MAP_TBL_ADDR + node_id * PPE_L1_FLOW_PORT_MAP_TBL_INC; -+ -+ ret = regmap_write(ppe_dev->regmap, reg, val); -+ if (ret) -+ return ret; -+ -+ reg = PPE_L1_COMP_CFG_TBL_ADDR + node_id * PPE_L1_COMP_CFG_TBL_INC; -+ val = FIELD_PREP(PPE_L1_COMP_CFG_TBL_NODE_METER_LEN, scheduler_cfg.frame_mode); -+ -+ return regmap_update_bits(ppe_dev->regmap, reg, PPE_L1_COMP_CFG_TBL_NODE_METER_LEN, val); -+} -+ -+/** -+ * ppe_queue_scheduler_set - Configure scheduler for PPE hardware queue -+ * @ppe_dev: PPE device -+ * @node_id: PPE queue ID or flow ID -+ * @flow_level: Flow level scheduler or queue level scheduler -+ * @port: PPE port ID set scheduler configuration -+ * @scheduler_cfg: PPE scheduler configuration -+ * -+ * PPE scheduler configuration supports queue level and flow level on -+ * the PPE egress port. -+ * -+ * Return: 0 on success, negative error code on failure. -+ */ -+int ppe_queue_scheduler_set(struct ppe_device *ppe_dev, -+ int node_id, bool flow_level, int port, -+ struct ppe_scheduler_cfg scheduler_cfg) -+{ -+ if (flow_level) -+ return ppe_scheduler_l1_queue_map_set(ppe_dev, node_id, -+ port, scheduler_cfg); -+ -+ return ppe_scheduler_l0_queue_map_set(ppe_dev, node_id, -+ port, scheduler_cfg); -+} -+ - static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id, - const struct ppe_bm_port_config port_cfg) - { -@@ -358,6 +1013,133 @@ qm_config_fail: - return ret; - } - -+static int ppe_node_scheduler_config(struct ppe_device *ppe_dev, -+ const struct ppe_scheduler_port_config config) -+{ -+ struct ppe_scheduler_cfg sch_cfg; -+ int ret, i; -+ -+ for (i = 0; i < config.loop_num; i++) { -+ if (!config.pri_max) { -+ /* Round robin scheduler without priority. */ -+ sch_cfg.flow_id = config.flow_id; -+ sch_cfg.pri = 0; -+ sch_cfg.drr_node_id = config.drr_node_id; -+ } else { -+ sch_cfg.flow_id = config.flow_id + (i / config.pri_max); -+ sch_cfg.pri = i % config.pri_max; -+ sch_cfg.drr_node_id = config.drr_node_id + i; -+ } -+ -+ /* Scheduler weight, must be more than 0. */ -+ sch_cfg.drr_node_wt = 1; -+ /* Byte based to be scheduled. */ -+ sch_cfg.unit_is_packet = false; -+ /* Frame + CRC calculated. */ -+ sch_cfg.frame_mode = PPE_SCH_WITH_FRAME_CRC; -+ -+ ret = ppe_queue_scheduler_set(ppe_dev, config.node_id + i, -+ config.flow_level, -+ config.port, -+ sch_cfg); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+/* Initialize scheduler settings for PPE buffer utilization and dispatching -+ * packet on PPE queue. -+ */ -+static int ppe_config_scheduler(struct ppe_device *ppe_dev) -+{ -+ const struct ppe_scheduler_port_config *port_cfg; -+ const struct ppe_scheduler_qm_config *qm_cfg; -+ const struct ppe_scheduler_bm_config *bm_cfg; -+ int ret, i, count; -+ u32 val, reg; -+ -+ count = ARRAY_SIZE(ipq9574_ppe_sch_bm_config); -+ bm_cfg = ipq9574_ppe_sch_bm_config; -+ -+ /* Configure the depth of BM scheduler entries. */ -+ val = FIELD_PREP(PPE_BM_SCH_CTRL_SCH_DEPTH, count); -+ val |= FIELD_PREP(PPE_BM_SCH_CTRL_SCH_OFFSET, 0); -+ val |= FIELD_PREP(PPE_BM_SCH_CTRL_SCH_EN, 1); -+ -+ ret = regmap_write(ppe_dev->regmap, PPE_BM_SCH_CTRL_ADDR, val); -+ if (ret) -+ goto sch_config_fail; -+ -+ /* Configure each BM scheduler entry with the valid ingress port and -+ * egress port, the second port takes effect when the specified port -+ * is in the inactive state. -+ */ -+ for (i = 0; i < count; i++) { -+ val = FIELD_PREP(PPE_BM_SCH_CFG_TBL_VALID, bm_cfg[i].valid); -+ val |= FIELD_PREP(PPE_BM_SCH_CFG_TBL_DIR, bm_cfg[i].is_egress); -+ val |= FIELD_PREP(PPE_BM_SCH_CFG_TBL_PORT_NUM, bm_cfg[i].port); -+ val |= FIELD_PREP(PPE_BM_SCH_CFG_TBL_SECOND_PORT_VALID, bm_cfg[i].second_valid); -+ val |= FIELD_PREP(PPE_BM_SCH_CFG_TBL_SECOND_PORT, bm_cfg[i].second_port); -+ -+ reg = PPE_BM_SCH_CFG_TBL_ADDR + i * PPE_BM_SCH_CFG_TBL_INC; -+ ret = regmap_write(ppe_dev->regmap, reg, val); -+ if (ret) -+ goto sch_config_fail; -+ } -+ -+ count = ARRAY_SIZE(ipq9574_ppe_sch_qm_config); -+ qm_cfg = ipq9574_ppe_sch_qm_config; -+ -+ /* Configure the depth of QM scheduler entries. */ -+ val = FIELD_PREP(PPE_PSCH_SCH_DEPTH_CFG_SCH_DEPTH, count); -+ ret = regmap_write(ppe_dev->regmap, PPE_PSCH_SCH_DEPTH_CFG_ADDR, val); -+ if (ret) -+ goto sch_config_fail; -+ -+ /* Configure each QM scheduler entry with enqueue port and dequeue -+ * port, the second port takes effect when the specified dequeue -+ * port is in the inactive port. -+ */ -+ for (i = 0; i < count; i++) { -+ val = FIELD_PREP(PPE_PSCH_SCH_CFG_TBL_ENS_PORT_BITMAP, -+ qm_cfg[i].ensch_port_bmp); -+ val |= FIELD_PREP(PPE_PSCH_SCH_CFG_TBL_ENS_PORT, -+ qm_cfg[i].ensch_port); -+ val |= FIELD_PREP(PPE_PSCH_SCH_CFG_TBL_DES_PORT, -+ qm_cfg[i].desch_port); -+ val |= FIELD_PREP(PPE_PSCH_SCH_CFG_TBL_DES_SECOND_PORT_EN, -+ qm_cfg[i].desch_second_valid); -+ val |= FIELD_PREP(PPE_PSCH_SCH_CFG_TBL_DES_SECOND_PORT, -+ qm_cfg[i].desch_second_port); -+ -+ reg = PPE_PSCH_SCH_CFG_TBL_ADDR + i * PPE_PSCH_SCH_CFG_TBL_INC; -+ ret = regmap_write(ppe_dev->regmap, reg, val); -+ if (ret) -+ goto sch_config_fail; -+ } -+ -+ count = ARRAY_SIZE(ppe_port_sch_config); -+ port_cfg = ppe_port_sch_config; -+ -+ /* Configure scheduler per PPE queue or flow. */ -+ for (i = 0; i < count; i++) { -+ if (port_cfg[i].port >= ppe_dev->num_ports) -+ break; -+ -+ ret = ppe_node_scheduler_config(ppe_dev, port_cfg[i]); -+ if (ret) -+ goto sch_config_fail; -+ } -+ -+ return 0; -+ -+sch_config_fail: -+ dev_err(ppe_dev->dev, "PPE scheduler arbitration config error %d\n", ret); -+ return ret; -+}; -+ - int ppe_hw_config(struct ppe_device *ppe_dev) - { - int ret; -@@ -366,5 +1148,9 @@ int ppe_hw_config(struct ppe_device *ppe - if (ret) - return ret; - -- return ppe_config_qm(ppe_dev); -+ ret = ppe_config_qm(ppe_dev); -+ if (ret) -+ return ret; -+ -+ return ppe_config_scheduler(ppe_dev); - } ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h -@@ -8,5 +8,42 @@ - - #include "ppe.h" - -+/** -+ * enum ppe_scheduler_frame_mode - PPE scheduler frame mode. -+ * @PPE_SCH_WITH_IPG_PREAMBLE_FRAME_CRC: The scheduled frame includes IPG, -+ * preamble, Ethernet packet and CRC. -+ * @PPE_SCH_WITH_FRAME_CRC: The scheduled frame includes Ethernet frame and CRC -+ * excluding IPG and preamble. -+ * @PPE_SCH_WITH_L3_PAYLOAD: The scheduled frame includes layer 3 packet data. -+ */ -+enum ppe_scheduler_frame_mode { -+ PPE_SCH_WITH_IPG_PREAMBLE_FRAME_CRC = 0, -+ PPE_SCH_WITH_FRAME_CRC = 1, -+ PPE_SCH_WITH_L3_PAYLOAD = 2, -+}; -+ -+/** -+ * struct ppe_scheduler_cfg - PPE scheduler configuration. -+ * @flow_id: PPE flow ID. -+ * @pri: Scheduler priority. -+ * @drr_node_id: Node ID for scheduled traffic. -+ * @drr_node_wt: Weight for scheduled traffic. -+ * @unit_is_packet: Packet based or byte based unit for scheduled traffic. -+ * @frame_mode: Packet mode to be scheduled. -+ * -+ * PPE scheduler supports commit rate and exceed rate configurations. -+ */ -+struct ppe_scheduler_cfg { -+ int flow_id; -+ int pri; -+ int drr_node_id; -+ int drr_node_wt; -+ bool unit_is_packet; -+ enum ppe_scheduler_frame_mode frame_mode; -+}; -+ - int ppe_hw_config(struct ppe_device *ppe_dev); -+int ppe_queue_scheduler_set(struct ppe_device *ppe_dev, -+ int node_id, bool flow_level, int port, -+ struct ppe_scheduler_cfg scheduler_cfg); - #endif ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h -@@ -9,16 +9,113 @@ - - #include - -+/* PPE scheduler configurations for buffer manager block. */ -+#define PPE_BM_SCH_CTRL_ADDR 0xb000 -+#define PPE_BM_SCH_CTRL_INC 4 -+#define PPE_BM_SCH_CTRL_SCH_DEPTH GENMASK(7, 0) -+#define PPE_BM_SCH_CTRL_SCH_OFFSET GENMASK(14, 8) -+#define PPE_BM_SCH_CTRL_SCH_EN BIT(31) -+ -+#define PPE_BM_SCH_CFG_TBL_ADDR 0xc000 -+#define PPE_BM_SCH_CFG_TBL_ENTRIES 128 -+#define PPE_BM_SCH_CFG_TBL_INC 0x10 -+#define PPE_BM_SCH_CFG_TBL_PORT_NUM GENMASK(3, 0) -+#define PPE_BM_SCH_CFG_TBL_DIR BIT(4) -+#define PPE_BM_SCH_CFG_TBL_VALID BIT(5) -+#define PPE_BM_SCH_CFG_TBL_SECOND_PORT_VALID BIT(6) -+#define PPE_BM_SCH_CFG_TBL_SECOND_PORT GENMASK(11, 8) -+ - /* PPE queue counters enable/disable control. */ - #define PPE_EG_BRIDGE_CONFIG_ADDR 0x20044 - #define PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN BIT(2) - -+/* Port scheduler global config. */ -+#define PPE_PSCH_SCH_DEPTH_CFG_ADDR 0x400000 -+#define PPE_PSCH_SCH_DEPTH_CFG_INC 4 -+#define PPE_PSCH_SCH_DEPTH_CFG_SCH_DEPTH GENMASK(7, 0) -+ -+/* PPE queue level scheduler configurations. */ -+#define PPE_L0_FLOW_MAP_TBL_ADDR 0x402000 -+#define PPE_L0_FLOW_MAP_TBL_ENTRIES 300 -+#define PPE_L0_FLOW_MAP_TBL_INC 0x10 -+#define PPE_L0_FLOW_MAP_TBL_FLOW_ID GENMASK(5, 0) -+#define PPE_L0_FLOW_MAP_TBL_C_PRI GENMASK(8, 6) -+#define PPE_L0_FLOW_MAP_TBL_E_PRI GENMASK(11, 9) -+#define PPE_L0_FLOW_MAP_TBL_C_NODE_WT GENMASK(21, 12) -+#define PPE_L0_FLOW_MAP_TBL_E_NODE_WT GENMASK(31, 22) -+ -+#define PPE_L0_C_FLOW_CFG_TBL_ADDR 0x404000 -+#define PPE_L0_C_FLOW_CFG_TBL_ENTRIES 512 -+#define PPE_L0_C_FLOW_CFG_TBL_INC 0x10 -+#define PPE_L0_C_FLOW_CFG_TBL_NODE_ID GENMASK(7, 0) -+#define PPE_L0_C_FLOW_CFG_TBL_NODE_CREDIT_UNIT BIT(8) -+ -+#define PPE_L0_E_FLOW_CFG_TBL_ADDR 0x406000 -+#define PPE_L0_E_FLOW_CFG_TBL_ENTRIES 512 -+#define PPE_L0_E_FLOW_CFG_TBL_INC 0x10 -+#define PPE_L0_E_FLOW_CFG_TBL_NODE_ID GENMASK(7, 0) -+#define PPE_L0_E_FLOW_CFG_TBL_NODE_CREDIT_UNIT BIT(8) -+ -+#define PPE_L0_FLOW_PORT_MAP_TBL_ADDR 0x408000 -+#define PPE_L0_FLOW_PORT_MAP_TBL_ENTRIES 300 -+#define PPE_L0_FLOW_PORT_MAP_TBL_INC 0x10 -+#define PPE_L0_FLOW_PORT_MAP_TBL_PORT_NUM GENMASK(3, 0) -+ -+#define PPE_L0_COMP_CFG_TBL_ADDR 0x428000 -+#define PPE_L0_COMP_CFG_TBL_ENTRIES 300 -+#define PPE_L0_COMP_CFG_TBL_INC 0x10 -+#define PPE_L0_COMP_CFG_TBL_SHAPER_METER_LEN GENMASK(1, 0) -+#define PPE_L0_COMP_CFG_TBL_NODE_METER_LEN GENMASK(3, 2) -+ - /* Table addresses for per-queue dequeue setting. */ - #define PPE_DEQ_OPR_TBL_ADDR 0x430000 - #define PPE_DEQ_OPR_TBL_ENTRIES 300 - #define PPE_DEQ_OPR_TBL_INC 0x10 - #define PPE_DEQ_OPR_TBL_DEQ_DISABLE BIT(0) - -+/* PPE flow level scheduler configurations. */ -+#define PPE_L1_FLOW_MAP_TBL_ADDR 0x440000 -+#define PPE_L1_FLOW_MAP_TBL_ENTRIES 64 -+#define PPE_L1_FLOW_MAP_TBL_INC 0x10 -+#define PPE_L1_FLOW_MAP_TBL_FLOW_ID GENMASK(3, 0) -+#define PPE_L1_FLOW_MAP_TBL_C_PRI GENMASK(6, 4) -+#define PPE_L1_FLOW_MAP_TBL_E_PRI GENMASK(9, 7) -+#define PPE_L1_FLOW_MAP_TBL_C_NODE_WT GENMASK(19, 10) -+#define PPE_L1_FLOW_MAP_TBL_E_NODE_WT GENMASK(29, 20) -+ -+#define PPE_L1_C_FLOW_CFG_TBL_ADDR 0x442000 -+#define PPE_L1_C_FLOW_CFG_TBL_ENTRIES 64 -+#define PPE_L1_C_FLOW_CFG_TBL_INC 0x10 -+#define PPE_L1_C_FLOW_CFG_TBL_NODE_ID GENMASK(5, 0) -+#define PPE_L1_C_FLOW_CFG_TBL_NODE_CREDIT_UNIT BIT(6) -+ -+#define PPE_L1_E_FLOW_CFG_TBL_ADDR 0x444000 -+#define PPE_L1_E_FLOW_CFG_TBL_ENTRIES 64 -+#define PPE_L1_E_FLOW_CFG_TBL_INC 0x10 -+#define PPE_L1_E_FLOW_CFG_TBL_NODE_ID GENMASK(5, 0) -+#define PPE_L1_E_FLOW_CFG_TBL_NODE_CREDIT_UNIT BIT(6) -+ -+#define PPE_L1_FLOW_PORT_MAP_TBL_ADDR 0x446000 -+#define PPE_L1_FLOW_PORT_MAP_TBL_ENTRIES 64 -+#define PPE_L1_FLOW_PORT_MAP_TBL_INC 0x10 -+#define PPE_L1_FLOW_PORT_MAP_TBL_PORT_NUM GENMASK(3, 0) -+ -+#define PPE_L1_COMP_CFG_TBL_ADDR 0x46a000 -+#define PPE_L1_COMP_CFG_TBL_ENTRIES 64 -+#define PPE_L1_COMP_CFG_TBL_INC 0x10 -+#define PPE_L1_COMP_CFG_TBL_SHAPER_METER_LEN GENMASK(1, 0) -+#define PPE_L1_COMP_CFG_TBL_NODE_METER_LEN GENMASK(3, 2) -+ -+/* PPE port scheduler configurations for egress. */ -+#define PPE_PSCH_SCH_CFG_TBL_ADDR 0x47a000 -+#define PPE_PSCH_SCH_CFG_TBL_ENTRIES 128 -+#define PPE_PSCH_SCH_CFG_TBL_INC 0x10 -+#define PPE_PSCH_SCH_CFG_TBL_DES_PORT GENMASK(3, 0) -+#define PPE_PSCH_SCH_CFG_TBL_ENS_PORT GENMASK(7, 4) -+#define PPE_PSCH_SCH_CFG_TBL_ENS_PORT_BITMAP GENMASK(15, 8) -+#define PPE_PSCH_SCH_CFG_TBL_DES_SECOND_PORT_EN BIT(16) -+#define PPE_PSCH_SCH_CFG_TBL_DES_SECOND_PORT GENMASK(20, 17) -+ - /* There are 15 BM ports and 4 BM groups supported by PPE. - * BM port (0-7) is for EDMA port 0, BM port (8-13) is for - * PPE physical port 1-6 and BM port 14 is for EIP port. diff --git a/target/linux/qualcommbe/patches-6.18/0329-net-ethernet-qualcomm-Initialize-PPE-queue-settings.patch b/target/linux/qualcommbe/patches-6.18/0329-net-ethernet-qualcomm-Initialize-PPE-queue-settings.patch deleted file mode 100644 index fe29d76e36..0000000000 --- a/target/linux/qualcommbe/patches-6.18/0329-net-ethernet-qualcomm-Initialize-PPE-queue-settings.patch +++ /dev/null @@ -1,522 +0,0 @@ -From 63874f7c2e46f192e43e6214d66236372e36396c Mon Sep 17 00:00:00 2001 -From: Luo Jie -Date: Sun, 9 Feb 2025 22:29:41 +0800 -Subject: [PATCH] net: ethernet: qualcomm: Initialize PPE queue settings - -Configure unicast and multicast hardware queues for the PPE -ports to enable packet forwarding between the ports. - -Each PPE port is assigned with a range of queues. The queue ID -selection for a packet is decided by the queue base and queue -offset that is configured based on the internal priority and -the RSS hash value of the packet. - -Signed-off-by: Luo Jie ---- - .../net/ethernet/qualcomm/ppe/ppe_config.c | 356 +++++++++++++++++- - .../net/ethernet/qualcomm/ppe/ppe_config.h | 63 ++++ - drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 21 ++ - 3 files changed, 439 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c -@@ -128,6 +128,34 @@ struct ppe_scheduler_port_config { - unsigned int drr_node_id; - }; - -+/** -+ * struct ppe_port_schedule_resource - PPE port scheduler resource. -+ * @ucastq_start: Unicast queue start ID. -+ * @ucastq_end: Unicast queue end ID. -+ * @mcastq_start: Multicast queue start ID. -+ * @mcastq_end: Multicast queue end ID. -+ * @flow_id_start: Flow start ID. -+ * @flow_id_end: Flow end ID. -+ * @l0node_start: Scheduler node start ID for queue level. -+ * @l0node_end: Scheduler node end ID for queue level. -+ * @l1node_start: Scheduler node start ID for flow level. -+ * @l1node_end: Scheduler node end ID for flow level. -+ * -+ * PPE scheduler resource allocated among the PPE ports. -+ */ -+struct ppe_port_schedule_resource { -+ unsigned int ucastq_start; -+ unsigned int ucastq_end; -+ unsigned int mcastq_start; -+ unsigned int mcastq_end; -+ unsigned int flow_id_start; -+ unsigned int flow_id_end; -+ unsigned int l0node_start; -+ unsigned int l0node_end; -+ unsigned int l1node_start; -+ unsigned int l1node_end; -+}; -+ - /* Assign the share buffer number 1550 to group 0 by default. */ - static const int ipq9574_ppe_bm_group_config = 1550; - -@@ -676,6 +704,111 @@ static const struct ppe_scheduler_port_c - }, - }; - -+/* The scheduler resource is applied to each PPE port, The resource -+ * includes the unicast & multicast queues, flow nodes and DRR nodes. -+ */ -+static const struct ppe_port_schedule_resource ppe_scheduler_res[] = { -+ { .ucastq_start = 0, -+ .ucastq_end = 63, -+ .mcastq_start = 256, -+ .mcastq_end = 271, -+ .flow_id_start = 0, -+ .flow_id_end = 0, -+ .l0node_start = 0, -+ .l0node_end = 7, -+ .l1node_start = 0, -+ .l1node_end = 0, -+ }, -+ { .ucastq_start = 144, -+ .ucastq_end = 159, -+ .mcastq_start = 272, -+ .mcastq_end = 275, -+ .flow_id_start = 36, -+ .flow_id_end = 39, -+ .l0node_start = 48, -+ .l0node_end = 63, -+ .l1node_start = 8, -+ .l1node_end = 11, -+ }, -+ { .ucastq_start = 160, -+ .ucastq_end = 175, -+ .mcastq_start = 276, -+ .mcastq_end = 279, -+ .flow_id_start = 40, -+ .flow_id_end = 43, -+ .l0node_start = 64, -+ .l0node_end = 79, -+ .l1node_start = 12, -+ .l1node_end = 15, -+ }, -+ { .ucastq_start = 176, -+ .ucastq_end = 191, -+ .mcastq_start = 280, -+ .mcastq_end = 283, -+ .flow_id_start = 44, -+ .flow_id_end = 47, -+ .l0node_start = 80, -+ .l0node_end = 95, -+ .l1node_start = 16, -+ .l1node_end = 19, -+ }, -+ { .ucastq_start = 192, -+ .ucastq_end = 207, -+ .mcastq_start = 284, -+ .mcastq_end = 287, -+ .flow_id_start = 48, -+ .flow_id_end = 51, -+ .l0node_start = 96, -+ .l0node_end = 111, -+ .l1node_start = 20, -+ .l1node_end = 23, -+ }, -+ { .ucastq_start = 208, -+ .ucastq_end = 223, -+ .mcastq_start = 288, -+ .mcastq_end = 291, -+ .flow_id_start = 52, -+ .flow_id_end = 55, -+ .l0node_start = 112, -+ .l0node_end = 127, -+ .l1node_start = 24, -+ .l1node_end = 27, -+ }, -+ { .ucastq_start = 224, -+ .ucastq_end = 239, -+ .mcastq_start = 292, -+ .mcastq_end = 295, -+ .flow_id_start = 56, -+ .flow_id_end = 59, -+ .l0node_start = 128, -+ .l0node_end = 143, -+ .l1node_start = 28, -+ .l1node_end = 31, -+ }, -+ { .ucastq_start = 240, -+ .ucastq_end = 255, -+ .mcastq_start = 296, -+ .mcastq_end = 299, -+ .flow_id_start = 60, -+ .flow_id_end = 63, -+ .l0node_start = 144, -+ .l0node_end = 159, -+ .l1node_start = 32, -+ .l1node_end = 35, -+ }, -+ { .ucastq_start = 64, -+ .ucastq_end = 143, -+ .mcastq_start = 0, -+ .mcastq_end = 0, -+ .flow_id_start = 1, -+ .flow_id_end = 35, -+ .l0node_start = 8, -+ .l0node_end = 47, -+ .l1node_start = 1, -+ .l1node_end = 7, -+ }, -+}; -+ - /* Set the PPE queue level scheduler configuration. */ - static int ppe_scheduler_l0_queue_map_set(struct ppe_device *ppe_dev, - int node_id, int port, -@@ -807,6 +940,149 @@ int ppe_queue_scheduler_set(struct ppe_d - port, scheduler_cfg); - } - -+/** -+ * ppe_queue_ucast_base_set - Set PPE unicast queue base ID and profile ID -+ * @ppe_dev: PPE device -+ * @queue_dst: PPE queue destination configuration -+ * @queue_base: PPE queue base ID -+ * @profile_id: Profile ID -+ * -+ * The PPE unicast queue base ID and profile ID are configured based on the -+ * destination port information that can be service code or CPU code or the -+ * destination port. -+ * -+ * Return: 0 on success, negative error code on failure. -+ */ -+int ppe_queue_ucast_base_set(struct ppe_device *ppe_dev, -+ struct ppe_queue_ucast_dest queue_dst, -+ int queue_base, int profile_id) -+{ -+ int index, profile_size; -+ u32 val, reg; -+ -+ profile_size = queue_dst.src_profile << 8; -+ if (queue_dst.service_code_en) -+ index = PPE_QUEUE_BASE_SERVICE_CODE + profile_size + -+ queue_dst.service_code; -+ else if (queue_dst.cpu_code_en) -+ index = PPE_QUEUE_BASE_CPU_CODE + profile_size + -+ queue_dst.cpu_code; -+ else -+ index = profile_size + queue_dst.dest_port; -+ -+ val = FIELD_PREP(PPE_UCAST_QUEUE_MAP_TBL_PROFILE_ID, profile_id); -+ val |= FIELD_PREP(PPE_UCAST_QUEUE_MAP_TBL_QUEUE_ID, queue_base); -+ reg = PPE_UCAST_QUEUE_MAP_TBL_ADDR + index * PPE_UCAST_QUEUE_MAP_TBL_INC; -+ -+ return regmap_write(ppe_dev->regmap, reg, val); -+} -+ -+/** -+ * ppe_queue_ucast_offset_pri_set - Set PPE unicast queue offset based on priority -+ * @ppe_dev: PPE device -+ * @profile_id: Profile ID -+ * @priority: PPE internal priority to be used to set queue offset -+ * @queue_offset: Queue offset used for calculating the destination queue ID -+ * -+ * The PPE unicast queue offset is configured based on the PPE -+ * internal priority. -+ * -+ * Return: 0 on success, negative error code on failure. -+ */ -+int ppe_queue_ucast_offset_pri_set(struct ppe_device *ppe_dev, -+ int profile_id, -+ int priority, -+ int queue_offset) -+{ -+ u32 val, reg; -+ int index; -+ -+ index = (profile_id << 4) + priority; -+ val = FIELD_PREP(PPE_UCAST_PRIORITY_MAP_TBL_CLASS, queue_offset); -+ reg = PPE_UCAST_PRIORITY_MAP_TBL_ADDR + index * PPE_UCAST_PRIORITY_MAP_TBL_INC; -+ -+ return regmap_write(ppe_dev->regmap, reg, val); -+} -+ -+/** -+ * ppe_queue_ucast_offset_hash_set - Set PPE unicast queue offset based on hash -+ * @ppe_dev: PPE device -+ * @profile_id: Profile ID -+ * @rss_hash: Packet hash value to be used to set queue offset -+ * @queue_offset: Queue offset used for calculating the destination queue ID -+ * -+ * The PPE unicast queue offset is configured based on the RSS hash value. -+ * -+ * Return: 0 on success, negative error code on failure. -+ */ -+int ppe_queue_ucast_offset_hash_set(struct ppe_device *ppe_dev, -+ int profile_id, -+ int rss_hash, -+ int queue_offset) -+{ -+ u32 val, reg; -+ int index; -+ -+ index = (profile_id << 8) + rss_hash; -+ val = FIELD_PREP(PPE_UCAST_HASH_MAP_TBL_HASH, queue_offset); -+ reg = PPE_UCAST_HASH_MAP_TBL_ADDR + index * PPE_UCAST_HASH_MAP_TBL_INC; -+ -+ return regmap_write(ppe_dev->regmap, reg, val); -+} -+ -+/** -+ * ppe_port_resource_get - Get PPE resource per port -+ * @ppe_dev: PPE device -+ * @port: PPE port -+ * @type: Resource type -+ * @res_start: Resource start ID returned -+ * @res_end: Resource end ID returned -+ * -+ * PPE resource is assigned per PPE port, which is acquired for QoS scheduler. -+ * -+ * Return: 0 on success, negative error code on failure. -+ */ -+int ppe_port_resource_get(struct ppe_device *ppe_dev, int port, -+ enum ppe_resource_type type, -+ int *res_start, int *res_end) -+{ -+ struct ppe_port_schedule_resource res; -+ -+ /* The reserved resource with the maximum port ID of PPE is -+ * also allowed to be acquired. -+ */ -+ if (port > ppe_dev->num_ports) -+ return -EINVAL; -+ -+ res = ppe_scheduler_res[port]; -+ switch (type) { -+ case PPE_RES_UCAST: -+ *res_start = res.ucastq_start; -+ *res_end = res.ucastq_end; -+ break; -+ case PPE_RES_MCAST: -+ *res_start = res.mcastq_start; -+ *res_end = res.mcastq_end; -+ break; -+ case PPE_RES_FLOW_ID: -+ *res_start = res.flow_id_start; -+ *res_end = res.flow_id_end; -+ break; -+ case PPE_RES_L0_NODE: -+ *res_start = res.l0node_start; -+ *res_end = res.l0node_end; -+ break; -+ case PPE_RES_L1_NODE: -+ *res_start = res.l1node_start; -+ *res_end = res.l1node_end; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ - static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id, - const struct ppe_bm_port_config port_cfg) - { -@@ -1140,6 +1416,80 @@ sch_config_fail: - return ret; - }; - -+/* Configure PPE queue destination of each PPE port. */ -+static int ppe_queue_dest_init(struct ppe_device *ppe_dev) -+{ -+ int ret, port_id, index, q_base, q_offset, res_start, res_end, pri_max; -+ struct ppe_queue_ucast_dest queue_dst; -+ -+ for (port_id = 0; port_id < ppe_dev->num_ports; port_id++) { -+ memset(&queue_dst, 0, sizeof(queue_dst)); -+ -+ ret = ppe_port_resource_get(ppe_dev, port_id, PPE_RES_UCAST, -+ &res_start, &res_end); -+ if (ret) -+ return ret; -+ -+ q_base = res_start; -+ queue_dst.dest_port = port_id; -+ -+ /* Configure queue base ID and profile ID that is same as -+ * physical port ID. -+ */ -+ ret = ppe_queue_ucast_base_set(ppe_dev, queue_dst, -+ q_base, port_id); -+ if (ret) -+ return ret; -+ -+ /* Queue priority range supported by each PPE port */ -+ ret = ppe_port_resource_get(ppe_dev, port_id, PPE_RES_L0_NODE, -+ &res_start, &res_end); -+ if (ret) -+ return ret; -+ -+ pri_max = res_end - res_start; -+ -+ /* Redirect ARP reply packet with the max priority on CPU port, -+ * which keeps the ARP reply directed to CPU (CPU code is 101) -+ * with highest priority queue of EDMA. -+ */ -+ if (port_id == 0) { -+ memset(&queue_dst, 0, sizeof(queue_dst)); -+ -+ queue_dst.cpu_code_en = true; -+ queue_dst.cpu_code = 101; -+ ret = ppe_queue_ucast_base_set(ppe_dev, queue_dst, -+ q_base + pri_max, -+ 0); -+ if (ret) -+ return ret; -+ } -+ -+ /* Initialize the queue offset of internal priority. */ -+ for (index = 0; index < PPE_QUEUE_INTER_PRI_NUM; index++) { -+ q_offset = index > pri_max ? pri_max : index; -+ -+ ret = ppe_queue_ucast_offset_pri_set(ppe_dev, port_id, -+ index, q_offset); -+ if (ret) -+ return ret; -+ } -+ -+ /* Initialize the queue offset of RSS hash as 0 to avoid the -+ * random hardware value that will lead to the unexpected -+ * destination queue generated. -+ */ -+ for (index = 0; index < PPE_QUEUE_HASH_NUM; index++) { -+ ret = ppe_queue_ucast_offset_hash_set(ppe_dev, port_id, -+ index, 0); -+ if (ret) -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ - int ppe_hw_config(struct ppe_device *ppe_dev) - { - int ret; -@@ -1152,5 +1502,9 @@ int ppe_hw_config(struct ppe_device *ppe - if (ret) - return ret; - -- return ppe_config_scheduler(ppe_dev); -+ ret = ppe_config_scheduler(ppe_dev); -+ if (ret) -+ return ret; -+ -+ return ppe_queue_dest_init(ppe_dev); - } ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h -@@ -8,6 +8,16 @@ - - #include "ppe.h" - -+/* There are different table index ranges for configuring queue base ID of -+ * the destination port, CPU code and service code. -+ */ -+#define PPE_QUEUE_BASE_DEST_PORT 0 -+#define PPE_QUEUE_BASE_CPU_CODE 1024 -+#define PPE_QUEUE_BASE_SERVICE_CODE 2048 -+ -+#define PPE_QUEUE_INTER_PRI_NUM 16 -+#define PPE_QUEUE_HASH_NUM 256 -+ - /** - * enum ppe_scheduler_frame_mode - PPE scheduler frame mode. - * @PPE_SCH_WITH_IPG_PREAMBLE_FRAME_CRC: The scheduled frame includes IPG, -@@ -42,8 +52,61 @@ struct ppe_scheduler_cfg { - enum ppe_scheduler_frame_mode frame_mode; - }; - -+/** -+ * enum ppe_resource_type - PPE resource type. -+ * @PPE_RES_UCAST: Unicast queue resource. -+ * @PPE_RES_MCAST: Multicast queue resource. -+ * @PPE_RES_L0_NODE: Level 0 for queue based node resource. -+ * @PPE_RES_L1_NODE: Level 1 for flow based node resource. -+ * @PPE_RES_FLOW_ID: Flow based node resource. -+ */ -+enum ppe_resource_type { -+ PPE_RES_UCAST, -+ PPE_RES_MCAST, -+ PPE_RES_L0_NODE, -+ PPE_RES_L1_NODE, -+ PPE_RES_FLOW_ID, -+}; -+ -+/** -+ * struct ppe_queue_ucast_dest - PPE unicast queue destination. -+ * @src_profile: Source profile. -+ * @service_code_en: Enable service code to map the queue base ID. -+ * @service_code: Service code. -+ * @cpu_code_en: Enable CPU code to map the queue base ID. -+ * @cpu_code: CPU code. -+ * @dest_port: destination port. -+ * -+ * PPE egress queue ID is decided by the service code if enabled, otherwise -+ * by the CPU code if enabled, or by destination port if both service code -+ * and CPU code are disabled. -+ */ -+struct ppe_queue_ucast_dest { -+ int src_profile; -+ bool service_code_en; -+ int service_code; -+ bool cpu_code_en; -+ int cpu_code; -+ int dest_port; -+}; -+ - int ppe_hw_config(struct ppe_device *ppe_dev); - int ppe_queue_scheduler_set(struct ppe_device *ppe_dev, - int node_id, bool flow_level, int port, - struct ppe_scheduler_cfg scheduler_cfg); -+int ppe_queue_ucast_base_set(struct ppe_device *ppe_dev, -+ struct ppe_queue_ucast_dest queue_dst, -+ int queue_base, -+ int profile_id); -+int ppe_queue_ucast_offset_pri_set(struct ppe_device *ppe_dev, -+ int profile_id, -+ int priority, -+ int queue_offset); -+int ppe_queue_ucast_offset_hash_set(struct ppe_device *ppe_dev, -+ int profile_id, -+ int rss_hash, -+ int queue_offset); -+int ppe_port_resource_get(struct ppe_device *ppe_dev, int port, -+ enum ppe_resource_type type, -+ int *res_start, int *res_end); - #endif ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h -@@ -164,6 +164,27 @@ - #define PPE_BM_PORT_FC_SET_PRE_ALLOC(tbl_cfg, value) \ - u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_PRE_ALLOC) - -+/* The queue base configurations based on destination port, -+ * service code or CPU code. -+ */ -+#define PPE_UCAST_QUEUE_MAP_TBL_ADDR 0x810000 -+#define PPE_UCAST_QUEUE_MAP_TBL_ENTRIES 3072 -+#define PPE_UCAST_QUEUE_MAP_TBL_INC 0x10 -+#define PPE_UCAST_QUEUE_MAP_TBL_PROFILE_ID GENMASK(3, 0) -+#define PPE_UCAST_QUEUE_MAP_TBL_QUEUE_ID GENMASK(11, 4) -+ -+/* The queue offset configurations based on RSS hash value. */ -+#define PPE_UCAST_HASH_MAP_TBL_ADDR 0x830000 -+#define PPE_UCAST_HASH_MAP_TBL_ENTRIES 4096 -+#define PPE_UCAST_HASH_MAP_TBL_INC 0x10 -+#define PPE_UCAST_HASH_MAP_TBL_HASH GENMASK(7, 0) -+ -+/* The queue offset configurations based on PPE internal priority. */ -+#define PPE_UCAST_PRIORITY_MAP_TBL_ADDR 0x842000 -+#define PPE_UCAST_PRIORITY_MAP_TBL_ENTRIES 256 -+#define PPE_UCAST_PRIORITY_MAP_TBL_INC 0x10 -+#define PPE_UCAST_PRIORITY_MAP_TBL_CLASS GENMASK(3, 0) -+ - /* PPE unicast queue (0-255) configurations. */ - #define PPE_AC_UNICAST_QUEUE_CFG_TBL_ADDR 0x848000 - #define PPE_AC_UNICAST_QUEUE_CFG_TBL_ENTRIES 256 diff --git a/target/linux/qualcommbe/patches-6.18/0330-net-ethernet-qualcomm-Initialize-PPE-service-code-se.patch b/target/linux/qualcommbe/patches-6.18/0330-net-ethernet-qualcomm-Initialize-PPE-service-code-se.patch deleted file mode 100644 index 176b7d6bb4..0000000000 --- a/target/linux/qualcommbe/patches-6.18/0330-net-ethernet-qualcomm-Initialize-PPE-service-code-se.patch +++ /dev/null @@ -1,384 +0,0 @@ -From 4147ce0d95816bded5c5e6cb276b1aa9f2620045 Mon Sep 17 00:00:00 2001 -From: Luo Jie -Date: Sun, 9 Feb 2025 22:29:42 +0800 -Subject: [PATCH] net: ethernet: qualcomm: Initialize PPE service code settings - -PPE service code is a special code (0-255) that is defined by PPE for -PPE's packet processing stages, as per the network functions required -for the packet. - -For packet being sent out by ARM cores on Ethernet ports, The service -code 1 is used as the default service code. This service code is used -to bypass most of packet processing stages of the PPE before the packet -transmitted out PPE port, since the software network stack has already -processed the packet. - -Signed-off-by: Luo Jie ---- - .../net/ethernet/qualcomm/ppe/ppe_config.c | 95 +++++++++++- - .../net/ethernet/qualcomm/ppe/ppe_config.h | 145 ++++++++++++++++++ - drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 53 +++++++ - 3 files changed, 292 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c -@@ -8,6 +8,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -1083,6 +1084,75 @@ int ppe_port_resource_get(struct ppe_dev - return 0; - } - -+/** -+ * ppe_sc_config_set - Set PPE service code configuration -+ * @ppe_dev: PPE device -+ * @sc: Service ID, 0-255 supported by PPE -+ * @cfg: Service code configuration -+ * -+ * PPE service code is used by the PPE during its packet processing stages, -+ * to perform or bypass certain selected packet operations on the packet. -+ * -+ * Return: 0 on success, negative error code on failure. -+ */ -+int ppe_sc_config_set(struct ppe_device *ppe_dev, int sc, struct ppe_sc_cfg cfg) -+{ -+ u32 val, reg, servcode_val[2] = {}; -+ unsigned long bitmap_value; -+ int ret; -+ -+ val = FIELD_PREP(PPE_IN_L2_SERVICE_TBL_DST_PORT_ID_VALID, cfg.dest_port_valid); -+ val |= FIELD_PREP(PPE_IN_L2_SERVICE_TBL_DST_PORT_ID, cfg.dest_port); -+ val |= FIELD_PREP(PPE_IN_L2_SERVICE_TBL_DST_DIRECTION, cfg.is_src); -+ -+ bitmap_value = bitmap_read(cfg.bitmaps.egress, 0, PPE_SC_BYPASS_EGRESS_SIZE); -+ val |= FIELD_PREP(PPE_IN_L2_SERVICE_TBL_DST_BYPASS_BITMAP, bitmap_value); -+ val |= FIELD_PREP(PPE_IN_L2_SERVICE_TBL_RX_CNT_EN, -+ test_bit(PPE_SC_BYPASS_COUNTER_RX, cfg.bitmaps.counter)); -+ val |= FIELD_PREP(PPE_IN_L2_SERVICE_TBL_TX_CNT_EN, -+ test_bit(PPE_SC_BYPASS_COUNTER_TX, cfg.bitmaps.counter)); -+ reg = PPE_IN_L2_SERVICE_TBL_ADDR + PPE_IN_L2_SERVICE_TBL_INC * sc; -+ -+ ret = regmap_write(ppe_dev->regmap, reg, val); -+ if (ret) -+ return ret; -+ -+ bitmap_value = bitmap_read(cfg.bitmaps.ingress, 0, PPE_SC_BYPASS_INGRESS_SIZE); -+ PPE_SERVICE_SET_BYPASS_BITMAP(servcode_val, bitmap_value); -+ PPE_SERVICE_SET_RX_CNT_EN(servcode_val, -+ test_bit(PPE_SC_BYPASS_COUNTER_RX_VLAN, cfg.bitmaps.counter)); -+ reg = PPE_SERVICE_TBL_ADDR + PPE_SERVICE_TBL_INC * sc; -+ -+ ret = regmap_bulk_write(ppe_dev->regmap, reg, -+ servcode_val, ARRAY_SIZE(servcode_val)); -+ if (ret) -+ return ret; -+ -+ reg = PPE_EG_SERVICE_TBL_ADDR + PPE_EG_SERVICE_TBL_INC * sc; -+ ret = regmap_bulk_read(ppe_dev->regmap, reg, -+ servcode_val, ARRAY_SIZE(servcode_val)); -+ if (ret) -+ return ret; -+ -+ PPE_EG_SERVICE_SET_NEXT_SERVCODE(servcode_val, cfg.next_service_code); -+ PPE_EG_SERVICE_SET_UPDATE_ACTION(servcode_val, cfg.eip_field_update_bitmap); -+ PPE_EG_SERVICE_SET_HW_SERVICE(servcode_val, cfg.eip_hw_service); -+ PPE_EG_SERVICE_SET_OFFSET_SEL(servcode_val, cfg.eip_offset_sel); -+ PPE_EG_SERVICE_SET_TX_CNT_EN(servcode_val, -+ test_bit(PPE_SC_BYPASS_COUNTER_TX_VLAN, cfg.bitmaps.counter)); -+ -+ ret = regmap_bulk_write(ppe_dev->regmap, reg, -+ servcode_val, ARRAY_SIZE(servcode_val)); -+ if (ret) -+ return ret; -+ -+ bitmap_value = bitmap_read(cfg.bitmaps.tunnel, 0, PPE_SC_BYPASS_TUNNEL_SIZE); -+ val = FIELD_PREP(PPE_TL_SERVICE_TBL_BYPASS_BITMAP, bitmap_value); -+ reg = PPE_TL_SERVICE_TBL_ADDR + PPE_TL_SERVICE_TBL_INC * sc; -+ -+ return regmap_write(ppe_dev->regmap, reg, val); -+} -+ - static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id, - const struct ppe_bm_port_config port_cfg) - { -@@ -1490,6 +1560,25 @@ static int ppe_queue_dest_init(struct pp - return 0; - } - -+/* Initialize the service code 1 used by CPU port. */ -+static int ppe_servcode_init(struct ppe_device *ppe_dev) -+{ -+ struct ppe_sc_cfg sc_cfg = {}; -+ -+ bitmap_zero(sc_cfg.bitmaps.counter, PPE_SC_BYPASS_COUNTER_SIZE); -+ bitmap_zero(sc_cfg.bitmaps.tunnel, PPE_SC_BYPASS_TUNNEL_SIZE); -+ -+ bitmap_fill(sc_cfg.bitmaps.ingress, PPE_SC_BYPASS_INGRESS_SIZE); -+ clear_bit(PPE_SC_BYPASS_INGRESS_FAKE_MAC_HEADER, sc_cfg.bitmaps.ingress); -+ clear_bit(PPE_SC_BYPASS_INGRESS_SERVICE_CODE, sc_cfg.bitmaps.ingress); -+ clear_bit(PPE_SC_BYPASS_INGRESS_FAKE_L2_PROTO, sc_cfg.bitmaps.ingress); -+ -+ bitmap_fill(sc_cfg.bitmaps.egress, PPE_SC_BYPASS_EGRESS_SIZE); -+ clear_bit(PPE_SC_BYPASS_EGRESS_ACL_POST_ROUTING_CHECK, sc_cfg.bitmaps.egress); -+ -+ return ppe_sc_config_set(ppe_dev, PPE_EDMA_SC_BYPASS_ID, sc_cfg); -+} -+ - int ppe_hw_config(struct ppe_device *ppe_dev) - { - int ret; -@@ -1506,5 +1595,9 @@ int ppe_hw_config(struct ppe_device *ppe - if (ret) - return ret; - -- return ppe_queue_dest_init(ppe_dev); -+ ret = ppe_queue_dest_init(ppe_dev); -+ if (ret) -+ return ret; -+ -+ return ppe_servcode_init(ppe_dev); - } ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h -@@ -6,6 +6,8 @@ - #ifndef __PPE_CONFIG_H__ - #define __PPE_CONFIG_H__ - -+#include -+ - #include "ppe.h" - - /* There are different table index ranges for configuring queue base ID of -@@ -18,6 +20,9 @@ - #define PPE_QUEUE_INTER_PRI_NUM 16 - #define PPE_QUEUE_HASH_NUM 256 - -+/* The service code is used by EDMA port to transmit packet to PPE. */ -+#define PPE_EDMA_SC_BYPASS_ID 1 -+ - /** - * enum ppe_scheduler_frame_mode - PPE scheduler frame mode. - * @PPE_SCH_WITH_IPG_PREAMBLE_FRAME_CRC: The scheduled frame includes IPG, -@@ -90,6 +95,144 @@ struct ppe_queue_ucast_dest { - int dest_port; - }; - -+/* Hardware bitmaps for bypassing features of the ingress packet. */ -+enum ppe_sc_ingress_type { -+ PPE_SC_BYPASS_INGRESS_VLAN_TAG_FMT_CHECK = 0, -+ PPE_SC_BYPASS_INGRESS_VLAN_MEMBER_CHECK = 1, -+ PPE_SC_BYPASS_INGRESS_VLAN_TRANSLATE = 2, -+ PPE_SC_BYPASS_INGRESS_MY_MAC_CHECK = 3, -+ PPE_SC_BYPASS_INGRESS_DIP_LOOKUP = 4, -+ PPE_SC_BYPASS_INGRESS_FLOW_LOOKUP = 5, -+ PPE_SC_BYPASS_INGRESS_FLOW_ACTION = 6, -+ PPE_SC_BYPASS_INGRESS_ACL = 7, -+ PPE_SC_BYPASS_INGRESS_FAKE_MAC_HEADER = 8, -+ PPE_SC_BYPASS_INGRESS_SERVICE_CODE = 9, -+ PPE_SC_BYPASS_INGRESS_WRONG_PKT_FMT_L2 = 10, -+ PPE_SC_BYPASS_INGRESS_WRONG_PKT_FMT_L3_IPV4 = 11, -+ PPE_SC_BYPASS_INGRESS_WRONG_PKT_FMT_L3_IPV6 = 12, -+ PPE_SC_BYPASS_INGRESS_WRONG_PKT_FMT_L4 = 13, -+ PPE_SC_BYPASS_INGRESS_FLOW_SERVICE_CODE = 14, -+ PPE_SC_BYPASS_INGRESS_ACL_SERVICE_CODE = 15, -+ PPE_SC_BYPASS_INGRESS_FAKE_L2_PROTO = 16, -+ PPE_SC_BYPASS_INGRESS_PPPOE_TERMINATION = 17, -+ PPE_SC_BYPASS_INGRESS_DEFAULT_VLAN = 18, -+ PPE_SC_BYPASS_INGRESS_DEFAULT_PCP = 19, -+ PPE_SC_BYPASS_INGRESS_VSI_ASSIGN = 20, -+ /* Values 21-23 are not specified by hardware. */ -+ PPE_SC_BYPASS_INGRESS_VLAN_ASSIGN_FAIL = 24, -+ PPE_SC_BYPASS_INGRESS_SOURCE_GUARD = 25, -+ PPE_SC_BYPASS_INGRESS_MRU_MTU_CHECK = 26, -+ PPE_SC_BYPASS_INGRESS_FLOW_SRC_CHECK = 27, -+ PPE_SC_BYPASS_INGRESS_FLOW_QOS = 28, -+ /* This must be last as it determines the size of the BITMAP. */ -+ PPE_SC_BYPASS_INGRESS_SIZE, -+}; -+ -+/* Hardware bitmaps for bypassing features of the egress packet. */ -+enum ppe_sc_egress_type { -+ PPE_SC_BYPASS_EGRESS_VLAN_MEMBER_CHECK = 0, -+ PPE_SC_BYPASS_EGRESS_VLAN_TRANSLATE = 1, -+ PPE_SC_BYPASS_EGRESS_VLAN_TAG_FMT_CTRL = 2, -+ PPE_SC_BYPASS_EGRESS_FDB_LEARN = 3, -+ PPE_SC_BYPASS_EGRESS_FDB_REFRESH = 4, -+ PPE_SC_BYPASS_EGRESS_L2_SOURCE_SECURITY = 5, -+ PPE_SC_BYPASS_EGRESS_MANAGEMENT_FWD = 6, -+ PPE_SC_BYPASS_EGRESS_BRIDGING_FWD = 7, -+ PPE_SC_BYPASS_EGRESS_IN_STP_FLTR = 8, -+ PPE_SC_BYPASS_EGRESS_EG_STP_FLTR = 9, -+ PPE_SC_BYPASS_EGRESS_SOURCE_FLTR = 10, -+ PPE_SC_BYPASS_EGRESS_POLICER = 11, -+ PPE_SC_BYPASS_EGRESS_L2_PKT_EDIT = 12, -+ PPE_SC_BYPASS_EGRESS_L3_PKT_EDIT = 13, -+ PPE_SC_BYPASS_EGRESS_ACL_POST_ROUTING_CHECK = 14, -+ PPE_SC_BYPASS_EGRESS_PORT_ISOLATION = 15, -+ PPE_SC_BYPASS_EGRESS_PRE_ACL_QOS = 16, -+ PPE_SC_BYPASS_EGRESS_POST_ACL_QOS = 17, -+ PPE_SC_BYPASS_EGRESS_DSCP_QOS = 18, -+ PPE_SC_BYPASS_EGRESS_PCP_QOS = 19, -+ PPE_SC_BYPASS_EGRESS_PREHEADER_QOS = 20, -+ PPE_SC_BYPASS_EGRESS_FAKE_MAC_DROP = 21, -+ PPE_SC_BYPASS_EGRESS_TUNL_CONTEXT = 22, -+ PPE_SC_BYPASS_EGRESS_FLOW_POLICER = 23, -+ /* This must be last as it determines the size of the BITMAP. */ -+ PPE_SC_BYPASS_EGRESS_SIZE, -+}; -+ -+/* Hardware bitmaps for bypassing counter of packet. */ -+enum ppe_sc_counter_type { -+ PPE_SC_BYPASS_COUNTER_RX_VLAN = 0, -+ PPE_SC_BYPASS_COUNTER_RX = 1, -+ PPE_SC_BYPASS_COUNTER_TX_VLAN = 2, -+ PPE_SC_BYPASS_COUNTER_TX = 3, -+ /* This must be last as it determines the size of the BITMAP. */ -+ PPE_SC_BYPASS_COUNTER_SIZE, -+}; -+ -+/* Hardware bitmaps for bypassing features of tunnel packet. */ -+enum ppe_sc_tunnel_type { -+ PPE_SC_BYPASS_TUNNEL_SERVICE_CODE = 0, -+ PPE_SC_BYPASS_TUNNEL_TUNNEL_HANDLE = 1, -+ PPE_SC_BYPASS_TUNNEL_L3_IF_CHECK = 2, -+ PPE_SC_BYPASS_TUNNEL_VLAN_CHECK = 3, -+ PPE_SC_BYPASS_TUNNEL_DMAC_CHECK = 4, -+ PPE_SC_BYPASS_TUNNEL_UDP_CSUM_0_CHECK = 5, -+ PPE_SC_BYPASS_TUNNEL_TBL_DE_ACCE_CHECK = 6, -+ PPE_SC_BYPASS_TUNNEL_PPPOE_MC_TERM_CHECK = 7, -+ PPE_SC_BYPASS_TUNNEL_TTL_EXCEED_CHECK = 8, -+ PPE_SC_BYPASS_TUNNEL_MAP_SRC_CHECK = 9, -+ PPE_SC_BYPASS_TUNNEL_MAP_DST_CHECK = 10, -+ PPE_SC_BYPASS_TUNNEL_LPM_DST_LOOKUP = 11, -+ PPE_SC_BYPASS_TUNNEL_LPM_LOOKUP = 12, -+ PPE_SC_BYPASS_TUNNEL_WRONG_PKT_FMT_L2 = 13, -+ PPE_SC_BYPASS_TUNNEL_WRONG_PKT_FMT_L3_IPV4 = 14, -+ PPE_SC_BYPASS_TUNNEL_WRONG_PKT_FMT_L3_IPV6 = 15, -+ PPE_SC_BYPASS_TUNNEL_WRONG_PKT_FMT_L4 = 16, -+ PPE_SC_BYPASS_TUNNEL_WRONG_PKT_FMT_TUNNEL = 17, -+ /* Values 18-19 are not specified by hardware. */ -+ PPE_SC_BYPASS_TUNNEL_PRE_IPO = 20, -+ /* This must be last as it determines the size of the BITMAP. */ -+ PPE_SC_BYPASS_TUNNEL_SIZE, -+}; -+ -+/** -+ * struct ppe_sc_bypass - PPE service bypass bitmaps -+ * @ingress: Bitmap of features that can be bypassed on the ingress packet. -+ * @egress: Bitmap of features that can be bypassed on the egress packet. -+ * @counter: Bitmap of features that can be bypassed on the counter type. -+ * @tunnel: Bitmap of features that can be bypassed on the tunnel packet. -+ */ -+struct ppe_sc_bypass { -+ DECLARE_BITMAP(ingress, PPE_SC_BYPASS_INGRESS_SIZE); -+ DECLARE_BITMAP(egress, PPE_SC_BYPASS_EGRESS_SIZE); -+ DECLARE_BITMAP(counter, PPE_SC_BYPASS_COUNTER_SIZE); -+ DECLARE_BITMAP(tunnel, PPE_SC_BYPASS_TUNNEL_SIZE); -+}; -+ -+/** -+ * struct ppe_sc_cfg - PPE service code configuration. -+ * @dest_port_valid: Generate destination port or not. -+ * @dest_port: Destination port ID. -+ * @bitmaps: Bitmap of bypass features. -+ * @is_src: Destination port acts as source port, packet sent to CPU. -+ * @next_service_code: New service code generated. -+ * @eip_field_update_bitmap: Fields updated as actions taken for EIP. -+ * @eip_hw_service: Selected hardware functions for EIP. -+ * @eip_offset_sel: Packet offset selection, using packet's layer 4 offset -+ * or using packet's layer 3 offset for EIP. -+ * -+ * Service code is generated during the packet passing through PPE. -+ */ -+struct ppe_sc_cfg { -+ bool dest_port_valid; -+ int dest_port; -+ struct ppe_sc_bypass bitmaps; -+ bool is_src; -+ int next_service_code; -+ int eip_field_update_bitmap; -+ int eip_hw_service; -+ int eip_offset_sel; -+}; -+ - int ppe_hw_config(struct ppe_device *ppe_dev); - int ppe_queue_scheduler_set(struct ppe_device *ppe_dev, - int node_id, bool flow_level, int port, -@@ -109,4 +252,6 @@ int ppe_queue_ucast_offset_hash_set(stru - int ppe_port_resource_get(struct ppe_device *ppe_dev, int port, - enum ppe_resource_type type, - int *res_start, int *res_end); -+int ppe_sc_config_set(struct ppe_device *ppe_dev, int sc, -+ struct ppe_sc_cfg cfg); - #endif ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h -@@ -25,10 +25,63 @@ - #define PPE_BM_SCH_CFG_TBL_SECOND_PORT_VALID BIT(6) - #define PPE_BM_SCH_CFG_TBL_SECOND_PORT GENMASK(11, 8) - -+/* PPE service code configuration for the ingress direction functions, -+ * including bypass configuration for relevant PPE switch core functions -+ * such as flow entry lookup bypass. -+ */ -+#define PPE_SERVICE_TBL_ADDR 0x15000 -+#define PPE_SERVICE_TBL_ENTRIES 256 -+#define PPE_SERVICE_TBL_INC 0x10 -+#define PPE_SERVICE_W0_BYPASS_BITMAP GENMASK(31, 0) -+#define PPE_SERVICE_W1_RX_CNT_EN BIT(0) -+ -+#define PPE_SERVICE_SET_BYPASS_BITMAP(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_SERVICE_W0_BYPASS_BITMAP) -+#define PPE_SERVICE_SET_RX_CNT_EN(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_SERVICE_W1_RX_CNT_EN) -+ - /* PPE queue counters enable/disable control. */ - #define PPE_EG_BRIDGE_CONFIG_ADDR 0x20044 - #define PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN BIT(2) - -+/* PPE service code configuration on the egress direction. */ -+#define PPE_EG_SERVICE_TBL_ADDR 0x43000 -+#define PPE_EG_SERVICE_TBL_ENTRIES 256 -+#define PPE_EG_SERVICE_TBL_INC 0x10 -+#define PPE_EG_SERVICE_W0_UPDATE_ACTION GENMASK(31, 0) -+#define PPE_EG_SERVICE_W1_NEXT_SERVCODE GENMASK(7, 0) -+#define PPE_EG_SERVICE_W1_HW_SERVICE GENMASK(13, 8) -+#define PPE_EG_SERVICE_W1_OFFSET_SEL BIT(14) -+#define PPE_EG_SERVICE_W1_TX_CNT_EN BIT(15) -+ -+#define PPE_EG_SERVICE_SET_UPDATE_ACTION(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_EG_SERVICE_W0_UPDATE_ACTION) -+#define PPE_EG_SERVICE_SET_NEXT_SERVCODE(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_EG_SERVICE_W1_NEXT_SERVCODE) -+#define PPE_EG_SERVICE_SET_HW_SERVICE(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_EG_SERVICE_W1_HW_SERVICE) -+#define PPE_EG_SERVICE_SET_OFFSET_SEL(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_EG_SERVICE_W1_OFFSET_SEL) -+#define PPE_EG_SERVICE_SET_TX_CNT_EN(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_EG_SERVICE_W1_TX_CNT_EN) -+ -+/* PPE service code configuration for destination port and counter. */ -+#define PPE_IN_L2_SERVICE_TBL_ADDR 0x66000 -+#define PPE_IN_L2_SERVICE_TBL_ENTRIES 256 -+#define PPE_IN_L2_SERVICE_TBL_INC 0x10 -+#define PPE_IN_L2_SERVICE_TBL_DST_PORT_ID_VALID BIT(0) -+#define PPE_IN_L2_SERVICE_TBL_DST_PORT_ID GENMASK(4, 1) -+#define PPE_IN_L2_SERVICE_TBL_DST_DIRECTION BIT(5) -+#define PPE_IN_L2_SERVICE_TBL_DST_BYPASS_BITMAP GENMASK(29, 6) -+#define PPE_IN_L2_SERVICE_TBL_RX_CNT_EN BIT(30) -+#define PPE_IN_L2_SERVICE_TBL_TX_CNT_EN BIT(31) -+ -+/* PPE service code configuration for the tunnel packet. */ -+#define PPE_TL_SERVICE_TBL_ADDR 0x306000 -+#define PPE_TL_SERVICE_TBL_ENTRIES 256 -+#define PPE_TL_SERVICE_TBL_INC 4 -+#define PPE_TL_SERVICE_TBL_BYPASS_BITMAP GENMASK(31, 0) -+ - /* Port scheduler global config. */ - #define PPE_PSCH_SCH_DEPTH_CFG_ADDR 0x400000 - #define PPE_PSCH_SCH_DEPTH_CFG_INC 4 diff --git a/target/linux/qualcommbe/patches-6.18/0331-net-ethernet-qualcomm-Initialize-PPE-port-control-se.patch b/target/linux/qualcommbe/patches-6.18/0331-net-ethernet-qualcomm-Initialize-PPE-port-control-se.patch deleted file mode 100644 index f1dcb51a87..0000000000 --- a/target/linux/qualcommbe/patches-6.18/0331-net-ethernet-qualcomm-Initialize-PPE-port-control-se.patch +++ /dev/null @@ -1,215 +0,0 @@ -From 63af46200da794acda25cf8083bde0c1576b0859 Mon Sep 17 00:00:00 2001 -From: Luo Jie -Date: Sun, 9 Feb 2025 22:29:43 +0800 -Subject: [PATCH] net: ethernet: qualcomm: Initialize PPE port control settings - -1. Enable port specific counters in PPE. -2. Configure the default action as drop when the packet size - is more than the configured MTU of physical port. - -Signed-off-by: Luo Jie ---- - .../net/ethernet/qualcomm/ppe/ppe_config.c | 86 ++++++++++++++++++- - .../net/ethernet/qualcomm/ppe/ppe_config.h | 15 ++++ - drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 47 ++++++++++ - 3 files changed, 147 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c -@@ -1153,6 +1153,44 @@ int ppe_sc_config_set(struct ppe_device - return regmap_write(ppe_dev->regmap, reg, val); - } - -+/** -+ * ppe_counter_enable_set - Set PPE port counter enabled -+ * @ppe_dev: PPE device -+ * @port: PPE port ID -+ * -+ * Enable PPE counters on the given port for the unicast packet, multicast -+ * packet and VLAN packet received and transmitted by PPE. -+ * -+ * Return: 0 on success, negative error code on failure. -+ */ -+int ppe_counter_enable_set(struct ppe_device *ppe_dev, int port) -+{ -+ u32 reg, mru_mtu_val[3]; -+ int ret; -+ -+ reg = PPE_MRU_MTU_CTRL_TBL_ADDR + PPE_MRU_MTU_CTRL_TBL_INC * port; -+ ret = regmap_bulk_read(ppe_dev->regmap, reg, -+ mru_mtu_val, ARRAY_SIZE(mru_mtu_val)); -+ if (ret) -+ return ret; -+ -+ PPE_MRU_MTU_CTRL_SET_RX_CNT_EN(mru_mtu_val, true); -+ PPE_MRU_MTU_CTRL_SET_TX_CNT_EN(mru_mtu_val, true); -+ ret = regmap_bulk_write(ppe_dev->regmap, reg, -+ mru_mtu_val, ARRAY_SIZE(mru_mtu_val)); -+ if (ret) -+ return ret; -+ -+ reg = PPE_MC_MTU_CTRL_TBL_ADDR + PPE_MC_MTU_CTRL_TBL_INC * port; -+ ret = regmap_set_bits(ppe_dev->regmap, reg, PPE_MC_MTU_CTRL_TBL_TX_CNT_EN); -+ if (ret) -+ return ret; -+ -+ reg = PPE_PORT_EG_VLAN_TBL_ADDR + PPE_PORT_EG_VLAN_TBL_INC * port; -+ -+ return regmap_set_bits(ppe_dev->regmap, reg, PPE_PORT_EG_VLAN_TBL_TX_COUNTING_EN); -+} -+ - static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id, - const struct ppe_bm_port_config port_cfg) - { -@@ -1579,6 +1617,48 @@ static int ppe_servcode_init(struct ppe_ - return ppe_sc_config_set(ppe_dev, PPE_EDMA_SC_BYPASS_ID, sc_cfg); - } - -+/* Initialize PPE port configurations. */ -+static int ppe_port_config_init(struct ppe_device *ppe_dev) -+{ -+ u32 reg, val, mru_mtu_val[3]; -+ int i, ret; -+ -+ /* MTU and MRU settings are not required for CPU port 0. */ -+ for (i = 1; i < ppe_dev->num_ports; i++) { -+ /* Enable Ethernet port counter */ -+ ret = ppe_counter_enable_set(ppe_dev, i); -+ if (ret) -+ return ret; -+ -+ reg = PPE_MRU_MTU_CTRL_TBL_ADDR + PPE_MRU_MTU_CTRL_TBL_INC * i; -+ ret = regmap_bulk_read(ppe_dev->regmap, reg, -+ mru_mtu_val, ARRAY_SIZE(mru_mtu_val)); -+ if (ret) -+ return ret; -+ -+ /* Drop the packet when the packet size is more than -+ * the MTU or MRU of the physical interface. -+ */ -+ PPE_MRU_MTU_CTRL_SET_MRU_CMD(mru_mtu_val, PPE_ACTION_DROP); -+ PPE_MRU_MTU_CTRL_SET_MTU_CMD(mru_mtu_val, PPE_ACTION_DROP); -+ ret = regmap_bulk_write(ppe_dev->regmap, reg, -+ mru_mtu_val, ARRAY_SIZE(mru_mtu_val)); -+ if (ret) -+ return ret; -+ -+ reg = PPE_MC_MTU_CTRL_TBL_ADDR + PPE_MC_MTU_CTRL_TBL_INC * i; -+ val = FIELD_PREP(PPE_MC_MTU_CTRL_TBL_MTU_CMD, PPE_ACTION_DROP); -+ ret = regmap_update_bits(ppe_dev->regmap, reg, -+ PPE_MC_MTU_CTRL_TBL_MTU_CMD, -+ val); -+ if (ret) -+ return ret; -+ } -+ -+ /* Enable CPU port counters. */ -+ return ppe_counter_enable_set(ppe_dev, 0); -+} -+ - int ppe_hw_config(struct ppe_device *ppe_dev) - { - int ret; -@@ -1599,5 +1679,9 @@ int ppe_hw_config(struct ppe_device *ppe - if (ret) - return ret; - -- return ppe_servcode_init(ppe_dev); -+ ret = ppe_servcode_init(ppe_dev); -+ if (ret) -+ return ret; -+ -+ return ppe_port_config_init(ppe_dev); - } ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h -@@ -233,6 +233,20 @@ struct ppe_sc_cfg { - int eip_offset_sel; - }; - -+/** -+ * enum ppe_action_type - PPE action of the received packet. -+ * @PPE_ACTION_FORWARD: Packet forwarded per L2/L3 process. -+ * @PPE_ACTION_DROP: Packet dropped by PPE. -+ * @PPE_ACTION_COPY_TO_CPU: Packet copied to CPU port per multicast queue. -+ * @PPE_ACTION_REDIRECT_TO_CPU: Packet redirected to CPU port per unicast queue. -+ */ -+enum ppe_action_type { -+ PPE_ACTION_FORWARD = 0, -+ PPE_ACTION_DROP = 1, -+ PPE_ACTION_COPY_TO_CPU = 2, -+ PPE_ACTION_REDIRECT_TO_CPU = 3, -+}; -+ - int ppe_hw_config(struct ppe_device *ppe_dev); - int ppe_queue_scheduler_set(struct ppe_device *ppe_dev, - int node_id, bool flow_level, int port, -@@ -254,4 +268,5 @@ int ppe_port_resource_get(struct ppe_dev - int *res_start, int *res_end); - int ppe_sc_config_set(struct ppe_device *ppe_dev, int sc, - struct ppe_sc_cfg cfg); -+int ppe_counter_enable_set(struct ppe_device *ppe_dev, int port); - #endif ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h -@@ -40,6 +40,18 @@ - #define PPE_SERVICE_SET_RX_CNT_EN(tbl_cfg, value) \ - u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_SERVICE_W1_RX_CNT_EN) - -+/* PPE port egress VLAN configurations. */ -+#define PPE_PORT_EG_VLAN_TBL_ADDR 0x20020 -+#define PPE_PORT_EG_VLAN_TBL_ENTRIES 8 -+#define PPE_PORT_EG_VLAN_TBL_INC 4 -+#define PPE_PORT_EG_VLAN_TBL_VLAN_TYPE BIT(0) -+#define PPE_PORT_EG_VLAN_TBL_CTAG_MODE GENMASK(2, 1) -+#define PPE_PORT_EG_VLAN_TBL_STAG_MODE GENMASK(4, 3) -+#define PPE_PORT_EG_VLAN_TBL_VSI_TAG_MODE_EN BIT(5) -+#define PPE_PORT_EG_VLAN_TBL_PCP_PROP_CMD BIT(6) -+#define PPE_PORT_EG_VLAN_TBL_DEI_PROP_CMD BIT(7) -+#define PPE_PORT_EG_VLAN_TBL_TX_COUNTING_EN BIT(8) -+ - /* PPE queue counters enable/disable control. */ - #define PPE_EG_BRIDGE_CONFIG_ADDR 0x20044 - #define PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN BIT(2) -@@ -65,6 +77,41 @@ - #define PPE_EG_SERVICE_SET_TX_CNT_EN(tbl_cfg, value) \ - u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_EG_SERVICE_W1_TX_CNT_EN) - -+/* PPE port control configurations for the traffic to the multicast queues. */ -+#define PPE_MC_MTU_CTRL_TBL_ADDR 0x60a00 -+#define PPE_MC_MTU_CTRL_TBL_ENTRIES 8 -+#define PPE_MC_MTU_CTRL_TBL_INC 4 -+#define PPE_MC_MTU_CTRL_TBL_MTU GENMASK(13, 0) -+#define PPE_MC_MTU_CTRL_TBL_MTU_CMD GENMASK(15, 14) -+#define PPE_MC_MTU_CTRL_TBL_TX_CNT_EN BIT(16) -+ -+/* PPE port control configurations for the traffic to the unicast queues. */ -+#define PPE_MRU_MTU_CTRL_TBL_ADDR 0x65000 -+#define PPE_MRU_MTU_CTRL_TBL_ENTRIES 256 -+#define PPE_MRU_MTU_CTRL_TBL_INC 0x10 -+#define PPE_MRU_MTU_CTRL_W0_MRU GENMASK(13, 0) -+#define PPE_MRU_MTU_CTRL_W0_MRU_CMD GENMASK(15, 14) -+#define PPE_MRU_MTU_CTRL_W0_MTU GENMASK(29, 16) -+#define PPE_MRU_MTU_CTRL_W0_MTU_CMD GENMASK(31, 30) -+#define PPE_MRU_MTU_CTRL_W1_RX_CNT_EN BIT(0) -+#define PPE_MRU_MTU_CTRL_W1_TX_CNT_EN BIT(1) -+#define PPE_MRU_MTU_CTRL_W1_SRC_PROFILE GENMASK(3, 2) -+#define PPE_MRU_MTU_CTRL_W1_INNER_PREC_LOW BIT(31) -+#define PPE_MRU_MTU_CTRL_W2_INNER_PREC_HIGH GENMASK(1, 0) -+ -+#define PPE_MRU_MTU_CTRL_SET_MRU(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_MRU_MTU_CTRL_W0_MRU) -+#define PPE_MRU_MTU_CTRL_SET_MRU_CMD(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_MRU_MTU_CTRL_W0_MRU_CMD) -+#define PPE_MRU_MTU_CTRL_SET_MTU(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_MRU_MTU_CTRL_W0_MTU) -+#define PPE_MRU_MTU_CTRL_SET_MTU_CMD(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_MRU_MTU_CTRL_W0_MTU_CMD) -+#define PPE_MRU_MTU_CTRL_SET_RX_CNT_EN(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_MRU_MTU_CTRL_W1_RX_CNT_EN) -+#define PPE_MRU_MTU_CTRL_SET_TX_CNT_EN(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_MRU_MTU_CTRL_W1_TX_CNT_EN) -+ - /* PPE service code configuration for destination port and counter. */ - #define PPE_IN_L2_SERVICE_TBL_ADDR 0x66000 - #define PPE_IN_L2_SERVICE_TBL_ENTRIES 256 diff --git a/target/linux/qualcommbe/patches-6.18/0332-net-ethernet-qualcomm-Initialize-PPE-RSS-hash-settin.patch b/target/linux/qualcommbe/patches-6.18/0332-net-ethernet-qualcomm-Initialize-PPE-RSS-hash-settin.patch deleted file mode 100644 index fc0764284d..0000000000 --- a/target/linux/qualcommbe/patches-6.18/0332-net-ethernet-qualcomm-Initialize-PPE-RSS-hash-settin.patch +++ /dev/null @@ -1,344 +0,0 @@ -From 796be78fffeebe77237a6464da7ebe9807d670f0 Mon Sep 17 00:00:00 2001 -From: Luo Jie -Date: Sun, 9 Feb 2025 22:29:44 +0800 -Subject: [PATCH] net: ethernet: qualcomm: Initialize PPE RSS hash settings - -PPE RSS hash is generated during PPE receive, based on the packet -content (3 tuples or 5 tuples) and as per the configured RSS seed. -The hash is then used to select the queue to transmit the packet -to the ARM CPU. - -This patch initializes the RSS hash settings that are used to -generate the hash for the packet during PPE packet receive. - -Signed-off-by: Luo Jie ---- - .../net/ethernet/qualcomm/ppe/ppe_config.c | 194 +++++++++++++++++- - .../net/ethernet/qualcomm/ppe/ppe_config.h | 39 ++++ - drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 40 ++++ - 3 files changed, 272 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c -@@ -1191,6 +1191,143 @@ int ppe_counter_enable_set(struct ppe_de - return regmap_set_bits(ppe_dev->regmap, reg, PPE_PORT_EG_VLAN_TBL_TX_COUNTING_EN); - } - -+static int ppe_rss_hash_ipv4_config(struct ppe_device *ppe_dev, int index, -+ struct ppe_rss_hash_cfg cfg) -+{ -+ u32 reg, val; -+ -+ switch (index) { -+ case 0: -+ val = FIELD_PREP(PPE_RSS_HASH_MIX_IPV4_VAL, cfg.hash_sip_mix[0]); -+ break; -+ case 1: -+ val = FIELD_PREP(PPE_RSS_HASH_MIX_IPV4_VAL, cfg.hash_dip_mix[0]); -+ break; -+ case 2: -+ val = FIELD_PREP(PPE_RSS_HASH_MIX_IPV4_VAL, cfg.hash_protocol_mix); -+ break; -+ case 3: -+ val = FIELD_PREP(PPE_RSS_HASH_MIX_IPV4_VAL, cfg.hash_dport_mix); -+ break; -+ case 4: -+ val = FIELD_PREP(PPE_RSS_HASH_MIX_IPV4_VAL, cfg.hash_sport_mix); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ reg = PPE_RSS_HASH_MIX_IPV4_ADDR + index * PPE_RSS_HASH_MIX_IPV4_INC; -+ -+ return regmap_write(ppe_dev->regmap, reg, val); -+} -+ -+static int ppe_rss_hash_ipv6_config(struct ppe_device *ppe_dev, int index, -+ struct ppe_rss_hash_cfg cfg) -+{ -+ u32 reg, val; -+ -+ switch (index) { -+ case 0 ... 3: -+ val = FIELD_PREP(PPE_RSS_HASH_MIX_VAL, cfg.hash_sip_mix[index]); -+ break; -+ case 4 ... 7: -+ val = FIELD_PREP(PPE_RSS_HASH_MIX_VAL, cfg.hash_dip_mix[index - 4]); -+ break; -+ case 8: -+ val = FIELD_PREP(PPE_RSS_HASH_MIX_VAL, cfg.hash_protocol_mix); -+ break; -+ case 9: -+ val = FIELD_PREP(PPE_RSS_HASH_MIX_VAL, cfg.hash_dport_mix); -+ break; -+ case 10: -+ val = FIELD_PREP(PPE_RSS_HASH_MIX_VAL, cfg.hash_sport_mix); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ reg = PPE_RSS_HASH_MIX_ADDR + index * PPE_RSS_HASH_MIX_INC; -+ -+ return regmap_write(ppe_dev->regmap, reg, val); -+} -+ -+/** -+ * ppe_rss_hash_config_set - Configure the PPE hash settings for the packet received. -+ * @ppe_dev: PPE device. -+ * @mode: Configure RSS hash for the packet type IPv4 and IPv6. -+ * @cfg: RSS hash configuration. -+ * -+ * PPE RSS hash settings are configured for the packet type IPv4 and IPv6. -+ * -+ * Return: 0 on success, negative error code on failure. -+ */ -+int ppe_rss_hash_config_set(struct ppe_device *ppe_dev, int mode, -+ struct ppe_rss_hash_cfg cfg) -+{ -+ u32 val, reg; -+ int i, ret; -+ -+ if (mode & PPE_RSS_HASH_MODE_IPV4) { -+ val = FIELD_PREP(PPE_RSS_HASH_MASK_IPV4_HASH_MASK, cfg.hash_mask); -+ val |= FIELD_PREP(PPE_RSS_HASH_MASK_IPV4_FRAGMENT, cfg.hash_fragment_mode); -+ ret = regmap_write(ppe_dev->regmap, PPE_RSS_HASH_MASK_IPV4_ADDR, val); -+ if (ret) -+ return ret; -+ -+ val = FIELD_PREP(PPE_RSS_HASH_SEED_IPV4_VAL, cfg.hash_seed); -+ ret = regmap_write(ppe_dev->regmap, PPE_RSS_HASH_SEED_IPV4_ADDR, val); -+ if (ret) -+ return ret; -+ -+ for (i = 0; i < PPE_RSS_HASH_MIX_IPV4_ENTRIES; i++) { -+ ret = ppe_rss_hash_ipv4_config(ppe_dev, i, cfg); -+ if (ret) -+ return ret; -+ } -+ -+ for (i = 0; i < PPE_RSS_HASH_FIN_IPV4_ENTRIES; i++) { -+ val = FIELD_PREP(PPE_RSS_HASH_FIN_IPV4_INNER, cfg.hash_fin_inner[i]); -+ val |= FIELD_PREP(PPE_RSS_HASH_FIN_IPV4_OUTER, cfg.hash_fin_outer[i]); -+ reg = PPE_RSS_HASH_FIN_IPV4_ADDR + i * PPE_RSS_HASH_FIN_IPV4_INC; -+ -+ ret = regmap_write(ppe_dev->regmap, reg, val); -+ if (ret) -+ return ret; -+ } -+ } -+ -+ if (mode & PPE_RSS_HASH_MODE_IPV6) { -+ val = FIELD_PREP(PPE_RSS_HASH_MASK_HASH_MASK, cfg.hash_mask); -+ val |= FIELD_PREP(PPE_RSS_HASH_MASK_FRAGMENT, cfg.hash_fragment_mode); -+ ret = regmap_write(ppe_dev->regmap, PPE_RSS_HASH_MASK_ADDR, val); -+ if (ret) -+ return ret; -+ -+ val = FIELD_PREP(PPE_RSS_HASH_SEED_VAL, cfg.hash_seed); -+ ret = regmap_write(ppe_dev->regmap, PPE_RSS_HASH_SEED_ADDR, val); -+ if (ret) -+ return ret; -+ -+ for (i = 0; i < PPE_RSS_HASH_MIX_ENTRIES; i++) { -+ ret = ppe_rss_hash_ipv6_config(ppe_dev, i, cfg); -+ if (ret) -+ return ret; -+ } -+ -+ for (i = 0; i < PPE_RSS_HASH_FIN_ENTRIES; i++) { -+ val = FIELD_PREP(PPE_RSS_HASH_FIN_INNER, cfg.hash_fin_inner[i]); -+ val |= FIELD_PREP(PPE_RSS_HASH_FIN_OUTER, cfg.hash_fin_outer[i]); -+ reg = PPE_RSS_HASH_FIN_ADDR + i * PPE_RSS_HASH_FIN_INC; -+ -+ ret = regmap_write(ppe_dev->regmap, reg, val); -+ if (ret) -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ - static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id, - const struct ppe_bm_port_config port_cfg) - { -@@ -1659,6 +1796,57 @@ static int ppe_port_config_init(struct p - return ppe_counter_enable_set(ppe_dev, 0); - } - -+/* Initialize the PPE RSS configuration for IPv4 and IPv6 packet receive. -+ * RSS settings are to calculate the random RSS hash value generated during -+ * packet receive. This hash is then used to generate the queue offset used -+ * to determine the queue used to transmit the packet. -+ */ -+static int ppe_rss_hash_init(struct ppe_device *ppe_dev) -+{ -+ u16 fins[PPE_RSS_HASH_TUPLES] = { 0x205, 0x264, 0x227, 0x245, 0x201 }; -+ u8 ips[PPE_RSS_HASH_IP_LENGTH] = { 0x13, 0xb, 0x13, 0xb }; -+ struct ppe_rss_hash_cfg hash_cfg; -+ int i, ret; -+ -+ hash_cfg.hash_seed = get_random_u32(); -+ hash_cfg.hash_mask = 0xfff; -+ -+ /* Use 5 tuple as RSS hash key for the first fragment of TCP, UDP -+ * and UDP-Lite packets. -+ */ -+ hash_cfg.hash_fragment_mode = false; -+ -+ /* The final common seed configs used to calculate the RSS has value, -+ * which is available for both IPv4 and IPv6 packet. -+ */ -+ for (i = 0; i < ARRAY_SIZE(fins); i++) { -+ hash_cfg.hash_fin_inner[i] = fins[i] & 0x1f; -+ hash_cfg.hash_fin_outer[i] = fins[i] >> 5; -+ } -+ -+ /* RSS seeds for IP protocol, L4 destination & source port and -+ * destination & source IP used to calculate the RSS hash value. -+ */ -+ hash_cfg.hash_protocol_mix = 0x13; -+ hash_cfg.hash_dport_mix = 0xb; -+ hash_cfg.hash_sport_mix = 0x13; -+ hash_cfg.hash_dip_mix[0] = 0xb; -+ hash_cfg.hash_sip_mix[0] = 0x13; -+ -+ /* Configure RSS seed configs for IPv4 packet. */ -+ ret = ppe_rss_hash_config_set(ppe_dev, PPE_RSS_HASH_MODE_IPV4, hash_cfg); -+ if (ret) -+ return ret; -+ -+ for (i = 0; i < ARRAY_SIZE(ips); i++) { -+ hash_cfg.hash_sip_mix[i] = ips[i]; -+ hash_cfg.hash_dip_mix[i] = ips[i]; -+ } -+ -+ /* Configure RSS seed configs for IPv6 packet. */ -+ return ppe_rss_hash_config_set(ppe_dev, PPE_RSS_HASH_MODE_IPV6, hash_cfg); -+} -+ - int ppe_hw_config(struct ppe_device *ppe_dev) - { - int ret; -@@ -1683,5 +1871,9 @@ int ppe_hw_config(struct ppe_device *ppe - if (ret) - return ret; - -- return ppe_port_config_init(ppe_dev); -+ ret = ppe_port_config_init(ppe_dev); -+ if (ret) -+ return ret; -+ -+ return ppe_rss_hash_init(ppe_dev); - } ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h -@@ -23,6 +23,12 @@ - /* The service code is used by EDMA port to transmit packet to PPE. */ - #define PPE_EDMA_SC_BYPASS_ID 1 - -+/* The PPE RSS hash configured for IPv4 and IPv6 packet separately. */ -+#define PPE_RSS_HASH_MODE_IPV4 BIT(0) -+#define PPE_RSS_HASH_MODE_IPV6 BIT(1) -+#define PPE_RSS_HASH_IP_LENGTH 4 -+#define PPE_RSS_HASH_TUPLES 5 -+ - /** - * enum ppe_scheduler_frame_mode - PPE scheduler frame mode. - * @PPE_SCH_WITH_IPG_PREAMBLE_FRAME_CRC: The scheduled frame includes IPG, -@@ -247,6 +253,37 @@ enum ppe_action_type { - PPE_ACTION_REDIRECT_TO_CPU = 3, - }; - -+/** -+ * struct ppe_rss_hash_cfg - PPE RSS hash configuration. -+ * @hash_mask: Mask of the generated hash value. -+ * @hash_fragment_mode: Hash generation mode for the first fragment of TCP, -+ * UDP and UDP-Lite packets, to use either 3 tuple or 5 tuple for RSS hash -+ * key computation. -+ * @hash_seed: Seed to generate RSS hash. -+ * @hash_sip_mix: Source IP selection. -+ * @hash_dip_mix: Destination IP selection. -+ * @hash_protocol_mix: Protocol selection. -+ * @hash_sport_mix: Source L4 port selection. -+ * @hash_dport_mix: Destination L4 port selection. -+ * @hash_fin_inner: RSS hash value first selection. -+ * @hash_fin_outer: RSS hash value second selection. -+ * -+ * PPE RSS hash value is generated for the packet based on the RSS hash -+ * configured. -+ */ -+struct ppe_rss_hash_cfg { -+ u32 hash_mask; -+ bool hash_fragment_mode; -+ u32 hash_seed; -+ u8 hash_sip_mix[PPE_RSS_HASH_IP_LENGTH]; -+ u8 hash_dip_mix[PPE_RSS_HASH_IP_LENGTH]; -+ u8 hash_protocol_mix; -+ u8 hash_sport_mix; -+ u8 hash_dport_mix; -+ u8 hash_fin_inner[PPE_RSS_HASH_TUPLES]; -+ u8 hash_fin_outer[PPE_RSS_HASH_TUPLES]; -+}; -+ - int ppe_hw_config(struct ppe_device *ppe_dev); - int ppe_queue_scheduler_set(struct ppe_device *ppe_dev, - int node_id, bool flow_level, int port, -@@ -269,4 +306,6 @@ int ppe_port_resource_get(struct ppe_dev - int ppe_sc_config_set(struct ppe_device *ppe_dev, int sc, - struct ppe_sc_cfg cfg); - int ppe_counter_enable_set(struct ppe_device *ppe_dev, int port); -+int ppe_rss_hash_config_set(struct ppe_device *ppe_dev, int mode, -+ struct ppe_rss_hash_cfg hash_cfg); - #endif ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h -@@ -16,6 +16,46 @@ - #define PPE_BM_SCH_CTRL_SCH_OFFSET GENMASK(14, 8) - #define PPE_BM_SCH_CTRL_SCH_EN BIT(31) - -+/* RSS settings are to calculate the random RSS hash value generated during -+ * packet receive to ARM cores. This hash is then used to generate the queue -+ * offset used to determine the queue used to transmit the packet to ARM cores. -+ */ -+#define PPE_RSS_HASH_MASK_ADDR 0xb4318 -+#define PPE_RSS_HASH_MASK_HASH_MASK GENMASK(20, 0) -+#define PPE_RSS_HASH_MASK_FRAGMENT BIT(28) -+ -+#define PPE_RSS_HASH_SEED_ADDR 0xb431c -+#define PPE_RSS_HASH_SEED_VAL GENMASK(31, 0) -+ -+#define PPE_RSS_HASH_MIX_ADDR 0xb4320 -+#define PPE_RSS_HASH_MIX_ENTRIES 11 -+#define PPE_RSS_HASH_MIX_INC 4 -+#define PPE_RSS_HASH_MIX_VAL GENMASK(4, 0) -+ -+#define PPE_RSS_HASH_FIN_ADDR 0xb4350 -+#define PPE_RSS_HASH_FIN_ENTRIES 5 -+#define PPE_RSS_HASH_FIN_INC 4 -+#define PPE_RSS_HASH_FIN_INNER GENMASK(4, 0) -+#define PPE_RSS_HASH_FIN_OUTER GENMASK(9, 5) -+ -+#define PPE_RSS_HASH_MASK_IPV4_ADDR 0xb4380 -+#define PPE_RSS_HASH_MASK_IPV4_HASH_MASK GENMASK(20, 0) -+#define PPE_RSS_HASH_MASK_IPV4_FRAGMENT BIT(28) -+ -+#define PPE_RSS_HASH_SEED_IPV4_ADDR 0xb4384 -+#define PPE_RSS_HASH_SEED_IPV4_VAL GENMASK(31, 0) -+ -+#define PPE_RSS_HASH_MIX_IPV4_ADDR 0xb4390 -+#define PPE_RSS_HASH_MIX_IPV4_ENTRIES 5 -+#define PPE_RSS_HASH_MIX_IPV4_INC 4 -+#define PPE_RSS_HASH_MIX_IPV4_VAL GENMASK(4, 0) -+ -+#define PPE_RSS_HASH_FIN_IPV4_ADDR 0xb43b0 -+#define PPE_RSS_HASH_FIN_IPV4_ENTRIES 5 -+#define PPE_RSS_HASH_FIN_IPV4_INC 4 -+#define PPE_RSS_HASH_FIN_IPV4_INNER GENMASK(4, 0) -+#define PPE_RSS_HASH_FIN_IPV4_OUTER GENMASK(9, 5) -+ - #define PPE_BM_SCH_CFG_TBL_ADDR 0xc000 - #define PPE_BM_SCH_CFG_TBL_ENTRIES 128 - #define PPE_BM_SCH_CFG_TBL_INC 0x10 diff --git a/target/linux/qualcommbe/patches-6.18/0333-net-ethernet-qualcomm-Initialize-PPE-queue-to-Ethern.patch b/target/linux/qualcommbe/patches-6.18/0333-net-ethernet-qualcomm-Initialize-PPE-queue-to-Ethern.patch deleted file mode 100644 index e05748f0f3..0000000000 --- a/target/linux/qualcommbe/patches-6.18/0333-net-ethernet-qualcomm-Initialize-PPE-queue-to-Ethern.patch +++ /dev/null @@ -1,122 +0,0 @@ -From c4a321bc120fabc318df165a7fcdeddfcf052253 Mon Sep 17 00:00:00 2001 -From: Luo Jie -Date: Sun, 9 Feb 2025 22:29:45 +0800 -Subject: [PATCH] net: ethernet: qualcomm: Initialize PPE queue to Ethernet DMA - ring mapping - -Configure the selected queues to map with an Ethernet DMA ring for the -packet to receive on ARM cores. - -As default initialization, all queues assigned to CPU port 0 are mapped -to the EDMA ring 0. This configuration is later updated during Ethernet -DMA initialization. - -Signed-off-by: Luo Jie ---- - .../net/ethernet/qualcomm/ppe/ppe_config.c | 47 ++++++++++++++++++- - .../net/ethernet/qualcomm/ppe/ppe_config.h | 6 +++ - drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 5 ++ - 3 files changed, 57 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c -@@ -1328,6 +1328,28 @@ int ppe_rss_hash_config_set(struct ppe_d - return 0; - } - -+/** -+ * ppe_ring_queue_map_set - Set the PPE queue to Ethernet DMA ring mapping -+ * @ppe_dev: PPE device -+ * @ring_id: Ethernet DMA ring ID -+ * @queue_map: Bit map of queue IDs to given Ethernet DMA ring -+ * -+ * Configure the mapping from a set of PPE queues to a given Ethernet DMA ring. -+ * -+ * Return: 0 on success, negative error code on failure. -+ */ -+int ppe_ring_queue_map_set(struct ppe_device *ppe_dev, int ring_id, u32 *queue_map) -+{ -+ u32 reg, queue_bitmap_val[PPE_RING_TO_QUEUE_BITMAP_WORD_CNT]; -+ -+ memcpy(queue_bitmap_val, queue_map, sizeof(queue_bitmap_val)); -+ reg = PPE_RING_Q_MAP_TBL_ADDR + PPE_RING_Q_MAP_TBL_INC * ring_id; -+ -+ return regmap_bulk_write(ppe_dev->regmap, reg, -+ queue_bitmap_val, -+ ARRAY_SIZE(queue_bitmap_val)); -+} -+ - static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id, - const struct ppe_bm_port_config port_cfg) - { -@@ -1847,6 +1869,25 @@ static int ppe_rss_hash_init(struct ppe_ - return ppe_rss_hash_config_set(ppe_dev, PPE_RSS_HASH_MODE_IPV6, hash_cfg); - } - -+/* Initialize mapping between PPE queues assigned to CPU port 0 -+ * to Ethernet DMA ring 0. -+ */ -+static int ppe_queues_to_ring_init(struct ppe_device *ppe_dev) -+{ -+ u32 queue_bmap[PPE_RING_TO_QUEUE_BITMAP_WORD_CNT] = {}; -+ int ret, queue_id, queue_max; -+ -+ ret = ppe_port_resource_get(ppe_dev, 0, PPE_RES_UCAST, -+ &queue_id, &queue_max); -+ if (ret) -+ return ret; -+ -+ for (; queue_id <= queue_max; queue_id++) -+ queue_bmap[queue_id / 32] |= BIT_MASK(queue_id % 32); -+ -+ return ppe_ring_queue_map_set(ppe_dev, 0, queue_bmap); -+} -+ - int ppe_hw_config(struct ppe_device *ppe_dev) - { - int ret; -@@ -1875,5 +1916,9 @@ int ppe_hw_config(struct ppe_device *ppe - if (ret) - return ret; - -- return ppe_rss_hash_init(ppe_dev); -+ ret = ppe_rss_hash_init(ppe_dev); -+ if (ret) -+ return ret; -+ -+ return ppe_queues_to_ring_init(ppe_dev); - } ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h -@@ -29,6 +29,9 @@ - #define PPE_RSS_HASH_IP_LENGTH 4 - #define PPE_RSS_HASH_TUPLES 5 - -+/* PPE supports 300 queues, each bit presents as one queue. */ -+#define PPE_RING_TO_QUEUE_BITMAP_WORD_CNT 10 -+ - /** - * enum ppe_scheduler_frame_mode - PPE scheduler frame mode. - * @PPE_SCH_WITH_IPG_PREAMBLE_FRAME_CRC: The scheduled frame includes IPG, -@@ -308,4 +311,7 @@ int ppe_sc_config_set(struct ppe_device - int ppe_counter_enable_set(struct ppe_device *ppe_dev, int port); - int ppe_rss_hash_config_set(struct ppe_device *ppe_dev, int mode, - struct ppe_rss_hash_cfg hash_cfg); -+int ppe_ring_queue_map_set(struct ppe_device *ppe_dev, -+ int ring_id, -+ u32 *queue_map); - #endif ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h -@@ -207,6 +207,11 @@ - #define PPE_L0_COMP_CFG_TBL_SHAPER_METER_LEN GENMASK(1, 0) - #define PPE_L0_COMP_CFG_TBL_NODE_METER_LEN GENMASK(3, 2) - -+/* PPE queue to Ethernet DMA ring mapping table. */ -+#define PPE_RING_Q_MAP_TBL_ADDR 0x42a000 -+#define PPE_RING_Q_MAP_TBL_ENTRIES 24 -+#define PPE_RING_Q_MAP_TBL_INC 0x40 -+ - /* Table addresses for per-queue dequeue setting. */ - #define PPE_DEQ_OPR_TBL_ADDR 0x430000 - #define PPE_DEQ_OPR_TBL_ENTRIES 300 diff --git a/target/linux/qualcommbe/patches-6.18/0334-net-ethernet-qualcomm-Initialize-PPE-L2-bridge-setti.patch b/target/linux/qualcommbe/patches-6.18/0334-net-ethernet-qualcomm-Initialize-PPE-L2-bridge-setti.patch deleted file mode 100644 index 28a48163a6..0000000000 --- a/target/linux/qualcommbe/patches-6.18/0334-net-ethernet-qualcomm-Initialize-PPE-L2-bridge-setti.patch +++ /dev/null @@ -1,193 +0,0 @@ -From cf7282d1e5712953516fa1cc0ffaae405491b3ca Mon Sep 17 00:00:00 2001 -From: Lei Wei -Date: Sun, 9 Feb 2025 22:29:46 +0800 -Subject: [PATCH] net: ethernet: qualcomm: Initialize PPE L2 bridge settings - -Initialize the L2 bridge settings for the PPE ports to only enable -L2 frame forwarding between CPU port and PPE Ethernet ports. - -The per-port L2 bridge settings are initialized as follows: -For PPE CPU port, the PPE bridge TX is enabled and FDB learning is -disabled. For PPE physical ports, the default L2 forwarding action -is initialized to forward to CPU port only. - -L2/FDB learning and forwarding will not be enabled for PPE physical -ports yet, since the port's VSI (Virtual Switch Instance) and VSI -membership are not yet configured, which are required for FDB -forwarding. The VSI and FDB forwarding will later be enabled when -switchdev is enabled. - -Signed-off-by: Lei Wei -Signed-off-by: Luo Jie ---- - .../net/ethernet/qualcomm/ppe/ppe_config.c | 80 ++++++++++++++++++- - drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 50 ++++++++++++ - 2 files changed, 129 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c -@@ -1888,6 +1888,80 @@ static int ppe_queues_to_ring_init(struc - return ppe_ring_queue_map_set(ppe_dev, 0, queue_bmap); - } - -+/* Initialize PPE bridge settings to only enable L2 frame receive and -+ * transmit between CPU port and PPE Ethernet ports. -+ */ -+static int ppe_bridge_init(struct ppe_device *ppe_dev) -+{ -+ u32 reg, mask, port_cfg[4], vsi_cfg[2]; -+ int ret, i; -+ -+ /* Configure the following settings for CPU port0: -+ * a.) Enable Bridge TX -+ * b.) Disable FDB new address learning -+ * c.) Disable station move address learning -+ */ -+ mask = PPE_PORT_BRIDGE_TXMAC_EN; -+ mask |= PPE_PORT_BRIDGE_NEW_LRN_EN; -+ mask |= PPE_PORT_BRIDGE_STA_MOVE_LRN_EN; -+ ret = regmap_update_bits(ppe_dev->regmap, -+ PPE_PORT_BRIDGE_CTRL_ADDR, -+ mask, -+ PPE_PORT_BRIDGE_TXMAC_EN); -+ if (ret) -+ return ret; -+ -+ for (i = 1; i < ppe_dev->num_ports; i++) { -+ /* Enable invalid VSI forwarding for all the physical ports -+ * to CPU port0, in case no VSI is assigned to the physical -+ * port. -+ */ -+ reg = PPE_L2_VP_PORT_TBL_ADDR + PPE_L2_VP_PORT_TBL_INC * i; -+ ret = regmap_bulk_read(ppe_dev->regmap, reg, -+ port_cfg, ARRAY_SIZE(port_cfg)); -+ -+ if (ret) -+ return ret; -+ -+ PPE_L2_PORT_SET_INVALID_VSI_FWD_EN(port_cfg, true); -+ PPE_L2_PORT_SET_DST_INFO(port_cfg, 0); -+ -+ ret = regmap_bulk_write(ppe_dev->regmap, reg, -+ port_cfg, ARRAY_SIZE(port_cfg)); -+ if (ret) -+ return ret; -+ } -+ -+ for (i = 0; i < PPE_VSI_TBL_ENTRIES; i++) { -+ /* Set the VSI forward membership to include only CPU port0. -+ * FDB learning and forwarding take place only after switchdev -+ * is supported later to create the VSI and join the physical -+ * ports to the VSI port member. -+ */ -+ reg = PPE_VSI_TBL_ADDR + PPE_VSI_TBL_INC * i; -+ ret = regmap_bulk_read(ppe_dev->regmap, reg, -+ vsi_cfg, ARRAY_SIZE(vsi_cfg)); -+ if (ret) -+ return ret; -+ -+ PPE_VSI_SET_MEMBER_PORT_BITMAP(vsi_cfg, BIT(0)); -+ PPE_VSI_SET_UUC_BITMAP(vsi_cfg, BIT(0)); -+ PPE_VSI_SET_UMC_BITMAP(vsi_cfg, BIT(0)); -+ PPE_VSI_SET_BC_BITMAP(vsi_cfg, BIT(0)); -+ PPE_VSI_SET_NEW_ADDR_LRN_EN(vsi_cfg, true); -+ PPE_VSI_SET_NEW_ADDR_FWD_CMD(vsi_cfg, PPE_ACTION_FORWARD); -+ PPE_VSI_SET_STATION_MOVE_LRN_EN(vsi_cfg, true); -+ PPE_VSI_SET_STATION_MOVE_FWD_CMD(vsi_cfg, PPE_ACTION_FORWARD); -+ -+ ret = regmap_bulk_write(ppe_dev->regmap, reg, -+ vsi_cfg, ARRAY_SIZE(vsi_cfg)); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ - int ppe_hw_config(struct ppe_device *ppe_dev) - { - int ret; -@@ -1920,5 +1994,9 @@ int ppe_hw_config(struct ppe_device *ppe - if (ret) - return ret; - -- return ppe_queues_to_ring_init(ppe_dev); -+ ret = ppe_queues_to_ring_init(ppe_dev); -+ if (ret) -+ return ret; -+ -+ return ppe_bridge_init(ppe_dev); - } ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h -@@ -117,6 +117,14 @@ - #define PPE_EG_SERVICE_SET_TX_CNT_EN(tbl_cfg, value) \ - u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_EG_SERVICE_W1_TX_CNT_EN) - -+/* PPE port bridge configuration */ -+#define PPE_PORT_BRIDGE_CTRL_ADDR 0x60300 -+#define PPE_PORT_BRIDGE_CTRL_ENTRIES 8 -+#define PPE_PORT_BRIDGE_CTRL_INC 4 -+#define PPE_PORT_BRIDGE_NEW_LRN_EN BIT(0) -+#define PPE_PORT_BRIDGE_STA_MOVE_LRN_EN BIT(3) -+#define PPE_PORT_BRIDGE_TXMAC_EN BIT(16) -+ - /* PPE port control configurations for the traffic to the multicast queues. */ - #define PPE_MC_MTU_CTRL_TBL_ADDR 0x60a00 - #define PPE_MC_MTU_CTRL_TBL_ENTRIES 8 -@@ -125,6 +133,36 @@ - #define PPE_MC_MTU_CTRL_TBL_MTU_CMD GENMASK(15, 14) - #define PPE_MC_MTU_CTRL_TBL_TX_CNT_EN BIT(16) - -+/* PPE VSI configurations */ -+#define PPE_VSI_TBL_ADDR 0x63800 -+#define PPE_VSI_TBL_ENTRIES 64 -+#define PPE_VSI_TBL_INC 0x10 -+#define PPE_VSI_W0_MEMBER_PORT_BITMAP GENMASK(7, 0) -+#define PPE_VSI_W0_UUC_BITMAP GENMASK(15, 8) -+#define PPE_VSI_W0_UMC_BITMAP GENMASK(23, 16) -+#define PPE_VSI_W0_BC_BITMAP GENMASK(31, 24) -+#define PPE_VSI_W1_NEW_ADDR_LRN_EN BIT(0) -+#define PPE_VSI_W1_NEW_ADDR_FWD_CMD GENMASK(2, 1) -+#define PPE_VSI_W1_STATION_MOVE_LRN_EN BIT(3) -+#define PPE_VSI_W1_STATION_MOVE_FWD_CMD GENMASK(5, 4) -+ -+#define PPE_VSI_SET_MEMBER_PORT_BITMAP(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_VSI_W0_MEMBER_PORT_BITMAP) -+#define PPE_VSI_SET_UUC_BITMAP(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_VSI_W0_UUC_BITMAP) -+#define PPE_VSI_SET_UMC_BITMAP(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_VSI_W0_UMC_BITMAP) -+#define PPE_VSI_SET_BC_BITMAP(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_VSI_W0_BC_BITMAP) -+#define PPE_VSI_SET_NEW_ADDR_LRN_EN(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_VSI_W1_NEW_ADDR_LRN_EN) -+#define PPE_VSI_SET_NEW_ADDR_FWD_CMD(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_VSI_W1_NEW_ADDR_FWD_CMD) -+#define PPE_VSI_SET_STATION_MOVE_LRN_EN(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_VSI_W1_STATION_MOVE_LRN_EN) -+#define PPE_VSI_SET_STATION_MOVE_FWD_CMD(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_VSI_W1_STATION_MOVE_FWD_CMD) -+ - /* PPE port control configurations for the traffic to the unicast queues. */ - #define PPE_MRU_MTU_CTRL_TBL_ADDR 0x65000 - #define PPE_MRU_MTU_CTRL_TBL_ENTRIES 256 -@@ -163,6 +201,18 @@ - #define PPE_IN_L2_SERVICE_TBL_RX_CNT_EN BIT(30) - #define PPE_IN_L2_SERVICE_TBL_TX_CNT_EN BIT(31) - -+/* L2 Port configurations */ -+#define PPE_L2_VP_PORT_TBL_ADDR 0x98000 -+#define PPE_L2_VP_PORT_TBL_ENTRIES 256 -+#define PPE_L2_VP_PORT_TBL_INC 0x10 -+#define PPE_L2_VP_PORT_W0_INVALID_VSI_FWD_EN BIT(0) -+#define PPE_L2_VP_PORT_W0_DST_INFO GENMASK(9, 2) -+ -+#define PPE_L2_PORT_SET_INVALID_VSI_FWD_EN(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_L2_VP_PORT_W0_INVALID_VSI_FWD_EN) -+#define PPE_L2_PORT_SET_DST_INFO(tbl_cfg, value) \ -+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_L2_VP_PORT_W0_DST_INFO) -+ - /* PPE service code configuration for the tunnel packet. */ - #define PPE_TL_SERVICE_TBL_ADDR 0x306000 - #define PPE_TL_SERVICE_TBL_ENTRIES 256 diff --git a/target/linux/qualcommbe/patches-6.18/0335-net-ethernet-qualcomm-Add-PPE-debugfs-support-for-PP.patch b/target/linux/qualcommbe/patches-6.18/0335-net-ethernet-qualcomm-Add-PPE-debugfs-support-for-PP.patch deleted file mode 100644 index e748bca604..0000000000 --- a/target/linux/qualcommbe/patches-6.18/0335-net-ethernet-qualcomm-Add-PPE-debugfs-support-for-PP.patch +++ /dev/null @@ -1,950 +0,0 @@ -From fc25088f79cccb934d69e563221068589565926f Mon Sep 17 00:00:00 2001 -From: Luo Jie -Date: Sun, 9 Feb 2025 22:29:47 +0800 -Subject: [PATCH] net: ethernet: qualcomm: Add PPE debugfs support for PPE - counters - -The PPE hardware counters maintain counters for packets handled by -the various functional blocks of PPE. They help in tracing the packets -passed through PPE and debugging any packet drops. - -The counters displayed by this debugfs file are ones that are common -for all Ethernet ports, and they do not include the counters that are -specific for a MAC port. Hence they cannot be displayed using ethtool. -The per-MAC counters will be supported using "ethtool -S" along with -the netdevice driver. - -The PPE hardware packet counters are made available through -the debugfs entry "/sys/kernel/debug/ppe/packet_counters". - -Signed-off-by: Luo Jie ---- - drivers/net/ethernet/qualcomm/ppe/Makefile | 2 +- - drivers/net/ethernet/qualcomm/ppe/ppe.c | 11 + - drivers/net/ethernet/qualcomm/ppe/ppe.h | 3 + - .../net/ethernet/qualcomm/ppe/ppe_debugfs.c | 692 ++++++++++++++++++ - .../net/ethernet/qualcomm/ppe/ppe_debugfs.h | 16 + - drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 102 +++ - 6 files changed, 825 insertions(+), 1 deletion(-) - create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c - create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.h - ---- a/drivers/net/ethernet/qualcomm/ppe/Makefile -+++ b/drivers/net/ethernet/qualcomm/ppe/Makefile -@@ -4,4 +4,4 @@ - # - - obj-$(CONFIG_QCOM_PPE) += qcom-ppe.o --qcom-ppe-objs := ppe.o ppe_config.o -+qcom-ppe-objs := ppe.o ppe_config.o ppe_debugfs.o ---- a/drivers/net/ethernet/qualcomm/ppe/ppe.c -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.c -@@ -16,6 +16,7 @@ - - #include "ppe.h" - #include "ppe_config.h" -+#include "ppe_debugfs.h" - - #define PPE_PORT_MAX 8 - #define PPE_CLK_RATE 353000000 -@@ -199,11 +200,20 @@ static int qcom_ppe_probe(struct platfor - if (ret) - return dev_err_probe(dev, ret, "PPE HW config failed\n"); - -+ ppe_debugfs_setup(ppe_dev); - platform_set_drvdata(pdev, ppe_dev); - - return 0; - } - -+static void qcom_ppe_remove(struct platform_device *pdev) -+{ -+ struct ppe_device *ppe_dev; -+ -+ ppe_dev = platform_get_drvdata(pdev); -+ ppe_debugfs_teardown(ppe_dev); -+} -+ - static const struct of_device_id qcom_ppe_of_match[] = { - { .compatible = "qcom,ipq9574-ppe" }, - {} -@@ -216,6 +226,7 @@ static struct platform_driver qcom_ppe_d - .of_match_table = qcom_ppe_of_match, - }, - .probe = qcom_ppe_probe, -+ .remove = qcom_ppe_remove, - }; - module_platform_driver(qcom_ppe_driver); - ---- a/drivers/net/ethernet/qualcomm/ppe/ppe.h -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.h -@@ -11,6 +11,7 @@ - - struct device; - struct regmap; -+struct dentry; - - /** - * struct ppe_device - PPE device private data. -@@ -18,6 +19,7 @@ struct regmap; - * @regmap: PPE register map. - * @clk_rate: PPE clock rate. - * @num_ports: Number of PPE ports. -+ * @debugfs_root: Debugfs root entry. - * @num_icc_paths: Number of interconnect paths. - * @icc_paths: Interconnect path array. - * -@@ -30,6 +32,7 @@ struct ppe_device { - struct regmap *regmap; - unsigned long clk_rate; - unsigned int num_ports; -+ struct dentry *debugfs_root; - unsigned int num_icc_paths; - struct icc_bulk_data icc_paths[] __counted_by(num_icc_paths); - }; ---- /dev/null -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c -@@ -0,0 +1,692 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+/* PPE debugfs routines for display of PPE counters useful for debug. */ -+ -+#include -+#include -+#include -+#include -+ -+#include "ppe.h" -+#include "ppe_config.h" -+#include "ppe_debugfs.h" -+#include "ppe_regs.h" -+ -+#define PPE_PKT_CNT_TBL_SIZE 3 -+#define PPE_DROP_PKT_CNT_TBL_SIZE 5 -+ -+#define PPE_W0_PKT_CNT GENMASK(31, 0) -+#define PPE_W2_DROP_PKT_CNT_LOW GENMASK(31, 8) -+#define PPE_W3_DROP_PKT_CNT_HIGH GENMASK(7, 0) -+ -+#define PPE_GET_PKT_CNT(tbl_cnt) \ -+ u32_get_bits(*((u32 *)(tbl_cnt)), PPE_W0_PKT_CNT) -+#define PPE_GET_DROP_PKT_CNT_LOW(tbl_cnt) \ -+ u32_get_bits(*((u32 *)(tbl_cnt) + 0x2), PPE_W2_DROP_PKT_CNT_LOW) -+#define PPE_GET_DROP_PKT_CNT_HIGH(tbl_cnt) \ -+ u32_get_bits(*((u32 *)(tbl_cnt) + 0x3), PPE_W3_DROP_PKT_CNT_HIGH) -+ -+#define PRINT_COUNTER_PREFIX(desc, cnt_type) \ -+ seq_printf(seq, "%-16s %16s", desc, cnt_type) -+ -+#define PRINT_CPU_CODE_COUNTER(cnt, code) \ -+ seq_printf(seq, "%10u(cpucode:%d)", cnt, code) -+ -+#define PRINT_DROP_CODE_COUNTER(cnt, port, code) \ -+ seq_printf(seq, "%10u(port=%d),dropcode:%d", cnt, port, code) -+ -+#define PRINT_SINGLE_COUNTER(tag, cnt, str, index) \ -+do { \ -+ if (!((tag) % 4)) \ -+ seq_printf(seq, "\n%-16s %16s", "", ""); \ -+ seq_printf(seq, "%10u(%s=%04d)", cnt, str, index); \ -+} while (0) -+ -+#define PRINT_TWO_COUNTERS(tag, cnt0, cnt1, str, index) \ -+do { \ -+ if (!((tag) % 4)) \ -+ seq_printf(seq, "\n%-16s %16s", "", ""); \ -+ seq_printf(seq, "%10u/%u(%s=%04d)", cnt0, cnt1, str, index); \ -+} while (0) -+ -+/** -+ * enum ppe_cnt_size_type - PPE counter size type -+ * @PPE_PKT_CNT_SIZE_1WORD: Counter size with single register -+ * @PPE_PKT_CNT_SIZE_3WORD: Counter size with table of 3 words -+ * @PPE_PKT_CNT_SIZE_5WORD: Counter size with table of 5 words -+ * -+ * PPE takes the different register size to record the packet counters. -+ * It uses single register, or register table with 3 words or 5 words. -+ * The counter with table size 5 words also records the drop counter. -+ * There are also some other counter types occupying sizes less than 32 -+ * bits, which is not covered by this enumeration type. -+ */ -+enum ppe_cnt_size_type { -+ PPE_PKT_CNT_SIZE_1WORD, -+ PPE_PKT_CNT_SIZE_3WORD, -+ PPE_PKT_CNT_SIZE_5WORD, -+}; -+ -+static int ppe_pkt_cnt_get(struct ppe_device *ppe_dev, u32 reg, -+ enum ppe_cnt_size_type cnt_type, -+ u32 *cnt, u32 *drop_cnt) -+{ -+ u32 drop_pkt_cnt[PPE_DROP_PKT_CNT_TBL_SIZE]; -+ u32 pkt_cnt[PPE_PKT_CNT_TBL_SIZE]; -+ u32 value; -+ int ret; -+ -+ switch (cnt_type) { -+ case PPE_PKT_CNT_SIZE_1WORD: -+ ret = regmap_read(ppe_dev->regmap, reg, &value); -+ if (ret) -+ return ret; -+ -+ *cnt = value; -+ break; -+ case PPE_PKT_CNT_SIZE_3WORD: -+ ret = regmap_bulk_read(ppe_dev->regmap, reg, -+ pkt_cnt, ARRAY_SIZE(pkt_cnt)); -+ if (ret) -+ return ret; -+ -+ *cnt = PPE_GET_PKT_CNT(pkt_cnt); -+ break; -+ case PPE_PKT_CNT_SIZE_5WORD: -+ ret = regmap_bulk_read(ppe_dev->regmap, reg, -+ drop_pkt_cnt, ARRAY_SIZE(drop_pkt_cnt)); -+ if (ret) -+ return ret; -+ -+ *cnt = PPE_GET_PKT_CNT(drop_pkt_cnt); -+ -+ /* Drop counter with low 24 bits. */ -+ value = PPE_GET_DROP_PKT_CNT_LOW(drop_pkt_cnt); -+ *drop_cnt = FIELD_PREP(GENMASK(23, 0), value); -+ -+ /* Drop counter with high 8 bits. */ -+ value = PPE_GET_DROP_PKT_CNT_HIGH(drop_pkt_cnt); -+ *drop_cnt |= FIELD_PREP(GENMASK(31, 24), value); -+ break; -+ } -+ -+ return 0; -+} -+ -+static void ppe_tbl_pkt_cnt_clear(struct ppe_device *ppe_dev, u32 reg, -+ enum ppe_cnt_size_type cnt_type) -+{ -+ u32 drop_pkt_cnt[PPE_DROP_PKT_CNT_TBL_SIZE] = {}; -+ u32 pkt_cnt[PPE_PKT_CNT_TBL_SIZE] = {}; -+ -+ switch (cnt_type) { -+ case PPE_PKT_CNT_SIZE_1WORD: -+ regmap_write(ppe_dev->regmap, reg, 0); -+ break; -+ case PPE_PKT_CNT_SIZE_3WORD: -+ regmap_bulk_write(ppe_dev->regmap, reg, -+ pkt_cnt, ARRAY_SIZE(pkt_cnt)); -+ break; -+ case PPE_PKT_CNT_SIZE_5WORD: -+ regmap_bulk_write(ppe_dev->regmap, reg, -+ drop_pkt_cnt, ARRAY_SIZE(drop_pkt_cnt)); -+ break; -+ } -+} -+ -+/* The number of packets dropped because of no buffer available, no PPE -+ * buffer assigned to these packets. -+ */ -+static void ppe_port_rx_drop_counter_get(struct ppe_device *ppe_dev, -+ struct seq_file *seq) -+{ -+ u32 reg, drop_cnt = 0; -+ int ret, i, tag = 0; -+ -+ PRINT_COUNTER_PREFIX("PRX_DROP_CNT", "SILENT_DROP:"); -+ for (i = 0; i < PPE_DROP_CNT_TBL_ENTRIES; i++) { -+ reg = PPE_DROP_CNT_TBL_ADDR + i * PPE_DROP_CNT_TBL_INC; -+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_1WORD, -+ &drop_cnt, NULL); -+ if (ret) { -+ seq_printf(seq, "ERROR %d\n", ret); -+ return; -+ } -+ -+ if (drop_cnt > 0) { -+ tag++; -+ PRINT_SINGLE_COUNTER(tag, drop_cnt, "port", i); -+ } -+ } -+ -+ seq_putc(seq, '\n'); -+} -+ -+/* The number of packets dropped because hardware buffers were available -+ * only partially for the packet. -+ */ -+static void ppe_port_rx_bm_drop_counter_get(struct ppe_device *ppe_dev, -+ struct seq_file *seq) -+{ -+ u32 reg, pkt_cnt = 0; -+ int ret, i, tag = 0; -+ -+ PRINT_COUNTER_PREFIX("PRX_BM_DROP_CNT", "OVERFLOW_DROP:"); -+ for (i = 0; i < PPE_DROP_STAT_TBL_ENTRIES; i++) { -+ reg = PPE_DROP_STAT_TBL_ADDR + PPE_DROP_STAT_TBL_INC * i; -+ -+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD, -+ &pkt_cnt, NULL); -+ if (ret) { -+ seq_printf(seq, "ERROR %d\n", ret); -+ return; -+ } -+ -+ if (pkt_cnt > 0) { -+ tag++; -+ PRINT_SINGLE_COUNTER(tag, pkt_cnt, "port", i); -+ } -+ } -+ -+ seq_putc(seq, '\n'); -+} -+ -+/* The number of currently occupied buffers, that can't be flushed. */ -+static void ppe_port_rx_bm_port_counter_get(struct ppe_device *ppe_dev, -+ struct seq_file *seq) -+{ -+ int used_cnt, react_cnt; -+ int ret, i, tag = 0; -+ u32 reg, val; -+ -+ PRINT_COUNTER_PREFIX("PRX_BM_PORT_CNT", "USED/REACT:"); -+ for (i = 0; i < PPE_BM_USED_CNT_TBL_ENTRIES; i++) { -+ reg = PPE_BM_USED_CNT_TBL_ADDR + i * PPE_BM_USED_CNT_TBL_INC; -+ ret = regmap_read(ppe_dev->regmap, reg, &val); -+ if (ret) { -+ seq_printf(seq, "ERROR %d\n", ret); -+ return; -+ } -+ -+ /* The number of PPE buffers used for caching the received -+ * packets before the pause frame sent. -+ */ -+ used_cnt = FIELD_GET(PPE_BM_USED_CNT_VAL, val); -+ -+ reg = PPE_BM_REACT_CNT_TBL_ADDR + i * PPE_BM_REACT_CNT_TBL_INC; -+ ret = regmap_read(ppe_dev->regmap, reg, &val); -+ if (ret) { -+ seq_printf(seq, "ERROR %d\n", ret); -+ return; -+ } -+ -+ /* The number of PPE buffers used for caching the received -+ * packets after pause frame sent out. -+ */ -+ react_cnt = FIELD_GET(PPE_BM_REACT_CNT_VAL, val); -+ -+ if (used_cnt > 0 || react_cnt > 0) { -+ tag++; -+ PRINT_TWO_COUNTERS(tag, used_cnt, react_cnt, "port", i); -+ } -+ } -+ -+ seq_putc(seq, '\n'); -+} -+ -+/* The number of packets processed by the ingress parser module of PPE. */ -+static void ppe_parse_pkt_counter_get(struct ppe_device *ppe_dev, -+ struct seq_file *seq) -+{ -+ u32 reg, cnt = 0, tunnel_cnt = 0; -+ int i, ret, tag = 0; -+ -+ PRINT_COUNTER_PREFIX("IPR_PKT_CNT", "TPRX/IPRX:"); -+ for (i = 0; i < PPE_IPR_PKT_CNT_TBL_ENTRIES; i++) { -+ reg = PPE_TPR_PKT_CNT_TBL_ADDR + i * PPE_TPR_PKT_CNT_TBL_INC; -+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_1WORD, -+ &tunnel_cnt, NULL); -+ if (ret) { -+ seq_printf(seq, "ERROR %d\n", ret); -+ return; -+ } -+ -+ reg = PPE_IPR_PKT_CNT_TBL_ADDR + i * PPE_IPR_PKT_CNT_TBL_INC; -+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_1WORD, -+ &cnt, NULL); -+ if (ret) { -+ seq_printf(seq, "ERROR %d\n", ret); -+ return; -+ } -+ -+ if (tunnel_cnt > 0 || cnt > 0) { -+ tag++; -+ PRINT_TWO_COUNTERS(tag, tunnel_cnt, cnt, "port", i); -+ } -+ } -+ -+ seq_putc(seq, '\n'); -+} -+ -+/* The number of packets received or dropped on the ingress direction. */ -+static void ppe_port_rx_counter_get(struct ppe_device *ppe_dev, -+ struct seq_file *seq) -+{ -+ u32 reg, pkt_cnt = 0, drop_cnt = 0; -+ int ret, i, tag = 0; -+ -+ PRINT_COUNTER_PREFIX("PORT_RX_CNT", "RX/RX_DROP:"); -+ for (i = 0; i < PPE_PHY_PORT_RX_CNT_TBL_ENTRIES; i++) { -+ reg = PPE_PHY_PORT_RX_CNT_TBL_ADDR + PPE_PHY_PORT_RX_CNT_TBL_INC * i; -+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_5WORD, -+ &pkt_cnt, &drop_cnt); -+ if (ret) { -+ seq_printf(seq, "ERROR %d\n", ret); -+ return; -+ } -+ -+ if (pkt_cnt > 0) { -+ tag++; -+ PRINT_TWO_COUNTERS(tag, pkt_cnt, drop_cnt, "port", i); -+ } -+ } -+ -+ seq_putc(seq, '\n'); -+} -+ -+/* The number of packets received or dropped by the port. */ -+static void ppe_vp_rx_counter_get(struct ppe_device *ppe_dev, -+ struct seq_file *seq) -+{ -+ u32 reg, pkt_cnt = 0, drop_cnt = 0; -+ int ret, i, tag = 0; -+ -+ PRINT_COUNTER_PREFIX("VPORT_RX_CNT", "RX/RX_DROP:"); -+ for (i = 0; i < PPE_PORT_RX_CNT_TBL_ENTRIES; i++) { -+ reg = PPE_PORT_RX_CNT_TBL_ADDR + PPE_PORT_RX_CNT_TBL_INC * i; -+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_5WORD, -+ &pkt_cnt, &drop_cnt); -+ if (ret) { -+ seq_printf(seq, "ERROR %d\n", ret); -+ return; -+ } -+ -+ if (pkt_cnt > 0) { -+ tag++; -+ PRINT_TWO_COUNTERS(tag, pkt_cnt, drop_cnt, "port", i); -+ } -+ } -+ -+ seq_putc(seq, '\n'); -+} -+ -+/* The number of packets received or dropped by layer 2 processing. */ -+static void ppe_pre_l2_counter_get(struct ppe_device *ppe_dev, -+ struct seq_file *seq) -+{ -+ u32 reg, pkt_cnt = 0, drop_cnt = 0; -+ int ret, i, tag = 0; -+ -+ PRINT_COUNTER_PREFIX("PRE_L2_CNT", "RX/RX_DROP:"); -+ for (i = 0; i < PPE_PRE_L2_CNT_TBL_ENTRIES; i++) { -+ reg = PPE_PRE_L2_CNT_TBL_ADDR + PPE_PRE_L2_CNT_TBL_INC * i; -+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_5WORD, -+ &pkt_cnt, &drop_cnt); -+ if (ret) { -+ seq_printf(seq, "ERROR %d\n", ret); -+ return; -+ } -+ -+ if (pkt_cnt > 0) { -+ tag++; -+ PRINT_TWO_COUNTERS(tag, pkt_cnt, drop_cnt, "vsi", i); -+ } -+ } -+ -+ seq_putc(seq, '\n'); -+} -+ -+/* The number of VLAN packets received by PPE. */ -+static void ppe_vlan_counter_get(struct ppe_device *ppe_dev, -+ struct seq_file *seq) -+{ -+ u32 reg, pkt_cnt = 0; -+ int ret, i, tag = 0; -+ -+ PRINT_COUNTER_PREFIX("VLAN_CNT", "RX:"); -+ for (i = 0; i < PPE_VLAN_CNT_TBL_ENTRIES; i++) { -+ reg = PPE_VLAN_CNT_TBL_ADDR + PPE_VLAN_CNT_TBL_INC * i; -+ -+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD, -+ &pkt_cnt, NULL); -+ if (ret) { -+ seq_printf(seq, "ERROR %d\n", ret); -+ return; -+ } -+ -+ if (pkt_cnt > 0) { -+ tag++; -+ PRINT_SINGLE_COUNTER(tag, pkt_cnt, "vsi", i); -+ } -+ } -+ -+ seq_putc(seq, '\n'); -+} -+ -+/* The number of packets handed to CPU by PPE. */ -+static void ppe_cpu_code_counter_get(struct ppe_device *ppe_dev, -+ struct seq_file *seq) -+{ -+ u32 reg, pkt_cnt = 0; -+ int ret, i; -+ -+ PRINT_COUNTER_PREFIX("CPU_CODE_CNT", "CODE:"); -+ for (i = 0; i < PPE_DROP_CPU_CNT_TBL_ENTRIES; i++) { -+ reg = PPE_DROP_CPU_CNT_TBL_ADDR + PPE_DROP_CPU_CNT_TBL_INC * i; -+ -+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD, -+ &pkt_cnt, NULL); -+ if (ret) { -+ seq_printf(seq, "ERROR %d\n", ret); -+ return; -+ } -+ -+ if (!pkt_cnt) -+ continue; -+ -+ /* There are 256 CPU codes saved in the first 256 entries -+ * of register table, and 128 drop codes for each PPE port -+ * (0-7), the total entries is 256 + 8 * 128. -+ */ -+ if (i < 256) -+ PRINT_CPU_CODE_COUNTER(pkt_cnt, i); -+ else -+ PRINT_DROP_CODE_COUNTER(pkt_cnt, (i - 256) % 8, -+ (i - 256) / 8); -+ seq_putc(seq, '\n'); -+ PRINT_COUNTER_PREFIX("", ""); -+ } -+ -+ seq_putc(seq, '\n'); -+} -+ -+/* The number of packets forwarded by VLAN on the egress direction. */ -+static void ppe_eg_vsi_counter_get(struct ppe_device *ppe_dev, -+ struct seq_file *seq) -+{ -+ u32 reg, pkt_cnt = 0; -+ int ret, i, tag = 0; -+ -+ PRINT_COUNTER_PREFIX("EG_VSI_CNT", "TX:"); -+ for (i = 0; i < PPE_EG_VSI_COUNTER_TBL_ENTRIES; i++) { -+ reg = PPE_EG_VSI_COUNTER_TBL_ADDR + PPE_EG_VSI_COUNTER_TBL_INC * i; -+ -+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD, -+ &pkt_cnt, NULL); -+ if (ret) { -+ seq_printf(seq, "ERROR %d\n", ret); -+ return; -+ } -+ -+ if (pkt_cnt > 0) { -+ tag++; -+ PRINT_SINGLE_COUNTER(tag, pkt_cnt, "vsi", i); -+ } -+ } -+ -+ seq_putc(seq, '\n'); -+} -+ -+/* The number of packets trasmitted or dropped by port. */ -+static void ppe_vp_tx_counter_get(struct ppe_device *ppe_dev, -+ struct seq_file *seq) -+{ -+ u32 reg, pkt_cnt = 0, drop_cnt = 0; -+ int ret, i, tag = 0; -+ -+ PRINT_COUNTER_PREFIX("VPORT_TX_CNT", "TX/TX_DROP:"); -+ for (i = 0; i < PPE_VPORT_TX_COUNTER_TBL_ENTRIES; i++) { -+ reg = PPE_VPORT_TX_COUNTER_TBL_ADDR + PPE_VPORT_TX_COUNTER_TBL_INC * i; -+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD, -+ &pkt_cnt, NULL); -+ if (ret) { -+ seq_printf(seq, "ERROR %d\n", ret); -+ return; -+ } -+ -+ reg = PPE_VPORT_TX_DROP_CNT_TBL_ADDR + PPE_VPORT_TX_DROP_CNT_TBL_INC * i; -+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD, -+ &drop_cnt, NULL); -+ if (ret) { -+ seq_printf(seq, "ERROR %d\n", ret); -+ return; -+ } -+ -+ if (pkt_cnt > 0 || drop_cnt > 0) { -+ tag++; -+ PRINT_TWO_COUNTERS(tag, pkt_cnt, drop_cnt, "port", i); -+ } -+ } -+ -+ seq_putc(seq, '\n'); -+} -+ -+/* The number of packets trasmitted or dropped on the egress direction. */ -+static void ppe_port_tx_counter_get(struct ppe_device *ppe_dev, -+ struct seq_file *seq) -+{ -+ u32 reg, pkt_cnt = 0, drop_cnt = 0; -+ int ret, i, tag = 0; -+ -+ PRINT_COUNTER_PREFIX("PORT_TX_CNT", "TX/TX_DROP:"); -+ for (i = 0; i < PPE_PORT_TX_COUNTER_TBL_ENTRIES; i++) { -+ reg = PPE_PORT_TX_COUNTER_TBL_ADDR + PPE_PORT_TX_COUNTER_TBL_INC * i; -+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD, -+ &pkt_cnt, NULL); -+ if (ret) { -+ seq_printf(seq, "ERROR %d\n", ret); -+ return; -+ } -+ -+ reg = PPE_PORT_TX_DROP_CNT_TBL_ADDR + PPE_PORT_TX_DROP_CNT_TBL_INC * i; -+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD, -+ &drop_cnt, NULL); -+ if (ret) { -+ seq_printf(seq, "ERROR %d\n", ret); -+ return; -+ } -+ -+ if (pkt_cnt > 0 || drop_cnt > 0) { -+ tag++; -+ PRINT_TWO_COUNTERS(tag, pkt_cnt, drop_cnt, "port", i); -+ } -+ } -+ -+ seq_putc(seq, '\n'); -+} -+ -+/* The number of packets transmitted or pending by the PPE queue. */ -+static void ppe_queue_tx_counter_get(struct ppe_device *ppe_dev, -+ struct seq_file *seq) -+{ -+ u32 reg, val, pkt_cnt = 0, pend_cnt = 0; -+ int ret, i, tag = 0; -+ -+ PRINT_COUNTER_PREFIX("QUEUE_TX_CNT", "TX/PEND:"); -+ for (i = 0; i < PPE_QUEUE_TX_COUNTER_TBL_ENTRIES; i++) { -+ reg = PPE_QUEUE_TX_COUNTER_TBL_ADDR + PPE_QUEUE_TX_COUNTER_TBL_INC * i; -+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD, -+ &pkt_cnt, NULL); -+ if (ret) { -+ seq_printf(seq, "ERROR %d\n", ret); -+ return; -+ } -+ -+ if (i < PPE_AC_UNICAST_QUEUE_CFG_TBL_ENTRIES) { -+ reg = PPE_AC_UNICAST_QUEUE_CNT_TBL_ADDR + -+ PPE_AC_UNICAST_QUEUE_CNT_TBL_INC * i; -+ ret = regmap_read(ppe_dev->regmap, reg, &val); -+ if (ret) { -+ seq_printf(seq, "ERROR %d\n", ret); -+ return; -+ } -+ -+ pend_cnt = FIELD_GET(PPE_AC_UNICAST_QUEUE_CNT_TBL_PEND_CNT, val); -+ } else { -+ reg = PPE_AC_MULTICAST_QUEUE_CNT_TBL_ADDR + -+ PPE_AC_MULTICAST_QUEUE_CNT_TBL_INC * -+ (i - PPE_AC_UNICAST_QUEUE_CFG_TBL_ENTRIES); -+ ret = regmap_read(ppe_dev->regmap, reg, &val); -+ if (ret) { -+ seq_printf(seq, "ERROR %d\n", ret); -+ return; -+ } -+ -+ pend_cnt = FIELD_GET(PPE_AC_MULTICAST_QUEUE_CNT_TBL_PEND_CNT, val); -+ } -+ -+ if (pkt_cnt > 0 || pend_cnt > 0) { -+ tag++; -+ PRINT_TWO_COUNTERS(tag, pkt_cnt, pend_cnt, "queue", i); -+ } -+ } -+ -+ seq_putc(seq, '\n'); -+} -+ -+/* Display the various packet counters of PPE. */ -+static int ppe_packet_counter_show(struct seq_file *seq, void *v) -+{ -+ struct ppe_device *ppe_dev = seq->private; -+ -+ ppe_port_rx_drop_counter_get(ppe_dev, seq); -+ ppe_port_rx_bm_drop_counter_get(ppe_dev, seq); -+ ppe_port_rx_bm_port_counter_get(ppe_dev, seq); -+ ppe_parse_pkt_counter_get(ppe_dev, seq); -+ ppe_port_rx_counter_get(ppe_dev, seq); -+ ppe_vp_rx_counter_get(ppe_dev, seq); -+ ppe_pre_l2_counter_get(ppe_dev, seq); -+ ppe_vlan_counter_get(ppe_dev, seq); -+ ppe_cpu_code_counter_get(ppe_dev, seq); -+ ppe_eg_vsi_counter_get(ppe_dev, seq); -+ ppe_vp_tx_counter_get(ppe_dev, seq); -+ ppe_port_tx_counter_get(ppe_dev, seq); -+ ppe_queue_tx_counter_get(ppe_dev, seq); -+ -+ return 0; -+} -+ -+static int ppe_packet_counter_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, ppe_packet_counter_show, inode->i_private); -+} -+ -+static ssize_t ppe_packet_counter_clear(struct file *file, -+ const char __user *buf, -+ size_t count, loff_t *pos) -+{ -+ struct ppe_device *ppe_dev = file_inode(file)->i_private; -+ u32 reg; -+ int i; -+ -+ for (i = 0; i < PPE_DROP_CNT_TBL_ENTRIES; i++) { -+ reg = PPE_DROP_CNT_TBL_ADDR + i * PPE_DROP_CNT_TBL_INC; -+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_1WORD); -+ } -+ -+ for (i = 0; i < PPE_DROP_STAT_TBL_ENTRIES; i++) { -+ reg = PPE_DROP_STAT_TBL_ADDR + PPE_DROP_STAT_TBL_INC * i; -+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD); -+ } -+ -+ for (i = 0; i < PPE_IPR_PKT_CNT_TBL_ENTRIES; i++) { -+ reg = PPE_IPR_PKT_CNT_TBL_ADDR + i * PPE_IPR_PKT_CNT_TBL_INC; -+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_1WORD); -+ -+ reg = PPE_TPR_PKT_CNT_TBL_ADDR + i * PPE_TPR_PKT_CNT_TBL_INC; -+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_1WORD); -+ } -+ -+ for (i = 0; i < PPE_VLAN_CNT_TBL_ENTRIES; i++) { -+ reg = PPE_VLAN_CNT_TBL_ADDR + PPE_VLAN_CNT_TBL_INC * i; -+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD); -+ } -+ -+ for (i = 0; i < PPE_PRE_L2_CNT_TBL_ENTRIES; i++) { -+ reg = PPE_PRE_L2_CNT_TBL_ADDR + PPE_PRE_L2_CNT_TBL_INC * i; -+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_5WORD); -+ } -+ -+ for (i = 0; i < PPE_PORT_TX_COUNTER_TBL_ENTRIES; i++) { -+ reg = PPE_PORT_TX_DROP_CNT_TBL_ADDR + PPE_PORT_TX_DROP_CNT_TBL_INC * i; -+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD); -+ -+ reg = PPE_PORT_TX_COUNTER_TBL_ADDR + PPE_PORT_TX_COUNTER_TBL_INC * i; -+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD); -+ } -+ -+ for (i = 0; i < PPE_EG_VSI_COUNTER_TBL_ENTRIES; i++) { -+ reg = PPE_EG_VSI_COUNTER_TBL_ADDR + PPE_EG_VSI_COUNTER_TBL_INC * i; -+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD); -+ } -+ -+ for (i = 0; i < PPE_VPORT_TX_COUNTER_TBL_ENTRIES; i++) { -+ reg = PPE_VPORT_TX_COUNTER_TBL_ADDR + PPE_VPORT_TX_COUNTER_TBL_INC * i; -+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD); -+ -+ reg = PPE_VPORT_TX_DROP_CNT_TBL_ADDR + PPE_VPORT_TX_DROP_CNT_TBL_INC * i; -+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD); -+ } -+ -+ for (i = 0; i < PPE_QUEUE_TX_COUNTER_TBL_ENTRIES; i++) { -+ reg = PPE_QUEUE_TX_COUNTER_TBL_ADDR + PPE_QUEUE_TX_COUNTER_TBL_INC * i; -+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD); -+ } -+ -+ ppe_tbl_pkt_cnt_clear(ppe_dev, PPE_EPE_DBG_IN_CNT_ADDR, PPE_PKT_CNT_SIZE_1WORD); -+ ppe_tbl_pkt_cnt_clear(ppe_dev, PPE_EPE_DBG_OUT_CNT_ADDR, PPE_PKT_CNT_SIZE_1WORD); -+ -+ for (i = 0; i < PPE_DROP_CPU_CNT_TBL_ENTRIES; i++) { -+ reg = PPE_DROP_CPU_CNT_TBL_ADDR + PPE_DROP_CPU_CNT_TBL_INC * i; -+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD); -+ } -+ -+ for (i = 0; i < PPE_PORT_RX_CNT_TBL_ENTRIES; i++) { -+ reg = PPE_PORT_RX_CNT_TBL_ADDR + PPE_PORT_RX_CNT_TBL_INC * i; -+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_5WORD); -+ } -+ -+ for (i = 0; i < PPE_PHY_PORT_RX_CNT_TBL_ENTRIES; i++) { -+ reg = PPE_PHY_PORT_RX_CNT_TBL_ADDR + PPE_PHY_PORT_RX_CNT_TBL_INC * i; -+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_5WORD); -+ } -+ -+ return count; -+} -+ -+static const struct file_operations ppe_debugfs_packet_counter_fops = { -+ .owner = THIS_MODULE, -+ .open = ppe_packet_counter_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+ .write = ppe_packet_counter_clear, -+}; -+ -+void ppe_debugfs_setup(struct ppe_device *ppe_dev) -+{ -+ ppe_dev->debugfs_root = debugfs_create_dir("ppe", NULL); -+ debugfs_create_file("packet_counters", 0444, -+ ppe_dev->debugfs_root, -+ ppe_dev, -+ &ppe_debugfs_packet_counter_fops); -+} -+ -+void ppe_debugfs_teardown(struct ppe_device *ppe_dev) -+{ -+ debugfs_remove_recursive(ppe_dev->debugfs_root); -+ ppe_dev->debugfs_root = NULL; -+} ---- /dev/null -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.h -@@ -0,0 +1,16 @@ -+/* SPDX-License-Identifier: GPL-2.0-only -+ * -+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+/* PPE debugfs counters setup. */ -+ -+#ifndef __PPE_DEBUGFS_H__ -+#define __PPE_DEBUGFS_H__ -+ -+#include "ppe.h" -+ -+void ppe_debugfs_setup(struct ppe_device *ppe_dev); -+void ppe_debugfs_teardown(struct ppe_device *ppe_dev); -+ -+#endif ---- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h -+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h -@@ -16,6 +16,39 @@ - #define PPE_BM_SCH_CTRL_SCH_OFFSET GENMASK(14, 8) - #define PPE_BM_SCH_CTRL_SCH_EN BIT(31) - -+/* PPE drop counters. */ -+#define PPE_DROP_CNT_TBL_ADDR 0xb024 -+#define PPE_DROP_CNT_TBL_ENTRIES 8 -+#define PPE_DROP_CNT_TBL_INC 4 -+ -+/* BM port drop counters. */ -+#define PPE_DROP_STAT_TBL_ADDR 0xe000 -+#define PPE_DROP_STAT_TBL_ENTRIES 30 -+#define PPE_DROP_STAT_TBL_INC 0x10 -+ -+#define PPE_EPE_DBG_IN_CNT_ADDR 0x26054 -+#define PPE_EPE_DBG_OUT_CNT_ADDR 0x26070 -+ -+/* Egress VLAN counters. */ -+#define PPE_EG_VSI_COUNTER_TBL_ADDR 0x41000 -+#define PPE_EG_VSI_COUNTER_TBL_ENTRIES 64 -+#define PPE_EG_VSI_COUNTER_TBL_INC 0x10 -+ -+/* Port TX counters. */ -+#define PPE_PORT_TX_COUNTER_TBL_ADDR 0x45000 -+#define PPE_PORT_TX_COUNTER_TBL_ENTRIES 8 -+#define PPE_PORT_TX_COUNTER_TBL_INC 0x10 -+ -+/* Virtual port TX counters. */ -+#define PPE_VPORT_TX_COUNTER_TBL_ADDR 0x47000 -+#define PPE_VPORT_TX_COUNTER_TBL_ENTRIES 256 -+#define PPE_VPORT_TX_COUNTER_TBL_INC 0x10 -+ -+/* Queue counters. */ -+#define PPE_QUEUE_TX_COUNTER_TBL_ADDR 0x4a000 -+#define PPE_QUEUE_TX_COUNTER_TBL_ENTRIES 300 -+#define PPE_QUEUE_TX_COUNTER_TBL_INC 0x10 -+ - /* RSS settings are to calculate the random RSS hash value generated during - * packet receive to ARM cores. This hash is then used to generate the queue - * offset used to determine the queue used to transmit the packet to ARM cores. -@@ -213,6 +246,51 @@ - #define PPE_L2_PORT_SET_DST_INFO(tbl_cfg, value) \ - u32p_replace_bits((u32 *)tbl_cfg, value, PPE_L2_VP_PORT_W0_DST_INFO) - -+/* Port RX and RX drop counters. */ -+#define PPE_PORT_RX_CNT_TBL_ADDR 0x150000 -+#define PPE_PORT_RX_CNT_TBL_ENTRIES 256 -+#define PPE_PORT_RX_CNT_TBL_INC 0x20 -+ -+/* Physical port RX and RX drop counters. */ -+#define PPE_PHY_PORT_RX_CNT_TBL_ADDR 0x156000 -+#define PPE_PHY_PORT_RX_CNT_TBL_ENTRIES 8 -+#define PPE_PHY_PORT_RX_CNT_TBL_INC 0x20 -+ -+/* Counters for the packet to CPU port. */ -+#define PPE_DROP_CPU_CNT_TBL_ADDR 0x160000 -+#define PPE_DROP_CPU_CNT_TBL_ENTRIES 1280 -+#define PPE_DROP_CPU_CNT_TBL_INC 0x10 -+ -+/* VLAN counters. */ -+#define PPE_VLAN_CNT_TBL_ADDR 0x178000 -+#define PPE_VLAN_CNT_TBL_ENTRIES 64 -+#define PPE_VLAN_CNT_TBL_INC 0x10 -+ -+/* PPE L2 counters. */ -+#define PPE_PRE_L2_CNT_TBL_ADDR 0x17c000 -+#define PPE_PRE_L2_CNT_TBL_ENTRIES 64 -+#define PPE_PRE_L2_CNT_TBL_INC 0x20 -+ -+/* Port TX drop counters. */ -+#define PPE_PORT_TX_DROP_CNT_TBL_ADDR 0x17d000 -+#define PPE_PORT_TX_DROP_CNT_TBL_ENTRIES 8 -+#define PPE_PORT_TX_DROP_CNT_TBL_INC 0x10 -+ -+/* Virtual port TX counters. */ -+#define PPE_VPORT_TX_DROP_CNT_TBL_ADDR 0x17e000 -+#define PPE_VPORT_TX_DROP_CNT_TBL_ENTRIES 256 -+#define PPE_VPORT_TX_DROP_CNT_TBL_INC 0x10 -+ -+/* Counters for the tunnel packet. */ -+#define PPE_TPR_PKT_CNT_TBL_ADDR 0x1d0080 -+#define PPE_TPR_PKT_CNT_TBL_ENTRIES 8 -+#define PPE_TPR_PKT_CNT_TBL_INC 4 -+ -+/* Counters for the all packet received. */ -+#define PPE_IPR_PKT_CNT_TBL_ADDR 0x1e0080 -+#define PPE_IPR_PKT_CNT_TBL_ENTRIES 8 -+#define PPE_IPR_PKT_CNT_TBL_INC 4 -+ - /* PPE service code configuration for the tunnel packet. */ - #define PPE_TL_SERVICE_TBL_ADDR 0x306000 - #define PPE_TL_SERVICE_TBL_ENTRIES 256 -@@ -325,6 +403,18 @@ - #define PPE_BM_PORT_GROUP_ID_INC 0x4 - #define PPE_BM_PORT_GROUP_ID_SHARED_GROUP_ID GENMASK(1, 0) - -+/* Counters for PPE buffers used for packets cached. */ -+#define PPE_BM_USED_CNT_TBL_ADDR 0x6001c0 -+#define PPE_BM_USED_CNT_TBL_ENTRIES 15 -+#define PPE_BM_USED_CNT_TBL_INC 0x4 -+#define PPE_BM_USED_CNT_VAL GENMASK(10, 0) -+ -+/* Counters for PPE buffers used for packets received after pause frame sent. */ -+#define PPE_BM_REACT_CNT_TBL_ADDR 0x600240 -+#define PPE_BM_REACT_CNT_TBL_ENTRIES 15 -+#define PPE_BM_REACT_CNT_TBL_INC 0x4 -+#define PPE_BM_REACT_CNT_VAL GENMASK(8, 0) -+ - #define PPE_BM_SHARED_GROUP_CFG_ADDR 0x600290 - #define PPE_BM_SHARED_GROUP_CFG_ENTRIES 4 - #define PPE_BM_SHARED_GROUP_CFG_INC 0x4 -@@ -449,6 +539,18 @@ - #define PPE_AC_GRP_SET_BUF_LIMIT(tbl_cfg, value) \ - u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_AC_GRP_W1_BUF_LIMIT) - -+/* Counters for packets handled by unicast queues (0-255). */ -+#define PPE_AC_UNICAST_QUEUE_CNT_TBL_ADDR 0x84e000 -+#define PPE_AC_UNICAST_QUEUE_CNT_TBL_ENTRIES 256 -+#define PPE_AC_UNICAST_QUEUE_CNT_TBL_INC 0x10 -+#define PPE_AC_UNICAST_QUEUE_CNT_TBL_PEND_CNT GENMASK(12, 0) -+ -+/* Counters for packets handled by multicast queues (256-299). */ -+#define PPE_AC_MULTICAST_QUEUE_CNT_TBL_ADDR 0x852000 -+#define PPE_AC_MULTICAST_QUEUE_CNT_TBL_ENTRIES 44 -+#define PPE_AC_MULTICAST_QUEUE_CNT_TBL_INC 0x10 -+#define PPE_AC_MULTICAST_QUEUE_CNT_TBL_PEND_CNT GENMASK(12, 0) -+ - /* Table addresses for per-queue enqueue setting. */ - #define PPE_ENQ_OPR_TBL_ADDR 0x85c000 - #define PPE_ENQ_OPR_TBL_ENTRIES 300