Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6b98107 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'hns3-Add-more-commands-to-Debugfs-in-HNS3-driver'

Salil Mehta says:

====================
net: hns3: Add more commands to Debugfs in HNS3 driver

This patch-set adds few more debugfs commands to HNS3 Ethernet
Driver. Support has been added to query info related to below
items:
1. Packet buffer descriptor ("echo bd info [queue no] [bd index] > cmd")
2. Manager table("echo dump mng tbl > cmd")
3. Dfx status register("echo dump reg ssu [prt id] > cmd")
4. Dcb status register("echo dump reg dcb [port id] > cmd")
5. Queue map ("echo queue map [queue no] > cmd")
6. Tm map ("echo tm map [queue no] > cmd")

NOTE: Above commands are *read-only* and are only intended to
query the information from the SoC(and dump inside the kernel,
for now) and in no way tries to perform write operations for
the purpose of configuration etc.

Change Log:
V1-->V2:
1. Addressed the GCC-8.2 compiler issue reported by David S. Miller.
   Link: https://lkml.org/lkml/2018/12/14/1298


====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b9948e11 82e00b86
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ enum HCLGE_MBX_OPCODE {
	HCLGE_MBX_KEEP_ALIVE,		/* (VF -> PF) send keep alive cmd */
	HCLGE_MBX_SET_ALIVE,		/* (VF -> PF) set alive state */
	HCLGE_MBX_SET_MTU,		/* (VF -> PF) set mtu */
	HCLGE_MBX_GET_QID_IN_PF,	/* (VF -> PF) get queue id in pf */
};

/* below are per-VF mac-vlan subcodes */
+1 −0
Original line number Diff line number Diff line
@@ -460,6 +460,7 @@ struct hnae3_ae_ops {
	bool (*ae_dev_resetting)(struct hnae3_handle *handle);
	unsigned long (*ae_dev_reset_cnt)(struct hnae3_handle *handle);
	int (*set_gro_en)(struct hnae3_handle *handle, int enable);
	u16 (*get_global_queue_id)(struct hnae3_handle *handle, u16 queue_id);
};

struct hnae3_dcb_ops {
+137 −3
Original line number Diff line number Diff line
@@ -48,11 +48,11 @@ static int hns3_dbg_queue_info(struct hnae3_handle *h, char *cmd_buf)
		 * to prevent reference to invalid memory. And need to ensure
		 * that the following code is executed within 100ms.
		 */
		if (test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
		if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
		    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
			return -EPERM;

		ring = ring_data[i + h->kinfo.num_tqps].ring;
		ring = ring_data[(u32)(i + h->kinfo.num_tqps)].ring;
		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 +
@@ -125,16 +125,146 @@ static int hns3_dbg_queue_info(struct hnae3_handle *h, char *cmd_buf)
	return 0;
}

static int hns3_dbg_queue_map(struct hnae3_handle *h)
{
	struct hns3_nic_priv *priv = h->priv;
	struct hns3_nic_ring_data *ring_data;
	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);
		ring_data = &priv->ring_data[i];
		if (!ring_data || !ring_data->ring ||
		    !ring_data->ring->tqp_vector)
			continue;

		dev_info(&h->pdev->dev,
			 "      %4d            %4d            %4d\n",
			 i, global_qid,
			 ring_data->ring->tqp_vector->vector_irq);
	}

	return 0;
}

static int hns3_dbg_bd_info(struct hnae3_handle *h, char *cmd_buf)
{
	struct hns3_nic_priv *priv = h->priv;
	struct hns3_nic_ring_data *ring_data;
	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;
	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) {
		dev_err(dev, "Queue number(%u) is out of range(%u)\n", q_num,
			h->kinfo.num_tqps - 1);
		return -EINVAL;
	}

	ring_data = priv->ring_data;
	ring  = ring_data[q_num].ring;
	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) {
		dev_err(dev, "bd index (%u) is out of range(%u)\n", tx_index,
			ring->desc_num - 1);
		return -EINVAL;
	}

	tx_desc = &ring->desc[tx_index];
	dev_info(dev, "TX Queue Num: %u, BD Index: %u\n", q_num, tx_index);
	dev_info(dev, "(TX) addr: 0x%llx\n", tx_desc->addr);
	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);

	ring  = ring_data[q_num + h->kinfo.num_tqps].ring;
	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];

	dev_info(dev, "RX Queue Num: %u, BD Index: %u\n", q_num, rx_index);
	dev_info(dev, "(RX)addr: 0x%llx\n", rx_desc->addr);
	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;
}

