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