Commit 069684e8 authored by Dave Jiang's avatar Dave Jiang Committed by Jon Mason

ntb: use errata flag set via DID to implement workaround

Instead of using a module parameter, we should detect the errata via
PCI DID and then set an appropriate flag. This will be used for additional
errata later on.
Signed-off-by: default avatarDave Jiang <dave.jiang@intel.com>
Signed-off-by: default avatarJon Mason <jdmason@kudzu.us>
parent 1db97f25
...@@ -64,10 +64,6 @@ MODULE_VERSION(NTB_VER); ...@@ -64,10 +64,6 @@ MODULE_VERSION(NTB_VER);
MODULE_LICENSE("Dual BSD/GPL"); MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Intel Corporation"); MODULE_AUTHOR("Intel Corporation");
static bool xeon_errata_workaround = true;
module_param(xeon_errata_workaround, bool, 0644);
MODULE_PARM_DESC(xeon_errata_workaround, "Workaround for the Xeon Errata");
enum { enum {
NTB_CONN_TRANSPARENT = 0, NTB_CONN_TRANSPARENT = 0,
NTB_CONN_B2B, NTB_CONN_B2B,
...@@ -144,6 +140,30 @@ static int is_ntb_atom(struct ntb_device *ndev) ...@@ -144,6 +140,30 @@ static int is_ntb_atom(struct ntb_device *ndev)
return 0; return 0;
} }
static void ntb_set_errata_flags(struct ntb_device *ndev)
{
switch (ndev->pdev->device) {
/*
* this workaround applies to all platform up to IvyBridge
* Haswell has splitbar support and use a different workaround
*/
case PCI_DEVICE_ID_INTEL_NTB_SS_JSF:
case PCI_DEVICE_ID_INTEL_NTB_SS_SNB:
case PCI_DEVICE_ID_INTEL_NTB_SS_IVT:
case PCI_DEVICE_ID_INTEL_NTB_SS_HSX:
case PCI_DEVICE_ID_INTEL_NTB_PS_JSF:
case PCI_DEVICE_ID_INTEL_NTB_PS_SNB:
case PCI_DEVICE_ID_INTEL_NTB_PS_IVT:
case PCI_DEVICE_ID_INTEL_NTB_PS_HSX:
case PCI_DEVICE_ID_INTEL_NTB_B2B_JSF:
case PCI_DEVICE_ID_INTEL_NTB_B2B_SNB:
case PCI_DEVICE_ID_INTEL_NTB_B2B_IVT:
case PCI_DEVICE_ID_INTEL_NTB_B2B_HSX:
ndev->wa_flags |= WA_SNB_ERR;
break;
}
}
/** /**
* ntb_register_event_callback() - register event callback * ntb_register_event_callback() - register event callback
* @ndev: pointer to ntb_device instance * @ndev: pointer to ntb_device instance
...@@ -717,7 +737,7 @@ static int ntb_xeon_setup(struct ntb_device *ndev) ...@@ -717,7 +737,7 @@ static int ntb_xeon_setup(struct ntb_device *ndev)
* this use the second memory window to access the interrupt and * this use the second memory window to access the interrupt and
* scratch pad registers on the remote system. * scratch pad registers on the remote system.
*/ */
if (xeon_errata_workaround) { if (ndev->wa_flags & WA_SNB_ERR) {
if (!ndev->mw[1].bar_sz) if (!ndev->mw[1].bar_sz)
return -EINVAL; return -EINVAL;
...@@ -772,7 +792,7 @@ static int ntb_xeon_setup(struct ntb_device *ndev) ...@@ -772,7 +792,7 @@ static int ntb_xeon_setup(struct ntb_device *ndev)
if (ndev->dev_type == NTB_DEV_USD) { if (ndev->dev_type == NTB_DEV_USD) {
writeq(SNB_MBAR23_DSD_ADDR, ndev->reg_base + writeq(SNB_MBAR23_DSD_ADDR, ndev->reg_base +
SNB_PBAR2XLAT_OFFSET); SNB_PBAR2XLAT_OFFSET);
if (xeon_errata_workaround) if (ndev->wa_flags & WA_SNB_ERR)
writeq(SNB_MBAR01_DSD_ADDR, ndev->reg_base + writeq(SNB_MBAR01_DSD_ADDR, ndev->reg_base +
SNB_PBAR4XLAT_OFFSET); SNB_PBAR4XLAT_OFFSET);
else { else {
...@@ -796,7 +816,7 @@ static int ntb_xeon_setup(struct ntb_device *ndev) ...@@ -796,7 +816,7 @@ static int ntb_xeon_setup(struct ntb_device *ndev)
} else { } else {
writeq(SNB_MBAR23_USD_ADDR, ndev->reg_base + writeq(SNB_MBAR23_USD_ADDR, ndev->reg_base +
SNB_PBAR2XLAT_OFFSET); SNB_PBAR2XLAT_OFFSET);
if (xeon_errata_workaround) if (ndev->wa_flags & WA_SNB_ERR)
writeq(SNB_MBAR01_USD_ADDR, ndev->reg_base + writeq(SNB_MBAR01_USD_ADDR, ndev->reg_base +
SNB_PBAR4XLAT_OFFSET); SNB_PBAR4XLAT_OFFSET);
else { else {
...@@ -819,9 +839,9 @@ static int ntb_xeon_setup(struct ntb_device *ndev) ...@@ -819,9 +839,9 @@ static int ntb_xeon_setup(struct ntb_device *ndev)
} }
break; break;
case NTB_CONN_RP: case NTB_CONN_RP:
if (xeon_errata_workaround) { if (ndev->wa_flags & WA_SNB_ERR) {
dev_err(&ndev->pdev->dev, dev_err(&ndev->pdev->dev,
"NTB-RP disabled due to hardware errata. To disregard this warning and potentially lock-up the system, add the parameter 'xeon_errata_workaround=0'.\n"); "NTB-RP disabled due to hardware errata.\n");
return -EINVAL; return -EINVAL;
} }
...@@ -848,6 +868,12 @@ static int ntb_xeon_setup(struct ntb_device *ndev) ...@@ -848,6 +868,12 @@ static int ntb_xeon_setup(struct ntb_device *ndev)
ndev->limits.max_mw = SNB_MAX_MW; ndev->limits.max_mw = SNB_MAX_MW;
break; break;
case NTB_CONN_TRANSPARENT: case NTB_CONN_TRANSPARENT:
if (ndev->wa_flags & WA_SNB_ERR) {
dev_err(&ndev->pdev->dev,
"NTB-TRANSPARENT disabled due to hardware errata.\n");
return -EINVAL;
}
/* Scratch pads need to have exclusive access from the primary /* Scratch pads need to have exclusive access from the primary
* or secondary side. Halve the num spads so that each side can * or secondary side. Halve the num spads so that each side can
* have an equal amount. * have an equal amount.
...@@ -1595,6 +1621,9 @@ static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1595,6 +1621,9 @@ static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return -ENOMEM; return -ENOMEM;
ndev->pdev = pdev; ndev->pdev = pdev;
ntb_set_errata_flags(ndev);
ndev->link_status = NTB_LINK_DOWN; ndev->link_status = NTB_LINK_DOWN;
pci_set_drvdata(pdev, ndev); pci_set_drvdata(pdev, ndev);
ntb_setup_debugfs(ndev); ntb_setup_debugfs(ndev);
......
...@@ -109,6 +109,8 @@ struct ntb_db_cb { ...@@ -109,6 +109,8 @@ struct ntb_db_cb {
struct tasklet_struct irq_work; struct tasklet_struct irq_work;
}; };
#define WA_SNB_ERR 0x00000001
struct ntb_device { struct ntb_device {
struct pci_dev *pdev; struct pci_dev *pdev;
struct msix_entry *msix_entries; struct msix_entry *msix_entries;
...@@ -153,6 +155,8 @@ struct ntb_device { ...@@ -153,6 +155,8 @@ struct ntb_device {
struct dentry *debugfs_dir; struct dentry *debugfs_dir;
struct dentry *debugfs_info; struct dentry *debugfs_info;
unsigned int wa_flags;
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment