1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | // Copyright (c) 2023 Hisilicon Limited. |
3 | |
4 | #include "hclgevf_main.h" |
5 | #include "hclgevf_regs.h" |
6 | #include "hnae3.h" |
7 | |
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}; |
22 | |
23 | static const u32 common_reg_addr_list[] = {HCLGEVF_MISC_VECTOR_REG_BASE, |
24 | HCLGEVF_RST_ING, |
25 | HCLGEVF_GRO_EN_REG}; |
26 | |
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, |
52 | HCLGEVF_RING_EN_REG}; |
53 | |
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}; |
59 | |
60 | enum hclgevf_reg_tag { |
61 | HCLGEVF_REG_TAG_CMDQ = 0, |
62 | HCLGEVF_REG_TAG_COMMON, |
63 | HCLGEVF_REG_TAG_RING, |
64 | HCLGEVF_REG_TAG_TQP_INTR, |
65 | }; |
66 | |
67 | #pragma pack(4) |
68 | struct hclgevf_reg_tlv { |
69 | u16 tag; |
70 | u16 len; |
71 | }; |
72 | |
73 | struct { |
74 | u64 ; |
75 | u8 ; |
76 | u8 [7]; |
77 | }; |
78 | |
79 | #pragma pack() |
80 | |
81 | #define HCLGEVF_REG_TLV_SIZE sizeof(struct hclgevf_reg_tlv) |
82 | #define sizeof(struct hclgevf_reg_header) |
83 | #define HCLGEVF_REG_TLV_SPACE (sizeof(struct hclgevf_reg_tlv) / sizeof(u32)) |
84 | #define (sizeof(struct hclgevf_reg_header) / sizeof(u32)) |
85 | #define HCLGEVF_REG_MAGIC_NUMBER 0x686e733372656773 /* meaning is hns3regs */ |
86 | |
87 | static u32 (void *data) |
88 | { |
89 | struct hclgevf_reg_header * = data; |
90 | |
91 | header->magic_number = HCLGEVF_REG_MAGIC_NUMBER; |
92 | header->is_vf = 0x1; |
93 | |
94 | return HCLGEVF_REG_HEADER_SPACE; |
95 | } |
96 | |
97 | static u32 hclgevf_reg_get_tlv(u32 tag, u32 regs_num, void *data) |
98 | { |
99 | struct hclgevf_reg_tlv *tlv = data; |
100 | |
101 | tlv->tag = tag; |
102 | tlv->len = regs_num * sizeof(u32) + HCLGEVF_REG_TLV_SIZE; |
103 | |
104 | return HCLGEVF_REG_TLV_SPACE; |
105 | } |
106 | |
107 | int hclgevf_get_regs_len(struct hnae3_handle *handle) |
108 | { |
109 | struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); |
110 | int cmdq_len, common_len, ring_len, tqp_intr_len; |
111 | |
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); |
116 | |
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; |
121 | } |
122 | |
123 | void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, |
124 | void *data) |
125 | { |
126 | #define HCLGEVF_RING_REG_OFFSET 0x200 |
127 | #define HCLGEVF_RING_INT_REG_OFFSET 0x4 |
128 | |
129 | struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); |
130 | int i, j, reg_um; |
131 | u32 *reg = data; |
132 | |
133 | *version = hdev->fw_version; |
134 | reg += hclgevf_reg_get_header(data: reg); |
135 | |
136 | /* fetching per-VF registers values from VF PCIe register space */ |
137 | reg_um = sizeof(cmdq_reg_addr_list) / sizeof(u32); |
138 | reg += hclgevf_reg_get_tlv(tag: HCLGEVF_REG_TAG_CMDQ, regs_num: reg_um, data: reg); |
139 | for (i = 0; i < reg_um; i++) |
140 | *reg++ = hclgevf_read_dev(&hdev->hw, cmdq_reg_addr_list[i]); |
141 | |
142 | reg_um = sizeof(common_reg_addr_list) / sizeof(u32); |
143 | reg += hclgevf_reg_get_tlv(tag: HCLGEVF_REG_TAG_COMMON, regs_num: reg_um, data: reg); |
144 | for (i = 0; i < reg_um; i++) |
145 | *reg++ = hclgevf_read_dev(&hdev->hw, common_reg_addr_list[i]); |
146 | |
147 | reg_um = sizeof(ring_reg_addr_list) / sizeof(u32); |
148 | for (j = 0; j < hdev->num_tqps; j++) { |
149 | reg += hclgevf_reg_get_tlv(tag: HCLGEVF_REG_TAG_RING, regs_num: reg_um, data: 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); |
154 | } |
155 | |
156 | reg_um = sizeof(tqp_intr_reg_addr_list) / sizeof(u32); |
157 | for (j = 0; j < hdev->num_msi_used - 1; j++) { |
158 | reg += hclgevf_reg_get_tlv(tag: HCLGEVF_REG_TAG_TQP_INTR, regs_num: reg_um, data: 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); |
163 | } |
164 | } |
165 | |