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, 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_print), 75 info->count); 76 } 77 78 return 0; 79 } 80 81 static int hbg_dbg_mac_table(struct seq_file *s, void *unused) 82 { 83 struct net_device *netdev = dev_get_drvdata(s->private); 84 struct hbg_priv *priv = netdev_priv(netdev); 85 struct hbg_mac_filter *filter; 86 u32 i; 87 88 filter = &priv->filter; 89 seq_printf(s, "mac addr max count: %u\n", filter->table_max_len); 90 seq_printf(s, "filter enabled: %s\n", str_true_false(filter->enabled)); 91 92 for (i = 0; i < filter->table_max_len; i++) { 93 if (is_zero_ether_addr(filter->mac_table[i].addr)) 94 continue; 95 96 seq_printf(s, "[%u] %pM\n", i, filter->mac_table[i].addr); 97 } 98 99 return 0; 100 } 101 102 static const char * const reset_type_str[] = {"None", "FLR", "Function"}; 103 104 static int hbg_dbg_nic_state(struct seq_file *s, void *unused) 105 { 106 struct net_device *netdev = dev_get_drvdata(s->private); 107 struct hbg_priv *priv = netdev_priv(netdev); 108 109 seq_printf(s, "event handling state: %s\n", 110 state_str_true_false(priv, HBG_NIC_STATE_EVENT_HANDLING)); 111 seq_printf(s, "resetting state: %s\n", 112 state_str_true_false(priv, HBG_NIC_STATE_RESETTING)); 113 seq_printf(s, "reset fail state: %s\n", 114 state_str_true_false(priv, HBG_NIC_STATE_RESET_FAIL)); 115 seq_printf(s, "last reset type: %s\n", 116 reset_type_str[priv->reset_type]); 117 118 return 0; 119 } 120 121 static const struct hbg_dbg_info hbg_dbg_infos[] = { 122 { "tx_ring", hbg_dbg_tx_ring }, 123 { "rx_ring", hbg_dbg_rx_ring }, 124 { "irq_info", hbg_dbg_irq_info }, 125 { "mac_table", hbg_dbg_mac_table }, 126 { "nic_state", hbg_dbg_nic_state }, 127 }; 128 129 static void hbg_debugfs_uninit(void *data) 130 { 131 debugfs_remove_recursive((struct dentry *)data); 132 } 133 134 void hbg_debugfs_init(struct hbg_priv *priv) 135 { 136 const char *name = pci_name(priv->pdev); 137 struct device *dev = &priv->pdev->dev; 138 struct dentry *root; 139 u32 i; 140 141 root = debugfs_create_dir(name, hbg_dbgfs_root); 142 143 for (i = 0; i < ARRAY_SIZE(hbg_dbg_infos); i++) 144 debugfs_create_devm_seqfile(dev, hbg_dbg_infos[i].name, 145 root, hbg_dbg_infos[i].read); 146 147 /* Ignore the failure because debugfs is not a key feature. */ 148 devm_add_action_or_reset(dev, hbg_debugfs_uninit, root); 149 } 150 151 void hbg_debugfs_register(void) 152 { 153 hbg_dbgfs_root = debugfs_create_dir("hibmcge", NULL); 154 } 155 156 void hbg_debugfs_unregister(void) 157 { 158 debugfs_remove_recursive(hbg_dbgfs_root); 159 hbg_dbgfs_root = NULL; 160 } 161