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