[PATCH net-next 15/20] net: ethernet: qualcomm: Add PPE debugfs counters

From: Luo Jie
Date: Wed Jan 10 2024 - 06:49:31 EST


The PPE counter is checked with the command below.
"cat /sys/kernel/debug/ppe/packet_counter"

Signed-off-by: Luo Jie <quic_luoj@xxxxxxxxxxx>
---
drivers/net/ethernet/qualcomm/ppe/Makefile | 2 +-
drivers/net/ethernet/qualcomm/ppe/ppe.c | 8 +
.../net/ethernet/qualcomm/ppe/ppe_debugfs.c | 953 ++++++++++++++++++
.../net/ethernet/qualcomm/ppe/ppe_debugfs.h | 25 +
drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 256 +++++
include/linux/soc/qcom/ppe.h | 1 +
6 files changed, 1244 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c
create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.h

diff --git a/drivers/net/ethernet/qualcomm/ppe/Makefile b/drivers/net/ethernet/qualcomm/ppe/Makefile
index c00265339aa7..516ea23443ab 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_ops.o
+qcom-ppe-objs := ppe.o ppe_ops.o ppe_debugfs.o
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe.c b/drivers/net/ethernet/qualcomm/ppe/ppe.c
index d0e0fa9d5609..71973bce2cd2 100644
--- a/drivers/net/ethernet/qualcomm/ppe/ppe.c
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.c
@@ -17,6 +17,7 @@
#include "ppe.h"
#include "ppe_regs.h"
#include "ppe_ops.h"
+#include "ppe_debugfs.h"

#define PPE_SCHEDULER_PORT_NUM 8
#define MPPE_SCHEDULER_PORT_NUM 3
@@ -1328,11 +1329,18 @@ static int qcom_ppe_probe(struct platform_device *pdev)

ppe_dev->ppe_ops = &qcom_ppe_ops;
ppe_dev->is_ppe_probed = true;
+ ppe_debugfs_setup(ppe_dev);
+
return 0;
}

