hns3_debugfs.c 11.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
// SPDX-License-Identifier: GPL-2.0+
/* Copyright (c) 2018-2019 Hisilicon Limited. */

#include <linux/debugfs.h>
#include <linux/device.h>

#include "hnae3.h"
#include "hns3_enet.h"

#define HNS3_DBG_READ_LEN 256
11
#define HNS3_DBG_WRITE_LEN 1024
12 13 14

static struct dentry *hns3_dbgfs_root;

15 16
static int hns3_dbg_queue_info(struct hnae3_handle *h,
			       const char *cmd_buf)
17 18 19 20 21 22 23 24
{
	struct hns3_nic_priv *priv = h->priv;
	struct hns3_enet_ring *ring;
	u32 base_add_l, base_add_h;
	u32 queue_num, queue_max;
	u32 value, i = 0;
	int cnt;

25 26
	if (!priv->ring) {
		dev_err(&h->pdev->dev, "priv->ring is NULL\n");
27 28 29 30 31 32 33 34 35 36 37 38 39 40
		return -EFAULT;
	}

	queue_max = h->kinfo.num_tqps;
	cnt = kstrtouint(&cmd_buf[11], 0, &queue_num);
	if (cnt)
		queue_num = 0;
	else
		queue_max = queue_num + 1;

	dev_info(&h->pdev->dev, "queue info\n");

	if (queue_num >= h->kinfo.num_tqps) {
		dev_err(&h->pdev->dev,
41
			"Queue number(%u) is out of range(0-%u)\n", queue_num,
42 43 44 45 46 47 48 49 50
			h->kinfo.num_tqps - 1);
		return -EINVAL;
	}

	for (i = queue_num; i < queue_max; i++) {
		/* Each cycle needs to determine whether the instance is reset,
		 * to prevent reference to invalid memory. And need to ensure
		 * that the following code is executed within 100ms.
		 */
51
		if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
52 53 54
		    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
			return -EPERM;

55
		ring = &priv->ring[(u32)(i + h->kinfo.num_tqps)];
56 57 58 59
		base_add_h = readl_relaxed(ring->tqp->io_base +
					   HNS3_RING_RX_RING_BASEADDR_H_REG);
		base_add_l = readl_relaxed(ring->tqp->io_base +
					   HNS3_RING_RX_RING_BASEADDR_L_REG);
60
		dev_info(&h->pdev->dev, "RX(%u) BASE ADD: 0x%08x%08x\n", i,
61 62 63 64
			 base_add_h, base_add_l);

		value = readl_relaxed(ring->tqp->io_base +
				      HNS3_RING_RX_RING_BD_NUM_REG);
65
		dev_info(&h->pdev->dev, "RX(%u) RING BD NUM: %u\n", i, value);
66 67 68

		value = readl_relaxed(ring->tqp->io_base +
				      HNS3_RING_RX_RING_BD_LEN_REG);
69
		dev_info(&h->pdev->dev, "RX(%u) RING BD LEN: %u\n", i, value);
70 71 72

		value = readl_relaxed(ring->tqp->io_base +
				      HNS3_RING_RX_RING_TAIL_REG);
73
		dev_info(&h->pdev->dev, "RX(%u) RING TAIL: %u\n", i, value);
74 75 76

		value = readl_relaxed(ring->tqp->io_base +
				      HNS3_RING_RX_RING_HEAD_REG);
77
		dev_info(&h->pdev->dev, "RX(%u) RING HEAD: %u\n", i, value);
78 79 80

		value = readl_relaxed(ring->tqp->io_base +
				      HNS3_RING_RX_RING_FBDNUM_REG);
81
		dev_info(&h->pdev->dev, "RX(%u) RING FBDNUM: %u\n", i, value);
82 83 84

		value = readl_relaxed(ring->tqp->io_base +
				      HNS3_RING_RX_RING_PKTNUM_RECORD_REG);
85
		dev_info(&h->pdev->dev, "RX(%u) RING PKTNUM: %u\n", i, value);
86

87
		ring = &priv->ring[i];
88 89 90 91
		base_add_h = readl_relaxed(ring->tqp->io_base +
					   HNS3_RING_TX_RING_BASEADDR_H_REG);
		base_add_l = readl_relaxed(ring->tqp->io_base +
					   HNS3_RING_TX_RING_BASEADDR_L_REG);
92
		dev_info(&h->pdev->dev, "TX(%u) BASE ADD: 0x%08x%08x\n", i,
93 94 95 96
			 base_add_h, base_add_l);

		value = readl_relaxed(ring->tqp->io_base +
				      HNS3_RING_TX_RING_BD_NUM_REG);
97
		dev_info(&h->pdev->dev, "TX(%u) RING BD NUM: %u\n", i, value);
98 99 100

		value = readl_relaxed(ring->tqp->io_base +
				      HNS3_RING_TX_RING_TC_REG);
101
		dev_info(&h->pdev->dev, "TX(%u) RING TC: %u\n", i, value);
102 103 104

		value = readl_relaxed(ring->tqp->io_base +
				      HNS3_RING_TX_RING_TAIL_REG);
105
		dev_info(&h->pdev->dev, "TX(%u) RING TAIL: %u\n", i, value);
106 107 108

		value = readl_relaxed(ring->tqp->io_base +
				      HNS3_RING_TX_RING_HEAD_REG);
109
		dev_info(&h->pdev->dev, "TX(%u) RING HEAD: %u\n", i, value);
110 111 112

		value = readl_relaxed(ring->tqp->io_base +
				      HNS3_RING_TX_RING_FBDNUM_REG);
113
		dev_info(&h->pdev->dev, "TX(%u) RING FBDNUM: %u\n", i, value);
114 115 116

		value = readl_relaxed(ring->tqp->io_base +
				      HNS3_RING_TX_RING_OFFSET_REG);
117
		dev_info(&h->pdev->dev, "TX(%u) RING OFFSET: %u\n", i, value);
118 119 120

		value = readl_relaxed(ring->tqp->io_base +
				      HNS3_RING_TX_RING_PKTNUM_RECORD_REG);
121
		dev_info(&h->pdev->dev, "TX(%u) RING PKTNUM: %u\n\n", i,
122 123 124 125 126 127
			 value);
	}

	return 0;
}

