Linux Audio

Check our new training course

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