static int qcom_ppe_remove(struct platform_device *pdev)
{
+ struct ppe_device *ppe_dev;
+
+ ppe_dev = platform_get_drvdata(pdev);
+ ppe_debugfs_teardown(ppe_dev);
+
return 0;
}

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..a72c0eed9142
--- /dev/null
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c
@@ -0,0 +1,953 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/* PPE debugfs routines for display of PPE counters useful for debug. */
+
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/soc/qcom/ppe.h>
+#include "ppe_debugfs.h"
+#include "ppe_regs.h"
+#include "ppe.h"
+
+static const char * const ppe_cpucode[] = {
+ "Forwarding to CPU",
+ "Unknown L2 protocol exception redirect/copy to CPU",
+ "PPPoE wrong version or wrong type exception redirect/copy to CPU",
+ "PPPoE wrong code exception redirect/copy to CPU",
+ "PPPoE unsupported PPP protocol exception redirect/copy to CPU",
+ "IPv4 wrong version exception redirect/copy to CPU",
+ "IPv4 small IHL exception redirect/copy to CPU",
+ "IPv4 with option exception redirect/copy to CPU",
+ "IPv4 header incomplete exception redirect/copy to CPU",
+ "IPv4 bad total length exception redirect/copy to CPU",
+ "IPv4 data incomplete exception redirect/copy to CPU",
+ "IPv4 fragment exception redirect/copy to CPU",
+ "IPv4 ping of death exception redirect/copy to CPU",
+ "IPv4 small TTL exception redirect/copy to CPU",
+ "IPv4 unknown IP protocol exception redirect/copy to CPU",
+ "IPv4 checksum error exception redirect/copy to CPU",
+ "IPv4 invalid SIP exception redirect/copy to CPU",
+ "IPv4 invalid DIP exception redirect/copy to CPU",
+ "IPv4 LAND attack exception redirect/copy to CPU",
+ "IPv4 AH header incomplete exception redirect/copy to CPU",
+ "IPv4 AH header cross 128-byte exception redirect/copy to CPU",
+ "IPv4 ESP header incomplete exception redirect/copy to CPU",
+ "IPv6 wrong version exception redirect/copy to CPU",
+ "IPv6 header incomplete exception redirect/copy to CPU",
+ "IPv6 bad total length exception redirect/copy to CPU",
+ "IPv6 data incomplete exception redirect/copy to CPU",
+ "IPv6 with extension header exception redirect/copy to CPU",
+ "IPv6 small hop limit exception redirect/copy to CPU",
+ "IPv6 invalid SIP exception redirect/copy to CPU",
+ "IPv6 invalid DIP exception redirect/copy to CPU",
+ "IPv6 LAND attack exception redirect/copy to CPU",
+ "IPv6 fragment exception redirect/copy to CPU",
+ "IPv6 ping of death exception redirect/copy to CPU",
+ "IPv6 with more than 2 extension headers exception redirect/copy to CPU",
+ "IPv6 unknown last next header exception redirect/copy to CPU",
+ "IPv6 mobility header incomplete exception redirect/copy to CPU",
+ "IPv6 mobility header cross 128-byte exception redirect/copy to CPU",
+ "IPv6 AH header incomplete exception redirect/copy to CPU",
+ "IPv6 AH header cross 128-byte exception redirect/copy to CPU",
+ "IPv6 ESP header incomplete exception redirect/copy to CPU",
+ "IPv6 ESP header cross 128-byte exception redirect/copy to CPU",
+ "IPv6 other extension header incomplete exception redirect/copy to CPU",
+ "IPv6 other extension header cross 128-byte exception redirect/copy to CPU",
+ "TCP header incomplete exception redirect/copy to CPU",
+ "TCP header cross 128-byte exception redirect/copy to CPU",
+ "TCP same SP and DP exception redirect/copy to CPU",
+ "TCP small data offset redirect/copy to CPU",
+ "TCP flags VALUE/MASK group 0 exception redirect/copy to CPU",
+ "TCP flags VALUE/MASK group 1 exception redirect/copy to CPU",
+ "TCP flags VALUE/MASK group 2 exception redirect/copy to CPU",
+ "TCP flags VALUE/MASK group 3 exception redirect/copy to CPU",
+ "TCP flags VALUE/MASK group 4 exception redirect/copy to CPU",
+ "TCP flags VALUE/MASK group 5 exception redirect/copy to CPU",
+ "TCP flags VALUE/MASK group 6 exception redirect/copy to CPU",
+ "TCP flags VALUE/MASK group 7 exception redirect/copy to CPU",
+ "TCP checksum error exception redirect/copy to CPU",
+ "UDP header incomplete exception redirect/copy to CPU",
+ "UDP header cross 128-byte exception redirect/copy to CPU",
+ "UDP same SP and DP exception redirect/copy to CPU",
+ "UDP bad length exception redirect/copy to CPU",
+ "UDP data incomplete exception redirect/copy to CPU",
+ "UDP checksum error exception redirect/copy to CPU",
+ "UDP-Lite header incomplete exception redirect/copy to CPU",
+ "UDP-Lite header cross 128-byte exception redirect/copy to CPU",
+ "UDP-Lite same SP and DP exception redirect/copy to CPU",
+ "UDP-Lite checksum coverage value 0-7 exception redirect/copy to CPU",
+ "UDP-Lite checksum coverage value too big exception redirect/copy to CPU",
+ "UDP-Lite checksum coverage value cross 128-byte exception redirect/copy to CPU",
+ "UDP-Lite checksum error exception redirect/copy to CPU",
+ "Fake L2 protocol packet redirect/copy to CPU",
+ "Fake MAC header packet redirect/copy to CPU",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "L2 MRU checking fail redirect/copy to CPU",
+ "L2 MTU checking fail redirect/copy to CPU",
+ "IP prefix broadcast redirect/copy to CPU",
+ "L3 MTU checking fail redirect/copy to CPU",
+ "L3 MRU checking fail redirect/copy to CPU",
+ "ICMP redirect/copy to CPU",
+ "IP to me routing TTL 1 redirect/copy to CPU",
+ "IP to me routing TTL 0 redirect/copy to CPU",
+ "Flow service code loop redirect/copy to CPU",
+ "Flow de-accelerate redirect/copy to CPU",
+ "Flow source interface check fail redirect/copy to CPU",
+ "Flow sync toggle mismatch redirect/copy to CPU",
+ "MTU check fail if DF set redirect/copy to CPU",
+ "PPPoE multicast redirect/copy to CPU",
+ "Flow MTU check fail redirect/copy to cpu",
+ "Flow MTU DF check fail redirect/copy to CPU",
+ "UDP CHECKSUM ZERO redirect/copy to CPU",
+ "Reserved",
+ "EAPoL packet redirect/copy to CPU",
+ "PPPoE discovery packet redirect/copy to CPU",
+ "IGMP packet redirect/copy to CPU",
+ "ARP request packet redirect/copy to CPU",
+ "ARP reply packet redirect/copy to CPU",
+ "DHCPv4 packet redirect/copy to CPU",
+ "Reserved",
+ "LINKOAM packet redirect/copy to CPU",
+ "Reserved",
+ "Reserved",
+ "MLD packet redirect/copy to CPU",
+ "NS packet redirect/copy to CPU",
+ "NA packet redirect/copy to CPU",
+ "DHCPv6 packet redirect/copy to CPU",
+ "Reserved",
+ "Reserved",
+ "PTP sync packet redirect/copy to CPU",
+ "PTP follow up packet redirect/copy to CPU",
+ "PTP delay request packet redirect/copy to CPU",
+ "PTP delay response packet redirect/copy to CPU",
+ "PTP delay request packet redirect/copy to CPU",
+ "PTP delay response packet redirect/copy to CPU",
+ "PTP delay response follow up packet redirect/copy to CPU",
+ "PTP announce packet redirect/copy to CPU",
+ "PTP management packet redirect/copy to CPU",
+ "PTP signaling packet redirect/copy to CPU",
+ "PTP message reserved type 0 packet redirect/copy to CPU",
+ "PTP message reserved type 1 packet redirect/copy to CPU",
+ "PTP message reserved type 2 packet redirect/copy to CPU",
+ "PTP message reserved type 3 packet redirect/copy to CPU",
+ "PTP message reserved type packet redirect/copy to CPU",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "IPv4 source guard unknown packet redirect/copy to CPU",
+ "IPv6 source guard unknown packet redirect/copy to CPU",
+ "ARP source guard unknown packet redirect/copy to CPU",
+ "ND source guard unknown packet redirect/copy to CPU",
+ "IPv4 source guard violation packet redirect/copy to CPU",
+ "IPv6 source guard violation packet redirect/copy to CPU",
+ "ARP source guard violation packet redirect/copy to CPU",
+ "ND source guard violation packet redirect/copy to CPU",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "L3 route host mismatch action redirect/copy to CPU",
+ "L3 flow SNAT action redirect/copy to CPU",
+ "L3 flow DNAT action redirect/copy to CPU",
+ "L3 flow routing action redirect/copy to CPU",
+ "L3 flow bridging action redirect/copy to CPU",
+ "L3 multicast bridging action redirect/copy to CPU",
+ "L3 route preheader routing action redirect/copy to CPU",
+ "L3 route preheader SNAPT action redirect/copy to CPU",
+ "L3 route preheader DNAPT action redirect/copy to CPU",
+ "L3 route preheader SNAT action redirect/copy to CPU",
+ "L3 route preheader DNAT action redirect/copy to CPU",
+ "L3 no route preheader NAT action redirect/copy to CPU",
+ "L3 no route preheader NAT error redirect/copy to CPU",
+ "L3 route action redirect/copy to CPU",
+ "L3 no route action redirect/copy to CPU",
+ "L3 no route next hop invalid action redirect/copy to CPU",
+ "L3 no route preheader action redirect/copy to CPU",
+ "L3 bridge action redirect/copy to CPU",
+ "L3 flow action redirect/copy to CPU",
+ "L3 flow miss action redirect/copy to CPU",
+ "L2 new MAC address redirect/copy to CPU",
+ "L2 hash violation redirect/copy to CPU",
+ "L2 station move redirect/copy to CPU",
+ "L2 learn limit redirect/copy to CPU",
+ "L2 SA lookup action redirect/copy to CPU",
+ "L2 DA lookup action redirect/copy to CPU",
+ "APP_CTRL action redirect/copy to CPU",
+ "INGRESS_VLAN filter action redirect/copy to CPU",
+ "INGRSS VLAN translation miss redirect/copy to CPU",
+ "EGREE VLAN filter redirect/copy to CPU",
+ "Pre-IPO action",
+ "Post-IPO action",
+ "Service code action",
+ "L3 route Pre-IPO action redirect/copy to CPU",
+ "L3 route Pre-IPO snapt action redirect/copy to CPU",
+ "L3 route Pre-IPO dnapt action redirect/copy to CPU",
+ "L3 route Pre-IPO snat action redirect/copy to CPU",
+ "L3 route Pre-IPO dnat action redirect/copy to CPU",
+ "Tl L3 if check fail redirect/copy to CPU",
+ "TL vlan check fail redirect/copy to CPU",
+ "TL PPPoE Multicast termination redirect/copy to CPU",
+ "TL de-acceleration redirect/copy to CPU",
+ "TL UDP checksum zero redirect/copy to CPU",
+ "TL TTL exceed redirect/copy to CPU",
+ "TL LPM interface check fail redirect/copy to CPU",
+ "TL LPM vlan check fail redirect/copy to CPU",
+ "TL map src check fail redirect/copy to CPU",
+ "TL map dst check fail redirect/copy to CPU",
+ "TL map UDP checksum zero redirect/copy to CPU",
+ "TL map non TCP/UDP redirect/copy to CPU",
+ "TL forward cmd action redirect/copy to CPU",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "L2 Pre IPO action redirect/copy to CPU",
+ "L2 tunnel context check invalid redirect/copy to CPU",
+ "Reserved",
+ "Reserved",
+ "Tunnel decap ecn redirect/copy to CPU",
+ "Tunnel decap inner packet too short redirect/copy to CPU",
+ "Tunnel VXLAN header exception redirect/copy to CPU",
+ "Tunnel VXLAN-GPE header exception redirect/copy to CPU",
+ "Tunnel GENEVE header exception redirect/copy to CPU",
+ "Tunnel GRE header exception redirect/copy to CPU",
+ "Reserved",
+ "Tunnel decap unknown inner type redirect/copy to CPU",
+ "Tunnel parser VXLAN flag exception redirect/copy to CPU",
+ "Tunnel parser VXLAN-GPE flag exception redirect/copy to CPU",
+ "Tunnel parser GRE flag exception redirect/copy to CPU",
+ "Tunnel parser GENEVE flag exception redirect/copy to CPU",
+ "Tunnel parser PROGRAM0 exception redirect/copy to CPU",
+ "Tunnel parser PROGRAM1 exception redirect/copy to CPU",
+ "Tunnel parser PROGRAM2 exception redirect/copy to CPU",
+ "Tunnel parser PROGRAM3 exception redirect/copy to CPU",
+ "Tunnel parser PROGRAM4 exception redirect/copy to CPU",
+ "Tunnel parser PROGRAM5 exception redirect/copy to CPU",
+ "Trap for flooding",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Egress mirror to CPU",
+ "Ingress mirror to CPU",
+};
+
+static const char * const ppe_dropcode[] = {
+ "None",
+ "Unknown L2 protocol exception drop",
+ "PPPoE wrong version or wrong type exception drop",
+ "PPPoE unsupported PPP protocol exception drop",
+ "IPv4 wrong version exception drop",
+ "IPv4 small IHL or header incomplete or data incomplete exception drop",
+ "IPv4 with option exception drop",
+ "IPv4 bad total length exception drop",
+ "IPv4 fragment exception drop",
+ "IPv4 ping of death exception drop",
+ "IPv4 small TTL exception drop",
+ "IPv4 unknown IP protocol exception drop",
+ "IPv4 checksum error exception drop",
+ "IPv4 invalid SIP/DIP exception drop",
+ "IPv4 LAND attack exception drop",
+ "IPv4 AH or ESP header incomplete or AH header cross 128 byte exception drop",
+ "IPv6 wrong version exception drop",
+ "IPv6 header or data incomplete exception drop",
+ "IPv6 bad payload length exception drop",
+ "IPv6 with extension header exception drop",
+ "IPv6 small hop limit exception drop",
+ "IPv6 invalid SIP/DIP exception drop",
+ "IPv6 LAND attack exception drop",
+ "IPv6 fragment exception drop",
+ "IPv6 ping of death exception drop",
+ "IPv6 with more than 2 extension headers or unknown last next header exception drop",
+ "IPv6 AH/ESP/other extension/mobility header incomplete/cross 128 bytes exception drop",
+ "TCP header incomplete or cross 128 byte or small data offset exception drop",
+ "TCP same SP and DP exception drop",
+ "TCP flags VALUE/MASK group 0/1/2/3/4/5/6/7 exception drop",
+ "TCP checksum error exception drop",
+ "UDP header incomplete or cross 128 byte or data incomplete exception drop",
+ "UDP same SP and DP exception drop",
+ "UDP bad length exception drop",
+ "UDP checksum error exception drop",
+ "UDP-Lite header incomplete/same SP and DP/checksum coverage invalid value exception drop",
+ "UDP-Lite checksum error exception drop",
+ "L3 route Pre-IPO action exception drop",
+ "L3 route Pre-IPO snapt action exception drop",
+ "L3 route Pre-IPO dnapt action exception drop",
+ "L3 route Pre-IPO snat action exception drop",
+ "L3 route Pre-IPO dnat action exception drop",
+ "Tl L3 if check fail exception drop",
+ "TL vlan check fail exception drop",
+ "TL PPPoE Multicast termination exception drop",
+ "TL de-acceleration exception drop",
+ "TL UDP checksum zero exception drop",
+ "TL TTL exceed exception drop",
+ "TL LPM interface check fail exception drop",
+ "TL LPM vlan check fail exception drop",
+ "TL map src check fail exception drop",
+ "TL map dst check fail exception drop",
+ "TL map UDP checksum zero exception drop",
+ "TL map non TCP/UDP exception drop",
+ "L2 Pre IPO action redirect/copy to CPU",
+ "L2 tunnel context check invalid redirect/copy to CPU",
+ "Reserved",
+ "Reserved",
+ "Tunnel decap ecn exception drop",
+ "Tunnel decap inner packet too short exception drop",
+ "Tunnel VXLAN header exception drop",
+ "Tunnel VXLAN-GPE header exception drop",
+ "Tunnel GENEVE header exception drop",
+ "Tunnel GRE header exception drop",
+ "Reserved",
+ "Tunnel decap unknown inner type exception drop",
+ "Tunnel parser VXLAN, VXLAN-GPE, GRE or GENEVE flag exception drop",
+ "Tunnel parser PROGRAM0~ PROGRAM5 exception drop",
+ "TL forward cmd action exception drop",
+ "L3 multicast bridging action",
+ "L3 no route with preheader NAT action",
+ "L3 no route with preheader NAT action error configuration",
+ "L3 route action drop",
+ "L3 no route action drop",
+ "L3 no route next hop invalid action drop",
+ "L3 no route preheader action drop",
+ "L3 bridge action drop",
+ "L3 flow action drop",
+ "L3 flow miss action drop",
+ "L2 MRU checking fail drop",
+ "L2 MTU checking fail drop",
+ "L3 IP prefix broadcast drop",
+ "L3 MTU checking fail drop",
+ "L3 MRU checking fail drop",
+ "L3 ICMP redirect drop",
+ "Fake MAC header indicated packet not routing or bypass L3 edit drop",
+ "L3 IP route TTL zero drop",
+ "L3 flow service code loop drop",
+ "L3 flow de-accelerate drop",
+ "L3 flow source interface check fail drop",
+ "Flow toggle mismatch exception drop",
+ "MTU check exception if DF set drop",
+ "PPPoE multicast packet with IP routing enabled drop",
+ "IPv4 SG unknown drop",
+ "IPv6 SG unknown drop",
+ "ARP SG unknown drop",
+ "ND SG unknown drop",
+ "IPv4 SG violation drop",
+ "IPv6 SG violation drop",
+ "ARP SG violation drop",
+ "ND SG violation drop",
+ "L2 new MAC address drop",
+ "L2 hash violation drop",
+ "L2 station move drop",
+ "L2 learn limit drop",
+ "L2 SA lookup action drop",
+ "L2 DA lookup action drop",
+ "APP_CTRL action drop",
+ "Ingress VLAN filtering action drop",
+ "Ingress VLAN translation miss drop",
+ "Egress VLAN filtering drop",
+ "Pre-IPO entry hit action drop",
+ "Post-IPO entry hit action drop",
+ "Multicast SA or broadcast SA drop",
+ "No destination drop",
+ "STG ingress filtering drop",
+ "STG egress filtering drop",
+ "Source port filter drop",
+ "Trunk select fail drop",
+ "TX MAC disable drop",
+ "Ingress VLAN tag format drop",
+ "CRC error drop",
+ "PAUSE frame drop",
+ "Promiscuous drop",
+ "Isolation drop",
+ "Management packet APP_CTRL drop",
+ "Fake L2 protocol indicated packet not routing or bypass L3 edit drop",
+ "Policing drop",
+};
+
+static int ppe_prx_drop_counter_get(struct ppe_device *ppe_dev,
+ struct seq_file *seq)
+{
+ int i, tag;
+ u32 val;
+
+ /* The counter for the packet dropped because of no buffer available,
+ * no need to release the buffer.
+ */
+ PREFIX_S("PRX_DROP_CNT", "SILENT_DROP:");
+ tag = 0;
+ for (i = 0; i < PPE_DROP_CNT_NUM; i++) {
+ ppe_read(ppe_dev, PPE_DROP_CNT + i * PPE_DROP_CNT_INC, &val);
+
+ if (val > 0) {
+ tag++;
+ if (!(tag % 4)) {
+ seq_putc(seq, '\n');
+ PREFIX_S("", "");
+ }
+
+ CNT_ONE_TYPE(val, "port", i);
+ }
+ }
+
+ seq_putc(seq, '\n');
+ return 0;
+}
+
+static int ppe_prx_bm_drop_counter_get(struct ppe_device *ppe_dev,
+ struct seq_file *seq)
+{
+ union ppe_drop_stat_u drop_stat;
+ int i, tag;
+
+ /* The counter for the packet dropped because of no enough buffer
+ * to cache packet, some buffer allocated for the part of packet.
+ */
+ PREFIX_S("PRX_BM_DROP_CNT", "OVERFLOW_DROP:");
+ tag = 0;
+ for (i = 0; i < PPE_DROP_STAT_NUM; i++) {
+ memset(&drop_stat, 0, sizeof(drop_stat));
+ ppe_read_tbl(ppe_dev, PPE_DROP_STAT + PPE_DROP_STAT_INC * i,
+ drop_stat.val, sizeof(drop_stat.val));
+
+ if (drop_stat.bf.pkt_cnt > 0) {
+ tag++;
+ if (!(tag % 4)) {
+ seq_putc(seq, '\n');
+ PREFIX_S("", "");
+ }
+
+ CNT_ONE_TYPE(drop_stat.bf.pkt_cnt, "port", i);
+ }
+ }
+
+ seq_putc(seq, '\n');
+ return 0;
+}
+
+static int ppe_prx_bm_port_counter_get(struct ppe_device *ppe_dev,
+ struct seq_file *seq)
+{
+ int used_cnt, react_cnt;
+ int i, tag;
+ u32 val;
+
+ /* This is read only counter, which can't be flused. */
+ PREFIX_S("PRX_BM_PORT_CNT", "USED/REACT:");
+ tag = 0;
+ for (i = 0; i < PPE_BM_USED_CNT_NUM; i++) {
+ ppe_read(ppe_dev, PPE_BM_USED_CNT + i * PPE_BM_USED_CNT_INC, &val);
+ used_cnt = FIELD_GET(PPE_BM_USED_CNT_VAL, val);
+
+ ppe_read(ppe_dev, PPE_BM_REACT_CNT + i * PPE_BM_REACT_CNT_INC, &val);
+ react_cnt = FIELD_GET(PPE_BM_REACT_CNT_VAL, val);
+
+ if (used_cnt > 0 || react_cnt > 0) {
+ tag++;
+ if (!(tag % 4)) {
+ seq_putc(seq, '\n');
+ PREFIX_S("", "");
+ }
+
+ CNT_TWO_TYPE(used_cnt, react_cnt, "port", i);
+ }
+ }
+
+ seq_putc(seq, '\n');
+ return 0;
+}
+
+static int ppe_ipx_pkt_counter_get(struct ppe_device *ppe_dev,
+ struct seq_file *seq)
+{
+ u32 val, tunnel_val;
+ int i, tag;
+
+ PREFIX_S("IPR_PKT_CNT", "TPRX/IPRX:");
+ tag = 0;
+ for (i = 0; i < PPE_IPR_PKT_CNT_NUM; i++) {
+ ppe_read(ppe_dev, PPE_TPR_PKT_CNT + i * PPE_IPR_PKT_CNT_INC, &tunnel_val);
+ ppe_read(ppe_dev, PPE_IPR_PKT_CNT + i * PPE_IPR_PKT_CNT_INC, &val);
+
+ if (tunnel_val > 0 || val > 0) {
+ tag++;
+ if (!(tag % 4)) {
+ seq_putc(seq, '\n');
+ PREFIX_S("", "");
+ }
+
+ CNT_TWO_TYPE(tunnel_val, val, "port", i);
+ }
+ }
+
+ seq_putc(seq, '\n');
+ return 0;
+}
+
+static int ppe_port_rx_counter_get(struct ppe_device *ppe_dev,
+ struct seq_file *seq)
+{
+ union ppe_phy_port_rx_cnt_tbl_u phy_port_rx_cnt;
+ int i, tag;
+
+ PREFIX_S("PORT_RX_CNT", "RX/RX_DROP:");
+ tag = 0;
+ for (i = 0; i < PPE_PHY_PORT_RX_CNT_TBL_NUM; i++) {
+ memset(&phy_port_rx_cnt, 0, sizeof(phy_port_rx_cnt));
+ ppe_read_tbl(ppe_dev, PPE_PHY_PORT_RX_CNT_TBL + PPE_PHY_PORT_RX_CNT_TBL_INC * i,
+ phy_port_rx_cnt.val, sizeof(phy_port_rx_cnt.val));
+
+ if (phy_port_rx_cnt.bf.pkt_cnt > 0) {
+ tag++;
+ if (!(tag % 4)) {
+ seq_putc(seq, '\n');
+ PREFIX_S("", "");
+ }
+
+ CNT_TWO_TYPE(phy_port_rx_cnt.bf.pkt_cnt, phy_port_rx_cnt.bf.drop_pkt_cnt_0 |
+ phy_port_rx_cnt.bf.drop_pkt_cnt_1 << 24, "port", i);
+ }
+ }
+
+ seq_putc(seq, '\n');
+ return 0;
+}
+
+static int ppe_vp_rx_counter_get(struct ppe_device *ppe_dev,
+ struct seq_file *seq)
+{
+ union ppe_port_rx_cnt_tbl_u port_rx_cnt;
+ int i, tag;
+
+ PREFIX_S("VPORT_RX_CNT", "RX/RX_DROP:");
+ tag = 0;
+ for (i = 0; i < PPE_PORT_RX_CNT_TBL_NUM; i++) {
+ memset(&port_rx_cnt, 0, sizeof(port_rx_cnt));
+ ppe_read_tbl(ppe_dev, PPE_PORT_RX_CNT_TBL + PPE_PORT_RX_CNT_TBL_INC * i,
+ port_rx_cnt.val, sizeof(port_rx_cnt.val));
+
+ if (port_rx_cnt.bf.pkt_cnt > 0) {
+ tag++;
+ if (!(tag % 4)) {
+ seq_putc(seq, '\n');
+ PREFIX_S("", "");
+ }
+
+ CNT_TWO_TYPE(port_rx_cnt.bf.pkt_cnt, port_rx_cnt.bf.drop_pkt_cnt_0 |
+ port_rx_cnt.bf.drop_pkt_cnt_1 << 24, "port", i);
+ }
+ }
+
+ seq_putc(seq, '\n');
+ return 0;
+}
+
+static int ppe_pre_l2_counter_get(struct ppe_device *ppe_dev,
+ struct seq_file *seq)
+{
+ union ppe_pre_l2_cnt_tbl_u pre_l2_cnt;
+ int i, tag;
+
+ PREFIX_S("PRE_L2_CNT", "RX/RX_DROP:");
+ tag = 0;
+ for (i = 0; i < PPE_PRE_L2_CNT_TBL_NUM; i++) {
+ memset(&pre_l2_cnt, 0, sizeof(pre_l2_cnt));
+ ppe_read_tbl(ppe_dev, PPE_PRE_L2_CNT_TBL + PPE_PRE_L2_CNT_TBL_INC * i,
+ pre_l2_cnt.val, sizeof(pre_l2_cnt.val));
+
+ if (pre_l2_cnt.bf.pkt_cnt > 0) {
+ tag++;
+ if (!(tag % 4)) {
+ seq_putc(seq, '\n');
+ PREFIX_S("", "");
+ }
+
+ CNT_TWO_TYPE(pre_l2_cnt.bf.pkt_cnt, pre_l2_cnt.bf.drop_pkt_cnt_0 |
+ pre_l2_cnt.bf.drop_pkt_cnt_1 << 24, "vsi", i);
+ }
+ }
+
+ seq_putc(seq, '\n');
+ return 0;
+}
+
+static int ppe_vlan_counter_get(struct ppe_device *ppe_dev,
+ struct seq_file *seq)
+{
+ union ppe_vlan_cnt_u vlan_cnt;
+ int i, tag;
+
+ PREFIX_S("VLAN_CNT", "RX:");
+ tag = 0;
+ for (i = 0; i < PPE_VLAN_CNT_TBL_NUM; i++) {
+ memset(&vlan_cnt, 0, sizeof(vlan_cnt));
+ ppe_read_tbl(ppe_dev, PPE_VLAN_CNT_TBL + PPE_VLAN_CNT_TBL_INC * i,
+ vlan_cnt.val, sizeof(vlan_cnt.val));
+
+ if (vlan_cnt.bf.pkt_cnt > 0) {
+ tag++;
+ if (!(tag % 4)) {
+ seq_putc(seq, '\n');
+ PREFIX_S("", "");
+ }
+
+ CNT_ONE_TYPE(vlan_cnt.bf.pkt_cnt, "vsi", i);
+ }
+ }
+
+ seq_putc(seq, '\n');
+ return 0;
+}
+
+static int ppe_cpu_code_counter_get(struct ppe_device *ppe_dev,
+ struct seq_file *seq)
+{
+ union ppe_drop_cpu_cnt_u drop_cpu_cnt;
+ int i;
+
+ PREFIX_S("CPU_CODE_CNT", "CODE:");
+ for (i = 0; i < PPE_DROP_CPU_CNT_TBL_NUM; i++) {
+ memset(&drop_cpu_cnt, 0, sizeof(drop_cpu_cnt));
+ ppe_read_tbl(ppe_dev, PPE_DROP_CPU_CNT_TBL + PPE_DROP_CPU_CNT_TBL_INC * i,
+ drop_cpu_cnt.val, sizeof(drop_cpu_cnt.val));
+
+ /* entry index i = cpucode when i < 256;
+ * entry index i = 256 + dropcode * 8 + port & 7 when i > =256.
+ */
+ if (!drop_cpu_cnt.bf.pkt_cnt)
+ continue;
+
+ if (i < 256)
+ CNT_CPU_CODE(drop_cpu_cnt.bf.pkt_cnt, ppe_cpucode[i], i);
+ else
+ CNT_DROP_CODE(drop_cpu_cnt.bf.pkt_cnt,
+ ppe_dropcode[(i - 256) / 8],
+ (i - 256) % 8, (i - 256) / 8);
+
+ seq_putc(seq, '\n');
+ PREFIX_S("", "");
+ }
+
+ seq_putc(seq, '\n');
+ return 0;
+}
+
+static int ppe_eg_vsi_counter_get(struct ppe_device *ppe_dev,
+ struct seq_file *seq)
+{
+ union ppe_eg_vsi_cnt_tbl_u eg_vsi_cnt;
+ int i, tag;
+
+ PREFIX_S("EG_VSI_CNT", "TX:");
+ tag = 0;
+ for (i = 0; i < PPE_EG_VSI_COUNTER_TBL_NUM; i++) {
+ memset(&eg_vsi_cnt, 0, sizeof(eg_vsi_cnt));
+ ppe_read_tbl(ppe_dev, PPE_EG_VSI_COUNTER_TBL + PPE_EG_VSI_COUNTER_TBL_INC * i,
+ eg_vsi_cnt.val, sizeof(eg_vsi_cnt.val));
+
+ if (eg_vsi_cnt.bf.pkt_cnt > 0) {
+ tag++;
+ if (!(tag % 4)) {
+ seq_putc(seq, '\n');
+ PREFIX_S("", "");
+ }
+
+ CNT_ONE_TYPE(eg_vsi_cnt.bf.pkt_cnt, "vsi", i);
+ }
+ }
+
+ seq_putc(seq, '\n');
+ return 0;
+}
+
+static int ppe_vp_tx_counter_get(struct ppe_device *ppe_dev,
+ struct seq_file *seq)
+{
+ union ppe_vport_tx_counter_tbl_u vport_tx_counter;
+ union ppe_vport_tx_drop_u vport_tx_drop;
+ int i, tag;
+
+ PREFIX_S("VPORT_TX_CNT", "TX/TX_DROP:");
+ tag = 0;
+ for (i = 0; i < PPE_VPORT_TX_COUNTER_TBL_NUM; i++) {
+ memset(&vport_tx_counter, 0, sizeof(vport_tx_counter));
+ memset(&vport_tx_drop, 0, sizeof(vport_tx_drop));
+
+ ppe_read_tbl(ppe_dev, PPE_VPORT_TX_COUNTER_TBL + PPE_VPORT_TX_COUNTER_TBL_INC * i,
+ vport_tx_counter.val, sizeof(vport_tx_counter.val));
+ ppe_read_tbl(ppe_dev, PPE_VPORT_TX_DROP_CNT_TBL + PPE_VPORT_TX_DROP_CNT_TBL_INC * i,
+ vport_tx_drop.val, sizeof(vport_tx_drop.val));
+
+ if (vport_tx_counter.bf.pkt_cnt > 0 || vport_tx_drop.bf.pkt_cnt > 0) {
+ tag++;
+ if (!(tag % 4)) {
+ seq_putc(seq, '\n');
+ PREFIX_S("", "");
+ }
+
+ CNT_TWO_TYPE(vport_tx_counter.bf.pkt_cnt,
+ vport_tx_drop.bf.pkt_cnt, "port", i);
+ }
+ }
+
+ seq_putc(seq, '\n');
+ return 0;
+}
+
+static int ppe_port_tx_counter_get(struct ppe_device *ppe_dev,
+ struct seq_file *seq)
+{
+ union ppe_port_tx_counter_tbl_u port_tx_counter;
+ union ppe_port_tx_drop_u port_tx_drop;
+ int i, tag;
+
+ PREFIX_S("PORT_TX_CNT", "TX/TX_DROP:");
+ tag = 0;
+ for (i = 0; i < PPE_PORT_TX_COUNTER_TBL_NUM; i++) {
+ memset(&port_tx_counter, 0, sizeof(port_tx_counter));
+ memset(&port_tx_drop, 0, sizeof(port_tx_drop));
+
+ ppe_read_tbl(ppe_dev, PPE_PORT_TX_COUNTER_TBL + PPE_PORT_TX_COUNTER_TBL_INC * i,
+ port_tx_counter.val, sizeof(port_tx_counter.val));
+ ppe_read_tbl(ppe_dev, PPE_PORT_TX_DROP_CNT_TBL + PPE_PORT_TX_DROP_CNT_TBL_INC * i,
+ port_tx_drop.val, sizeof(port_tx_drop.val));
+
+ if (port_tx_counter.bf.pkt_cnt > 0 || port_tx_drop.bf.pkt_cnt > 0) {
+ tag++;
+ if (!(tag % 4)) {
+ seq_putc(seq, '\n');
+ PREFIX_S("", "");
+ }
+
+ CNT_TWO_TYPE(port_tx_counter.bf.pkt_cnt,
+ port_tx_drop.bf.pkt_cnt, "port", i);
+ }
+ }
+
+ seq_putc(seq, '\n');
+ return 0;
+}
+
+static int ppe_queue_tx_counter_get(struct ppe_device *ppe_dev,
+ struct seq_file *seq)
+{
+ union ppe_queue_tx_counter_tbl_u queue_tx_counter;
+ u32 val, pend_cnt;
+ int i, tag;
+
+ PREFIX_S("QUEUE_TX_CNT", "TX/PEND:");
+ tag = 0;
+ for (i = 0; i < PPE_QUEUE_TX_COUNTER_TBL_NUM; i++) {
+ memset(&queue_tx_counter, 0, sizeof(queue_tx_counter));
+ ppe_read_tbl(ppe_dev, PPE_QUEUE_TX_COUNTER_TBL + PPE_QUEUE_TX_COUNTER_TBL_INC * i,
+ queue_tx_counter.val, sizeof(queue_tx_counter.val));
+
+ if (i < PPE_AC_UNI_QUEUE_CFG_TBL_NUM) {
+ ppe_read(ppe_dev, PPE_AC_UNI_QUEUE_CNT_TBL +
+ PPE_AC_UNI_QUEUE_CNT_TBL_INC * i, &val);
+ pend_cnt = FIELD_GET(PPE_AC_UNI_QUEUE_CNT_TBL_PEND_CNT, val);
+ } else {
+ ppe_read(ppe_dev, PPE_AC_MUL_QUEUE_CNT_TBL +
+ PPE_AC_MUL_QUEUE_CNT_TBL_INC *
+ (i - PPE_AC_UNI_QUEUE_CFG_TBL_NUM), &val);
+ pend_cnt = FIELD_GET(PPE_AC_MUL_QUEUE_CNT_TBL_PEND_CNT, val);
+ }
+
+ if (queue_tx_counter.bf.pkt_cnt > 0 || pend_cnt > 0) {
+ tag++;
+ if (!(tag % 4)) {
+ seq_putc(seq, '\n');
+ PREFIX_S("", "");
+ }
+
+ CNT_TWO_TYPE(queue_tx_counter.bf.pkt_cnt, pend_cnt, "queue", i);
+ }
+ }
+
+ seq_putc(seq, '\n');
+ return 0;
+}
+
+static int ppe_packet_counter_show(struct seq_file *seq, void *v)
+{
+ struct ppe_device *ppe_dev = seq->private;
+
+ ppe_prx_drop_counter_get(ppe_dev, seq);
+ ppe_prx_bm_drop_counter_get(ppe_dev, seq);
+ ppe_prx_bm_port_counter_get(ppe_dev, seq);
+ ppe_ipx_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)
+{
+ union ppe_port_tx_counter_tbl_u port_tx_counter;
+ union ppe_vport_tx_counter_tbl_u vport_tx_counter;
+ union ppe_queue_tx_counter_tbl_u queue_tx_counter;
+ union ppe_phy_port_rx_cnt_tbl_u phy_port_rx_cnt;
+ union ppe_port_rx_cnt_tbl_u port_rx_cnt;
+ union ppe_pre_l2_cnt_tbl_u pre_l2_cnt;
+ union ppe_eg_vsi_cnt_tbl_u eg_vsi_cnt;
+ union ppe_vport_tx_drop_u vport_tx_drop;
+ union ppe_port_tx_drop_u port_tx_drop;
+ union ppe_drop_cpu_cnt_u drop_cpu_cnt;
+ union ppe_drop_stat_u drop_stat;
+ union ppe_vlan_cnt_u vlan_cnt;
+ struct ppe_device *ppe_dev;
+ u32 val;
+ int i;
+
+ memset(&drop_stat, 0, sizeof(drop_stat));
+ memset(&vlan_cnt, 0, sizeof(vlan_cnt));
+ memset(&pre_l2_cnt, 0, sizeof(pre_l2_cnt));
+ memset(&port_tx_drop, 0, sizeof(port_tx_drop));
+ memset(&eg_vsi_cnt, 0, sizeof(eg_vsi_cnt));
+ memset(&port_tx_counter, 0, sizeof(port_tx_counter));
+ memset(&vport_tx_counter, 0, sizeof(vport_tx_counter));
+ memset(&queue_tx_counter, 0, sizeof(queue_tx_counter));
+ memset(&vport_tx_drop, 0, sizeof(vport_tx_drop));
+ memset(&drop_cpu_cnt, 0, sizeof(drop_cpu_cnt));
+ memset(&port_rx_cnt, 0, sizeof(port_rx_cnt));
+ memset(&phy_port_rx_cnt, 0, sizeof(phy_port_rx_cnt));
+
+ val = 0;
+ ppe_dev = file_inode(file)->i_private;
+ for (i = 0; i < PPE_DROP_CNT_NUM; i++)
+ ppe_write(ppe_dev, PPE_DROP_CNT + i * PPE_DROP_CNT_INC, val);
+
+ for (i = 0; i < PPE_DROP_STAT_NUM; i++)
+ ppe_write_tbl(ppe_dev, PPE_DROP_STAT + PPE_DROP_STAT_INC * i,
+ drop_stat.val, sizeof(drop_stat.val));
+
+ for (i = 0; i < PPE_IPR_PKT_CNT_NUM; i++)
+ ppe_write(ppe_dev, PPE_IPR_PKT_CNT + i * PPE_IPR_PKT_CNT_INC, val);
+
+ for (i = 0; i < PPE_VLAN_CNT_TBL_NUM; i++)
+ ppe_write_tbl(ppe_dev, PPE_VLAN_CNT_TBL + PPE_VLAN_CNT_TBL_INC * i,
+ vlan_cnt.val, sizeof(vlan_cnt.val));
+
+ for (i = 0; i < PPE_PRE_L2_CNT_TBL_NUM; i++)
+ ppe_write_tbl(ppe_dev, PPE_PRE_L2_CNT_TBL + PPE_PRE_L2_CNT_TBL_INC * i,
+ pre_l2_cnt.val, sizeof(pre_l2_cnt.val));
+
+ for (i = 0; i < PPE_PORT_TX_DROP_CNT_TBL_NUM; i++)
+ ppe_write_tbl(ppe_dev, PPE_PORT_TX_DROP_CNT_TBL + PPE_PORT_TX_DROP_CNT_TBL_INC * i,
+ port_tx_drop.val, sizeof(port_tx_drop.val));
+
+ for (i = 0; i < PPE_EG_VSI_COUNTER_TBL_NUM; i++)
+ ppe_write_tbl(ppe_dev, PPE_EG_VSI_COUNTER_TBL + PPE_EG_VSI_COUNTER_TBL_INC * i,
+ eg_vsi_cnt.val, sizeof(eg_vsi_cnt.val));
+
+ for (i = 0; i < PPE_PORT_TX_COUNTER_TBL_NUM; i++)
+ ppe_write_tbl(ppe_dev, PPE_PORT_TX_COUNTER_TBL + PPE_PORT_TX_COUNTER_TBL_INC * i,
+ port_tx_counter.val, sizeof(port_tx_counter.val));
+
+ for (i = 0; i < PPE_VPORT_TX_COUNTER_TBL_NUM; i++)
+ ppe_write_tbl(ppe_dev, PPE_VPORT_TX_COUNTER_TBL + PPE_VPORT_TX_COUNTER_TBL_INC * i,
+ vport_tx_counter.val, sizeof(vport_tx_counter.val));
+
+ for (i = 0; i < PPE_QUEUE_TX_COUNTER_TBL_NUM; i++)
+ ppe_write_tbl(ppe_dev, PPE_QUEUE_TX_COUNTER_TBL + PPE_QUEUE_TX_COUNTER_TBL_INC * i,
+ queue_tx_counter.val, sizeof(queue_tx_counter.val));
+
+ ppe_write(ppe_dev, PPE_EPE_DBG_IN_CNT, val);
+ ppe_write(ppe_dev, PPE_EPE_DBG_OUT_CNT, val);
+
+ for (i = 0; i < PPE_VPORT_TX_DROP_CNT_TBL_NUM; i++)
+ ppe_write_tbl(ppe_dev, PPE_VPORT_TX_DROP_CNT_TBL +
+ PPE_VPORT_TX_DROP_CNT_TBL_INC * i,
+ vport_tx_drop.val, sizeof(vport_tx_drop.val));
+
+ for (i = 0; i < PPE_DROP_CPU_CNT_TBL_NUM; i++)
+ ppe_write_tbl(ppe_dev, PPE_DROP_CPU_CNT_TBL + PPE_DROP_CPU_CNT_TBL_INC * i,
+ drop_cpu_cnt.val, sizeof(drop_cpu_cnt.val));
+
+ for (i = 0; i < PPE_PORT_RX_CNT_TBL_NUM; i++)
+ ppe_write_tbl(ppe_dev, PPE_PORT_RX_CNT_TBL + PPE_PORT_RX_CNT_TBL_INC * i,
+ port_rx_cnt.val, sizeof(port_rx_cnt.val));
+
+ for (i = 0; i < PPE_PHY_PORT_RX_CNT_TBL_NUM; i++)
+ ppe_write_tbl(ppe_dev, PPE_PHY_PORT_RX_CNT_TBL + PPE_PHY_PORT_RX_CNT_TBL_INC * i,
+ phy_port_rx_cnt.val, sizeof(phy_port_rx_cnt.val));
+
+ 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,
+};
+
+int ppe_debugfs_setup(struct ppe_device *ppe_dev)
+{
+ ppe_dev->debugfs_root = debugfs_create_dir("ppe", NULL);
+ debugfs_create_file("packet_counter", 0444,
+ ppe_dev->debugfs_root,
+ ppe_dev,
+ &ppe_debugfs_packet_counter_fops);
+ return 0;
+}
+
+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..97463216d5af
--- /dev/null
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/* PPE debugfs counters setup. */
+
+#ifndef __PPE_DEBUGFS_H__
+#define __PPE_DEBUGFS_H__
+
+#define PREFIX_S(desc, cnt_type) \
+ seq_printf(seq, "%-16s %16s", desc, cnt_type)
+#define CNT_ONE_TYPE(cnt, str, index) \
+ seq_printf(seq, "%10u(%s=%04d)", cnt, str, index)
+#define CNT_TWO_TYPE(cnt, cnt1, str, index) \
+ seq_printf(seq, "%10u/%u(%s=%04d)", cnt, cnt1, str, index)
+#define CNT_CPU_CODE(cnt, str, index) \
+ seq_printf(seq, "%10u(%s),cpucode:%d", cnt, str, index)
+#define CNT_DROP_CODE(cnt, str, port, index) \
+ seq_printf(seq, "%10u(port=%d:%s),dropcode:%d", cnt, port, str, index)
+
+int 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 ef12037ffed5..98bf19f974ce 100644
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
@@ -19,6 +19,105 @@
#define PPE_RX_FIFO_CFG_INC 4
#define PPE_RX_FIFO_CFG_THRSH GENMASK(2, 0)

