crypto: qat - Use alternative reset methods depending on the specific device
Different product families will use FLR or SBR. Virtual Function devices have no reset method. Signed-off-by: Conor McLoughlin <conor.mcloughlin@intel.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Родитель
8d63a6d53b
Коммит
e24860f2a6
|
@ -229,6 +229,7 @@ void adf_init_hw_data_c3xxx(struct adf_hw_device_data *hw_data)
|
|||
hw_data->get_arb_mapping = adf_get_arbiter_mapping;
|
||||
hw_data->enable_ints = adf_enable_ints;
|
||||
hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms;
|
||||
hw_data->reset_device = adf_reset_flr;
|
||||
hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION;
|
||||
}
|
||||
|
||||
|
|
|
@ -239,6 +239,7 @@ void adf_init_hw_data_c62x(struct adf_hw_device_data *hw_data)
|
|||
hw_data->get_arb_mapping = adf_get_arbiter_mapping;
|
||||
hw_data->enable_ints = adf_enable_ints;
|
||||
hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms;
|
||||
hw_data->reset_device = adf_reset_flr;
|
||||
hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION;
|
||||
}
|
||||
|
||||
|
|
|
@ -176,6 +176,7 @@ struct adf_hw_device_data {
|
|||
void (*disable_iov)(struct adf_accel_dev *accel_dev);
|
||||
void (*enable_ints)(struct adf_accel_dev *accel_dev);
|
||||
int (*enable_vf2pf_comms)(struct adf_accel_dev *accel_dev);
|
||||
void (*reset_device)(struct adf_accel_dev *accel_dev);
|
||||
const char *fw_name;
|
||||
const char *fw_mmp_name;
|
||||
uint32_t fuses;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -141,6 +141,8 @@ int adf_ae_stop(struct adf_accel_dev *accel_dev);
|
|||
|
||||
int adf_enable_aer(struct adf_accel_dev *accel_dev, struct pci_driver *adf);
|
||||
void adf_disable_aer(struct adf_accel_dev *accel_dev);
|
||||
void adf_reset_sbr(struct adf_accel_dev *accel_dev);
|
||||
void adf_reset_flr(struct adf_accel_dev *accel_dev);
|
||||
void adf_dev_restore(struct adf_accel_dev *accel_dev);
|
||||
int adf_init_aer(void);
|
||||
void adf_exit_aer(void);
|
||||
|
|
|
@ -252,6 +252,7 @@ void adf_init_hw_data_dh895xcc(struct adf_hw_device_data *hw_data)
|
|||
hw_data->get_arb_mapping = adf_get_arbiter_mapping;
|
||||
hw_data->enable_ints = adf_enable_ints;
|
||||
hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms;
|
||||
hw_data->reset_device = adf_reset_sbr;
|
||||
hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче