aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCasey Leedom <leedom@chelsio.com>2013-08-06 06:18:37 -0400
committerBjorn Helgaas <bhelgaas@google.com>2013-08-12 15:58:14 -0400
commit2c6217e0fc5f6c7458f413346806061d97ce37cf (patch)
tree1a7a54f2758feeba2a0466e76e0c636420b1310c
parent3775a209d38aa3a0c7ed89a7d0f529e0230f280e (diff)
PCI: Chelsio quirk: Enable Bus Master during Function-Level Reset
T4 can wedge if there are DMAs in flight within the chip and Bus Master has been disabled. We need to have it on till the Function Level Reset completes. T4 can also suffer a Head Of Line blocking problem if MSI-X interrupts are disabled before the FLR has completed. Signed-off-by: Casey Leedom <leedom@chelsio.com> Signed-off-by: Vipul Pandya <vipul@chelsio.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r--drivers/pci/quirks.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index e85d23044ae0..8f075a3cd805 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3208,6 +3208,83 @@ reset_complete:
3208 return 0; 3208 return 0;
3209} 3209}
3210 3210
3211/*
3212 * Device-specific reset method for Chelsio T4-based adapters.
3213 */
3214static int reset_chelsio_generic_dev(struct pci_dev *dev, int probe)
3215{
3216 u16 old_command;
3217 u16 msix_flags;
3218
3219 /*
3220 * If this isn't a Chelsio T4-based device, return -ENOTTY indicating
3221 * that we have no device-specific reset method.
3222 */
3223 if ((dev->device & 0xf000) != 0x4000)
3224 return -ENOTTY;
3225
3226 /*
3227 * If this is the "probe" phase, return 0 indicating that we can
3228 * reset this device.
3229 */
3230 if (probe)
3231 return 0;
3232
3233 /*
3234 * T4 can wedge if there are DMAs in flight within the chip and Bus
3235 * Master has been disabled. We need to have it on till the Function
3236 * Level Reset completes. (BUS_MASTER is disabled in
3237 * pci_reset_function()).
3238 */
3239 pci_read_config_word(dev, PCI_COMMAND, &old_command);
3240 pci_write_config_word(dev, PCI_COMMAND,
3241 old_command | PCI_COMMAND_MASTER);
3242
3243 /*
3244 * Perform the actual device function reset, saving and restoring
3245 * configuration information around the reset.
3246 */
3247 pci_save_state(dev);
3248
3249 /*
3250 * T4 also suffers a Head-Of-Line blocking problem if MSI-X interrupts
3251 * are disabled when an MSI-X interrupt message needs to be delivered.
3252 * So we briefly re-enable MSI-X interrupts for the duration of the
3253 * FLR. The pci_restore_state() below will restore the original
3254 * MSI-X state.
3255 */
3256 pci_read_config_word(dev, dev->msix_cap+PCI_MSIX_FLAGS, &msix_flags);
3257 if ((msix_flags & PCI_MSIX_FLAGS_ENABLE) == 0)
3258 pci_write_config_word(dev, dev->msix_cap+PCI_MSIX_FLAGS,
3259 msix_flags |
3260 PCI_MSIX_FLAGS_ENABLE |
3261 PCI_MSIX_FLAGS_MASKALL);
3262
3263 /*
3264 * Start of pcie_flr() code sequence. This reset code is a copy of
3265 * the guts of pcie_flr() because that's not an exported function.
3266 */
3267
3268 if (!pci_wait_for_pending_transaction(dev))
3269 dev_err(&dev->dev, "transaction is not cleared; proceeding with reset anyway\n");
3270
3271 pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
3272 msleep(100);
3273
3274 /*
3275 * End of pcie_flr() code sequence.
3276 */
3277
3278 /*
3279 * Restore the configuration information (BAR values, etc.) including
3280 * the original PCI Configuration Space Command word, and return
3281 * success.
3282 */
3283 pci_restore_state(dev);
3284 pci_write_config_word(dev, PCI_COMMAND, old_command);
3285 return 0;
3286}
3287
3211#define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed 3288#define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed
3212#define PCI_DEVICE_ID_INTEL_IVB_M_VGA 0x0156 3289#define PCI_DEVICE_ID_INTEL_IVB_M_VGA 0x0156
3213#define PCI_DEVICE_ID_INTEL_IVB_M2_VGA 0x0166 3290#define PCI_DEVICE_ID_INTEL_IVB_M2_VGA 0x0166
@@ -3221,6 +3298,8 @@ static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
3221 reset_ivb_igd }, 3298 reset_ivb_igd },
3222 { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, 3299 { PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
3223 reset_intel_generic_dev }, 3300 reset_intel_generic_dev },
3301 { PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID,
3302 reset_chelsio_generic_dev },
3224 { 0 } 3303 { 0 }
3225}; 3304};
3226 3305