xref: /linux/drivers/net/ethernet/hisilicon/hibmcge/hbg_debugfs.c (revision 74f1af95820fc2ee580a775a3a17c416db30b38c)
186331b51SJijie Shao // SPDX-License-Identifier: GPL-2.0+
286331b51SJijie Shao // Copyright (c) 2024 Hisilicon Limited.
386331b51SJijie Shao 
486331b51SJijie Shao #include <linux/debugfs.h>
586331b51SJijie Shao #include <linux/device.h>
686331b51SJijie Shao #include <linux/etherdevice.h>
786331b51SJijie Shao #include <linux/seq_file.h>
886331b51SJijie Shao #include <linux/string_choices.h>
986331b51SJijie Shao #include "hbg_common.h"
1086331b51SJijie Shao #include "hbg_debugfs.h"
1186331b51SJijie Shao #include "hbg_hw.h"
1286331b51SJijie Shao #include "hbg_irq.h"
1386331b51SJijie Shao #include "hbg_txrx.h"
1486331b51SJijie Shao 
1586331b51SJijie Shao static struct dentry *hbg_dbgfs_root;
1686331b51SJijie Shao 
1786331b51SJijie Shao struct hbg_dbg_info {
1886331b51SJijie Shao 	const char *name;
1986331b51SJijie Shao 	int (*read)(struct seq_file *seq, void *data);
2086331b51SJijie Shao };
2186331b51SJijie Shao 
223f5a61f6SJijie Shao #define state_str_true_false(p, s) str_true_false(test_bit(s, &(p)->state))
233f5a61f6SJijie Shao 
hbg_dbg_ring(struct hbg_priv * priv,struct hbg_ring * ring,struct seq_file * s)2486331b51SJijie Shao static void hbg_dbg_ring(struct hbg_priv *priv, struct hbg_ring *ring,
2586331b51SJijie Shao 			 struct seq_file *s)
2686331b51SJijie Shao {
2786331b51SJijie Shao 	u32 irq_mask = ring->dir == HBG_DIR_TX ? HBG_INT_MSK_TX_B :
2886331b51SJijie Shao 						 HBG_INT_MSK_RX_B;
2986331b51SJijie Shao 
3086331b51SJijie Shao 	seq_printf(s, "ring used num: %u\n",
3186331b51SJijie Shao 		   hbg_get_queue_used_num(ring));
3286331b51SJijie Shao 	seq_printf(s, "ring max num: %u\n", ring->len);
3386331b51SJijie Shao 	seq_printf(s, "ring head: %u, tail: %u\n", ring->head, ring->tail);
3486331b51SJijie Shao 	seq_printf(s, "fifo used num: %u\n",
3586331b51SJijie Shao 		   hbg_hw_get_fifo_used_num(priv, ring->dir));
3686331b51SJijie Shao 	seq_printf(s, "fifo max num: %u\n",
3786331b51SJijie Shao 		   hbg_get_spec_fifo_max_num(priv, ring->dir));
3886331b51SJijie Shao 	seq_printf(s, "irq enabled: %s\n",
3986331b51SJijie Shao 		   str_true_false(hbg_hw_irq_is_enabled(priv, irq_mask)));
4086331b51SJijie Shao }
4186331b51SJijie Shao 
hbg_dbg_tx_ring(struct seq_file * s,void * unused)4286331b51SJijie Shao static int hbg_dbg_tx_ring(struct seq_file *s, void *unused)
4386331b51SJijie Shao {
4486331b51SJijie Shao 	struct net_device *netdev = dev_get_drvdata(s->private);
4586331b51SJijie Shao 	struct hbg_priv *priv = netdev_priv(netdev);
4686331b51SJijie Shao 
4786331b51SJijie Shao 	hbg_dbg_ring(priv, &priv->tx_ring, s);
4886331b51SJijie Shao 	return 0;
4986331b51SJijie Shao }
5086331b51SJijie Shao 
hbg_dbg_rx_ring(struct seq_file * s,void * unused)5186331b51SJijie Shao static int hbg_dbg_rx_ring(struct seq_file *s, void *unused)
5286331b51SJijie Shao {
5386331b51SJijie Shao 	struct net_device *netdev = dev_get_drvdata(s->private);
5486331b51SJijie Shao 	struct hbg_priv *priv = netdev_priv(netdev);
5586331b51SJijie Shao 
5686331b51SJijie Shao 	hbg_dbg_ring(priv, &priv->rx_ring, s);
5786331b51SJijie Shao 	return 0;
5886331b51SJijie Shao }
5986331b51SJijie Shao 
hbg_dbg_irq_info(struct seq_file * s,void * unused)60df491c41SJijie Shao static int hbg_dbg_irq_info(struct seq_file *s, void *unused)
61df491c41SJijie Shao {
62df491c41SJijie Shao 	struct net_device *netdev = dev_get_drvdata(s->private);
63df491c41SJijie Shao 	struct hbg_priv *priv = netdev_priv(netdev);
644ad3df75SJijie Shao 	const struct hbg_irq_info *info;
65df491c41SJijie Shao 	u32 i;
66df491c41SJijie Shao 
67df491c41SJijie Shao 	for (i = 0; i < priv->vectors.info_array_len; i++) {
68df491c41SJijie Shao 		info = &priv->vectors.info_array[i];
69df491c41SJijie Shao 		seq_printf(s,
70fd394a33SJijie Shao 			   "%-20s: enabled: %-5s, reset: %-5s, logged: %-5s, count: %llu\n",
71df491c41SJijie Shao 			   info->name,
72df491c41SJijie Shao 			   str_true_false(hbg_hw_irq_is_enabled(priv,
73df491c41SJijie Shao 								info->mask)),
74fd394a33SJijie Shao 			   str_true_false(info->need_reset),
75df491c41SJijie Shao 			   str_true_false(info->need_print),
764ad3df75SJijie Shao 			   priv->vectors.stats_array[i]);
77df491c41SJijie Shao 	}
78df491c41SJijie Shao 
79df491c41SJijie Shao 	return 0;
80df491c41SJijie Shao }
81df491c41SJijie Shao 
hbg_dbg_mac_table(struct seq_file * s,void * unused)8237b367d6SJijie Shao static int hbg_dbg_mac_table(struct seq_file *s, void *unused)
8337b367d6SJijie Shao {
8437b367d6SJijie Shao 	struct net_device *netdev = dev_get_drvdata(s->private);
8537b367d6SJijie Shao 	struct hbg_priv *priv = netdev_priv(netdev);
8637b367d6SJijie Shao 	struct hbg_mac_filter *filter;
8737b367d6SJijie Shao 	u32 i;
8837b367d6SJijie Shao 
8937b367d6SJijie Shao 	filter = &priv->filter;
9037b367d6SJijie Shao 	seq_printf(s, "mac addr max count: %u\n", filter->table_max_len);
9137b367d6SJijie Shao 	seq_printf(s, "filter enabled: %s\n", str_true_false(filter->enabled));
9237b367d6SJijie Shao 
9337b367d6SJijie Shao 	for (i = 0; i < filter->table_max_len; i++) {
9437b367d6SJijie Shao 		if (is_zero_ether_addr(filter->mac_table[i].addr))
9537b367d6SJijie Shao 			continue;
9637b367d6SJijie Shao 
9737b367d6SJijie Shao 		seq_printf(s, "[%u] %pM\n", i, filter->mac_table[i].addr);
9837b367d6SJijie Shao 	}
9937b367d6SJijie Shao 
10037b367d6SJijie Shao 	return 0;
10137b367d6SJijie Shao }
10237b367d6SJijie Shao 
1033f5a61f6SJijie Shao static const char * const reset_type_str[] = {"None", "FLR", "Function"};
1043f5a61f6SJijie Shao 
hbg_dbg_nic_state(struct seq_file * s,void * unused)1053f5a61f6SJijie Shao static int hbg_dbg_nic_state(struct seq_file *s, void *unused)
1063f5a61f6SJijie Shao {
1073f5a61f6SJijie Shao 	struct net_device *netdev = dev_get_drvdata(s->private);
1083f5a61f6SJijie Shao 	struct hbg_priv *priv = netdev_priv(netdev);
109*1d6c3e06SJijie Shao 	bool np_link_fail;
1103f5a61f6SJijie Shao 
1113f5a61f6SJijie Shao 	seq_printf(s, "event handling state: %s\n",
1123f5a61f6SJijie Shao 		   state_str_true_false(priv, HBG_NIC_STATE_EVENT_HANDLING));
1133f5a61f6SJijie Shao 	seq_printf(s, "resetting state: %s\n",
1143f5a61f6SJijie Shao 		   state_str_true_false(priv, HBG_NIC_STATE_RESETTING));
1153f5a61f6SJijie Shao 	seq_printf(s, "reset fail state: %s\n",
1163f5a61f6SJijie Shao 		   state_str_true_false(priv, HBG_NIC_STATE_RESET_FAIL));
1173f5a61f6SJijie Shao 	seq_printf(s, "last reset type: %s\n",
1183f5a61f6SJijie Shao 		   reset_type_str[priv->reset_type]);
119fd394a33SJijie Shao 	seq_printf(s, "need reset state: %s\n",
120fd394a33SJijie Shao 		   state_str_true_false(priv, HBG_NIC_STATE_NEED_RESET));
121*1d6c3e06SJijie Shao 
122*1d6c3e06SJijie Shao 	np_link_fail = !hbg_reg_read_field(priv, HBG_REG_AN_NEG_STATE_ADDR,
123*1d6c3e06SJijie Shao 					   HBG_REG_AN_NEG_STATE_NP_LINK_OK_B);
124*1d6c3e06SJijie Shao 	seq_printf(s, "np_link fail state: %s\n", str_true_false(np_link_fail));
1253f5a61f6SJijie Shao 
1263f5a61f6SJijie Shao 	return 0;
1273f5a61f6SJijie Shao }
1283f5a61f6SJijie Shao 
12986331b51SJijie Shao static const struct hbg_dbg_info hbg_dbg_infos[] = {
13086331b51SJijie Shao 	{ "tx_ring", hbg_dbg_tx_ring },
13186331b51SJijie Shao 	{ "rx_ring", hbg_dbg_rx_ring },
132df491c41SJijie Shao 	{ "irq_info", hbg_dbg_irq_info },
13337b367d6SJijie Shao 	{ "mac_table", hbg_dbg_mac_table },
1343f5a61f6SJijie Shao 	{ "nic_state", hbg_dbg_nic_state },
13586331b51SJijie Shao };
13686331b51SJijie Shao 
hbg_debugfs_uninit(void * data)13786331b51SJijie Shao static void hbg_debugfs_uninit(void *data)
13886331b51SJijie Shao {
13986331b51SJijie Shao 	debugfs_remove_recursive((struct dentry *)data);
14086331b51SJijie Shao }
14186331b51SJijie Shao 
hbg_debugfs_init(struct hbg_priv * priv)14286331b51SJijie Shao void hbg_debugfs_init(struct hbg_priv *priv)
14386331b51SJijie Shao {
14486331b51SJijie Shao 	const char *name = pci_name(priv->pdev);
14586331b51SJijie Shao 	struct device *dev = &priv->pdev->dev;
14686331b51SJijie Shao 	struct dentry *root;
14786331b51SJijie Shao 	u32 i;
14886331b51SJijie Shao 
14986331b51SJijie Shao 	root = debugfs_create_dir(name, hbg_dbgfs_root);
15086331b51SJijie Shao 
15186331b51SJijie Shao 	for (i = 0; i < ARRAY_SIZE(hbg_dbg_infos); i++)
15286331b51SJijie Shao 		debugfs_create_devm_seqfile(dev, hbg_dbg_infos[i].name,
15386331b51SJijie Shao 					    root, hbg_dbg_infos[i].read);
15486331b51SJijie Shao 
15586331b51SJijie Shao 	/* Ignore the failure because debugfs is not a key feature. */
15686331b51SJijie Shao 	devm_add_action_or_reset(dev, hbg_debugfs_uninit, root);
15786331b51SJijie Shao }
15886331b51SJijie Shao 
hbg_debugfs_register(void)15986331b51SJijie Shao void hbg_debugfs_register(void)
16086331b51SJijie Shao {
16186331b51SJijie Shao 	hbg_dbgfs_root = debugfs_create_dir("hibmcge", NULL);
16286331b51SJijie Shao }
16386331b51SJijie Shao 
hbg_debugfs_unregister(void)16486331b51SJijie Shao void hbg_debugfs_unregister(void)
16586331b51SJijie Shao {
16686331b51SJijie Shao 	debugfs_remove_recursive(hbg_dbgfs_root);
16786331b51SJijie Shao 	hbg_dbgfs_root = NULL;
16886331b51SJijie Shao }
169