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 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 info->count); 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 110 seq_printf(s, "event handling state: %s\n", 111 state_str_true_false(priv, HBG_NIC_STATE_EVENT_HANDLING)); 112 seq_printf(s, "resetting state: %s\n", 113 state_str_true_false(priv, HBG_NIC_STATE_RESETTING)); 114 seq_printf(s, "reset fail state: %s\n", 115 state_str_true_false(priv, HBG_NIC_STATE_RESET_FAIL)); 116 seq_printf(s, "last reset type: %s\n", 117 reset_type_str[priv->reset_type]); 118 seq_printf(s, "need reset state: %s\n", 119 state_str_true_false(priv, HBG_NIC_STATE_NEED_RESET)); 120 seq_printf(s, "np_link fail state: %s\n", 121 state_str_true_false(priv, HBG_NIC_STATE_NP_LINK_FAIL)); 122 123 return 0; 124 } 125 126 static const struct hbg_dbg_info hbg_dbg_infos[] = { 127 { "tx_ring", hbg_dbg_tx_ring }, 128 { "rx_ring", hbg_dbg_rx_ring }, 129 { "irq_info", hbg_dbg_irq_info }, 130 { "mac_table", hbg_dbg_mac_table }, 131 { "nic_state", hbg_dbg_nic_state }, 132 }; 133 134 static void hbg_debugfs_uninit(void *data) 135 { 136 debugfs_remove_recursive((struct dentry *)data); 137 } 138 139 void hbg_debugfs_init(struct hbg_priv *priv) 140 { 141 const char *name = pci_name(priv->pdev); 142 struct device *dev = &priv->pdev->dev; 143 struct dentry *root; 144 u32 i; 145 146 root = debugfs_create_dir(name, hbg_dbgfs_root); 147 148 for (i = 0; i < ARRAY_SIZE(hbg_dbg_infos); i++) 149 debugfs_create_devm_seqfile(dev, hbg_dbg_infos[i].name, 150 root, hbg_dbg_infos[i].read); 151 152 /* Ignore the failure because debugfs is not a key feature. */ 153 devm_add_action_or_reset(dev, hbg_debugfs_uninit, root); 154 } 155 156 void hbg_debugfs_register(void) 157 { 158 hbg_dbgfs_root = debugfs_create_dir("hibmcge", NULL); 159 } 160 161 void hbg_debugfs_unregister(void) 162 { 163 debugfs_remove_recursive(hbg_dbgfs_root); 164 hbg_dbgfs_root = NULL; 165 } 166