128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
static int hns3_dbg_queue_map(struct hnae3_handle *h)
{
	struct hns3_nic_priv *priv = h->priv;
	int i;

	if (!h->ae_algo->ops->get_global_queue_id)
		return -EOPNOTSUPP;

	dev_info(&h->pdev->dev, "map info for queue id and vector id\n");
	dev_info(&h->pdev->dev,
		 "local queue id | global queue id | vector id\n");
	for (i = 0; i < h->kinfo.num_tqps; i++) {
		u16 global_qid;

		global_qid = h->ae_algo->ops->get_global_queue_id(h, i);
143
		if (!priv->ring || !priv->ring[i].tqp_vector)
144 145 146 147
			continue;

		dev_info(&h->pdev->dev,
			 "      %4d            %4d            %4d\n",
148
			 i, global_qid, priv->ring[i].tqp_vector->vector_irq);
149 150 151 152 153
	}

	return 0;
}

154
static int hns3_dbg_bd_info(struct hnae3_handle *h, const char *cmd_buf)
155 156 157 158 159 160 161
{
	struct hns3_nic_priv *priv = h->priv;
	struct hns3_desc *rx_desc, *tx_desc;
	struct device *dev = &h->pdev->dev;
	struct hns3_enet_ring *ring;
	u32 tx_index, rx_index;
	u32 q_num, value;
162
	dma_addr_t addr;
163 164 165 166 167 168 169 170 171 172 173
	int cnt;

	cnt = sscanf(&cmd_buf[8], "%u %u", &q_num, &tx_index);
	if (cnt == 2) {
		rx_index = tx_index;
	} else if (cnt != 1) {
		dev_err(dev, "bd info: bad command string, cnt=%d\n", cnt);
		return -EINVAL;
	}

	if (q_num >= h->kinfo.num_tqps) {
174
		dev_err(dev, "Queue number(%u) is out of range(0-%u)\n", q_num,
175 176 177 178
			h->kinfo.num_tqps - 1);
		return -EINVAL;
	}

179
	ring  = &priv->ring[q_num];
180 181 182 183
	value = readl_relaxed(ring->tqp->io_base + HNS3_RING_TX_RING_TAIL_REG);
	tx_index = (cnt == 1) ? value : tx_index;

	if (tx_index >= ring->desc_num) {
184
		dev_err(dev, "bd index(%u) is out of range(0-%u)\n", tx_index,
185 186 187 188 189
			ring->desc_num - 1);
		return -EINVAL;
	}

	tx_desc = &ring->desc[tx_index];
190
	addr = le64_to_cpu(tx_desc->addr);
191
	dev_info(dev, "TX Queue Num: %u, BD Index: %u\n", q_num, tx_index);
192
	dev_info(dev, "(TX)addr: %pad\n", &addr);
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
	dev_info(dev, "(TX)vlan_tag: %u\n", tx_desc->tx.vlan_tag);
	dev_info(dev, "(TX)send_size: %u\n", tx_desc->tx.send_size);
	dev_info(dev, "(TX)vlan_tso: %u\n", tx_desc->tx.type_cs_vlan_tso);
	dev_info(dev, "(TX)l2_len: %u\n", tx_desc->tx.l2_len);
	dev_info(dev, "(TX)l3_len: %u\n", tx_desc->tx.l3_len);
	dev_info(dev, "(TX)l4_len: %u\n", tx_desc->tx.l4_len);
	dev_info(dev, "(TX)vlan_tag: %u\n", tx_desc->tx.outer_vlan_tag);
	dev_info(dev, "(TX)tv: %u\n", tx_desc->tx.tv);
	dev_info(dev, "(TX)vlan_msec: %u\n", tx_desc->tx.ol_type_vlan_msec);
	dev_info(dev, "(TX)ol2_len: %u\n", tx_desc->tx.ol2_len);
	dev_info(dev, "(TX)ol3_len: %u\n", tx_desc->tx.ol3_len);
	dev_info(dev, "(TX)ol4_len: %u\n", tx_desc->tx.ol4_len);
	dev_info(dev, "(TX)paylen: %u\n", tx_desc->tx.paylen);
	dev_info(dev, "(TX)vld_ra_ri: %u\n", tx_desc->tx.bdtp_fe_sc_vld_ra_ri);
	dev_info(dev, "(TX)mss: %u\n", tx_desc->tx.mss);

209
	ring  = &priv->ring[q_num + h->kinfo.num_tqps];
210 211 212 213
	value = readl_relaxed(ring->tqp->io_base + HNS3_RING_RX_RING_TAIL_REG);
	rx_index = (cnt == 1) ? value : tx_index;
	rx_desc	 = &ring->desc[rx_index];

214
	addr = le64_to_cpu(rx_desc->addr);
215
	dev_info(dev, "RX Queue Num: %u, BD Index: %u\n", q_num, rx_index);
216
	dev_info(dev, "(RX)addr: %pad\n", &addr);
217
	dev_info(dev, "(RX)l234_info: %u\n", rx_desc->rx.l234_info);
218 219 220 221 222 223 224 225 226 227 228 229
	dev_info(dev, "(RX)pkt_len: %u\n", rx_desc->rx.pkt_len);
	dev_info(dev, "(RX)size: %u\n", rx_desc->rx.size);
	dev_info(dev, "(RX)rss_hash: %u\n", rx_desc->rx.rss_hash);
	dev_info(dev, "(RX)fd_id: %u\n", rx_desc->rx.fd_id);
	dev_info(dev, "(RX)vlan_tag: %u\n", rx_desc->rx.vlan_tag);
	dev_info(dev, "(RX)o_dm_vlan_id_fb: %u\n", rx_desc->rx.o_dm_vlan_id_fb);
	dev_info(dev, "(RX)ot_vlan_tag: %u\n", rx_desc->rx.ot_vlan_tag);
	dev_info(dev, "(RX)bd_base_info: %u\n", rx_desc->rx.bd_base_info);

	return 0;
}

