From patchwork Sun Feb 9 14:29:35 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luo Jie X-Patchwork-Id: 863615 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CB2FAE56F; Sun, 9 Feb 2025 14:30:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739111432; cv=none; b=oBHx5laXEG4VZIAU8Bm9TSADWI2qrC5FQY2XrOL4Obxtn8IpsHEI+mLq50dxrYERCbkY/gmkABlrl1fFVqOJT4lhxugvZvQPpT7WoHPpl9Rc9y6F90Tb/pv1WqMbhxTj6RfCU4v9UcpsnSDjcUXqWQHSbEAIJ/2Ngxr/AIV2UCo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739111432; c=relaxed/simple; bh=0XrgztS2108myfypPQeLtIp1PT6ZdaN8vDf3md1xU3k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=S0zK3Uc8gmJvILgpNBWB5PesYHZN1/kXutWc/Zb5f+3xzLcs2bK10Mhhu5AUTU4uXqJo2QIWFF8lGUeTl/gQ4J4VZ9b/wJ2XKw0vC58wrm30PjctrickT6+hw609UF/fU8Di+ujFb7iUNI63dXiF8+COdrEHTvE0QYrldsW67oM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=Cl+rFGHG; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="Cl+rFGHG" Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 519DmUxE006135; Sun, 9 Feb 2025 14:30:16 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= qoks8AbRHk1IHI95zXn4a7Hcm5F30cBaTJyE5sPhZYg=; b=Cl+rFGHG+zbcThPc dlk2xp4g1reBtvDuhuWWpvPT5jc6CsFm7DdrRo7lR4oE0Ja/oLt9uM/UKHrGcMF9 +adWrHbwkrsS3b7Y8pOwK+wmAo7voGY9daVbaq6xCmKXZP2krW/VtZzAqb34SqIO zjrxwK4PxgYXCFP/Xbj4nmbZr0tkExeCfOt4xQBx4o32USHr9zBOPxee8tRHZDff ocghwJ+JG1VS0Hn1xpVAyn0Z0oi+46TxY00mZ6RVucPLdENCYYfaLL8wiSWdnidu +6dgFLKbDbfUi1W1hzLBnQqWxg3KzLzYzbhgRIKTX4Ym0UVG48Ra8fMW8TOxn+8t JtAePQ== Received: from nasanppmta03.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44p0dyj27f-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 09 Feb 2025 14:30:15 +0000 (GMT) Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA03.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 519EU0CV021675 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 9 Feb 2025 14:30:00 GMT Received: from nsssdc-sh01-lnx.ap.qualcomm.com (10.80.80.8) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Sun, 9 Feb 2025 06:29:54 -0800 From: Luo Jie Date: Sun, 9 Feb 2025 22:29:35 +0800 Subject: [PATCH net-next v3 01/14] dt-bindings: net: Add PPE for Qualcomm IPQ9574 SoC Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20250209-qcom_ipq_ppe-v3-1-453ea18d3271@quicinc.com> References: <20250209-qcom_ipq_ppe-v3-0-453ea18d3271@quicinc.com> In-Reply-To: <20250209-qcom_ipq_ppe-v3-0-453ea18d3271@quicinc.com> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Lei Wei , Suruchi Agarwal , Pavithra R , "Simon Horman" , Jonathan Corbet , Kees Cook , "Gustavo A. R. Silva" , "Philipp Zabel" CC: , , , , , , , , , , , Luo Jie X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1739111388; l=17301; i=quic_luoj@quicinc.com; s=20250209; h=from:subject:message-id; bh=0XrgztS2108myfypPQeLtIp1PT6ZdaN8vDf3md1xU3k=; b=IVhJBOV72KfyYVtkGASjiH7CB8BKH3B0y9B5LC1PSt271UDlBbdzroqQIHNYkscmzCyRkHDyD cbtnKvMUcMhDmDr4fGnpExsFt9euBLlAZR8HNP3srXqKAjZ6je+98+m X-Developer-Key: i=quic_luoj@quicinc.com; a=ed25519; pk=pzwy8bU5tJZ5UKGTv28n+QOuktaWuriznGmriA9Qkfc= X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: otPgi0IcI_c8O4JLB376_A88ZWRnMEXn X-Proofpoint-GUID: otPgi0IcI_c8O4JLB376_A88ZWRnMEXn X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-02-09_06,2025-02-07_03,2024-11-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 bulkscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 mlxlogscore=999 mlxscore=0 priorityscore=1501 spamscore=0 adultscore=0 phishscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2501170000 definitions=main-2502090129 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 --- .../devicetree/bindings/net/qcom,ipq9574-ppe.yaml | 406 +++++++++++++++++++++ 1 file changed, 406 insertions(+) diff --git a/Documentation/devicetree/bindings/net/qcom,ipq9574-ppe.yaml b/Documentation/devicetree/bindings/net/qcom,ipq9574-ppe.yaml new file mode 100644 index 000000000000..be6f9311eebb --- /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"; + }; + }; + }; From patchwork Sun Feb 9 14:29:37 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luo Jie X-Patchwork-Id: 863614 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D35061DE4C7; Sun, 9 Feb 2025 14:30:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739111433; cv=none; b=XZGEq8PfHtpN+DFgUnUMSSoB0F/DEUamhUFDDJtjWTpkNDCRVwiI8Msp/vrPgSSC2LQY5MYfqEwKIS6H6KPXSALhBjxHdeul03LYFRzPf1tmiePlTzpPaKiN7p/Utf/sBmUV+Dq3O4XIUgdVkryWaolufPV0xAcguhaosh1Zc1U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739111433; c=relaxed/simple; bh=NW8YrOjm3ufGiO/XWC3WjfxzSmTah3mqD8eXlUgoHZo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=DRaF9dqrndVSgyDpUd1jgD7XCqoBSr6m9JS8YJ/9ENIxsVMKFOesV0Yup6cj7nHF4N3+ZcV1cScASjTbZBzfgdJdPW4sdEUz2HQzWWIvQ0aB3A3aSyh9M8SRpFhsUr9o4KzPm/DY5Oair77IdIjgHx7c3pMYbFQca/f563QT188= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=KpMJTwEv; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="KpMJTwEv" Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 519CuAvh015554; Sun, 9 Feb 2025 14:30:17 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= d5AZ6DyNi/E6Xk4/Je0WW91xCbySyFZYV1ssIoTZvfA=; b=KpMJTwEvfnT/JqrE zAPgBaVeGCGTGbmP6V6ZI9uBO7gmiRzBNcwU+R216pK6h6fZbziB52uDpqYl/lg/ fE8ebWsR/zS0YwVguLUCQ6y+7dgTMY2Jh5103KQfgxP7RkNjpTzasxNqHZL8iM3C U1Vl4u4bMycaUdN0T6nmJ7AdIuxpVFkG7SHZ0XgqVnMhGYtdYCe4wwZYvlZnLvu/ MhOCz40nc02W9s1K/a5o7FpdX3BZKt5P8zFlc/W/CZMXzfXTDbKefHz9froZS3dj Ot+6gnZajzDnmGPNIl/HTMeMNqNXFSCDmU7dK2rqsEMx7QElSIw34Z29QmVzG9+C 15F3XQ== Received: from nasanppmta04.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44p0esa3k1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 09 Feb 2025 14:30:17 +0000 (GMT) Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA04.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 519EUBBv014405 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 9 Feb 2025 14:30:11 GMT Received: from nsssdc-sh01-lnx.ap.qualcomm.com (10.80.80.8) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Sun, 9 Feb 2025 06:30:05 -0800 From: Luo Jie Date: Sun, 9 Feb 2025 22:29:37 +0800 Subject: [PATCH net-next v3 03/14] net: ethernet: qualcomm: Add PPE driver for IPQ9574 SoC Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20250209-qcom_ipq_ppe-v3-3-453ea18d3271@quicinc.com> References: <20250209-qcom_ipq_ppe-v3-0-453ea18d3271@quicinc.com> In-Reply-To: <20250209-qcom_ipq_ppe-v3-0-453ea18d3271@quicinc.com> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Lei Wei , Suruchi Agarwal , Pavithra R , "Simon Horman" , Jonathan Corbet , Kees Cook , "Gustavo A. R. Silva" , "Philipp Zabel" CC: , , , , , , , , , , , Luo Jie X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1739111388; l=10782; i=quic_luoj@quicinc.com; s=20250209; h=from:subject:message-id; bh=NW8YrOjm3ufGiO/XWC3WjfxzSmTah3mqD8eXlUgoHZo=; b=u0/x09mD6ftH3rt16ByCbmE0xsrBxO1rVI2oz8Pk4bzvjBGH74PAAF+Iacxl5kFeuoVe0QgvD 1jy7ytQWq2PANXZRhM1ifqddMm6UXQ9MvJ0epFvzZ9XoH64xmmepwf0 X-Developer-Key: i=quic_luoj@quicinc.com; a=ed25519; pk=pzwy8bU5tJZ5UKGTv28n+QOuktaWuriznGmriA9Qkfc= X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: YoQqfjAkF5NMC49719BJiccKWimSSHGs X-Proofpoint-ORIG-GUID: YoQqfjAkF5NMC49719BJiccKWimSSHGs X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-02-09_06,2025-02-07_03,2024-11-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 clxscore=1015 suspectscore=0 lowpriorityscore=0 malwarescore=0 bulkscore=0 priorityscore=1501 mlxscore=0 adultscore=0 spamscore=0 mlxlogscore=999 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2501170000 definitions=main-2502090129 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(+) diff --git a/drivers/net/ethernet/qualcomm/Kconfig b/drivers/net/ethernet/qualcomm/Kconfig index 9210ff360fdc..59931c4edbeb 100644 --- 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 diff --git a/drivers/net/ethernet/qualcomm/Makefile b/drivers/net/ethernet/qualcomm/Makefile index 9250976dd884..166a59aea363 100644 --- 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/ diff --git a/drivers/net/ethernet/qualcomm/ppe/Makefile b/drivers/net/ethernet/qualcomm/ppe/Makefile new file mode 100644 index 000000000000..63d50d3b4f2e --- /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 diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe.c b/drivers/net/ethernet/qualcomm/ppe/ppe.c new file mode 100644 index 000000000000..40da7d240594 --- /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_enabled(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"); diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe.h b/drivers/net/ethernet/qualcomm/ppe/ppe.h new file mode 100644 index 000000000000..cc6767b7c2b8 --- /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 From patchwork Sun Feb 9 14:29:39 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luo Jie X-Patchwork-Id: 863613 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7B1301E22FC; Sun, 9 Feb 2025 14:30:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739111440; cv=none; b=Jc8+SeLBekkHlod52YkSoz6vfoQeKUPk/hHxI4zrcwOlcMxGgQd2OaOBbgaRImm8yWWQ8okyIQeGKmnYi+KKx4kBDClrtRxrhirsSmcCM75EOnUSoi4n+RVtR9PSkPFcuHeAiUVx85myzSSyt4ksqvmrdLrGIuThtE4OsyURemM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739111440; c=relaxed/simple; bh=pEmll+esWWtp1bpfs2x8cZ3Tdw9UjtDCWRxu/pcViC4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=PjP6XkkOA/0F9H/AQwyVSoNL7D4Pwq6DIMOSIRiOF6v8zYc7dJG3oa0Y15+I/x3si7oFuDe+Q+yifwlU2sXOkfAe6nYOG9IbyusY9LLOQsUpBqWMnHjzDrx3ocRfJT8VQDQ2vyBetH/EG1P6L5FJCHuYiR6G33g0TB3riI2p3/c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=SDK/kj+W; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="SDK/kj+W" Received: from pps.filterd (m0279866.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 519DUmbT023168; Sun, 9 Feb 2025 14:30:23 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= kd6L5yuaZfJhL8y2TiqrbkG8GCGVi0EyPNABQHqu0WM=; b=SDK/kj+WZYaAR33B nrgmr0x7dM17vF8/20yhbT5Nx0m8KVk9+fG9v+bkOh4azg3ymy4qWqxTEcjU+AqW 9RaSeTZHlJplfmeczdtDAoi0COQ4rhuWry6yFg46j4+WJINNX8zb13DiyIR0VS80 vp+I5hYfT8E8J7Mxm+CrmmWkRrDtvf853zi0omgG12gvK2b2ScD5ss53xzXdaQul pHzIAlN0HKmTV0Xoqu5FMrBNSk8FbuqQxGCrtSEru5mbzx8lidGePHcDO7OB/vlH 1ki+LBLKqgB6M454wEnwGhktRm6UCqtgfkU6jr/BBAyEBvLiKnRwLW+DM6pDgANX xDkSHA== Received: from nasanppmta03.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44p0kaj36p-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 09 Feb 2025 14:30:23 +0000 (GMT) Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA03.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 519EUM2r022796 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 9 Feb 2025 14:30:22 GMT Received: from nsssdc-sh01-lnx.ap.qualcomm.com (10.80.80.8) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Sun, 9 Feb 2025 06:30:17 -0800 From: Luo Jie Date: Sun, 9 Feb 2025 22:29:39 +0800 Subject: [PATCH net-next v3 05/14] net: ethernet: qualcomm: Initialize PPE queue management for IPQ9574 Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20250209-qcom_ipq_ppe-v3-5-453ea18d3271@quicinc.com> References: <20250209-qcom_ipq_ppe-v3-0-453ea18d3271@quicinc.com> In-Reply-To: <20250209-qcom_ipq_ppe-v3-0-453ea18d3271@quicinc.com> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Lei Wei , Suruchi Agarwal , Pavithra R , "Simon Horman" , Jonathan Corbet , Kees Cook , "Gustavo A. R. Silva" , "Philipp Zabel" CC: , , , , , , , , , , , Luo Jie X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1739111388; l=12236; i=quic_luoj@quicinc.com; s=20250209; h=from:subject:message-id; bh=pEmll+esWWtp1bpfs2x8cZ3Tdw9UjtDCWRxu/pcViC4=; b=lL5KLkNrNfPouIkjMk9ZqJKwcSrAEiIL/VuXmwAqx8yyIS5n7IcBkAXNiznO1g7Y/OJqbh3m+ /aIErcDITH0Apad59WqDwcSeapTzCisJa7xEumjqLlkzRdyHroUdmxo X-Developer-Key: i=quic_luoj@quicinc.com; a=ed25519; pk=pzwy8bU5tJZ5UKGTv28n+QOuktaWuriznGmriA9Qkfc= X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: -2LXmoSOFL6Ncgn3lMFFy6yS_RpHsLMa X-Proofpoint-ORIG-GUID: -2LXmoSOFL6Ncgn3lMFFy6yS_RpHsLMa X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-02-09_06,2025-02-07_03,2024-11-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 mlxscore=0 suspectscore=0 impostorscore=0 adultscore=0 lowpriorityscore=0 priorityscore=1501 bulkscore=0 phishscore=0 mlxlogscore=999 spamscore=0 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2501170000 definitions=main-2502090129 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 --- drivers/net/ethernet/qualcomm/ppe/ppe_config.c | 177 ++++++++++++++++++++++++- drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 85 ++++++++++++ 2 files changed, 261 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c index 18e9544a4e37..d55e99656271 100644 --- 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 ipq9574_ppe_bm_port_config[] = { }, }; +/* 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 @@ static int ppe_config_bm(struct ppe_device *ppe_dev) 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); } diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h index b00f77ec45fe..6eac3ab8e58b 100644 --- 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 From patchwork Sun Feb 9 14:29:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luo Jie X-Patchwork-Id: 863612 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 303421E32DA; Sun, 9 Feb 2025 14:30:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739111451; cv=none; b=XpDrLreiHfhVFFLEfa4GnrMREHqdKOgPEwlVhuWCoX3YXiuJ1BtBQQs6AD2sjpxyTcq6SkySUuRuMrvbM6p/gXbA0BLgab1HSXyjmN7xUWXOiebxfeJpeUtSUPXacMPqDYhiw+GHyHG2QD/mXaLCySsN9fjQc7ZejMZifCkqCq4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739111451; c=relaxed/simple; bh=qvHnVSI4d9CBee2NX3NKuGaXLDSm3tYyWRDMbXGzfI0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=lOrARfDinnbQO6zHG/A9r6RsQhkXTXZREQxZBAfqBEoJXA2G3ZXrEQfDT2sLz2yrBj2WqRrYHozLnFD5R4oifm4GAmXcWUnBb8meOkfhxC5Dur2AZTUA+7Op1FMehDxFXNcuI8kk/JYLO0qO4jcX8tJuJdb8nneV9t9rpcwdtbI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=FF4nCtWD; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="FF4nCtWD" Received: from pps.filterd (m0279866.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 5199fmHm031005; Sun, 9 Feb 2025 14:30:34 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= B0to1j9rb+mhPWbfyThWAdNgByIEKXMmiJjxGk4oh6s=; b=FF4nCtWDlDPvHfwu zABjbaXvsPagC725/ZNYO/m5k4pJ5+SZHYWz7hi4Asv2GJbbjVkCFau1VmjmNb8m 9hFfHsLlZT9WIUfx4ZQs8wIeAqa6PcqvuLQdNf1PMOwKGCyUM32GN9jWJ7JZNaRY e24Rmdf9sbF8PfhsgzbhMLn4dq+9o0iaqEoDgFXpThUw8ie3ccNRrsZDa3UoDiEH ztYs2CJNwTjfoGl2rsD0UBm6lG9suKz24Vq54VRUM/BeB9qSvt6US8ERCK7YjntB gd3PcCaFtX594gaP06cZD2cuuVeNVO468b1rRrgtGH4YlUf4QOMHB9/vK3MVuu+7 O8mEkQ== Received: from nasanppmta03.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44p0kaj373-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 09 Feb 2025 14:30:34 +0000 (GMT) Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA03.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 519EUXGu023304 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 9 Feb 2025 14:30:34 GMT Received: from nsssdc-sh01-lnx.ap.qualcomm.com (10.80.80.8) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Sun, 9 Feb 2025 06:30:28 -0800 From: Luo Jie Date: Sun, 9 Feb 2025 22:29:41 +0800 Subject: [PATCH net-next v3 07/14] net: ethernet: qualcomm: Initialize PPE queue settings Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20250209-qcom_ipq_ppe-v3-7-453ea18d3271@quicinc.com> References: <20250209-qcom_ipq_ppe-v3-0-453ea18d3271@quicinc.com> In-Reply-To: <20250209-qcom_ipq_ppe-v3-0-453ea18d3271@quicinc.com> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Lei Wei , Suruchi Agarwal , Pavithra R , "Simon Horman" , Jonathan Corbet , Kees Cook , "Gustavo A. R. Silva" , "Philipp Zabel" CC: , , , , , , , , , , , Luo Jie X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1739111388; l=16322; i=quic_luoj@quicinc.com; s=20250209; h=from:subject:message-id; bh=qvHnVSI4d9CBee2NX3NKuGaXLDSm3tYyWRDMbXGzfI0=; b=AtX5qqpLRUoevmIB0O2bvqGN0umiIrKSJ1pWUFHx4K8U6uS9+D+2AX5cEKFOXptRJxzlw5VQz L1i6G7YzzAtAVe6XLP7sfkL1mtrQMf4knv7dOQbDDdThkpOpPBeQ4FT X-Developer-Key: i=quic_luoj@quicinc.com; a=ed25519; pk=pzwy8bU5tJZ5UKGTv28n+QOuktaWuriznGmriA9Qkfc= X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: Nl4-k3W337FucM41nqL50k303chXOzo1 X-Proofpoint-ORIG-GUID: Nl4-k3W337FucM41nqL50k303chXOzo1 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-02-09_06,2025-02-07_03,2024-11-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 mlxscore=0 suspectscore=0 impostorscore=0 adultscore=0 lowpriorityscore=0 priorityscore=1501 bulkscore=0 phishscore=0 mlxlogscore=999 spamscore=0 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2501170000 definitions=main-2502090129 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 --- drivers/net/ethernet/qualcomm/ppe/ppe_config.c | 356 ++++++++++++++++++++++++- drivers/net/ethernet/qualcomm/ppe/ppe_config.h | 63 +++++ drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 21 ++ 3 files changed, 439 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c index e5bea9a28a5d..e23a8984af8e 100644 --- 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_config ppe_port_sch_config[] = { }, }; +/* 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_device *ppe_dev, 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 @@ static int ppe_config_scheduler(struct ppe_device *ppe_dev) 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_dev) 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); } diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h index f28cfe7e1548..6553da34effe 100644 --- 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 diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h index 4c832179d539..0232f23dcefe 100644 --- 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 From patchwork Sun Feb 9 14:29:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luo Jie X-Patchwork-Id: 863611 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 176A51DFD85; Sun, 9 Feb 2025 14:30:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739111461; cv=none; b=Z0dsPW5GVJmEg3qiA7W1/Lpy0JWKotRy8nUUNe80MRxQljcp2nYvDGkqehcXLMJ7B80Y6n235l8zitnO2naheOi754uAFwCxd6rn/faYIIaGZSoGRLFltVCirxFE+dcA2QsxlrJlBe+AZzs5kX3QmGbuahjI8D4Gc0dAQ4EqX60= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739111461; c=relaxed/simple; bh=w2hSM5r3+R0JKwEE2GmP4l7X/Sznl49r85p9ET/H87Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=QDsl7KyzlADQtiJbz6a6FNBiX/cNVepLCtAk25DDMewHMGI3MoNf8pR58n0FNL22uCUjlxmY1vggkpzq/6zZC3eVcjI5iOc1eU7D3IdKRc1KgTiQcCWfmnFhRnHFvWKQhlE4wuHqohudIJGCefnoQZB0O25xQYwHEcN2SBcDtvk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=YVdVxpgL; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="YVdVxpgL" Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 519EBpNx013138; Sun, 9 Feb 2025 14:30:46 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= CVx6vax/wRvZmbZ6wp0f+zB6/dD/eZSuhHwUbqTb7AE=; b=YVdVxpgLBbVFn+O6 So1pIpXEc+4lsCohZa42LM+YbkaTo7M+Z3Yb+shSlZhlpnowcUeNy7KZdmmDaXss 1yWYTFQ+6l67ZtHNI5p99D2HnqbYy9A59xzepj46T6/dPBefPeKmZoBcNAAJBKAT h0CFUB2L4JOjYOMCP3TifuIzxV/h4xSmRMTgAVisaytkXV9wJ60snII9MUeaFug2 lLp6+4J7XmVpEafnAPF4/PI984vWcKttsF13zmE/42MCRon/HxqC9r+FuHIRSVi2 oOWb9scr1odxADqwAs7nBzGqoKMM453UevxcD2HWQ8cFBPCswPyADxBCkUFBaJWv 9Oj/9Q== Received: from nasanppmta04.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44p0dyj28u-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 09 Feb 2025 14:30:45 +0000 (GMT) Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA04.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 519EUjQD014994 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 9 Feb 2025 14:30:45 GMT Received: from nsssdc-sh01-lnx.ap.qualcomm.com (10.80.80.8) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Sun, 9 Feb 2025 06:30:39 -0800 From: Luo Jie Date: Sun, 9 Feb 2025 22:29:43 +0800 Subject: [PATCH net-next v3 09/14] net: ethernet: qualcomm: Initialize PPE port control settings Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20250209-qcom_ipq_ppe-v3-9-453ea18d3271@quicinc.com> References: <20250209-qcom_ipq_ppe-v3-0-453ea18d3271@quicinc.com> In-Reply-To: <20250209-qcom_ipq_ppe-v3-0-453ea18d3271@quicinc.com> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Lei Wei , Suruchi Agarwal , Pavithra R , "Simon Horman" , Jonathan Corbet , Kees Cook , "Gustavo A. R. Silva" , "Philipp Zabel" CC: , , , , , , , , , , , Luo Jie X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1739111388; l=8604; i=quic_luoj@quicinc.com; s=20250209; h=from:subject:message-id; bh=w2hSM5r3+R0JKwEE2GmP4l7X/Sznl49r85p9ET/H87Q=; b=drxAJLYEF/TbycFVUsmKv45ILIpf8Gjq3SnGjOnzoZtor2rmsRpG1osHB1BWXY6ZHYWo+DiK8 H30nelGYK3hCFXxegV0MVrBFRyaOIYi+kTR9xwi5lh4EW4KvrIiWOfI X-Developer-Key: i=quic_luoj@quicinc.com; a=ed25519; pk=pzwy8bU5tJZ5UKGTv28n+QOuktaWuriznGmriA9Qkfc= X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: Ew-7ykHESdFhk_DRRkkGbYWaTRe8kCIp X-Proofpoint-GUID: Ew-7ykHESdFhk_DRRkkGbYWaTRe8kCIp X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-02-09_06,2025-02-07_03,2024-11-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 bulkscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 mlxlogscore=999 mlxscore=0 priorityscore=1501 spamscore=0 adultscore=0 phishscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2501170000 definitions=main-2502090129 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 --- drivers/net/ethernet/qualcomm/ppe/ppe_config.c | 86 +++++++++++++++++++++++++- drivers/net/ethernet/qualcomm/ppe/ppe_config.h | 15 +++++ drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 47 ++++++++++++++ 3 files changed, 147 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c index fc6d887d0feb..d7b0cabe63ed 100644 --- 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 *ppe_dev, int sc, struct ppe_sc_cfg cfg) 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_device *ppe_dev) 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_dev) 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); } diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h index 374635009ae3..277a77257b85 100644 --- 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_device *ppe_dev, int port, 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 diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h index 80f003afad78..e4596ffe04f6 100644 --- 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 From patchwork Sun Feb 9 14:29:45 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luo Jie X-Patchwork-Id: 863610 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D952D1E98E3; Sun, 9 Feb 2025 14:31:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739111474; cv=none; b=Nz6UGrb0sLs+H151Nby33XdWwucw0hVNgV05YeQCulm0XONnYSnNkbjvxzL/6EAZi+uuv8hb7qXCbKEnrd48Czd8rcs+MfU+oRFz8LXog2Jaj9fstezjN1QP6dm0TtMInyqddf9gnOrwUvVhbod6u6/3WMtNvLAX6iUdv86DgKM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739111474; c=relaxed/simple; bh=nSldvyYvVFvnbaFvZYjCZhhS3X2enuEHZArB5Uadi8A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=SOOGg3nYeAjkfEWelRW1hkN0V7gwrtejzv/IqK0DSDci0EzCh4eI1GIW1ILVC0T0d/H4Pm4Xko2cG/s96bh3ZMHBLQv5FsPRF/9tI6bR21GBBeKPoE3ju0Pyt7Y5tisNqfABT39v6DrNHVY9AP1sxq6Mwjg+hmSNK63K2vcYDpo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=Zzh0gA+C; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="Zzh0gA+C" Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 5197sfSX012709; Sun, 9 Feb 2025 14:30:57 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= +b+DOsqKfuWDmppWRXqfaKyaZq8yaEGS27rzw9EyTZQ=; b=Zzh0gA+CjFiWy5vK R7yBXojSPV2WH+kPB2svmU8bWAZDsQPVahfaTaJm3DzN5WWo2Ukg0b7/U+QsMkQu oheyH5dq0TLQwVTRPZ9EtXPJbtP1c07ml/S0fCOW9moBS3oAfnuuVDkjeM7tCHBF y2aAkuxRHI4lbwIHJjRY/lZNluAYlYecc/fhliqAYTmYp5I1rIIWmKgTFVBJVozk vDqjOOV/J9FrHSnjiz70JD/8ChESRU1+H/8mWKi5uhIKf6DCAVYS77OuaRKIPSRU yZh1sCN1kjPGLDrq8oCktKJCNXTzJCznxWkgzEHAPVX+m/vgj6c4Fh/Jo85O77Dc AokfQQ== Received: from nasanppmta01.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44p0dxa434-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 09 Feb 2025 14:30:57 +0000 (GMT) Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA01.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 519EUuHl026954 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 9 Feb 2025 14:30:56 GMT Received: from nsssdc-sh01-lnx.ap.qualcomm.com (10.80.80.8) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Sun, 9 Feb 2025 06:30:50 -0800 From: Luo Jie Date: Sun, 9 Feb 2025 22:29:45 +0800 Subject: [PATCH net-next v3 11/14] net: ethernet: qualcomm: Initialize PPE queue to Ethernet DMA ring mapping Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20250209-qcom_ipq_ppe-v3-11-453ea18d3271@quicinc.com> References: <20250209-qcom_ipq_ppe-v3-0-453ea18d3271@quicinc.com> In-Reply-To: <20250209-qcom_ipq_ppe-v3-0-453ea18d3271@quicinc.com> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Lei Wei , Suruchi Agarwal , Pavithra R , "Simon Horman" , Jonathan Corbet , Kees Cook , "Gustavo A. R. Silva" , "Philipp Zabel" CC: , , , , , , , , , , , Luo Jie X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1739111388; l=4626; i=quic_luoj@quicinc.com; s=20250209; h=from:subject:message-id; bh=nSldvyYvVFvnbaFvZYjCZhhS3X2enuEHZArB5Uadi8A=; b=V93VyVeq6Y6rB5R6bDUuiOBxdn/QS6tgzEquEaW6ftWoOpB9SCSe7cKKwyxPg63SqTSMv4hrB TkUEpHgEXkPBS5EOtCpjT+TtiugD7eRZnNlUK/7WiWikj+uEJeXW5Pm X-Developer-Key: i=quic_luoj@quicinc.com; a=ed25519; pk=pzwy8bU5tJZ5UKGTv28n+QOuktaWuriznGmriA9Qkfc= X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: alluo5Gi8Deqi0JinXhwN_LZO0dZTONE X-Proofpoint-ORIG-GUID: alluo5Gi8Deqi0JinXhwN_LZO0dZTONE X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-02-09_06,2025-02-07_03,2024-11-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxlogscore=999 impostorscore=0 malwarescore=0 priorityscore=1501 suspectscore=0 clxscore=1015 mlxscore=0 bulkscore=0 lowpriorityscore=0 adultscore=0 phishscore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2501170000 definitions=main-2502090129 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 --- drivers/net/ethernet/qualcomm/ppe/ppe_config.c | 47 +++++++++++++++++++++++++- drivers/net/ethernet/qualcomm/ppe/ppe_config.h | 6 ++++ drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 5 +++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c index d9dda7102a28..cf4d653bcfc5 100644 --- 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_device *ppe_dev, int mode, 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_device *ppe_dev) 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_dev) 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); } diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h index fedcb9d9602f..6383f399df54 100644 --- 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 *ppe_dev, int sc, 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 diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h index 5aa46c41e066..da55b06b30b8 100644 --- 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 From patchwork Sun Feb 9 14:29:47 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luo Jie X-Patchwork-Id: 863609 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1E5AF1E0B7D; Sun, 9 Feb 2025 14:31:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739111485; cv=none; b=AKKiyzihOZ45ukUPUmkRCMn/YbDdWpfb0Y9YokViDCvcgLk/Mohd6osxJfN4JrVeoc89W/vx0zbn3UhKTf8Krh8Hg5yHIj+71v+hfp1f4LsULUv1PPEq4X67qV04pnVkilyTbqUGOi5AiN5YCN+2YihtOHxoFfKt0+sqWQigX/E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739111485; c=relaxed/simple; bh=PldDsk/c+6uM+EkeLMZWH20Gsr8jfwa9QBMwJcxqMeg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=d+/hKf6CgPbwQ8sRTMDaN077Yi5B0PW0n8/MK1OJR3nEa+Pic4Y+W8H8toNzILBxlXQLS3CEUcRZRViWrsgSu4HpJ0u9ACCxG4UtO9xEZJZdm0s0ZdaAJjy+yy+oC9+vdBt7w/EFfDcfXWDWYRgjIEq03GcN3LpBNcP+RX18LOo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=S/HDrVnU; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="S/HDrVnU" Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 5199waHu017457; Sun, 9 Feb 2025 14:31:08 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= CqmW47WivgmHAqaEI/dVf3W4jm0OE42gRpE5e85tc90=; b=S/HDrVnUaiQLGCh4 JP7wBLorjr+Qb9CzvC2Zx9C1L2gEBCPf5g/f2jua7xeeH4wU0JI2z8AXnyQTW5tb gkZwnUQoz/jVZU6aeXaTCcrRUu1fOKS4yn9zcw5jHq3e4tbK7dbVJ+cZEYGo6Vr/ rB/rMgmmK0EhoqjhoHBhEbKmX0+zuQw74iWwx7rXsHZ4iSzgYUTlfIMXBkUL8VbI FRgzG8fIxv8/aE+UWSDxsJgAWV/MNpC7QrB1di8EC2QcQDwzAx1zZF6bUbUEPGMV EmnpK+FXkjVWePZE2KmmeEXW+FeEMllTON2VRK/ayKFHaPE/ZA5pSoPVkegfb4qN c31nbQ== Received: from nasanppmta05.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44p0g8t3bf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 09 Feb 2025 14:31:07 +0000 (GMT) Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA05.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 519EV7ZX007554 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 9 Feb 2025 14:31:07 GMT Received: from nsssdc-sh01-lnx.ap.qualcomm.com (10.80.80.8) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Sun, 9 Feb 2025 06:31:01 -0800 From: Luo Jie Date: Sun, 9 Feb 2025 22:29:47 +0800 Subject: [PATCH net-next v3 13/14] net: ethernet: qualcomm: Add PPE debugfs support for PPE counters Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20250209-qcom_ipq_ppe-v3-13-453ea18d3271@quicinc.com> References: <20250209-qcom_ipq_ppe-v3-0-453ea18d3271@quicinc.com> In-Reply-To: <20250209-qcom_ipq_ppe-v3-0-453ea18d3271@quicinc.com> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Lei Wei , Suruchi Agarwal , Pavithra R , "Simon Horman" , Jonathan Corbet , Kees Cook , "Gustavo A. R. Silva" , "Philipp Zabel" CC: , , , , , , , , , , , Luo Jie X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1739111388; l=30507; i=quic_luoj@quicinc.com; s=20250209; h=from:subject:message-id; bh=PldDsk/c+6uM+EkeLMZWH20Gsr8jfwa9QBMwJcxqMeg=; b=4ZLm7bpD4vQdH328dvNyWQGTIEeYYuX9g+BRfWYqXEjNb7KMLpGXVzVlSL895DLdPaG/aoVhF K7uDR26oo/WB5mXrPZcDKx+h87fnragmhp44TQMSt+W/9T56U0U0xfe X-Developer-Key: i=quic_luoj@quicinc.com; a=ed25519; pk=pzwy8bU5tJZ5UKGTv28n+QOuktaWuriznGmriA9Qkfc= X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: 7RPHg4CkQDef1zklPls1_jT48vwzMk6k X-Proofpoint-ORIG-GUID: 7RPHg4CkQDef1zklPls1_jT48vwzMk6k X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-02-09_06,2025-02-07_03,2024-11-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 malwarescore=0 adultscore=0 lowpriorityscore=0 phishscore=0 mlxscore=0 suspectscore=0 bulkscore=0 priorityscore=1501 spamscore=0 impostorscore=0 mlxlogscore=999 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2501170000 definitions=main-2502090128 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 + drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c | 692 ++++++++++++++++++++++++ drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.h | 16 + drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 102 ++++ 6 files changed, 825 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/qualcomm/ppe/Makefile b/drivers/net/ethernet/qualcomm/ppe/Makefile index 410a7bb54cfe..9e60b2400c16 100644 --- 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 diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe.c b/drivers/net/ethernet/qualcomm/ppe/ppe.c index 253de6a15466..17f6770c59ae 100644 --- 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 platform_device *pdev) 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_driver = { .of_match_table = qcom_ppe_of_match, }, .probe = qcom_ppe_probe, + .remove = qcom_ppe_remove, }; module_platform_driver(qcom_ppe_driver); diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe.h b/drivers/net/ethernet/qualcomm/ppe/ppe.h index cc6767b7c2b8..e9a208b77459 100644 --- 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); }; diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c b/drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c new file mode 100644 index 000000000000..5c05cbb7a0fe --- /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; +} diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.h new file mode 100644 index 000000000000..ba0a5b3af583 --- /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 diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h index f23fafa35766..a9f3a2bc4861 100644 --- 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