+#define PPE_DROP_CNT 0xb024
+#define PPE_DROP_CNT_NUM 8
+#define PPE_DROP_CNT_INC 4
+#define PPE_DROP_CNT_PKT_CNT GENMASK(31, 0)
+
+#define PPE_DROP_STAT 0xe000
+#define PPE_DROP_STAT_NUM 30
+#define PPE_DROP_STAT_INC 0x10
+#define PPE_DROP_STAT_PKT_CNT GENMASK(31, 0)
+
+/* BM port drop counter */
+struct ppe_drop_stat {
+ u32 pkt_cnt;
+ u32 byte_cnt_0;
+ u32 byte_cnt_1:8,
+ res0:24;
+};
+
+union ppe_drop_stat_u {
+ u32 val[3];
+ struct ppe_drop_stat bf;
+};
+
+#define PPE_EPE_DBG_IN_CNT 0x26054
+#define PPE_EPE_DBG_IN_CNT_NUM 1
+#define PPE_EPE_DBG_IN_CNT_INC 0x4
+
+#define PPE_EPE_DBG_OUT_CNT 0x26070
+#define PPE_EPE_DBG_OUT_CNT_NUM 1
+#define PPE_EPE_DBG_OUT_CNT_INC 0x4
+
+#define PPE_EG_VSI_COUNTER_TBL 0x41000
+#define PPE_EG_VSI_COUNTER_TBL_NUM 64
+#define PPE_EG_VSI_COUNTER_TBL_INC 0x10
+
+/* Egress VLAN counter */
+struct ppe_eg_vsi_cnt_tbl {
+ u32 pkt_cnt;
+ u32 byte_cnt_0;
+ u32 byte_cnt_1:8,
+ res0:24;
+};
+
+union ppe_eg_vsi_cnt_tbl_u {
+ u32 val[3];
+ struct ppe_eg_vsi_cnt_tbl bf;
+};
+
+#define PPE_PORT_TX_COUNTER_TBL 0x45000
+#define PPE_PORT_TX_COUNTER_TBL_NUM 8
+#define PPE_PORT_TX_COUNTER_TBL_INC 0x10
+
+/* Port TX counter */
+struct ppe_port_tx_counter_tbl {
+ u32 pkt_cnt;
+ u32 byte_cnt_0;
+ u32 byte_cnt_1:8,
+ res0:24;
+};
+
+union ppe_port_tx_counter_tbl_u {
+ u32 val[3];
+ struct ppe_port_tx_counter_tbl bf;
+};
+
+#define PPE_VPORT_TX_COUNTER_TBL 0x47000
+#define PPE_VPORT_TX_COUNTER_TBL_NUM 256
+#define PPE_VPORT_TX_COUNTER_TBL_INC 0x10
+
+/* Virtual port TX counter */
+struct ppe_vport_tx_counter_tbl {
+ u32 pkt_cnt;
+ u32 byte_cnt_0;
+ u32 byte_cnt_1:8,
+ res0:24;
+};
+
+union ppe_vport_tx_counter_tbl_u {
+ u32 val[3];
+ struct ppe_vport_tx_counter_tbl bf;
+};
+
+#define PPE_QUEUE_TX_COUNTER_TBL 0x4a000
+#define PPE_QUEUE_TX_COUNTER_TBL_NUM 300
+#define PPE_QUEUE_TX_COUNTER_TBL_INC 0x10
+
+/* Queue counter */
+struct ppe_queue_tx_counter_tbl {
+ u32 pkt_cnt;
+ u32 byte_cnt_0;
+ u32 byte_cnt_1:8,
+ res0:24;
+};
+
+union ppe_queue_tx_counter_tbl_u {
+ u32 val[3];
+ struct ppe_queue_tx_counter_tbl bf;
+};
+
#define PPE_RSS_HASH_MASK 0xb4318
#define PPE_RSS_HASH_MASK_NUM 1
#define PPE_RSS_HASH_MASK_INC 4
@@ -196,6 +295,143 @@ union ppe_mru_mtu_ctrl_cfg_u {
#define PPE_IN_L2_SERVICE_TBL_RX_CNT_EN BIT(30)
#define PPE_IN_L2_SERVICE_TBL_TX_CNT_EN BIT(31)

+#define PPE_PORT_RX_CNT_TBL 0x150000
+#define PPE_PORT_RX_CNT_TBL_NUM 256
+#define PPE_PORT_RX_CNT_TBL_INC 0x20
+
+/* Port RX counter */
+struct ppe_port_rx_cnt_tbl {
+ u32 pkt_cnt;
+ u32 byte_cnt_0;
+ u32 byte_cnt_1:8,
+ drop_pkt_cnt_0:24;
+ u32 drop_pkt_cnt_1:8,
+ drop_byte_cnt_0:24;
+ u32 drop_byte_cnt_1:16,
+ res0:16;
+};
+
+union ppe_port_rx_cnt_tbl_u {
+ u32 val[5];
+ struct ppe_port_rx_cnt_tbl bf;
+};
+
+#define PPE_PHY_PORT_RX_CNT_TBL 0x156000
+#define PPE_PHY_PORT_RX_CNT_TBL_NUM 8
+#define PPE_PHY_PORT_RX_CNT_TBL_INC 0x20
+
+/* Physical port RX and RX drop counter */
+struct ppe_phy_port_rx_cnt_tbl {
+ u32 pkt_cnt;
+ u32 byte_cnt_0;
+ u32 byte_cnt_1:8,
+ drop_pkt_cnt_0:24;
+ u32 drop_pkt_cnt_1:8,
+ drop_byte_cnt_0:24;
+ u32 drop_byte_cnt_1:16,
+ res0:16;
+};
+
+union ppe_phy_port_rx_cnt_tbl_u {
+ u32 val[5];
+ struct ppe_phy_port_rx_cnt_tbl bf;
+};
+
+#define PPE_DROP_CPU_CNT_TBL 0x160000
+#define PPE_DROP_CPU_CNT_TBL_NUM 1280
+#define PPE_DROP_CPU_CNT_TBL_INC 0x10
+
+/* counter for the packet to CPU port */
+struct ppe_drop_cpu_cnt {
+ u32 pkt_cnt;
+ u32 byte_cnt_0;
+ u32 byte_cnt_1:8,
+ res0:24;
+};
+
+union ppe_drop_cpu_cnt_u {
+ u32 val[3];
+ struct ppe_drop_cpu_cnt bf;
+};
+
+#define PPE_VLAN_CNT_TBL 0x178000
+#define PPE_VLAN_CNT_TBL_NUM 64
+#define PPE_VLAN_CNT_TBL_INC 0x10
+
+/* VLAN counter */
+struct ppe_vlan_cnt {
+ u32 pkt_cnt;
+ u32 byte_cnt_0;
+ u32 byte_cnt_1:8,
+ res0:24;
+};
+
+union ppe_vlan_cnt_u {
+ u32 val[3];
+ struct ppe_vlan_cnt bf;
+};
+
+#define PPE_PRE_L2_CNT_TBL 0x17c000
+#define PPE_PRE_L2_CNT_TBL_NUM 64
+#define PPE_PRE_L2_CNT_TBL_INC 0x20
+
+/* PPE L2 counter */
+struct ppe_pre_l2_cnt_tbl {
+ u32 pkt_cnt;
+ u32 byte_cnt_0;
+ u32 byte_cnt_1:8,
+ drop_pkt_cnt_0:24;
+ u32 drop_pkt_cnt_1:8,
+ drop_byte_cnt_0:24;
+ u32 drop_byte_cnt_1:16,
+ res0:16;
+};
+
+union ppe_pre_l2_cnt_tbl_u {
+ u32 val[5];
+ struct ppe_pre_l2_cnt_tbl bf;
+};
+
+#define PPE_PORT_TX_DROP_CNT_TBL 0x17d000
+#define PPE_PORT_TX_DROP_CNT_TBL_NUM 8
+#define PPE_PORT_TX_DROP_CNT_TBL_INC 0x10
+
+/* Port TX drop counter */
+struct ppe_port_tx_drop_cnt {
+ u32 pkt_cnt;
+ u32 byte_cnt_0;
+ u32 byte_cnt_1:8,
+ res0:24;
+};
+
+union ppe_port_tx_drop_u {
+ u32 val[3];
+ struct ppe_port_tx_drop_cnt bf;
+};
+
+#define PPE_VPORT_TX_DROP_CNT_TBL 0x17e000
+#define PPE_VPORT_TX_DROP_CNT_TBL_NUM 256
+#define PPE_VPORT_TX_DROP_CNT_TBL_INC 0x10
+
+/* Virtual port TX counter */
+struct ppe_vport_tx_drop_cnt {
+ u32 pkt_cnt;
+ u32 byte_cnt_0;
+ u32 byte_cnt_1:8,
+ res0:24;
+};
+
+union ppe_vport_tx_drop_u {
+ u32 val[3];
+ struct ppe_vport_tx_drop_cnt bf;
+};
+
+#define PPE_TPR_PKT_CNT 0x1d0080
+#define PPE_IPR_PKT_CNT 0x1e0080
+#define PPE_IPR_PKT_CNT_NUM 8
+#define PPE_IPR_PKT_CNT_INC 4
+#define PPE_IPR_PKT_CNT_PKT_CNT GENMASK(31, 0)
+
#define PPE_TL_SERVICE_TBL 0x306000
#define PPE_TL_SERVICE_TBL_NUM 256
#define PPE_TL_SERVICE_TBL_INC 4
@@ -318,6 +554,16 @@ union ppe_ring_q_map_cfg_u {
#define PPE_BM_PORT_GROUP_ID_INC 4
#define PPE_BM_PORT_GROUP_ID_SHARED_GROUP_ID GENMASK(1, 0)

+#define PPE_BM_USED_CNT 0x6001c0
+#define PPE_BM_USED_CNT_NUM 15
+#define PPE_BM_USED_CNT_INC 0x4
+#define PPE_BM_USED_CNT_VAL GENMASK(10, 0)
+
+#define PPE_BM_REACT_CNT 0x600240
+#define PPE_BM_REACT_CNT_NUM 15
+#define PPE_BM_REACT_CNT_INC 0x4
+#define PPE_BM_REACT_CNT_VAL GENMASK(8, 0)
+
#define PPE_BM_SHARED_GROUP_CFG 0x600290
#define PPE_BM_SHARED_GROUP_CFG_NUM 4
#define PPE_BM_SHARED_GROUP_CFG_INC 4
@@ -456,6 +702,16 @@ union ppe_ac_grp_cfg_u {
struct ppe_ac_grp_cfg bf;
};

+#define PPE_AC_UNI_QUEUE_CNT_TBL 0x84e000
+#define PPE_AC_UNI_QUEUE_CNT_TBL_NUM 256
+#define PPE_AC_UNI_QUEUE_CNT_TBL_INC 0x10
+#define PPE_AC_UNI_QUEUE_CNT_TBL_PEND_CNT GENMASK(12, 0)
+
+#define PPE_AC_MUL_QUEUE_CNT_TBL 0x852000
+#define PPE_AC_MUL_QUEUE_CNT_TBL_NUM 44
+#define PPE_AC_MUL_QUEUE_CNT_TBL_INC 0x10
+#define PPE_AC_MUL_QUEUE_CNT_TBL_PEND_CNT GENMASK(12, 0)
+
#define PPE_ENQ_OPR_TBL 0x85c000
#define PPE_ENQ_OPR_TBL_NUM 300
#define PPE_ENQ_OPR_TBL_INC 0x10
diff --git a/include/linux/soc/qcom/ppe.h b/include/linux/soc/qcom/ppe.h
index 70ee192d9ef0..268109c823ad 100644
--- a/include/linux/soc/qcom/ppe.h
+++ b/include/linux/soc/qcom/ppe.h
@@ -17,6 +17,7 @@ struct ppe_device {
struct device *dev;
struct regmap *regmap;
struct ppe_device_ops *ppe_ops;
+ struct dentry *debugfs_root;
bool is_ppe_probed;
void *ppe_priv;
};
--
2.42.0