aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2023-08-16 08:56:38 +0100
committerDavid S. Miller <davem@davemloft.net>2023-08-16 08:56:38 +0100
commitbc02fc7990239a73f199105bb57b34963b6a12c7 (patch)
tree309c7470a38477a15964ec3750eb130cd2520521
parent78c53eaae1e13d973098a968d3e3bdaaceef5aca (diff)
parent36122201eeaefd78547def9681aa5d83b5a00b6a (diff)
downloadnf-next-bc02fc7990239a73f199105bb57b34963b6a12c7.tar.gz
Merge branch 'hns3-ethtool'
Jijie Shao says: ==================== hns3: refactor registers information for ethtool -d refactor registers information for ethtool -d ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/Makefile4
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hnae3.h1
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h4
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c1
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c560
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h2
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c668
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.h17
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c121
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h1
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c164
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.h13
12 files changed, 875 insertions, 681 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/Makefile b/drivers/net/ethernet/hisilicon/hns3/Makefile
index 6efea466285875..e214bfaece1f3a 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 514a20bce4f449..a4b43bcd2f0c9c 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 0bd858620f27b5..4d15eb73b97285 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 0fb2eaee3e8a0a..f01a7a9ee02ca1 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 437b510f2b809f..0f50dba6cc4780 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, &regs_num_32_bit, &regs_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, &regs_num_32_bit, &regs_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 70b059e6d35f88..ec233ec57222aa 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 00000000000000..43c1c18fa81f8d
--- /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, &regs_num_32_bit, &regs_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, &regs_num_32_bit, &regs_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 00000000000000..b6bc1ecb8054eb
--- /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 34f02ca8d1d2d0..7a2f9233d69548 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 59ca6c794d6dbe..81c16b8c8da296 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 00000000000000..65b9dcd3813756
--- /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 00000000000000..77bdcf60a1afe5
--- /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