static void hns3_dbg_help(struct hnae3_handle *h)
{
#define HNS3_DBG_BUF_LEN 256

	char printf_buf[HNS3_DBG_BUF_LEN];

	dev_info(&h->pdev->dev, "available commands\n");
	dev_info(&h->pdev->dev, "queue info [number]\n");
	dev_info(&h->pdev->dev, "queue map\n");
	dev_info(&h->pdev->dev, "bd info [q_num] <bd index>\n");
	dev_info(&h->pdev->dev, "dump fd tcam\n");
	dev_info(&h->pdev->dev, "dump tc\n");
	dev_info(&h->pdev->dev, "dump tm map [q_num]\n");
	dev_info(&h->pdev->dev, "dump tm\n");
	dev_info(&h->pdev->dev, "dump qos pause cfg\n");
	dev_info(&h->pdev->dev, "dump qos pri map\n");
	dev_info(&h->pdev->dev, "dump qos buf cfg\n");
	dev_info(&h->pdev->dev, "dump mng tbl\n");

	memset(printf_buf, 0, HNS3_DBG_BUF_LEN);
	strncat(printf_buf, "dump reg [[bios common] [ssu <prt_id>]",
		HNS3_DBG_BUF_LEN - 1);
	strncat(printf_buf + strlen(printf_buf),
		" [igu egu <prt_id>] [rpu <tc_queue_num>]",
		HNS3_DBG_BUF_LEN - strlen(printf_buf) - 1);
	strncat(printf_buf + strlen(printf_buf),
		" [rtc] [ppp] [rcb] [tqp <q_num>]]\n",
		HNS3_DBG_BUF_LEN - strlen(printf_buf) - 1);
	dev_info(&h->pdev->dev, "%s", printf_buf);

	memset(printf_buf, 0, HNS3_DBG_BUF_LEN);
	strncat(printf_buf, "dump reg dcb [port_id] [pri_id] [pg_id]",
		HNS3_DBG_BUF_LEN - 1);
	strncat(printf_buf + strlen(printf_buf), " [rq_id] [nq_id] [qset_id]\n",
		HNS3_DBG_BUF_LEN - strlen(printf_buf) - 1);
	dev_info(&h->pdev->dev, "%s", printf_buf);
}

