1 // SPDX-License-Identifier: GPL-2.0+
2 // Copyright (c) 2023 Hisilicon Limited.
4 #include "hclgevf_main.h"
5 #include "hclgevf_regs.h"
8 static const u32 cmdq_reg_addr_list
[] = {HCLGE_COMM_NIC_CSQ_BASEADDR_L_REG
,
9 HCLGE_COMM_NIC_CSQ_BASEADDR_H_REG
,
10 HCLGE_COMM_NIC_CSQ_DEPTH_REG
,
11 HCLGE_COMM_NIC_CSQ_TAIL_REG
,
12 HCLGE_COMM_NIC_CSQ_HEAD_REG
,
13 HCLGE_COMM_NIC_CRQ_BASEADDR_L_REG
,
14 HCLGE_COMM_NIC_CRQ_BASEADDR_H_REG
,
15 HCLGE_COMM_NIC_CRQ_DEPTH_REG
,
16 HCLGE_COMM_NIC_CRQ_TAIL_REG
,
17 HCLGE_COMM_NIC_CRQ_HEAD_REG
,
18 HCLGE_COMM_VECTOR0_CMDQ_SRC_REG
,
19 HCLGE_COMM_VECTOR0_CMDQ_STATE_REG
,
20 HCLGE_COMM_CMDQ_INTR_EN_REG
,
21 HCLGE_COMM_CMDQ_INTR_GEN_REG
};
23 static const u32 common_reg_addr_list
[] = {HCLGEVF_MISC_VECTOR_REG_BASE
,
27 static const u32 ring_reg_addr_list
[] = {HCLGEVF_RING_RX_ADDR_L_REG
,
28 HCLGEVF_RING_RX_ADDR_H_REG
,
29 HCLGEVF_RING_RX_BD_NUM_REG
,
30 HCLGEVF_RING_RX_BD_LENGTH_REG
,
31 HCLGEVF_RING_RX_MERGE_EN_REG
,
32 HCLGEVF_RING_RX_TAIL_REG
,
33 HCLGEVF_RING_RX_HEAD_REG
,
34 HCLGEVF_RING_RX_FBD_NUM_REG
,
35 HCLGEVF_RING_RX_OFFSET_REG
,
36 HCLGEVF_RING_RX_FBD_OFFSET_REG
,
37 HCLGEVF_RING_RX_STASH_REG
,
38 HCLGEVF_RING_RX_BD_ERR_REG
,
39 HCLGEVF_RING_TX_ADDR_L_REG
,
40 HCLGEVF_RING_TX_ADDR_H_REG
,
41 HCLGEVF_RING_TX_BD_NUM_REG
,
42 HCLGEVF_RING_TX_PRIORITY_REG
,
43 HCLGEVF_RING_TX_TC_REG
,
44 HCLGEVF_RING_TX_MERGE_EN_REG
,
45 HCLGEVF_RING_TX_TAIL_REG
,
46 HCLGEVF_RING_TX_HEAD_REG
,
47 HCLGEVF_RING_TX_FBD_NUM_REG
,
48 HCLGEVF_RING_TX_OFFSET_REG
,
49 HCLGEVF_RING_TX_EBD_NUM_REG
,
50 HCLGEVF_RING_TX_EBD_OFFSET_REG
,
51 HCLGEVF_RING_TX_BD_ERR_REG
,
54 static const u32 tqp_intr_reg_addr_list
[] = {HCLGEVF_TQP_INTR_CTRL_REG
,
55 HCLGEVF_TQP_INTR_GL0_REG
,
56 HCLGEVF_TQP_INTR_GL1_REG
,
57 HCLGEVF_TQP_INTR_GL2_REG
,
58 HCLGEVF_TQP_INTR_RL_REG
};
60 enum hclgevf_reg_tag
{
61 HCLGEVF_REG_TAG_CMDQ
= 0,
62 HCLGEVF_REG_TAG_COMMON
,
64 HCLGEVF_REG_TAG_TQP_INTR
,
68 struct hclgevf_reg_tlv
{
73 struct hclgevf_reg_header
{
81 #define HCLGEVF_REG_TLV_SIZE sizeof(struct hclgevf_reg_tlv)
82 #define HCLGEVF_REG_HEADER_SIZE sizeof(struct hclgevf_reg_header)
83 #define HCLGEVF_REG_TLV_SPACE (sizeof(struct hclgevf_reg_tlv) / sizeof(u32))
84 #define HCLGEVF_REG_HEADER_SPACE (sizeof(struct hclgevf_reg_header) / sizeof(u32))
85 #define HCLGEVF_REG_MAGIC_NUMBER 0x686e733372656773 /* meaning is hns3regs */
87 static u32
hclgevf_reg_get_header(void *data
)
89 struct hclgevf_reg_header
*header
= data
;
91 header
->magic_number
= HCLGEVF_REG_MAGIC_NUMBER
;
94 return HCLGEVF_REG_HEADER_SPACE
;
97 static u32
hclgevf_reg_get_tlv(u32 tag
, u32 regs_num
, void *data
)
99 struct hclgevf_reg_tlv
*tlv
= data
;
102 tlv
->len
= regs_num
* sizeof(u32
) + HCLGEVF_REG_TLV_SIZE
;
104 return HCLGEVF_REG_TLV_SPACE
;
107 int hclgevf_get_regs_len(struct hnae3_handle
*handle
)
109 struct hclgevf_dev
*hdev
= hclgevf_ae_get_hdev(handle
);
110 int cmdq_len
, common_len
, ring_len
, tqp_intr_len
;
112 cmdq_len
= HCLGEVF_REG_TLV_SIZE
+ sizeof(cmdq_reg_addr_list
);
113 common_len
= HCLGEVF_REG_TLV_SIZE
+ sizeof(common_reg_addr_list
);
114 ring_len
= HCLGEVF_REG_TLV_SIZE
+ sizeof(ring_reg_addr_list
);
115 tqp_intr_len
= HCLGEVF_REG_TLV_SIZE
+ sizeof(tqp_intr_reg_addr_list
);
117 /* return the total length of all register values */
118 return HCLGEVF_REG_HEADER_SIZE
+ cmdq_len
+ common_len
+
119 tqp_intr_len
* (hdev
->num_msi_used
- 1) +
120 ring_len
* hdev
->num_tqps
;
123 void hclgevf_get_regs(struct hnae3_handle
*handle
, u32
*version
,
126 #define HCLGEVF_RING_REG_OFFSET 0x200
127 #define HCLGEVF_RING_INT_REG_OFFSET 0x4
129 struct hclgevf_dev
*hdev
= hclgevf_ae_get_hdev(handle
);
133 *version
= hdev
->fw_version
;
134 reg
+= hclgevf_reg_get_header(reg
);
136 /* fetching per-VF registers values from VF PCIe register space */
137 reg_um
= ARRAY_SIZE(cmdq_reg_addr_list
);
138 reg
+= hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_CMDQ
, reg_um
, reg
);
139 for (i
= 0; i
< reg_um
; i
++)
140 *reg
++ = hclgevf_read_dev(&hdev
->hw
, cmdq_reg_addr_list
[i
]);
142 reg_um
= ARRAY_SIZE(common_reg_addr_list
);
143 reg
+= hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_COMMON
, reg_um
, reg
);
144 for (i
= 0; i
< reg_um
; i
++)
145 *reg
++ = hclgevf_read_dev(&hdev
->hw
, common_reg_addr_list
[i
]);
147 reg_um
= ARRAY_SIZE(ring_reg_addr_list
);
148 for (j
= 0; j
< hdev
->num_tqps
; j
++) {
149 reg
+= hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING
, reg_um
, reg
);
150 for (i
= 0; i
< reg_um
; i
++)
151 *reg
++ = hclgevf_read_dev(&hdev
->hw
,
152 ring_reg_addr_list
[i
] +
153 HCLGEVF_RING_REG_OFFSET
* j
);
156 reg_um
= ARRAY_SIZE(tqp_intr_reg_addr_list
);
157 for (j
= 0; j
< hdev
->num_msi_used
- 1; j
++) {
158 reg
+= hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_TQP_INTR
, reg_um
, reg
);
159 for (i
= 0; i
< reg_um
; i
++)
160 *reg
++ = hclgevf_read_dev(&hdev
->hw
,
161 tqp_intr_reg_addr_list
[i
] +
162 HCLGEVF_RING_INT_REG_OFFSET
* j
);