1272 lines · 29.3 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0/* Copyright (c) 2022 HiSilicon Limited. */#include <linux/hisi_acc_qm.h>#include "qm_common.h" #define QM_DFX_BASE			0x0100000#define QM_DFX_STATE1			0x0104000#define QM_DFX_STATE2			0x01040C8#define QM_DFX_COMMON			0x0000#define QM_DFX_BASE_LEN			0x5A#define QM_DFX_STATE1_LEN		0x2E#define QM_DFX_STATE2_LEN		0x11#define QM_DFX_COMMON_LEN		0xC3#define QM_DFX_REGS_LEN			4UL#define QM_DBG_TMP_BUF_LEN		22#define QM_XQC_ADDR_MASK		GENMASK(31, 0)#define CURRENT_FUN_MASK		GENMASK(5, 0)#define CURRENT_Q_MASK			GENMASK(31, 16)#define QM_SQE_ADDR_MASK		GENMASK(7, 0) #define QM_DFX_MB_CNT_VF		0x104010#define QM_DFX_DB_CNT_VF		0x104020#define QM_DFX_SQE_CNT_VF_SQN		0x104030#define QM_DFX_CQE_CNT_VF_CQN		0x104040#define QM_DFX_QN_SHIFT			16#define QM_DFX_CNT_CLR_CE		0x100118#define QM_DBG_WRITE_LEN		1024#define QM_IN_IDLE_ST_REG		0x1040e4#define QM_IN_IDLE_STATE		0x1 static const char * const qm_debug_file_name[] = {	[CURRENT_QM]   = "current_qm",	[CURRENT_Q]    = "current_q",	[CLEAR_ENABLE] = "clear_enable",}; static const char * const qm_s[] = {	"work", "stop",}; struct qm_dfx_item {	const char *name;	u32 offset;}; struct qm_cmd_dump_item {	const char *cmd;	const char *info_name;	int (*dump_fn)(struct hisi_qm *qm, char *cmd, const char *info_name);}; static struct qm_dfx_item qm_dfx_files[] = {	{"err_irq", offsetof(struct qm_dfx, err_irq_cnt)},	{"aeq_irq", offsetof(struct qm_dfx, aeq_irq_cnt)},	{"abnormal_irq", offsetof(struct qm_dfx, abnormal_irq_cnt)},	{"create_qp_err", offsetof(struct qm_dfx, create_qp_err_cnt)},	{"mb_err", offsetof(struct qm_dfx, mb_err_cnt)},}; #define CNT_CYC_REGS_NUM		10static const struct debugfs_reg32 qm_dfx_regs[] = {	/* XXX_CNT are reading clear register */	{"QM_ECC_1BIT_CNT               ",  0x104000},	{"QM_ECC_MBIT_CNT               ",  0x104008},	{"QM_DFX_MB_CNT                 ",  0x104018},	{"QM_DFX_DB_CNT                 ",  0x104028},	{"QM_DFX_SQE_CNT                ",  0x104038},	{"QM_DFX_CQE_CNT                ",  0x104048},	{"QM_DFX_SEND_SQE_TO_ACC_CNT    ",  0x104050},	{"QM_DFX_WB_SQE_FROM_ACC_CNT    ",  0x104058},	{"QM_DFX_ACC_FINISH_CNT         ",  0x104060},	{"QM_DFX_CQE_ERR_CNT            ",  0x1040b4},	{"QM_DFX_FUNS_ACTIVE_ST         ",  0x200},	{"QM_ECC_1BIT_INF               ",  0x104004},	{"QM_ECC_MBIT_INF               ",  0x10400c},	{"QM_DFX_ACC_RDY_VLD0           ",  0x1040a0},	{"QM_DFX_ACC_RDY_VLD1           ",  0x1040a4},	{"QM_DFX_AXI_RDY_VLD            ",  0x1040a8},	{"QM_DFX_FF_ST0                 ",  0x1040c8},	{"QM_DFX_FF_ST1                 ",  0x1040cc},	{"QM_DFX_FF_ST2                 ",  0x1040d0},	{"QM_DFX_FF_ST3                 ",  0x1040d4},	{"QM_DFX_FF_ST4                 ",  0x1040d8},	{"QM_DFX_FF_ST5                 ",  0x1040dc},	{"QM_DFX_FF_ST6                 ",  0x1040e0},	{"QM_IN_IDLE_ST                 ",  0x1040e4},	{"QM_CACHE_CTL                  ",  0x100050},	{"QM_TIMEOUT_CFG                ",  0x100070},	{"QM_DB_TIMEOUT_CFG             ",  0x100074},	{"QM_FLR_PENDING_TIME_CFG       ",  0x100078},	{"QM_ARUSR_MCFG1                ",  0x100088},	{"QM_AWUSR_MCFG1                ",  0x100098},	{"QM_AXI_M_CFG_ENABLE           ",  0x1000B0},	{"QM_RAS_CE_THRESHOLD           ",  0x1000F8},	{"QM_AXI_TIMEOUT_CTRL           ",  0x100120},	{"QM_AXI_TIMEOUT_STATUS         ",  0x100124},	{"QM_CQE_AGGR_TIMEOUT_CTRL      ",  0x100144},	{"ACC_RAS_MSI_INT_SEL           ",  0x1040fc},	{"QM_CQE_OUT                    ",  0x104100},	{"QM_EQE_OUT                    ",  0x104104},	{"QM_AEQE_OUT                   ",  0x104108},	{"QM_DB_INFO0                   ",  0x104180},	{"QM_DB_INFO1                   ",  0x104184},	{"QM_AM_CTRL_GLOBAL             ",  0x300000},	{"QM_AM_CURR_PORT_STS           ",  0x300100},	{"QM_AM_CURR_TRANS_RETURN       ",  0x300150},	{"QM_AM_CURR_RD_MAX_TXID        ",  0x300154},	{"QM_AM_CURR_WR_MAX_TXID        ",  0x300158},	{"QM_AM_ALARM_RRESP             ",  0x300180},	{"QM_AM_ALARM_BRESP             ",  0x300184},}; static const struct debugfs_reg32 qm_vf_dfx_regs[] = {	{"QM_DFX_FUNS_ACTIVE_ST         ",  0x200},}; /* define the QM's dfx regs region and region length */static struct dfx_diff_registers qm_diff_regs[] = {	{		.reg_offset = QM_DFX_BASE,		.reg_len = QM_DFX_BASE_LEN,	}, {		.reg_offset = QM_DFX_STATE1,		.reg_len = QM_DFX_STATE1_LEN,	}, {		.reg_offset = QM_DFX_STATE2,		.reg_len = QM_DFX_STATE2_LEN,	}, {		.reg_offset = QM_DFX_COMMON,		.reg_len = QM_DFX_COMMON_LEN,	},}; static struct hisi_qm *file_to_qm(struct debugfs_file *file){	struct qm_debug *debug = file->debug; 	return container_of(debug, struct hisi_qm, debug);} static ssize_t qm_cmd_read(struct file *filp, char __user *buffer,			   size_t count, loff_t *pos){	char buf[QM_DBG_READ_LEN];	int len; 	len = scnprintf(buf, QM_DBG_READ_LEN, "%s\n",			"Please echo help to cmd to get help information"); 	return simple_read_from_buffer(buffer, count, pos, buf, len);} static void dump_show(struct hisi_qm *qm, void *info,		     unsigned int info_size, const char *info_name){	struct device *dev = &qm->pdev->dev;	u8 *info_curr = info;	u32 i;#define BYTE_PER_DW	4 	dev_info(dev, "%s DUMP\n", info_name);	for (i = 0; i < info_size; i += BYTE_PER_DW, info_curr += BYTE_PER_DW) {		pr_info("DW%u: %02X%02X %02X%02X\n", i / BYTE_PER_DW,			*(info_curr + 3), *(info_curr + 2), *(info_curr + 1), *(info_curr));	}} static int qm_sqc_dump(struct hisi_qm *qm, char *s, const char *name){	struct device *dev = &qm->pdev->dev;	struct qm_sqc sqc;	u32 qp_id;	int ret; 	if (!s)		return -EINVAL; 	ret = kstrtou32(s, 0, &qp_id);	if (ret || qp_id >= qm->qp_num) {		dev_err(dev, "Please input qp num (0-%u)", qm->qp_num - 1);		return -EINVAL;	} 	ret = qm_set_and_get_xqc(qm, QM_MB_CMD_SQC, &sqc, qp_id, 1);	if (!ret) {		sqc.base_h = cpu_to_le32(QM_XQC_ADDR_MASK);		sqc.base_l = cpu_to_le32(QM_XQC_ADDR_MASK);		dump_show(qm, &sqc, sizeof(struct qm_sqc), name); 		return 0;	} 	down_read(&qm->qps_lock);	if (qm->sqc) {		memcpy(&sqc, qm->sqc + qp_id, sizeof(struct qm_sqc));		sqc.base_h = cpu_to_le32(QM_XQC_ADDR_MASK);		sqc.base_l = cpu_to_le32(QM_XQC_ADDR_MASK);		dump_show(qm, &sqc, sizeof(struct qm_sqc), "SOFT SQC");	}	up_read(&qm->qps_lock); 	return 0;} static int qm_cqc_dump(struct hisi_qm *qm, char *s, const char *name){	struct device *dev = &qm->pdev->dev;	struct qm_cqc cqc;	u32 qp_id;	int ret; 	if (!s)		return -EINVAL; 	ret = kstrtou32(s, 0, &qp_id);	if (ret || qp_id >= qm->qp_num) {		dev_err(dev, "Please input qp num (0-%u)", qm->qp_num - 1);		return -EINVAL;	} 	ret = qm_set_and_get_xqc(qm, QM_MB_CMD_CQC, &cqc, qp_id, 1);	if (!ret) {		cqc.base_h = cpu_to_le32(QM_XQC_ADDR_MASK);		cqc.base_l = cpu_to_le32(QM_XQC_ADDR_MASK);		dump_show(qm, &cqc, sizeof(struct qm_cqc), name); 		return 0;	} 	down_read(&qm->qps_lock);	if (qm->cqc) {		memcpy(&cqc, qm->cqc + qp_id, sizeof(struct qm_cqc));		cqc.base_h = cpu_to_le32(QM_XQC_ADDR_MASK);		cqc.base_l = cpu_to_le32(QM_XQC_ADDR_MASK);		dump_show(qm, &cqc, sizeof(struct qm_cqc), "SOFT CQC");	}	up_read(&qm->qps_lock); 	return 0;} static int qm_eqc_aeqc_dump(struct hisi_qm *qm, char *s, const char *name){	struct device *dev = &qm->pdev->dev;	struct qm_aeqc aeqc;	struct qm_eqc eqc;	size_t size;	void *xeqc;	int ret;	u8 cmd; 	if (strsep(&s, " ")) {		dev_err(dev, "Please do not input extra characters!\n");		return -EINVAL;	} 	if (!strcmp(name, "EQC")) {		cmd = QM_MB_CMD_EQC;		size = sizeof(struct qm_eqc);		xeqc = &eqc;	} else {		cmd = QM_MB_CMD_AEQC;		size = sizeof(struct qm_aeqc);		xeqc = &aeqc;	} 	ret = qm_set_and_get_xqc(qm, cmd, xeqc, 0, 1);	if (ret)		return ret; 	aeqc.base_h = cpu_to_le32(QM_XQC_ADDR_MASK);	aeqc.base_l = cpu_to_le32(QM_XQC_ADDR_MASK);	eqc.base_h = cpu_to_le32(QM_XQC_ADDR_MASK);	eqc.base_l = cpu_to_le32(QM_XQC_ADDR_MASK);	dump_show(qm, xeqc, size, name); 	return ret;} static int q_dump_param_parse(struct hisi_qm *qm, char *s,			      u32 *e_id, u32 *q_id, u16 q_depth){	struct device *dev = &qm->pdev->dev;	unsigned int qp_num = qm->qp_num;	char *presult;	int ret; 	presult = strsep(&s, " ");	if (!presult) {		dev_err(dev, "Please input qp number!\n");		return -EINVAL;	} 	ret = kstrtou32(presult, 0, q_id);	if (ret || *q_id >= qp_num) {		dev_err(dev, "Please input qp num (0-%u)", qp_num - 1);		return -EINVAL;	} 	presult = strsep(&s, " ");	if (!presult) {		dev_err(dev, "Please input sqe number!\n");		return -EINVAL;	} 	ret = kstrtou32(presult, 0, e_id);	if (ret || *e_id >= q_depth) {		dev_err(dev, "Please input sqe num (0-%d)", q_depth - 1);		return -EINVAL;	} 	if (strsep(&s, " ")) {		dev_err(dev, "Please do not input extra characters!\n");		return -EINVAL;	} 	return 0;} static int qm_sq_dump(struct hisi_qm *qm, char *s, const char *name){	u16 sq_depth = qm->qp_array->sq_depth;	struct hisi_qp *qp;	u32 qp_id, sqe_id;	void *sqe;	int ret; 	ret = q_dump_param_parse(qm, s, &sqe_id, &qp_id, sq_depth);	if (ret)		return ret; 	sqe = kzalloc(qm->sqe_size, GFP_KERNEL);	if (!sqe)		return -ENOMEM; 	qp = &qm->qp_array[qp_id];	memcpy(sqe, qp->sqe + sqe_id * qm->sqe_size, qm->sqe_size);	memset(sqe + qm->debug.sqe_mask_offset, QM_SQE_ADDR_MASK,	       qm->debug.sqe_mask_len); 	dump_show(qm, sqe, qm->sqe_size, name); 	kfree(sqe); 	return 0;} static int qm_cq_dump(struct hisi_qm *qm, char *s, const char *name){	struct qm_cqe *cqe_curr;	struct hisi_qp *qp;	u32 qp_id, cqe_id;	int ret; 	ret = q_dump_param_parse(qm, s, &cqe_id, &qp_id, qm->qp_array->cq_depth);	if (ret)		return ret; 	qp = &qm->qp_array[qp_id];	cqe_curr = qp->cqe + cqe_id;	dump_show(qm, cqe_curr, sizeof(struct qm_cqe), name); 	return 0;} static int qm_eq_aeq_dump(struct hisi_qm *qm, char *s, const char *name){	struct device *dev = &qm->pdev->dev;	u16 xeq_depth;	size_t size;	void *xeqe;	u32 xeqe_id;	int ret; 	if (!s)		return -EINVAL; 	ret = kstrtou32(s, 0, &xeqe_id);	if (ret)		return -EINVAL; 	if (!strcmp(name, "EQE")) {		xeq_depth = qm->eq_depth;		size = sizeof(struct qm_eqe);	} else {		xeq_depth = qm->aeq_depth;		size = sizeof(struct qm_aeqe);	} 	if (xeqe_id >= xeq_depth) {		dev_err(dev, "Please input eqe or aeqe num (0-%d)", xeq_depth - 1);		return -EINVAL;	} 	down_read(&qm->qps_lock); 	if (qm->eqe && !strcmp(name, "EQE")) {		xeqe = qm->eqe + xeqe_id;	} else if (qm->aeqe && !strcmp(name, "AEQE")) {		xeqe = qm->aeqe + xeqe_id;	} else {		ret = -EINVAL;		goto err_unlock;	} 	dump_show(qm, xeqe, size, name); err_unlock:	up_read(&qm->qps_lock);	return ret;} static int qm_dbg_help(struct hisi_qm *qm, char *s){	struct device *dev = &qm->pdev->dev; 	if (strsep(&s, " ")) {		dev_err(dev, "Please do not input extra characters!\n");		return -EINVAL;	} 	dev_info(dev, "available commands:\n");	dev_info(dev, "sqc <num>\n");	dev_info(dev, "cqc <num>\n");	dev_info(dev, "eqc\n");	dev_info(dev, "aeqc\n");	dev_info(dev, "sq <num> <e>\n");	dev_info(dev, "cq <num> <e>\n");	dev_info(dev, "eq <e>\n");	dev_info(dev, "aeq <e>\n"); 	return 0;} static const struct qm_cmd_dump_item qm_cmd_dump_table[] = {	{		.cmd = "sqc",		.info_name = "SQC",		.dump_fn = qm_sqc_dump,	}, {		.cmd = "cqc",		.info_name = "CQC",		.dump_fn = qm_cqc_dump,	}, {		.cmd = "eqc",		.info_name = "EQC",		.dump_fn = qm_eqc_aeqc_dump,	}, {		.cmd = "aeqc",		.info_name = "AEQC",		.dump_fn = qm_eqc_aeqc_dump,	}, {		.cmd = "sq",		.info_name = "SQE",		.dump_fn = qm_sq_dump,	}, {		.cmd = "cq",		.info_name = "CQE",		.dump_fn = qm_cq_dump,	}, {		.cmd = "eq",		.info_name = "EQE",		.dump_fn = qm_eq_aeq_dump,	}, {		.cmd = "aeq",		.info_name = "AEQE",		.dump_fn = qm_eq_aeq_dump,	},}; static int qm_cmd_write_dump(struct hisi_qm *qm, const char *cmd_buf){	struct device *dev = &qm->pdev->dev;	char *presult, *s, *s_tmp;	int table_size, i, ret; 	s = kstrdup(cmd_buf, GFP_KERNEL);	if (!s)		return -ENOMEM; 	s_tmp = s;	presult = strsep(&s, " ");	if (!presult) {		ret = -EINVAL;		goto err_buffer_free;	} 	if (!strcmp(presult, "help")) {		ret = qm_dbg_help(qm, s);		goto err_buffer_free;	} 	table_size = ARRAY_SIZE(qm_cmd_dump_table);	for (i = 0; i < table_size; i++) {		if (!strcmp(presult, qm_cmd_dump_table[i].cmd)) {			ret = qm_cmd_dump_table[i].dump_fn(qm, s,				qm_cmd_dump_table[i].info_name);			break;		}	}

Lines 1–500 of 1272.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t