aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Mason <jon.mason@intel.com>2013-04-18 20:07:36 -0400
committerJon Mason <jon.mason@intel.com>2013-09-03 16:51:51 -0400
commit948d3a65b6d164b34309625f57656cb9e8b1a908 (patch)
tree01afe66a33f978552f0577eb478d801e8e6a6284
parent1517a3f21a1dd321f16bcf44204bddff9d21abd0 (diff)
NTB: Xeon Errata Workaround
There is a Xeon hardware errata related to writes to SDOORBELL or B2BDOORBELL in conjunction with inbound access to NTB MMIO Space, which may hang the system. To workaround this issue, use one of the memory windows to access the interrupt and scratch pad registers on the remote system. This bypasses the issue, but removes one of the memory windows from use by the transport. This reduction of MWs necessitates adding some logic to determine the number of available MWs. Since some NTB usage methodologies may have unidirectional traffic, the ability to disable the workaround via modparm has been added. See BF113 in http://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/xeon-c5500-c3500-spec-update.pdf See BT119 in http://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/xeon-e5-family-spec-update.pdf Signed-off-by: Jon Mason <jon.mason@intel.com>
-rw-r--r--drivers/ntb/ntb_hw.c109
-rw-r--r--drivers/ntb/ntb_hw.h39
-rw-r--r--drivers/ntb/ntb_regs.h25
-rw-r--r--drivers/ntb/ntb_transport.c78
4 files changed, 193 insertions, 58 deletions
diff --git a/drivers/ntb/ntb_hw.c b/drivers/ntb/ntb_hw.c
index b9bf8b551e3c..226f82b7da65 100644
--- a/drivers/ntb/ntb_hw.c
+++ b/drivers/ntb/ntb_hw.c
@@ -62,6 +62,10 @@ MODULE_VERSION(NTB_VER);
62MODULE_LICENSE("Dual BSD/GPL"); 62MODULE_LICENSE("Dual BSD/GPL");
63MODULE_AUTHOR("Intel Corporation"); 63MODULE_AUTHOR("Intel Corporation");
64 64
65static bool xeon_errata_workaround = true;
66module_param(xeon_errata_workaround, bool, 0644);
67MODULE_PARM_DESC(xeon_errata_workaround, "Workaround for the Xeon Errata");
68
65enum { 69enum {
66 NTB_CONN_CLASSIC = 0, 70 NTB_CONN_CLASSIC = 0,
67 NTB_CONN_B2B, 71 NTB_CONN_B2B,
@@ -81,7 +85,7 @@ enum {
81static struct dentry *debugfs_dir; 85static struct dentry *debugfs_dir;
82 86
83/* Translate memory window 0,1 to BAR 2,4 */ 87/* Translate memory window 0,1 to BAR 2,4 */
84#define MW_TO_BAR(mw) (mw * 2 + 2) 88#define MW_TO_BAR(mw) (mw * NTB_MAX_NUM_MW + 2)
85 89
86static DEFINE_PCI_DEVICE_TABLE(ntb_pci_tbl) = { 90static DEFINE_PCI_DEVICE_TABLE(ntb_pci_tbl) = {
87 {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_BWD)}, 91 {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_BWD)},
@@ -347,7 +351,7 @@ int ntb_read_remote_spad(struct ntb_device *ndev, unsigned int idx, u32 *val)
347 */ 351 */
348void __iomem *ntb_get_mw_vbase(struct ntb_device *ndev, unsigned int mw) 352void __iomem *ntb_get_mw_vbase(struct ntb_device *ndev, unsigned int mw)
349{ 353{
350 if (mw >= NTB_NUM_MW) 354 if (mw >= ntb_max_mw(ndev))
351 return NULL; 355 return NULL;
352 356
353 return ndev->mw[mw].vbase; 357 return ndev->mw[mw].vbase;
@@ -364,7 +368,7 @@ void __iomem *ntb_get_mw_vbase(struct ntb_device *ndev, unsigned int mw)
364 */ 368 */
365resource_size_t ntb_get_mw_size(struct ntb_device *ndev, unsigned int mw) 369resource_size_t ntb_get_mw_size(struct ntb_device *ndev, unsigned int mw)
366{ 370{
367 if (mw >= NTB_NUM_MW) 371 if (mw >= ntb_max_mw(ndev))
368 return 0; 372 return 0;
369 373
370 return ndev->mw[mw].bar_sz; 374 return ndev->mw[mw].bar_sz;
@@ -382,7 +386,7 @@ resource_size_t ntb_get_mw_size(struct ntb_device *ndev, unsigned int mw)
382 */ 386 */
383void ntb_set_mw_addr(struct ntb_device *ndev, unsigned int mw, u64 addr) 387void ntb_set_mw_addr(struct ntb_device *ndev, unsigned int mw, u64 addr)
384{ 388{
385 if (mw >= NTB_NUM_MW) 389 if (mw >= ntb_max_mw(ndev))
386 return; 390 return;
387 391
388 dev_dbg(&ndev->pdev->dev, "Writing addr %Lx to BAR %d\n", addr, 392 dev_dbg(&ndev->pdev->dev, "Writing addr %Lx to BAR %d\n", addr,
@@ -546,16 +550,94 @@ static int ntb_xeon_setup(struct ntb_device *ndev)
546 ndev->reg_ofs.spad_read = ndev->reg_base + SNB_SPAD_OFFSET; 550 ndev->reg_ofs.spad_read = ndev->reg_base + SNB_SPAD_OFFSET;
547 ndev->reg_ofs.spci_cmd = ndev->reg_base + SNB_PCICMD_OFFSET; 551 ndev->reg_ofs.spci_cmd = ndev->reg_base + SNB_PCICMD_OFFSET;
548 552
549 if (ndev->conn_type == NTB_CONN_B2B) { 553 /* There is a Xeon hardware errata related to writes to
550 ndev->reg_ofs.sdb = ndev->reg_base + SNB_B2B_DOORBELL_OFFSET; 554 * SDOORBELL or B2BDOORBELL in conjunction with inbound access
551 ndev->reg_ofs.spad_write = ndev->reg_base + SNB_B2B_SPAD_OFFSET; 555 * to NTB MMIO Space, which may hang the system. To workaround
552 ndev->limits.max_spads = SNB_MAX_B2B_SPADS; 556 * this use the second memory window to access the interrupt and
557 * scratch pad registers on the remote system.
558 */
559 if (xeon_errata_workaround) {
560 if (!ndev->mw[1].bar_sz)
561 return -EINVAL;
562
563 ndev->limits.max_mw = SNB_ERRATA_MAX_MW;
564 ndev->reg_ofs.spad_write = ndev->mw[1].vbase +
565 SNB_SPAD_OFFSET;
566 ndev->reg_ofs.sdb = ndev->mw[1].vbase +
567 SNB_PDOORBELL_OFFSET;
568
569 /* Set the Limit register to 4k, the minimum size, to
570 * prevent an illegal access
571 */
572 writeq(ndev->mw[1].bar_sz + 0x1000, ndev->reg_base +
573 SNB_PBAR4LMT_OFFSET);
574 } else {
575 ndev->limits.max_mw = SNB_MAX_MW;
576 ndev->reg_ofs.spad_write = ndev->reg_base +
577 SNB_B2B_SPAD_OFFSET;
578 ndev->reg_ofs.sdb = ndev->reg_base +
579 SNB_B2B_DOORBELL_OFFSET;
580
581 /* Disable the Limit register, just incase it is set to
582 * something silly
583 */
584 writeq(0, ndev->reg_base + SNB_PBAR4LMT_OFFSET);
585 }
586
587 /* The Xeon errata workaround requires setting SBAR Base
588 * addresses to known values, so that the PBAR XLAT can be
589 * pointed at SBAR0 of the remote system.
590 */
591 if (ndev->dev_type == NTB_DEV_USD) {
592 writeq(SNB_MBAR23_DSD_ADDR, ndev->reg_base +
593 SNB_PBAR2XLAT_OFFSET);
594 if (xeon_errata_workaround)
595 writeq(SNB_MBAR01_DSD_ADDR, ndev->reg_base +
596 SNB_PBAR4XLAT_OFFSET);
597 else {
598 writeq(SNB_MBAR45_DSD_ADDR, ndev->reg_base +
599 SNB_PBAR4XLAT_OFFSET);
600 /* B2B_XLAT_OFFSET is a 64bit register, but can
601 * only take 32bit writes
602 */
603 writel(SNB_MBAR01_USD_ADDR & 0xffffffff,
604 ndev->reg_base + SNB_B2B_XLAT_OFFSETL);
605 writel(SNB_MBAR01_DSD_ADDR >> 32,
606 ndev->reg_base + SNB_B2B_XLAT_OFFSETU);
607 }
608
609 writeq(SNB_MBAR01_USD_ADDR, ndev->reg_base +
610 SNB_SBAR0BASE_OFFSET);
611 writeq(SNB_MBAR23_USD_ADDR, ndev->reg_base +
612 SNB_SBAR2BASE_OFFSET);
613 writeq(SNB_MBAR45_USD_ADDR, ndev->reg_base +
614 SNB_SBAR4BASE_OFFSET);
553 } else { 615 } else {
554 ndev->reg_ofs.sdb = ndev->reg_base + SNB_SDOORBELL_OFFSET; 616 writeq(SNB_MBAR23_USD_ADDR, ndev->reg_base +
555 ndev->reg_ofs.spad_write = ndev->reg_base + SNB_SPAD_OFFSET; 617 SNB_PBAR2XLAT_OFFSET);
556 ndev->limits.max_spads = SNB_MAX_COMPAT_SPADS; 618 if (xeon_errata_workaround)
619 writeq(SNB_MBAR01_USD_ADDR, ndev->reg_base +
620 SNB_PBAR4XLAT_OFFSET);
621 else {
622 writeq(SNB_MBAR45_USD_ADDR, ndev->reg_base +
623 SNB_PBAR4XLAT_OFFSET);
624 /* B2B_XLAT_OFFSET is a 64bit register, but can
625 * only take 32bit writes
626 */
627 writel(SNB_MBAR01_USD_ADDR & 0xffffffff,
628 ndev->reg_base + SNB_B2B_XLAT_OFFSETL);
629 writel(SNB_MBAR01_USD_ADDR >> 32,
630 ndev->reg_base + SNB_B2B_XLAT_OFFSETU);
631 }
632 writeq(SNB_MBAR01_DSD_ADDR, ndev->reg_base +
633 SNB_SBAR0BASE_OFFSET);
634 writeq(SNB_MBAR23_DSD_ADDR, ndev->reg_base +
635 SNB_SBAR2BASE_OFFSET);
636 writeq(SNB_MBAR45_DSD_ADDR, ndev->reg_base +
637 SNB_SBAR4BASE_OFFSET);
557 } 638 }
558 639
640 ndev->limits.max_spads = SNB_MAX_B2B_SPADS;
559 ndev->limits.max_db_bits = SNB_MAX_DB_BITS; 641 ndev->limits.max_db_bits = SNB_MAX_DB_BITS;
560 ndev->limits.msix_cnt = SNB_MSIX_CNT; 642 ndev->limits.msix_cnt = SNB_MSIX_CNT;
561 ndev->bits_per_vector = SNB_DB_BITS_PER_VEC; 643 ndev->bits_per_vector = SNB_DB_BITS_PER_VEC;
@@ -614,6 +696,7 @@ static int ntb_bwd_setup(struct ntb_device *ndev)
614 ndev->limits.max_spads = BWD_MAX_COMPAT_SPADS; 696 ndev->limits.max_spads = BWD_MAX_COMPAT_SPADS;
615 } 697 }
616 698
699 ndev->limits.max_mw = BWD_MAX_MW;
617 ndev->limits.max_db_bits = BWD_MAX_DB_BITS; 700 ndev->limits.max_db_bits = BWD_MAX_DB_BITS;
618 ndev->limits.msix_cnt = BWD_MSIX_CNT; 701 ndev->limits.msix_cnt = BWD_MSIX_CNT;
619 ndev->bits_per_vector = BWD_DB_BITS_PER_VEC; 702 ndev->bits_per_vector = BWD_DB_BITS_PER_VEC;
@@ -1053,7 +1136,7 @@ static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1053 goto err2; 1136 goto err2;
1054 } 1137 }
1055 1138
1056 for (i = 0; i < NTB_NUM_MW; i++) { 1139 for (i = 0; i < NTB_MAX_NUM_MW; i++) {
1057 ndev->mw[i].bar_sz = pci_resource_len(pdev, MW_TO_BAR(i)); 1140 ndev->mw[i].bar_sz = pci_resource_len(pdev, MW_TO_BAR(i));
1058 ndev->mw[i].vbase = 1141 ndev->mw[i].vbase =
1059 ioremap_wc(pci_resource_start(pdev, MW_TO_BAR(i)), 1142 ioremap_wc(pci_resource_start(pdev, MW_TO_BAR(i)),
@@ -1155,7 +1238,7 @@ static void ntb_pci_remove(struct pci_dev *pdev)
1155 ntb_free_callbacks(ndev); 1238 ntb_free_callbacks(ndev);
1156 ntb_device_free(ndev); 1239 ntb_device_free(ndev);
1157 1240
1158 for (i = 0; i < NTB_NUM_MW; i++) 1241 for (i = 0; i < NTB_MAX_NUM_MW; i++)
1159 iounmap(ndev->mw[i].vbase); 1242 iounmap(ndev->mw[i].vbase);
1160 1243
1161 iounmap(ndev->reg_base); 1244 iounmap(ndev->reg_base);
diff --git a/drivers/ntb/ntb_hw.h b/drivers/ntb/ntb_hw.h
index 6a4f56f564ee..72fcb22d7dd8 100644
--- a/drivers/ntb/ntb_hw.h
+++ b/drivers/ntb/ntb_hw.h
@@ -68,7 +68,7 @@
68 68
69#define NTB_HB_TIMEOUT msecs_to_jiffies(1000) 69#define NTB_HB_TIMEOUT msecs_to_jiffies(1000)
70 70
71#define NTB_NUM_MW 2 71#define NTB_MAX_NUM_MW 2
72 72
73enum ntb_hw_event { 73enum ntb_hw_event {
74 NTB_EVENT_SW_EVENT0 = 0, 74 NTB_EVENT_SW_EVENT0 = 0,
@@ -96,11 +96,12 @@ struct ntb_device {
96 struct pci_dev *pdev; 96 struct pci_dev *pdev;
97 struct msix_entry *msix_entries; 97 struct msix_entry *msix_entries;
98 void __iomem *reg_base; 98 void __iomem *reg_base;
99 struct ntb_mw mw[NTB_NUM_MW]; 99 struct ntb_mw mw[NTB_MAX_NUM_MW];
100 struct { 100 struct {
101 unsigned int max_spads; 101 unsigned char max_mw;
102 unsigned int max_db_bits; 102 unsigned char max_spads;
103 unsigned int msix_cnt; 103 unsigned char max_db_bits;
104 unsigned char msix_cnt;
104 } limits; 105 } limits;
105 struct { 106 struct {
106 void __iomem *pdb; 107 void __iomem *pdb;
@@ -132,6 +133,32 @@ struct ntb_device {
132}; 133};
133 134
134/** 135/**
136 * ntb_max_cbs() - return the max callbacks
137 * @ndev: pointer to ntb_device instance
138 *
139 * Given the ntb pointer, return the maximum number of callbacks
140 *
141 * RETURNS: the maximum number of callbacks
142 */
143static inline unsigned char ntb_max_cbs(struct ntb_device *ndev)
144{
145 return ndev->max_cbs;
146}
147
148/**
149 * ntb_max_mw() - return the max number of memory windows
150 * @ndev: pointer to ntb_device instance
151 *
152 * Given the ntb pointer, return the maximum number of memory windows
153 *
154 * RETURNS: the maximum number of memory windows
155 */
156static inline unsigned char ntb_max_mw(struct ntb_device *ndev)
157{
158 return ndev->limits.max_mw;
159}
160
161/**
135 * ntb_hw_link_status() - return the hardware link status 162 * ntb_hw_link_status() - return the hardware link status
136 * @ndev: pointer to ntb_device instance 163 * @ndev: pointer to ntb_device instance
137 * 164 *
@@ -148,7 +175,7 @@ static inline bool ntb_hw_link_status(struct ntb_device *ndev)
148 * ntb_query_pdev() - return the pci_dev pointer 175 * ntb_query_pdev() - return the pci_dev pointer
149 * @ndev: pointer to ntb_device instance 176 * @ndev: pointer to ntb_device instance
150 * 177 *
151 * Given the ntb pointer return the pci_dev pointerfor the NTB hardware device 178 * Given the ntb pointer, return the pci_dev pointer for the NTB hardware device
152 * 179 *
153 * RETURNS: a pointer to the ntb pci_dev 180 * RETURNS: a pointer to the ntb pci_dev
154 */ 181 */
diff --git a/drivers/ntb/ntb_regs.h b/drivers/ntb/ntb_regs.h
index 96209b4abc22..4ddc590d03a6 100644
--- a/drivers/ntb/ntb_regs.h
+++ b/drivers/ntb/ntb_regs.h
@@ -58,6 +58,8 @@
58/* Reserve the uppermost bit for link interrupt */ 58/* Reserve the uppermost bit for link interrupt */
59#define SNB_MAX_DB_BITS 15 59#define SNB_MAX_DB_BITS 15
60#define SNB_DB_BITS_PER_VEC 5 60#define SNB_DB_BITS_PER_VEC 5
61#define SNB_MAX_MW 2
62#define SNB_ERRATA_MAX_MW 1
61 63
62#define SNB_DB_HW_LINK 0x8000 64#define SNB_DB_HW_LINK 0x8000
63 65
@@ -74,6 +76,9 @@
74#define SNB_SBAR2XLAT_OFFSET 0x0030 76#define SNB_SBAR2XLAT_OFFSET 0x0030
75#define SNB_SBAR4XLAT_OFFSET 0x0038 77#define SNB_SBAR4XLAT_OFFSET 0x0038
76#define SNB_SBAR0BASE_OFFSET 0x0040 78#define SNB_SBAR0BASE_OFFSET 0x0040
79#define SNB_SBAR0BASE_OFFSET 0x0040
80#define SNB_SBAR2BASE_OFFSET 0x0048
81#define SNB_SBAR4BASE_OFFSET 0x0050
77#define SNB_SBAR2BASE_OFFSET 0x0048 82#define SNB_SBAR2BASE_OFFSET 0x0048
78#define SNB_SBAR4BASE_OFFSET 0x0050 83#define SNB_SBAR4BASE_OFFSET 0x0050
79#define SNB_NTBCNTL_OFFSET 0x0058 84#define SNB_NTBCNTL_OFFSET 0x0058
@@ -88,13 +93,22 @@
88#define SNB_WCCNTRL_OFFSET 0x00e0 93#define SNB_WCCNTRL_OFFSET 0x00e0
89#define SNB_B2B_SPAD_OFFSET 0x0100 94#define SNB_B2B_SPAD_OFFSET 0x0100
90#define SNB_B2B_DOORBELL_OFFSET 0x0140 95#define SNB_B2B_DOORBELL_OFFSET 0x0140
91#define SNB_B2B_XLAT_OFFSET 0x0144 96#define SNB_B2B_XLAT_OFFSETL 0x0144
97#define SNB_B2B_XLAT_OFFSETU 0x0148
98
99#define SNB_MBAR01_USD_ADDR 0x000000210000000CULL
100#define SNB_MBAR23_USD_ADDR 0x000000410000000CULL
101#define SNB_MBAR45_USD_ADDR 0x000000810000000CULL
102#define SNB_MBAR01_DSD_ADDR 0x000000200000000CULL
103#define SNB_MBAR23_DSD_ADDR 0x000000400000000CULL
104#define SNB_MBAR45_DSD_ADDR 0x000000800000000CULL
92 105
93#define BWD_MSIX_CNT 34 106#define BWD_MSIX_CNT 34
94#define BWD_MAX_SPADS 16 107#define BWD_MAX_SPADS 16
95#define BWD_MAX_COMPAT_SPADS 16 108#define BWD_MAX_COMPAT_SPADS 16
96#define BWD_MAX_DB_BITS 34 109#define BWD_MAX_DB_BITS 34
97#define BWD_DB_BITS_PER_VEC 1 110#define BWD_DB_BITS_PER_VEC 1
111#define BWD_MAX_MW 2
98 112
99#define BWD_PCICMD_OFFSET 0xb004 113#define BWD_PCICMD_OFFSET 0xb004
100#define BWD_MBAR23_OFFSET 0xb018 114#define BWD_MBAR23_OFFSET 0xb018
@@ -128,12 +142,3 @@
128#define BWD_PPD_INIT_LINK 0x0008 142#define BWD_PPD_INIT_LINK 0x0008
129#define BWD_PPD_CONN_TYPE 0x0300 143#define BWD_PPD_CONN_TYPE 0x0300
130#define BWD_PPD_DEV_TYPE 0x1000 144#define BWD_PPD_DEV_TYPE 0x1000
131
132#define BWD_PBAR2XLAT_USD_ADDR 0x0000004000000000
133#define BWD_PBAR4XLAT_USD_ADDR 0x0000008000000000
134#define BWD_MBAR23_USD_ADDR 0x000000410000000C
135#define BWD_MBAR45_USD_ADDR 0x000000810000000C
136#define BWD_PBAR2XLAT_DSD_ADDR 0x0000004100000000
137#define BWD_PBAR4XLAT_DSD_ADDR 0x0000008100000000
138#define BWD_MBAR23_DSD_ADDR 0x000000400000000C
139#define BWD_MBAR45_DSD_ADDR 0x000000800000000C
diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c
index c3089151aa49..f7380e959656 100644
--- a/drivers/ntb/ntb_transport.c
+++ b/drivers/ntb/ntb_transport.c
@@ -64,7 +64,7 @@ static unsigned int transport_mtu = 0x401E;
64module_param(transport_mtu, uint, 0644); 64module_param(transport_mtu, uint, 0644);
65MODULE_PARM_DESC(transport_mtu, "Maximum size of NTB transport packets"); 65MODULE_PARM_DESC(transport_mtu, "Maximum size of NTB transport packets");
66 66
67static unsigned char max_num_clients = 2; 67static unsigned char max_num_clients;
68module_param(max_num_clients, byte, 0644); 68module_param(max_num_clients, byte, 0644);
69MODULE_PARM_DESC(max_num_clients, "Maximum number of NTB transport clients"); 69MODULE_PARM_DESC(max_num_clients, "Maximum number of NTB transport clients");
70 70
@@ -150,7 +150,7 @@ struct ntb_transport {
150 struct list_head client_devs; 150 struct list_head client_devs;
151 151
152 struct ntb_device *ndev; 152 struct ntb_device *ndev;
153 struct ntb_transport_mw mw[NTB_NUM_MW]; 153 struct ntb_transport_mw *mw;
154 struct ntb_transport_qp *qps; 154 struct ntb_transport_qp *qps;
155 unsigned int max_qps; 155 unsigned int max_qps;
156 unsigned long qp_bitmap; 156 unsigned long qp_bitmap;
@@ -182,7 +182,7 @@ enum {
182 MAX_SPAD, 182 MAX_SPAD,
183}; 183};
184 184
185#define QP_TO_MW(qp) ((qp) % NTB_NUM_MW) 185#define QP_TO_MW(ndev, qp) ((qp) % ntb_max_mw(ndev))
186#define NTB_QP_DEF_NUM_ENTRIES 100 186#define NTB_QP_DEF_NUM_ENTRIES 100
187#define NTB_LINK_DOWN_TIMEOUT 10 187#define NTB_LINK_DOWN_TIMEOUT 10
188 188
@@ -474,19 +474,22 @@ static void ntb_transport_setup_qp_mw(struct ntb_transport *nt,
474{ 474{
475 struct ntb_transport_qp *qp = &nt->qps[qp_num]; 475 struct ntb_transport_qp *qp = &nt->qps[qp_num];
476 unsigned int rx_size, num_qps_mw; 476 unsigned int rx_size, num_qps_mw;
477 u8 mw_num = QP_TO_MW(qp_num); 477 u8 mw_num, mw_max;
478 unsigned int i; 478 unsigned int i;
479 479
480 mw_max = ntb_max_mw(nt->ndev);
481 mw_num = QP_TO_MW(nt->ndev, qp_num);
482
480 WARN_ON(nt->mw[mw_num].virt_addr == NULL); 483 WARN_ON(nt->mw[mw_num].virt_addr == NULL);
481 484
482 if (nt->max_qps % NTB_NUM_MW && mw_num < nt->max_qps % NTB_NUM_MW) 485 if (nt->max_qps % mw_max && mw_num < nt->max_qps % mw_max)
483 num_qps_mw = nt->max_qps / NTB_NUM_MW + 1; 486 num_qps_mw = nt->max_qps / mw_max + 1;
484 else 487 else
485 num_qps_mw = nt->max_qps / NTB_NUM_MW; 488 num_qps_mw = nt->max_qps / mw_max;
486 489
487 rx_size = (unsigned int) nt->mw[mw_num].size / num_qps_mw; 490 rx_size = (unsigned int) nt->mw[mw_num].size / num_qps_mw;
488 qp->remote_rx_info = nt->mw[mw_num].virt_addr + 491 qp->remote_rx_info = nt->mw[mw_num].virt_addr +
489 (qp_num / NTB_NUM_MW * rx_size); 492 (qp_num / mw_max * rx_size);
490 rx_size -= sizeof(struct ntb_rx_info); 493 rx_size -= sizeof(struct ntb_rx_info);
491 494
492 qp->rx_buff = qp->remote_rx_info + 1; 495 qp->rx_buff = qp->remote_rx_info + 1;
@@ -630,7 +633,7 @@ static void ntb_transport_link_work(struct work_struct *work)
630 int rc, i; 633 int rc, i;
631 634
632 /* send the local info, in the opposite order of the way we read it */ 635 /* send the local info, in the opposite order of the way we read it */
633 for (i = 0; i < NTB_NUM_MW; i++) { 636 for (i = 0; i < ntb_max_mw(ndev); i++) {
634 rc = ntb_write_remote_spad(ndev, MW0_SZ_HIGH + (i * 2), 637 rc = ntb_write_remote_spad(ndev, MW0_SZ_HIGH + (i * 2),
635 ntb_get_mw_size(ndev, i) >> 32); 638 ntb_get_mw_size(ndev, i) >> 32);
636 if (rc) { 639 if (rc) {
@@ -650,10 +653,10 @@ static void ntb_transport_link_work(struct work_struct *work)
650 } 653 }
651 } 654 }
652 655
653 rc = ntb_write_remote_spad(ndev, NUM_MWS, NTB_NUM_MW); 656 rc = ntb_write_remote_spad(ndev, NUM_MWS, ntb_max_mw(ndev));
654 if (rc) { 657 if (rc) {
655 dev_err(&pdev->dev, "Error writing %x to remote spad %d\n", 658 dev_err(&pdev->dev, "Error writing %x to remote spad %d\n",
656 NTB_NUM_MW, NUM_MWS); 659 ntb_max_mw(ndev), NUM_MWS);
657 goto out; 660 goto out;
658 } 661 }
659 662
@@ -698,11 +701,11 @@ static void ntb_transport_link_work(struct work_struct *work)
698 goto out; 701 goto out;
699 } 702 }
700 703
701 if (val != NTB_NUM_MW) 704 if (val != ntb_max_mw(ndev))
702 goto out; 705 goto out;
703 dev_dbg(&pdev->dev, "Remote number of mws = %d\n", val); 706 dev_dbg(&pdev->dev, "Remote number of mws = %d\n", val);
704 707
705 for (i = 0; i < NTB_NUM_MW; i++) { 708 for (i = 0; i < ntb_max_mw(ndev); i++) {
706 u64 val64; 709 u64 val64;
707 710
708 rc = ntb_read_remote_spad(ndev, MW0_SZ_HIGH + (i * 2), &val); 711 rc = ntb_read_remote_spad(ndev, MW0_SZ_HIGH + (i * 2), &val);
@@ -744,7 +747,7 @@ static void ntb_transport_link_work(struct work_struct *work)
744 return; 747 return;
745 748
746out1: 749out1:
747 for (i = 0; i < NTB_NUM_MW; i++) 750 for (i = 0; i < ntb_max_mw(ndev); i++)
748 ntb_free_mw(nt, i); 751 ntb_free_mw(nt, i);
749out: 752out:
750 if (ntb_hw_link_status(ndev)) 753 if (ntb_hw_link_status(ndev))
@@ -798,7 +801,10 @@ static void ntb_transport_init_queue(struct ntb_transport *nt,
798{ 801{
799 struct ntb_transport_qp *qp; 802 struct ntb_transport_qp *qp;
800 unsigned int num_qps_mw, tx_size; 803 unsigned int num_qps_mw, tx_size;
801 u8 mw_num = QP_TO_MW(qp_num); 804 u8 mw_num, mw_max;
805
806 mw_max = ntb_max_mw(nt->ndev);
807 mw_num = QP_TO_MW(nt->ndev, qp_num);
802 808
803 qp = &nt->qps[qp_num]; 809 qp = &nt->qps[qp_num];
804 qp->qp_num = qp_num; 810 qp->qp_num = qp_num;
@@ -808,14 +814,14 @@ static void ntb_transport_init_queue(struct ntb_transport *nt,
808 qp->client_ready = NTB_LINK_DOWN; 814 qp->client_ready = NTB_LINK_DOWN;
809 qp->event_handler = NULL; 815 qp->event_handler = NULL;
810 816
811 if (nt->max_qps % NTB_NUM_MW && mw_num < nt->max_qps % NTB_NUM_MW) 817 if (nt->max_qps % mw_max && mw_num < nt->max_qps % mw_max)
812 num_qps_mw = nt->max_qps / NTB_NUM_MW + 1; 818 num_qps_mw = nt->max_qps / mw_max + 1;
813 else 819 else
814 num_qps_mw = nt->max_qps / NTB_NUM_MW; 820 num_qps_mw = nt->max_qps / mw_max;
815 821
816 tx_size = (unsigned int) ntb_get_mw_size(qp->ndev, mw_num) / num_qps_mw; 822 tx_size = (unsigned int) ntb_get_mw_size(qp->ndev, mw_num) / num_qps_mw;
817 qp->rx_info = ntb_get_mw_vbase(nt->ndev, mw_num) + 823 qp->rx_info = ntb_get_mw_vbase(nt->ndev, mw_num) +
818 (qp_num / NTB_NUM_MW * tx_size); 824 (qp_num / mw_max * tx_size);
819 tx_size -= sizeof(struct ntb_rx_info); 825 tx_size -= sizeof(struct ntb_rx_info);
820 826
821 qp->tx_mw = qp->rx_info + 1; 827 qp->tx_mw = qp->rx_info + 1;
@@ -862,13 +868,23 @@ int ntb_transport_init(struct pci_dev *pdev)
862 goto err; 868 goto err;
863 } 869 }
864 870
865 nt->max_qps = min(nt->ndev->max_cbs, max_num_clients); 871 nt->mw = kcalloc(ntb_max_mw(nt->ndev), sizeof(struct ntb_transport_mw),
872 GFP_KERNEL);
873 if (!nt->mw) {
874 rc = -ENOMEM;
875 goto err1;
876 }
877
878 if (max_num_clients)
879 nt->max_qps = min(ntb_max_cbs(nt->ndev), max_num_clients);
880 else
881 nt->max_qps = min(ntb_max_cbs(nt->ndev), ntb_max_mw(nt->ndev));
866 882
867 nt->qps = kcalloc(nt->max_qps, sizeof(struct ntb_transport_qp), 883 nt->qps = kcalloc(nt->max_qps, sizeof(struct ntb_transport_qp),
868 GFP_KERNEL); 884 GFP_KERNEL);
869 if (!nt->qps) { 885 if (!nt->qps) {
870 rc = -ENOMEM; 886 rc = -ENOMEM;
871 goto err1; 887 goto err2;
872 } 888 }
873 889
874 nt->qp_bitmap = ((u64) 1 << nt->max_qps) - 1; 890 nt->qp_bitmap = ((u64) 1 << nt->max_qps) - 1;
@@ -882,22 +898,24 @@ int ntb_transport_init(struct pci_dev *pdev)
882 rc = ntb_register_event_callback(nt->ndev, 898 rc = ntb_register_event_callback(nt->ndev,
883 ntb_transport_event_callback); 899 ntb_transport_event_callback);
884 if (rc) 900 if (rc)
885 goto err2; 901 goto err3;
886 902
887 INIT_LIST_HEAD(&nt->client_devs); 903 INIT_LIST_HEAD(&nt->client_devs);
888 rc = ntb_bus_init(nt); 904 rc = ntb_bus_init(nt);
889 if (rc) 905 if (rc)
890 goto err3; 906 goto err4;
891 907
892 if (ntb_hw_link_status(nt->ndev)) 908 if (ntb_hw_link_status(nt->ndev))
893 schedule_delayed_work(&nt->link_work, 0); 909 schedule_delayed_work(&nt->link_work, 0);
894 910
895 return 0; 911 return 0;
896 912
897err3: 913err4:
898 ntb_unregister_event_callback(nt->ndev); 914 ntb_unregister_event_callback(nt->ndev);
899err2: 915err3:
900 kfree(nt->qps); 916 kfree(nt->qps);
917err2:
918 kfree(nt->mw);
901err1: 919err1:
902 ntb_unregister_transport(nt->ndev); 920 ntb_unregister_transport(nt->ndev);
903err: 921err:
@@ -908,6 +926,7 @@ err:
908void ntb_transport_free(void *transport) 926void ntb_transport_free(void *transport)
909{ 927{
910 struct ntb_transport *nt = transport; 928 struct ntb_transport *nt = transport;
929 struct ntb_device *ndev = nt->ndev;
911 struct pci_dev *pdev; 930 struct pci_dev *pdev;
912 int i; 931 int i;
913 932
@@ -924,15 +943,16 @@ void ntb_transport_free(void *transport)
924 943
925 cancel_delayed_work_sync(&nt->link_work); 944 cancel_delayed_work_sync(&nt->link_work);
926 945
927 ntb_unregister_event_callback(nt->ndev); 946 ntb_unregister_event_callback(ndev);
928 947
929 pdev = ntb_query_pdev(nt->ndev); 948 pdev = ntb_query_pdev(ndev);
930 949
931 for (i = 0; i < NTB_NUM_MW; i++) 950 for (i = 0; i < ntb_max_mw(ndev); i++)
932 ntb_free_mw(nt, i); 951 ntb_free_mw(nt, i);
933 952
934 kfree(nt->qps); 953 kfree(nt->qps);
935 ntb_unregister_transport(nt->ndev); 954 kfree(nt->mw);
955 ntb_unregister_transport(ndev);
936 kfree(nt); 956 kfree(nt);
937} 957}
938 958