1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 Intel Corporation */
3 /* $FreeBSD$ */
4 #include <dev/pci/pcireg.h>
5 #include "adf_c4xxx_reset.h"
6
7 static void
8 adf_check_uncorr_status(struct adf_accel_dev *accel_dev)
9 {
10 u32 uncorr_err;
11 device_t pdev = accel_dev->accel_pci_dev.pci_dev;
12
13 uncorr_err = pci_read_config(pdev, PCI_EXP_AERUCS, 4);
14 if (uncorr_err & PCIE_C4XXX_VALID_ERR_MASK) {
15 device_printf(GET_DEV(accel_dev),
16 "Uncorrectable error occurred during reset\n");
17 device_printf(GET_DEV(accel_dev),
18 "Error code value: 0x%04x\n",
19 uncorr_err);
20 }
21 }
22
23 static void
24 adf_c4xxx_dev_reset(struct adf_accel_dev *accel_dev)
25 {
26 device_t pdev = accel_dev->accel_pci_dev.pci_dev;
27 struct adf_hw_device_data *hw_device = accel_dev->hw_device;
28 u8 count = 0;
29 uintptr_t device_id1;
30 uintptr_t device_id2;
31
32 /* Read device ID before triggering reset */
33 device_id1 = pci_read_config(pdev, PCIR_DEVICE, 2);
34 hw_device->reset_device(accel_dev);
35
36 /* Wait for reset to complete */
37 do {
38 /* Ensure we have the configuration space restored */
39 device_id2 = pci_read_config(pdev, PCIR_DEVICE, 2);
40 if (device_id1 == device_id2) {
41 /* Check if a PCIe uncorrectable error occurred
42 * during the reset
43 */
44 adf_check_uncorr_status(accel_dev);
45 return;
46 }
47 count++;
48 pause_ms("adfstop", 100);
49 } while (count < ADF_PCIE_FLR_ATTEMPT);
50 device_printf(GET_DEV(accel_dev),
51 "Too many attempts to read back config space.\n");
52 }
53
54 void
55 adf_c4xxx_dev_restore(struct adf_accel_dev *accel_dev)
56 {
57 struct adf_hw_device_data *hw_device = accel_dev->hw_device;
58 device_t pdev = accel_dev->accel_pci_dev.pci_dev;
59 u32 pmisclbar1;
60 u32 pmisclbar2;
61 u32 pmiscubar1;
62 u32 pmiscubar2;
63
64 if (hw_device->reset_device) {
65 device_printf(GET_DEV(accel_dev),
66 "Resetting device qat_dev%d\n",
67 accel_dev->accel_id);
68
69 /* Read pmiscubar and pmisclbar */
70 pmisclbar1 = pci_read_config(pdev, ADF_PMISC_L_OFFSET, 4);
71 pmiscubar1 = pci_read_config(pdev, ADF_PMISC_U_OFFSET, 4);
72
73 adf_c4xxx_dev_reset(accel_dev);
74 pci_restore_state(pdev);
75
76 /* Read pmiscubar and pmisclbar */
77 pmisclbar2 = pci_read_config(pdev, ADF_PMISC_L_OFFSET, 4);
78 pmiscubar2 = pci_read_config(pdev, ADF_PMISC_U_OFFSET, 4);
79
80 /* Check if restore operation has completed successfully */
81 if (pmisclbar1 != pmisclbar2 || pmiscubar1 != pmiscubar2) {
82 device_printf(
83 GET_DEV(accel_dev),
84 "Failed to restore device configuration\n");
85 return;
86 }
87 pci_save_state(pdev);
88 }
89
90 if (hw_device->post_reset) {
91 dev_dbg(GET_DEV(accel_dev), "Performing post reset restore\n");
92 hw_device->post_reset(accel_dev);
93 }
94 }
Cache object: 73b9fb8a167e37a5533626ae1522a4a1
|