1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2016-2020 Intel Corporation
13 #include <rte_malloc.h>
14 #include <rte_errno.h>
16 #include "base/dlb2_resource.h"
17 #include "base/dlb2_osdep.h"
18 #include "base/dlb2_regs.h"
19 #include "dlb2_main.h"
20 #include "../dlb2_user.h"
21 #include "../dlb2_priv.h"
22 #include "../dlb2_inline_fns.h"
24 #define PF_ID_ZERO 0 /* PF ONLY! */
25 #define NO_OWNER_VF 0 /* PF ONLY! */
26 #define NOT_VF_REQ false /* PF ONLY! */
28 #define DLB2_PCI_CFG_SPACE_SIZE 256
29 #define DLB2_PCI_CAP_POINTER 0x34
30 #define DLB2_PCI_CAP_NEXT(hdr) (((hdr) >> 8) & 0xFC)
31 #define DLB2_PCI_CAP_ID(hdr) ((hdr) & 0xFF)
32 #define DLB2_PCI_EXT_CAP_NEXT(hdr) (((hdr) >> 20) & 0xFFC)
33 #define DLB2_PCI_EXT_CAP_ID(hdr) ((hdr) & 0xFFFF)
34 #define DLB2_PCI_EXT_CAP_ID_ERR 1
35 #define DLB2_PCI_ERR_UNCOR_MASK 8
36 #define DLB2_PCI_ERR_UNC_UNSUP 0x00100000
38 #define DLB2_PCI_EXP_DEVCTL 8
39 #define DLB2_PCI_LNKCTL 16
40 #define DLB2_PCI_SLTCTL 24
41 #define DLB2_PCI_RTCTL 28
42 #define DLB2_PCI_EXP_DEVCTL2 40
43 #define DLB2_PCI_LNKCTL2 48
44 #define DLB2_PCI_SLTCTL2 56
45 #define DLB2_PCI_CMD 4
46 #define DLB2_PCI_X_CMD 2
47 #define DLB2_PCI_EXP_DEVSTA 10
48 #define DLB2_PCI_EXP_DEVSTA_TRPND 0x20
49 #define DLB2_PCI_EXP_DEVCTL_BCR_FLR 0x8000
51 #define DLB2_PCI_CAP_ID_EXP 0x10
52 #define DLB2_PCI_CAP_ID_MSIX 0x11
53 #define DLB2_PCI_EXT_CAP_ID_PAS 0x1B
54 #define DLB2_PCI_EXT_CAP_ID_PRI 0x13
55 #define DLB2_PCI_EXT_CAP_ID_ACS 0xD
57 #define DLB2_PCI_PRI_CTRL_ENABLE 0x1
58 #define DLB2_PCI_PRI_ALLOC_REQ 0xC
59 #define DLB2_PCI_PRI_CTRL 0x4
60 #define DLB2_PCI_MSIX_FLAGS 0x2
61 #define DLB2_PCI_MSIX_FLAGS_ENABLE 0x8000
62 #define DLB2_PCI_MSIX_FLAGS_MASKALL 0x4000
63 #define DLB2_PCI_ERR_ROOT_STATUS 0x30
64 #define DLB2_PCI_ERR_COR_STATUS 0x10
65 #define DLB2_PCI_ERR_UNCOR_STATUS 0x4
66 #define DLB2_PCI_COMMAND_INTX_DISABLE 0x400
67 #define DLB2_PCI_ACS_CAP 0x4
68 #define DLB2_PCI_ACS_CTRL 0x6
69 #define DLB2_PCI_ACS_SV 0x1
70 #define DLB2_PCI_ACS_RR 0x4
71 #define DLB2_PCI_ACS_CR 0x8
72 #define DLB2_PCI_ACS_UF 0x10
73 #define DLB2_PCI_ACS_EC 0x20
75 /* Stubs: Allow building partial probe patch */
76 void dlb2_resource_free(struct dlb2_hw *hw)
81 int dlb2_resource_init(struct dlb2_hw *hw)
89 void dlb2_clr_pmcsr_disable(struct dlb2_hw *hw)
97 dlb2_pci_find_ext_capability(struct rte_pci_device *pdev, uint32_t id)
103 pos = DLB2_PCI_CFG_SPACE_SIZE;
107 if (rte_pci_read_config(pdev, &hdr, sz, pos) != (int)sz)
110 if (DLB2_PCI_EXT_CAP_ID(hdr) == id)
113 pos = DLB2_PCI_EXT_CAP_NEXT(hdr);
119 static int dlb2_pci_find_capability(struct rte_pci_device *pdev, uint32_t id)
125 ret = rte_pci_read_config(pdev, &pos, 1, DLB2_PCI_CAP_POINTER);
132 ret = rte_pci_read_config(pdev, &hdr, 2, pos);
136 if (DLB2_PCI_CAP_ID(hdr) == id)
139 if (DLB2_PCI_CAP_ID(hdr) == 0xFF)
142 pos = DLB2_PCI_CAP_NEXT(hdr);
149 dlb2_pf_init_driver_state(struct dlb2_dev *dlb2_dev)
151 rte_spinlock_init(&dlb2_dev->resource_mutex);
152 rte_spinlock_init(&dlb2_dev->measurement_lock);
157 static void dlb2_pf_enable_pm(struct dlb2_dev *dlb2_dev)
159 dlb2_clr_pmcsr_disable(&dlb2_dev->hw);
162 #define DLB2_READY_RETRY_LIMIT 1000
163 static int dlb2_pf_wait_for_device_ready(struct dlb2_dev *dlb2_dev)
167 /* Allow at least 1s for the device to become active after power-on */
168 for (retries = 0; retries < DLB2_READY_RETRY_LIMIT; retries++) {
169 union dlb2_cfg_mstr_cfg_diagnostic_idle_status idle;
170 union dlb2_cfg_mstr_cfg_pm_status pm_st;
173 addr = DLB2_CFG_MSTR_CFG_PM_STATUS;
174 pm_st.val = DLB2_CSR_RD(&dlb2_dev->hw, addr);
175 addr = DLB2_CFG_MSTR_CFG_DIAGNOSTIC_IDLE_STATUS;
176 idle.val = DLB2_CSR_RD(&dlb2_dev->hw, addr);
177 if (pm_st.field.pmsm == 1 && idle.field.dlb_func_idle == 1)
183 if (retries == DLB2_READY_RETRY_LIMIT) {
184 DLB2_LOG_ERR("[%s()] wait for device ready timed out\n",
193 dlb2_probe(struct rte_pci_device *pdev)
195 struct dlb2_dev *dlb2_dev;
198 DLB2_INFO(dlb2_dev, "probe\n");
200 dlb2_dev = rte_malloc("DLB2_PF", sizeof(struct dlb2_dev),
201 RTE_CACHE_LINE_SIZE);
203 if (dlb2_dev == NULL) {
205 goto dlb2_dev_malloc_fail;
208 /* PCI Bus driver has already mapped bar space into process.
209 * Save off our IO register and FUNC addresses.
213 if (pdev->mem_resource[0].addr == NULL) {
214 DLB2_ERR(dlb2_dev, "probe: BAR 0 addr (csr_kva) is NULL\n");
216 goto pci_mmap_bad_addr;
218 dlb2_dev->hw.func_kva = (void *)(uintptr_t)pdev->mem_resource[0].addr;
219 dlb2_dev->hw.func_phys_addr = pdev->mem_resource[0].phys_addr;
221 DLB2_INFO(dlb2_dev, "DLB2 FUNC VA=%p, PA=%p, len=%p\n",
222 (void *)dlb2_dev->hw.func_kva,
223 (void *)dlb2_dev->hw.func_phys_addr,
224 (void *)(pdev->mem_resource[0].len));
227 if (pdev->mem_resource[2].addr == NULL) {
228 DLB2_ERR(dlb2_dev, "probe: BAR 2 addr (func_kva) is NULL\n");
230 goto pci_mmap_bad_addr;
232 dlb2_dev->hw.csr_kva = (void *)(uintptr_t)pdev->mem_resource[2].addr;
233 dlb2_dev->hw.csr_phys_addr = pdev->mem_resource[2].phys_addr;
235 DLB2_INFO(dlb2_dev, "DLB2 CSR VA=%p, PA=%p, len=%p\n",
236 (void *)dlb2_dev->hw.csr_kva,
237 (void *)dlb2_dev->hw.csr_phys_addr,
238 (void *)(pdev->mem_resource[2].len));
240 dlb2_dev->pdev = pdev;
242 /* PM enable must be done before any other MMIO accesses, and this
243 * setting is persistent across device reset.
245 dlb2_pf_enable_pm(dlb2_dev);
247 ret = dlb2_pf_wait_for_device_ready(dlb2_dev);
249 goto wait_for_device_ready_fail;
251 ret = dlb2_pf_reset(dlb2_dev);
253 goto dlb2_reset_fail;
255 ret = dlb2_pf_init_driver_state(dlb2_dev);
257 goto init_driver_state_fail;
259 ret = dlb2_resource_init(&dlb2_dev->hw);
261 goto resource_init_fail;
266 dlb2_resource_free(&dlb2_dev->hw);
267 init_driver_state_fail:
270 wait_for_device_ready_fail:
272 dlb2_dev_malloc_fail:
278 dlb2_pf_reset(struct dlb2_dev *dlb2_dev)
286 uint16_t dev_ctl_word;
287 uint16_t dev_ctl2_word;
292 uint16_t rt_ctl_word;
293 uint32_t pri_reqs_dword;
294 uint16_t pri_ctrl_word;
303 uint16_t devsta_busy_word;
304 uint16_t devctl_word;
306 struct rte_pci_device *pdev = dlb2_dev->pdev;
308 /* Save PCI config state */
310 for (i = 0; i < 16; i++) {
311 if (rte_pci_read_config(pdev, &dword[i], 4, i * 4) != 4)
315 pcie_cap_offset = dlb2_pci_find_capability(pdev, DLB2_PCI_CAP_ID_EXP);
317 if (pcie_cap_offset < 0) {
318 DLB2_LOG_ERR("[%s()] failed to find the pcie capability\n",
320 return pcie_cap_offset;
323 off = pcie_cap_offset + DLB2_PCI_EXP_DEVCTL;
324 if (rte_pci_read_config(pdev, &dev_ctl_word, 2, off) != 2)
327 off = pcie_cap_offset + DLB2_PCI_LNKCTL;
328 if (rte_pci_read_config(pdev, &lnk_word, 2, off) != 2)
331 off = pcie_cap_offset + DLB2_PCI_SLTCTL;
332 if (rte_pci_read_config(pdev, &slt_word, 2, off) != 2)
335 off = pcie_cap_offset + DLB2_PCI_RTCTL;
336 if (rte_pci_read_config(pdev, &rt_ctl_word, 2, off) != 2)
339 off = pcie_cap_offset + DLB2_PCI_EXP_DEVCTL2;
340 if (rte_pci_read_config(pdev, &dev_ctl2_word, 2, off) != 2)
343 off = pcie_cap_offset + DLB2_PCI_LNKCTL2;
344 if (rte_pci_read_config(pdev, &lnk_word2, 2, off) != 2)
347 off = pcie_cap_offset + DLB2_PCI_SLTCTL2;
348 if (rte_pci_read_config(pdev, &slt_word2, 2, off) != 2)
351 off = DLB2_PCI_EXT_CAP_ID_PRI;
352 pri_cap_offset = dlb2_pci_find_ext_capability(pdev, off);
354 if (pri_cap_offset >= 0) {
355 off = pri_cap_offset + DLB2_PCI_PRI_ALLOC_REQ;
356 if (rte_pci_read_config(pdev, &pri_reqs_dword, 4, off) != 4)
360 /* clear the PCI command register before issuing the FLR */
364 if (rte_pci_write_config(pdev, &cmd, 2, off) != 2) {
365 DLB2_LOG_ERR("[%s()] failed to write the pci command\n",
371 for (wait_count = 0; wait_count < 4; wait_count++) {
374 off = pcie_cap_offset + DLB2_PCI_EXP_DEVSTA;
375 ret = rte_pci_read_config(pdev, &devsta_busy_word, 2, off);
377 DLB2_LOG_ERR("[%s()] failed to read the pci device status\n",
382 if (!(devsta_busy_word & DLB2_PCI_EXP_DEVSTA_TRPND))
385 sleep_time = (1 << (wait_count)) * 100;
386 rte_delay_ms(sleep_time);
389 if (wait_count == 4) {
390 DLB2_LOG_ERR("[%s()] wait for pci pending transactions timed out\n",
395 off = pcie_cap_offset + DLB2_PCI_EXP_DEVCTL;
396 ret = rte_pci_read_config(pdev, &devctl_word, 2, off);
398 DLB2_LOG_ERR("[%s()] failed to read the pcie device control\n",
403 devctl_word |= DLB2_PCI_EXP_DEVCTL_BCR_FLR;
405 ret = rte_pci_write_config(pdev, &devctl_word, 2, off);
407 DLB2_LOG_ERR("[%s()] failed to write the pcie device control\n",
414 /* Restore PCI config state */
416 if (pcie_cap_offset >= 0) {
417 off = pcie_cap_offset + DLB2_PCI_EXP_DEVCTL;
418 ret = rte_pci_write_config(pdev, &dev_ctl_word, 2, off);
420 DLB2_LOG_ERR("[%s()] failed to write the pcie device control at offset %d\n",
425 off = pcie_cap_offset + DLB2_PCI_LNKCTL;
426 ret = rte_pci_write_config(pdev, &lnk_word, 2, off);
428 DLB2_LOG_ERR("[%s()] failed to write the pcie config space at offset %d\n",
433 off = pcie_cap_offset + DLB2_PCI_SLTCTL;
434 ret = rte_pci_write_config(pdev, &slt_word, 2, off);
436 DLB2_LOG_ERR("[%s()] failed to write the pcie config space at offset %d\n",
441 off = pcie_cap_offset + DLB2_PCI_RTCTL;
442 ret = rte_pci_write_config(pdev, &rt_ctl_word, 2, off);
444 DLB2_LOG_ERR("[%s()] failed to write the pcie config space at offset %d\n",
449 off = pcie_cap_offset + DLB2_PCI_EXP_DEVCTL2;
450 ret = rte_pci_write_config(pdev, &dev_ctl2_word, 2, off);
452 DLB2_LOG_ERR("[%s()] failed to write the pcie config space at offset %d\n",
457 off = pcie_cap_offset + DLB2_PCI_LNKCTL2;
458 ret = rte_pci_write_config(pdev, &lnk_word2, 2, off);
460 DLB2_LOG_ERR("[%s()] failed to write the pcie config space at offset %d\n",
465 off = pcie_cap_offset + DLB2_PCI_SLTCTL2;
466 ret = rte_pci_write_config(pdev, &slt_word2, 2, off);
468 DLB2_LOG_ERR("[%s()] failed to write the pcie config space at offset %d\n",
474 if (pri_cap_offset >= 0) {
475 pri_ctrl_word = DLB2_PCI_PRI_CTRL_ENABLE;
477 off = pri_cap_offset + DLB2_PCI_PRI_ALLOC_REQ;
478 ret = rte_pci_write_config(pdev, &pri_reqs_dword, 4, off);
480 DLB2_LOG_ERR("[%s()] failed to write the pcie config space at offset %d\n",
485 off = pri_cap_offset + DLB2_PCI_PRI_CTRL;
486 ret = rte_pci_write_config(pdev, &pri_ctrl_word, 2, off);
488 DLB2_LOG_ERR("[%s()] failed to write the pcie config space at offset %d\n",
494 off = DLB2_PCI_EXT_CAP_ID_ERR;
495 err_cap_offset = dlb2_pci_find_ext_capability(pdev, off);
497 if (err_cap_offset >= 0) {
500 off = err_cap_offset + DLB2_PCI_ERR_ROOT_STATUS;
501 if (rte_pci_read_config(pdev, &tmp, 4, off) != 4)
504 ret = rte_pci_write_config(pdev, &tmp, 4, off);
506 DLB2_LOG_ERR("[%s()] failed to write the pcie config space at offset %d\n",
511 off = err_cap_offset + DLB2_PCI_ERR_COR_STATUS;
512 if (rte_pci_read_config(pdev, &tmp, 4, off) != 4)
515 ret = rte_pci_write_config(pdev, &tmp, 4, off);
517 DLB2_LOG_ERR("[%s()] failed to write the pcie config space at offset %d\n",
522 off = err_cap_offset + DLB2_PCI_ERR_UNCOR_STATUS;
523 if (rte_pci_read_config(pdev, &tmp, 4, off) != 4)
526 ret = rte_pci_write_config(pdev, &tmp, 4, off);
528 DLB2_LOG_ERR("[%s()] failed to write the pcie config space at offset %d\n",
534 for (i = 16; i > 0; i--) {
536 ret = rte_pci_write_config(pdev, &dword[i - 1], 4, off);
538 DLB2_LOG_ERR("[%s()] failed to write the pcie config space at offset %d\n",
545 if (rte_pci_read_config(pdev, &cmd, 2, off) == 2) {
546 cmd &= ~DLB2_PCI_COMMAND_INTX_DISABLE;
547 if (rte_pci_write_config(pdev, &cmd, 2, off) != 2) {
548 DLB2_LOG_ERR("[%s()] failed to write the pci command\n",
554 msix_cap_offset = dlb2_pci_find_capability(pdev,
555 DLB2_PCI_CAP_ID_MSIX);
556 if (msix_cap_offset >= 0) {
557 off = msix_cap_offset + DLB2_PCI_MSIX_FLAGS;
558 if (rte_pci_read_config(pdev, &cmd, 2, off) == 2) {
559 cmd |= DLB2_PCI_MSIX_FLAGS_ENABLE;
560 cmd |= DLB2_PCI_MSIX_FLAGS_MASKALL;
561 if (rte_pci_write_config(pdev, &cmd, 2, off) != 2) {
562 DLB2_LOG_ERR("[%s()] failed to write msix flags\n",
568 off = msix_cap_offset + DLB2_PCI_MSIX_FLAGS;
569 if (rte_pci_read_config(pdev, &cmd, 2, off) == 2) {
570 cmd &= ~DLB2_PCI_MSIX_FLAGS_MASKALL;
571 if (rte_pci_write_config(pdev, &cmd, 2, off) != 2) {
572 DLB2_LOG_ERR("[%s()] failed to write msix flags\n",
579 off = DLB2_PCI_EXT_CAP_ID_ACS;
580 acs_cap_offset = dlb2_pci_find_ext_capability(pdev, off);
582 if (acs_cap_offset >= 0) {
583 uint16_t acs_cap, acs_ctrl, acs_mask;
584 off = acs_cap_offset + DLB2_PCI_ACS_CAP;
585 if (rte_pci_read_config(pdev, &acs_cap, 2, off) != 2)
588 off = acs_cap_offset + DLB2_PCI_ACS_CTRL;
589 if (rte_pci_read_config(pdev, &acs_ctrl, 2, off) != 2)
592 acs_mask = DLB2_PCI_ACS_SV | DLB2_PCI_ACS_RR;
593 acs_mask |= (DLB2_PCI_ACS_CR | DLB2_PCI_ACS_UF);
594 acs_ctrl |= (acs_cap & acs_mask);
596 ret = rte_pci_write_config(pdev, &acs_ctrl, 2, off);
598 DLB2_LOG_ERR("[%s()] failed to write the pcie config space at offset %d\n",
603 off = acs_cap_offset + DLB2_PCI_ACS_CTRL;
604 if (rte_pci_read_config(pdev, &acs_ctrl, 2, off) != 2)
607 acs_mask = DLB2_PCI_ACS_RR | DLB2_PCI_ACS_CR;
608 acs_mask |= DLB2_PCI_ACS_EC;
609 acs_ctrl &= ~acs_mask;
611 off = acs_cap_offset + DLB2_PCI_ACS_CTRL;
612 ret = rte_pci_write_config(pdev, &acs_ctrl, 2, off);
614 DLB2_LOG_ERR("[%s()] failed to write the pcie config space at offset %d\n",