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