brintos

brintos / linux-shallow public Read only

0
0
Text · 38.9 KiB · 807eb3b Raw
1458 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/* Copyright (c) 2018-2019 Hisilicon Limited. */3 4#include <linux/debugfs.h>5#include <linux/device.h>6 7#include "hnae3.h"8#include "hns3_debugfs.h"9#include "hns3_enet.h"10 11static struct dentry *hns3_dbgfs_root;12 13static struct hns3_dbg_dentry_info hns3_dbg_dentry[] = {14	{15		.name = "tm"16	},17	{18		.name = "tx_bd_info"19	},20	{21		.name = "rx_bd_info"22	},23	{24		.name = "mac_list"25	},26	{27		.name = "reg"28	},29	{30		.name = "queue"31	},32	{33		.name = "fd"34	},35	/* keep common at the bottom and add new directory above */36	{37		.name = "common"38	},39};40 41static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, u32 cmd);42static int hns3_dbg_common_file_init(struct hnae3_handle *handle, u32 cmd);43 44static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = {45	{46		.name = "tm_nodes",47		.cmd = HNAE3_DBG_CMD_TM_NODES,48		.dentry = HNS3_DBG_DENTRY_TM,49		.buf_len = HNS3_DBG_READ_LEN,50		.init = hns3_dbg_common_file_init,51	},52	{53		.name = "tm_priority",54		.cmd = HNAE3_DBG_CMD_TM_PRI,55		.dentry = HNS3_DBG_DENTRY_TM,56		.buf_len = HNS3_DBG_READ_LEN,57		.init = hns3_dbg_common_file_init,58	},59	{60		.name = "tm_qset",61		.cmd = HNAE3_DBG_CMD_TM_QSET,62		.dentry = HNS3_DBG_DENTRY_TM,63		.buf_len = HNS3_DBG_READ_LEN,64		.init = hns3_dbg_common_file_init,65	},66	{67		.name = "tm_map",68		.cmd = HNAE3_DBG_CMD_TM_MAP,69		.dentry = HNS3_DBG_DENTRY_TM,70		.buf_len = HNS3_DBG_READ_LEN_1MB,71		.init = hns3_dbg_common_file_init,72	},73	{74		.name = "tm_pg",75		.cmd = HNAE3_DBG_CMD_TM_PG,76		.dentry = HNS3_DBG_DENTRY_TM,77		.buf_len = HNS3_DBG_READ_LEN,78		.init = hns3_dbg_common_file_init,79	},80	{81		.name = "tm_port",82		.cmd = HNAE3_DBG_CMD_TM_PORT,83		.dentry = HNS3_DBG_DENTRY_TM,84		.buf_len = HNS3_DBG_READ_LEN,85		.init = hns3_dbg_common_file_init,86	},87	{88		.name = "tc_sch_info",89		.cmd = HNAE3_DBG_CMD_TC_SCH_INFO,90		.dentry = HNS3_DBG_DENTRY_TM,91		.buf_len = HNS3_DBG_READ_LEN,92		.init = hns3_dbg_common_file_init,93	},94	{95		.name = "qos_pause_cfg",96		.cmd = HNAE3_DBG_CMD_QOS_PAUSE_CFG,97		.dentry = HNS3_DBG_DENTRY_TM,98		.buf_len = HNS3_DBG_READ_LEN,99		.init = hns3_dbg_common_file_init,100	},101	{102		.name = "qos_pri_map",103		.cmd = HNAE3_DBG_CMD_QOS_PRI_MAP,104		.dentry = HNS3_DBG_DENTRY_TM,105		.buf_len = HNS3_DBG_READ_LEN,106		.init = hns3_dbg_common_file_init,107	},108	{109		.name = "qos_dscp_map",110		.cmd = HNAE3_DBG_CMD_QOS_DSCP_MAP,111		.dentry = HNS3_DBG_DENTRY_TM,112		.buf_len = HNS3_DBG_READ_LEN,113		.init = hns3_dbg_common_file_init,114	},115	{116		.name = "qos_buf_cfg",117		.cmd = HNAE3_DBG_CMD_QOS_BUF_CFG,118		.dentry = HNS3_DBG_DENTRY_TM,119		.buf_len = HNS3_DBG_READ_LEN,120		.init = hns3_dbg_common_file_init,121	},122	{123		.name = "dev_info",124		.cmd = HNAE3_DBG_CMD_DEV_INFO,125		.dentry = HNS3_DBG_DENTRY_COMMON,126		.buf_len = HNS3_DBG_READ_LEN,127		.init = hns3_dbg_common_file_init,128	},129	{130		.name = "tx_bd_queue",131		.cmd = HNAE3_DBG_CMD_TX_BD,132		.dentry = HNS3_DBG_DENTRY_TX_BD,133		.buf_len = HNS3_DBG_READ_LEN_5MB,134		.init = hns3_dbg_bd_file_init,135	},136	{137		.name = "rx_bd_queue",138		.cmd = HNAE3_DBG_CMD_RX_BD,139		.dentry = HNS3_DBG_DENTRY_RX_BD,140		.buf_len = HNS3_DBG_READ_LEN_4MB,141		.init = hns3_dbg_bd_file_init,142	},143	{144		.name = "uc",145		.cmd = HNAE3_DBG_CMD_MAC_UC,146		.dentry = HNS3_DBG_DENTRY_MAC,147		.buf_len = HNS3_DBG_READ_LEN_128KB,148		.init = hns3_dbg_common_file_init,149	},150	{151		.name = "mc",152		.cmd = HNAE3_DBG_CMD_MAC_MC,153		.dentry = HNS3_DBG_DENTRY_MAC,154		.buf_len = HNS3_DBG_READ_LEN,155		.init = hns3_dbg_common_file_init,156	},157	{158		.name = "mng_tbl",159		.cmd = HNAE3_DBG_CMD_MNG_TBL,160		.dentry = HNS3_DBG_DENTRY_COMMON,161		.buf_len = HNS3_DBG_READ_LEN,162		.init = hns3_dbg_common_file_init,163	},164	{165		.name = "loopback",166		.cmd = HNAE3_DBG_CMD_LOOPBACK,167		.dentry = HNS3_DBG_DENTRY_COMMON,168		.buf_len = HNS3_DBG_READ_LEN,169		.init = hns3_dbg_common_file_init,170	},171	{172		.name = "interrupt_info",173		.cmd = HNAE3_DBG_CMD_INTERRUPT_INFO,174		.dentry = HNS3_DBG_DENTRY_COMMON,175		.buf_len = HNS3_DBG_READ_LEN,176		.init = hns3_dbg_common_file_init,177	},178	{179		.name = "reset_info",180		.cmd = HNAE3_DBG_CMD_RESET_INFO,181		.dentry = HNS3_DBG_DENTRY_COMMON,182		.buf_len = HNS3_DBG_READ_LEN,183		.init = hns3_dbg_common_file_init,184	},185	{186		.name = "imp_info",187		.cmd = HNAE3_DBG_CMD_IMP_INFO,188		.dentry = HNS3_DBG_DENTRY_COMMON,189		.buf_len = HNS3_DBG_READ_LEN,190		.init = hns3_dbg_common_file_init,191	},192	{193		.name = "ncl_config",194		.cmd = HNAE3_DBG_CMD_NCL_CONFIG,195		.dentry = HNS3_DBG_DENTRY_COMMON,196		.buf_len = HNS3_DBG_READ_LEN_128KB,197		.init = hns3_dbg_common_file_init,198	},199	{200		.name = "mac_tnl_status",201		.cmd = HNAE3_DBG_CMD_MAC_TNL_STATUS,202		.dentry = HNS3_DBG_DENTRY_COMMON,203		.buf_len = HNS3_DBG_READ_LEN,204		.init = hns3_dbg_common_file_init,205	},206	{207		.name = "bios_common",208		.cmd = HNAE3_DBG_CMD_REG_BIOS_COMMON,209		.dentry = HNS3_DBG_DENTRY_REG,210		.buf_len = HNS3_DBG_READ_LEN,211		.init = hns3_dbg_common_file_init,212	},213	{214		.name = "ssu",215		.cmd = HNAE3_DBG_CMD_REG_SSU,216		.dentry = HNS3_DBG_DENTRY_REG,217		.buf_len = HNS3_DBG_READ_LEN,218		.init = hns3_dbg_common_file_init,219	},220	{221		.name = "igu_egu",222		.cmd = HNAE3_DBG_CMD_REG_IGU_EGU,223		.dentry = HNS3_DBG_DENTRY_REG,224		.buf_len = HNS3_DBG_READ_LEN,225		.init = hns3_dbg_common_file_init,226	},227	{228		.name = "rpu",229		.cmd = HNAE3_DBG_CMD_REG_RPU,230		.dentry = HNS3_DBG_DENTRY_REG,231		.buf_len = HNS3_DBG_READ_LEN,232		.init = hns3_dbg_common_file_init,233	},234	{235		.name = "ncsi",236		.cmd = HNAE3_DBG_CMD_REG_NCSI,237		.dentry = HNS3_DBG_DENTRY_REG,238		.buf_len = HNS3_DBG_READ_LEN,239		.init = hns3_dbg_common_file_init,240	},241	{242		.name = "rtc",243		.cmd = HNAE3_DBG_CMD_REG_RTC,244		.dentry = HNS3_DBG_DENTRY_REG,245		.buf_len = HNS3_DBG_READ_LEN,246		.init = hns3_dbg_common_file_init,247	},248	{249		.name = "ppp",250		.cmd = HNAE3_DBG_CMD_REG_PPP,251		.dentry = HNS3_DBG_DENTRY_REG,252		.buf_len = HNS3_DBG_READ_LEN,253		.init = hns3_dbg_common_file_init,254	},255	{256		.name = "rcb",257		.cmd = HNAE3_DBG_CMD_REG_RCB,258		.dentry = HNS3_DBG_DENTRY_REG,259		.buf_len = HNS3_DBG_READ_LEN,260		.init = hns3_dbg_common_file_init,261	},262	{263		.name = "tqp",264		.cmd = HNAE3_DBG_CMD_REG_TQP,265		.dentry = HNS3_DBG_DENTRY_REG,266		.buf_len = HNS3_DBG_READ_LEN_128KB,267		.init = hns3_dbg_common_file_init,268	},269	{270		.name = "mac",271		.cmd = HNAE3_DBG_CMD_REG_MAC,272		.dentry = HNS3_DBG_DENTRY_REG,273		.buf_len = HNS3_DBG_READ_LEN,274		.init = hns3_dbg_common_file_init,275	},276	{277		.name = "dcb",278		.cmd = HNAE3_DBG_CMD_REG_DCB,279		.dentry = HNS3_DBG_DENTRY_REG,280		.buf_len = HNS3_DBG_READ_LEN,281		.init = hns3_dbg_common_file_init,282	},283	{284		.name = "queue_map",285		.cmd = HNAE3_DBG_CMD_QUEUE_MAP,286		.dentry = HNS3_DBG_DENTRY_QUEUE,287		.buf_len = HNS3_DBG_READ_LEN,288		.init = hns3_dbg_common_file_init,289	},290	{291		.name = "rx_queue_info",292		.cmd = HNAE3_DBG_CMD_RX_QUEUE_INFO,293		.dentry = HNS3_DBG_DENTRY_QUEUE,294		.buf_len = HNS3_DBG_READ_LEN_1MB,295		.init = hns3_dbg_common_file_init,296	},297	{298		.name = "tx_queue_info",299		.cmd = HNAE3_DBG_CMD_TX_QUEUE_INFO,300		.dentry = HNS3_DBG_DENTRY_QUEUE,301		.buf_len = HNS3_DBG_READ_LEN_1MB,302		.init = hns3_dbg_common_file_init,303	},304	{305		.name = "fd_tcam",306		.cmd = HNAE3_DBG_CMD_FD_TCAM,307		.dentry = HNS3_DBG_DENTRY_FD,308		.buf_len = HNS3_DBG_READ_LEN_1MB,309		.init = hns3_dbg_common_file_init,310	},311	{312		.name = "service_task_info",313		.cmd = HNAE3_DBG_CMD_SERV_INFO,314		.dentry = HNS3_DBG_DENTRY_COMMON,315		.buf_len = HNS3_DBG_READ_LEN,316		.init = hns3_dbg_common_file_init,317	},318	{319		.name = "vlan_config",320		.cmd = HNAE3_DBG_CMD_VLAN_CONFIG,321		.dentry = HNS3_DBG_DENTRY_COMMON,322		.buf_len = HNS3_DBG_READ_LEN,323		.init = hns3_dbg_common_file_init,324	},325	{326		.name = "ptp_info",327		.cmd = HNAE3_DBG_CMD_PTP_INFO,328		.dentry = HNS3_DBG_DENTRY_COMMON,329		.buf_len = HNS3_DBG_READ_LEN,330		.init = hns3_dbg_common_file_init,331	},332	{333		.name = "fd_counter",334		.cmd = HNAE3_DBG_CMD_FD_COUNTER,335		.dentry = HNS3_DBG_DENTRY_FD,336		.buf_len = HNS3_DBG_READ_LEN,337		.init = hns3_dbg_common_file_init,338	},339	{340		.name = "umv_info",341		.cmd = HNAE3_DBG_CMD_UMV_INFO,342		.dentry = HNS3_DBG_DENTRY_COMMON,343		.buf_len = HNS3_DBG_READ_LEN,344		.init = hns3_dbg_common_file_init,345	},346	{347		.name = "page_pool_info",348		.cmd = HNAE3_DBG_CMD_PAGE_POOL_INFO,349		.dentry = HNS3_DBG_DENTRY_COMMON,350		.buf_len = HNS3_DBG_READ_LEN,351		.init = hns3_dbg_common_file_init,352	},353	{354		.name = "coalesce_info",355		.cmd = HNAE3_DBG_CMD_COAL_INFO,356		.dentry = HNS3_DBG_DENTRY_COMMON,357		.buf_len = HNS3_DBG_READ_LEN_1MB,358		.init = hns3_dbg_common_file_init,359	},360};361 362static struct hns3_dbg_cap_info hns3_dbg_cap[] = {363	{364		.name = "support FD",365		.cap_bit = HNAE3_DEV_SUPPORT_FD_B,366	}, {367		.name = "support GRO",368		.cap_bit = HNAE3_DEV_SUPPORT_GRO_B,369	}, {370		.name = "support FEC",371		.cap_bit = HNAE3_DEV_SUPPORT_FEC_B,372	}, {373		.name = "support UDP GSO",374		.cap_bit = HNAE3_DEV_SUPPORT_UDP_GSO_B,375	}, {376		.name = "support PTP",377		.cap_bit = HNAE3_DEV_SUPPORT_PTP_B,378	}, {379		.name = "support INT QL",380		.cap_bit = HNAE3_DEV_SUPPORT_INT_QL_B,381	}, {382		.name = "support HW TX csum",383		.cap_bit = HNAE3_DEV_SUPPORT_HW_TX_CSUM_B,384	}, {385		.name = "support UDP tunnel csum",386		.cap_bit = HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B,387	}, {388		.name = "support TX push",389		.cap_bit = HNAE3_DEV_SUPPORT_TX_PUSH_B,390	}, {391		.name = "support imp-controlled PHY",392		.cap_bit = HNAE3_DEV_SUPPORT_PHY_IMP_B,393	}, {394		.name = "support imp-controlled RAS",395		.cap_bit = HNAE3_DEV_SUPPORT_RAS_IMP_B,396	}, {397		.name = "support rxd advanced layout",398		.cap_bit = HNAE3_DEV_SUPPORT_RXD_ADV_LAYOUT_B,399	}, {400		.name = "support port vlan bypass",401		.cap_bit = HNAE3_DEV_SUPPORT_PORT_VLAN_BYPASS_B,402	}, {403		.name = "support modify vlan filter state",404		.cap_bit = HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B,405	}, {406		.name = "support FEC statistics",407		.cap_bit = HNAE3_DEV_SUPPORT_FEC_STATS_B,408	}, {409		.name = "support lane num",410		.cap_bit = HNAE3_DEV_SUPPORT_LANE_NUM_B,411	}, {412		.name = "support wake on lan",413		.cap_bit = HNAE3_DEV_SUPPORT_WOL_B,414	}, {415		.name = "support tm flush",416		.cap_bit = HNAE3_DEV_SUPPORT_TM_FLUSH_B,417	}, {418		.name = "support vf fault detect",419		.cap_bit = HNAE3_DEV_SUPPORT_VF_FAULT_B,420	}421};422 423static const struct hns3_dbg_item coal_info_items[] = {424	{ "VEC_ID", 2 },425	{ "ALGO_STATE", 2 },426	{ "PROFILE_ID", 2 },427	{ "CQE_MODE", 2 },428	{ "TUNE_STATE", 2 },429	{ "STEPS_LEFT", 2 },430	{ "STEPS_RIGHT", 2 },431	{ "TIRED", 2 },432	{ "SW_GL", 2 },433	{ "SW_QL", 2 },434	{ "HW_GL", 2 },435	{ "HW_QL", 2 },436};437 438static const char * const dim_cqe_mode_str[] = { "EQE", "CQE" };439static const char * const dim_state_str[] = { "START", "IN_PROG", "APPLY" };440static const char * const441dim_tune_stat_str[] = { "ON_TOP", "TIRED", "RIGHT", "LEFT" };442 443static void hns3_dbg_fill_content(char *content, u16 len,444				  const struct hns3_dbg_item *items,445				  const char **result, u16 size)446{447#define HNS3_DBG_LINE_END_LEN	2448	char *pos = content;449	u16 item_len;450	u16 i;451 452	if (!len) {453		return;454	} else if (len <= HNS3_DBG_LINE_END_LEN) {455		*pos++ = '\0';456		return;457	}458 459	memset(content, ' ', len);460	len -= HNS3_DBG_LINE_END_LEN;461 462	for (i = 0; i < size; i++) {463		item_len = strlen(items[i].name) + items[i].interval;464		if (len < item_len)465			break;466 467		if (result) {468			if (item_len < strlen(result[i]))469				break;470			memcpy(pos, result[i], strlen(result[i]));471		} else {472			memcpy(pos, items[i].name, strlen(items[i].name));473		}474		pos += item_len;475		len -= item_len;476	}477	*pos++ = '\n';478	*pos++ = '\0';479}480 481static void hns3_get_coal_info(struct hns3_enet_tqp_vector *tqp_vector,482			       char **result, int i, bool is_tx)483{484	unsigned int gl_offset, ql_offset;485	struct hns3_enet_coalesce *coal;486	unsigned int reg_val;487	unsigned int j = 0;488	struct dim *dim;489	bool ql_enable;490 491	if (is_tx) {492		coal = &tqp_vector->tx_group.coal;493		dim = &tqp_vector->tx_group.dim;494		gl_offset = HNS3_VECTOR_GL1_OFFSET;495		ql_offset = HNS3_VECTOR_TX_QL_OFFSET;496		ql_enable = tqp_vector->tx_group.coal.ql_enable;497	} else {498		coal = &tqp_vector->rx_group.coal;499		dim = &tqp_vector->rx_group.dim;500		gl_offset = HNS3_VECTOR_GL0_OFFSET;501		ql_offset = HNS3_VECTOR_RX_QL_OFFSET;502		ql_enable = tqp_vector->rx_group.coal.ql_enable;503	}504 505	sprintf(result[j++], "%d", i);506	sprintf(result[j++], "%s", dim->state < ARRAY_SIZE(dim_state_str) ?507		dim_state_str[dim->state] : "unknown");508	sprintf(result[j++], "%u", dim->profile_ix);509	sprintf(result[j++], "%s", dim->mode < ARRAY_SIZE(dim_cqe_mode_str) ?510		dim_cqe_mode_str[dim->mode] : "unknown");511	sprintf(result[j++], "%s",512		dim->tune_state < ARRAY_SIZE(dim_tune_stat_str) ?513		dim_tune_stat_str[dim->tune_state] : "unknown");514	sprintf(result[j++], "%u", dim->steps_left);515	sprintf(result[j++], "%u", dim->steps_right);516	sprintf(result[j++], "%u", dim->tired);517	sprintf(result[j++], "%u", coal->int_gl);518	sprintf(result[j++], "%u", coal->int_ql);519	reg_val = readl(tqp_vector->mask_addr + gl_offset) &520		  HNS3_VECTOR_GL_MASK;521	sprintf(result[j++], "%u", reg_val);522	if (ql_enable) {523		reg_val = readl(tqp_vector->mask_addr + ql_offset) &524			  HNS3_VECTOR_QL_MASK;525		sprintf(result[j++], "%u", reg_val);526	} else {527		sprintf(result[j++], "NA");528	}529}530 531static void hns3_dump_coal_info(struct hnae3_handle *h, char *buf, int len,532				int *pos, bool is_tx)533{534	char data_str[ARRAY_SIZE(coal_info_items)][HNS3_DBG_DATA_STR_LEN];535	char *result[ARRAY_SIZE(coal_info_items)];536	struct hns3_enet_tqp_vector *tqp_vector;537	struct hns3_nic_priv *priv = h->priv;538	char content[HNS3_DBG_INFO_LEN];539	unsigned int i;540 541	for (i = 0; i < ARRAY_SIZE(coal_info_items); i++)542		result[i] = &data_str[i][0];543 544	*pos += scnprintf(buf + *pos, len - *pos,545			  "%s interrupt coalesce info:\n",546			  is_tx ? "tx" : "rx");547	hns3_dbg_fill_content(content, sizeof(content), coal_info_items,548			      NULL, ARRAY_SIZE(coal_info_items));549	*pos += scnprintf(buf + *pos, len - *pos, "%s", content);550 551	for (i = 0; i < priv->vector_num; i++) {552		tqp_vector = &priv->tqp_vector[i];553		hns3_get_coal_info(tqp_vector, result, i, is_tx);554		hns3_dbg_fill_content(content, sizeof(content), coal_info_items,555				      (const char **)result,556				      ARRAY_SIZE(coal_info_items));557		*pos += scnprintf(buf + *pos, len - *pos, "%s", content);558	}559}560 561static int hns3_dbg_coal_info(struct hnae3_handle *h, char *buf, int len)562{563	int pos = 0;564 565	hns3_dump_coal_info(h, buf, len, &pos, true);566	pos += scnprintf(buf + pos, len - pos, "\n");567	hns3_dump_coal_info(h, buf, len, &pos, false);568 569	return 0;570}571 572static const struct hns3_dbg_item tx_spare_info_items[] = {573	{ "QUEUE_ID", 2 },574	{ "COPYBREAK", 2 },575	{ "LEN", 7 },576	{ "NTU", 4 },577	{ "NTC", 4 },578	{ "LTC", 4 },579	{ "DMA", 17 },580};581 582static void hns3_dbg_tx_spare_info(struct hns3_enet_ring *ring, char *buf,583				   int len, u32 ring_num, int *pos)584{585	char data_str[ARRAY_SIZE(tx_spare_info_items)][HNS3_DBG_DATA_STR_LEN];586	struct hns3_tx_spare *tx_spare = ring->tx_spare;587	char *result[ARRAY_SIZE(tx_spare_info_items)];588	char content[HNS3_DBG_INFO_LEN];589	u32 i, j;590 591	if (!tx_spare) {592		*pos += scnprintf(buf + *pos, len - *pos,593				  "tx spare buffer is not enabled\n");594		return;595	}596 597	for (i = 0; i < ARRAY_SIZE(tx_spare_info_items); i++)598		result[i] = &data_str[i][0];599 600	*pos += scnprintf(buf + *pos, len - *pos, "tx spare buffer info\n");601	hns3_dbg_fill_content(content, sizeof(content), tx_spare_info_items,602			      NULL, ARRAY_SIZE(tx_spare_info_items));603	*pos += scnprintf(buf + *pos, len - *pos, "%s", content);604 605	for (i = 0; i < ring_num; i++) {606		j = 0;607		sprintf(result[j++], "%u", i);608		sprintf(result[j++], "%u", ring->tx_copybreak);609		sprintf(result[j++], "%u", tx_spare->len);610		sprintf(result[j++], "%u", tx_spare->next_to_use);611		sprintf(result[j++], "%u", tx_spare->next_to_clean);612		sprintf(result[j++], "%u", tx_spare->last_to_clean);613		sprintf(result[j++], "%pad", &tx_spare->dma);614		hns3_dbg_fill_content(content, sizeof(content),615				      tx_spare_info_items,616				      (const char **)result,617				      ARRAY_SIZE(tx_spare_info_items));618		*pos += scnprintf(buf + *pos, len - *pos, "%s", content);619	}620}621 622static const struct hns3_dbg_item rx_queue_info_items[] = {623	{ "QUEUE_ID", 2 },624	{ "BD_NUM", 2 },625	{ "BD_LEN", 2 },626	{ "TAIL", 2 },627	{ "HEAD", 2 },628	{ "FBDNUM", 2 },629	{ "PKTNUM", 5 },630	{ "COPYBREAK", 2 },631	{ "RING_EN", 2 },632	{ "RX_RING_EN", 2 },633	{ "BASE_ADDR", 10 },634};635 636static void hns3_dump_rx_queue_info(struct hns3_enet_ring *ring,637				    struct hnae3_ae_dev *ae_dev, char **result,638				    u32 index)639{640	u32 base_add_l, base_add_h;641	u32 j = 0;642 643	sprintf(result[j++], "%u", index);644 645	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +646		HNS3_RING_RX_RING_BD_NUM_REG));647 648	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +649		HNS3_RING_RX_RING_BD_LEN_REG));650 651	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +652		HNS3_RING_RX_RING_TAIL_REG));653 654	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +655		HNS3_RING_RX_RING_HEAD_REG));656 657	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +658		HNS3_RING_RX_RING_FBDNUM_REG));659 660	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +661		HNS3_RING_RX_RING_PKTNUM_RECORD_REG));662	sprintf(result[j++], "%u", ring->rx_copybreak);663 664	sprintf(result[j++], "%s", readl_relaxed(ring->tqp->io_base +665		HNS3_RING_EN_REG) ? "on" : "off");666 667	if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev))668		sprintf(result[j++], "%s", readl_relaxed(ring->tqp->io_base +669			HNS3_RING_RX_EN_REG) ? "on" : "off");670	else671		sprintf(result[j++], "%s", "NA");672 673	base_add_h = readl_relaxed(ring->tqp->io_base +674					HNS3_RING_RX_RING_BASEADDR_H_REG);675	base_add_l = readl_relaxed(ring->tqp->io_base +676					HNS3_RING_RX_RING_BASEADDR_L_REG);677	sprintf(result[j++], "0x%08x%08x", base_add_h, base_add_l);678}679 680static int hns3_dbg_rx_queue_info(struct hnae3_handle *h,681				  char *buf, int len)682{683	char data_str[ARRAY_SIZE(rx_queue_info_items)][HNS3_DBG_DATA_STR_LEN];684	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);685	char *result[ARRAY_SIZE(rx_queue_info_items)];686	struct hns3_nic_priv *priv = h->priv;687	char content[HNS3_DBG_INFO_LEN];688	struct hns3_enet_ring *ring;689	int pos = 0;690	u32 i;691 692	if (!priv->ring) {693		dev_err(&h->pdev->dev, "priv->ring is NULL\n");694		return -EFAULT;695	}696 697	for (i = 0; i < ARRAY_SIZE(rx_queue_info_items); i++)698		result[i] = &data_str[i][0];699 700	hns3_dbg_fill_content(content, sizeof(content), rx_queue_info_items,701			      NULL, ARRAY_SIZE(rx_queue_info_items));702	pos += scnprintf(buf + pos, len - pos, "%s", content);703	for (i = 0; i < h->kinfo.num_tqps; i++) {704		/* Each cycle needs to determine whether the instance is reset,705		 * to prevent reference to invalid memory. And need to ensure706		 * that the following code is executed within 100ms.707		 */708		if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||709		    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))710			return -EPERM;711 712		ring = &priv->ring[(u32)(i + h->kinfo.num_tqps)];713		hns3_dump_rx_queue_info(ring, ae_dev, result, i);714		hns3_dbg_fill_content(content, sizeof(content),715				      rx_queue_info_items,716				      (const char **)result,717				      ARRAY_SIZE(rx_queue_info_items));718		pos += scnprintf(buf + pos, len - pos, "%s", content);719	}720 721	return 0;722}723 724static const struct hns3_dbg_item tx_queue_info_items[] = {725	{ "QUEUE_ID", 2 },726	{ "BD_NUM", 2 },727	{ "TC", 2 },728	{ "TAIL", 2 },729	{ "HEAD", 2 },730	{ "FBDNUM", 2 },731	{ "OFFSET", 2 },732	{ "PKTNUM", 5 },733	{ "RING_EN", 2 },734	{ "TX_RING_EN", 2 },735	{ "BASE_ADDR", 10 },736};737 738static void hns3_dump_tx_queue_info(struct hns3_enet_ring *ring,739				    struct hnae3_ae_dev *ae_dev, char **result,740				    u32 index)741{742	u32 base_add_l, base_add_h;743	u32 j = 0;744 745	sprintf(result[j++], "%u", index);746	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +747		HNS3_RING_TX_RING_BD_NUM_REG));748 749	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +750		HNS3_RING_TX_RING_TC_REG));751 752	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +753		HNS3_RING_TX_RING_TAIL_REG));754 755	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +756		HNS3_RING_TX_RING_HEAD_REG));757 758	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +759		HNS3_RING_TX_RING_FBDNUM_REG));760 761	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +762		HNS3_RING_TX_RING_OFFSET_REG));763 764	sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +765		HNS3_RING_TX_RING_PKTNUM_RECORD_REG));766 767	sprintf(result[j++], "%s", readl_relaxed(ring->tqp->io_base +768		HNS3_RING_EN_REG) ? "on" : "off");769 770	if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev))771		sprintf(result[j++], "%s", readl_relaxed(ring->tqp->io_base +772			HNS3_RING_TX_EN_REG) ? "on" : "off");773	else774		sprintf(result[j++], "%s", "NA");775 776	base_add_h = readl_relaxed(ring->tqp->io_base +777					HNS3_RING_TX_RING_BASEADDR_H_REG);778	base_add_l = readl_relaxed(ring->tqp->io_base +779					HNS3_RING_TX_RING_BASEADDR_L_REG);780	sprintf(result[j++], "0x%08x%08x", base_add_h, base_add_l);781}782 783static int hns3_dbg_tx_queue_info(struct hnae3_handle *h,784				  char *buf, int len)785{786	char data_str[ARRAY_SIZE(tx_queue_info_items)][HNS3_DBG_DATA_STR_LEN];787	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);788	char *result[ARRAY_SIZE(tx_queue_info_items)];789	struct hns3_nic_priv *priv = h->priv;790	char content[HNS3_DBG_INFO_LEN];791	struct hns3_enet_ring *ring;792	int pos = 0;793	u32 i;794 795	if (!priv->ring) {796		dev_err(&h->pdev->dev, "priv->ring is NULL\n");797		return -EFAULT;798	}799 800	for (i = 0; i < ARRAY_SIZE(tx_queue_info_items); i++)801		result[i] = &data_str[i][0];802 803	hns3_dbg_fill_content(content, sizeof(content), tx_queue_info_items,804			      NULL, ARRAY_SIZE(tx_queue_info_items));805	pos += scnprintf(buf + pos, len - pos, "%s", content);806 807	for (i = 0; i < h->kinfo.num_tqps; i++) {808		/* Each cycle needs to determine whether the instance is reset,809		 * to prevent reference to invalid memory. And need to ensure810		 * that the following code is executed within 100ms.811		 */812		if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||813		    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))814			return -EPERM;815 816		ring = &priv->ring[i];817		hns3_dump_tx_queue_info(ring, ae_dev, result, i);818		hns3_dbg_fill_content(content, sizeof(content),819				      tx_queue_info_items,820				      (const char **)result,821				      ARRAY_SIZE(tx_queue_info_items));822		pos += scnprintf(buf + pos, len - pos, "%s", content);823	}824 825	hns3_dbg_tx_spare_info(ring, buf, len, h->kinfo.num_tqps, &pos);826 827	return 0;828}829 830static const struct hns3_dbg_item queue_map_items[] = {831	{ "local_queue_id", 2 },832	{ "global_queue_id", 2 },833	{ "vector_id", 2 },834};835 836static int hns3_dbg_queue_map(struct hnae3_handle *h, char *buf, int len)837{838	char data_str[ARRAY_SIZE(queue_map_items)][HNS3_DBG_DATA_STR_LEN];839	char *result[ARRAY_SIZE(queue_map_items)];840	struct hns3_nic_priv *priv = h->priv;841	char content[HNS3_DBG_INFO_LEN];842	int pos = 0;843	int j;844	u32 i;845 846	if (!h->ae_algo->ops->get_global_queue_id)847		return -EOPNOTSUPP;848 849	for (i = 0; i < ARRAY_SIZE(queue_map_items); i++)850		result[i] = &data_str[i][0];851 852	hns3_dbg_fill_content(content, sizeof(content), queue_map_items,853			      NULL, ARRAY_SIZE(queue_map_items));854	pos += scnprintf(buf + pos, len - pos, "%s", content);855	for (i = 0; i < h->kinfo.num_tqps; i++) {856		if (!priv->ring || !priv->ring[i].tqp_vector)857			continue;858		j = 0;859		sprintf(result[j++], "%u", i);860		sprintf(result[j++], "%u",861			h->ae_algo->ops->get_global_queue_id(h, i));862		sprintf(result[j++], "%d",863			priv->ring[i].tqp_vector->vector_irq);864		hns3_dbg_fill_content(content, sizeof(content), queue_map_items,865				      (const char **)result,866				      ARRAY_SIZE(queue_map_items));867		pos += scnprintf(buf + pos, len - pos, "%s", content);868	}869 870	return 0;871}872 873static const struct hns3_dbg_item rx_bd_info_items[] = {874	{ "BD_IDX", 3 },875	{ "L234_INFO", 2 },876	{ "PKT_LEN", 3 },877	{ "SIZE", 4 },878	{ "RSS_HASH", 4 },879	{ "FD_ID", 2 },880	{ "VLAN_TAG", 2 },881	{ "O_DM_VLAN_ID_FB", 2 },882	{ "OT_VLAN_TAG", 2 },883	{ "BD_BASE_INFO", 2 },884	{ "PTYPE", 2 },885	{ "HW_CSUM", 2 },886};887 888static void hns3_dump_rx_bd_info(struct hns3_nic_priv *priv,889				 struct hns3_desc *desc, char **result, int idx)890{891	unsigned int j = 0;892 893	sprintf(result[j++], "%d", idx);894	sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.l234_info));895	sprintf(result[j++], "%u", le16_to_cpu(desc->rx.pkt_len));896	sprintf(result[j++], "%u", le16_to_cpu(desc->rx.size));897	sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.rss_hash));898	sprintf(result[j++], "%u", le16_to_cpu(desc->rx.fd_id));899	sprintf(result[j++], "%u", le16_to_cpu(desc->rx.vlan_tag));900	sprintf(result[j++], "%u", le16_to_cpu(desc->rx.o_dm_vlan_id_fb));901	sprintf(result[j++], "%u", le16_to_cpu(desc->rx.ot_vlan_tag));902	sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.bd_base_info));903	if (test_bit(HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, &priv->state)) {904		u32 ol_info = le32_to_cpu(desc->rx.ol_info);905 906		sprintf(result[j++], "%5lu", hnae3_get_field(ol_info,907							     HNS3_RXD_PTYPE_M,908							     HNS3_RXD_PTYPE_S));909		sprintf(result[j++], "%7u", le16_to_cpu(desc->csum));910	} else {911		sprintf(result[j++], "NA");912		sprintf(result[j++], "NA");913	}914}915 916static int hns3_dbg_rx_bd_info(struct hns3_dbg_data *d, char *buf, int len)917{918	char data_str[ARRAY_SIZE(rx_bd_info_items)][HNS3_DBG_DATA_STR_LEN];919	struct hns3_nic_priv *priv = d->handle->priv;920	char *result[ARRAY_SIZE(rx_bd_info_items)];921	char content[HNS3_DBG_INFO_LEN];922	struct hns3_enet_ring *ring;923	struct hns3_desc *desc;924	unsigned int i;925	int pos = 0;926 927	if (d->qid >= d->handle->kinfo.num_tqps) {928		dev_err(&d->handle->pdev->dev,929			"queue%u is not in use\n", d->qid);930		return -EINVAL;931	}932 933	for (i = 0; i < ARRAY_SIZE(rx_bd_info_items); i++)934		result[i] = &data_str[i][0];935 936	pos += scnprintf(buf + pos, len - pos,937			  "Queue %u rx bd info:\n", d->qid);938	hns3_dbg_fill_content(content, sizeof(content), rx_bd_info_items,939			      NULL, ARRAY_SIZE(rx_bd_info_items));940	pos += scnprintf(buf + pos, len - pos, "%s", content);941 942	ring = &priv->ring[d->qid + d->handle->kinfo.num_tqps];943	for (i = 0; i < ring->desc_num; i++) {944		desc = &ring->desc[i];945 946		hns3_dump_rx_bd_info(priv, desc, result, i);947		hns3_dbg_fill_content(content, sizeof(content),948				      rx_bd_info_items, (const char **)result,949				      ARRAY_SIZE(rx_bd_info_items));950		pos += scnprintf(buf + pos, len - pos, "%s", content);951	}952 953	return 0;954}955 956static const struct hns3_dbg_item tx_bd_info_items[] = {957	{ "BD_IDX", 2 },958	{ "ADDRESS", 13 },959	{ "VLAN_TAG", 2 },960	{ "SIZE", 2 },961	{ "T_CS_VLAN_TSO", 2 },962	{ "OT_VLAN_TAG", 3 },963	{ "TV", 5 },964	{ "OLT_VLAN_LEN", 2 },965	{ "PAYLEN_OL4CS", 2 },966	{ "BD_FE_SC_VLD", 2 },967	{ "MSS_HW_CSUM", 0 },968};969 970static void hns3_dump_tx_bd_info(struct hns3_desc *desc, char **result, int idx)971{972	unsigned int j = 0;973 974	sprintf(result[j++], "%d", idx);975	sprintf(result[j++], "%#llx", le64_to_cpu(desc->addr));976	sprintf(result[j++], "%u", le16_to_cpu(desc->tx.vlan_tag));977	sprintf(result[j++], "%u", le16_to_cpu(desc->tx.send_size));978	sprintf(result[j++], "%#x",979		le32_to_cpu(desc->tx.type_cs_vlan_tso_len));980	sprintf(result[j++], "%u", le16_to_cpu(desc->tx.outer_vlan_tag));981	sprintf(result[j++], "%u", le16_to_cpu(desc->tx.tv));982	sprintf(result[j++], "%u",983		le32_to_cpu(desc->tx.ol_type_vlan_len_msec));984	sprintf(result[j++], "%#x", le32_to_cpu(desc->tx.paylen_ol4cs));985	sprintf(result[j++], "%#x", le16_to_cpu(desc->tx.bdtp_fe_sc_vld_ra_ri));986	sprintf(result[j++], "%u", le16_to_cpu(desc->tx.mss_hw_csum));987}988 989static int hns3_dbg_tx_bd_info(struct hns3_dbg_data *d, char *buf, int len)990{991	char data_str[ARRAY_SIZE(tx_bd_info_items)][HNS3_DBG_DATA_STR_LEN];992	struct hns3_nic_priv *priv = d->handle->priv;993	char *result[ARRAY_SIZE(tx_bd_info_items)];994	char content[HNS3_DBG_INFO_LEN];995	struct hns3_enet_ring *ring;996	struct hns3_desc *desc;997	unsigned int i;998	int pos = 0;999 1000	if (d->qid >= d->handle->kinfo.num_tqps) {1001		dev_err(&d->handle->pdev->dev,1002			"queue%u is not in use\n", d->qid);1003		return -EINVAL;1004	}1005 1006	for (i = 0; i < ARRAY_SIZE(tx_bd_info_items); i++)1007		result[i] = &data_str[i][0];1008 1009	pos += scnprintf(buf + pos, len - pos,1010			  "Queue %u tx bd info:\n", d->qid);1011	hns3_dbg_fill_content(content, sizeof(content), tx_bd_info_items,1012			      NULL, ARRAY_SIZE(tx_bd_info_items));1013	pos += scnprintf(buf + pos, len - pos, "%s", content);1014 1015	ring = &priv->ring[d->qid];1016	for (i = 0; i < ring->desc_num; i++) {1017		desc = &ring->desc[i];1018 1019		hns3_dump_tx_bd_info(desc, result, i);1020		hns3_dbg_fill_content(content, sizeof(content),1021				      tx_bd_info_items, (const char **)result,1022				      ARRAY_SIZE(tx_bd_info_items));1023		pos += scnprintf(buf + pos, len - pos, "%s", content);1024	}1025 1026	return 0;1027}1028 1029static void1030hns3_dbg_dev_caps(struct hnae3_handle *h, char *buf, int len, int *pos)1031{1032	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);1033	const char * const str[] = {"no", "yes"};1034	unsigned long *caps = ae_dev->caps;1035	u32 i, state;1036 1037	*pos += scnprintf(buf + *pos, len - *pos, "dev capability:\n");1038 1039	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cap); i++) {1040		state = test_bit(hns3_dbg_cap[i].cap_bit, caps);1041		*pos += scnprintf(buf + *pos, len - *pos, "%s: %s\n",1042				  hns3_dbg_cap[i].name, str[state]);1043	}1044 1045	*pos += scnprintf(buf + *pos, len - *pos, "\n");1046}1047 1048static void1049hns3_dbg_dev_specs(struct hnae3_handle *h, char *buf, int len, int *pos)1050{1051	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);1052	struct hnae3_dev_specs *dev_specs = &ae_dev->dev_specs;1053	struct hnae3_knic_private_info *kinfo = &h->kinfo;1054	struct net_device *dev = kinfo->netdev;1055 1056	*pos += scnprintf(buf + *pos, len - *pos, "dev_spec:\n");1057	*pos += scnprintf(buf + *pos, len - *pos, "MAC entry num: %u\n",1058			  dev_specs->mac_entry_num);1059	*pos += scnprintf(buf + *pos, len - *pos, "MNG entry num: %u\n",1060			  dev_specs->mng_entry_num);1061	*pos += scnprintf(buf + *pos, len - *pos, "MAX non tso bd num: %u\n",1062			  dev_specs->max_non_tso_bd_num);1063	*pos += scnprintf(buf + *pos, len - *pos, "RSS ind tbl size: %u\n",1064			  dev_specs->rss_ind_tbl_size);1065	*pos += scnprintf(buf + *pos, len - *pos, "RSS key size: %u\n",1066			  dev_specs->rss_key_size);1067	*pos += scnprintf(buf + *pos, len - *pos, "RSS size: %u\n",1068			  kinfo->rss_size);1069	*pos += scnprintf(buf + *pos, len - *pos, "Allocated RSS size: %u\n",1070			  kinfo->req_rss_size);1071	*pos += scnprintf(buf + *pos, len - *pos,1072			  "Task queue pairs numbers: %u\n",1073			  kinfo->num_tqps);1074	*pos += scnprintf(buf + *pos, len - *pos, "RX buffer length: %u\n",1075			  kinfo->rx_buf_len);1076	*pos += scnprintf(buf + *pos, len - *pos, "Desc num per TX queue: %u\n",1077			  kinfo->num_tx_desc);1078	*pos += scnprintf(buf + *pos, len - *pos, "Desc num per RX queue: %u\n",1079			  kinfo->num_rx_desc);1080	*pos += scnprintf(buf + *pos, len - *pos,1081			  "Total number of enabled TCs: %u\n",1082			  kinfo->tc_info.num_tc);1083	*pos += scnprintf(buf + *pos, len - *pos, "MAX INT QL: %u\n",1084			  dev_specs->int_ql_max);1085	*pos += scnprintf(buf + *pos, len - *pos, "MAX INT GL: %u\n",1086			  dev_specs->max_int_gl);1087	*pos += scnprintf(buf + *pos, len - *pos, "MAX TM RATE: %u\n",1088			  dev_specs->max_tm_rate);1089	*pos += scnprintf(buf + *pos, len - *pos, "MAX QSET number: %u\n",1090			  dev_specs->max_qset_num);1091	*pos += scnprintf(buf + *pos, len - *pos, "umv size: %u\n",1092			  dev_specs->umv_size);1093	*pos += scnprintf(buf + *pos, len - *pos, "mc mac size: %u\n",1094			  dev_specs->mc_mac_size);1095	*pos += scnprintf(buf + *pos, len - *pos, "MAC statistics number: %u\n",1096			  dev_specs->mac_stats_num);1097	*pos += scnprintf(buf + *pos, len - *pos,1098			  "TX timeout threshold: %d seconds\n",1099			  dev->watchdog_timeo / HZ);1100	*pos += scnprintf(buf + *pos, len - *pos, "Hilink Version: %u\n",1101			  dev_specs->hilink_version);1102}1103 1104static int hns3_dbg_dev_info(struct hnae3_handle *h, char *buf, int len)1105{1106	int pos = 0;1107 1108	hns3_dbg_dev_caps(h, buf, len, &pos);1109 1110	hns3_dbg_dev_specs(h, buf, len, &pos);1111 1112	return 0;1113}1114 1115static const struct hns3_dbg_item page_pool_info_items[] = {1116	{ "QUEUE_ID", 2 },1117	{ "ALLOCATE_CNT", 2 },1118	{ "FREE_CNT", 6 },1119	{ "POOL_SIZE(PAGE_NUM)", 2 },1120	{ "ORDER", 2 },1121	{ "NUMA_ID", 2 },1122	{ "MAX_LEN", 2 },1123};1124 1125static void hns3_dump_page_pool_info(struct hns3_enet_ring *ring,1126				     char **result, u32 index)1127{1128	u32 j = 0;1129 1130	sprintf(result[j++], "%u", index);1131	sprintf(result[j++], "%u",1132		READ_ONCE(ring->page_pool->pages_state_hold_cnt));1133	sprintf(result[j++], "%d",1134		atomic_read(&ring->page_pool->pages_state_release_cnt));1135	sprintf(result[j++], "%u", ring->page_pool->p.pool_size);1136	sprintf(result[j++], "%u", ring->page_pool->p.order);1137	sprintf(result[j++], "%d", ring->page_pool->p.nid);1138	sprintf(result[j++], "%uK", ring->page_pool->p.max_len / 1024);1139}1140 1141static int1142hns3_dbg_page_pool_info(struct hnae3_handle *h, char *buf, int len)1143{1144	char data_str[ARRAY_SIZE(page_pool_info_items)][HNS3_DBG_DATA_STR_LEN];1145	char *result[ARRAY_SIZE(page_pool_info_items)];1146	struct hns3_nic_priv *priv = h->priv;1147	char content[HNS3_DBG_INFO_LEN];1148	struct hns3_enet_ring *ring;1149	int pos = 0;1150	u32 i;1151 1152	if (!priv->ring) {1153		dev_err(&h->pdev->dev, "priv->ring is NULL\n");1154		return -EFAULT;1155	}1156 1157	if (!priv->ring[h->kinfo.num_tqps].page_pool) {1158		dev_err(&h->pdev->dev, "page pool is not initialized\n");1159		return -EFAULT;1160	}1161 1162	for (i = 0; i < ARRAY_SIZE(page_pool_info_items); i++)1163		result[i] = &data_str[i][0];1164 1165	hns3_dbg_fill_content(content, sizeof(content), page_pool_info_items,1166			      NULL, ARRAY_SIZE(page_pool_info_items));1167	pos += scnprintf(buf + pos, len - pos, "%s", content);1168	for (i = 0; i < h->kinfo.num_tqps; i++) {1169		if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||1170		    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))1171			return -EPERM;1172		ring = &priv->ring[(u32)(i + h->kinfo.num_tqps)];1173		hns3_dump_page_pool_info(ring, result, i);1174		hns3_dbg_fill_content(content, sizeof(content),1175				      page_pool_info_items,1176				      (const char **)result,1177				      ARRAY_SIZE(page_pool_info_items));1178		pos += scnprintf(buf + pos, len - pos, "%s", content);1179	}1180 1181	return 0;1182}1183 1184static int hns3_dbg_get_cmd_index(struct hns3_dbg_data *dbg_data, u32 *index)1185{1186	u32 i;1187 1188	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) {1189		if (hns3_dbg_cmd[i].cmd == dbg_data->cmd) {1190			*index = i;1191			return 0;1192		}1193	}1194 1195	dev_err(&dbg_data->handle->pdev->dev, "unknown command(%d)\n",1196		dbg_data->cmd);1197	return -EINVAL;1198}1199 1200static const struct hns3_dbg_func hns3_dbg_cmd_func[] = {1201	{1202		.cmd = HNAE3_DBG_CMD_QUEUE_MAP,1203		.dbg_dump = hns3_dbg_queue_map,1204	},1205	{1206		.cmd = HNAE3_DBG_CMD_DEV_INFO,1207		.dbg_dump = hns3_dbg_dev_info,1208	},1209	{1210		.cmd = HNAE3_DBG_CMD_TX_BD,1211		.dbg_dump_bd = hns3_dbg_tx_bd_info,1212	},1213	{1214		.cmd = HNAE3_DBG_CMD_RX_BD,1215		.dbg_dump_bd = hns3_dbg_rx_bd_info,1216	},1217	{1218		.cmd = HNAE3_DBG_CMD_RX_QUEUE_INFO,1219		.dbg_dump = hns3_dbg_rx_queue_info,1220	},1221	{1222		.cmd = HNAE3_DBG_CMD_TX_QUEUE_INFO,1223		.dbg_dump = hns3_dbg_tx_queue_info,1224	},1225	{1226		.cmd = HNAE3_DBG_CMD_PAGE_POOL_INFO,1227		.dbg_dump = hns3_dbg_page_pool_info,1228	},1229	{1230		.cmd = HNAE3_DBG_CMD_COAL_INFO,1231		.dbg_dump = hns3_dbg_coal_info,1232	},1233};1234 1235static int hns3_dbg_read_cmd(struct hns3_dbg_data *dbg_data,1236			     enum hnae3_dbg_cmd cmd, char *buf, int len)1237{1238	const struct hnae3_ae_ops *ops = dbg_data->handle->ae_algo->ops;1239	const struct hns3_dbg_func *cmd_func;1240	u32 i;1241 1242	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd_func); i++) {1243		if (cmd == hns3_dbg_cmd_func[i].cmd) {1244			cmd_func = &hns3_dbg_cmd_func[i];1245			if (cmd_func->dbg_dump)1246				return cmd_func->dbg_dump(dbg_data->handle, buf,1247							  len);1248			else1249				return cmd_func->dbg_dump_bd(dbg_data, buf,1250							     len);1251		}1252	}1253 1254	if (!ops->dbg_read_cmd)1255		return -EOPNOTSUPP;1256 1257	return ops->dbg_read_cmd(dbg_data->handle, cmd, buf, len);1258}1259 1260static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,1261			     size_t count, loff_t *ppos)1262{1263	struct hns3_dbg_data *dbg_data = filp->private_data;1264	struct hnae3_handle *handle = dbg_data->handle;1265	struct hns3_nic_priv *priv = handle->priv;1266	ssize_t size = 0;1267	char **save_buf;1268	char *read_buf;1269	u32 index;1270	int ret;1271 1272	ret = hns3_dbg_get_cmd_index(dbg_data, &index);1273	if (ret)1274		return ret;1275 1276	mutex_lock(&handle->dbgfs_lock);1277	save_buf = &handle->dbgfs_buf[index];1278 1279	if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||1280	    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) {1281		ret = -EBUSY;1282		goto out;1283	}1284 1285	if (*save_buf) {1286		read_buf = *save_buf;1287	} else {1288		read_buf = kvzalloc(hns3_dbg_cmd[index].buf_len, GFP_KERNEL);1289		if (!read_buf) {1290			ret = -ENOMEM;1291			goto out;1292		}1293 1294		/* save the buffer addr until the last read operation */1295		*save_buf = read_buf;1296 1297		/* get data ready for the first time to read */1298		ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd,1299					read_buf, hns3_dbg_cmd[index].buf_len);1300		if (ret)1301			goto out;1302	}1303 1304	size = simple_read_from_buffer(buffer, count, ppos, read_buf,1305				       strlen(read_buf));1306	if (size > 0) {1307		mutex_unlock(&handle->dbgfs_lock);1308		return size;1309	}1310 1311out:1312	/* free the buffer for the last read operation */1313	if (*save_buf) {1314		kvfree(*save_buf);1315		*save_buf = NULL;1316	}1317 1318	mutex_unlock(&handle->dbgfs_lock);1319	return ret;1320}1321 1322static const struct file_operations hns3_dbg_fops = {1323	.owner = THIS_MODULE,1324	.open  = simple_open,1325	.read  = hns3_dbg_read,1326};1327 1328static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, u32 cmd)1329{1330	struct dentry *entry_dir;1331	struct hns3_dbg_data *data;1332	u16 max_queue_num;1333	unsigned int i;1334 1335	entry_dir = hns3_dbg_dentry[hns3_dbg_cmd[cmd].dentry].dentry;1336	max_queue_num = hns3_get_max_available_channels(handle);1337	data = devm_kzalloc(&handle->pdev->dev, max_queue_num * sizeof(*data),1338			    GFP_KERNEL);1339	if (!data)1340		return -ENOMEM;1341 1342	for (i = 0; i < max_queue_num; i++) {1343		char name[HNS3_DBG_FILE_NAME_LEN];1344 1345		data[i].handle = handle;1346		data[i].cmd = hns3_dbg_cmd[cmd].cmd;1347		data[i].qid = i;1348		sprintf(name, "%s%u", hns3_dbg_cmd[cmd].name, i);1349		debugfs_create_file(name, 0400, entry_dir, &data[i],1350				    &hns3_dbg_fops);1351	}1352 1353	return 0;1354}1355 1356static int1357hns3_dbg_common_file_init(struct hnae3_handle *handle, u32 cmd)1358{1359	struct hns3_dbg_data *data;1360	struct dentry *entry_dir;1361 1362	data = devm_kzalloc(&handle->pdev->dev, sizeof(*data), GFP_KERNEL);1363	if (!data)1364		return -ENOMEM;1365 1366	data->handle = handle;1367	data->cmd = hns3_dbg_cmd[cmd].cmd;1368	entry_dir = hns3_dbg_dentry[hns3_dbg_cmd[cmd].dentry].dentry;1369	debugfs_create_file(hns3_dbg_cmd[cmd].name, 0400, entry_dir,1370			    data, &hns3_dbg_fops);1371 1372	return 0;1373}1374 1375int hns3_dbg_init(struct hnae3_handle *handle)1376{1377	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev);1378	const char *name = pci_name(handle->pdev);1379	int ret;1380	u32 i;1381 1382	handle->dbgfs_buf = devm_kcalloc(&handle->pdev->dev,1383					 ARRAY_SIZE(hns3_dbg_cmd),1384					 sizeof(*handle->dbgfs_buf),1385					 GFP_KERNEL);1386	if (!handle->dbgfs_buf)1387		return -ENOMEM;1388 1389	hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry =1390				debugfs_create_dir(name, hns3_dbgfs_root);1391	handle->hnae3_dbgfs = hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry;1392 1393	for (i = 0; i < HNS3_DBG_DENTRY_COMMON; i++)1394		hns3_dbg_dentry[i].dentry =1395			debugfs_create_dir(hns3_dbg_dentry[i].name,1396					   handle->hnae3_dbgfs);1397 1398	mutex_init(&handle->dbgfs_lock);1399 1400	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) {1401		if ((hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_TM_NODES &&1402		     ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) ||1403		    (hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_PTP_INFO &&1404		     !test_bit(HNAE3_DEV_SUPPORT_PTP_B, ae_dev->caps)))1405			continue;1406 1407		if (!hns3_dbg_cmd[i].init) {1408			dev_err(&handle->pdev->dev,1409				"cmd %s lack of init func\n",1410				hns3_dbg_cmd[i].name);1411			ret = -EINVAL;1412			goto out;1413		}1414 1415		ret = hns3_dbg_cmd[i].init(handle, i);1416		if (ret) {1417			dev_err(&handle->pdev->dev, "failed to init cmd %s\n",1418				hns3_dbg_cmd[i].name);1419			goto out;1420		}1421	}1422 1423	return 0;1424 1425out:1426	debugfs_remove_recursive(handle->hnae3_dbgfs);1427	handle->hnae3_dbgfs = NULL;1428	mutex_destroy(&handle->dbgfs_lock);1429	return ret;1430}1431 1432void hns3_dbg_uninit(struct hnae3_handle *handle)1433{1434	u32 i;1435 1436	debugfs_remove_recursive(handle->hnae3_dbgfs);1437	handle->hnae3_dbgfs = NULL;1438 1439	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++)1440		if (handle->dbgfs_buf[i]) {1441			kvfree(handle->dbgfs_buf[i]);1442			handle->dbgfs_buf[i] = NULL;1443		}1444 1445	mutex_destroy(&handle->dbgfs_lock);1446}1447 1448void hns3_dbg_register_debugfs(const char *debugfs_dir_name)1449{1450	hns3_dbgfs_root = debugfs_create_dir(debugfs_dir_name, NULL);1451}1452 1453void hns3_dbg_unregister_debugfs(void)1454{1455	debugfs_remove_recursive(hns3_dbgfs_root);1456	hns3_dbgfs_root = NULL;1457}1458