brintos

brintos / linux-shallow public Read only

0
0
Text · 4.8 KiB · 570ebf9 Raw
196 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* 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_info12{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 void51mtk_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 void65mtk_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 int77mtk_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 int171mtk_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 int178mtk_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}196