xref: /linux/drivers/net/ethernet/hisilicon/hibmcge/hbg_debugfs.c (revision 0ad9617c78acbc71373fb341a6f75d4012b01d69)
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 
22*3f5a61f6SJijie Shao #define state_str_true_false(p, s) str_true_false(test_bit(s, &(p)->state))
23*3f5a61f6SJijie Shao 
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 
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 
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 
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);
64df491c41SJijie Shao 	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,
70df491c41SJijie Shao 			   "%-20s: enabled: %-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)),
74df491c41SJijie Shao 			   str_true_false(info->need_print),
75df491c41SJijie Shao 			   info->count);
76df491c41SJijie Shao 	}
77df491c41SJijie Shao 
78df491c41SJijie Shao 	return 0;
79df491c41SJijie Shao }
80df491c41SJijie Shao 
8137b367d6SJijie Shao static int hbg_dbg_mac_table(struct seq_file *s, void *unused)
8237b367d6SJijie Shao {
8337b367d6SJijie Shao 	struct net_device *netdev = dev_get_drvdata(s->private);
8437b367d6SJijie Shao 	struct hbg_priv *priv = netdev_priv(netdev);
8537b367d6SJijie Shao 	struct hbg_mac_filter *filter;
8637b367d6SJijie Shao 	u32 i;
8737b367d6SJijie Shao 
8837b367d6SJijie Shao 	filter = &priv->filter;
8937b367d6SJijie Shao 	seq_printf(s, "mac addr max count: %u\n", filter->table_max_len);
9037b367d6SJijie Shao 	seq_printf(s, "filter enabled: %s\n", str_true_false(filter->enabled));
9137b367d6SJijie Shao 
9237b367d6SJijie Shao 	for (i = 0; i < filter->table_max_len; i++) {
9337b367d6SJijie Shao 		if (is_zero_ether_addr(filter->mac_table[i].addr))
9437b367d6SJijie Shao 			continue;
9537b367d6SJijie Shao 
9637b367d6SJijie Shao 		seq_printf(s, "[%u] %pM\n", i, filter->mac_table[i].addr);
9737b367d6SJijie Shao 	}
9837b367d6SJijie Shao 
9937b367d6SJijie Shao 	return 0;
10037b367d6SJijie Shao }
10137b367d6SJijie Shao 
102*3f5a61f6SJijie Shao static const char * const reset_type_str[] = {"None", "FLR", "Function"};
103*3f5a61f6SJijie Shao 
104*3f5a61f6SJijie Shao static int hbg_dbg_nic_state(struct seq_file *s, void *unused)
105*3f5a61f6SJijie Shao {
106*3f5a61f6SJijie Shao 	struct net_device *netdev = dev_get_drvdata(s->private);
107*3f5a61f6SJijie Shao 	struct hbg_priv *priv = netdev_priv(netdev);
108*3f5a61f6SJijie Shao 
109*3f5a61f6SJijie Shao 	seq_printf(s, "event handling state: %s\n",
110*3f5a61f6SJijie Shao 		   state_str_true_false(priv, HBG_NIC_STATE_EVENT_HANDLING));
111*3f5a61f6SJijie Shao 	seq_printf(s, "resetting state: %s\n",
112*3f5a61f6SJijie Shao 		   state_str_true_false(priv, HBG_NIC_STATE_RESETTING));
113*3f5a61f6SJijie Shao 	seq_printf(s, "reset fail state: %s\n",
114*3f5a61f6SJijie Shao 		   state_str_true_false(priv, HBG_NIC_STATE_RESET_FAIL));
115*3f5a61f6SJijie Shao 	seq_printf(s, "last reset type: %s\n",
116*3f5a61f6SJijie Shao 		   reset_type_str[priv->reset_type]);
117*3f5a61f6SJijie Shao 
118*3f5a61f6SJijie Shao 	return 0;
119*3f5a61f6SJijie Shao }
120*3f5a61f6SJijie Shao 
12186331b51SJijie Shao static const struct hbg_dbg_info hbg_dbg_infos[] = {
12286331b51SJijie Shao 	{ "tx_ring", hbg_dbg_tx_ring },
12386331b51SJijie Shao 	{ "rx_ring", hbg_dbg_rx_ring },
124df491c41SJijie Shao 	{ "irq_info", hbg_dbg_irq_info },
12537b367d6SJijie Shao 	{ "mac_table", hbg_dbg_mac_table },
126*3f5a61f6SJijie Shao 	{ "nic_state", hbg_dbg_nic_state },
12786331b51SJijie Shao };
12886331b51SJijie Shao 
12986331b51SJijie Shao static void hbg_debugfs_uninit(void *data)
13086331b51SJijie Shao {
13186331b51SJijie Shao 	debugfs_remove_recursive((struct dentry *)data);
13286331b51SJijie Shao }
13386331b51SJijie Shao 
13486331b51SJijie Shao void hbg_debugfs_init(struct hbg_priv *priv)
13586331b51SJijie Shao {
13686331b51SJijie Shao 	const char *name = pci_name(priv->pdev);
13786331b51SJijie Shao 	struct device *dev = &priv->pdev->dev;
13886331b51SJijie Shao 	struct dentry *root;
13986331b51SJijie Shao 	u32 i;
14086331b51SJijie Shao 
14186331b51SJijie Shao 	root = debugfs_create_dir(name, hbg_dbgfs_root);
14286331b51SJijie Shao 
14386331b51SJijie Shao 	for (i = 0; i < ARRAY_SIZE(hbg_dbg_infos); i++)
14486331b51SJijie Shao 		debugfs_create_devm_seqfile(dev, hbg_dbg_infos[i].name,
14586331b51SJijie Shao 					    root, hbg_dbg_infos[i].read);
14686331b51SJijie Shao 
14786331b51SJijie Shao 	/* Ignore the failure because debugfs is not a key feature. */
14886331b51SJijie Shao 	devm_add_action_or_reset(dev, hbg_debugfs_uninit, root);
14986331b51SJijie Shao }
15086331b51SJijie Shao 
15186331b51SJijie Shao void hbg_debugfs_register(void)
15286331b51SJijie Shao {
15386331b51SJijie Shao 	hbg_dbgfs_root = debugfs_create_dir("hibmcge", NULL);
15486331b51SJijie Shao }
15586331b51SJijie Shao 
15686331b51SJijie Shao void hbg_debugfs_unregister(void)
15786331b51SJijie Shao {
15886331b51SJijie Shao 	debugfs_remove_recursive(hbg_dbgfs_root);
15986331b51SJijie Shao 	hbg_dbgfs_root = NULL;
16086331b51SJijie Shao }
161