diff options
12 files changed, 875 insertions, 681 deletions
| diff --git a/drivers/net/ethernet/hisilicon/hns3/Makefile b/drivers/net/ethernet/hisilicon/hns3/Makefile index 6efea4662858..e214bfaece1f 100644 --- a/drivers/net/ethernet/hisilicon/hns3/Makefile +++ b/drivers/net/ethernet/hisilicon/hns3/Makefile @@ -17,11 +17,11 @@ hns3-$(CONFIG_HNS3_DCB) += hns3_dcbnl.o  obj-$(CONFIG_HNS3_HCLGEVF) += hclgevf.o -hclgevf-objs = hns3vf/hclgevf_main.o hns3vf/hclgevf_mbx.o  hns3vf/hclgevf_devlink.o \ +hclgevf-objs = hns3vf/hclgevf_main.o hns3vf/hclgevf_mbx.o  hns3vf/hclgevf_devlink.o hns3vf/hclgevf_regs.o \  		hns3_common/hclge_comm_cmd.o hns3_common/hclge_comm_rss.o hns3_common/hclge_comm_tqp_stats.o  obj-$(CONFIG_HNS3_HCLGE) += hclge.o -hclge-objs = hns3pf/hclge_main.o hns3pf/hclge_mdio.o hns3pf/hclge_tm.o \ +hclge-objs = hns3pf/hclge_main.o hns3pf/hclge_mdio.o hns3pf/hclge_tm.o hns3pf/hclge_regs.o \  		hns3pf/hclge_mbx.o hns3pf/hclge_err.o  hns3pf/hclge_debugfs.o hns3pf/hclge_ptp.o hns3pf/hclge_devlink.o \  		hns3_common/hclge_comm_cmd.o hns3_common/hclge_comm_rss.o hns3_common/hclge_comm_tqp_stats.o diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 514a20bce4f4..a4b43bcd2f0c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -382,6 +382,7 @@ struct hnae3_dev_specs {  	u16 umv_size;  	u16 mc_mac_size;  	u32 mac_stats_num; +	u8 tnl_num;  };  struct hnae3_client_ops { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h index 0bd858620f27..4d15eb73b972 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h @@ -826,7 +826,9 @@ struct hclge_dev_specs_1_cmd {  	u8 rsv0[2];  	__le16 umv_size;  	__le16 mc_mac_size; -	u8 rsv1[12]; +	u8 rsv1[6]; +	u8 tnl_num; +	u8 rsv2[5];  };  /* mac speed type defined in firmware command */ diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c index 0fb2eaee3e8a..f01a7a9ee02c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c @@ -7,6 +7,7 @@  #include "hclge_debugfs.h"  #include "hclge_err.h"  #include "hclge_main.h" +#include "hclge_regs.h"  #include "hclge_tm.h"  #include "hnae3.h" diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 437b510f2b80..0f50dba6cc47 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -20,6 +20,7 @@  #include "hclge_main.h"  #include "hclge_mbx.h"  #include "hclge_mdio.h" +#include "hclge_regs.h"  #include "hclge_tm.h"  #include "hclge_err.h"  #include "hnae3.h" @@ -40,20 +41,6 @@  #define HCLGE_PF_RESET_SYNC_TIME	20  #define HCLGE_PF_RESET_SYNC_CNT		1500 -/* Get DFX BD number offset */ -#define HCLGE_DFX_BIOS_BD_OFFSET        1 -#define HCLGE_DFX_SSU_0_BD_OFFSET       2 -#define HCLGE_DFX_SSU_1_BD_OFFSET       3 -#define HCLGE_DFX_IGU_BD_OFFSET         4 -#define HCLGE_DFX_RPU_0_BD_OFFSET       5 -#define HCLGE_DFX_RPU_1_BD_OFFSET       6 -#define HCLGE_DFX_NCSI_BD_OFFSET        7 -#define HCLGE_DFX_RTC_BD_OFFSET         8 -#define HCLGE_DFX_PPP_BD_OFFSET         9 -#define HCLGE_DFX_RCB_BD_OFFSET         10 -#define HCLGE_DFX_TQP_BD_OFFSET         11 -#define HCLGE_DFX_SSU_2_BD_OFFSET       12 -  #define HCLGE_LINK_STATUS_MS	10  static int hclge_set_mac_mtu(struct hclge_dev *hdev, int new_mps); @@ -94,62 +81,6 @@ static const struct pci_device_id ae_algo_pci_tbl[] = {  MODULE_DEVICE_TABLE(pci, ae_algo_pci_tbl); -static const u32 cmdq_reg_addr_list[] = {HCLGE_COMM_NIC_CSQ_BASEADDR_L_REG, -					 HCLGE_COMM_NIC_CSQ_BASEADDR_H_REG, -					 HCLGE_COMM_NIC_CSQ_DEPTH_REG, -					 HCLGE_COMM_NIC_CSQ_TAIL_REG, -					 HCLGE_COMM_NIC_CSQ_HEAD_REG, -					 HCLGE_COMM_NIC_CRQ_BASEADDR_L_REG, -					 HCLGE_COMM_NIC_CRQ_BASEADDR_H_REG, -					 HCLGE_COMM_NIC_CRQ_DEPTH_REG, -					 HCLGE_COMM_NIC_CRQ_TAIL_REG, -					 HCLGE_COMM_NIC_CRQ_HEAD_REG, -					 HCLGE_COMM_VECTOR0_CMDQ_SRC_REG, -					 HCLGE_COMM_CMDQ_INTR_STS_REG, -					 HCLGE_COMM_CMDQ_INTR_EN_REG, -					 HCLGE_COMM_CMDQ_INTR_GEN_REG}; - -static const u32 common_reg_addr_list[] = {HCLGE_MISC_VECTOR_REG_BASE, -					   HCLGE_PF_OTHER_INT_REG, -					   HCLGE_MISC_RESET_STS_REG, -					   HCLGE_MISC_VECTOR_INT_STS, -					   HCLGE_GLOBAL_RESET_REG, -					   HCLGE_FUN_RST_ING, -					   HCLGE_GRO_EN_REG}; - -static const u32 ring_reg_addr_list[] = {HCLGE_RING_RX_ADDR_L_REG, -					 HCLGE_RING_RX_ADDR_H_REG, -					 HCLGE_RING_RX_BD_NUM_REG, -					 HCLGE_RING_RX_BD_LENGTH_REG, -					 HCLGE_RING_RX_MERGE_EN_REG, -					 HCLGE_RING_RX_TAIL_REG, -					 HCLGE_RING_RX_HEAD_REG, -					 HCLGE_RING_RX_FBD_NUM_REG, -					 HCLGE_RING_RX_OFFSET_REG, -					 HCLGE_RING_RX_FBD_OFFSET_REG, -					 HCLGE_RING_RX_STASH_REG, -					 HCLGE_RING_RX_BD_ERR_REG, -					 HCLGE_RING_TX_ADDR_L_REG, -					 HCLGE_RING_TX_ADDR_H_REG, -					 HCLGE_RING_TX_BD_NUM_REG, -					 HCLGE_RING_TX_PRIORITY_REG, -					 HCLGE_RING_TX_TC_REG, -					 HCLGE_RING_TX_MERGE_EN_REG, -					 HCLGE_RING_TX_TAIL_REG, -					 HCLGE_RING_TX_HEAD_REG, -					 HCLGE_RING_TX_FBD_NUM_REG, -					 HCLGE_RING_TX_OFFSET_REG, -					 HCLGE_RING_TX_EBD_NUM_REG, -					 HCLGE_RING_TX_EBD_OFFSET_REG, -					 HCLGE_RING_TX_BD_ERR_REG, -					 HCLGE_RING_EN_REG}; - -static const u32 tqp_intr_reg_addr_list[] = {HCLGE_TQP_INTR_CTRL_REG, -					     HCLGE_TQP_INTR_GL0_REG, -					     HCLGE_TQP_INTR_GL1_REG, -					     HCLGE_TQP_INTR_GL2_REG, -					     HCLGE_TQP_INTR_RL_REG}; -  static const char hns3_nic_test_strs[][ETH_GSTRING_LEN] = {  	"External Loopback test",  	"App      Loopback test", @@ -375,36 +306,6 @@ static const struct hclge_mac_mgr_tbl_entry_cmd hclge_mgr_table[] = {  	},  }; -static const u32 hclge_dfx_bd_offset_list[] = { -	HCLGE_DFX_BIOS_BD_OFFSET, -	HCLGE_DFX_SSU_0_BD_OFFSET, -	HCLGE_DFX_SSU_1_BD_OFFSET, -	HCLGE_DFX_IGU_BD_OFFSET, -	HCLGE_DFX_RPU_0_BD_OFFSET, -	HCLGE_DFX_RPU_1_BD_OFFSET, -	HCLGE_DFX_NCSI_BD_OFFSET, -	HCLGE_DFX_RTC_BD_OFFSET, -	HCLGE_DFX_PPP_BD_OFFSET, -	HCLGE_DFX_RCB_BD_OFFSET, -	HCLGE_DFX_TQP_BD_OFFSET, -	HCLGE_DFX_SSU_2_BD_OFFSET -}; - -static const enum hclge_opcode_type hclge_dfx_reg_opcode_list[] = { -	HCLGE_OPC_DFX_BIOS_COMMON_REG, -	HCLGE_OPC_DFX_SSU_REG_0, -	HCLGE_OPC_DFX_SSU_REG_1, -	HCLGE_OPC_DFX_IGU_EGU_REG, -	HCLGE_OPC_DFX_RPU_REG_0, -	HCLGE_OPC_DFX_RPU_REG_1, -	HCLGE_OPC_DFX_NCSI_REG, -	HCLGE_OPC_DFX_RTC_REG, -	HCLGE_OPC_DFX_PPP_REG, -	HCLGE_OPC_DFX_RCB_REG, -	HCLGE_OPC_DFX_TQP_REG, -	HCLGE_OPC_DFX_SSU_REG_2 -}; -  static const struct key_info meta_data_key_info[] = {  	{ PACKET_TYPE_ID, 6 },  	{ IP_FRAGEMENT, 1 }, @@ -1425,6 +1326,7 @@ static void hclge_set_default_dev_specs(struct hclge_dev *hdev)  	ae_dev->dev_specs.max_frm_size = HCLGE_MAC_MAX_FRAME;  	ae_dev->dev_specs.max_qset_num = HCLGE_MAX_QSET_NUM;  	ae_dev->dev_specs.umv_size = HCLGE_DEFAULT_UMV_SPACE_PER_PF; +	ae_dev->dev_specs.tnl_num = 0;  }  static void hclge_parse_dev_specs(struct hclge_dev *hdev, @@ -1448,6 +1350,7 @@ static void hclge_parse_dev_specs(struct hclge_dev *hdev,  	ae_dev->dev_specs.max_frm_size = le16_to_cpu(req1->max_frm_size);  	ae_dev->dev_specs.umv_size = le16_to_cpu(req1->umv_size);  	ae_dev->dev_specs.mc_mac_size = le16_to_cpu(req1->mc_mac_size); +	ae_dev->dev_specs.tnl_num = req1->tnl_num;  }  static void hclge_check_dev_specs(struct hclge_dev *hdev) @@ -12383,463 +12286,6 @@ out:  	return ret;  } -static int hclge_get_regs_num(struct hclge_dev *hdev, u32 *regs_num_32_bit, -			      u32 *regs_num_64_bit) -{ -	struct hclge_desc desc; -	u32 total_num; -	int ret; - -	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QUERY_REG_NUM, true); -	ret = hclge_cmd_send(&hdev->hw, &desc, 1); -	if (ret) { -		dev_err(&hdev->pdev->dev, -			"Query register number cmd failed, ret = %d.\n", ret); -		return ret; -	} - -	*regs_num_32_bit = le32_to_cpu(desc.data[0]); -	*regs_num_64_bit = le32_to_cpu(desc.data[1]); - -	total_num = *regs_num_32_bit + *regs_num_64_bit; -	if (!total_num) -		return -EINVAL; - -	return 0; -} - -static int hclge_get_32_bit_regs(struct hclge_dev *hdev, u32 regs_num, -				 void *data) -{ -#define HCLGE_32_BIT_REG_RTN_DATANUM 8 -#define HCLGE_32_BIT_DESC_NODATA_LEN 2 - -	struct hclge_desc *desc; -	u32 *reg_val = data; -	__le32 *desc_data; -	int nodata_num; -	int cmd_num; -	int i, k, n; -	int ret; - -	if (regs_num == 0) -		return 0; - -	nodata_num = HCLGE_32_BIT_DESC_NODATA_LEN; -	cmd_num = DIV_ROUND_UP(regs_num + nodata_num, -			       HCLGE_32_BIT_REG_RTN_DATANUM); -	desc = kcalloc(cmd_num, sizeof(struct hclge_desc), GFP_KERNEL); -	if (!desc) -		return -ENOMEM; - -	hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_QUERY_32_BIT_REG, true); -	ret = hclge_cmd_send(&hdev->hw, desc, cmd_num); -	if (ret) { -		dev_err(&hdev->pdev->dev, -			"Query 32 bit register cmd failed, ret = %d.\n", ret); -		kfree(desc); -		return ret; -	} - -	for (i = 0; i < cmd_num; i++) { -		if (i == 0) { -			desc_data = (__le32 *)(&desc[i].data[0]); -			n = HCLGE_32_BIT_REG_RTN_DATANUM - nodata_num; -		} else { -			desc_data = (__le32 *)(&desc[i]); -			n = HCLGE_32_BIT_REG_RTN_DATANUM; -		} -		for (k = 0; k < n; k++) { -			*reg_val++ = le32_to_cpu(*desc_data++); - -			regs_num--; -			if (!regs_num) -				break; -		} -	} - -	kfree(desc); -	return 0; -} - -static int hclge_get_64_bit_regs(struct hclge_dev *hdev, u32 regs_num, -				 void *data) -{ -#define HCLGE_64_BIT_REG_RTN_DATANUM 4 -#define HCLGE_64_BIT_DESC_NODATA_LEN 1 - -	struct hclge_desc *desc; -	u64 *reg_val = data; -	__le64 *desc_data; -	int nodata_len; -	int cmd_num; -	int i, k, n; -	int ret; - -	if (regs_num == 0) -		return 0; - -	nodata_len = HCLGE_64_BIT_DESC_NODATA_LEN; -	cmd_num = DIV_ROUND_UP(regs_num + nodata_len, -			       HCLGE_64_BIT_REG_RTN_DATANUM); -	desc = kcalloc(cmd_num, sizeof(struct hclge_desc), GFP_KERNEL); -	if (!desc) -		return -ENOMEM; - -	hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_QUERY_64_BIT_REG, true); -	ret = hclge_cmd_send(&hdev->hw, desc, cmd_num); -	if (ret) { -		dev_err(&hdev->pdev->dev, -			"Query 64 bit register cmd failed, ret = %d.\n", ret); -		kfree(desc); -		return ret; -	} - -	for (i = 0; i < cmd_num; i++) { -		if (i == 0) { -			desc_data = (__le64 *)(&desc[i].data[0]); -			n = HCLGE_64_BIT_REG_RTN_DATANUM - nodata_len; -		} else { -			desc_data = (__le64 *)(&desc[i]); -			n = HCLGE_64_BIT_REG_RTN_DATANUM; -		} -		for (k = 0; k < n; k++) { -			*reg_val++ = le64_to_cpu(*desc_data++); - -			regs_num--; -			if (!regs_num) -				break; -		} -	} - -	kfree(desc); -	return 0; -} - -#define MAX_SEPARATE_NUM	4 -#define SEPARATOR_VALUE		0xFDFCFBFA -#define REG_NUM_PER_LINE	4 -#define REG_LEN_PER_LINE	(REG_NUM_PER_LINE * sizeof(u32)) -#define REG_SEPARATOR_LINE	1 -#define REG_NUM_REMAIN_MASK	3 - -int hclge_query_bd_num_cmd_send(struct hclge_dev *hdev, struct hclge_desc *desc) -{ -	int i; - -	/* initialize command BD except the last one */ -	for (i = 0; i < HCLGE_GET_DFX_REG_TYPE_CNT - 1; i++) { -		hclge_cmd_setup_basic_desc(&desc[i], HCLGE_OPC_DFX_BD_NUM, -					   true); -		desc[i].flag |= cpu_to_le16(HCLGE_COMM_CMD_FLAG_NEXT); -	} - -	/* initialize the last command BD */ -	hclge_cmd_setup_basic_desc(&desc[i], HCLGE_OPC_DFX_BD_NUM, true); - -	return hclge_cmd_send(&hdev->hw, desc, HCLGE_GET_DFX_REG_TYPE_CNT); -} - -static int hclge_get_dfx_reg_bd_num(struct hclge_dev *hdev, -				    int *bd_num_list, -				    u32 type_num) -{ -	u32 entries_per_desc, desc_index, index, offset, i; -	struct hclge_desc desc[HCLGE_GET_DFX_REG_TYPE_CNT]; -	int ret; - -	ret = hclge_query_bd_num_cmd_send(hdev, desc); -	if (ret) { -		dev_err(&hdev->pdev->dev, -			"Get dfx bd num fail, status is %d.\n", ret); -		return ret; -	} - -	entries_per_desc = ARRAY_SIZE(desc[0].data); -	for (i = 0; i < type_num; i++) { -		offset = hclge_dfx_bd_offset_list[i]; -		index = offset % entries_per_desc; -		desc_index = offset / entries_per_desc; -		bd_num_list[i] = le32_to_cpu(desc[desc_index].data[index]); -	} - -	return ret; -} - -static int hclge_dfx_reg_cmd_send(struct hclge_dev *hdev, -				  struct hclge_desc *desc_src, int bd_num, -				  enum hclge_opcode_type cmd) -{ -	struct hclge_desc *desc = desc_src; -	int i, ret; - -	hclge_cmd_setup_basic_desc(desc, cmd, true); -	for (i = 0; i < bd_num - 1; i++) { -		desc->flag |= cpu_to_le16(HCLGE_COMM_CMD_FLAG_NEXT); -		desc++; -		hclge_cmd_setup_basic_desc(desc, cmd, true); -	} - -	desc = desc_src; -	ret = hclge_cmd_send(&hdev->hw, desc, bd_num); -	if (ret) -		dev_err(&hdev->pdev->dev, -			"Query dfx reg cmd(0x%x) send fail, status is %d.\n", -			cmd, ret); - -	return ret; -} - -static int hclge_dfx_reg_fetch_data(struct hclge_desc *desc_src, int bd_num, -				    void *data) -{ -	int entries_per_desc, reg_num, separator_num, desc_index, index, i; -	struct hclge_desc *desc = desc_src; -	u32 *reg = data; - -	entries_per_desc = ARRAY_SIZE(desc->data); -	reg_num = entries_per_desc * bd_num; -	separator_num = REG_NUM_PER_LINE - (reg_num & REG_NUM_REMAIN_MASK); -	for (i = 0; i < reg_num; i++) { -		index = i % entries_per_desc; -		desc_index = i / entries_per_desc; -		*reg++ = le32_to_cpu(desc[desc_index].data[index]); -	} -	for (i = 0; i < separator_num; i++) -		*reg++ = SEPARATOR_VALUE; - -	return reg_num + separator_num; -} - -static int hclge_get_dfx_reg_len(struct hclge_dev *hdev, int *len) -{ -	u32 dfx_reg_type_num = ARRAY_SIZE(hclge_dfx_bd_offset_list); -	int data_len_per_desc, bd_num, i; -	int *bd_num_list; -	u32 data_len; -	int ret; - -	bd_num_list = kcalloc(dfx_reg_type_num, sizeof(int), GFP_KERNEL); -	if (!bd_num_list) -		return -ENOMEM; - -	ret = hclge_get_dfx_reg_bd_num(hdev, bd_num_list, dfx_reg_type_num); -	if (ret) { -		dev_err(&hdev->pdev->dev, -			"Get dfx reg bd num fail, status is %d.\n", ret); -		goto out; -	} - -	data_len_per_desc = sizeof_field(struct hclge_desc, data); -	*len = 0; -	for (i = 0; i < dfx_reg_type_num; i++) { -		bd_num = bd_num_list[i]; -		data_len = data_len_per_desc * bd_num; -		*len += (data_len / REG_LEN_PER_LINE + 1) * REG_LEN_PER_LINE; -	} - -out: -	kfree(bd_num_list); -	return ret; -} - -static int hclge_get_dfx_reg(struct hclge_dev *hdev, void *data) -{ -	u32 dfx_reg_type_num = ARRAY_SIZE(hclge_dfx_bd_offset_list); -	int bd_num, bd_num_max, buf_len, i; -	struct hclge_desc *desc_src; -	int *bd_num_list; -	u32 *reg = data; -	int ret; - -	bd_num_list = kcalloc(dfx_reg_type_num, sizeof(int), GFP_KERNEL); -	if (!bd_num_list) -		return -ENOMEM; - -	ret = hclge_get_dfx_reg_bd_num(hdev, bd_num_list, dfx_reg_type_num); -	if (ret) { -		dev_err(&hdev->pdev->dev, -			"Get dfx reg bd num fail, status is %d.\n", ret); -		goto out; -	} - -	bd_num_max = bd_num_list[0]; -	for (i = 1; i < dfx_reg_type_num; i++) -		bd_num_max = max_t(int, bd_num_max, bd_num_list[i]); - -	buf_len = sizeof(*desc_src) * bd_num_max; -	desc_src = kzalloc(buf_len, GFP_KERNEL); -	if (!desc_src) { -		ret = -ENOMEM; -		goto out; -	} - -	for (i = 0; i < dfx_reg_type_num; i++) { -		bd_num = bd_num_list[i]; -		ret = hclge_dfx_reg_cmd_send(hdev, desc_src, bd_num, -					     hclge_dfx_reg_opcode_list[i]); -		if (ret) { -			dev_err(&hdev->pdev->dev, -				"Get dfx reg fail, status is %d.\n", ret); -			break; -		} - -		reg += hclge_dfx_reg_fetch_data(desc_src, bd_num, reg); -	} - -	kfree(desc_src); -out: -	kfree(bd_num_list); -	return ret; -} - -static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data, -			      struct hnae3_knic_private_info *kinfo) -{ -#define HCLGE_RING_REG_OFFSET		0x200 -#define HCLGE_RING_INT_REG_OFFSET	0x4 - -	int i, j, reg_num, separator_num; -	int data_num_sum; -	u32 *reg = data; - -	/* fetching per-PF registers valus from PF PCIe register space */ -	reg_num = ARRAY_SIZE(cmdq_reg_addr_list); -	separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK); -	for (i = 0; i < reg_num; i++) -		*reg++ = hclge_read_dev(&hdev->hw, cmdq_reg_addr_list[i]); -	for (i = 0; i < separator_num; i++) -		*reg++ = SEPARATOR_VALUE; -	data_num_sum = reg_num + separator_num; - -	reg_num = ARRAY_SIZE(common_reg_addr_list); -	separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK); -	for (i = 0; i < reg_num; i++) -		*reg++ = hclge_read_dev(&hdev->hw, common_reg_addr_list[i]); -	for (i = 0; i < separator_num; i++) -		*reg++ = SEPARATOR_VALUE; -	data_num_sum += reg_num + separator_num; - -	reg_num = ARRAY_SIZE(ring_reg_addr_list); -	separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK); -	for (j = 0; j < kinfo->num_tqps; j++) { -		for (i = 0; i < reg_num; i++) -			*reg++ = hclge_read_dev(&hdev->hw, -						ring_reg_addr_list[i] + -						HCLGE_RING_REG_OFFSET * j); -		for (i = 0; i < separator_num; i++) -			*reg++ = SEPARATOR_VALUE; -	} -	data_num_sum += (reg_num + separator_num) * kinfo->num_tqps; - -	reg_num = ARRAY_SIZE(tqp_intr_reg_addr_list); -	separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK); -	for (j = 0; j < hdev->num_msi_used - 1; j++) { -		for (i = 0; i < reg_num; i++) -			*reg++ = hclge_read_dev(&hdev->hw, -						tqp_intr_reg_addr_list[i] + -						HCLGE_RING_INT_REG_OFFSET * j); -		for (i = 0; i < separator_num; i++) -			*reg++ = SEPARATOR_VALUE; -	} -	data_num_sum += (reg_num + separator_num) * (hdev->num_msi_used - 1); - -	return data_num_sum; -} - -static int hclge_get_regs_len(struct hnae3_handle *handle) -{ -	int cmdq_lines, common_lines, ring_lines, tqp_intr_lines; -	struct hnae3_knic_private_info *kinfo = &handle->kinfo; -	struct hclge_vport *vport = hclge_get_vport(handle); -	struct hclge_dev *hdev = vport->back; -	int regs_num_32_bit, regs_num_64_bit, dfx_regs_len; -	int regs_lines_32_bit, regs_lines_64_bit; -	int ret; - -	ret = hclge_get_regs_num(hdev, ®s_num_32_bit, ®s_num_64_bit); -	if (ret) { -		dev_err(&hdev->pdev->dev, -			"Get register number failed, ret = %d.\n", ret); -		return ret; -	} - -	ret = hclge_get_dfx_reg_len(hdev, &dfx_regs_len); -	if (ret) { -		dev_err(&hdev->pdev->dev, -			"Get dfx reg len failed, ret = %d.\n", ret); -		return ret; -	} - -	cmdq_lines = sizeof(cmdq_reg_addr_list) / REG_LEN_PER_LINE + -		REG_SEPARATOR_LINE; -	common_lines = sizeof(common_reg_addr_list) / REG_LEN_PER_LINE + -		REG_SEPARATOR_LINE; -	ring_lines = sizeof(ring_reg_addr_list) / REG_LEN_PER_LINE + -		REG_SEPARATOR_LINE; -	tqp_intr_lines = sizeof(tqp_intr_reg_addr_list) / REG_LEN_PER_LINE + -		REG_SEPARATOR_LINE; -	regs_lines_32_bit = regs_num_32_bit * sizeof(u32) / REG_LEN_PER_LINE + -		REG_SEPARATOR_LINE; -	regs_lines_64_bit = regs_num_64_bit * sizeof(u64) / REG_LEN_PER_LINE + -		REG_SEPARATOR_LINE; - -	return (cmdq_lines + common_lines + ring_lines * kinfo->num_tqps + -		tqp_intr_lines * (hdev->num_msi_used - 1) + regs_lines_32_bit + -		regs_lines_64_bit) * REG_LEN_PER_LINE + dfx_regs_len; -} - -static void hclge_get_regs(struct hnae3_handle *handle, u32 *version, -			   void *data) -{ -	struct hnae3_knic_private_info *kinfo = &handle->kinfo; -	struct hclge_vport *vport = hclge_get_vport(handle); -	struct hclge_dev *hdev = vport->back; -	u32 regs_num_32_bit, regs_num_64_bit; -	int i, reg_num, separator_num, ret; -	u32 *reg = data; - -	*version = hdev->fw_version; - -	ret = hclge_get_regs_num(hdev, ®s_num_32_bit, ®s_num_64_bit); -	if (ret) { -		dev_err(&hdev->pdev->dev, -			"Get register number failed, ret = %d.\n", ret); -		return; -	} - -	reg += hclge_fetch_pf_reg(hdev, reg, kinfo); - -	ret = hclge_get_32_bit_regs(hdev, regs_num_32_bit, reg); -	if (ret) { -		dev_err(&hdev->pdev->dev, -			"Get 32 bit register failed, ret = %d.\n", ret); -		return; -	} -	reg_num = regs_num_32_bit; -	reg += reg_num; -	separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK); -	for (i = 0; i < separator_num; i++) -		*reg++ = SEPARATOR_VALUE; - -	ret = hclge_get_64_bit_regs(hdev, regs_num_64_bit, reg); -	if (ret) { -		dev_err(&hdev->pdev->dev, -			"Get 64 bit register failed, ret = %d.\n", ret); -		return; -	} -	reg_num = regs_num_64_bit * 2; -	reg += reg_num; -	separator_num = MAX_SEPARATE_NUM - (reg_num & REG_NUM_REMAIN_MASK); -	for (i = 0; i < separator_num; i++) -		*reg++ = SEPARATOR_VALUE; - -	ret = hclge_get_dfx_reg(hdev, reg); -	if (ret) -		dev_err(&hdev->pdev->dev, -			"Get dfx register failed, ret = %d.\n", ret); -} -  static int hclge_set_led_status(struct hclge_dev *hdev, u8 locate_led_status)  {  	struct hclge_set_led_state_cmd *req; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 70b059e6d35f..ec233ec57222 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -1142,8 +1142,6 @@ int hclge_push_vf_port_base_vlan_info(struct hclge_vport *vport, u8 vfid,  				      u16 state,  				      struct hclge_vlan_info *vlan_info);  void hclge_task_schedule(struct hclge_dev *hdev, unsigned long delay_time); -int hclge_query_bd_num_cmd_send(struct hclge_dev *hdev, -				struct hclge_desc *desc);  void hclge_report_hw_error(struct hclge_dev *hdev,  			   enum hnae3_hw_error_type type);  int hclge_dbg_dump_rst_info(struct hclge_dev *hdev, char *buf, int len); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c new file mode 100644 index 000000000000..43c1c18fa81f --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c @@ -0,0 +1,668 @@ +// SPDX-License-Identifier: GPL-2.0+ +// Copyright (c) 2023 Hisilicon Limited. + +#include "hclge_cmd.h" +#include "hclge_main.h" +#include "hclge_regs.h" +#include "hnae3.h" + +static const u32 cmdq_reg_addr_list[] = {HCLGE_COMM_NIC_CSQ_BASEADDR_L_REG, +					 HCLGE_COMM_NIC_CSQ_BASEADDR_H_REG, +					 HCLGE_COMM_NIC_CSQ_DEPTH_REG, +					 HCLGE_COMM_NIC_CSQ_TAIL_REG, +					 HCLGE_COMM_NIC_CSQ_HEAD_REG, +					 HCLGE_COMM_NIC_CRQ_BASEADDR_L_REG, +					 HCLGE_COMM_NIC_CRQ_BASEADDR_H_REG, +					 HCLGE_COMM_NIC_CRQ_DEPTH_REG, +					 HCLGE_COMM_NIC_CRQ_TAIL_REG, +					 HCLGE_COMM_NIC_CRQ_HEAD_REG, +					 HCLGE_COMM_VECTOR0_CMDQ_SRC_REG, +					 HCLGE_COMM_CMDQ_INTR_STS_REG, +					 HCLGE_COMM_CMDQ_INTR_EN_REG, +					 HCLGE_COMM_CMDQ_INTR_GEN_REG}; + +static const u32 common_reg_addr_list[] = {HCLGE_MISC_VECTOR_REG_BASE, +					   HCLGE_PF_OTHER_INT_REG, +					   HCLGE_MISC_RESET_STS_REG, +					   HCLGE_MISC_VECTOR_INT_STS, +					   HCLGE_GLOBAL_RESET_REG, +					   HCLGE_FUN_RST_ING, +					   HCLGE_GRO_EN_REG}; + +static const u32 ring_reg_addr_list[] = {HCLGE_RING_RX_ADDR_L_REG, +					 HCLGE_RING_RX_ADDR_H_REG, +					 HCLGE_RING_RX_BD_NUM_REG, +					 HCLGE_RING_RX_BD_LENGTH_REG, +					 HCLGE_RING_RX_MERGE_EN_REG, +					 HCLGE_RING_RX_TAIL_REG, +					 HCLGE_RING_RX_HEAD_REG, +					 HCLGE_RING_RX_FBD_NUM_REG, +					 HCLGE_RING_RX_OFFSET_REG, +					 HCLGE_RING_RX_FBD_OFFSET_REG, +					 HCLGE_RING_RX_STASH_REG, +					 HCLGE_RING_RX_BD_ERR_REG, +					 HCLGE_RING_TX_ADDR_L_REG, +					 HCLGE_RING_TX_ADDR_H_REG, +					 HCLGE_RING_TX_BD_NUM_REG, +					 HCLGE_RING_TX_PRIORITY_REG, +					 HCLGE_RING_TX_TC_REG, +					 HCLGE_RING_TX_MERGE_EN_REG, +					 HCLGE_RING_TX_TAIL_REG, +					 HCLGE_RING_TX_HEAD_REG, +					 HCLGE_RING_TX_FBD_NUM_REG, +					 HCLGE_RING_TX_OFFSET_REG, +					 HCLGE_RING_TX_EBD_NUM_REG, +					 HCLGE_RING_TX_EBD_OFFSET_REG, +					 HCLGE_RING_TX_BD_ERR_REG, +					 HCLGE_RING_EN_REG}; + +static const u32 tqp_intr_reg_addr_list[] = {HCLGE_TQP_INTR_CTRL_REG, +					     HCLGE_TQP_INTR_GL0_REG, +					     HCLGE_TQP_INTR_GL1_REG, +					     HCLGE_TQP_INTR_GL2_REG, +					     HCLGE_TQP_INTR_RL_REG}; + +/* Get DFX BD number offset */ +#define HCLGE_DFX_BIOS_BD_OFFSET        1 +#define HCLGE_DFX_SSU_0_BD_OFFSET       2 +#define HCLGE_DFX_SSU_1_BD_OFFSET       3 +#define HCLGE_DFX_IGU_BD_OFFSET         4 +#define HCLGE_DFX_RPU_0_BD_OFFSET       5 +#define HCLGE_DFX_RPU_1_BD_OFFSET       6 +#define HCLGE_DFX_NCSI_BD_OFFSET        7 +#define HCLGE_DFX_RTC_BD_OFFSET         8 +#define HCLGE_DFX_PPP_BD_OFFSET         9 +#define HCLGE_DFX_RCB_BD_OFFSET         10 +#define HCLGE_DFX_TQP_BD_OFFSET         11 +#define HCLGE_DFX_SSU_2_BD_OFFSET       12 + +static const u32 hclge_dfx_bd_offset_list[] = { +	HCLGE_DFX_BIOS_BD_OFFSET, +	HCLGE_DFX_SSU_0_BD_OFFSET, +	HCLGE_DFX_SSU_1_BD_OFFSET, +	HCLGE_DFX_IGU_BD_OFFSET, +	HCLGE_DFX_RPU_0_BD_OFFSET, +	HCLGE_DFX_RPU_1_BD_OFFSET, +	HCLGE_DFX_NCSI_BD_OFFSET, +	HCLGE_DFX_RTC_BD_OFFSET, +	HCLGE_DFX_PPP_BD_OFFSET, +	HCLGE_DFX_RCB_BD_OFFSET, +	HCLGE_DFX_TQP_BD_OFFSET, +	HCLGE_DFX_SSU_2_BD_OFFSET +}; + +static const enum hclge_opcode_type hclge_dfx_reg_opcode_list[] = { +	HCLGE_OPC_DFX_BIOS_COMMON_REG, +	HCLGE_OPC_DFX_SSU_REG_0, +	HCLGE_OPC_DFX_SSU_REG_1, +	HCLGE_OPC_DFX_IGU_EGU_REG, +	HCLGE_OPC_DFX_RPU_REG_0, +	HCLGE_OPC_DFX_RPU_REG_1, +	HCLGE_OPC_DFX_NCSI_REG, +	HCLGE_OPC_DFX_RTC_REG, +	HCLGE_OPC_DFX_PPP_REG, +	HCLGE_OPC_DFX_RCB_REG, +	HCLGE_OPC_DFX_TQP_REG, +	HCLGE_OPC_DFX_SSU_REG_2 +}; + +enum hclge_reg_tag { +	HCLGE_REG_TAG_CMDQ = 0, +	HCLGE_REG_TAG_COMMON, +	HCLGE_REG_TAG_RING, +	HCLGE_REG_TAG_TQP_INTR, +	HCLGE_REG_TAG_QUERY_32_BIT, +	HCLGE_REG_TAG_QUERY_64_BIT, +	HCLGE_REG_TAG_DFX_BIOS_COMMON, +	HCLGE_REG_TAG_DFX_SSU_0, +	HCLGE_REG_TAG_DFX_SSU_1, +	HCLGE_REG_TAG_DFX_IGU_EGU, +	HCLGE_REG_TAG_DFX_RPU_0, +	HCLGE_REG_TAG_DFX_RPU_1, +	HCLGE_REG_TAG_DFX_NCSI, +	HCLGE_REG_TAG_DFX_RTC, +	HCLGE_REG_TAG_DFX_PPP, +	HCLGE_REG_TAG_DFX_RCB, +	HCLGE_REG_TAG_DFX_TQP, +	HCLGE_REG_TAG_DFX_SSU_2, +	HCLGE_REG_TAG_RPU_TNL, +}; + +#pragma pack(4) +struct hclge_reg_tlv { +	u16 tag; +	u16 len; +}; + +struct hclge_reg_header { +	u64 magic_number; +	u8 is_vf; +	u8 rsv[7]; +}; + +#pragma pack() + +#define HCLGE_REG_TLV_SIZE	sizeof(struct hclge_reg_tlv) +#define HCLGE_REG_HEADER_SIZE	sizeof(struct hclge_reg_header) +#define HCLGE_REG_TLV_SPACE	(sizeof(struct hclge_reg_tlv) / sizeof(u32)) +#define HCLGE_REG_HEADER_SPACE	(sizeof(struct hclge_reg_header) / sizeof(u32)) +#define HCLGE_REG_MAGIC_NUMBER	0x686e733372656773 /* meaning is hns3regs */ + +#define HCLGE_REG_RPU_TNL_ID_0	1 + +static u32 hclge_reg_get_header(void *data) +{ +	struct hclge_reg_header *header = data; + +	header->magic_number = HCLGE_REG_MAGIC_NUMBER; +	header->is_vf = 0x0; + +	return HCLGE_REG_HEADER_SPACE; +} + +static u32 hclge_reg_get_tlv(u32 tag, u32 regs_num, void *data) +{ +	struct hclge_reg_tlv *tlv = data; + +	tlv->tag = tag; +	tlv->len = regs_num * sizeof(u32) + HCLGE_REG_TLV_SIZE; + +	return HCLGE_REG_TLV_SPACE; +} + +static int hclge_get_32_bit_regs(struct hclge_dev *hdev, u32 regs_num, +				 void *data) +{ +#define HCLGE_32_BIT_REG_RTN_DATANUM 8 +#define HCLGE_32_BIT_DESC_NODATA_LEN 2 + +	struct hclge_desc *desc; +	u32 *reg_val = data; +	__le32 *desc_data; +	int nodata_num; +	int cmd_num; +	int i, k, n; +	int ret; + +	if (regs_num == 0) +		return 0; + +	nodata_num = HCLGE_32_BIT_DESC_NODATA_LEN; +	cmd_num = DIV_ROUND_UP(regs_num + nodata_num, +			       HCLGE_32_BIT_REG_RTN_DATANUM); +	desc = kcalloc(cmd_num, sizeof(struct hclge_desc), GFP_KERNEL); +	if (!desc) +		return -ENOMEM; + +	hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_QUERY_32_BIT_REG, true); +	ret = hclge_cmd_send(&hdev->hw, desc, cmd_num); +	if (ret) { +		dev_err(&hdev->pdev->dev, +			"Query 32 bit register cmd failed, ret = %d.\n", ret); +		kfree(desc); +		return ret; +	} + +	for (i = 0; i < cmd_num; i++) { +		if (i == 0) { +			desc_data = (__le32 *)(&desc[i].data[0]); +			n = HCLGE_32_BIT_REG_RTN_DATANUM - nodata_num; +		} else { +			desc_data = (__le32 *)(&desc[i]); +			n = HCLGE_32_BIT_REG_RTN_DATANUM; +		} +		for (k = 0; k < n; k++) { +			*reg_val++ = le32_to_cpu(*desc_data++); + +			regs_num--; +			if (!regs_num) +				break; +		} +	} + +	kfree(desc); +	return 0; +} + +static int hclge_get_64_bit_regs(struct hclge_dev *hdev, u32 regs_num, +				 void *data) +{ +#define HCLGE_64_BIT_REG_RTN_DATANUM 4 +#define HCLGE_64_BIT_DESC_NODATA_LEN 1 + +	struct hclge_desc *desc; +	u64 *reg_val = data; +	__le64 *desc_data; +	int nodata_len; +	int cmd_num; +	int i, k, n; +	int ret; + +	if (regs_num == 0) +		return 0; + +	nodata_len = HCLGE_64_BIT_DESC_NODATA_LEN; +	cmd_num = DIV_ROUND_UP(regs_num + nodata_len, +			       HCLGE_64_BIT_REG_RTN_DATANUM); +	desc = kcalloc(cmd_num, sizeof(struct hclge_desc), GFP_KERNEL); +	if (!desc) +		return -ENOMEM; + +	hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_QUERY_64_BIT_REG, true); +	ret = hclge_cmd_send(&hdev->hw, desc, cmd_num); +	if (ret) { +		dev_err(&hdev->pdev->dev, +			"Query 64 bit register cmd failed, ret = %d.\n", ret); +		kfree(desc); +		return ret; +	} + +	for (i = 0; i < cmd_num; i++) { +		if (i == 0) { +			desc_data = (__le64 *)(&desc[i].data[0]); +			n = HCLGE_64_BIT_REG_RTN_DATANUM - nodata_len; +		} else { +			desc_data = (__le64 *)(&desc[i]); +			n = HCLGE_64_BIT_REG_RTN_DATANUM; +		} +		for (k = 0; k < n; k++) { +			*reg_val++ = le64_to_cpu(*desc_data++); + +			regs_num--; +			if (!regs_num) +				break; +		} +	} + +	kfree(desc); +	return 0; +} + +int hclge_query_bd_num_cmd_send(struct hclge_dev *hdev, struct hclge_desc *desc) +{ +	int i; + +	/* initialize command BD except the last one */ +	for (i = 0; i < HCLGE_GET_DFX_REG_TYPE_CNT - 1; i++) { +		hclge_cmd_setup_basic_desc(&desc[i], HCLGE_OPC_DFX_BD_NUM, +					   true); +		desc[i].flag |= cpu_to_le16(HCLGE_COMM_CMD_FLAG_NEXT); +	} + +	/* initialize the last command BD */ +	hclge_cmd_setup_basic_desc(&desc[i], HCLGE_OPC_DFX_BD_NUM, true); + +	return hclge_cmd_send(&hdev->hw, desc, HCLGE_GET_DFX_REG_TYPE_CNT); +} + +static int hclge_get_dfx_reg_bd_num(struct hclge_dev *hdev, +				    int *bd_num_list, +				    u32 type_num) +{ +	u32 entries_per_desc, desc_index, index, offset, i; +	struct hclge_desc desc[HCLGE_GET_DFX_REG_TYPE_CNT]; +	int ret; + +	ret = hclge_query_bd_num_cmd_send(hdev, desc); +	if (ret) { +		dev_err(&hdev->pdev->dev, +			"Get dfx bd num fail, status is %d.\n", ret); +		return ret; +	} + +	entries_per_desc = ARRAY_SIZE(desc[0].data); +	for (i = 0; i < type_num; i++) { +		offset = hclge_dfx_bd_offset_list[i]; +		index = offset % entries_per_desc; +		desc_index = offset / entries_per_desc; +		bd_num_list[i] = le32_to_cpu(desc[desc_index].data[index]); +	} + +	return ret; +} + +static int hclge_dfx_reg_cmd_send(struct hclge_dev *hdev, +				  struct hclge_desc *desc_src, int bd_num, +				  enum hclge_opcode_type cmd) +{ +	struct hclge_desc *desc = desc_src; +	int i, ret; + +	hclge_cmd_setup_basic_desc(desc, cmd, true); +	for (i = 0; i < bd_num - 1; i++) { +		desc->flag |= cpu_to_le16(HCLGE_COMM_CMD_FLAG_NEXT); +		desc++; +		hclge_cmd_setup_basic_desc(desc, cmd, true); +	} + +	desc = desc_src; +	ret = hclge_cmd_send(&hdev->hw, desc, bd_num); +	if (ret) +		dev_err(&hdev->pdev->dev, +			"Query dfx reg cmd(0x%x) send fail, status is %d.\n", +			cmd, ret); + +	return ret; +} + +/* tnl_id = 0 means get sum of all tnl reg's value */ +static int hclge_dfx_reg_rpu_tnl_cmd_send(struct hclge_dev *hdev, u32 tnl_id, +					  struct hclge_desc *desc, int bd_num) +{ +	int i, ret; + +	for (i = 0; i < bd_num; i++) { +		hclge_cmd_setup_basic_desc(&desc[i], HCLGE_OPC_DFX_RPU_REG_0, +					   true); +		if (i != bd_num - 1) +			desc[i].flag |= cpu_to_le16(HCLGE_COMM_CMD_FLAG_NEXT); +	} + +	desc[0].data[0] = cpu_to_le32(tnl_id); +	ret = hclge_cmd_send(&hdev->hw, desc, bd_num); +	if (ret) +		dev_err(&hdev->pdev->dev, +			"failed to query dfx rpu tnl reg, ret = %d\n", +			ret); +	return ret; +} + +static int hclge_dfx_reg_fetch_data(struct hclge_desc *desc_src, int bd_num, +				    void *data) +{ +	int entries_per_desc, reg_num, desc_index, index, i; +	struct hclge_desc *desc = desc_src; +	u32 *reg = data; + +	entries_per_desc = ARRAY_SIZE(desc->data); +	reg_num = entries_per_desc * bd_num; +	for (i = 0; i < reg_num; i++) { +		index = i % entries_per_desc; +		desc_index = i / entries_per_desc; +		*reg++ = le32_to_cpu(desc[desc_index].data[index]); +	} + +	return reg_num; +} + +static int hclge_get_dfx_reg_len(struct hclge_dev *hdev, int *len) +{ +	u32 dfx_reg_type_num = ARRAY_SIZE(hclge_dfx_bd_offset_list); +	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); +	int data_len_per_desc; +	int *bd_num_list; +	int ret; +	u32 i; + +	bd_num_list = kcalloc(dfx_reg_type_num, sizeof(int), GFP_KERNEL); +	if (!bd_num_list) +		return -ENOMEM; + +	ret = hclge_get_dfx_reg_bd_num(hdev, bd_num_list, dfx_reg_type_num); +	if (ret) { +		dev_err(&hdev->pdev->dev, +			"Get dfx reg bd num fail, status is %d.\n", ret); +		goto out; +	} + +	data_len_per_desc = sizeof_field(struct hclge_desc, data); +	*len = 0; +	for (i = 0; i < dfx_reg_type_num; i++) +		*len += bd_num_list[i] * data_len_per_desc + HCLGE_REG_TLV_SIZE; + +	/** +	 * the num of dfx_rpu_0 is reused by each dfx_rpu_tnl +	 * HCLGE_DFX_BD_OFFSET is starting at 1, but the array subscript is +	 * starting at 0, so offset need '- 1'. +	 */ +	*len += (bd_num_list[HCLGE_DFX_RPU_0_BD_OFFSET - 1] * data_len_per_desc + +		 HCLGE_REG_TLV_SIZE) * ae_dev->dev_specs.tnl_num; + +out: +	kfree(bd_num_list); +	return ret; +} + +static int hclge_get_dfx_rpu_tnl_reg(struct hclge_dev *hdev, u32 *reg, +				     struct hclge_desc *desc_src, +				     int bd_num) +{ +	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); +	int ret = 0; +	u8 i; + +	for (i = HCLGE_REG_RPU_TNL_ID_0; i <= ae_dev->dev_specs.tnl_num; i++) { +		ret = hclge_dfx_reg_rpu_tnl_cmd_send(hdev, i, desc_src, bd_num); +		if (ret) +			break; + +		reg += hclge_reg_get_tlv(HCLGE_REG_TAG_RPU_TNL, +					 ARRAY_SIZE(desc_src->data) * bd_num, +					 reg); +		reg += hclge_dfx_reg_fetch_data(desc_src, bd_num, reg); +	} + +	return ret; +} + +static int hclge_get_dfx_reg(struct hclge_dev *hdev, void *data) +{ +	u32 dfx_reg_type_num = ARRAY_SIZE(hclge_dfx_bd_offset_list); +	int bd_num, bd_num_max, buf_len; +	struct hclge_desc *desc_src; +	int *bd_num_list; +	u32 *reg = data; +	int ret; +	u32 i; + +	bd_num_list = kcalloc(dfx_reg_type_num, sizeof(int), GFP_KERNEL); +	if (!bd_num_list) +		return -ENOMEM; + +	ret = hclge_get_dfx_reg_bd_num(hdev, bd_num_list, dfx_reg_type_num); +	if (ret) { +		dev_err(&hdev->pdev->dev, +			"Get dfx reg bd num fail, status is %d.\n", ret); +		goto out; +	} + +	bd_num_max = bd_num_list[0]; +	for (i = 1; i < dfx_reg_type_num; i++) +		bd_num_max = max_t(int, bd_num_max, bd_num_list[i]); + +	buf_len = sizeof(*desc_src) * bd_num_max; +	desc_src = kzalloc(buf_len, GFP_KERNEL); +	if (!desc_src) { +		ret = -ENOMEM; +		goto out; +	} + +	for (i = 0; i < dfx_reg_type_num; i++) { +		bd_num = bd_num_list[i]; +		ret = hclge_dfx_reg_cmd_send(hdev, desc_src, bd_num, +					     hclge_dfx_reg_opcode_list[i]); +		if (ret) { +			dev_err(&hdev->pdev->dev, +				"Get dfx reg fail, status is %d.\n", ret); +			goto free; +		} + +		reg += hclge_reg_get_tlv(HCLGE_REG_TAG_DFX_BIOS_COMMON + i, +					 ARRAY_SIZE(desc_src->data) * bd_num, +					 reg); +		reg += hclge_dfx_reg_fetch_data(desc_src, bd_num, reg); +	} + +	/** +	 * HCLGE_DFX_BD_OFFSET is starting at 1, but the array subscript is +	 * starting at 0, so offset need '- 1'. +	 */ +	bd_num = bd_num_list[HCLGE_DFX_RPU_0_BD_OFFSET - 1]; +	ret = hclge_get_dfx_rpu_tnl_reg(hdev, reg, desc_src, bd_num); + +free: +	kfree(desc_src); +out: +	kfree(bd_num_list); +	return ret; +} + +static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data, +			      struct hnae3_knic_private_info *kinfo) +{ +#define HCLGE_RING_REG_OFFSET		0x200 +#define HCLGE_RING_INT_REG_OFFSET	0x4 + +	int i, j, reg_num; +	int data_num_sum; +	u32 *reg = data; + +	/* fetching per-PF registers valus from PF PCIe register space */ +	reg_num = ARRAY_SIZE(cmdq_reg_addr_list); +	reg += hclge_reg_get_tlv(HCLGE_REG_TAG_CMDQ, reg_num, reg); +	for (i = 0; i < reg_num; i++) +		*reg++ = hclge_read_dev(&hdev->hw, cmdq_reg_addr_list[i]); +	data_num_sum = reg_num + HCLGE_REG_TLV_SPACE; + +	reg_num = ARRAY_SIZE(common_reg_addr_list); +	reg += hclge_reg_get_tlv(HCLGE_REG_TAG_COMMON, reg_num, reg); +	for (i = 0; i < reg_num; i++) +		*reg++ = hclge_read_dev(&hdev->hw, common_reg_addr_list[i]); +	data_num_sum += reg_num + HCLGE_REG_TLV_SPACE; + +	reg_num = ARRAY_SIZE(ring_reg_addr_list); +	for (j = 0; j < kinfo->num_tqps; j++) { +		reg += hclge_reg_get_tlv(HCLGE_REG_TAG_RING, reg_num, reg); +		for (i = 0; i < reg_num; i++) +			*reg++ = hclge_read_dev(&hdev->hw, +						ring_reg_addr_list[i] + +						HCLGE_RING_REG_OFFSET * j); +	} +	data_num_sum += (reg_num + HCLGE_REG_TLV_SPACE) * kinfo->num_tqps; + +	reg_num = ARRAY_SIZE(tqp_intr_reg_addr_list); +	for (j = 0; j < hdev->num_msi_used - 1; j++) { +		reg += hclge_reg_get_tlv(HCLGE_REG_TAG_TQP_INTR, reg_num, reg); +		for (i = 0; i < reg_num; i++) +			*reg++ = hclge_read_dev(&hdev->hw, +						tqp_intr_reg_addr_list[i] + +						HCLGE_RING_INT_REG_OFFSET * j); +	} +	data_num_sum += (reg_num + HCLGE_REG_TLV_SPACE) * +			(hdev->num_msi_used - 1); + +	return data_num_sum; +} + +static int hclge_get_regs_num(struct hclge_dev *hdev, u32 *regs_num_32_bit, +			      u32 *regs_num_64_bit) +{ +	struct hclge_desc desc; +	u32 total_num; +	int ret; + +	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QUERY_REG_NUM, true); +	ret = hclge_cmd_send(&hdev->hw, &desc, 1); +	if (ret) { +		dev_err(&hdev->pdev->dev, +			"Query register number cmd failed, ret = %d.\n", ret); +		return ret; +	} + +	*regs_num_32_bit = le32_to_cpu(desc.data[0]); +	*regs_num_64_bit = le32_to_cpu(desc.data[1]); + +	total_num = *regs_num_32_bit + *regs_num_64_bit; +	if (!total_num) +		return -EINVAL; + +	return 0; +} + +int hclge_get_regs_len(struct hnae3_handle *handle) +{ +	struct hnae3_knic_private_info *kinfo = &handle->kinfo; +	struct hclge_vport *vport = hclge_get_vport(handle); +	int regs_num_32_bit, regs_num_64_bit, dfx_regs_len; +	int cmdq_len, common_len, ring_len, tqp_intr_len; +	int regs_len_32_bit, regs_len_64_bit; +	struct hclge_dev *hdev = vport->back; +	int ret; + +	ret = hclge_get_regs_num(hdev, ®s_num_32_bit, ®s_num_64_bit); +	if (ret) { +		dev_err(&hdev->pdev->dev, +			"Get register number failed, ret = %d.\n", ret); +		return ret; +	} + +	ret = hclge_get_dfx_reg_len(hdev, &dfx_regs_len); +	if (ret) { +		dev_err(&hdev->pdev->dev, +			"Get dfx reg len failed, ret = %d.\n", ret); +		return ret; +	} + +	cmdq_len = HCLGE_REG_TLV_SIZE + sizeof(cmdq_reg_addr_list); +	common_len = HCLGE_REG_TLV_SIZE + sizeof(common_reg_addr_list); +	ring_len = HCLGE_REG_TLV_SIZE + sizeof(ring_reg_addr_list); +	tqp_intr_len = HCLGE_REG_TLV_SIZE + sizeof(tqp_intr_reg_addr_list); +	regs_len_32_bit = HCLGE_REG_TLV_SIZE + regs_num_32_bit * sizeof(u32); +	regs_len_64_bit = HCLGE_REG_TLV_SIZE + regs_num_64_bit * sizeof(u64); + +	/* return the total length of all register values */ +	return HCLGE_REG_HEADER_SIZE + cmdq_len + common_len + ring_len * +		kinfo->num_tqps + tqp_intr_len * (hdev->num_msi_used - 1) + +		regs_len_32_bit + regs_len_64_bit + dfx_regs_len; +} + +void hclge_get_regs(struct hnae3_handle *handle, u32 *version, +		    void *data) +{ +#define HCLGE_REG_64_BIT_SPACE_MULTIPLE		2 + +	struct hnae3_knic_private_info *kinfo = &handle->kinfo; +	struct hclge_vport *vport = hclge_get_vport(handle); +	struct hclge_dev *hdev = vport->back; +	u32 regs_num_32_bit, regs_num_64_bit; +	u32 *reg = data; +	int ret; + +	*version = hdev->fw_version; + +	ret = hclge_get_regs_num(hdev, ®s_num_32_bit, ®s_num_64_bit); +	if (ret) { +		dev_err(&hdev->pdev->dev, +			"Get register number failed, ret = %d.\n", ret); +		return; +	} + +	reg += hclge_reg_get_header(reg); +	reg += hclge_fetch_pf_reg(hdev, reg, kinfo); + +	reg += hclge_reg_get_tlv(HCLGE_REG_TAG_QUERY_32_BIT, +				 regs_num_32_bit, reg); +	ret = hclge_get_32_bit_regs(hdev, regs_num_32_bit, reg); +	if (ret) { +		dev_err(&hdev->pdev->dev, +			"Get 32 bit register failed, ret = %d.\n", ret); +		return; +	} +	reg += regs_num_32_bit; + +	reg += hclge_reg_get_tlv(HCLGE_REG_TAG_QUERY_64_BIT, +				 regs_num_64_bit * +				 HCLGE_REG_64_BIT_SPACE_MULTIPLE, reg); +	ret = hclge_get_64_bit_regs(hdev, regs_num_64_bit, reg); +	if (ret) { +		dev_err(&hdev->pdev->dev, +			"Get 64 bit register failed, ret = %d.\n", ret); +		return; +	} +	reg += regs_num_64_bit * HCLGE_REG_64_BIT_SPACE_MULTIPLE; + +	ret = hclge_get_dfx_reg(hdev, reg); +	if (ret) +		dev_err(&hdev->pdev->dev, +			"Get dfx register failed, ret = %d.\n", ret); +} diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.h new file mode 100644 index 000000000000..b6bc1ecb8054 --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +// Copyright (c) 2023 Hisilicon Limited. + +#ifndef __HCLGE_REGS_H +#define __HCLGE_REGS_H +#include <linux/types.h> +#include "hclge_comm_cmd.h" + +struct hnae3_handle; +struct hclge_dev; + +int hclge_query_bd_num_cmd_send(struct hclge_dev *hdev, +				struct hclge_desc *desc); +int hclge_get_regs_len(struct hnae3_handle *handle); +void hclge_get_regs(struct hnae3_handle *handle, u32 *version, +		    void *data); +#endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index 34f02ca8d1d2..7a2f9233d695 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -6,6 +6,7 @@  #include <net/rtnetlink.h>  #include "hclgevf_cmd.h"  #include "hclgevf_main.h" +#include "hclgevf_regs.h"  #include "hclge_mbx.h"  #include "hnae3.h"  #include "hclgevf_devlink.h" @@ -33,58 +34,6 @@ static const struct pci_device_id ae_algovf_pci_tbl[] = {  MODULE_DEVICE_TABLE(pci, ae_algovf_pci_tbl); -static const u32 cmdq_reg_addr_list[] = {HCLGE_COMM_NIC_CSQ_BASEADDR_L_REG, -					 HCLGE_COMM_NIC_CSQ_BASEADDR_H_REG, -					 HCLGE_COMM_NIC_CSQ_DEPTH_REG, -					 HCLGE_COMM_NIC_CSQ_TAIL_REG, -					 HCLGE_COMM_NIC_CSQ_HEAD_REG, -					 HCLGE_COMM_NIC_CRQ_BASEADDR_L_REG, -					 HCLGE_COMM_NIC_CRQ_BASEADDR_H_REG, -					 HCLGE_COMM_NIC_CRQ_DEPTH_REG, -					 HCLGE_COMM_NIC_CRQ_TAIL_REG, -					 HCLGE_COMM_NIC_CRQ_HEAD_REG, -					 HCLGE_COMM_VECTOR0_CMDQ_SRC_REG, -					 HCLGE_COMM_VECTOR0_CMDQ_STATE_REG, -					 HCLGE_COMM_CMDQ_INTR_EN_REG, -					 HCLGE_COMM_CMDQ_INTR_GEN_REG}; - -static const u32 common_reg_addr_list[] = {HCLGEVF_MISC_VECTOR_REG_BASE, -					   HCLGEVF_RST_ING, -					   HCLGEVF_GRO_EN_REG}; - -static const u32 ring_reg_addr_list[] = {HCLGEVF_RING_RX_ADDR_L_REG, -					 HCLGEVF_RING_RX_ADDR_H_REG, -					 HCLGEVF_RING_RX_BD_NUM_REG, -					 HCLGEVF_RING_RX_BD_LENGTH_REG, -					 HCLGEVF_RING_RX_MERGE_EN_REG, -					 HCLGEVF_RING_RX_TAIL_REG, -					 HCLGEVF_RING_RX_HEAD_REG, -					 HCLGEVF_RING_RX_FBD_NUM_REG, -					 HCLGEVF_RING_RX_OFFSET_REG, -					 HCLGEVF_RING_RX_FBD_OFFSET_REG, -					 HCLGEVF_RING_RX_STASH_REG, -					 HCLGEVF_RING_RX_BD_ERR_REG, -					 HCLGEVF_RING_TX_ADDR_L_REG, -					 HCLGEVF_RING_TX_ADDR_H_REG, -					 HCLGEVF_RING_TX_BD_NUM_REG, -					 HCLGEVF_RING_TX_PRIORITY_REG, -					 HCLGEVF_RING_TX_TC_REG, -					 HCLGEVF_RING_TX_MERGE_EN_REG, -					 HCLGEVF_RING_TX_TAIL_REG, -					 HCLGEVF_RING_TX_HEAD_REG, -					 HCLGEVF_RING_TX_FBD_NUM_REG, -					 HCLGEVF_RING_TX_OFFSET_REG, -					 HCLGEVF_RING_TX_EBD_NUM_REG, -					 HCLGEVF_RING_TX_EBD_OFFSET_REG, -					 HCLGEVF_RING_TX_BD_ERR_REG, -					 HCLGEVF_RING_EN_REG}; - -static const u32 tqp_intr_reg_addr_list[] = {HCLGEVF_TQP_INTR_CTRL_REG, -					     HCLGEVF_TQP_INTR_GL0_REG, -					     HCLGEVF_TQP_INTR_GL1_REG, -					     HCLGEVF_TQP_INTR_GL2_REG, -					     HCLGEVF_TQP_INTR_RL_REG}; -  /* hclgevf_cmd_send - send command to command queue   * @hw: pointer to the hw struct   * @desc: prefilled descriptor for describing the command @@ -111,7 +60,7 @@ void hclgevf_arq_init(struct hclgevf_dev *hdev)  	spin_unlock(&cmdq->crq.lock);  } -static struct hclgevf_dev *hclgevf_ae_get_hdev(struct hnae3_handle *handle) +struct hclgevf_dev *hclgevf_ae_get_hdev(struct hnae3_handle *handle)  {  	if (!handle->client)  		return container_of(handle, struct hclgevf_dev, nic); @@ -3258,72 +3207,6 @@ static void hclgevf_get_link_mode(struct hnae3_handle *handle,  	*advertising = hdev->hw.mac.advertising;  } -#define MAX_SEPARATE_NUM	4 -#define SEPARATOR_VALUE		0xFDFCFBFA -#define REG_NUM_PER_LINE	4 -#define REG_LEN_PER_LINE	(REG_NUM_PER_LINE * sizeof(u32)) - -static int hclgevf_get_regs_len(struct hnae3_handle *handle) -{ -	int cmdq_lines, common_lines, ring_lines, tqp_intr_lines; -	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); - -	cmdq_lines = sizeof(cmdq_reg_addr_list) / REG_LEN_PER_LINE + 1; -	common_lines = sizeof(common_reg_addr_list) / REG_LEN_PER_LINE + 1; -	ring_lines = sizeof(ring_reg_addr_list) / REG_LEN_PER_LINE + 1; -	tqp_intr_lines = sizeof(tqp_intr_reg_addr_list) / REG_LEN_PER_LINE + 1; - -	return (cmdq_lines + common_lines + ring_lines * hdev->num_tqps + -		tqp_intr_lines * (hdev->num_msi_used - 1)) * REG_LEN_PER_LINE; -} - -static void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, -			     void *data) -{ -	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); -	int i, j, reg_um, separator_num; -	u32 *reg = data; - -	*version = hdev->fw_version; - -	/* fetching per-VF registers values from VF PCIe register space */ -	reg_um = sizeof(cmdq_reg_addr_list) / sizeof(u32); -	separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE; -	for (i = 0; i < reg_um; i++) -		*reg++ = hclgevf_read_dev(&hdev->hw, cmdq_reg_addr_list[i]); -	for (i = 0; i < separator_num; i++) -		*reg++ = SEPARATOR_VALUE; - -	reg_um = sizeof(common_reg_addr_list) / sizeof(u32); -	separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE; -	for (i = 0; i < reg_um; i++) -		*reg++ = hclgevf_read_dev(&hdev->hw, common_reg_addr_list[i]); -	for (i = 0; i < separator_num; i++) -		*reg++ = SEPARATOR_VALUE; - -	reg_um = sizeof(ring_reg_addr_list) / sizeof(u32); -	separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE; -	for (j = 0; j < hdev->num_tqps; j++) { -		for (i = 0; i < reg_um; i++) -			*reg++ = hclgevf_read_dev(&hdev->hw, -						  ring_reg_addr_list[i] + -						  HCLGEVF_TQP_REG_SIZE * j); -		for (i = 0; i < separator_num; i++) -			*reg++ = SEPARATOR_VALUE; -	} - -	reg_um = sizeof(tqp_intr_reg_addr_list) / sizeof(u32); -	separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE; -	for (j = 0; j < hdev->num_msi_used - 1; j++) { -		for (i = 0; i < reg_um; i++) -			*reg++ = hclgevf_read_dev(&hdev->hw, -						  tqp_intr_reg_addr_list[i] + -						  4 * j); -		for (i = 0; i < separator_num; i++) -			*reg++ = SEPARATOR_VALUE; -	} -} -  void hclgevf_update_port_base_vlan_info(struct hclgevf_dev *hdev, u16 state,  				struct hclge_mbx_port_base_vlan *port_base_vlan)  { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h index 59ca6c794d6d..81c16b8c8da2 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h @@ -294,4 +294,5 @@ void hclgevf_reset_task_schedule(struct hclgevf_dev *hdev);  void hclgevf_mbx_task_schedule(struct hclgevf_dev *hdev);  void hclgevf_update_port_base_vlan_info(struct hclgevf_dev *hdev, u16 state,  			struct hclge_mbx_port_base_vlan *port_base_vlan); +struct hclgevf_dev *hclgevf_ae_get_hdev(struct hnae3_handle *handle);  #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c new file mode 100644 index 000000000000..65b9dcd38137 --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0+ +// Copyright (c) 2023 Hisilicon Limited. + +#include "hclgevf_main.h" +#include "hclgevf_regs.h" +#include "hnae3.h" + +static const u32 cmdq_reg_addr_list[] = {HCLGE_COMM_NIC_CSQ_BASEADDR_L_REG, +					 HCLGE_COMM_NIC_CSQ_BASEADDR_H_REG, +					 HCLGE_COMM_NIC_CSQ_DEPTH_REG, +					 HCLGE_COMM_NIC_CSQ_TAIL_REG, +					 HCLGE_COMM_NIC_CSQ_HEAD_REG, +					 HCLGE_COMM_NIC_CRQ_BASEADDR_L_REG, +					 HCLGE_COMM_NIC_CRQ_BASEADDR_H_REG, +					 HCLGE_COMM_NIC_CRQ_DEPTH_REG, +					 HCLGE_COMM_NIC_CRQ_TAIL_REG, +					 HCLGE_COMM_NIC_CRQ_HEAD_REG, +					 HCLGE_COMM_VECTOR0_CMDQ_SRC_REG, +					 HCLGE_COMM_VECTOR0_CMDQ_STATE_REG, +					 HCLGE_COMM_CMDQ_INTR_EN_REG, +					 HCLGE_COMM_CMDQ_INTR_GEN_REG}; + +static const u32 common_reg_addr_list[] = {HCLGEVF_MISC_VECTOR_REG_BASE, +					   HCLGEVF_RST_ING, +					   HCLGEVF_GRO_EN_REG}; + +static const u32 ring_reg_addr_list[] = {HCLGEVF_RING_RX_ADDR_L_REG, +					 HCLGEVF_RING_RX_ADDR_H_REG, +					 HCLGEVF_RING_RX_BD_NUM_REG, +					 HCLGEVF_RING_RX_BD_LENGTH_REG, +					 HCLGEVF_RING_RX_MERGE_EN_REG, +					 HCLGEVF_RING_RX_TAIL_REG, +					 HCLGEVF_RING_RX_HEAD_REG, +					 HCLGEVF_RING_RX_FBD_NUM_REG, +					 HCLGEVF_RING_RX_OFFSET_REG, +					 HCLGEVF_RING_RX_FBD_OFFSET_REG, +					 HCLGEVF_RING_RX_STASH_REG, +					 HCLGEVF_RING_RX_BD_ERR_REG, +					 HCLGEVF_RING_TX_ADDR_L_REG, +					 HCLGEVF_RING_TX_ADDR_H_REG, +					 HCLGEVF_RING_TX_BD_NUM_REG, +					 HCLGEVF_RING_TX_PRIORITY_REG, +					 HCLGEVF_RING_TX_TC_REG, +					 HCLGEVF_RING_TX_MERGE_EN_REG, +					 HCLGEVF_RING_TX_TAIL_REG, +					 HCLGEVF_RING_TX_HEAD_REG, +					 HCLGEVF_RING_TX_FBD_NUM_REG, +					 HCLGEVF_RING_TX_OFFSET_REG, +					 HCLGEVF_RING_TX_EBD_NUM_REG, +					 HCLGEVF_RING_TX_EBD_OFFSET_REG, +					 HCLGEVF_RING_TX_BD_ERR_REG, +					 HCLGEVF_RING_EN_REG}; + +static const u32 tqp_intr_reg_addr_list[] = {HCLGEVF_TQP_INTR_CTRL_REG, +					     HCLGEVF_TQP_INTR_GL0_REG, +					     HCLGEVF_TQP_INTR_GL1_REG, +					     HCLGEVF_TQP_INTR_GL2_REG, +					     HCLGEVF_TQP_INTR_RL_REG}; + +enum hclgevf_reg_tag { +	HCLGEVF_REG_TAG_CMDQ = 0, +	HCLGEVF_REG_TAG_COMMON, +	HCLGEVF_REG_TAG_RING, +	HCLGEVF_REG_TAG_TQP_INTR, +}; + +#pragma pack(4) +struct hclgevf_reg_tlv { +	u16 tag; +	u16 len; +}; + +struct hclgevf_reg_header { +	u64 magic_number; +	u8 is_vf; +	u8 rsv[7]; +}; + +#pragma pack() + +#define HCLGEVF_REG_TLV_SIZE		sizeof(struct hclgevf_reg_tlv) +#define HCLGEVF_REG_HEADER_SIZE		sizeof(struct hclgevf_reg_header) +#define HCLGEVF_REG_TLV_SPACE		(sizeof(struct hclgevf_reg_tlv) / sizeof(u32)) +#define HCLGEVF_REG_HEADER_SPACE	(sizeof(struct hclgevf_reg_header) / sizeof(u32)) +#define HCLGEVF_REG_MAGIC_NUMBER	0x686e733372656773 /* meaning is hns3regs */ + +static u32 hclgevf_reg_get_header(void *data) +{ +	struct hclgevf_reg_header *header = data; + +	header->magic_number = HCLGEVF_REG_MAGIC_NUMBER; +	header->is_vf = 0x1; + +	return HCLGEVF_REG_HEADER_SPACE; +} + +static u32 hclgevf_reg_get_tlv(u32 tag, u32 regs_num, void *data) +{ +	struct hclgevf_reg_tlv *tlv = data; + +	tlv->tag = tag; +	tlv->len = regs_num * sizeof(u32) + HCLGEVF_REG_TLV_SIZE; + +	return HCLGEVF_REG_TLV_SPACE; +} + +int hclgevf_get_regs_len(struct hnae3_handle *handle) +{ +	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); +	int cmdq_len, common_len, ring_len, tqp_intr_len; + +	cmdq_len = HCLGEVF_REG_TLV_SIZE + sizeof(cmdq_reg_addr_list); +	common_len = HCLGEVF_REG_TLV_SIZE + sizeof(common_reg_addr_list); +	ring_len = HCLGEVF_REG_TLV_SIZE + sizeof(ring_reg_addr_list); +	tqp_intr_len = HCLGEVF_REG_TLV_SIZE + sizeof(tqp_intr_reg_addr_list); + +	/* return the total length of all register values */ +	return HCLGEVF_REG_HEADER_SIZE + cmdq_len + common_len + +	       tqp_intr_len * (hdev->num_msi_used - 1) + +	       ring_len * hdev->num_tqps; +} + +void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, +		      void *data) +{ +#define HCLGEVF_RING_REG_OFFSET		0x200 +#define HCLGEVF_RING_INT_REG_OFFSET	0x4 + +	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); +	int i, j, reg_um; +	u32 *reg = data; + +	*version = hdev->fw_version; +	reg += hclgevf_reg_get_header(reg); + +	/* fetching per-VF registers values from VF PCIe register space */ +	reg_um = sizeof(cmdq_reg_addr_list) / sizeof(u32); +	reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_CMDQ, reg_um, reg); +	for (i = 0; i < reg_um; i++) +		*reg++ = hclgevf_read_dev(&hdev->hw, cmdq_reg_addr_list[i]); + +	reg_um = sizeof(common_reg_addr_list) / sizeof(u32); +	reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_COMMON, reg_um, reg); +	for (i = 0; i < reg_um; i++) +		*reg++ = hclgevf_read_dev(&hdev->hw, common_reg_addr_list[i]); + +	reg_um = sizeof(ring_reg_addr_list) / sizeof(u32); +	for (j = 0; j < hdev->num_tqps; j++) { +		reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING, reg_um, reg); +		for (i = 0; i < reg_um; i++) +			*reg++ = hclgevf_read_dev(&hdev->hw, +						  ring_reg_addr_list[i] + +						  HCLGEVF_RING_REG_OFFSET * j); +	} + +	reg_um = sizeof(tqp_intr_reg_addr_list) / sizeof(u32); +	for (j = 0; j < hdev->num_msi_used - 1; j++) { +		reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_TQP_INTR, reg_um, reg); +		for (i = 0; i < reg_um; i++) +			*reg++ = hclgevf_read_dev(&hdev->hw, +						  tqp_intr_reg_addr_list[i] + +						  HCLGEVF_RING_INT_REG_OFFSET * j); +	} +} diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.h new file mode 100644 index 000000000000..77bdcf60a1af --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* Copyright (c) 2023 Hisilicon Limited. */ + +#ifndef __HCLGEVF_REGS_H +#define __HCLGEVF_REGS_H +#include <linux/types.h> + +struct hnae3_handle; + +int hclgevf_get_regs_len(struct hnae3_handle *handle); +void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, +		      void *data); +#endif | 
