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>hifive-unleashed-5.1
parent
8d63a6d53b
commit
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->get_arb_mapping = adf_get_arbiter_mapping;
|
||||||
hw_data->enable_ints = adf_enable_ints;
|
hw_data->enable_ints = adf_enable_ints;
|
||||||
hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms;
|
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;
|
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->get_arb_mapping = adf_get_arbiter_mapping;
|
||||||
hw_data->enable_ints = adf_enable_ints;
|
hw_data->enable_ints = adf_enable_ints;
|
||||||
hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms;
|
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;
|
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 (*disable_iov)(struct adf_accel_dev *accel_dev);
|
||||||
void (*enable_ints)(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);
|
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_name;
|
||||||
const char *fw_mmp_name;
|
const char *fw_mmp_name;
|
||||||
uint32_t fuses;
|
uint32_t fuses;
|
||||||
|
|
|
@ -82,18 +82,12 @@ struct adf_reset_dev_data {
|
||||||
struct work_struct reset_work;
|
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 *pdev = accel_to_pci_dev(accel_dev);
|
||||||
struct pci_dev *parent = pdev->bus->self;
|
struct pci_dev *parent = pdev->bus->self;
|
||||||
uint16_t bridge_ctl = 0;
|
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)
|
if (!parent)
|
||||||
parent = pdev;
|
parent = pdev;
|
||||||
|
|
||||||
|
@ -101,6 +95,8 @@ void adf_dev_restore(struct adf_accel_dev *accel_dev)
|
||||||
dev_info(&GET_DEV(accel_dev),
|
dev_info(&GET_DEV(accel_dev),
|
||||||
"Transaction still in progress. Proceeding\n");
|
"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);
|
pci_read_config_word(parent, PCI_BRIDGE_CONTROL, &bridge_ctl);
|
||||||
bridge_ctl |= PCI_BRIDGE_CTL_BUS_RESET;
|
bridge_ctl |= PCI_BRIDGE_CTL_BUS_RESET;
|
||||||
pci_write_config_word(parent, PCI_BRIDGE_CONTROL, bridge_ctl);
|
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;
|
bridge_ctl &= ~PCI_BRIDGE_CTL_BUS_RESET;
|
||||||
pci_write_config_word(parent, PCI_BRIDGE_CONTROL, bridge_ctl);
|
pci_write_config_word(parent, PCI_BRIDGE_CONTROL, bridge_ctl);
|
||||||
msleep(100);
|
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)
|
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);
|
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_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);
|
void adf_dev_restore(struct adf_accel_dev *accel_dev);
|
||||||
int adf_init_aer(void);
|
int adf_init_aer(void);
|
||||||
void adf_exit_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->get_arb_mapping = adf_get_arbiter_mapping;
|
||||||
hw_data->enable_ints = adf_enable_ints;
|
hw_data->enable_ints = adf_enable_ints;
|
||||||
hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms;
|
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;
|
hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue