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 15 static struct dentry *hbg_dbgfs_root; 16 17 struct 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 24 static 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 42 static 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 51 static 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 60 static 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 82 static 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 103 static const char * const reset_type_str[] = {"None", "FLR", "Function"}; 104 105 static 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 129 static 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 137 static void hbg_debugfs_uninit(void *data) 138 { 139 debugfs_remove_recursive((struct dentry *)data); 140 } 141 142 void 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 159 void hbg_debugfs_register(void) 160 { 161 hbg_dbgfs_root = debugfs_create_dir("hibmcge", NULL); 162 } 163 164 void hbg_debugfs_unregister(void) 165 { 166 debugfs_remove_recursive(hbg_dbgfs_root); 167 hbg_dbgfs_root = NULL; 168 } 169