static ssize_t hns3_dbg_cmd_read(struct file *filp, char __user *buffer,
@@ -179,7 +309,7 @@ static ssize_t hns3_dbg_cmd_write(struct file *filp, const char __user *buffer,
		return 0;

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

@@ -205,6 +335,10 @@ static ssize_t hns3_dbg_cmd_write(struct file *filp, const char __user *buffer,
		hns3_dbg_help(handle);
	else if (strncmp(cmd_buf, "queue info", 10) == 0)
		ret = hns3_dbg_queue_info(handle, cmd_buf);
	else if (strncmp(cmd_buf, "queue map", 9) == 0)
		ret = hns3_dbg_queue_map(handle);
	else if (strncmp(cmd_buf, "bd info", 7) == 0)
		ret = hns3_dbg_bd_info(handle, cmd_buf);
	else if (handle->ae_algo->ops->dbg_run_cmd)
		ret = handle->ae_algo->ops->dbg_run_cmd(handle, cmd_buf);

+43 −0
Original line number Diff line number Diff line
@@ -86,6 +86,20 @@ enum hclge_opcode_type {
	HCLGE_OPC_QUERY_REG_NUM		= 0x0040,
	HCLGE_OPC_QUERY_32_BIT_REG	= 0x0041,
	HCLGE_OPC_QUERY_64_BIT_REG	= 0x0042,
	HCLGE_OPC_DFX_BD_NUM		= 0x0043,
	HCLGE_OPC_DFX_BIOS_COMMON_REG	= 0x0044,
	HCLGE_OPC_DFX_SSU_REG_0		= 0x0045,
	HCLGE_OPC_DFX_SSU_REG_1		= 0x0046,
	HCLGE_OPC_DFX_IGU_EGU_REG	= 0x0047,
	HCLGE_OPC_DFX_RPU_REG_0		= 0x0048,
	HCLGE_OPC_DFX_RPU_REG_1		= 0x0049,
	HCLGE_OPC_DFX_NCSI_REG		= 0x004A,
	HCLGE_OPC_DFX_RTC_REG		= 0x004B,
	HCLGE_OPC_DFX_PPP_REG		= 0x004C,
	HCLGE_OPC_DFX_RCB_REG		= 0x004D,
	HCLGE_OPC_DFX_TQP_REG		= 0x004E,
	HCLGE_OPC_DFX_SSU_REG_2		= 0x004F,
	HCLGE_OPC_DFX_QUERY_CHIP_CAP	= 0x0050,

	/* MAC command */
	HCLGE_OPC_CONFIG_MAC_MODE	= 0x0301,
@@ -126,6 +140,15 @@ enum hclge_opcode_type {
	HCLGE_OPC_TM_QS_SCH_MODE_CFG    = 0x0814,
	HCLGE_OPC_TM_BP_TO_QSET_MAPPING = 0x0815,
	HCLGE_OPC_ETS_TC_WEIGHT		= 0x0843,
	HCLGE_OPC_QSET_DFX_STS		= 0x0844,
	HCLGE_OPC_PRI_DFX_STS		= 0x0845,
	HCLGE_OPC_PG_DFX_STS		= 0x0846,
	HCLGE_OPC_PORT_DFX_STS		= 0x0847,
	HCLGE_OPC_SCH_NQ_CNT		= 0x0848,
	HCLGE_OPC_SCH_RQ_CNT		= 0x0849,
	HCLGE_OPC_TM_INTERNAL_STS	= 0x0850,
	HCLGE_OPC_TM_INTERNAL_CNT	= 0x0851,
	HCLGE_OPC_TM_INTERNAL_STS_1	= 0x0852,

	/* Packet buffer allocate commands */
	HCLGE_OPC_TX_BUFF_ALLOC		= 0x0901,
@@ -142,6 +165,7 @@ enum hclge_opcode_type {
	HCLGE_OPC_CFG_TX_QUEUE		= 0x0B01,
	HCLGE_OPC_QUERY_TX_POINTER	= 0x0B02,
	HCLGE_OPC_QUERY_TX_STATUS	= 0x0B03,
	HCLGE_OPC_TQP_TX_QUEUE_TC	= 0x0B04,
	HCLGE_OPC_CFG_RX_QUEUE		= 0x0B11,
	HCLGE_OPC_QUERY_RX_POINTER	= 0x0B12,
	HCLGE_OPC_QUERY_RX_STATUS	= 0x0B13,
@@ -237,6 +261,7 @@ enum hclge_opcode_type {
	HCLGE_TM_QCN_MEM_INT_CFG	= 0x1A14,
	HCLGE_PPP_CMD0_INT_CMD		= 0x2100,
	HCLGE_PPP_CMD1_INT_CMD		= 0x2101,
	HCLGE_MAC_ETHERTYPE_IDX_RD      = 0x2105,
	HCLGE_NCSI_INT_EN		= 0x2401,
};

@@ -744,6 +769,24 @@ struct hclge_cfg_tx_queue_pointer_cmd {
	u8 rsv[14];
};

#pragma pack(1)
struct hclge_mac_ethertype_idx_rd_cmd {
	u8	flags;
	u8	resp_code;
	__le16  vlan_tag;
	u8      mac_add[6];
	__le16  index;
	__le16	ethter_type;
	__le16  egress_port;
	__le16  egress_queue;
	__le16  rev0;
	u8	i_port_bitmap;
	u8	i_port_direction;
	u8	rev1[2];
};

#pragma pack()

#define HCLGE_TSO_MSS_MIN_S	0
#define HCLGE_TSO_MSS_MIN_M	GENMASK(13, 0)

+446 −0
Original line number Diff line number Diff line
@@ -9,6 +9,300 @@
#include "hclge_tm.h"
#include "hnae3.h"

static int hclge_dbg_get_dfx_bd_num(struct hclge_dev *hdev, int offset)
{
	struct hclge_desc desc[4];
	int ret;

	hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_DFX_BD_NUM, true);
	desc[0].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT);
	hclge_cmd_setup_basic_desc(&desc[1], HCLGE_OPC_DFX_BD_NUM, true);
	desc[1].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT);
	hclge_cmd_setup_basic_desc(&desc[2], HCLGE_OPC_DFX_BD_NUM, true);
	desc[2].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT);
	hclge_cmd_setup_basic_desc(&desc[3], HCLGE_OPC_DFX_BD_NUM, true);

	ret = hclge_cmd_send(&hdev->hw, desc, 4);
	if (ret != HCLGE_CMD_EXEC_SUCCESS) {
		dev_err(&hdev->pdev->dev,
			"get dfx bdnum fail, status is %d.\n", ret);
		return ret;
	}

	return (int)desc[offset / 6].data[offset % 6];
}

static int hclge_dbg_cmd_send(struct hclge_dev *hdev,
			      struct hclge_desc *desc_src,
			      int index, int bd_num,
			      enum hclge_opcode_type cmd)
{
	struct hclge_desc *desc = desc_src;
	int ret, i;

	hclge_cmd_setup_basic_desc(desc, cmd, true);
	desc->data[0] = cpu_to_le32(index);

	for (i = 1; i < bd_num; i++) {
		desc->flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT);
		desc++;
		hclge_cmd_setup_basic_desc(desc, cmd, true);
	}

	ret = hclge_cmd_send(&hdev->hw, desc_src, bd_num);
	if (ret) {
		dev_err(&hdev->pdev->dev,
			"read reg cmd send fail, status is %d.\n", ret);
		return ret;
	}

	return ret;
}

static void hclge_dbg_dump_reg_common(struct hclge_dev *hdev,
				      struct hclge_dbg_dfx_message *dfx_message,
				      char *cmd_buf, int msg_num, int offset,
				      enum hclge_opcode_type cmd)
{
	struct hclge_desc *desc_src;
	struct hclge_desc *desc;
	int bd_num, buf_len;
	int ret, i;
	int index;
	int max;

	ret = kstrtouint(cmd_buf, 10, &index);
	index = (ret != 0) ? 0 : index;

	bd_num = hclge_dbg_get_dfx_bd_num(hdev, offset);
	if (bd_num <= 0)
		return;

	buf_len	 = sizeof(struct hclge_desc) * bd_num;
	desc_src = kzalloc(buf_len, GFP_KERNEL);
	if (!desc_src) {
		dev_err(&hdev->pdev->dev, "call kzalloc failed\n");
		return;
	}

	desc = desc_src;
	ret  = hclge_dbg_cmd_send(hdev, desc, index, bd_num, cmd);
	if (ret != HCLGE_CMD_EXEC_SUCCESS) {
		kfree(desc_src);
		return;
	}

	max = (bd_num * 6) <= msg_num ? (bd_num * 6) : msg_num;

	desc = desc_src;
	for (i = 0; i < max; i++) {
		(((i / 6) > 0) && ((i % 6) == 0)) ? desc++ : desc;
		if (dfx_message->flag)
			dev_info(&hdev->pdev->dev, "%s: 0x%x\n",
				 dfx_message->message, desc->data[i % 6]);

		dfx_message++;
	}

	kfree(desc_src);
}

static void hclge_dbg_dump_dcb(struct hclge_dev *hdev, char *cmd_buf)
{
	struct device *dev = &hdev->pdev->dev;
	struct hclge_dbg_bitmap_cmd *bitmap;
	int rq_id, pri_id, qset_id;
	int port_id, nq_id, pg_id;
	struct hclge_desc desc[2];

	int cnt, ret;

	cnt = sscanf(cmd_buf, "%i %i %i %i %i %i",
		     &port_id, &pri_id, &pg_id, &rq_id, &nq_id, &qset_id);
	if (cnt != 6) {
		dev_err(&hdev->pdev->dev,
			"dump dcb: bad command parameter, cnt=%d\n", cnt);
		return;
	}

	ret = hclge_dbg_cmd_send(hdev, desc, qset_id, 1,
				 HCLGE_OPC_QSET_DFX_STS);
	if (ret)
		return;

	bitmap = (struct hclge_dbg_bitmap_cmd *)&desc[0].data[1];
	dev_info(dev, "roce_qset_mask: 0x%x\n", bitmap->bit0);
	dev_info(dev, "nic_qs_mask: 0x%x\n", bitmap->bit1);
	dev_info(dev, "qs_shaping_pass: 0x%x\n", bitmap->bit2);
	dev_info(dev, "qs_bp_sts: 0x%x\n", bitmap->bit3);

	ret = hclge_dbg_cmd_send(hdev, desc, pri_id, 1, HCLGE_OPC_PRI_DFX_STS);
	if (ret)
		return;

	bitmap = (struct hclge_dbg_bitmap_cmd *)&desc[0].data[1];
	dev_info(dev, "pri_mask: 0x%x\n", bitmap->bit0);
	dev_info(dev, "pri_cshaping_pass: 0x%x\n", bitmap->bit1);
	dev_info(dev, "pri_pshaping_pass: 0x%x\n", bitmap->bit2);

	ret = hclge_dbg_cmd_send(hdev, desc, pg_id, 1, HCLGE_OPC_PG_DFX_STS);
	if (ret)
		return;

	bitmap = (struct hclge_dbg_bitmap_cmd *)&desc[0].data[1];
	dev_info(dev, "pg_mask: 0x%x\n", bitmap->bit0);
	dev_info(dev, "pg_cshaping_pass: 0x%x\n", bitmap->bit1);
	dev_info(dev, "pg_pshaping_pass: 0x%x\n", bitmap->bit2);

	ret = hclge_dbg_cmd_send(hdev, desc, port_id, 1,
				 HCLGE_OPC_PORT_DFX_STS);
	if (ret)
		return;

	bitmap = (struct hclge_dbg_bitmap_cmd *)&desc[0].data[1];
	dev_info(dev, "port_mask: 0x%x\n", bitmap->bit0);
	dev_info(dev, "port_shaping_pass: 0x%x\n", bitmap->bit1);

	ret = hclge_dbg_cmd_send(hdev, desc, nq_id, 1, HCLGE_OPC_SCH_NQ_CNT);
	if (ret)
		return;

	dev_info(dev, "sch_nq_cnt: 0x%x\n", desc[0].data[1]);

	ret = hclge_dbg_cmd_send(hdev, desc, nq_id, 1, HCLGE_OPC_SCH_RQ_CNT);
	if (ret)
		return;

	dev_info(dev, "sch_rq_cnt: 0x%x\n", desc[0].data[1]);

	ret = hclge_dbg_cmd_send(hdev, desc, 0, 2, HCLGE_OPC_TM_INTERNAL_STS);
	if (ret)
		return;

	dev_info(dev, "pri_bp: 0x%x\n", desc[0].data[1]);
	dev_info(dev, "fifo_dfx_info: 0x%x\n", desc[0].data[2]);
	dev_info(dev, "sch_roce_fifo_afull_gap: 0x%x\n", desc[0].data[3]);
	dev_info(dev, "tx_private_waterline: 0x%x\n", desc[0].data[4]);
	dev_info(dev, "tm_bypass_en: 0x%x\n", desc[0].data[5]);
	dev_info(dev, "SSU_TM_BYPASS_EN: 0x%x\n", desc[1].data[0]);
	dev_info(dev, "SSU_RESERVE_CFG: 0x%x\n", desc[1].data[1]);

	ret = hclge_dbg_cmd_send(hdev, desc, port_id, 1,
				 HCLGE_OPC_TM_INTERNAL_CNT);
	if (ret)
		return;

	dev_info(dev, "SCH_NIC_NUM: 0x%x\n", desc[0].data[1]);
	dev_info(dev, "SCH_ROCE_NUM: 0x%x\n", desc[0].data[2]);

	ret = hclge_dbg_cmd_send(hdev, desc, port_id, 1,
				 HCLGE_OPC_TM_INTERNAL_STS_1);
	if (ret)
		return;

	dev_info(dev, "TC_MAP_SEL: 0x%x\n", desc[0].data[1]);
	dev_info(dev, "IGU_PFC_PRI_EN: 0x%x\n", desc[0].data[2]);
	dev_info(dev, "MAC_PFC_PRI_EN: 0x%x\n", desc[0].data[3]);
	dev_info(dev, "IGU_PRI_MAP_TC_CFG: 0x%x\n", desc[0].data[4]);
	dev_info(dev, "IGU_TX_PRI_MAP_TC_CFG: 0x%x\n", desc[0].data[5]);
}

static void hclge_dbg_dump_reg_cmd(struct hclge_dev *hdev, char *cmd_buf)
{
	int msg_num;

	if (strncmp(&cmd_buf[9], "bios common", 11) == 0) {
		msg_num = sizeof(hclge_dbg_bios_common_reg) /
			  sizeof(struct hclge_dbg_dfx_message);
		hclge_dbg_dump_reg_common(hdev, hclge_dbg_bios_common_reg,
					  &cmd_buf[21], msg_num,
					  HCLGE_DBG_DFX_BIOS_OFFSET,
					  HCLGE_OPC_DFX_BIOS_COMMON_REG);
	} else if (strncmp(&cmd_buf[9], "ssu", 3) == 0) {
		msg_num = sizeof(hclge_dbg_ssu_reg_0) /
			  sizeof(struct hclge_dbg_dfx_message);
		hclge_dbg_dump_reg_common(hdev, hclge_dbg_ssu_reg_0,
					  &cmd_buf[13], msg_num,
					  HCLGE_DBG_DFX_SSU_0_OFFSET,
					  HCLGE_OPC_DFX_SSU_REG_0);

		msg_num = sizeof(hclge_dbg_ssu_reg_1) /
			  sizeof(struct hclge_dbg_dfx_message);
		hclge_dbg_dump_reg_common(hdev, hclge_dbg_ssu_reg_1,
					  &cmd_buf[13], msg_num,
					  HCLGE_DBG_DFX_SSU_1_OFFSET,
					  HCLGE_OPC_DFX_SSU_REG_1);

		msg_num = sizeof(hclge_dbg_ssu_reg_2) /
			  sizeof(struct hclge_dbg_dfx_message);
		hclge_dbg_dump_reg_common(hdev, hclge_dbg_ssu_reg_2,
					  &cmd_buf[13], msg_num,
					  HCLGE_DBG_DFX_SSU_2_OFFSET,
					  HCLGE_OPC_DFX_SSU_REG_2);
	} else if (strncmp(&cmd_buf[9], "igu egu", 7) == 0) {
		msg_num = sizeof(hclge_dbg_igu_egu_reg) /
			  sizeof(struct hclge_dbg_dfx_message);
		hclge_dbg_dump_reg_common(hdev, hclge_dbg_igu_egu_reg,
					  &cmd_buf[17], msg_num,
					  HCLGE_DBG_DFX_IGU_OFFSET,
					  HCLGE_OPC_DFX_IGU_EGU_REG);
	} else if (strncmp(&cmd_buf[9], "rpu", 3) == 0) {
		msg_num = sizeof(hclge_dbg_rpu_reg_0) /
			  sizeof(struct hclge_dbg_dfx_message);
		hclge_dbg_dump_reg_common(hdev, hclge_dbg_rpu_reg_0,
					  &cmd_buf[13], msg_num,
					  HCLGE_DBG_DFX_RPU_0_OFFSET,
					  HCLGE_OPC_DFX_RPU_REG_0);

		msg_num = sizeof(hclge_dbg_rpu_reg_1) /
			  sizeof(struct hclge_dbg_dfx_message);
		hclge_dbg_dump_reg_common(hdev, hclge_dbg_rpu_reg_1,
					  &cmd_buf[13], msg_num,
					  HCLGE_DBG_DFX_RPU_1_OFFSET,
					  HCLGE_OPC_DFX_RPU_REG_1);
	} else if (strncmp(&cmd_buf[9], "ncsi", 4) == 0) {
		msg_num = sizeof(hclge_dbg_ncsi_reg) /
			  sizeof(struct hclge_dbg_dfx_message);
		hclge_dbg_dump_reg_common(hdev, hclge_dbg_ncsi_reg,
					  &cmd_buf[14], msg_num,
					  HCLGE_DBG_DFX_NCSI_OFFSET,
					  HCLGE_OPC_DFX_NCSI_REG);
	} else if (strncmp(&cmd_buf[9], "rtc", 3) == 0) {
		msg_num = sizeof(hclge_dbg_rtc_reg) /
			  sizeof(struct hclge_dbg_dfx_message);
		hclge_dbg_dump_reg_common(hdev, hclge_dbg_rtc_reg,
					  &cmd_buf[13], msg_num,
					  HCLGE_DBG_DFX_RTC_OFFSET,
					  HCLGE_OPC_DFX_RTC_REG);
	} else if (strncmp(&cmd_buf[9], "ppp", 3) == 0) {
		msg_num = sizeof(hclge_dbg_ppp_reg) /
			  sizeof(struct hclge_dbg_dfx_message);
		hclge_dbg_dump_reg_common(hdev, hclge_dbg_ppp_reg,
					  &cmd_buf[13], msg_num,
					  HCLGE_DBG_DFX_PPP_OFFSET,
					  HCLGE_OPC_DFX_PPP_REG);
	} else if (strncmp(&cmd_buf[9], "rcb", 3) == 0) {
		msg_num = sizeof(hclge_dbg_rcb_reg) /
			  sizeof(struct hclge_dbg_dfx_message);
		hclge_dbg_dump_reg_common(hdev, hclge_dbg_rcb_reg,
					  &cmd_buf[13], msg_num,
					  HCLGE_DBG_DFX_RCB_OFFSET,
					  HCLGE_OPC_DFX_RCB_REG);
	} else if (strncmp(&cmd_buf[9], "tqp", 3) == 0) {
		msg_num = sizeof(hclge_dbg_tqp_reg) /
			  sizeof(struct hclge_dbg_dfx_message);
		hclge_dbg_dump_reg_common(hdev, hclge_dbg_tqp_reg,
					  &cmd_buf[13], msg_num,
					  HCLGE_DBG_DFX_TQP_OFFSET,
					  HCLGE_OPC_DFX_TQP_REG);
	} else if (strncmp(&cmd_buf[9], "dcb", 3) == 0) {
		hclge_dbg_dump_dcb(hdev, &cmd_buf[13]);
	} else {
		dev_info(&hdev->pdev->dev, "unknown command\n");
		return;
	}
}

static void hclge_title_idx_print(struct hclge_dev *hdev, bool flag, int index,
				  char *title_buf, char *true_buf,
				  char *false_buf)
@@ -243,6 +537,88 @@ static void hclge_dbg_dump_tm(struct hclge_dev *hdev)
		cmd, ret);
}

