]> Git Repo - linux.git/blob - drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
zstd: import usptream v1.5.2
[linux.git] / drivers / net / ethernet / mediatek / mtk_ppe_debugfs.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (C) 2020 Felix Fietkau <[email protected]> */
3
4 #include <linux/kernel.h>
5 #include <linux/debugfs.h>
6 #include "mtk_eth_soc.h"
7
8 struct mtk_flow_addr_info
9 {
10         void *src, *dest;
11         u16 *src_port, *dest_port;
12         bool ipv6;
13 };
14
15 static const char *mtk_foe_entry_state_str(int state)
16 {
17         static const char * const state_str[] = {
18                 [MTK_FOE_STATE_INVALID] = "INV",
19                 [MTK_FOE_STATE_UNBIND] = "UNB",
20                 [MTK_FOE_STATE_BIND] = "BND",
21                 [MTK_FOE_STATE_FIN] = "FIN",
22         };
23
24         if (state >= ARRAY_SIZE(state_str) || !state_str[state])
25                 return "UNK";
26
27         return state_str[state];
28 }
29
30 static const char *mtk_foe_pkt_type_str(int type)
31 {
32         static const char * const type_str[] = {
33                 [MTK_PPE_PKT_TYPE_IPV4_HNAPT] = "IPv4 5T",
34                 [MTK_PPE_PKT_TYPE_IPV4_ROUTE] = "IPv4 3T",
35                 [MTK_PPE_PKT_TYPE_IPV4_DSLITE] = "DS-LITE",
36                 [MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T] = "IPv6 3T",
37                 [MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T] = "IPv6 5T",
38                 [MTK_PPE_PKT_TYPE_IPV6_6RD] = "6RD",
39         };
40
41         if (type >= ARRAY_SIZE(type_str) || !type_str[type])
42                 return "UNKNOWN";
43
44         return type_str[type];
45 }
46
47 static void
48 mtk_print_addr(struct seq_file *m, u32 *addr, bool ipv6)
49 {
50         u32 n_addr[4];
51         int i;
52
53         if (!ipv6) {
54                 seq_printf(m, "%pI4h", addr);
55                 return;
56         }
57
58         for (i = 0; i < ARRAY_SIZE(n_addr); i++)
59                 n_addr[i] = htonl(addr[i]);
60         seq_printf(m, "%pI6", n_addr);
61 }
62
63 static void
64 mtk_print_addr_info(struct seq_file *m, struct mtk_flow_addr_info *ai)
65 {
66         mtk_print_addr(m, ai->src, ai->ipv6);
67         if (ai->src_port)
68                 seq_printf(m, ":%d", *ai->src_port);
69         seq_printf(m, "->");
70         mtk_print_addr(m, ai->dest, ai->ipv6);
71         if (ai->dest_port)
72                 seq_printf(m, ":%d", *ai->dest_port);
73 }
74
75 static int
76 mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind)
77 {
78         struct mtk_ppe *ppe = m->private;
79         int i;
80
81         for (i = 0; i < MTK_PPE_ENTRIES; i++) {
82                 struct mtk_foe_entry *entry = mtk_foe_get_entry(ppe, i);
83                 struct mtk_foe_mac_info *l2;
84                 struct mtk_flow_addr_info ai = {};
85                 unsigned char h_source[ETH_ALEN];
86                 unsigned char h_dest[ETH_ALEN];
87                 int type, state;
88                 u32 ib2;
89
90
91                 state = FIELD_GET(MTK_FOE_IB1_STATE, entry->ib1);
92                 if (!state)
93                         continue;
94
95                 if (bind && state != MTK_FOE_STATE_BIND)
96                         continue;
97
98                 type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
99                 seq_printf(m, "%05x %s %7s", i,
100                            mtk_foe_entry_state_str(state),
101                            mtk_foe_pkt_type_str(type));
102
103                 switch (type) {
104                 case MTK_PPE_PKT_TYPE_IPV4_HNAPT:
105                 case MTK_PPE_PKT_TYPE_IPV4_DSLITE:
106                         ai.src_port = &entry->ipv4.orig.src_port;
107                         ai.dest_port = &entry->ipv4.orig.dest_port;
108                         fallthrough;
109                 case MTK_PPE_PKT_TYPE_IPV4_ROUTE:
110                         ai.src = &entry->ipv4.orig.src_ip;
111                         ai.dest = &entry->ipv4.orig.dest_ip;
112                         break;
113                 case MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T:
114                         ai.src_port = &entry->ipv6.src_port;
115                         ai.dest_port = &entry->ipv6.dest_port;
116                         fallthrough;
117                 case MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T:
118                 case MTK_PPE_PKT_TYPE_IPV6_6RD:
119                         ai.src = &entry->ipv6.src_ip;
120                         ai.dest = &entry->ipv6.dest_ip;
121                         ai.ipv6 = true;
122                         break;
123                 }
124
125                 seq_printf(m, " orig=");
126                 mtk_print_addr_info(m, &ai);
127
128                 switch (type) {
129                 case MTK_PPE_PKT_TYPE_IPV4_HNAPT:
130                 case MTK_PPE_PKT_TYPE_IPV4_DSLITE:
131                         ai.src_port = &entry->ipv4.new.src_port;
132                         ai.dest_port = &entry->ipv4.new.dest_port;
133                         fallthrough;
134                 case MTK_PPE_PKT_TYPE_IPV4_ROUTE:
135                         ai.src = &entry->ipv4.new.src_ip;
136                         ai.dest = &entry->ipv4.new.dest_ip;
137                         seq_printf(m, " new=");
138                         mtk_print_addr_info(m, &ai);
139                         break;
140                 }
141
142                 if (type >= MTK_PPE_PKT_TYPE_IPV4_DSLITE) {
143                         l2 = &entry->ipv6.l2;
144                         ib2 = entry->ipv6.ib2;
145                 } else {
146                         l2 = &entry->ipv4.l2;
147                         ib2 = entry->ipv4.ib2;
148                 }
149
150                 *((__be32 *)h_source) = htonl(l2->src_mac_hi);
151                 *((__be16 *)&h_source[4]) = htons(l2->src_mac_lo);
152                 *((__be32 *)h_dest) = htonl(l2->dest_mac_hi);
153                 *((__be16 *)&h_dest[4]) = htons(l2->dest_mac_lo);
154
155                 seq_printf(m, " eth=%pM->%pM etype=%04x"
156                               " vlan=%d,%d ib1=%08x ib2=%08x\n",
157                            h_source, h_dest, ntohs(l2->etype),
158                            l2->vlan1, l2->vlan2, entry->ib1, ib2);
159         }
160
161         return 0;
162 }
163
164 static int
165 mtk_ppe_debugfs_foe_all_show(struct seq_file *m, void *private)
166 {
167         return mtk_ppe_debugfs_foe_show(m, private, false);
168 }
169 DEFINE_SHOW_ATTRIBUTE(mtk_ppe_debugfs_foe_all);
170
171 static int
172 mtk_ppe_debugfs_foe_bind_show(struct seq_file *m, void *private)
173 {
174         return mtk_ppe_debugfs_foe_show(m, private, true);
175 }
176 DEFINE_SHOW_ATTRIBUTE(mtk_ppe_debugfs_foe_bind);
177
178 int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index)
179 {
180         struct dentry *root;
181
182         snprintf(ppe->dirname, sizeof(ppe->dirname), "ppe%d", index);
183
184         root = debugfs_create_dir(ppe->dirname, NULL);
185         debugfs_create_file("entries", S_IRUGO, root, ppe, &mtk_ppe_debugfs_foe_all_fops);
186         debugfs_create_file("bind", S_IRUGO, root, ppe, &mtk_ppe_debugfs_foe_bind_fops);
187
188         return 0;
189 }
This page took 0.043612 seconds and 4 git commands to generate.