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 : : static inline bool hinic3_is_vf_dev(const struct rte_pci_device *pdev)
142 : : {
143 : 0 : return pdev->id.device_id == HINIC3_DEV_ID_VF_SP620 ||
144 : : pdev->id.device_id == HINIC3_DEV_ID_VF_SP230;
145 : : }
146 : :
147 : : uint32_t
148 : 0 : hinic3_hwif_read_reg(struct hinic3_hwif *hwif, uint32_t reg)
149 : : {
150 [ # # ]: 0 : if (HINIC3_GET_REG_FLAG(reg) == HINIC3_MGMT_REGS_FLAG)
151 : 0 : return rte_be_to_cpu_32(rte_read32(hwif->mgmt_regs_base +
152 : : HINIC3_GET_REG_ADDR(reg)));
153 : : else
154 : 0 : return rte_be_to_cpu_32(rte_read32(hwif->cfg_regs_base +
155 : : HINIC3_GET_REG_ADDR(reg)));
156 : : }
157 : :
158 : : void
159 : 0 : hinic3_hwif_write_reg(struct hinic3_hwif *hwif, uint32_t reg, uint32_t val)
160 : : {
161 [ # # ]: 0 : if (HINIC3_GET_REG_FLAG(reg) == HINIC3_MGMT_REGS_FLAG)
162 : 0 : rte_write32(rte_cpu_to_be_32(val),
163 [ # # ]: 0 : hwif->mgmt_regs_base + HINIC3_GET_REG_ADDR(reg));
164 : : else
165 : 0 : rte_write32(rte_cpu_to_be_32(val),
166 [ # # ]: 0 : hwif->cfg_regs_base + HINIC3_GET_REG_ADDR(reg));
167 : 0 : }
168 : :
169 : : /**
170 : : * Judge whether HW initialization ok.
171 : : *
172 : : * @param[in] hwdev
173 : : * The pointer to the private hardware device.
174 : : * @return
175 : : * 0 on success, non-zero on failure.
176 : : */
177 : : static int
178 : : hwif_ready(struct hinic3_hwdev *hwdev)
179 : : {
180 : : uint32_t addr, attr1;
181 : :
182 : : addr = HINIC3_CSR_FUNC_ATTR1_ADDR;
183 : 0 : attr1 = hinic3_hwif_read_reg(hwdev->hwif, addr);
184 [ # # ]: 0 : if (attr1 == HINIC3_PCIE_LINK_DOWN)
185 : : return -EBUSY;
186 : :
187 [ # # ]: 0 : if (!HINIC3_AF1_GET(attr1, MGMT_INIT_STATUS))
188 : : return -EBUSY;
189 : :
190 : : return 0;
191 : : }
192 : :
193 : : static int
194 : 0 : wait_hwif_ready(struct hinic3_hwdev *hwdev)
195 : : {
196 : : ulong timeout = 0;
197 : :
198 : : do {
199 : : if (!hwif_ready(hwdev))
200 : : return 0;
201 : :
202 : : rte_delay_ms(1);
203 : 0 : timeout++;
204 [ # # ]: 0 : } while (timeout <= WAIT_HWIF_READY_TIMEOUT);
205 : :
206 : 0 : PMD_DRV_LOG(ERR, "Hwif is not ready ,dev_name: %s", hwdev->eth_dev->data->name);
207 : 0 : return -EBUSY;
208 : : }
209 : :
210 : : /**
211 : : * set the attributes as members in hwif
212 : : *
213 : : * @param[in] hwif
214 : : * The hardware interface of a pci function device.
215 : : */
216 : : static void
217 : 0 : set_hwif_attr(struct hinic3_hwif *hwif, uint32_t attr0, uint32_t attr1, uint32_t attr2,
218 : : uint32_t attr3)
219 : : {
220 : 0 : hwif->attr.func_global_idx = HINIC3_AF0_GET(attr0, FUNC_GLOBAL_IDX);
221 : 0 : hwif->attr.port_to_port_idx = HINIC3_AF0_GET(attr0, P2P_IDX);
222 : 0 : hwif->attr.pci_intf_idx = HINIC3_AF0_GET(attr0, PCI_INTF_IDX);
223 : 0 : hwif->attr.vf_in_pf = HINIC3_AF0_GET(attr0, VF_IN_PF);
224 : 0 : hwif->attr.func_type = HINIC3_AF0_GET(attr0, FUNC_TYPE);
225 : :
226 : 0 : hwif->attr.ppf_idx = HINIC3_AF1_GET(attr1, PPF_IDX);
227 : 0 : hwif->attr.num_aeqs = RTE_BIT32(HINIC3_AF1_GET(attr1, AEQS_PER_FUNC));
228 : :
229 : 0 : hwif->attr.num_ceqs = (uint8_t)HINIC3_AF2_GET(attr2, CEQS_PER_FUNC);
230 : 0 : hwif->attr.num_irqs = HINIC3_AF2_GET(attr2, IRQS_PER_FUNC);
231 : 0 : hwif->attr.num_dma_attr = RTE_BIT32(HINIC3_AF2_GET(attr2, DMA_ATTR_PER_FUNC));
232 : :
233 : 0 : hwif->attr.global_vf_id_of_pf = HINIC3_AF3_GET(attr3, GLOBAL_VF_ID_OF_PF);
234 : 0 : }
235 : :
236 : : /**
237 : : * Read and set the attributes as members in hwif.
238 : : *
239 : : * @param[in] hwif
240 : : * The hardware interface of a pci function device.
241 : : */
242 : : static void
243 : 0 : update_hwif_attr(struct hinic3_hwif *hwif)
244 : : {
245 : : uint32_t addr, attr0, attr1, attr2, attr3;
246 : :
247 : : addr = HINIC3_CSR_FUNC_ATTR0_ADDR;
248 : 0 : attr0 = hinic3_hwif_read_reg(hwif, addr);
249 : :
250 : : addr = HINIC3_CSR_FUNC_ATTR1_ADDR;
251 : 0 : attr1 = hinic3_hwif_read_reg(hwif, addr);
252 : :
253 : : addr = HINIC3_CSR_FUNC_ATTR2_ADDR;
254 : 0 : attr2 = hinic3_hwif_read_reg(hwif, addr);
255 : :
256 : : addr = HINIC3_CSR_FUNC_ATTR3_ADDR;
257 : 0 : attr3 = hinic3_hwif_read_reg(hwif, addr);
258 : :
259 : 0 : set_hwif_attr(hwif, attr0, attr1, attr2, attr3);
260 : 0 : }
261 : :
262 : : /**
263 : : * Update message signaled interrupt information.
264 : : *
265 : : * @param[in] hwif
266 : : * The hardware interface of a pci function device.
267 : : */
268 : : void
269 : 0 : hinic3_update_msix_info(struct hinic3_hwif *hwif)
270 : : {
271 : 0 : uint32_t attr6 = hinic3_hwif_read_reg(hwif, HINIC3_CSR_FUNC_ATTR6_ADDR);
272 : 0 : hwif->attr.num_queue = HINIC3_AF6_GET(attr6, FUNC_MAX_QUEUE);
273 : 0 : hwif->attr.msix_flex_en = HINIC3_AF6_GET(attr6, MSIX_FLEX_EN);
274 : 0 : PMD_DRV_LOG(DEBUG, "msix_flex_en: %u, queue msix: %u",
275 : : hwif->attr.msix_flex_en, hwif->attr.num_queue);
276 : 0 : }
277 : :
278 : : void
279 : 0 : hinic3_set_pf_status(struct hinic3_hwif *hwif, enum hinic3_pf_status status)
280 : : {
281 : 0 : uint32_t attr6 = hinic3_hwif_read_reg(hwif, HINIC3_CSR_FUNC_ATTR6_ADDR);
282 : :
283 : 0 : attr6 = HINIC3_AF6_CLEAR(attr6, PF_STATUS);
284 : 0 : attr6 |= HINIC3_AF6_SET(status, PF_STATUS);
285 : :
286 [ # # ]: 0 : if (hwif->attr.func_type == TYPE_VF)
287 : : return;
288 : :
289 : 0 : hinic3_hwif_write_reg(hwif, HINIC3_CSR_FUNC_ATTR6_ADDR, attr6);
290 : : }
291 : :
292 : : enum hinic3_pf_status
293 : 0 : hinic3_get_pf_status(struct hinic3_hwif *hwif)
294 : : {
295 : 0 : uint32_t attr6 = hinic3_hwif_read_reg(hwif, HINIC3_CSR_FUNC_ATTR6_ADDR);
296 : :
297 : 0 : return HINIC3_AF6_GET(attr6, PF_STATUS);
298 : : }
299 : :
300 : : static enum hinic3_doorbell_ctrl
301 : : hinic3_get_doorbell_ctrl_status(struct hinic3_hwif *hwif)
302 : : {
303 : 0 : uint32_t attr4 = hinic3_hwif_read_reg(hwif, HINIC3_CSR_FUNC_ATTR4_ADDR);
304 : :
305 : : return HINIC3_AF4_GET(attr4, DOORBELL_CTRL);
306 : : }
307 : :
308 : : static enum hinic3_outbound_ctrl
309 : : hinic3_get_outbound_ctrl_status(struct hinic3_hwif *hwif)
310 : : {
311 : 0 : uint32_t attr5 = hinic3_hwif_read_reg(hwif, HINIC3_CSR_FUNC_ATTR5_ADDR);
312 : :
313 : : return HINIC3_AF5_GET(attr5, OUTBOUND_CTRL);
314 : : }
315 : :
316 : : void
317 : 0 : hinic3_enable_doorbell(struct hinic3_hwif *hwif)
318 : : {
319 : : uint32_t addr, attr4;
320 : :
321 : : addr = HINIC3_CSR_FUNC_ATTR4_ADDR;
322 : 0 : attr4 = hinic3_hwif_read_reg(hwif, addr);
323 : :
324 : 0 : attr4 = HINIC3_AF4_CLEAR(attr4, DOORBELL_CTRL);
325 : : attr4 |= HINIC3_AF4_SET(ENABLE_DOORBELL, DOORBELL_CTRL);
326 : :
327 : 0 : hinic3_hwif_write_reg(hwif, addr, attr4);
328 : 0 : }
329 : :
330 : : void
331 : 0 : hinic3_disable_doorbell(struct hinic3_hwif *hwif)
332 : : {
333 : : uint32_t addr, attr4;
334 : :
335 : : addr = HINIC3_CSR_FUNC_ATTR4_ADDR;
336 : 0 : attr4 = hinic3_hwif_read_reg(hwif, addr);
337 : :
338 : 0 : attr4 = HINIC3_AF4_CLEAR(attr4, DOORBELL_CTRL);
339 : 0 : attr4 |= HINIC3_AF4_SET(DISABLE_DOORBELL, DOORBELL_CTRL);
340 : :
341 : 0 : hinic3_hwif_write_reg(hwif, addr, attr4);
342 : 0 : }
343 : :
344 : : /**
345 : : * Try to set hwif as ppf and set the type of hwif in this case.
346 : : *
347 : : * @param[in] hwif
348 : : * The hardware interface of a pci function device
349 : : */
350 : : static void
351 : 0 : set_ppf(struct hinic3_hwif *hwif)
352 : : {
353 : : struct hinic3_func_attr *attr = &hwif->attr;
354 : : uint32_t addr, val, ppf_election;
355 : :
356 : : addr = HINIC3_CSR_PPF_ELECTION_ADDR;
357 : :
358 : 0 : val = hinic3_hwif_read_reg(hwif, addr);
359 : 0 : val = HINIC3_PPF_ELECTION_CLEAR(val, IDX);
360 : :
361 : 0 : ppf_election = HINIC3_PPF_ELECTION_SET(attr->func_global_idx, IDX);
362 : 0 : val |= ppf_election;
363 : :
364 : 0 : hinic3_hwif_write_reg(hwif, addr, val);
365 : :
366 : : /* Check PPF. */
367 : 0 : val = hinic3_hwif_read_reg(hwif, addr);
368 : :
369 : 0 : attr->ppf_idx = HINIC3_PPF_ELECTION_GET(val, IDX);
370 [ # # ]: 0 : if (attr->ppf_idx == attr->func_global_idx)
371 : 0 : attr->func_type = TYPE_PPF;
372 : 0 : }
373 : :
374 : : /**
375 : : * Get the mpf index from the hwif.
376 : : *
377 : : * @param[in] hwif
378 : : * The hardware interface of a pci function device.
379 : : */
380 : : static void
381 : : get_mpf(struct hinic3_hwif *hwif)
382 : : {
383 : : struct hinic3_func_attr *attr = &hwif->attr;
384 : : uint32_t mpf_election, addr;
385 : :
386 : : addr = HINIC3_CSR_GLOBAL_MPF_ELECTION_ADDR;
387 : :
388 : 0 : mpf_election = hinic3_hwif_read_reg(hwif, addr);
389 : 0 : attr->mpf_idx = HINIC3_MPF_ELECTION_GET(mpf_election, IDX);
390 : 0 : }
391 : :
392 : : /**
393 : : * Try to set hwif as mpf and set the mpf idx in hwif.
394 : : *
395 : : * @param[in] hwif
396 : : * The hardware interface of a pci function device.
397 : : */
398 : : static void
399 : 0 : set_mpf(struct hinic3_hwif *hwif)
400 : : {
401 : : struct hinic3_func_attr *attr = &hwif->attr;
402 : : uint32_t addr, val, mpf_election;
403 : :
404 : : addr = HINIC3_CSR_GLOBAL_MPF_ELECTION_ADDR;
405 : :
406 : 0 : val = hinic3_hwif_read_reg(hwif, addr);
407 : :
408 : 0 : val = HINIC3_MPF_ELECTION_CLEAR(val, IDX);
409 : 0 : mpf_election = HINIC3_MPF_ELECTION_SET(attr->func_global_idx, IDX);
410 : :
411 : 0 : val |= mpf_election;
412 : 0 : hinic3_hwif_write_reg(hwif, addr, val);
413 : 0 : }
414 : :
415 : : int
416 : 0 : hinic3_alloc_db_addr(struct hinic3_hwdev *hwdev, void **db_base,
417 : : enum hinic3_db_type queue_type)
418 : : {
419 : : struct hinic3_hwif *hwif = NULL;
420 : :
421 [ # # ]: 0 : if (!hwdev || !db_base)
422 : : return -EINVAL;
423 : :
424 : 0 : hwif = hwdev->hwif;
425 : 0 : *db_base = hwif->db_base + queue_type * HINIC3_DB_PAGE_SIZE;
426 : :
427 : 0 : return 0;
428 : : }
429 : :
430 : : void
431 : 0 : hinic3_set_msix_auto_mask_state(struct hinic3_hwdev *hwdev, uint16_t msix_idx,
432 : : enum hinic3_msix_auto_mask flag)
433 : : {
434 : : struct hinic3_hwif *hwif = NULL;
435 : : uint32_t mask_bits;
436 : : uint32_t addr;
437 : :
438 [ # # ]: 0 : if (!hwdev)
439 : : return;
440 : :
441 : 0 : hwif = hwdev->hwif;
442 : :
443 [ # # ]: 0 : if (flag)
444 : : mask_bits = HINIC3_MSI_CLR_INDIR_SET(1, AUTO_MSK_SET);
445 : : else
446 : : mask_bits = HINIC3_MSI_CLR_INDIR_SET(1, AUTO_MSK_CLR);
447 : :
448 : 0 : mask_bits = mask_bits |
449 : 0 : HINIC3_MSI_CLR_INDIR_SET(msix_idx, SIMPLE_INDIR_IDX);
450 : :
451 : : addr = HINIC3_CSR_FUNC_MSI_CLR_WR_ADDR;
452 : 0 : hinic3_hwif_write_reg(hwif, addr, mask_bits);
453 : : }
454 : :
455 : : /**
456 : : * Set msix state.
457 : : *
458 : : * @param[in] hwdev
459 : : * The pointer to the private hardware device object.
460 : : * @param[in] msix_idx
461 : : * MSIX(Message Signaled Interrupts) index.
462 : : * @param[in] flag
463 : : * MSIX state flag, 0-enable, 1-disable.
464 : : */
465 : : void
466 : 0 : hinic3_set_msix_state(struct hinic3_hwdev *hwdev, uint16_t msix_idx, enum hinic3_msix_state flag)
467 : : {
468 : : struct hinic3_hwif *hwif = NULL;
469 : : uint32_t mask_bits;
470 : : uint32_t addr;
471 : : uint8_t int_msk = 1;
472 : :
473 [ # # ]: 0 : if (!hwdev)
474 : : return;
475 : :
476 : 0 : hwif = hwdev->hwif;
477 : :
478 [ # # ]: 0 : if (flag)
479 : : mask_bits = HINIC3_MSI_CLR_INDIR_SET(int_msk, INT_MSK_SET);
480 : : else
481 : : mask_bits = HINIC3_MSI_CLR_INDIR_SET(int_msk, INT_MSK_CLR);
482 : 0 : mask_bits = mask_bits |
483 : 0 : HINIC3_MSI_CLR_INDIR_SET(msix_idx, SIMPLE_INDIR_IDX);
484 : :
485 : : addr = HINIC3_CSR_FUNC_MSI_CLR_WR_ADDR;
486 : 0 : hinic3_hwif_write_reg(hwif, addr, mask_bits);
487 : : }
488 : :
489 : : static void
490 : : disable_all_msix(struct hinic3_hwdev *hwdev)
491 : : {
492 : 0 : uint16_t num_irqs = hwdev->hwif->attr.num_irqs;
493 : : uint16_t i;
494 : :
495 [ # # ]: 0 : for (i = 0; i < num_irqs; i++)
496 : 0 : hinic3_set_msix_state(hwdev, i, HINIC3_MSIX_DISABLE);
497 : : }
498 : :
499 : : /**
500 : : * Clear msix resend bit.
501 : : *
502 : : * @param[in] hwdev
503 : : * The pointer to the private hardware device object.
504 : : * @param[in] msix_idx
505 : : * MSIX(Message Signaled Interrupts) index
506 : : * @param[in] clear_resend_en
507 : : * Clear resend en flag, 1-clear.
508 : : */
509 : : void
510 : 0 : hinic3_misx_intr_clear_resend_bit(struct hinic3_hwdev *hwdev,
511 : : uint16_t msix_idx, uint8_t clear_resend_en)
512 : : {
513 : : struct hinic3_hwif *hwif = NULL;
514 : : uint32_t msix_ctrl = 0, addr;
515 : :
516 [ # # ]: 0 : if (!hwdev)
517 : : return;
518 : :
519 : 0 : hwif = hwdev->hwif;
520 : :
521 : 0 : msix_ctrl = HINIC3_MSI_CLR_INDIR_SET(msix_idx, SIMPLE_INDIR_IDX) |
522 : 0 : HINIC3_MSI_CLR_INDIR_SET(clear_resend_en, RESEND_TIMER_CLR);
523 : :
524 : : addr = HINIC3_CSR_FUNC_MSI_CLR_WR_ADDR;
525 : 0 : hinic3_hwif_write_reg(hwif, addr, msix_ctrl);
526 : : }
527 : :
528 : : static int
529 : 0 : wait_until_doorbell_and_outbound_enabled(struct hinic3_hwif *hwif)
530 : : {
531 : : enum hinic3_doorbell_ctrl db_ctrl;
532 : : enum hinic3_outbound_ctrl outbound_ctrl;
533 : : uint32_t cnt = 0;
534 : :
535 [ # # ]: 0 : while (cnt < HINIC3_WAIT_DOORBELL_AND_OUTBOUND_TIMEOUT) {
536 : : db_ctrl = hinic3_get_doorbell_ctrl_status(hwif);
537 : : outbound_ctrl = hinic3_get_outbound_ctrl_status(hwif);
538 [ # # ]: 0 : if (outbound_ctrl == ENABLE_OUTBOUND &&
539 : : db_ctrl == ENABLE_DOORBELL)
540 : : return 0;
541 : :
542 : : rte_delay_ms(1);
543 : 0 : cnt++;
544 : : }
545 : :
546 : : return -EFAULT;
547 : : }
548 : :
549 : : static int
550 : 0 : hinic3_get_bar_addr(struct hinic3_hwdev *hwdev)
551 : : {
552 : 0 : struct rte_pci_device *pci_dev = hwdev->pci_dev;
553 : 0 : struct hinic3_hwif *hwif = hwdev->hwif;
554 : : void *cfg_regs_base = NULL;
555 : : void *mgmt_reg_base = NULL;
556 : : void *db_base = NULL;
557 : : int cfg_bar;
558 : :
559 : 0 : cfg_bar = hinic3_is_vf_dev(pci_dev) ? HINIC3_VF_PCI_CFG_REG_BAR
560 : 0 : : HINIC3_PF_PCI_CFG_REG_BAR;
561 : 0 : cfg_regs_base = pci_dev->mem_resource[cfg_bar].addr;
562 : :
563 [ # # ]: 0 : if (cfg_regs_base == NULL) {
564 : 0 : PMD_DRV_LOG(ERR,
565 : : "mem_resource addr is null, cfg_regs_base is NULL");
566 : 0 : return -EFAULT;
567 : : }
568 [ # # ]: 0 : if (!hinic3_is_vf_dev(pci_dev)) {
569 : 0 : mgmt_reg_base =
570 : : pci_dev->mem_resource[HINIC3_PCI_MGMT_REG_BAR].addr;
571 [ # # ]: 0 : if (mgmt_reg_base == NULL) {
572 : 0 : PMD_DRV_LOG(ERR, "mgmt_reg_base addr is null");
573 : 0 : return -EFAULT;
574 : : }
575 : : }
576 : 0 : db_base = pci_dev->mem_resource[HINIC3_PCI_DB_BAR].addr;
577 [ # # ]: 0 : if (db_base == NULL) {
578 : 0 : PMD_DRV_LOG(ERR, "mem_resource addr is null, db_base is NULL");
579 : 0 : return -EFAULT;
580 : : }
581 : : /* If function is VF, mgmt_regs_base will be NULL. */
582 [ # # ]: 0 : if (!mgmt_reg_base)
583 : 0 : hwif->cfg_regs_base =
584 : 0 : (uint8_t *)cfg_regs_base + HINIC3_VF_CFG_REG_OFFSET;
585 : : else
586 : 0 : hwif->cfg_regs_base = cfg_regs_base;
587 : 0 : hwif->mgmt_regs_base = mgmt_reg_base;
588 : 0 : hwif->db_base = db_base;
589 : 0 : hwif->db_dwqe_len = pci_dev->mem_resource[HINIC3_PCI_DB_BAR].len;
590 : :
591 : 0 : return 0;
592 : : }
593 : :
594 : : /**
595 : : * Initialize the hw interface.
596 : : *
597 : : * @param[in] hwdev
598 : : * The pointer to the private hardware device object.
599 : : * @return
600 : : * 0 on success, non-zero on failure.
601 : : */
602 : : int
603 : 0 : hinic3_init_hwif(struct hinic3_hwdev *hwdev)
604 : : {
605 : : struct hinic3_hwif *hwif;
606 : : int err;
607 : : uint32_t attr4, attr5;
608 : :
609 : 0 : hwif = rte_zmalloc("hinic_hwif", sizeof(struct hinic3_hwif),
610 : : RTE_CACHE_LINE_SIZE);
611 [ # # ]: 0 : if (hwif == NULL)
612 : : return -ENOMEM;
613 : :
614 : 0 : hwdev->hwif = hwif;
615 : :
616 : 0 : err = hinic3_get_bar_addr(hwdev);
617 [ # # ]: 0 : if (err) {
618 : 0 : PMD_DRV_LOG(ERR, "get bar addr fail");
619 : 0 : goto hwif_ready_err;
620 : : }
621 : :
622 : 0 : err = wait_hwif_ready(hwdev);
623 [ # # ]: 0 : if (err) {
624 : 0 : PMD_DRV_LOG(ERR, "Chip status is not ready");
625 : 0 : goto hwif_ready_err;
626 : : }
627 : :
628 : 0 : update_hwif_attr(hwif);
629 : :
630 : 0 : err = wait_until_doorbell_and_outbound_enabled(hwif);
631 [ # # ]: 0 : if (err) {
632 : 0 : attr4 = hinic3_hwif_read_reg(hwif, HINIC3_CSR_FUNC_ATTR4_ADDR);
633 : 0 : attr5 = hinic3_hwif_read_reg(hwif, HINIC3_CSR_FUNC_ATTR5_ADDR);
634 : 0 : PMD_DRV_LOG(ERR,
635 : : "Hw doorbell/outbound is disabled, attr4 0x%x attr5 0x%x",
636 : : attr4, attr5);
637 : 0 : goto hwif_ready_err;
638 : : }
639 : :
640 [ # # ]: 0 : if (!HINIC3_IS_VF(hwdev)) {
641 : 0 : set_ppf(hwif);
642 : :
643 [ # # ]: 0 : if (HINIC3_IS_PPF(hwdev))
644 : 0 : set_mpf(hwif);
645 : :
646 : : get_mpf(hwif);
647 : : }
648 : :
649 : : disable_all_msix(hwdev);
650 : : /* Disable mgmt cpu reporting any event. */
651 : 0 : hinic3_set_pf_status(hwdev->hwif, HINIC3_PF_STATUS_INIT);
652 : :
653 : 0 : PMD_DRV_LOG(DEBUG,
654 : : "global_func_idx: %d, func_type: %d, host_id: %d, ppf: %d, mpf: %d init success",
655 : : hwif->attr.func_global_idx, hwif->attr.func_type,
656 : : hwif->attr.pci_intf_idx, hwif->attr.ppf_idx,
657 : : hwif->attr.mpf_idx);
658 : :
659 : 0 : return 0;
660 : :
661 : 0 : hwif_ready_err:
662 : 0 : rte_free(hwdev->hwif);
663 : 0 : hwdev->hwif = NULL;
664 : :
665 : 0 : return err;
666 : : }
667 : :
668 : : /**
669 : : * Free the hw interface.
670 : : *
671 : : * @param[in] dev
672 : : * The pointer to the private hardware device.
673 : : */
674 : : void
675 : 0 : hinic3_deinit_hwif(struct hinic3_hwdev *hwdev)
676 : : {
677 : 0 : rte_free(hwdev->hwif);
678 : 0 : }
679 : :
680 : : uint16_t
681 : 0 : hinic3_global_func_id(struct hinic3_hwdev *hwdev)
682 : : {
683 : : struct hinic3_hwif *hwif = NULL;
684 : :
685 [ # # ]: 0 : if (!hwdev)
686 : : return 0;
687 : :
688 : 0 : hwif = hwdev->hwif;
689 : :
690 : 0 : return hwif->attr.func_global_idx;
691 : : }
692 : :
693 : : uint8_t
694 : 0 : hinic3_pf_id_of_vf(struct hinic3_hwdev *hwdev)
695 : : {
696 : : struct hinic3_hwif *hwif = NULL;
697 : :
698 [ # # ]: 0 : if (!hwdev)
699 : : return 0;
700 : :
701 : 0 : hwif = hwdev->hwif;
702 : :
703 : 0 : return hwif->attr.port_to_port_idx;
704 : : }
705 : :
706 : : uint8_t
707 : 0 : hinic3_pcie_itf_id(struct hinic3_hwdev *hwdev)
708 : : {
709 : : struct hinic3_hwif *hwif = NULL;
710 : :
711 [ # # ]: 0 : if (!hwdev)
712 : : return 0;
713 : :
714 : 0 : hwif = hwdev->hwif;
715 : :
716 : 0 : return hwif->attr.pci_intf_idx;
717 : : }
718 : :
719 : : enum func_type
720 : 0 : hinic3_func_type(struct hinic3_hwdev *hwdev)
721 : : {
722 : : struct hinic3_hwif *hwif = NULL;
723 : :
724 [ # # ]: 0 : if (!hwdev)
725 : : return 0;
726 : :
727 : 0 : hwif = hwdev->hwif;
728 : :
729 : 0 : return hwif->attr.func_type;
730 : : }
731 : :
732 : : uint16_t
733 : 0 : hinic3_glb_pf_vf_offset(struct hinic3_hwdev *hwdev)
734 : : {
735 : : struct hinic3_hwif *hwif = NULL;
736 : :
737 [ # # ]: 0 : if (!hwdev)
738 : : return 0;
739 : :
740 : 0 : hwif = hwdev->hwif;
741 : :
742 : 0 : return hwif->attr.global_vf_id_of_pf;
743 : : }
|