static void hclge_dbg_dump_tm_map(struct hclge_dev *hdev, char *cmd_buf)
{
	struct hclge_bp_to_qs_map_cmd *bp_to_qs_map_cmd;
	struct hclge_nq_to_qs_link_cmd *nq_to_qs_map;
	struct hclge_qs_to_pri_link_cmd *map;
	struct hclge_tqp_tx_queue_tc_cmd *tc;
	enum hclge_opcode_type cmd;
	struct hclge_desc desc;
	int queue_id, group_id;
	u32 qset_maping[32];
	int tc_id, qset_id;
	int pri_id, ret;
	u32 i;

	ret = kstrtouint(&cmd_buf[12], 10, &queue_id);
	queue_id = (ret != 0) ? 0 : queue_id;

	cmd = HCLGE_OPC_TM_NQ_TO_QS_LINK;
	nq_to_qs_map = (struct hclge_nq_to_qs_link_cmd *)desc.data;
	hclge_cmd_setup_basic_desc(&desc, cmd, true);
	nq_to_qs_map->nq_id = cpu_to_le16(queue_id);
	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
	if (ret)
		goto err_tm_map_cmd_send;
	qset_id = nq_to_qs_map->qset_id & 0x3FF;

	cmd = HCLGE_OPC_TM_QS_TO_PRI_LINK;
	map = (struct hclge_qs_to_pri_link_cmd *)desc.data;
	hclge_cmd_setup_basic_desc(&desc, cmd, true);
	map->qs_id = cpu_to_le16(qset_id);
	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
	if (ret)
		goto err_tm_map_cmd_send;
	pri_id = map->priority;

	cmd = HCLGE_OPC_TQP_TX_QUEUE_TC;
	tc = (struct hclge_tqp_tx_queue_tc_cmd *)desc.data;
	hclge_cmd_setup_basic_desc(&desc, cmd, true);
	tc->queue_id = cpu_to_le16(queue_id);
	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
	if (ret)
		goto err_tm_map_cmd_send;
	tc_id = tc->tc_id & 0x7;

	dev_info(&hdev->pdev->dev, "queue_id | qset_id | pri_id | tc_id\n");
	dev_info(&hdev->pdev->dev, "%04d     | %04d    | %02d     | %02d\n",
		 queue_id, qset_id, pri_id, tc_id);

	cmd = HCLGE_OPC_TM_BP_TO_QSET_MAPPING;
	bp_to_qs_map_cmd = (struct hclge_bp_to_qs_map_cmd *)desc.data;
	for (group_id = 0; group_id < 32; group_id++) {
		hclge_cmd_setup_basic_desc(&desc, cmd, true);
		bp_to_qs_map_cmd->tc_id = tc_id;
		bp_to_qs_map_cmd->qs_group_id = group_id;
		ret = hclge_cmd_send(&hdev->hw, &desc, 1);
		if (ret)
			goto err_tm_map_cmd_send;

		qset_maping[group_id] = bp_to_qs_map_cmd->qs_bit_map;
	}

	dev_info(&hdev->pdev->dev, "index | tm bp qset maping:\n");

	i = 0;
	for (group_id = 0; group_id < 4; group_id++) {
		dev_info(&hdev->pdev->dev,
			 "%04d  | %08x:%08x:%08x:%08x:%08x:%08x:%08x:%08x\n",
			 group_id * 256, qset_maping[(u32)(i + 7)],
			 qset_maping[(u32)(i + 6)], qset_maping[(u32)(i + 5)],
			 qset_maping[(u32)(i + 4)], qset_maping[(u32)(i + 3)],
			 qset_maping[(u32)(i + 2)], qset_maping[(u32)(i + 1)],
			 qset_maping[i]);
		i += 8;
	}

	return;

err_tm_map_cmd_send:
	dev_err(&hdev->pdev->dev, "dump tqp map fail(0x%x), status is %d\n",
		cmd, ret);
}

