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 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 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 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