|
@@ -82,18 +82,12 @@ struct adf_reset_dev_data {
|
|
|
struct work_struct reset_work;
|
|
|
};
|
|
|
|
|
|
-void adf_dev_restore(struct adf_accel_dev *accel_dev)
|
|
|
+void adf_reset_sbr(struct adf_accel_dev *accel_dev)
|
|
|
{
|
|
|
struct pci_dev *pdev = accel_to_pci_dev(accel_dev);
|
|
|
struct pci_dev *parent = pdev->bus->self;
|
|
|
uint16_t bridge_ctl = 0;
|
|
|
|
|
|
- if (accel_dev->is_vf)
|
|
|
- return;
|
|
|
-
|
|
|
- dev_info(&GET_DEV(accel_dev), "Resetting device qat_dev%d\n",
|
|
|
- accel_dev->accel_id);
|
|
|
-
|
|
|
if (!parent)
|
|
|
parent = pdev;
|
|
|
|
|
@@ -101,6 +95,8 @@ void adf_dev_restore(struct adf_accel_dev *accel_dev)
|
|
|
dev_info(&GET_DEV(accel_dev),
|
|
|
"Transaction still in progress. Proceeding\n");
|
|
|
|
|
|
+ dev_info(&GET_DEV(accel_dev), "Secondary bus reset\n");
|
|
|
+
|
|
|
pci_read_config_word(parent, PCI_BRIDGE_CONTROL, &bridge_ctl);
|
|
|
bridge_ctl |= PCI_BRIDGE_CTL_BUS_RESET;
|
|
|
pci_write_config_word(parent, PCI_BRIDGE_CONTROL, bridge_ctl);
|
|
@@ -108,8 +104,40 @@ void adf_dev_restore(struct adf_accel_dev *accel_dev)
|
|
|
bridge_ctl &= ~PCI_BRIDGE_CTL_BUS_RESET;
|
|
|
pci_write_config_word(parent, PCI_BRIDGE_CONTROL, bridge_ctl);
|
|
|
msleep(100);
|
|
|
- pci_restore_state(pdev);
|
|
|
- pci_save_state(pdev);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(adf_reset_sbr);
|
|
|
+
|
|
|
+void adf_reset_flr(struct adf_accel_dev *accel_dev)
|
|
|
+{
|
|
|
+ struct pci_dev *pdev = accel_to_pci_dev(accel_dev);
|
|
|
+ u16 control = 0;
|
|
|
+ int pos = 0;
|
|
|
+
|
|
|
+ dev_info(&GET_DEV(accel_dev), "Function level reset\n");
|
|
|
+ pos = pci_pcie_cap(pdev);
|
|
|
+ if (!pos) {
|
|
|
+ dev_err(&GET_DEV(accel_dev), "Restart device failed\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ pci_read_config_word(pdev, pos + PCI_EXP_DEVCTL, &control);
|
|
|
+ control |= PCI_EXP_DEVCTL_BCR_FLR;
|
|
|
+ pci_write_config_word(pdev, pos + PCI_EXP_DEVCTL, control);
|
|
|
+ msleep(100);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(adf_reset_flr);
|
|
|
+
|
|
|
+void adf_dev_restore(struct adf_accel_dev *accel_dev)
|
|
|
+{
|
|
|
+ struct adf_hw_device_data *hw_device = accel_dev->hw_device;
|
|
|
+ struct pci_dev *pdev = accel_to_pci_dev(accel_dev);
|
|
|
+
|
|
|
+ if (hw_device->reset_device) {
|
|
|
+ dev_info(&GET_DEV(accel_dev), "Resetting device qat_dev%d\n",
|
|
|
+ accel_dev->accel_id);
|
|
|
+ hw_device->reset_device(accel_dev);
|
|
|
+ pci_restore_state(pdev);
|
|
|
+ pci_save_state(pdev);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static void adf_device_reset_worker(struct work_struct *work)
|