static void hclge_dbg_dump_qos_pause_cfg(struct hclge_dev *hdev)
{
	struct hclge_cfg_pause_param_cmd *pause_param;
@@ -407,6 +783,70 @@ static void hclge_dbg_dump_qos_buf_cfg(struct hclge_dev *hdev)
		"dump qos buf cfg fail(0x%x), status is %d\n", cmd, ret);
}

static void hclge_dbg_dump_mng_table(struct hclge_dev *hdev)
{
	struct hclge_mac_ethertype_idx_rd_cmd *req0;
	char printf_buf[HCLGE_DBG_BUF_LEN];
	struct hclge_desc desc;
	int ret, i;

	dev_info(&hdev->pdev->dev, "mng tab:\n");
	memset(printf_buf, 0, HCLGE_DBG_BUF_LEN);
	strncat(printf_buf,
		"entry|mac_addr         |mask|ether|mask|vlan|mask",
		HCLGE_DBG_BUF_LEN - 1);
	strncat(printf_buf + strlen(printf_buf),
		"|i_map|i_dir|e_type|pf_id|vf_id|q_id|drop\n",
		HCLGE_DBG_BUF_LEN - strlen(printf_buf) - 1);

	dev_info(&hdev->pdev->dev, "%s", printf_buf);

	for (i = 0; i < HCLGE_DBG_MNG_TBL_MAX; i++) {
		hclge_cmd_setup_basic_desc(&desc, HCLGE_MAC_ETHERTYPE_IDX_RD,
					   true);
		req0 = (struct hclge_mac_ethertype_idx_rd_cmd *)&desc.data;
		req0->index = cpu_to_le16(i);

		ret = hclge_cmd_send(&hdev->hw, &desc, 1);
		if (ret) {
			dev_err(&hdev->pdev->dev,
				"call hclge_cmd_send fail, ret = %d\n", ret);
			return;
		}

		if (!req0->resp_code)
			continue;

		memset(printf_buf, 0, HCLGE_DBG_BUF_LEN);
		snprintf(printf_buf, HCLGE_DBG_BUF_LEN,
			 "%02u   |%02x:%02x:%02x:%02x:%02x:%02x|",
			 req0->index, req0->mac_add[0], req0->mac_add[1],
			 req0->mac_add[2], req0->mac_add[3], req0->mac_add[4],
			 req0->mac_add[5]);

		snprintf(printf_buf + strlen(printf_buf),
			 HCLGE_DBG_BUF_LEN - strlen(printf_buf),
			 "%x   |%04x |%x   |%04x|%x   |%02x   |%02x   |",
			 !!(req0->flags & HCLGE_DBG_MNG_MAC_MASK_B),
			 req0->ethter_type,
			 !!(req0->flags & HCLGE_DBG_MNG_ETHER_MASK_B),
			 req0->vlan_tag & HCLGE_DBG_MNG_VLAN_TAG,
			 !!(req0->flags & HCLGE_DBG_MNG_VLAN_MASK_B),
			 req0->i_port_bitmap, req0->i_port_direction);

		snprintf(printf_buf + strlen(printf_buf),
			 HCLGE_DBG_BUF_LEN - strlen(printf_buf),
			 "%d     |%d    |%02d   |%04d|%x\n",
			 !!(req0->egress_port & HCLGE_DBG_MNG_E_TYPE_B),
			 req0->egress_port & HCLGE_DBG_MNG_PF_ID,
			 (req0->egress_port >> 3) & HCLGE_DBG_MNG_VF_ID,
			 req0->egress_queue,
			 !!(req0->egress_port & HCLGE_DBG_MNG_DROP_B));

		dev_info(&hdev->pdev->dev, "%s", printf_buf);
	}
}

