diff options
author | Dave Jiang <dave.jiang@intel.com> | 2014-08-28 16:53:18 -0400 |
---|---|---|
committer | Jon Mason <jdmason@kudzu.us> | 2014-10-17 07:08:51 -0400 |
commit | 069684e888da73f175da0f10fe26da4f450d8c18 (patch) | |
tree | 1942ceebcd12b321e20a5372fd039343c6b233e4 | |
parent | 1db97f258966878317ece10868eaca99201d5884 (diff) |
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: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Jon Mason <jdmason@kudzu.us>
-rw-r--r-- | drivers/ntb/ntb_hw.c | 47 | ||||
-rw-r--r-- | drivers/ntb/ntb_hw.h | 4 |
2 files changed, 42 insertions, 9 deletions
diff --git a/drivers/ntb/ntb_hw.c b/drivers/ntb/ntb_hw.c index 6f1c92182f35..53b739df8cd5 100644 --- a/drivers/ntb/ntb_hw.c +++ b/drivers/ntb/ntb_hw.c | |||
@@ -64,10 +64,6 @@ MODULE_VERSION(NTB_VER); | |||
64 | MODULE_LICENSE("Dual BSD/GPL"); | 64 | MODULE_LICENSE("Dual BSD/GPL"); |
65 | MODULE_AUTHOR("Intel Corporation"); | 65 | MODULE_AUTHOR("Intel Corporation"); |
66 | 66 | ||
67 | static bool xeon_errata_workaround = true; | ||
68 | module_param(xeon_errata_workaround, bool, 0644); | ||
69 | MODULE_PARM_DESC(xeon_errata_workaround, "Workaround for the Xeon Errata"); | ||
70 | |||
71 | enum { | 67 | enum { |
72 | NTB_CONN_TRANSPARENT = 0, | 68 | NTB_CONN_TRANSPARENT = 0, |
73 | NTB_CONN_B2B, | 69 | NTB_CONN_B2B, |
@@ -144,6 +140,30 @@ static int is_ntb_atom(struct ntb_device *ndev) | |||
144 | return 0; | 140 | return 0; |
145 | } | 141 | } |
146 | 142 | ||
143 | static void ntb_set_errata_flags(struct ntb_device *ndev) | ||
144 | { | ||
145 | switch (ndev->pdev->device) { | ||
146 | /* | ||
147 | * this workaround applies to all platform up to IvyBridge | ||
148 | * Haswell has splitbar support and use a different workaround | ||
149 | */ | ||
150 | case PCI_DEVICE_ID_INTEL_NTB_SS_JSF: | ||
151 | case PCI_DEVICE_ID_INTEL_NTB_SS_SNB: | ||
152 | case PCI_DEVICE_ID_INTEL_NTB_SS_IVT: | ||
153 | case PCI_DEVICE_ID_INTEL_NTB_SS_HSX: | ||
154 | case PCI_DEVICE_ID_INTEL_NTB_PS_JSF: | ||
155 | case PCI_DEVICE_ID_INTEL_NTB_PS_SNB: | ||
156 | case PCI_DEVICE_ID_INTEL_NTB_PS_IVT: | ||
157 | case PCI_DEVICE_ID_INTEL_NTB_PS_HSX: | ||
158 | case PCI_DEVICE_ID_INTEL_NTB_B2B_JSF: | ||
159 | case PCI_DEVICE_ID_INTEL_NTB_B2B_SNB: | ||
160 | case PCI_DEVICE_ID_INTEL_NTB_B2B_IVT: | ||
161 | case PCI_DEVICE_ID_INTEL_NTB_B2B_HSX: | ||
162 | ndev->wa_flags |= WA_SNB_ERR; | ||
163 | break; | ||
164 | } | ||
165 | } | ||
166 | |||
147 | /** | 167 | /** |
148 | * ntb_register_event_callback() - register event callback | 168 | * ntb_register_event_callback() - register event callback |
149 | * @ndev: pointer to ntb_device instance | 169 | * @ndev: pointer to ntb_device instance |
@@ -717,7 +737,7 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
717 | * this use the second memory window to access the interrupt and | 737 | * this use the second memory window to access the interrupt and |
718 | * scratch pad registers on the remote system. | 738 | * scratch pad registers on the remote system. |
719 | */ | 739 | */ |
720 | if (xeon_errata_workaround) { | 740 | if (ndev->wa_flags & WA_SNB_ERR) { |
721 | if (!ndev->mw[1].bar_sz) | 741 | if (!ndev->mw[1].bar_sz) |
722 | return -EINVAL; | 742 | return -EINVAL; |
723 | 743 | ||
@@ -772,7 +792,7 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
772 | if (ndev->dev_type == NTB_DEV_USD) { | 792 | if (ndev->dev_type == NTB_DEV_USD) { |
773 | writeq(SNB_MBAR23_DSD_ADDR, ndev->reg_base + | 793 | writeq(SNB_MBAR23_DSD_ADDR, ndev->reg_base + |
774 | SNB_PBAR2XLAT_OFFSET); | 794 | SNB_PBAR2XLAT_OFFSET); |
775 | if (xeon_errata_workaround) | 795 | if (ndev->wa_flags & WA_SNB_ERR) |
776 | writeq(SNB_MBAR01_DSD_ADDR, ndev->reg_base + | 796 | writeq(SNB_MBAR01_DSD_ADDR, ndev->reg_base + |
777 | SNB_PBAR4XLAT_OFFSET); | 797 | SNB_PBAR4XLAT_OFFSET); |
778 | else { | 798 | else { |
@@ -796,7 +816,7 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
796 | } else { | 816 | } else { |
797 | writeq(SNB_MBAR23_USD_ADDR, ndev->reg_base + | 817 | writeq(SNB_MBAR23_USD_ADDR, ndev->reg_base + |
798 | SNB_PBAR2XLAT_OFFSET); | 818 | SNB_PBAR2XLAT_OFFSET); |
799 | if (xeon_errata_workaround) | 819 | if (ndev->wa_flags & WA_SNB_ERR) |
800 | writeq(SNB_MBAR01_USD_ADDR, ndev->reg_base + | 820 | writeq(SNB_MBAR01_USD_ADDR, ndev->reg_base + |
801 | SNB_PBAR4XLAT_OFFSET); | 821 | SNB_PBAR4XLAT_OFFSET); |
802 | else { | 822 | else { |
@@ -819,9 +839,9 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
819 | } | 839 | } |
820 | break; | 840 | break; |
821 | case NTB_CONN_RP: | 841 | case NTB_CONN_RP: |
822 | if (xeon_errata_workaround) { | 842 | if (ndev->wa_flags & WA_SNB_ERR) { |
823 | dev_err(&ndev->pdev->dev, | 843 | dev_err(&ndev->pdev->dev, |
824 | "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"); | 844 | "NTB-RP disabled due to hardware errata.\n"); |
825 | return -EINVAL; | 845 | return -EINVAL; |
826 | } | 846 | } |
827 | 847 | ||
@@ -848,6 +868,12 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
848 | ndev->limits.max_mw = SNB_MAX_MW; | 868 | ndev->limits.max_mw = SNB_MAX_MW; |
849 | break; | 869 | break; |
850 | case NTB_CONN_TRANSPARENT: | 870 | case NTB_CONN_TRANSPARENT: |
871 | if (ndev->wa_flags & WA_SNB_ERR) { | ||
872 | dev_err(&ndev->pdev->dev, | ||
873 | "NTB-TRANSPARENT disabled due to hardware errata.\n"); | ||
874 | return -EINVAL; | ||
875 | } | ||
876 | |||
851 | /* Scratch pads need to have exclusive access from the primary | 877 | /* Scratch pads need to have exclusive access from the primary |
852 | * or secondary side. Halve the num spads so that each side can | 878 | * or secondary side. Halve the num spads so that each side can |
853 | * have an equal amount. | 879 | * have an equal amount. |
@@ -1595,6 +1621,9 @@ static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1595 | return -ENOMEM; | 1621 | return -ENOMEM; |
1596 | 1622 | ||
1597 | ndev->pdev = pdev; | 1623 | ndev->pdev = pdev; |
1624 | |||
1625 | ntb_set_errata_flags(ndev); | ||
1626 | |||
1598 | ndev->link_status = NTB_LINK_DOWN; | 1627 | ndev->link_status = NTB_LINK_DOWN; |
1599 | pci_set_drvdata(pdev, ndev); | 1628 | pci_set_drvdata(pdev, ndev); |
1600 | ntb_setup_debugfs(ndev); | 1629 | ntb_setup_debugfs(ndev); |
diff --git a/drivers/ntb/ntb_hw.h b/drivers/ntb/ntb_hw.h index ddbcbfda0f49..5380ca16198a 100644 --- a/drivers/ntb/ntb_hw.h +++ b/drivers/ntb/ntb_hw.h | |||
@@ -109,6 +109,8 @@ struct ntb_db_cb { | |||
109 | struct tasklet_struct irq_work; | 109 | struct tasklet_struct irq_work; |
110 | }; | 110 | }; |
111 | 111 | ||
112 | #define WA_SNB_ERR 0x00000001 | ||
113 | |||
112 | struct ntb_device { | 114 | struct ntb_device { |
113 | struct pci_dev *pdev; | 115 | struct pci_dev *pdev; |
114 | struct msix_entry *msix_entries; | 116 | struct msix_entry *msix_entries; |
@@ -153,6 +155,8 @@ struct ntb_device { | |||
153 | 155 | ||
154 | struct dentry *debugfs_dir; | 156 | struct dentry *debugfs_dir; |
155 | struct dentry *debugfs_info; | 157 | struct dentry *debugfs_info; |
158 | |||
159 | unsigned int wa_flags; | ||
156 | }; | 160 | }; |
157 | 161 | ||
158 | /** | 162 | /** |