Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e24860f2 authored by Conor McLoughlin's avatar Conor McLoughlin Committed by Herbert Xu
Browse files

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: default avatarConor McLoughlin <conor.mcloughlin@intel.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 8d63a6d5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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;
}

+1 −0
Original line number Diff line number Diff line
@@ -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;
}

+1 −0
Original line number Diff line number Diff line
@@ -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;
+37 −9
Original line number Diff line number Diff line
@@ -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,9 +104,41 @@ 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);
}
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)
{
+2 −0
Original line number Diff line number Diff line
@@ -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);
Loading