static void hclge_dbg_fd_tcam_read(struct hclge_dev *hdev, u8 stage,
				   bool sel_x, u32 loc)
{
@@ -470,6 +910,8 @@ int hclge_dbg_run_cmd(struct hnae3_handle *handle, char *cmd_buf)
		hclge_dbg_fd_tcam(hdev);
	} else if (strncmp(cmd_buf, "dump tc", 7) == 0) {
		hclge_dbg_dump_tc(hdev);
	} else if (strncmp(cmd_buf, "dump tm map", 11) == 0) {
		hclge_dbg_dump_tm_map(hdev, cmd_buf);
	} else if (strncmp(cmd_buf, "dump tm", 7) == 0) {
		hclge_dbg_dump_tm(hdev);
	} else if (strncmp(cmd_buf, "dump qos pause cfg", 18) == 0) {
@@ -478,6 +920,10 @@ int hclge_dbg_run_cmd(struct hnae3_handle *handle, char *cmd_buf)
		hclge_dbg_dump_qos_pri_map(hdev);
	} else if (strncmp(cmd_buf, "dump qos buf cfg", 16) == 0) {
		hclge_dbg_dump_qos_buf_cfg(hdev);
	} else if (strncmp(cmd_buf, "dump mng tbl", 12) == 0) {
		hclge_dbg_dump_mng_table(hdev);
	} else if (strncmp(cmd_buf, "dump reg", 8) == 0) {
		hclge_dbg_dump_reg_cmd(hdev, cmd_buf);
	} else {
		dev_info(&hdev->pdev->dev, "unknown command\n");
		return -EINVAL;
Loading