Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2025 Huawei Technologies Co., Ltd
3 : : */
4 : :
5 : : #include "hinic3_compat.h"
6 : : #include "hinic3_csr.h"
7 : : #include "hinic3_hwif.h"
8 : :
9 : : #define WAIT_HWIF_READY_TIMEOUT 10000
10 : :
11 : : #define DB_IDX(db, db_base) \
12 : : ((uint32_t)(((ulong)(db) - (ulong)(db_base)) / HINIC3_DB_PAGE_SIZE))
13 : :
14 : : #define HINIC3_AF0_FUNC_GLOBAL_IDX_SHIFT 0
15 : : #define HINIC3_AF0_P2P_IDX_SHIFT 12
16 : : #define HINIC3_AF0_PCI_INTF_IDX_SHIFT 17
17 : : #define HINIC3_AF0_VF_IN_PF_SHIFT 20
18 : : #define HINIC3_AF0_FUNC_TYPE_SHIFT 28
19 : :
20 : : #define HINIC3_AF0_FUNC_GLOBAL_IDX_MASK 0xFFF
21 : : #define HINIC3_AF0_P2P_IDX_MASK 0x1F
22 : : #define HINIC3_AF0_PCI_INTF_IDX_MASK 0x7
23 : : #define HINIC3_AF0_VF_IN_PF_MASK 0xFF
24 : : #define HINIC3_AF0_FUNC_TYPE_MASK 0x1
25 : :
26 : : #define HINIC3_AF0_GET(val, member) \
27 : : (((val) >> HINIC3_AF0_##member##_SHIFT) & HINIC3_AF0_##member##_MASK)
28 : :
29 : : #define HINIC3_AF1_PPF_IDX_SHIFT 0
30 : : #define HINIC3_AF1_AEQS_PER_FUNC_SHIFT 8
31 : : #define HINIC3_AF1_MGMT_INIT_STATUS_SHIFT 30
32 : : #define HINIC3_AF1_PF_INIT_STATUS_SHIFT 31
33 : :
34 : : #define HINIC3_AF1_PPF_IDX_MASK 0x3F
35 : : #define HINIC3_AF1_AEQS_PER_FUNC_MASK 0x3
36 : : #define HINIC3_AF1_MGMT_INIT_STATUS_MASK 0x1
37 : : #define HINIC3_AF1_PF_INIT_STATUS_MASK 0x1
38 : :
39 : : #define HINIC3_AF1_GET(val, member) \
40 : : (((val) >> HINIC3_AF1_##member##_SHIFT) & HINIC3_AF1_##member##_MASK)
41 : :
42 : : #define HINIC3_AF2_CEQS_PER_FUNC_SHIFT 0
43 : : #define HINIC3_AF2_DMA_ATTR_PER_FUNC_SHIFT 9
44 : : #define HINIC3_AF2_IRQS_PER_FUNC_SHIFT 16
45 : :
46 : : #define HINIC3_AF2_CEQS_PER_FUNC_MASK 0x1FF
47 : : #define HINIC3_AF2_DMA_ATTR_PER_FUNC_MASK 0x7
48 : : #define HINIC3_AF2_IRQS_PER_FUNC_MASK 0x7FF
49 : :
50 : : #define HINIC3_AF2_GET(val, member) \
51 : : (((val) >> HINIC3_AF2_##member##_SHIFT) & HINIC3_AF2_##member##_MASK)
52 : :
53 : : #define HINIC3_AF3_GLOBAL_VF_ID_OF_NXT_PF_SHIFT 0
54 : : #define HINIC3_AF3_GLOBAL_VF_ID_OF_PF_SHIFT 16
55 : :
56 : : #define HINIC3_AF3_GLOBAL_VF_ID_OF_NXT_PF_MASK 0xFFF
57 : : #define HINIC3_AF3_GLOBAL_VF_ID_OF_PF_MASK 0xFFF
58 : :
59 : : #define HINIC3_AF3_GET(val, member) \
60 : : (((val) >> HINIC3_AF3_##member##_SHIFT) & HINIC3_AF3_##member##_MASK)
61 : :
62 : : #define HINIC3_AF4_DOORBELL_CTRL_SHIFT 0
63 : : #define HINIC3_AF4_DOORBELL_CTRL_MASK 0x1
64 : :
65 : : #define HINIC3_AF4_GET(val, member) \
66 : : (((val) >> HINIC3_AF4_##member##_SHIFT) & HINIC3_AF4_##member##_MASK)
67 : :
68 : : #define HINIC3_AF4_SET(val, member) \
69 : : (((val) & HINIC3_AF4_##member##_MASK) << HINIC3_AF4_##member##_SHIFT)
70 : :
71 : : #define HINIC3_AF4_CLEAR(val, member) \
72 : : ((val) & (~(HINIC3_AF4_##member##_MASK << HINIC3_AF4_##member##_SHIFT)))
73 : :
74 : : #define HINIC3_AF5_OUTBOUND_CTRL_SHIFT 0
75 : : #define HINIC3_AF5_OUTBOUND_CTRL_MASK 0x1
76 : :
77 : : #define HINIC3_AF5_GET(val, member) \
78 : : (((val) >> HINIC3_AF5_##member##_SHIFT) & HINIC3_AF5_##member##_MASK)
79 : :
80 : : #define HINIC3_AF5_SET(val, member) \
81 : : (((val) & HINIC3_AF5_##member##_MASK) << HINIC3_AF5_##member##_SHIFT)
82 : :
83 : : #define HINIC3_AF5_CLEAR(val, member) \
84 : : ((val) & (~(HINIC3_AF5_##member##_MASK << HINIC3_AF5_##member##_SHIFT)))
85 : :
86 : : #define HINIC3_AF6_PF_STATUS_SHIFT 0
87 : : #define HINIC3_AF6_PF_STATUS_MASK 0xFFFF
88 : :
89 : : #define HINIC3_AF6_FUNC_MAX_QUEUE_SHIFT 23
90 : : #define HINIC3_AF6_FUNC_MAX_QUEUE_MASK 0x1FF
91 : :
92 : : #define HINIC3_AF6_MSIX_FLEX_EN_SHIFT 22
93 : : #define HINIC3_AF6_MSIX_FLEX_EN_MASK 0x1
94 : :
95 : : #define HINIC3_AF6_SET(val, member) \
96 : : ((((uint32_t)(val)) & HINIC3_AF6_##member##_MASK) \
97 : : << HINIC3_AF6_##member##_SHIFT)
98 : :
99 : : #define HINIC3_AF6_GET(val, member) \
100 : : (((val) >> HINIC3_AF6_##member##_SHIFT) & HINIC3_AF6_##member##_MASK)
101 : :
102 : : #define HINIC3_AF6_CLEAR(val, member) \
103 : : ((val) & (~(HINIC3_AF6_##member##_MASK << HINIC3_AF6_##member##_SHIFT)))
104 : :
105 : : #define HINIC3_PPF_ELECTION_IDX_SHIFT 0
106 : :
107 : : #define HINIC3_PPF_ELECTION_IDX_MASK 0x3F
108 : :
109 : : #define HINIC3_PPF_ELECTION_SET(val, member) \
110 : : (((val) & HINIC3_PPF_ELECTION_##member##_MASK) \
111 : : << HINIC3_PPF_ELECTION_##member##_SHIFT)
112 : :
113 : : #define HINIC3_PPF_ELECTION_GET(val, member) \
114 : : (((val) >> HINIC3_PPF_ELECTION_##member##_SHIFT) & \
115 : : HINIC3_PPF_ELECTION_##member##_MASK)
116 : :
117 : : #define HINIC3_PPF_ELECTION_CLEAR(val, member) \
118 : : ((val) & (~(HINIC3_PPF_ELECTION_##member##_MASK \
119 : : << HINIC3_PPF_ELECTION_##member##_SHIFT)))
120 : :
121 : : #define HINIC3_MPF_ELECTION_IDX_SHIFT 0
122 : :
123 : : #define HINIC3_MPF_ELECTION_IDX_MASK 0x1F
124 : :
125 : : #define HINIC3_MPF_ELECTION_SET(val, member) \
126 : : (((val) & HINIC3_MPF_ELECTION_##member##_MASK) \
127 : : << HINIC3_MPF_ELECTION_##member##_SHIFT)
128 : :
129 : : #define HINIC3_MPF_ELECTION_GET(val, member) \
130 : : (((val) >> HINIC3_MPF_ELECTION_##member##_SHIFT) & \
131 : : HINIC3_MPF_ELECTION_##member##_MASK)
132 : :
133 : : #define HINIC3_MPF_ELECTION_CLEAR(val, member) \
134 : : ((val) & (~(HINIC3_MPF_ELECTION_##member##_MASK \
135 : : << HINIC3_MPF_ELECTION_##member##_SHIFT)))
136 : :
137 : : #define HINIC3_GET_REG_FLAG(reg) ((reg) & (~(HINIC3_REGS_FLAG_MASK)))
138 : :
139 : : #define HINIC3_GET_REG_ADDR(reg) ((reg) & (HINIC3_REGS_FLAG_MASK))
140 : :
141 : : #define HINIC3_IS_VF_DEV(pdev) ((pdev)->id.device_id == HINIC3_DEV_ID_VF)
142 : :
143 : : uint32_t
144 : 0 : hinic3_hwif_read_reg(struct hinic3_hwif *hwif, uint32_t reg)
145 : : {
146 [ # # ]: 0 : if (HINIC3_GET_REG_FLAG(reg) == HINIC3_MGMT_REGS_FLAG)
147 : 0 : return rte_be_to_cpu_32(rte_read32(hwif->mgmt_regs_base +
148 : : HINIC3_GET_REG_ADDR(reg)));
149 : : else
150 : 0 : return rte_be_to_cpu_32(rte_read32(hwif->cfg_regs_base +
151 : : HINIC3_GET_REG_ADDR(reg)));
152 : : }
153 : :
154 : : void
155 : 0 : hinic3_hwif_write_reg(struct hinic3_hwif *hwif, uint32_t reg, uint32_t val)
156 : : {
157 [ # # ]: 0 : if (HINIC3_GET_REG_FLAG(reg) == HINIC3_MGMT_REGS_FLAG)
158 : 0 : rte_write32(rte_cpu_to_be_32(val),
159 [ # # ]: 0 : hwif->mgmt_regs_base + HINIC3_GET_REG_ADDR(reg));
160 : : else
161 : 0 : rte_write32(rte_cpu_to_be_32(val),
162 [ # # ]: 0 : hwif->cfg_regs_base + HINIC3_GET_REG_ADDR(reg));
163 : 0 : }
164 : :
165 : : /**
166 : : * Judge whether HW initialization ok.
167 : : *
168 : : * @param[in] hwdev
169 : : * The pointer to the private hardware device.
170 : : * @return
171 : : * 0 on success, non-zero on failure.
172 : : */
173 : : static int
174 : : hwif_ready(struct hinic3_hwdev *hwdev)
175 : : {
176 : : uint32_t addr, attr1;
177 : :
178 : : addr = HINIC3_CSR_FUNC_ATTR1_ADDR;
179 : 0 : attr1 = hinic3_hwif_read_reg(hwdev->hwif, addr);
180 [ # # ]: 0 : if (attr1 == HINIC3_PCIE_LINK_DOWN)
181 : : return -EBUSY;
182 : :
183 [ # # ]: 0 : if (!HINIC3_AF1_GET(attr1, MGMT_INIT_STATUS))
184 : : return -EBUSY;
185 : :
186 : : return 0;
187 : : }
188 : :
189 : : static int
190 : 0 : wait_hwif_ready(struct hinic3_hwdev *hwdev)
191 : : {
192 : : ulong timeout = 0;
193 : :
194 : : do {
195 : : if (!hwif_ready(hwdev))
196 : : return 0;
197 : :
198 : : rte_delay_ms(1);
199 : 0 : timeout++;
200 [ # # ]: 0 : } while (timeout <= WAIT_HWIF_READY_TIMEOUT);
201 : :
202 : 0 : PMD_DRV_LOG(ERR, "Hwif is not ready ,dev_name: %s", hwdev->eth_dev->data->name);
203 : 0 : return -EBUSY;
204 : : }
205 : :
206 : : /**
207 : : * set the attributes as members in hwif
208 : : *
209 : : * @param[in] hwif
210 : : * The hardware interface of a pci function device.
211 : : */
212 : : static void
213 : 0 : set_hwif_attr(struct hinic3_hwif *hwif, uint32_t attr0, uint32_t attr1, uint32_t attr2,
214 : : uint32_t attr3)
215 : : {
216 : 0 : hwif->attr.func_global_idx = HINIC3_AF0_GET(attr0, FUNC_GLOBAL_IDX);
217 : 0 : hwif->attr.port_to_port_idx = HINIC3_AF0_GET(attr0, P2P_IDX);
218 : 0 : hwif->attr.pci_intf_idx = HINIC3_AF0_GET(attr0, PCI_INTF_IDX);
219 : 0 : hwif->attr.vf_in_pf = HINIC3_AF0_GET(attr0, VF_IN_PF);
220 : 0 : hwif->attr.func_type = HINIC3_AF0_GET(attr0, FUNC_TYPE);
221 : :
222 : 0 : hwif->attr.ppf_idx = HINIC3_AF1_GET(attr1, PPF_IDX);
223 : 0 : hwif->attr.num_aeqs = RTE_BIT32(HINIC3_AF1_GET(attr1, AEQS_PER_FUNC));
224 : :
225 : 0 : hwif->attr.num_ceqs = (uint8_t)HINIC3_AF2_GET(attr2, CEQS_PER_FUNC);
226 : 0 : hwif->attr.num_irqs = HINIC3_AF2_GET(attr2, IRQS_PER_FUNC);
227 : 0 : hwif->attr.num_dma_attr = RTE_BIT32(HINIC3_AF2_GET(attr2, DMA_ATTR_PER_FUNC));
228 : :
229 : 0 : hwif->attr.global_vf_id_of_pf = HINIC3_AF3_GET(attr3, GLOBAL_VF_ID_OF_PF);
230 : 0 : }
231 : :
232 : : /**
233 : : * Read and set the attributes as members in hwif.
234 : : *
235 : : * @param[in] hwif
236 : : * The hardware interface of a pci function device.
237 : : */
238 : : static void
239 : 0 : update_hwif_attr(struct hinic3_hwif *hwif)
240 : : {
241 : : uint32_t addr, attr0, attr1, attr2, attr3;
242 : :
243 : : addr = HINIC3_CSR_FUNC_ATTR0_ADDR;
244 : 0 : attr0 = hinic3_hwif_read_reg(hwif, addr);
245 : :
246 : : addr = HINIC3_CSR_FUNC_ATTR1_ADDR;
247 : 0 : attr1 = hinic3_hwif_read_reg(hwif, addr);
248 : :
249 : : addr = HINIC3_CSR_FUNC_ATTR2_ADDR;
250 : 0 : attr2 = hinic3_hwif_read_reg(hwif, addr);
251 : :
252 : : addr = HINIC3_CSR_FUNC_ATTR3_ADDR;
253 : 0 : attr3 = hinic3_hwif_read_reg(hwif, addr);
254 : :
255 : 0 : set_hwif_attr(hwif, attr0, attr1, attr2, attr3);
256 : 0 : }
257 : :
258 : : /**
259 : : * Update message signaled interrupt information.
260 : : *
261 : : * @param[in] hwif
262 : : * The hardware interface of a pci function device.
263 : : */
264 : : void
265 : 0 : hinic3_update_msix_info(struct hinic3_hwif *hwif)
266 : : {
267 : 0 : uint32_t attr6 = hinic3_hwif_read_reg(hwif, HINIC3_CSR_FUNC_ATTR6_ADDR);
268 : 0 : hwif->attr.num_queue = HINIC3_AF6_GET(attr6, FUNC_MAX_QUEUE);
269 : 0 : hwif->attr.msix_flex_en = HINIC3_AF6_GET(attr6, MSIX_FLEX_EN);
270 : 0 : PMD_DRV_LOG(DEBUG, "msix_flex_en: %u, queue msix: %u",
271 : : hwif->attr.msix_flex_en, hwif->attr.num_queue);
272 : 0 : }
273 : :
274 : : void
275 : 0 : hinic3_set_pf_status(struct hinic3_hwif *hwif, enum hinic3_pf_status status)
276 : : {
277 : 0 : uint32_t attr6 = hinic3_hwif_read_reg(hwif, HINIC3_CSR_FUNC_ATTR6_ADDR);
278 : :
279 : 0 : attr6 = HINIC3_AF6_CLEAR(attr6, PF_STATUS);
280 : 0 : attr6 |= HINIC3_AF6_SET(status, PF_STATUS);
281 : :
282 [ # # ]: 0 : if (hwif->attr.func_type == TYPE_VF)
283 : : return;
284 : :
285 : 0 : hinic3_hwif_write_reg(hwif, HINIC3_CSR_FUNC_ATTR6_ADDR, attr6);
286 : : }
287 : :
288 : : enum hinic3_pf_status
289 : 0 : hinic3_get_pf_status(struct hinic3_hwif *hwif)
290 : : {
291 : 0 : uint32_t attr6 = hinic3_hwif_read_reg(hwif, HINIC3_CSR_FUNC_ATTR6_ADDR);
292 : :
293 : 0 : return HINIC3_AF6_GET(attr6, PF_STATUS);
294 : : }
295 : :
296 : : static enum hinic3_doorbell_ctrl
297 : : hinic3_get_doorbell_ctrl_status(struct hinic3_hwif *hwif)
298 : : {
299 : 0 : uint32_t attr4 = hinic3_hwif_read_reg(hwif, HINIC3_CSR_FUNC_ATTR4_ADDR);
300 : :
301 : : return HINIC3_AF4_GET(attr4, DOORBELL_CTRL);
302 : : }
303 : :
304 : : static enum hinic3_outbound_ctrl
305 : : hinic3_get_outbound_ctrl_status(struct hinic3_hwif *hwif)
306 : : {
307 : 0 : uint32_t attr5 = hinic3_hwif_read_reg(hwif, HINIC3_CSR_FUNC_ATTR5_ADDR);
308 : :
309 : : return HINIC3_AF5_GET(attr5, OUTBOUND_CTRL);
310 : : }
311 : :
312 : : void
313 : 0 : hinic3_enable_doorbell(struct hinic3_hwif *hwif)
314 : : {
315 : : uint32_t addr, attr4;
316 : :
317 : : addr = HINIC3_CSR_FUNC_ATTR4_ADDR;
318 : 0 : attr4 = hinic3_hwif_read_reg(hwif, addr);
319 : :
320 : 0 : attr4 = HINIC3_AF4_CLEAR(attr4, DOORBELL_CTRL);
321 : : attr4 |= HINIC3_AF4_SET(ENABLE_DOORBELL, DOORBELL_CTRL);
322 : :
323 : 0 : hinic3_hwif_write_reg(hwif, addr, attr4);
324 : 0 : }
325 : :
326 : : void
327 : 0 : hinic3_disable_doorbell(struct hinic3_hwif *hwif)
328 : : {
329 : : uint32_t addr, attr4;
330 : :
331 : : addr = HINIC3_CSR_FUNC_ATTR4_ADDR;
332 : 0 : attr4 = hinic3_hwif_read_reg(hwif, addr);
333 : :
334 : 0 : attr4 = HINIC3_AF4_CLEAR(attr4, DOORBELL_CTRL);
335 : 0 : attr4 |= HINIC3_AF4_SET(DISABLE_DOORBELL, DOORBELL_CTRL);
336 : :
337 : 0 : hinic3_hwif_write_reg(hwif, addr, attr4);
338 : 0 : }
339 : :
340 : : /**
341 : : * Try to set hwif as ppf and set the type of hwif in this case.
342 : : *
343 : : * @param[in] hwif
344 : : * The hardware interface of a pci function device
345 : : */
346 : : static void
347 : 0 : set_ppf(struct hinic3_hwif *hwif)
348 : : {
349 : : struct hinic3_func_attr *attr = &hwif->attr;
350 : : uint32_t addr, val, ppf_election;
351 : :
352 : : addr = HINIC3_CSR_PPF_ELECTION_ADDR;
353 : :
354 : 0 : val = hinic3_hwif_read_reg(hwif, addr);
355 : 0 : val = HINIC3_PPF_ELECTION_CLEAR(val, IDX);
356 : :
357 : 0 : ppf_election = HINIC3_PPF_ELECTION_SET(attr->func_global_idx, IDX);
358 : 0 : val |= ppf_election;
359 : :
360 : 0 : hinic3_hwif_write_reg(hwif, addr, val);
361 : :
362 : : /* Check PPF. */
363 : 0 : val = hinic3_hwif_read_reg(hwif, addr);
364 : :
365 : 0 : attr->ppf_idx = HINIC3_PPF_ELECTION_GET(val, IDX);
366 [ # # ]: 0 : if (attr->ppf_idx == attr->func_global_idx)
367 : 0 : attr->func_type = TYPE_PPF;
368 : 0 : }
369 : :
370 : : /**
371 : : * Get the mpf index from the hwif.
372 : : *
373 : : * @param[in] hwif
374 : : * The hardware interface of a pci function device.
375 : : */
376 : : static void
377 : : get_mpf(struct hinic3_hwif *hwif)
378 : : {
379 : : struct hinic3_func_attr *attr = &hwif->attr;
380 : : uint32_t mpf_election, addr;
381 : :
382 : : addr = HINIC3_CSR_GLOBAL_MPF_ELECTION_ADDR;
383 : :
384 : 0 : mpf_election = hinic3_hwif_read_reg(hwif, addr);
385 : 0 : attr->mpf_idx = HINIC3_MPF_ELECTION_GET(mpf_election, IDX);
386 : 0 : }
387 : :
388 : : /**
389 : : * Try to set hwif as mpf and set the mpf idx in hwif.
390 : : *
391 : : * @param[in] hwif
392 : : * The hardware interface of a pci function device.
393 : : */
394 : : static void
395 : 0 : set_mpf(struct hinic3_hwif *hwif)
396 : : {
397 : : struct hinic3_func_attr *attr = &hwif->attr;
398 : : uint32_t addr, val, mpf_election;
399 : :
400 : : addr = HINIC3_CSR_GLOBAL_MPF_ELECTION_ADDR;
401 : :
402 : 0 : val = hinic3_hwif_read_reg(hwif, addr);
403 : :
404 : 0 : val = HINIC3_MPF_ELECTION_CLEAR(val, IDX);
405 : 0 : mpf_election = HINIC3_MPF_ELECTION_SET(attr->func_global_idx, IDX);
406 : :
407 : 0 : val |= mpf_election;
408 : 0 : hinic3_hwif_write_reg(hwif, addr, val);
409 : 0 : }
410 : :
411 : : int
412 : 0 : hinic3_alloc_db_addr(struct hinic3_hwdev *hwdev, void **db_base,
413 : : enum hinic3_db_type queue_type)
414 : : {
415 : : struct hinic3_hwif *hwif = NULL;
416 : :
417 [ # # ]: 0 : if (!hwdev || !db_base)
418 : : return -EINVAL;
419 : :
420 : 0 : hwif = hwdev->hwif;
421 : 0 : *db_base = hwif->db_base + queue_type * HINIC3_DB_PAGE_SIZE;
422 : :
423 : 0 : return 0;
424 : : }
425 : :
426 : : void
427 : 0 : hinic3_set_msix_auto_mask_state(struct hinic3_hwdev *hwdev, uint16_t msix_idx,
428 : : enum hinic3_msix_auto_mask flag)
429 : : {
430 : : struct hinic3_hwif *hwif = NULL;
431 : : uint32_t mask_bits;
432 : : uint32_t addr;
433 : :
434 [ # # ]: 0 : if (!hwdev)
435 : : return;
436 : :
437 : 0 : hwif = hwdev->hwif;
438 : :
439 [ # # ]: 0 : if (flag)
440 : : mask_bits = HINIC3_MSI_CLR_INDIR_SET(1, AUTO_MSK_SET);
441 : : else
442 : : mask_bits = HINIC3_MSI_CLR_INDIR_SET(1, AUTO_MSK_CLR);
443 : :
444 : 0 : mask_bits = mask_bits |
445 : 0 : HINIC3_MSI_CLR_INDIR_SET(msix_idx, SIMPLE_INDIR_IDX);
446 : :
447 : : addr = HINIC3_CSR_FUNC_MSI_CLR_WR_ADDR;
448 : 0 : hinic3_hwif_write_reg(hwif, addr, mask_bits);
449 : : }
450 : :
451 : : /**
452 : : * Set msix state.
453 : : *
454 : : * @param[in] hwdev
455 : : * The pointer to the private hardware device object.
456 : : * @param[in] msix_idx
457 : : * MSIX(Message Signaled Interrupts) index.
458 : : * @param[in] flag
459 : : * MSIX state flag, 0-enable, 1-disable.
460 : : */
461 : : void
462 : 0 : hinic3_set_msix_state(struct hinic3_hwdev *hwdev, uint16_t msix_idx, enum hinic3_msix_state flag)
463 : : {
464 : : struct hinic3_hwif *hwif = NULL;
465 : : uint32_t mask_bits;
466 : : uint32_t addr;
467 : : uint8_t int_msk = 1;
468 : :
469 [ # # ]: 0 : if (!hwdev)
470 : : return;
471 : :
472 : 0 : hwif = hwdev->hwif;
473 : :
474 [ # # ]: 0 : if (flag)
475 : : mask_bits = HINIC3_MSI_CLR_INDIR_SET(int_msk, INT_MSK_SET);
476 : : else
477 : : mask_bits = HINIC3_MSI_CLR_INDIR_SET(int_msk, INT_MSK_CLR);
478 : 0 : mask_bits = mask_bits |
479 : 0 : HINIC3_MSI_CLR_INDIR_SET(msix_idx, SIMPLE_INDIR_IDX);
480 : :
481 : : addr = HINIC3_CSR_FUNC_MSI_CLR_WR_ADDR;
482 : 0 : hinic3_hwif_write_reg(hwif, addr, mask_bits);
483 : : }
484 : :
485 : : static void
486 : : disable_all_msix(struct hinic3_hwdev *hwdev)
487 : : {
488 : 0 : uint16_t num_irqs = hwdev->hwif->attr.num_irqs;
489 : : uint16_t i;
490 : :
491 [ # # ]: 0 : for (i = 0; i < num_irqs; i++)
492 : 0 : hinic3_set_msix_state(hwdev, i, HINIC3_MSIX_DISABLE);
493 : : }
494 : :
495 : : /**
496 : : * Clear msix resend bit.
497 : : *
498 : : * @param[in] hwdev
499 : : * The pointer to the private hardware device object.
500 : : * @param[in] msix_idx
501 : : * MSIX(Message Signaled Interrupts) index
502 : : * @param[in] clear_resend_en
503 : : * Clear resend en flag, 1-clear.
504 : : */
505 : : void
506 : 0 : hinic3_misx_intr_clear_resend_bit(struct hinic3_hwdev *hwdev,
507 : : uint16_t msix_idx, uint8_t clear_resend_en)
508 : : {
509 : : struct hinic3_hwif *hwif = NULL;
510 : : uint32_t msix_ctrl = 0, addr;
511 : :
512 [ # # ]: 0 : if (!hwdev)
513 : : return;
514 : :
515 : 0 : hwif = hwdev->hwif;
516 : :
517 : 0 : msix_ctrl = HINIC3_MSI_CLR_INDIR_SET(msix_idx, SIMPLE_INDIR_IDX) |
518 : 0 : HINIC3_MSI_CLR_INDIR_SET(clear_resend_en, RESEND_TIMER_CLR);
519 : :
520 : : addr = HINIC3_CSR_FUNC_MSI_CLR_WR_ADDR;
521 : 0 : hinic3_hwif_write_reg(hwif, addr, msix_ctrl);
522 : : }
523 : :
524 : : static int
525 : 0 : wait_until_doorbell_and_outbound_enabled(struct hinic3_hwif *hwif)
526 : : {
527 : : enum hinic3_doorbell_ctrl db_ctrl;
528 : : enum hinic3_outbound_ctrl outbound_ctrl;
529 : : uint32_t cnt = 0;
530 : :
531 [ # # ]: 0 : while (cnt < HINIC3_WAIT_DOORBELL_AND_OUTBOUND_TIMEOUT) {
532 : : db_ctrl = hinic3_get_doorbell_ctrl_status(hwif);
533 : : outbound_ctrl = hinic3_get_outbound_ctrl_status(hwif);
534 [ # # ]: 0 : if (outbound_ctrl == ENABLE_OUTBOUND &&
535 : : db_ctrl == ENABLE_DOORBELL)
536 : : return 0;
537 : :
538 : : rte_delay_ms(1);
539 : 0 : cnt++;
540 : : }
541 : :
542 : : return -EFAULT;
543 : : }
544 : :
545 : : static int
546 : 0 : hinic3_get_bar_addr(struct hinic3_hwdev *hwdev)
547 : : {
548 : 0 : struct rte_pci_device *pci_dev = hwdev->pci_dev;
549 : 0 : struct hinic3_hwif *hwif = hwdev->hwif;
550 : : void *cfg_regs_base = NULL;
551 : : void *mgmt_reg_base = NULL;
552 : : void *db_base = NULL;
553 : : int cfg_bar;
554 : :
555 : 0 : cfg_bar = HINIC3_IS_VF_DEV(pci_dev) ? HINIC3_VF_PCI_CFG_REG_BAR
556 : 0 : : HINIC3_PF_PCI_CFG_REG_BAR;
557 : 0 : cfg_regs_base = pci_dev->mem_resource[cfg_bar].addr;
558 : :
559 [ # # ]: 0 : if (cfg_regs_base == NULL) {
560 : 0 : PMD_DRV_LOG(ERR,
561 : : "mem_resource addr is null, cfg_regs_base is NULL");
562 : 0 : return -EFAULT;
563 : : }
564 [ # # ]: 0 : if (!HINIC3_IS_VF_DEV(pci_dev)) {
565 : 0 : mgmt_reg_base =
566 : : pci_dev->mem_resource[HINIC3_PCI_MGMT_REG_BAR].addr;
567 [ # # ]: 0 : if (mgmt_reg_base == NULL) {
568 : 0 : PMD_DRV_LOG(ERR, "mgmt_reg_base addr is null");
569 : 0 : return -EFAULT;
570 : : }
571 : : }
572 : 0 : db_base = pci_dev->mem_resource[HINIC3_PCI_DB_BAR].addr;
573 [ # # ]: 0 : if (db_base == NULL) {
574 : 0 : PMD_DRV_LOG(ERR, "mem_resource addr is null, db_base is NULL");
575 : 0 : return -EFAULT;
576 : : }
577 : : /* If function is VF, mgmt_regs_base will be NULL. */
578 [ # # ]: 0 : if (!mgmt_reg_base)
579 : 0 : hwif->cfg_regs_base =
580 : 0 : (uint8_t *)cfg_regs_base + HINIC3_VF_CFG_REG_OFFSET;
581 : : else
582 : 0 : hwif->cfg_regs_base = cfg_regs_base;
583 : 0 : hwif->mgmt_regs_base = mgmt_reg_base;
584 : 0 : hwif->db_base = db_base;
585 : 0 : hwif->db_dwqe_len = pci_dev->mem_resource[HINIC3_PCI_DB_BAR].len;
586 : :
587 : 0 : return 0;
588 : : }
589 : :
590 : : /**
591 : : * Initialize the hw interface.
592 : : *
593 : : * @param[in] hwdev
594 : : * The pointer to the private hardware device object.
595 : : * @return
596 : : * 0 on success, non-zero on failure.
597 : : */
598 : : int
599 : 0 : hinic3_init_hwif(struct hinic3_hwdev *hwdev)
600 : : {
601 : : struct hinic3_hwif *hwif;
602 : : int err;
603 : : uint32_t attr4, attr5;
604 : :
605 : 0 : hwif = rte_zmalloc("hinic_hwif", sizeof(struct hinic3_hwif),
606 : : RTE_CACHE_LINE_SIZE);
607 [ # # ]: 0 : if (hwif == NULL)
608 : : return -ENOMEM;
609 : :
610 : 0 : hwdev->hwif = hwif;
611 : :
612 : 0 : err = hinic3_get_bar_addr(hwdev);
613 [ # # ]: 0 : if (err) {
614 : 0 : PMD_DRV_LOG(ERR, "get bar addr fail");
615 : 0 : goto hwif_ready_err;
616 : : }
617 : :
618 : 0 : err = wait_hwif_ready(hwdev);
619 [ # # ]: 0 : if (err) {
620 : 0 : PMD_DRV_LOG(ERR, "Chip status is not ready");
621 : 0 : goto hwif_ready_err;
622 : : }
623 : :
624 : 0 : update_hwif_attr(hwif);
625 : :
626 : 0 : err = wait_until_doorbell_and_outbound_enabled(hwif);
627 [ # # ]: 0 : if (err) {
628 : 0 : attr4 = hinic3_hwif_read_reg(hwif, HINIC3_CSR_FUNC_ATTR4_ADDR);
629 : 0 : attr5 = hinic3_hwif_read_reg(hwif, HINIC3_CSR_FUNC_ATTR5_ADDR);
630 : 0 : PMD_DRV_LOG(ERR,
631 : : "Hw doorbell/outbound is disabled, attr4 0x%x attr5 0x%x",
632 : : attr4, attr5);
633 : 0 : goto hwif_ready_err;
634 : : }
635 : :
636 [ # # ]: 0 : if (!HINIC3_IS_VF(hwdev)) {
637 : 0 : set_ppf(hwif);
638 : :
639 [ # # ]: 0 : if (HINIC3_IS_PPF(hwdev))
640 : 0 : set_mpf(hwif);
641 : :
642 : : get_mpf(hwif);
643 : : }
644 : :
645 : : disable_all_msix(hwdev);
646 : : /* Disable mgmt cpu reporting any event. */
647 : 0 : hinic3_set_pf_status(hwdev->hwif, HINIC3_PF_STATUS_INIT);
648 : :
649 : 0 : PMD_DRV_LOG(DEBUG,
650 : : "global_func_idx: %d, func_type: %d, host_id: %d, ppf: %d, mpf: %d init success",
651 : : hwif->attr.func_global_idx, hwif->attr.func_type,
652 : : hwif->attr.pci_intf_idx, hwif->attr.ppf_idx,
653 : : hwif->attr.mpf_idx);
654 : :
655 : 0 : return 0;
656 : :
657 : 0 : hwif_ready_err:
658 : 0 : rte_free(hwdev->hwif);
659 : 0 : hwdev->hwif = NULL;
660 : :
661 : 0 : return err;
662 : : }
663 : :
664 : : /**
665 : : * Free the hw interface.
666 : : *
667 : : * @param[in] dev
668 : : * The pointer to the private hardware device.
669 : : */
670 : : void
671 : 0 : hinic3_deinit_hwif(struct hinic3_hwdev *hwdev)
672 : : {
673 : 0 : rte_free(hwdev->hwif);
674 : 0 : }
675 : :
676 : : uint16_t
677 : 0 : hinic3_global_func_id(struct hinic3_hwdev *hwdev)
678 : : {
679 : : struct hinic3_hwif *hwif = NULL;
680 : :
681 [ # # ]: 0 : if (!hwdev)
682 : : return 0;
683 : :
684 : 0 : hwif = hwdev->hwif;
685 : :
686 : 0 : return hwif->attr.func_global_idx;
687 : : }
688 : :
689 : : uint8_t
690 : 0 : hinic3_pf_id_of_vf(struct hinic3_hwdev *hwdev)
691 : : {
692 : : struct hinic3_hwif *hwif = NULL;
693 : :
694 [ # # ]: 0 : if (!hwdev)
695 : : return 0;
696 : :
697 : 0 : hwif = hwdev->hwif;
698 : :
699 : 0 : return hwif->attr.port_to_port_idx;
700 : : }
701 : :
702 : : uint8_t
703 : 0 : hinic3_pcie_itf_id(struct hinic3_hwdev *hwdev)
704 : : {
705 : : struct hinic3_hwif *hwif = NULL;
706 : :
707 [ # # ]: 0 : if (!hwdev)
708 : : return 0;
709 : :
710 : 0 : hwif = hwdev->hwif;
711 : :
712 : 0 : return hwif->attr.pci_intf_idx;
713 : : }
714 : :
715 : : enum func_type
716 : 0 : hinic3_func_type(struct hinic3_hwdev *hwdev)
717 : : {
718 : : struct hinic3_hwif *hwif = NULL;
719 : :
720 [ # # ]: 0 : if (!hwdev)
721 : : return 0;
722 : :
723 : 0 : hwif = hwdev->hwif;
724 : :
725 : 0 : return hwif->attr.func_type;
726 : : }
727 : :
728 : : uint16_t
729 : 0 : hinic3_glb_pf_vf_offset(struct hinic3_hwdev *hwdev)
730 : : {
731 : : struct hinic3_hwif *hwif = NULL;
732 : :
733 [ # # ]: 0 : if (!hwdev)
734 : : return 0;
735 : :
736 : 0 : hwif = hwdev->hwif;
737 : :
738 : 0 : return hwif->attr.global_vf_id_of_pf;
739 : : }
|