Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Conor McLoughlin and committed by
Herbert Xu
e24860f2 8d63a6d5

+43 -9
+1
drivers/crypto/qat/qat_c3xxx/adf_c3xxx_hw_data.c
··· 229 229 hw_data->get_arb_mapping = adf_get_arbiter_mapping; 230 230 hw_data->enable_ints = adf_enable_ints; 231 231 hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms; 232 + hw_data->reset_device = adf_reset_flr; 232 233 hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION; 233 234 } 234 235
+1
drivers/crypto/qat/qat_c62x/adf_c62x_hw_data.c
··· 239 239 hw_data->get_arb_mapping = adf_get_arbiter_mapping; 240 240 hw_data->enable_ints = adf_enable_ints; 241 241 hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms; 242 + hw_data->reset_device = adf_reset_flr; 242 243 hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION; 243 244 } 244 245
+1
drivers/crypto/qat/qat_common/adf_accel_devices.h
··· 176 176 void (*disable_iov)(struct adf_accel_dev *accel_dev); 177 177 void (*enable_ints)(struct adf_accel_dev *accel_dev); 178 178 int (*enable_vf2pf_comms)(struct adf_accel_dev *accel_dev); 179 + void (*reset_device)(struct adf_accel_dev *accel_dev); 179 180 const char *fw_name; 180 181 const char *fw_mmp_name; 181 182 uint32_t fuses;
+37 -9
drivers/crypto/qat/qat_common/adf_aer.c
··· 82 82 struct work_struct reset_work; 83 83 }; 84 84 85 - void adf_dev_restore(struct adf_accel_dev *accel_dev) 85 + void adf_reset_sbr(struct adf_accel_dev *accel_dev) 86 86 { 87 87 struct pci_dev *pdev = accel_to_pci_dev(accel_dev); 88 88 struct pci_dev *parent = pdev->bus->self; 89 89 uint16_t bridge_ctl = 0; 90 - 91 - if (accel_dev->is_vf) 92 - return; 93 - 94 - dev_info(&GET_DEV(accel_dev), "Resetting device qat_dev%d\n", 95 - accel_dev->accel_id); 96 90 97 91 if (!parent) 98 92 parent = pdev; ··· 95 101 dev_info(&GET_DEV(accel_dev), 96 102 "Transaction still in progress. Proceeding\n"); 97 103 104 + dev_info(&GET_DEV(accel_dev), "Secondary bus reset\n"); 105 + 98 106 pci_read_config_word(parent, PCI_BRIDGE_CONTROL, &bridge_ctl); 99 107 bridge_ctl |= PCI_BRIDGE_CTL_BUS_RESET; 100 108 pci_write_config_word(parent, PCI_BRIDGE_CONTROL, bridge_ctl); ··· 104 108 bridge_ctl &= ~PCI_BRIDGE_CTL_BUS_RESET; 105 109 pci_write_config_word(parent, PCI_BRIDGE_CONTROL, bridge_ctl); 106 110 msleep(100); 107 - pci_restore_state(pdev); 108 - pci_save_state(pdev); 111 + } 112 + EXPORT_SYMBOL_GPL(adf_reset_sbr); 113 + 114 + void adf_reset_flr(struct adf_accel_dev *accel_dev) 115 + { 116 + struct pci_dev *pdev = accel_to_pci_dev(accel_dev); 117 + u16 control = 0; 118 + int pos = 0; 119 + 120 + dev_info(&GET_DEV(accel_dev), "Function level reset\n"); 121 + pos = pci_pcie_cap(pdev); 122 + if (!pos) { 123 + dev_err(&GET_DEV(accel_dev), "Restart device failed\n"); 124 + return; 125 + } 126 + pci_read_config_word(pdev, pos + PCI_EXP_DEVCTL, &control); 127 + control |= PCI_EXP_DEVCTL_BCR_FLR; 128 + pci_write_config_word(pdev, pos + PCI_EXP_DEVCTL, control); 129 + msleep(100); 130 + } 131 + EXPORT_SYMBOL_GPL(adf_reset_flr); 132 + 133 + void adf_dev_restore(struct adf_accel_dev *accel_dev) 134 + { 135 + struct adf_hw_device_data *hw_device = accel_dev->hw_device; 136 + struct pci_dev *pdev = accel_to_pci_dev(accel_dev); 137 + 138 + if (hw_device->reset_device) { 139 + dev_info(&GET_DEV(accel_dev), "Resetting device qat_dev%d\n", 140 + accel_dev->accel_id); 141 + hw_device->reset_device(accel_dev); 142 + pci_restore_state(pdev); 143 + pci_save_state(pdev); 144 + } 109 145 } 110 146 111 147 static void adf_device_reset_worker(struct work_struct *work)
+2
drivers/crypto/qat/qat_common/adf_common_drv.h
··· 141 141 142 142 int adf_enable_aer(struct adf_accel_dev *accel_dev, struct pci_driver *adf); 143 143 void adf_disable_aer(struct adf_accel_dev *accel_dev); 144 + void adf_reset_sbr(struct adf_accel_dev *accel_dev); 145 + void adf_reset_flr(struct adf_accel_dev *accel_dev); 144 146 void adf_dev_restore(struct adf_accel_dev *accel_dev); 145 147 int adf_init_aer(void); 146 148 void adf_exit_aer(void);
+1
drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c
··· 252 252 hw_data->get_arb_mapping = adf_get_arbiter_mapping; 253 253 hw_data->enable_ints = adf_enable_ints; 254 254 hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms; 255 + hw_data->reset_device = adf_reset_sbr; 255 256 hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION; 256 257 } 257 258