230 231
static void hns3_dbg_help(struct hnae3_handle *h)
{
232 233 234 235
#define HNS3_DBG_BUF_LEN 256

	char printf_buf[HNS3_DBG_BUF_LEN];

236
	dev_info(&h->pdev->dev, "available commands\n");
237
	dev_info(&h->pdev->dev, "queue info <number>\n");
238
	dev_info(&h->pdev->dev, "queue map\n");
239
	dev_info(&h->pdev->dev, "bd info <q_num> <bd index>\n");
240 241 242 243

	if (!hns3_is_phys_func(h->pdev))
		return;

244
	dev_info(&h->pdev->dev, "dump fd tcam\n");
245
	dev_info(&h->pdev->dev, "dump tc\n");
246
	dev_info(&h->pdev->dev, "dump tm map <q_num>\n");
247
	dev_info(&h->pdev->dev, "dump tm\n");
248
	dev_info(&h->pdev->dev, "dump qos pause cfg\n");
249
	dev_info(&h->pdev->dev, "dump qos pri map\n");
250
	dev_info(&h->pdev->dev, "dump qos buf cfg\n");
251
	dev_info(&h->pdev->dev, "dump mng tbl\n");
252
	dev_info(&h->pdev->dev, "dump reset info\n");
253
	dev_info(&h->pdev->dev, "dump m7 info\n");
254
	dev_info(&h->pdev->dev, "dump ncl_config <offset> <length>(in hex)\n");
255
	dev_info(&h->pdev->dev, "dump mac tnl status\n");
256 257

	memset(printf_buf, 0, HNS3_DBG_BUF_LEN);
258
	strncat(printf_buf, "dump reg [[bios common] [ssu <port_id>]",
259 260
		HNS3_DBG_BUF_LEN - 1);
	strncat(printf_buf + strlen(printf_buf),
261
		" [igu egu <port_id>] [rpu <tc_queue_num>]",
262 263
		HNS3_DBG_BUF_LEN - strlen(printf_buf) - 1);
	strncat(printf_buf + strlen(printf_buf),
264
		" [rtc] [ppp] [rcb] [tqp <queue_num>]]\n",
265 266
		HNS3_DBG_BUF_LEN - strlen(printf_buf) - 1);
	dev_info(&h->pdev->dev, "%s", printf_buf);
267 268

	memset(printf_buf, 0, HNS3_DBG_BUF_LEN);
269
	strncat(printf_buf, "dump reg dcb <port_id> <pri_id> <pg_id>",
270
		HNS3_DBG_BUF_LEN - 1);
271
	strncat(printf_buf + strlen(printf_buf), " <rq_id> <nq_id> <qset_id>\n",
272 273
		HNS3_DBG_BUF_LEN - strlen(printf_buf) - 1);
	dev_info(&h->pdev->dev, "%s", printf_buf);
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
}

