File Index
Files and directories
Sign in
FILE

hbg_debugfs.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/hisilicon/hibmcge/hbg_debugfs.c C
  1// SPDX-License-Identifier: GPL-2.0+
  2// Copyright (c) 2024 Hisilicon Limited.
  3
  4#include <linux/debugfs.h>
  5#include <linux/device.h>
  6#include <linux/etherdevice.h>
  7#include <linux/seq_file.h>
  8#include <linux/string_choices.h>
  9#include "hbg_common.h"
 10#include "hbg_debugfs.h"
 11#include "hbg_hw.h"
 12#include "hbg_irq.h"
 13#include "hbg_txrx.h"
 14
 15static struct dentry *hbg_dbgfs_root;
 16
 17struct hbg_dbg_info {
 18	const char *name;
 19	int (*read)(struct seq_file *seq, void *data);
 20};
 21
 22#define state_str_true_false(p, s) str_true_false(test_bit(s, &(p)->state))
 23
 24static void hbg_dbg_ring(struct hbg_priv *priv, struct hbg_ring *ring,
 25			 struct seq_file *s)
 26{
 27	u32 irq_mask = ring->dir == HBG_DIR_TX ? HBG_INT_MSK_TX_B :
 28						 HBG_INT_MSK_RX_B;
 29
 30	seq_printf(s, "ring used num: %u\n",
 31		   hbg_get_queue_used_num(ring));
 32	seq_printf(s, "ring max num: %u\n", ring->len);
 33	seq_printf(s, "ring head: %u, tail: %u\n", ring->head, ring->tail);
 34	seq_printf(s, "fifo used num: %u\n",
 35		   hbg_hw_get_fifo_used_num(priv, ring->dir));
 36	seq_printf(s, "fifo max num: %u\n",
 37		   hbg_get_spec_fifo_max_num(priv, ring->dir));
 38	seq_printf(s, "irq enabled: %s\n",
 39		   str_true_false(hbg_hw_irq_is_enabled(priv, irq_mask)));
 40}
 41
 42static int hbg_dbg_tx_ring(struct seq_file *s, void *unused)
 43{
 44	struct net_device *netdev = dev_get_drvdata(s->private);
 45	struct hbg_priv *priv = netdev_priv(netdev);
 46
 47	hbg_dbg_ring(priv, &priv->tx_ring, s);
 48	return 0;
 49}
 50
 51static int hbg_dbg_rx_ring(struct seq_file *s, void *unused)
 52{
 53	struct net_device *netdev = dev_get_drvdata(s->private);
 54	struct hbg_priv *priv = netdev_priv(netdev);
 55
 56	hbg_dbg_ring(priv, &priv->rx_ring, s);
 57	return 0;
 58}
 59
 60static int hbg_dbg_irq_info(struct seq_file *s, void *unused)
 61{
 62	struct net_device *netdev = dev_get_drvdata(s->private);
 63	struct hbg_priv *priv = netdev_priv(netdev);
 64	const struct hbg_irq_info *info;
 65	u32 i;
 66
 67	for (i = 0; i < priv->vectors.info_array_len; i++) {
 68		info = &priv->vectors.info_array[i];
 69		seq_printf(s,
 70			   "%-20s: enabled: %-5s, reset: %-5s, logged: %-5s, count: %llu\n",
 71			   info->name,
 72			   str_true_false(hbg_hw_irq_is_enabled(priv,
 73								info->mask)),
 74			   str_true_false(info->need_reset),
 75			   str_true_false(info->need_print),
 76			   priv->vectors.stats_array[i]);
 77	}
 78
 79	return 0;
 80}
 81
 82static int hbg_dbg_mac_table(struct seq_file *s, void *unused)
 83{
 84	struct net_device *netdev = dev_get_drvdata(s->private);
 85	struct hbg_priv *priv = netdev_priv(netdev);
 86	struct hbg_mac_filter *filter;
 87	u32 i;
 88
 89	filter = &priv->filter;
 90	seq_printf(s, "mac addr max count: %u\n", filter->table_max_len);
 91	seq_printf(s, "filter enabled: %s\n", str_true_false(filter->enabled));
 92
 93	for (i = 0; i < filter->table_max_len; i++) {
 94		if (is_zero_ether_addr(filter->mac_table[i].addr))
 95			continue;
 96
 97		seq_printf(s, "[%u] %pM\n", i, filter->mac_table[i].addr);
 98	}
 99
100	return 0;
101}
102
103static const char * const reset_type_str[] = {"None", "FLR", "Function"};
104
105static int hbg_dbg_nic_state(struct seq_file *s, void *unused)
106{
107	struct net_device *netdev = dev_get_drvdata(s->private);
108	struct hbg_priv *priv = netdev_priv(netdev);
109	bool np_link_fail;
110
111	seq_printf(s, "event handling state: %s\n",
112		   state_str_true_false(priv, HBG_NIC_STATE_EVENT_HANDLING));
113	seq_printf(s, "resetting state: %s\n",
114		   state_str_true_false(priv, HBG_NIC_STATE_RESETTING));
115	seq_printf(s, "reset fail state: %s\n",
116		   state_str_true_false(priv, HBG_NIC_STATE_RESET_FAIL));
117	seq_printf(s, "last reset type: %s\n",
118		   reset_type_str[priv->reset_type]);
119	seq_printf(s, "need reset state: %s\n",
120		   state_str_true_false(priv, HBG_NIC_STATE_NEED_RESET));
121
122	np_link_fail = !hbg_reg_read_field(priv, HBG_REG_AN_NEG_STATE_ADDR,
123					   HBG_REG_AN_NEG_STATE_NP_LINK_OK_B);
124	seq_printf(s, "np_link fail state: %s\n", str_true_false(np_link_fail));
125
126	return 0;
127}
128
129static const struct hbg_dbg_info hbg_dbg_infos[] = {
130	{ "tx_ring", hbg_dbg_tx_ring },
131	{ "rx_ring", hbg_dbg_rx_ring },
132	{ "irq_info", hbg_dbg_irq_info },
133	{ "mac_table", hbg_dbg_mac_table },
134	{ "nic_state", hbg_dbg_nic_state },
135};
136
137static void hbg_debugfs_uninit(void *data)
138{
139	debugfs_remove_recursive((struct dentry *)data);
140}
141
142void hbg_debugfs_init(struct hbg_priv *priv)
143{
144	const char *name = pci_name(priv->pdev);
145	struct device *dev = &priv->pdev->dev;
146	struct dentry *root;
147	u32 i;
148
149	root = debugfs_create_dir(name, hbg_dbgfs_root);
150
151	for (i = 0; i < ARRAY_SIZE(hbg_dbg_infos); i++)
152		debugfs_create_devm_seqfile(dev, hbg_dbg_infos[i].name,
153					    root, hbg_dbg_infos[i].read);
154
155	/* Ignore the failure because debugfs is not a key feature. */
156	devm_add_action_or_reset(dev, hbg_debugfs_uninit, root);
157}
158
159void hbg_debugfs_register(void)
160{
161	hbg_dbgfs_root = debugfs_create_dir("hibmcge", NULL);
162}
163
164void hbg_debugfs_unregister(void)
165{
166	debugfs_remove_recursive(hbg_dbgfs_root);
167	hbg_dbgfs_root = NULL;
168}
~/ Read-only file preview.