static ssize_t hns3_dbg_cmd_read(struct file *filp, char __user *buffer,
				 size_t count, loff_t *ppos)
{
	int uncopy_bytes;
	char *buf;
	int len;

	if (*ppos != 0)
		return 0;

	if (count < HNS3_DBG_READ_LEN)
		return -ENOSPC;

	buf = kzalloc(HNS3_DBG_READ_LEN, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	len = snprintf(buf, HNS3_DBG_READ_LEN, "%s\n",
		       "Please echo help to cmd to get help information");
	uncopy_bytes = copy_to_user(buffer, buf, len);

	kfree(buf);

	if (uncopy_bytes)
		return -EFAULT;

	return (*ppos = len);
}

static ssize_t hns3_dbg_cmd_write(struct file *filp, const char __user *buffer,
				  size_t count, loff_t *ppos)
{
	struct hnae3_handle *handle = filp->private_data;
309
	struct hns3_nic_priv *priv  = handle->priv;
310 311 312 313 314 315 316
	char *cmd_buf, *cmd_buf_tmp;
	int uncopied_bytes;
	int ret = 0;

	if (*ppos != 0)
		return 0;

317
	/* Judge if the instance is being reset. */
318
	if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
319 320 321
	    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
		return 0;

322 323 324
	if (count > HNS3_DBG_WRITE_LEN)
		return -ENOSPC;

325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
	cmd_buf = kzalloc(count + 1, GFP_KERNEL);
	if (!cmd_buf)
		return count;

	uncopied_bytes = copy_from_user(cmd_buf, buffer, count);
	if (uncopied_bytes) {
		kfree(cmd_buf);
		return -EFAULT;
	}

	cmd_buf[count] = '\0';

	cmd_buf_tmp = strchr(cmd_buf, '\n');
	if (cmd_buf_tmp) {
		*cmd_buf_tmp = '\0';
		count = cmd_buf_tmp - cmd_buf + 1;
	}

	if (strncmp(cmd_buf, "help", 4) == 0)
		hns3_dbg_help(handle);
345 346
	else if (strncmp(cmd_buf, "queue info", 10) == 0)
		ret = hns3_dbg_queue_info(handle, cmd_buf);
347 348
	else if (strncmp(cmd_buf, "queue map", 9) == 0)
		ret = hns3_dbg_queue_map(handle);
349 350
	else if (strncmp(cmd_buf, "bd info", 7) == 0)
		ret = hns3_dbg_bd_info(handle, cmd_buf);
351 352
	else if (handle->ae_algo->ops->dbg_run_cmd)
		ret = handle->ae_algo->ops->dbg_run_cmd(handle, cmd_buf);
353 354
	else
		ret = -EOPNOTSUPP;
355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377

	if (ret)
		hns3_dbg_help(handle);

	kfree(cmd_buf);
	cmd_buf = NULL;

	return count;
}

static const struct file_operations hns3_dbg_cmd_fops = {
	.owner = THIS_MODULE,
	.open  = simple_open,
	.read  = hns3_dbg_cmd_read,
	.write = hns3_dbg_cmd_write,
};

void hns3_dbg_init(struct hnae3_handle *handle)
{
	const char *name = pci_name(handle->pdev);

	handle->hnae3_dbgfs = debugfs_create_dir(name, hns3_dbgfs_root);

378 379
	debugfs_create_file("cmd", 0600, handle->hnae3_dbgfs, handle,
			    &hns3_dbg_cmd_fops);
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
}

void hns3_dbg_uninit(struct hnae3_handle *handle)
{
	debugfs_remove_recursive(handle->hnae3_dbgfs);
	handle->hnae3_dbgfs = NULL;
}

void hns3_dbg_register_debugfs(const char *debugfs_dir_name)
{
	hns3_dbgfs_root = debugfs_create_dir(debugfs_dir_name, NULL);
}

void hns3_dbg_unregister_debugfs(void)
{
	debugfs_remove_recursive(hns3_dbgfs_root);
	hns3_dbgfs_root = NULL;
}