diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-07 23:17:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-07 23:17:44 -0400 |
commit | c4c17252283a13c0d63a8d9df828da109c116411 (patch) | |
tree | 852a975068aeef7762a76f476b9cac3625ae6ad8 | |
parent | 8de4651abe61c6b6a94a70a57ef163020fed05ee (diff) | |
parent | 73f47cadfe29f98c48d7fbac4dd79d3e7979ee0b (diff) |
Merge tag 'ntb-3.12' of git://github.com/jonmason/ntb
Pull NTB (non-transparent bridge) updates from Jon Mason:
"NTB driver bug fixes to address issues in NTB-RP enablement, spad,
debugfs, and USD/DSD identification.
Add a workaround on Xeon NTB devices for b2bdoorbell errata. Also,
add new NTB driver features to support 32bit x86, DMA engine support,
and NTB-RP support.
Finally, a few clean-ups and update to MAINTAINERS for the NTB git
tree and wiki location"
* tag 'ntb-3.12' of git://github.com/jonmason/ntb:
ntb: clean up unnecessary MSI/MSI-X capability find
MAINTAINERS: Add Website and Git Tree for NTB
NTB: Update Version
NTB: Comment Fix
NTB: Remove unused variable
NTB: Remove References of non-B2B BWD HW
NTB: NTB-RP support
NTB: Rename Variables for NTB-RP
NTB: Use DMA Engine to Transmit and Receive
NTB: Enable 32bit Support
NTB: Update Device IDs
NTB: BWD Link Recovery
NTB: Xeon Errata Workaround
NTB: Correct debugfs to work with more than 1 NTB Device
NTB: Correct USD/DSD Identification
NTB: Correct Number of Scratch Pad Registers
NTB: Add Error Handling in ntb_device_setup
-rw-r--r-- | MAINTAINERS | 2 | ||||
-rw-r--r-- | drivers/ntb/Kconfig | 2 | ||||
-rw-r--r-- | drivers/ntb/ntb_hw.c | 501 | ||||
-rw-r--r-- | drivers/ntb/ntb_hw.h | 105 | ||||
-rw-r--r-- | drivers/ntb/ntb_regs.h | 50 | ||||
-rw-r--r-- | drivers/ntb/ntb_transport.c | 422 |
6 files changed, 855 insertions, 227 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index b6b29c38b6b6..99c6f35fb459 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -5889,6 +5889,8 @@ F: drivers/scsi/nsp32* | |||
5889 | NTB DRIVER | 5889 | NTB DRIVER |
5890 | M: Jon Mason <jon.mason@intel.com> | 5890 | M: Jon Mason <jon.mason@intel.com> |
5891 | S: Supported | 5891 | S: Supported |
5892 | W: https://github.com/jonmason/ntb/wiki | ||
5893 | T: git git://github.com/jonmason/ntb.git | ||
5892 | F: drivers/ntb/ | 5894 | F: drivers/ntb/ |
5893 | F: drivers/net/ntb_netdev.c | 5895 | F: drivers/net/ntb_netdev.c |
5894 | F: include/linux/ntb.h | 5896 | F: include/linux/ntb.h |
diff --git a/drivers/ntb/Kconfig b/drivers/ntb/Kconfig index 37ee6495acc1..f69df793dbe2 100644 --- a/drivers/ntb/Kconfig +++ b/drivers/ntb/Kconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | config NTB | 1 | config NTB |
2 | tristate "Intel Non-Transparent Bridge support" | 2 | tristate "Intel Non-Transparent Bridge support" |
3 | depends on PCI | 3 | depends on PCI |
4 | depends on X86_64 | 4 | depends on X86 |
5 | help | 5 | help |
6 | The PCI-E Non-transparent bridge hardware is a point-to-point PCI-E bus | 6 | The PCI-E Non-transparent bridge hardware is a point-to-point PCI-E bus |
7 | connecting 2 systems. When configured, writes to the device's PCI | 7 | connecting 2 systems. When configured, writes to the device's PCI |
diff --git a/drivers/ntb/ntb_hw.c b/drivers/ntb/ntb_hw.c index 2dacd19e1b8a..1cb6e51e6bda 100644 --- a/drivers/ntb/ntb_hw.c +++ b/drivers/ntb/ntb_hw.c | |||
@@ -46,24 +46,30 @@ | |||
46 | * Jon Mason <jon.mason@intel.com> | 46 | * Jon Mason <jon.mason@intel.com> |
47 | */ | 47 | */ |
48 | #include <linux/debugfs.h> | 48 | #include <linux/debugfs.h> |
49 | #include <linux/delay.h> | ||
49 | #include <linux/init.h> | 50 | #include <linux/init.h> |
50 | #include <linux/interrupt.h> | 51 | #include <linux/interrupt.h> |
51 | #include <linux/module.h> | 52 | #include <linux/module.h> |
52 | #include <linux/pci.h> | 53 | #include <linux/pci.h> |
54 | #include <linux/random.h> | ||
53 | #include <linux/slab.h> | 55 | #include <linux/slab.h> |
54 | #include "ntb_hw.h" | 56 | #include "ntb_hw.h" |
55 | #include "ntb_regs.h" | 57 | #include "ntb_regs.h" |
56 | 58 | ||
57 | #define NTB_NAME "Intel(R) PCI-E Non-Transparent Bridge Driver" | 59 | #define NTB_NAME "Intel(R) PCI-E Non-Transparent Bridge Driver" |
58 | #define NTB_VER "0.25" | 60 | #define NTB_VER "1.0" |
59 | 61 | ||
60 | MODULE_DESCRIPTION(NTB_NAME); | 62 | MODULE_DESCRIPTION(NTB_NAME); |
61 | MODULE_VERSION(NTB_VER); | 63 | MODULE_VERSION(NTB_VER); |
62 | MODULE_LICENSE("Dual BSD/GPL"); | 64 | MODULE_LICENSE("Dual BSD/GPL"); |
63 | MODULE_AUTHOR("Intel Corporation"); | 65 | MODULE_AUTHOR("Intel Corporation"); |
64 | 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 | |||
65 | enum { | 71 | enum { |
66 | NTB_CONN_CLASSIC = 0, | 72 | NTB_CONN_TRANSPARENT = 0, |
67 | NTB_CONN_B2B, | 73 | NTB_CONN_B2B, |
68 | NTB_CONN_RP, | 74 | NTB_CONN_RP, |
69 | }; | 75 | }; |
@@ -78,17 +84,27 @@ enum { | |||
78 | BWD_HW, | 84 | BWD_HW, |
79 | }; | 85 | }; |
80 | 86 | ||
87 | static struct dentry *debugfs_dir; | ||
88 | |||
89 | #define BWD_LINK_RECOVERY_TIME 500 | ||
90 | |||
81 | /* Translate memory window 0,1 to BAR 2,4 */ | 91 | /* Translate memory window 0,1 to BAR 2,4 */ |
82 | #define MW_TO_BAR(mw) (mw * 2 + 2) | 92 | #define MW_TO_BAR(mw) (mw * NTB_MAX_NUM_MW + 2) |
83 | 93 | ||
84 | static DEFINE_PCI_DEVICE_TABLE(ntb_pci_tbl) = { | 94 | static DEFINE_PCI_DEVICE_TABLE(ntb_pci_tbl) = { |
85 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_BWD)}, | 95 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_BWD)}, |
86 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_JSF)}, | 96 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_JSF)}, |
87 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_CLASSIC_JSF)}, | ||
88 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_RP_JSF)}, | ||
89 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_RP_SNB)}, | ||
90 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_SNB)}, | 97 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_SNB)}, |
91 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_CLASSIC_SNB)}, | 98 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_IVT)}, |
99 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_HSX)}, | ||
100 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_PS_JSF)}, | ||
101 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_PS_SNB)}, | ||
102 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_PS_IVT)}, | ||
103 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_PS_HSX)}, | ||
104 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_SS_JSF)}, | ||
105 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_SS_SNB)}, | ||
106 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_SS_IVT)}, | ||
107 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_SS_HSX)}, | ||
92 | {0} | 108 | {0} |
93 | }; | 109 | }; |
94 | MODULE_DEVICE_TABLE(pci, ntb_pci_tbl); | 110 | MODULE_DEVICE_TABLE(pci, ntb_pci_tbl); |
@@ -129,6 +145,7 @@ void ntb_unregister_event_callback(struct ntb_device *ndev) | |||
129 | * ntb_register_db_callback() - register a callback for doorbell interrupt | 145 | * ntb_register_db_callback() - register a callback for doorbell interrupt |
130 | * @ndev: pointer to ntb_device instance | 146 | * @ndev: pointer to ntb_device instance |
131 | * @idx: doorbell index to register callback, zero based | 147 | * @idx: doorbell index to register callback, zero based |
148 | * @data: pointer to be returned to caller with every callback | ||
132 | * @func: callback function to register | 149 | * @func: callback function to register |
133 | * | 150 | * |
134 | * This function registers a callback function for the doorbell interrupt | 151 | * This function registers a callback function for the doorbell interrupt |
@@ -151,9 +168,9 @@ int ntb_register_db_callback(struct ntb_device *ndev, unsigned int idx, | |||
151 | ndev->db_cb[idx].data = data; | 168 | ndev->db_cb[idx].data = data; |
152 | 169 | ||
153 | /* unmask interrupt */ | 170 | /* unmask interrupt */ |
154 | mask = readw(ndev->reg_ofs.pdb_mask); | 171 | mask = readw(ndev->reg_ofs.ldb_mask); |
155 | clear_bit(idx * ndev->bits_per_vector, &mask); | 172 | clear_bit(idx * ndev->bits_per_vector, &mask); |
156 | writew(mask, ndev->reg_ofs.pdb_mask); | 173 | writew(mask, ndev->reg_ofs.ldb_mask); |
157 | 174 | ||
158 | return 0; | 175 | return 0; |
159 | } | 176 | } |
@@ -173,9 +190,9 @@ void ntb_unregister_db_callback(struct ntb_device *ndev, unsigned int idx) | |||
173 | if (idx >= ndev->max_cbs || !ndev->db_cb[idx].callback) | 190 | if (idx >= ndev->max_cbs || !ndev->db_cb[idx].callback) |
174 | return; | 191 | return; |
175 | 192 | ||
176 | mask = readw(ndev->reg_ofs.pdb_mask); | 193 | mask = readw(ndev->reg_ofs.ldb_mask); |
177 | set_bit(idx * ndev->bits_per_vector, &mask); | 194 | set_bit(idx * ndev->bits_per_vector, &mask); |
178 | writew(mask, ndev->reg_ofs.pdb_mask); | 195 | writew(mask, ndev->reg_ofs.ldb_mask); |
179 | 196 | ||
180 | ndev->db_cb[idx].callback = NULL; | 197 | ndev->db_cb[idx].callback = NULL; |
181 | } | 198 | } |
@@ -334,6 +351,23 @@ int ntb_read_remote_spad(struct ntb_device *ndev, unsigned int idx, u32 *val) | |||
334 | } | 351 | } |
335 | 352 | ||
336 | /** | 353 | /** |
354 | * ntb_get_mw_base() - get addr for the NTB memory window | ||
355 | * @ndev: pointer to ntb_device instance | ||
356 | * @mw: memory window number | ||
357 | * | ||
358 | * This function provides the base address of the memory window specified. | ||
359 | * | ||
360 | * RETURNS: address, or NULL on error. | ||
361 | */ | ||
362 | resource_size_t ntb_get_mw_base(struct ntb_device *ndev, unsigned int mw) | ||
363 | { | ||
364 | if (mw >= ntb_max_mw(ndev)) | ||
365 | return 0; | ||
366 | |||
367 | return pci_resource_start(ndev->pdev, MW_TO_BAR(mw)); | ||
368 | } | ||
369 | |||
370 | /** | ||
337 | * ntb_get_mw_vbase() - get virtual addr for the NTB memory window | 371 | * ntb_get_mw_vbase() - get virtual addr for the NTB memory window |
338 | * @ndev: pointer to ntb_device instance | 372 | * @ndev: pointer to ntb_device instance |
339 | * @mw: memory window number | 373 | * @mw: memory window number |
@@ -345,7 +379,7 @@ int ntb_read_remote_spad(struct ntb_device *ndev, unsigned int idx, u32 *val) | |||
345 | */ | 379 | */ |
346 | void __iomem *ntb_get_mw_vbase(struct ntb_device *ndev, unsigned int mw) | 380 | void __iomem *ntb_get_mw_vbase(struct ntb_device *ndev, unsigned int mw) |
347 | { | 381 | { |
348 | if (mw >= NTB_NUM_MW) | 382 | if (mw >= ntb_max_mw(ndev)) |
349 | return NULL; | 383 | return NULL; |
350 | 384 | ||
351 | return ndev->mw[mw].vbase; | 385 | return ndev->mw[mw].vbase; |
@@ -360,9 +394,9 @@ void __iomem *ntb_get_mw_vbase(struct ntb_device *ndev, unsigned int mw) | |||
360 | * | 394 | * |
361 | * RETURNS: the size of the memory window or zero on error | 395 | * RETURNS: the size of the memory window or zero on error |
362 | */ | 396 | */ |
363 | resource_size_t ntb_get_mw_size(struct ntb_device *ndev, unsigned int mw) | 397 | u64 ntb_get_mw_size(struct ntb_device *ndev, unsigned int mw) |
364 | { | 398 | { |
365 | if (mw >= NTB_NUM_MW) | 399 | if (mw >= ntb_max_mw(ndev)) |
366 | return 0; | 400 | return 0; |
367 | 401 | ||
368 | return ndev->mw[mw].bar_sz; | 402 | return ndev->mw[mw].bar_sz; |
@@ -380,7 +414,7 @@ resource_size_t ntb_get_mw_size(struct ntb_device *ndev, unsigned int mw) | |||
380 | */ | 414 | */ |
381 | void ntb_set_mw_addr(struct ntb_device *ndev, unsigned int mw, u64 addr) | 415 | void ntb_set_mw_addr(struct ntb_device *ndev, unsigned int mw, u64 addr) |
382 | { | 416 | { |
383 | if (mw >= NTB_NUM_MW) | 417 | if (mw >= ntb_max_mw(ndev)) |
384 | return; | 418 | return; |
385 | 419 | ||
386 | dev_dbg(&ndev->pdev->dev, "Writing addr %Lx to BAR %d\n", addr, | 420 | dev_dbg(&ndev->pdev->dev, "Writing addr %Lx to BAR %d\n", addr, |
@@ -390,16 +424,16 @@ void ntb_set_mw_addr(struct ntb_device *ndev, unsigned int mw, u64 addr) | |||
390 | 424 | ||
391 | switch (MW_TO_BAR(mw)) { | 425 | switch (MW_TO_BAR(mw)) { |
392 | case NTB_BAR_23: | 426 | case NTB_BAR_23: |
393 | writeq(addr, ndev->reg_ofs.sbar2_xlat); | 427 | writeq(addr, ndev->reg_ofs.bar2_xlat); |
394 | break; | 428 | break; |
395 | case NTB_BAR_45: | 429 | case NTB_BAR_45: |
396 | writeq(addr, ndev->reg_ofs.sbar4_xlat); | 430 | writeq(addr, ndev->reg_ofs.bar4_xlat); |
397 | break; | 431 | break; |
398 | } | 432 | } |
399 | } | 433 | } |
400 | 434 | ||
401 | /** | 435 | /** |
402 | * ntb_ring_sdb() - Set the doorbell on the secondary/external side | 436 | * ntb_ring_doorbell() - Set the doorbell on the secondary/external side |
403 | * @ndev: pointer to ntb_device instance | 437 | * @ndev: pointer to ntb_device instance |
404 | * @db: doorbell to ring | 438 | * @db: doorbell to ring |
405 | * | 439 | * |
@@ -408,15 +442,58 @@ void ntb_set_mw_addr(struct ntb_device *ndev, unsigned int mw, u64 addr) | |||
408 | * | 442 | * |
409 | * RETURNS: An appropriate -ERRNO error value on error, or zero for success. | 443 | * RETURNS: An appropriate -ERRNO error value on error, or zero for success. |
410 | */ | 444 | */ |
411 | void ntb_ring_sdb(struct ntb_device *ndev, unsigned int db) | 445 | void ntb_ring_doorbell(struct ntb_device *ndev, unsigned int db) |
412 | { | 446 | { |
413 | dev_dbg(&ndev->pdev->dev, "%s: ringing doorbell %d\n", __func__, db); | 447 | dev_dbg(&ndev->pdev->dev, "%s: ringing doorbell %d\n", __func__, db); |
414 | 448 | ||
415 | if (ndev->hw_type == BWD_HW) | 449 | if (ndev->hw_type == BWD_HW) |
416 | writeq((u64) 1 << db, ndev->reg_ofs.sdb); | 450 | writeq((u64) 1 << db, ndev->reg_ofs.rdb); |
417 | else | 451 | else |
418 | writew(((1 << ndev->bits_per_vector) - 1) << | 452 | writew(((1 << ndev->bits_per_vector) - 1) << |
419 | (db * ndev->bits_per_vector), ndev->reg_ofs.sdb); | 453 | (db * ndev->bits_per_vector), ndev->reg_ofs.rdb); |
454 | } | ||
455 | |||
456 | static void bwd_recover_link(struct ntb_device *ndev) | ||
457 | { | ||
458 | u32 status; | ||
459 | |||
460 | /* Driver resets the NTB ModPhy lanes - magic! */ | ||
461 | writeb(0xe0, ndev->reg_base + BWD_MODPHY_PCSREG6); | ||
462 | writeb(0x40, ndev->reg_base + BWD_MODPHY_PCSREG4); | ||
463 | writeb(0x60, ndev->reg_base + BWD_MODPHY_PCSREG4); | ||
464 | writeb(0x60, ndev->reg_base + BWD_MODPHY_PCSREG6); | ||
465 | |||
466 | /* Driver waits 100ms to allow the NTB ModPhy to settle */ | ||
467 | msleep(100); | ||
468 | |||
469 | /* Clear AER Errors, write to clear */ | ||
470 | status = readl(ndev->reg_base + BWD_ERRCORSTS_OFFSET); | ||
471 | dev_dbg(&ndev->pdev->dev, "ERRCORSTS = %x\n", status); | ||
472 | status &= PCI_ERR_COR_REP_ROLL; | ||
473 | writel(status, ndev->reg_base + BWD_ERRCORSTS_OFFSET); | ||
474 | |||
475 | /* Clear unexpected electrical idle event in LTSSM, write to clear */ | ||
476 | status = readl(ndev->reg_base + BWD_LTSSMERRSTS0_OFFSET); | ||
477 | dev_dbg(&ndev->pdev->dev, "LTSSMERRSTS0 = %x\n", status); | ||
478 | status |= BWD_LTSSMERRSTS0_UNEXPECTEDEI; | ||
479 | writel(status, ndev->reg_base + BWD_LTSSMERRSTS0_OFFSET); | ||
480 | |||
481 | /* Clear DeSkew Buffer error, write to clear */ | ||
482 | status = readl(ndev->reg_base + BWD_DESKEWSTS_OFFSET); | ||
483 | dev_dbg(&ndev->pdev->dev, "DESKEWSTS = %x\n", status); | ||
484 | status |= BWD_DESKEWSTS_DBERR; | ||
485 | writel(status, ndev->reg_base + BWD_DESKEWSTS_OFFSET); | ||
486 | |||
487 | status = readl(ndev->reg_base + BWD_IBSTERRRCRVSTS0_OFFSET); | ||
488 | dev_dbg(&ndev->pdev->dev, "IBSTERRRCRVSTS0 = %x\n", status); | ||
489 | status &= BWD_IBIST_ERR_OFLOW; | ||
490 | writel(status, ndev->reg_base + BWD_IBSTERRRCRVSTS0_OFFSET); | ||
491 | |||
492 | /* Releases the NTB state machine to allow the link to retrain */ | ||
493 | status = readl(ndev->reg_base + BWD_LTSSMSTATEJMP_OFFSET); | ||
494 | dev_dbg(&ndev->pdev->dev, "LTSSMSTATEJMP = %x\n", status); | ||
495 | status &= ~BWD_LTSSMSTATEJMP_FORCEDETECT; | ||
496 | writel(status, ndev->reg_base + BWD_LTSSMSTATEJMP_OFFSET); | ||
420 | } | 497 | } |
421 | 498 | ||
422 | static void ntb_link_event(struct ntb_device *ndev, int link_state) | 499 | static void ntb_link_event(struct ntb_device *ndev, int link_state) |
@@ -433,7 +510,8 @@ static void ntb_link_event(struct ntb_device *ndev, int link_state) | |||
433 | ndev->link_status = NTB_LINK_UP; | 510 | ndev->link_status = NTB_LINK_UP; |
434 | event = NTB_EVENT_HW_LINK_UP; | 511 | event = NTB_EVENT_HW_LINK_UP; |
435 | 512 | ||
436 | if (ndev->hw_type == BWD_HW) | 513 | if (ndev->hw_type == BWD_HW || |
514 | ndev->conn_type == NTB_CONN_TRANSPARENT) | ||
437 | status = readw(ndev->reg_ofs.lnk_stat); | 515 | status = readw(ndev->reg_ofs.lnk_stat); |
438 | else { | 516 | else { |
439 | int rc = pci_read_config_word(ndev->pdev, | 517 | int rc = pci_read_config_word(ndev->pdev, |
@@ -442,13 +520,16 @@ static void ntb_link_event(struct ntb_device *ndev, int link_state) | |||
442 | if (rc) | 520 | if (rc) |
443 | return; | 521 | return; |
444 | } | 522 | } |
523 | |||
524 | ndev->link_width = (status & NTB_LINK_WIDTH_MASK) >> 4; | ||
525 | ndev->link_speed = (status & NTB_LINK_SPEED_MASK); | ||
445 | dev_info(&ndev->pdev->dev, "Link Width %d, Link Speed %d\n", | 526 | dev_info(&ndev->pdev->dev, "Link Width %d, Link Speed %d\n", |
446 | (status & NTB_LINK_WIDTH_MASK) >> 4, | 527 | ndev->link_width, ndev->link_speed); |
447 | (status & NTB_LINK_SPEED_MASK)); | ||
448 | } else { | 528 | } else { |
449 | dev_info(&ndev->pdev->dev, "Link Down\n"); | 529 | dev_info(&ndev->pdev->dev, "Link Down\n"); |
450 | ndev->link_status = NTB_LINK_DOWN; | 530 | ndev->link_status = NTB_LINK_DOWN; |
451 | event = NTB_EVENT_HW_LINK_DOWN; | 531 | event = NTB_EVENT_HW_LINK_DOWN; |
532 | /* Don't modify link width/speed, we need it in link recovery */ | ||
452 | } | 533 | } |
453 | 534 | ||
454 | /* notify the upper layer if we have an event change */ | 535 | /* notify the upper layer if we have an event change */ |
@@ -488,6 +569,47 @@ static int ntb_link_status(struct ntb_device *ndev) | |||
488 | return 0; | 569 | return 0; |
489 | } | 570 | } |
490 | 571 | ||
572 | static void bwd_link_recovery(struct work_struct *work) | ||
573 | { | ||
574 | struct ntb_device *ndev = container_of(work, struct ntb_device, | ||
575 | lr_timer.work); | ||
576 | u32 status32; | ||
577 | |||
578 | bwd_recover_link(ndev); | ||
579 | /* There is a potential race between the 2 NTB devices recovering at the | ||
580 | * same time. If the times are the same, the link will not recover and | ||
581 | * the driver will be stuck in this loop forever. Add a random interval | ||
582 | * to the recovery time to prevent this race. | ||
583 | */ | ||
584 | msleep(BWD_LINK_RECOVERY_TIME + prandom_u32() % BWD_LINK_RECOVERY_TIME); | ||
585 | |||
586 | status32 = readl(ndev->reg_base + BWD_LTSSMSTATEJMP_OFFSET); | ||
587 | if (status32 & BWD_LTSSMSTATEJMP_FORCEDETECT) | ||
588 | goto retry; | ||
589 | |||
590 | status32 = readl(ndev->reg_base + BWD_IBSTERRRCRVSTS0_OFFSET); | ||
591 | if (status32 & BWD_IBIST_ERR_OFLOW) | ||
592 | goto retry; | ||
593 | |||
594 | status32 = readl(ndev->reg_ofs.lnk_cntl); | ||
595 | if (!(status32 & BWD_CNTL_LINK_DOWN)) { | ||
596 | unsigned char speed, width; | ||
597 | u16 status16; | ||
598 | |||
599 | status16 = readw(ndev->reg_ofs.lnk_stat); | ||
600 | width = (status16 & NTB_LINK_WIDTH_MASK) >> 4; | ||
601 | speed = (status16 & NTB_LINK_SPEED_MASK); | ||
602 | if (ndev->link_width != width || ndev->link_speed != speed) | ||
603 | goto retry; | ||
604 | } | ||
605 | |||
606 | schedule_delayed_work(&ndev->hb_timer, NTB_HB_TIMEOUT); | ||
607 | return; | ||
608 | |||
609 | retry: | ||
610 | schedule_delayed_work(&ndev->lr_timer, NTB_HB_TIMEOUT); | ||
611 | } | ||
612 | |||
491 | /* BWD doesn't have link status interrupt, poll on that platform */ | 613 | /* BWD doesn't have link status interrupt, poll on that platform */ |
492 | static void bwd_link_poll(struct work_struct *work) | 614 | static void bwd_link_poll(struct work_struct *work) |
493 | { | 615 | { |
@@ -503,6 +625,16 @@ static void bwd_link_poll(struct work_struct *work) | |||
503 | if (rc) | 625 | if (rc) |
504 | dev_err(&ndev->pdev->dev, | 626 | dev_err(&ndev->pdev->dev, |
505 | "Error determining link status\n"); | 627 | "Error determining link status\n"); |
628 | |||
629 | /* Check to see if a link error is the cause of the link down */ | ||
630 | if (ndev->link_status == NTB_LINK_DOWN) { | ||
631 | u32 status32 = readl(ndev->reg_base + | ||
632 | BWD_LTSSMSTATEJMP_OFFSET); | ||
633 | if (status32 & BWD_LTSSMSTATEJMP_FORCEDETECT) { | ||
634 | schedule_delayed_work(&ndev->lr_timer, 0); | ||
635 | return; | ||
636 | } | ||
637 | } | ||
506 | } | 638 | } |
507 | 639 | ||
508 | schedule_delayed_work(&ndev->hb_timer, NTB_HB_TIMEOUT); | 640 | schedule_delayed_work(&ndev->hb_timer, NTB_HB_TIMEOUT); |
@@ -519,41 +651,174 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
519 | if (rc) | 651 | if (rc) |
520 | return rc; | 652 | return rc; |
521 | 653 | ||
654 | if (val & SNB_PPD_DEV_TYPE) | ||
655 | ndev->dev_type = NTB_DEV_USD; | ||
656 | else | ||
657 | ndev->dev_type = NTB_DEV_DSD; | ||
658 | |||
522 | switch (val & SNB_PPD_CONN_TYPE) { | 659 | switch (val & SNB_PPD_CONN_TYPE) { |
523 | case NTB_CONN_B2B: | 660 | case NTB_CONN_B2B: |
661 | dev_info(&ndev->pdev->dev, "Conn Type = B2B\n"); | ||
524 | ndev->conn_type = NTB_CONN_B2B; | 662 | ndev->conn_type = NTB_CONN_B2B; |
663 | ndev->reg_ofs.ldb = ndev->reg_base + SNB_PDOORBELL_OFFSET; | ||
664 | ndev->reg_ofs.ldb_mask = ndev->reg_base + SNB_PDBMSK_OFFSET; | ||
665 | ndev->reg_ofs.spad_read = ndev->reg_base + SNB_SPAD_OFFSET; | ||
666 | ndev->reg_ofs.bar2_xlat = ndev->reg_base + SNB_SBAR2XLAT_OFFSET; | ||
667 | ndev->reg_ofs.bar4_xlat = ndev->reg_base + SNB_SBAR4XLAT_OFFSET; | ||
668 | ndev->limits.max_spads = SNB_MAX_B2B_SPADS; | ||
669 | |||
670 | /* There is a Xeon hardware errata related to writes to | ||
671 | * SDOORBELL or B2BDOORBELL in conjunction with inbound access | ||
672 | * to NTB MMIO Space, which may hang the system. To workaround | ||
673 | * this use the second memory window to access the interrupt and | ||
674 | * scratch pad registers on the remote system. | ||
675 | */ | ||
676 | if (xeon_errata_workaround) { | ||
677 | if (!ndev->mw[1].bar_sz) | ||
678 | return -EINVAL; | ||
679 | |||
680 | ndev->limits.max_mw = SNB_ERRATA_MAX_MW; | ||
681 | ndev->reg_ofs.spad_write = ndev->mw[1].vbase + | ||
682 | SNB_SPAD_OFFSET; | ||
683 | ndev->reg_ofs.rdb = ndev->mw[1].vbase + | ||
684 | SNB_PDOORBELL_OFFSET; | ||
685 | |||
686 | /* Set the Limit register to 4k, the minimum size, to | ||
687 | * prevent an illegal access | ||
688 | */ | ||
689 | writeq(ndev->mw[1].bar_sz + 0x1000, ndev->reg_base + | ||
690 | SNB_PBAR4LMT_OFFSET); | ||
691 | } else { | ||
692 | ndev->limits.max_mw = SNB_MAX_MW; | ||
693 | ndev->reg_ofs.spad_write = ndev->reg_base + | ||
694 | SNB_B2B_SPAD_OFFSET; | ||
695 | ndev->reg_ofs.rdb = ndev->reg_base + | ||
696 | SNB_B2B_DOORBELL_OFFSET; | ||
697 | |||
698 | /* Disable the Limit register, just incase it is set to | ||
699 | * something silly | ||
700 | */ | ||
701 | writeq(0, ndev->reg_base + SNB_PBAR4LMT_OFFSET); | ||
702 | } | ||
703 | |||
704 | /* The Xeon errata workaround requires setting SBAR Base | ||
705 | * addresses to known values, so that the PBAR XLAT can be | ||
706 | * pointed at SBAR0 of the remote system. | ||
707 | */ | ||
708 | if (ndev->dev_type == NTB_DEV_USD) { | ||
709 | writeq(SNB_MBAR23_DSD_ADDR, ndev->reg_base + | ||
710 | SNB_PBAR2XLAT_OFFSET); | ||
711 | if (xeon_errata_workaround) | ||
712 | writeq(SNB_MBAR01_DSD_ADDR, ndev->reg_base + | ||
713 | SNB_PBAR4XLAT_OFFSET); | ||
714 | else { | ||
715 | writeq(SNB_MBAR45_DSD_ADDR, ndev->reg_base + | ||
716 | SNB_PBAR4XLAT_OFFSET); | ||
717 | /* B2B_XLAT_OFFSET is a 64bit register, but can | ||
718 | * only take 32bit writes | ||
719 | */ | ||
720 | writel(SNB_MBAR01_DSD_ADDR & 0xffffffff, | ||
721 | ndev->reg_base + SNB_B2B_XLAT_OFFSETL); | ||
722 | writel(SNB_MBAR01_DSD_ADDR >> 32, | ||
723 | ndev->reg_base + SNB_B2B_XLAT_OFFSETU); | ||
724 | } | ||
725 | |||
726 | writeq(SNB_MBAR01_USD_ADDR, ndev->reg_base + | ||
727 | SNB_SBAR0BASE_OFFSET); | ||
728 | writeq(SNB_MBAR23_USD_ADDR, ndev->reg_base + | ||
729 | SNB_SBAR2BASE_OFFSET); | ||
730 | writeq(SNB_MBAR45_USD_ADDR, ndev->reg_base + | ||
731 | SNB_SBAR4BASE_OFFSET); | ||
732 | } else { | ||
733 | writeq(SNB_MBAR23_USD_ADDR, ndev->reg_base + | ||
734 | SNB_PBAR2XLAT_OFFSET); | ||
735 | if (xeon_errata_workaround) | ||
736 | writeq(SNB_MBAR01_USD_ADDR, ndev->reg_base + | ||
737 | SNB_PBAR4XLAT_OFFSET); | ||
738 | else { | ||
739 | writeq(SNB_MBAR45_USD_ADDR, ndev->reg_base + | ||
740 | SNB_PBAR4XLAT_OFFSET); | ||
741 | /* B2B_XLAT_OFFSET is a 64bit register, but can | ||
742 | * only take 32bit writes | ||
743 | */ | ||
744 | writel(SNB_MBAR01_DSD_ADDR & 0xffffffff, | ||
745 | ndev->reg_base + SNB_B2B_XLAT_OFFSETL); | ||
746 | writel(SNB_MBAR01_USD_ADDR >> 32, | ||
747 | ndev->reg_base + SNB_B2B_XLAT_OFFSETU); | ||
748 | } | ||
749 | writeq(SNB_MBAR01_DSD_ADDR, ndev->reg_base + | ||
750 | SNB_SBAR0BASE_OFFSET); | ||
751 | writeq(SNB_MBAR23_DSD_ADDR, ndev->reg_base + | ||
752 | SNB_SBAR2BASE_OFFSET); | ||
753 | writeq(SNB_MBAR45_DSD_ADDR, ndev->reg_base + | ||
754 | SNB_SBAR4BASE_OFFSET); | ||
755 | } | ||
525 | break; | 756 | break; |
526 | case NTB_CONN_CLASSIC: | ||
527 | case NTB_CONN_RP: | 757 | case NTB_CONN_RP: |
758 | dev_info(&ndev->pdev->dev, "Conn Type = RP\n"); | ||
759 | ndev->conn_type = NTB_CONN_RP; | ||
760 | |||
761 | if (xeon_errata_workaround) { | ||
762 | dev_err(&ndev->pdev->dev, | ||
763 | "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"); | ||
764 | return -EINVAL; | ||
765 | } | ||
766 | |||
767 | /* Scratch pads need to have exclusive access from the primary | ||
768 | * or secondary side. Halve the num spads so that each side can | ||
769 | * have an equal amount. | ||
770 | */ | ||
771 | ndev->limits.max_spads = SNB_MAX_COMPAT_SPADS / 2; | ||
772 | /* Note: The SDOORBELL is the cause of the errata. You REALLY | ||
773 | * don't want to touch it. | ||
774 | */ | ||
775 | ndev->reg_ofs.rdb = ndev->reg_base + SNB_SDOORBELL_OFFSET; | ||
776 | ndev->reg_ofs.ldb = ndev->reg_base + SNB_PDOORBELL_OFFSET; | ||
777 | ndev->reg_ofs.ldb_mask = ndev->reg_base + SNB_PDBMSK_OFFSET; | ||
778 | /* Offset the start of the spads to correspond to whether it is | ||
779 | * primary or secondary | ||
780 | */ | ||
781 | ndev->reg_ofs.spad_write = ndev->reg_base + SNB_SPAD_OFFSET + | ||
782 | ndev->limits.max_spads * 4; | ||
783 | ndev->reg_ofs.spad_read = ndev->reg_base + SNB_SPAD_OFFSET; | ||
784 | ndev->reg_ofs.bar2_xlat = ndev->reg_base + SNB_SBAR2XLAT_OFFSET; | ||
785 | ndev->reg_ofs.bar4_xlat = ndev->reg_base + SNB_SBAR4XLAT_OFFSET; | ||
786 | ndev->limits.max_mw = SNB_MAX_MW; | ||
787 | break; | ||
788 | case NTB_CONN_TRANSPARENT: | ||
789 | dev_info(&ndev->pdev->dev, "Conn Type = TRANSPARENT\n"); | ||
790 | ndev->conn_type = NTB_CONN_TRANSPARENT; | ||
791 | /* Scratch pads need to have exclusive access from the primary | ||
792 | * or secondary side. Halve the num spads so that each side can | ||
793 | * have an equal amount. | ||
794 | */ | ||
795 | ndev->limits.max_spads = SNB_MAX_COMPAT_SPADS / 2; | ||
796 | ndev->reg_ofs.rdb = ndev->reg_base + SNB_PDOORBELL_OFFSET; | ||
797 | ndev->reg_ofs.ldb = ndev->reg_base + SNB_SDOORBELL_OFFSET; | ||
798 | ndev->reg_ofs.ldb_mask = ndev->reg_base + SNB_SDBMSK_OFFSET; | ||
799 | ndev->reg_ofs.spad_write = ndev->reg_base + SNB_SPAD_OFFSET; | ||
800 | /* Offset the start of the spads to correspond to whether it is | ||
801 | * primary or secondary | ||
802 | */ | ||
803 | ndev->reg_ofs.spad_read = ndev->reg_base + SNB_SPAD_OFFSET + | ||
804 | ndev->limits.max_spads * 4; | ||
805 | ndev->reg_ofs.bar2_xlat = ndev->reg_base + SNB_PBAR2XLAT_OFFSET; | ||
806 | ndev->reg_ofs.bar4_xlat = ndev->reg_base + SNB_PBAR4XLAT_OFFSET; | ||
807 | |||
808 | ndev->limits.max_mw = SNB_MAX_MW; | ||
809 | break; | ||
528 | default: | 810 | default: |
529 | dev_err(&ndev->pdev->dev, "Only B2B supported at this time\n"); | 811 | /* Most likely caused by the remote NTB-RP device not being |
812 | * configured | ||
813 | */ | ||
814 | dev_err(&ndev->pdev->dev, "Unknown PPD %x\n", val); | ||
530 | return -EINVAL; | 815 | return -EINVAL; |
531 | } | 816 | } |
532 | 817 | ||
533 | if (val & SNB_PPD_DEV_TYPE) | ||
534 | ndev->dev_type = NTB_DEV_DSD; | ||
535 | else | ||
536 | ndev->dev_type = NTB_DEV_USD; | ||
537 | |||
538 | ndev->reg_ofs.pdb = ndev->reg_base + SNB_PDOORBELL_OFFSET; | ||
539 | ndev->reg_ofs.pdb_mask = ndev->reg_base + SNB_PDBMSK_OFFSET; | ||
540 | ndev->reg_ofs.sbar2_xlat = ndev->reg_base + SNB_SBAR2XLAT_OFFSET; | ||
541 | ndev->reg_ofs.sbar4_xlat = ndev->reg_base + SNB_SBAR4XLAT_OFFSET; | ||
542 | ndev->reg_ofs.lnk_cntl = ndev->reg_base + SNB_NTBCNTL_OFFSET; | 818 | ndev->reg_ofs.lnk_cntl = ndev->reg_base + SNB_NTBCNTL_OFFSET; |
543 | ndev->reg_ofs.lnk_stat = ndev->reg_base + SNB_LINK_STATUS_OFFSET; | 819 | ndev->reg_ofs.lnk_stat = ndev->reg_base + SNB_SLINK_STATUS_OFFSET; |
544 | ndev->reg_ofs.spad_read = ndev->reg_base + SNB_SPAD_OFFSET; | ||
545 | ndev->reg_ofs.spci_cmd = ndev->reg_base + SNB_PCICMD_OFFSET; | 820 | ndev->reg_ofs.spci_cmd = ndev->reg_base + SNB_PCICMD_OFFSET; |
546 | 821 | ||
547 | if (ndev->conn_type == NTB_CONN_B2B) { | ||
548 | ndev->reg_ofs.sdb = ndev->reg_base + SNB_B2B_DOORBELL_OFFSET; | ||
549 | ndev->reg_ofs.spad_write = ndev->reg_base + SNB_B2B_SPAD_OFFSET; | ||
550 | ndev->limits.max_spads = SNB_MAX_SPADS; | ||
551 | } else { | ||
552 | ndev->reg_ofs.sdb = ndev->reg_base + SNB_SDOORBELL_OFFSET; | ||
553 | ndev->reg_ofs.spad_write = ndev->reg_base + SNB_SPAD_OFFSET; | ||
554 | ndev->limits.max_spads = SNB_MAX_COMPAT_SPADS; | ||
555 | } | ||
556 | |||
557 | ndev->limits.max_db_bits = SNB_MAX_DB_BITS; | 822 | ndev->limits.max_db_bits = SNB_MAX_DB_BITS; |
558 | ndev->limits.msix_cnt = SNB_MSIX_CNT; | 823 | ndev->limits.msix_cnt = SNB_MSIX_CNT; |
559 | ndev->bits_per_vector = SNB_DB_BITS_PER_VEC; | 824 | ndev->bits_per_vector = SNB_DB_BITS_PER_VEC; |
@@ -578,7 +843,7 @@ static int ntb_bwd_setup(struct ntb_device *ndev) | |||
578 | break; | 843 | break; |
579 | case NTB_CONN_RP: | 844 | case NTB_CONN_RP: |
580 | default: | 845 | default: |
581 | dev_err(&ndev->pdev->dev, "Only B2B supported at this time\n"); | 846 | dev_err(&ndev->pdev->dev, "Unsupported NTB configuration\n"); |
582 | return -EINVAL; | 847 | return -EINVAL; |
583 | } | 848 | } |
584 | 849 | ||
@@ -593,31 +858,25 @@ static int ntb_bwd_setup(struct ntb_device *ndev) | |||
593 | if (rc) | 858 | if (rc) |
594 | return rc; | 859 | return rc; |
595 | 860 | ||
596 | ndev->reg_ofs.pdb = ndev->reg_base + BWD_PDOORBELL_OFFSET; | 861 | ndev->reg_ofs.ldb = ndev->reg_base + BWD_PDOORBELL_OFFSET; |
597 | ndev->reg_ofs.pdb_mask = ndev->reg_base + BWD_PDBMSK_OFFSET; | 862 | ndev->reg_ofs.ldb_mask = ndev->reg_base + BWD_PDBMSK_OFFSET; |
598 | ndev->reg_ofs.sbar2_xlat = ndev->reg_base + BWD_SBAR2XLAT_OFFSET; | 863 | ndev->reg_ofs.rdb = ndev->reg_base + BWD_B2B_DOORBELL_OFFSET; |
599 | ndev->reg_ofs.sbar4_xlat = ndev->reg_base + BWD_SBAR4XLAT_OFFSET; | 864 | ndev->reg_ofs.bar2_xlat = ndev->reg_base + BWD_SBAR2XLAT_OFFSET; |
865 | ndev->reg_ofs.bar4_xlat = ndev->reg_base + BWD_SBAR4XLAT_OFFSET; | ||
600 | ndev->reg_ofs.lnk_cntl = ndev->reg_base + BWD_NTBCNTL_OFFSET; | 866 | ndev->reg_ofs.lnk_cntl = ndev->reg_base + BWD_NTBCNTL_OFFSET; |
601 | ndev->reg_ofs.lnk_stat = ndev->reg_base + BWD_LINK_STATUS_OFFSET; | 867 | ndev->reg_ofs.lnk_stat = ndev->reg_base + BWD_LINK_STATUS_OFFSET; |
602 | ndev->reg_ofs.spad_read = ndev->reg_base + BWD_SPAD_OFFSET; | 868 | ndev->reg_ofs.spad_read = ndev->reg_base + BWD_SPAD_OFFSET; |
869 | ndev->reg_ofs.spad_write = ndev->reg_base + BWD_B2B_SPAD_OFFSET; | ||
603 | ndev->reg_ofs.spci_cmd = ndev->reg_base + BWD_PCICMD_OFFSET; | 870 | ndev->reg_ofs.spci_cmd = ndev->reg_base + BWD_PCICMD_OFFSET; |
604 | 871 | ndev->limits.max_mw = BWD_MAX_MW; | |
605 | if (ndev->conn_type == NTB_CONN_B2B) { | 872 | ndev->limits.max_spads = BWD_MAX_SPADS; |
606 | ndev->reg_ofs.sdb = ndev->reg_base + BWD_B2B_DOORBELL_OFFSET; | ||
607 | ndev->reg_ofs.spad_write = ndev->reg_base + BWD_B2B_SPAD_OFFSET; | ||
608 | ndev->limits.max_spads = BWD_MAX_SPADS; | ||
609 | } else { | ||
610 | ndev->reg_ofs.sdb = ndev->reg_base + BWD_PDOORBELL_OFFSET; | ||
611 | ndev->reg_ofs.spad_write = ndev->reg_base + BWD_SPAD_OFFSET; | ||
612 | ndev->limits.max_spads = BWD_MAX_COMPAT_SPADS; | ||
613 | } | ||
614 | |||
615 | ndev->limits.max_db_bits = BWD_MAX_DB_BITS; | 873 | ndev->limits.max_db_bits = BWD_MAX_DB_BITS; |
616 | ndev->limits.msix_cnt = BWD_MSIX_CNT; | 874 | ndev->limits.msix_cnt = BWD_MSIX_CNT; |
617 | ndev->bits_per_vector = BWD_DB_BITS_PER_VEC; | 875 | ndev->bits_per_vector = BWD_DB_BITS_PER_VEC; |
618 | 876 | ||
619 | /* Since bwd doesn't have a link interrupt, setup a poll timer */ | 877 | /* Since bwd doesn't have a link interrupt, setup a poll timer */ |
620 | INIT_DELAYED_WORK(&ndev->hb_timer, bwd_link_poll); | 878 | INIT_DELAYED_WORK(&ndev->hb_timer, bwd_link_poll); |
879 | INIT_DELAYED_WORK(&ndev->lr_timer, bwd_link_recovery); | ||
621 | schedule_delayed_work(&ndev->hb_timer, NTB_HB_TIMEOUT); | 880 | schedule_delayed_work(&ndev->hb_timer, NTB_HB_TIMEOUT); |
622 | 881 | ||
623 | return 0; | 882 | return 0; |
@@ -628,13 +887,18 @@ static int ntb_device_setup(struct ntb_device *ndev) | |||
628 | int rc; | 887 | int rc; |
629 | 888 | ||
630 | switch (ndev->pdev->device) { | 889 | switch (ndev->pdev->device) { |
631 | case PCI_DEVICE_ID_INTEL_NTB_2ND_SNB: | 890 | case PCI_DEVICE_ID_INTEL_NTB_SS_JSF: |
632 | case PCI_DEVICE_ID_INTEL_NTB_RP_JSF: | 891 | case PCI_DEVICE_ID_INTEL_NTB_SS_SNB: |
633 | case PCI_DEVICE_ID_INTEL_NTB_RP_SNB: | 892 | case PCI_DEVICE_ID_INTEL_NTB_SS_IVT: |
634 | case PCI_DEVICE_ID_INTEL_NTB_CLASSIC_JSF: | 893 | case PCI_DEVICE_ID_INTEL_NTB_SS_HSX: |
635 | case PCI_DEVICE_ID_INTEL_NTB_CLASSIC_SNB: | 894 | case PCI_DEVICE_ID_INTEL_NTB_PS_JSF: |
895 | case PCI_DEVICE_ID_INTEL_NTB_PS_SNB: | ||
896 | case PCI_DEVICE_ID_INTEL_NTB_PS_IVT: | ||
897 | case PCI_DEVICE_ID_INTEL_NTB_PS_HSX: | ||
636 | case PCI_DEVICE_ID_INTEL_NTB_B2B_JSF: | 898 | case PCI_DEVICE_ID_INTEL_NTB_B2B_JSF: |
637 | case PCI_DEVICE_ID_INTEL_NTB_B2B_SNB: | 899 | case PCI_DEVICE_ID_INTEL_NTB_B2B_SNB: |
900 | case PCI_DEVICE_ID_INTEL_NTB_B2B_IVT: | ||
901 | case PCI_DEVICE_ID_INTEL_NTB_B2B_HSX: | ||
638 | rc = ntb_xeon_setup(ndev); | 902 | rc = ntb_xeon_setup(ndev); |
639 | break; | 903 | break; |
640 | case PCI_DEVICE_ID_INTEL_NTB_B2B_BWD: | 904 | case PCI_DEVICE_ID_INTEL_NTB_B2B_BWD: |
@@ -644,16 +908,26 @@ static int ntb_device_setup(struct ntb_device *ndev) | |||
644 | rc = -ENODEV; | 908 | rc = -ENODEV; |
645 | } | 909 | } |
646 | 910 | ||
647 | /* Enable Bus Master and Memory Space on the secondary side */ | 911 | if (rc) |
648 | writew(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, ndev->reg_ofs.spci_cmd); | 912 | return rc; |
913 | |||
914 | dev_info(&ndev->pdev->dev, "Device Type = %s\n", | ||
915 | ndev->dev_type == NTB_DEV_USD ? "USD/DSP" : "DSD/USP"); | ||
649 | 916 | ||
650 | return rc; | 917 | if (ndev->conn_type == NTB_CONN_B2B) |
918 | /* Enable Bus Master and Memory Space on the secondary side */ | ||
919 | writew(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, | ||
920 | ndev->reg_ofs.spci_cmd); | ||
921 | |||
922 | return 0; | ||
651 | } | 923 | } |
652 | 924 | ||
653 | static void ntb_device_free(struct ntb_device *ndev) | 925 | static void ntb_device_free(struct ntb_device *ndev) |
654 | { | 926 | { |
655 | if (ndev->hw_type == BWD_HW) | 927 | if (ndev->hw_type == BWD_HW) { |
656 | cancel_delayed_work_sync(&ndev->hb_timer); | 928 | cancel_delayed_work_sync(&ndev->hb_timer); |
929 | cancel_delayed_work_sync(&ndev->lr_timer); | ||
930 | } | ||
657 | } | 931 | } |
658 | 932 | ||
659 | static irqreturn_t bwd_callback_msix_irq(int irq, void *data) | 933 | static irqreturn_t bwd_callback_msix_irq(int irq, void *data) |
@@ -672,7 +946,7 @@ static irqreturn_t bwd_callback_msix_irq(int irq, void *data) | |||
672 | */ | 946 | */ |
673 | ndev->last_ts = jiffies; | 947 | ndev->last_ts = jiffies; |
674 | 948 | ||
675 | writeq((u64) 1 << db_cb->db_num, ndev->reg_ofs.pdb); | 949 | writeq((u64) 1 << db_cb->db_num, ndev->reg_ofs.ldb); |
676 | 950 | ||
677 | return IRQ_HANDLED; | 951 | return IRQ_HANDLED; |
678 | } | 952 | } |
@@ -694,7 +968,7 @@ static irqreturn_t xeon_callback_msix_irq(int irq, void *data) | |||
694 | * interrupts. | 968 | * interrupts. |
695 | */ | 969 | */ |
696 | writew(((1 << ndev->bits_per_vector) - 1) << | 970 | writew(((1 << ndev->bits_per_vector) - 1) << |
697 | (db_cb->db_num * ndev->bits_per_vector), ndev->reg_ofs.pdb); | 971 | (db_cb->db_num * ndev->bits_per_vector), ndev->reg_ofs.ldb); |
698 | 972 | ||
699 | return IRQ_HANDLED; | 973 | return IRQ_HANDLED; |
700 | } | 974 | } |
@@ -712,7 +986,7 @@ static irqreturn_t xeon_event_msix_irq(int irq, void *dev) | |||
712 | dev_err(&ndev->pdev->dev, "Error determining link status\n"); | 986 | dev_err(&ndev->pdev->dev, "Error determining link status\n"); |
713 | 987 | ||
714 | /* bit 15 is always the link bit */ | 988 | /* bit 15 is always the link bit */ |
715 | writew(1 << ndev->limits.max_db_bits, ndev->reg_ofs.pdb); | 989 | writew(1 << ndev->limits.max_db_bits, ndev->reg_ofs.ldb); |
716 | 990 | ||
717 | return IRQ_HANDLED; | 991 | return IRQ_HANDLED; |
718 | } | 992 | } |
@@ -723,29 +997,28 @@ static irqreturn_t ntb_interrupt(int irq, void *dev) | |||
723 | unsigned int i = 0; | 997 | unsigned int i = 0; |
724 | 998 | ||
725 | if (ndev->hw_type == BWD_HW) { | 999 | if (ndev->hw_type == BWD_HW) { |
726 | u64 pdb = readq(ndev->reg_ofs.pdb); | 1000 | u64 ldb = readq(ndev->reg_ofs.ldb); |
727 | 1001 | ||
728 | dev_dbg(&ndev->pdev->dev, "irq %d - pdb = %Lx\n", irq, pdb); | 1002 | dev_dbg(&ndev->pdev->dev, "irq %d - ldb = %Lx\n", irq, ldb); |
729 | 1003 | ||
730 | while (pdb) { | 1004 | while (ldb) { |
731 | i = __ffs(pdb); | 1005 | i = __ffs(ldb); |
732 | pdb &= pdb - 1; | 1006 | ldb &= ldb - 1; |
733 | bwd_callback_msix_irq(irq, &ndev->db_cb[i]); | 1007 | bwd_callback_msix_irq(irq, &ndev->db_cb[i]); |
734 | } | 1008 | } |
735 | } else { | 1009 | } else { |
736 | u16 pdb = readw(ndev->reg_ofs.pdb); | 1010 | u16 ldb = readw(ndev->reg_ofs.ldb); |
737 | 1011 | ||
738 | dev_dbg(&ndev->pdev->dev, "irq %d - pdb = %x sdb %x\n", irq, | 1012 | dev_dbg(&ndev->pdev->dev, "irq %d - ldb = %x\n", irq, ldb); |
739 | pdb, readw(ndev->reg_ofs.sdb)); | ||
740 | 1013 | ||
741 | if (pdb & SNB_DB_HW_LINK) { | 1014 | if (ldb & SNB_DB_HW_LINK) { |
742 | xeon_event_msix_irq(irq, dev); | 1015 | xeon_event_msix_irq(irq, dev); |
743 | pdb &= ~SNB_DB_HW_LINK; | 1016 | ldb &= ~SNB_DB_HW_LINK; |
744 | } | 1017 | } |
745 | 1018 | ||
746 | while (pdb) { | 1019 | while (ldb) { |
747 | i = __ffs(pdb); | 1020 | i = __ffs(ldb); |
748 | pdb &= pdb - 1; | 1021 | ldb &= ldb - 1; |
749 | xeon_callback_msix_irq(irq, &ndev->db_cb[i]); | 1022 | xeon_callback_msix_irq(irq, &ndev->db_cb[i]); |
750 | } | 1023 | } |
751 | } | 1024 | } |
@@ -758,16 +1031,15 @@ static int ntb_setup_msix(struct ntb_device *ndev) | |||
758 | struct pci_dev *pdev = ndev->pdev; | 1031 | struct pci_dev *pdev = ndev->pdev; |
759 | struct msix_entry *msix; | 1032 | struct msix_entry *msix; |
760 | int msix_entries; | 1033 | int msix_entries; |
761 | int rc, i, pos; | 1034 | int rc, i; |
762 | u16 val; | 1035 | u16 val; |
763 | 1036 | ||
764 | pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); | 1037 | if (!pdev->msix_cap) { |
765 | if (!pos) { | ||
766 | rc = -EIO; | 1038 | rc = -EIO; |
767 | goto err; | 1039 | goto err; |
768 | } | 1040 | } |
769 | 1041 | ||
770 | rc = pci_read_config_word(pdev, pos + PCI_MSIX_FLAGS, &val); | 1042 | rc = pci_read_config_word(pdev, pdev->msix_cap + PCI_MSIX_FLAGS, &val); |
771 | if (rc) | 1043 | if (rc) |
772 | goto err; | 1044 | goto err; |
773 | 1045 | ||
@@ -903,10 +1175,10 @@ static int ntb_setup_interrupts(struct ntb_device *ndev) | |||
903 | * Interrupt. The rest will be unmasked as callbacks are registered. | 1175 | * Interrupt. The rest will be unmasked as callbacks are registered. |
904 | */ | 1176 | */ |
905 | if (ndev->hw_type == BWD_HW) | 1177 | if (ndev->hw_type == BWD_HW) |
906 | writeq(~0, ndev->reg_ofs.pdb_mask); | 1178 | writeq(~0, ndev->reg_ofs.ldb_mask); |
907 | else | 1179 | else |
908 | writew(~(1 << ndev->limits.max_db_bits), | 1180 | writew(~(1 << ndev->limits.max_db_bits), |
909 | ndev->reg_ofs.pdb_mask); | 1181 | ndev->reg_ofs.ldb_mask); |
910 | 1182 | ||
911 | rc = ntb_setup_msix(ndev); | 1183 | rc = ntb_setup_msix(ndev); |
912 | if (!rc) | 1184 | if (!rc) |
@@ -935,9 +1207,9 @@ static void ntb_free_interrupts(struct ntb_device *ndev) | |||
935 | 1207 | ||
936 | /* mask interrupts */ | 1208 | /* mask interrupts */ |
937 | if (ndev->hw_type == BWD_HW) | 1209 | if (ndev->hw_type == BWD_HW) |
938 | writeq(~0, ndev->reg_ofs.pdb_mask); | 1210 | writeq(~0, ndev->reg_ofs.ldb_mask); |
939 | else | 1211 | else |
940 | writew(~0, ndev->reg_ofs.pdb_mask); | 1212 | writew(~0, ndev->reg_ofs.ldb_mask); |
941 | 1213 | ||
942 | if (ndev->num_msix) { | 1214 | if (ndev->num_msix) { |
943 | struct msix_entry *msix; | 1215 | struct msix_entry *msix; |
@@ -963,9 +1235,9 @@ static int ntb_create_callbacks(struct ntb_device *ndev) | |||
963 | { | 1235 | { |
964 | int i; | 1236 | int i; |
965 | 1237 | ||
966 | /* Checken-egg issue. We won't know how many callbacks are necessary | 1238 | /* Chicken-egg issue. We won't know how many callbacks are necessary |
967 | * until we see how many MSI-X vectors we get, but these pointers need | 1239 | * until we see how many MSI-X vectors we get, but these pointers need |
968 | * to be passed into the MSI-X register fucntion. So, we allocate the | 1240 | * to be passed into the MSI-X register function. So, we allocate the |
969 | * max, knowing that they might not all be used, to work around this. | 1241 | * max, knowing that they might not all be used, to work around this. |
970 | */ | 1242 | */ |
971 | ndev->db_cb = kcalloc(ndev->limits.max_db_bits, | 1243 | ndev->db_cb = kcalloc(ndev->limits.max_db_bits, |
@@ -992,6 +1264,28 @@ static void ntb_free_callbacks(struct ntb_device *ndev) | |||
992 | kfree(ndev->db_cb); | 1264 | kfree(ndev->db_cb); |
993 | } | 1265 | } |
994 | 1266 | ||
1267 | static void ntb_setup_debugfs(struct ntb_device *ndev) | ||
1268 | { | ||
1269 | if (!debugfs_initialized()) | ||
1270 | return; | ||
1271 | |||
1272 | if (!debugfs_dir) | ||
1273 | debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL); | ||
1274 | |||
1275 | ndev->debugfs_dir = debugfs_create_dir(pci_name(ndev->pdev), | ||
1276 | debugfs_dir); | ||
1277 | } | ||
1278 | |||
1279 | static void ntb_free_debugfs(struct ntb_device *ndev) | ||
1280 | { | ||
1281 | debugfs_remove_recursive(ndev->debugfs_dir); | ||
1282 | |||
1283 | if (debugfs_dir && simple_empty(debugfs_dir)) { | ||
1284 | debugfs_remove_recursive(debugfs_dir); | ||
1285 | debugfs_dir = NULL; | ||
1286 | } | ||
1287 | } | ||
1288 | |||
995 | static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 1289 | static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
996 | { | 1290 | { |
997 | struct ntb_device *ndev; | 1291 | struct ntb_device *ndev; |
@@ -1004,6 +1298,7 @@ static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1004 | ndev->pdev = pdev; | 1298 | ndev->pdev = pdev; |
1005 | ndev->link_status = NTB_LINK_DOWN; | 1299 | ndev->link_status = NTB_LINK_DOWN; |
1006 | pci_set_drvdata(pdev, ndev); | 1300 | pci_set_drvdata(pdev, ndev); |
1301 | ntb_setup_debugfs(ndev); | ||
1007 | 1302 | ||
1008 | rc = pci_enable_device(pdev); | 1303 | rc = pci_enable_device(pdev); |
1009 | if (rc) | 1304 | if (rc) |
@@ -1022,13 +1317,13 @@ static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1022 | goto err2; | 1317 | goto err2; |
1023 | } | 1318 | } |
1024 | 1319 | ||
1025 | for (i = 0; i < NTB_NUM_MW; i++) { | 1320 | for (i = 0; i < NTB_MAX_NUM_MW; i++) { |
1026 | ndev->mw[i].bar_sz = pci_resource_len(pdev, MW_TO_BAR(i)); | 1321 | ndev->mw[i].bar_sz = pci_resource_len(pdev, MW_TO_BAR(i)); |
1027 | ndev->mw[i].vbase = | 1322 | ndev->mw[i].vbase = |
1028 | ioremap_wc(pci_resource_start(pdev, MW_TO_BAR(i)), | 1323 | ioremap_wc(pci_resource_start(pdev, MW_TO_BAR(i)), |
1029 | ndev->mw[i].bar_sz); | 1324 | ndev->mw[i].bar_sz); |
1030 | dev_info(&pdev->dev, "MW %d size %llu\n", i, | 1325 | dev_info(&pdev->dev, "MW %d size %llu\n", i, |
1031 | pci_resource_len(pdev, MW_TO_BAR(i))); | 1326 | (unsigned long long) ndev->mw[i].bar_sz); |
1032 | if (!ndev->mw[i].vbase) { | 1327 | if (!ndev->mw[i].vbase) { |
1033 | dev_warn(&pdev->dev, "Cannot remap BAR %d\n", | 1328 | dev_warn(&pdev->dev, "Cannot remap BAR %d\n", |
1034 | MW_TO_BAR(i)); | 1329 | MW_TO_BAR(i)); |
@@ -1100,6 +1395,7 @@ err2: | |||
1100 | err1: | 1395 | err1: |
1101 | pci_disable_device(pdev); | 1396 | pci_disable_device(pdev); |
1102 | err: | 1397 | err: |
1398 | ntb_free_debugfs(ndev); | ||
1103 | kfree(ndev); | 1399 | kfree(ndev); |
1104 | 1400 | ||
1105 | dev_err(&pdev->dev, "Error loading %s module\n", KBUILD_MODNAME); | 1401 | dev_err(&pdev->dev, "Error loading %s module\n", KBUILD_MODNAME); |
@@ -1114,7 +1410,7 @@ static void ntb_pci_remove(struct pci_dev *pdev) | |||
1114 | 1410 | ||
1115 | /* Bring NTB link down */ | 1411 | /* Bring NTB link down */ |
1116 | ntb_cntl = readl(ndev->reg_ofs.lnk_cntl); | 1412 | ntb_cntl = readl(ndev->reg_ofs.lnk_cntl); |
1117 | ntb_cntl |= NTB_LINK_DISABLE; | 1413 | ntb_cntl |= NTB_CNTL_LINK_DISABLE; |
1118 | writel(ntb_cntl, ndev->reg_ofs.lnk_cntl); | 1414 | writel(ntb_cntl, ndev->reg_ofs.lnk_cntl); |
1119 | 1415 | ||
1120 | ntb_transport_free(ndev->ntb_transport); | 1416 | ntb_transport_free(ndev->ntb_transport); |
@@ -1123,12 +1419,13 @@ static void ntb_pci_remove(struct pci_dev *pdev) | |||
1123 | ntb_free_callbacks(ndev); | 1419 | ntb_free_callbacks(ndev); |
1124 | ntb_device_free(ndev); | 1420 | ntb_device_free(ndev); |
1125 | 1421 | ||
1126 | for (i = 0; i < NTB_NUM_MW; i++) | 1422 | for (i = 0; i < NTB_MAX_NUM_MW; i++) |
1127 | iounmap(ndev->mw[i].vbase); | 1423 | iounmap(ndev->mw[i].vbase); |
1128 | 1424 | ||
1129 | iounmap(ndev->reg_base); | 1425 | iounmap(ndev->reg_base); |
1130 | pci_release_selected_regions(pdev, NTB_BAR_MASK); | 1426 | pci_release_selected_regions(pdev, NTB_BAR_MASK); |
1131 | pci_disable_device(pdev); | 1427 | pci_disable_device(pdev); |
1428 | ntb_free_debugfs(ndev); | ||
1132 | kfree(ndev); | 1429 | kfree(ndev); |
1133 | } | 1430 | } |
1134 | 1431 | ||
diff --git a/drivers/ntb/ntb_hw.h b/drivers/ntb/ntb_hw.h index 3a3038ca83e6..0a31cedae7d4 100644 --- a/drivers/ntb/ntb_hw.h +++ b/drivers/ntb/ntb_hw.h | |||
@@ -47,16 +47,36 @@ | |||
47 | */ | 47 | */ |
48 | 48 | ||
49 | #define PCI_DEVICE_ID_INTEL_NTB_B2B_JSF 0x3725 | 49 | #define PCI_DEVICE_ID_INTEL_NTB_B2B_JSF 0x3725 |
50 | #define PCI_DEVICE_ID_INTEL_NTB_CLASSIC_JSF 0x3726 | 50 | #define PCI_DEVICE_ID_INTEL_NTB_PS_JSF 0x3726 |
51 | #define PCI_DEVICE_ID_INTEL_NTB_RP_JSF 0x3727 | 51 | #define PCI_DEVICE_ID_INTEL_NTB_SS_JSF 0x3727 |
52 | #define PCI_DEVICE_ID_INTEL_NTB_RP_SNB 0x3C08 | ||
53 | #define PCI_DEVICE_ID_INTEL_NTB_B2B_SNB 0x3C0D | 52 | #define PCI_DEVICE_ID_INTEL_NTB_B2B_SNB 0x3C0D |
54 | #define PCI_DEVICE_ID_INTEL_NTB_CLASSIC_SNB 0x3C0E | 53 | #define PCI_DEVICE_ID_INTEL_NTB_PS_SNB 0x3C0E |
55 | #define PCI_DEVICE_ID_INTEL_NTB_2ND_SNB 0x3C0F | 54 | #define PCI_DEVICE_ID_INTEL_NTB_SS_SNB 0x3C0F |
55 | #define PCI_DEVICE_ID_INTEL_NTB_B2B_IVT 0x0E0D | ||
56 | #define PCI_DEVICE_ID_INTEL_NTB_PS_IVT 0x0E0E | ||
57 | #define PCI_DEVICE_ID_INTEL_NTB_SS_IVT 0x0E0F | ||
58 | #define PCI_DEVICE_ID_INTEL_NTB_B2B_HSX 0x2F0D | ||
59 | #define PCI_DEVICE_ID_INTEL_NTB_PS_HSX 0x2F0E | ||
60 | #define PCI_DEVICE_ID_INTEL_NTB_SS_HSX 0x2F0F | ||
56 | #define PCI_DEVICE_ID_INTEL_NTB_B2B_BWD 0x0C4E | 61 | #define PCI_DEVICE_ID_INTEL_NTB_B2B_BWD 0x0C4E |
57 | 62 | ||
58 | #define msix_table_size(control) ((control & PCI_MSIX_FLAGS_QSIZE)+1) | 63 | #define msix_table_size(control) ((control & PCI_MSIX_FLAGS_QSIZE)+1) |
59 | 64 | ||
65 | #ifndef readq | ||
66 | static inline u64 readq(void __iomem *addr) | ||
67 | { | ||
68 | return readl(addr) | (((u64) readl(addr + 4)) << 32LL); | ||
69 | } | ||
70 | #endif | ||
71 | |||
72 | #ifndef writeq | ||
73 | static inline void writeq(u64 val, void __iomem *addr) | ||
74 | { | ||
75 | writel(val & 0xffffffff, addr); | ||
76 | writel(val >> 32, addr + 4); | ||
77 | } | ||
78 | #endif | ||
79 | |||
60 | #define NTB_BAR_MMIO 0 | 80 | #define NTB_BAR_MMIO 0 |
61 | #define NTB_BAR_23 2 | 81 | #define NTB_BAR_23 2 |
62 | #define NTB_BAR_45 4 | 82 | #define NTB_BAR_45 4 |
@@ -68,7 +88,7 @@ | |||
68 | 88 | ||
69 | #define NTB_HB_TIMEOUT msecs_to_jiffies(1000) | 89 | #define NTB_HB_TIMEOUT msecs_to_jiffies(1000) |
70 | 90 | ||
71 | #define NTB_NUM_MW 2 | 91 | #define NTB_MAX_NUM_MW 2 |
72 | 92 | ||
73 | enum ntb_hw_event { | 93 | enum ntb_hw_event { |
74 | NTB_EVENT_SW_EVENT0 = 0, | 94 | NTB_EVENT_SW_EVENT0 = 0, |
@@ -96,18 +116,19 @@ struct ntb_device { | |||
96 | struct pci_dev *pdev; | 116 | struct pci_dev *pdev; |
97 | struct msix_entry *msix_entries; | 117 | struct msix_entry *msix_entries; |
98 | void __iomem *reg_base; | 118 | void __iomem *reg_base; |
99 | struct ntb_mw mw[NTB_NUM_MW]; | 119 | struct ntb_mw mw[NTB_MAX_NUM_MW]; |
100 | struct { | 120 | struct { |
101 | unsigned int max_spads; | 121 | unsigned char max_mw; |
102 | unsigned int max_db_bits; | 122 | unsigned char max_spads; |
103 | unsigned int msix_cnt; | 123 | unsigned char max_db_bits; |
124 | unsigned char msix_cnt; | ||
104 | } limits; | 125 | } limits; |
105 | struct { | 126 | struct { |
106 | void __iomem *pdb; | 127 | void __iomem *ldb; |
107 | void __iomem *pdb_mask; | 128 | void __iomem *ldb_mask; |
108 | void __iomem *sdb; | 129 | void __iomem *rdb; |
109 | void __iomem *sbar2_xlat; | 130 | void __iomem *bar2_xlat; |
110 | void __iomem *sbar4_xlat; | 131 | void __iomem *bar4_xlat; |
111 | void __iomem *spad_write; | 132 | void __iomem *spad_write; |
112 | void __iomem *spad_read; | 133 | void __iomem *spad_read; |
113 | void __iomem *lnk_cntl; | 134 | void __iomem *lnk_cntl; |
@@ -124,12 +145,45 @@ struct ntb_device { | |||
124 | unsigned char num_msix; | 145 | unsigned char num_msix; |
125 | unsigned char bits_per_vector; | 146 | unsigned char bits_per_vector; |
126 | unsigned char max_cbs; | 147 | unsigned char max_cbs; |
148 | unsigned char link_width; | ||
149 | unsigned char link_speed; | ||
127 | unsigned char link_status; | 150 | unsigned char link_status; |
151 | |||
128 | struct delayed_work hb_timer; | 152 | struct delayed_work hb_timer; |
129 | unsigned long last_ts; | 153 | unsigned long last_ts; |
154 | |||
155 | struct delayed_work lr_timer; | ||
156 | |||
157 | struct dentry *debugfs_dir; | ||
130 | }; | 158 | }; |
131 | 159 | ||
132 | /** | 160 | /** |
161 | * ntb_max_cbs() - return the max callbacks | ||
162 | * @ndev: pointer to ntb_device instance | ||
163 | * | ||
164 | * Given the ntb pointer, return the maximum number of callbacks | ||
165 | * | ||
166 | * RETURNS: the maximum number of callbacks | ||
167 | */ | ||
168 | static inline unsigned char ntb_max_cbs(struct ntb_device *ndev) | ||
169 | { | ||
170 | return ndev->max_cbs; | ||
171 | } | ||
172 | |||
173 | /** | ||
174 | * ntb_max_mw() - return the max number of memory windows | ||
175 | * @ndev: pointer to ntb_device instance | ||
176 | * | ||
177 | * Given the ntb pointer, return the maximum number of memory windows | ||
178 | * | ||
179 | * RETURNS: the maximum number of memory windows | ||
180 | */ | ||
181 | static inline unsigned char ntb_max_mw(struct ntb_device *ndev) | ||
182 | { | ||
183 | return ndev->limits.max_mw; | ||
184 | } | ||
185 | |||
186 | /** | ||
133 | * ntb_hw_link_status() - return the hardware link status | 187 | * ntb_hw_link_status() - return the hardware link status |
134 | * @ndev: pointer to ntb_device instance | 188 | * @ndev: pointer to ntb_device instance |
135 | * | 189 | * |
@@ -146,7 +200,7 @@ static inline bool ntb_hw_link_status(struct ntb_device *ndev) | |||
146 | * ntb_query_pdev() - return the pci_dev pointer | 200 | * ntb_query_pdev() - return the pci_dev pointer |
147 | * @ndev: pointer to ntb_device instance | 201 | * @ndev: pointer to ntb_device instance |
148 | * | 202 | * |
149 | * Given the ntb pointer return the pci_dev pointerfor the NTB hardware device | 203 | * Given the ntb pointer, return the pci_dev pointer for the NTB hardware device |
150 | * | 204 | * |
151 | * RETURNS: a pointer to the ntb pci_dev | 205 | * RETURNS: a pointer to the ntb pci_dev |
152 | */ | 206 | */ |
@@ -155,6 +209,20 @@ static inline struct pci_dev *ntb_query_pdev(struct ntb_device *ndev) | |||
155 | return ndev->pdev; | 209 | return ndev->pdev; |
156 | } | 210 | } |
157 | 211 | ||
212 | /** | ||
213 | * ntb_query_debugfs() - return the debugfs pointer | ||
214 | * @ndev: pointer to ntb_device instance | ||
215 | * | ||
216 | * Given the ntb pointer, return the debugfs directory pointer for the NTB | ||
217 | * hardware device | ||
218 | * | ||
219 | * RETURNS: a pointer to the debugfs directory | ||
220 | */ | ||
221 | static inline struct dentry *ntb_query_debugfs(struct ntb_device *ndev) | ||
222 | { | ||
223 | return ndev->debugfs_dir; | ||
224 | } | ||
225 | |||
158 | struct ntb_device *ntb_register_transport(struct pci_dev *pdev, | 226 | struct ntb_device *ntb_register_transport(struct pci_dev *pdev, |
159 | void *transport); | 227 | void *transport); |
160 | void ntb_unregister_transport(struct ntb_device *ndev); | 228 | void ntb_unregister_transport(struct ntb_device *ndev); |
@@ -172,9 +240,10 @@ int ntb_write_local_spad(struct ntb_device *ndev, unsigned int idx, u32 val); | |||
172 | int ntb_read_local_spad(struct ntb_device *ndev, unsigned int idx, u32 *val); | 240 | int ntb_read_local_spad(struct ntb_device *ndev, unsigned int idx, u32 *val); |
173 | int ntb_write_remote_spad(struct ntb_device *ndev, unsigned int idx, u32 val); | 241 | int ntb_write_remote_spad(struct ntb_device *ndev, unsigned int idx, u32 val); |
174 | int ntb_read_remote_spad(struct ntb_device *ndev, unsigned int idx, u32 *val); | 242 | int ntb_read_remote_spad(struct ntb_device *ndev, unsigned int idx, u32 *val); |
243 | resource_size_t ntb_get_mw_base(struct ntb_device *ndev, unsigned int mw); | ||
175 | void __iomem *ntb_get_mw_vbase(struct ntb_device *ndev, unsigned int mw); | 244 | void __iomem *ntb_get_mw_vbase(struct ntb_device *ndev, unsigned int mw); |
176 | resource_size_t ntb_get_mw_size(struct ntb_device *ndev, unsigned int mw); | 245 | u64 ntb_get_mw_size(struct ntb_device *ndev, unsigned int mw); |
177 | void ntb_ring_sdb(struct ntb_device *ndev, unsigned int idx); | 246 | void ntb_ring_doorbell(struct ntb_device *ndev, unsigned int idx); |
178 | void *ntb_find_transport(struct pci_dev *pdev); | 247 | void *ntb_find_transport(struct pci_dev *pdev); |
179 | 248 | ||
180 | int ntb_transport_init(struct pci_dev *pdev); | 249 | int ntb_transport_init(struct pci_dev *pdev); |
diff --git a/drivers/ntb/ntb_regs.h b/drivers/ntb/ntb_regs.h index 5bfa8c06c059..aa4bdd393c58 100644 --- a/drivers/ntb/ntb_regs.h +++ b/drivers/ntb/ntb_regs.h | |||
@@ -46,23 +46,24 @@ | |||
46 | * Jon Mason <jon.mason@intel.com> | 46 | * Jon Mason <jon.mason@intel.com> |
47 | */ | 47 | */ |
48 | 48 | ||
49 | #define NTB_LINK_ENABLE 0x0000 | ||
50 | #define NTB_LINK_DISABLE 0x0002 | ||
51 | #define NTB_LINK_STATUS_ACTIVE 0x2000 | 49 | #define NTB_LINK_STATUS_ACTIVE 0x2000 |
52 | #define NTB_LINK_SPEED_MASK 0x000f | 50 | #define NTB_LINK_SPEED_MASK 0x000f |
53 | #define NTB_LINK_WIDTH_MASK 0x03f0 | 51 | #define NTB_LINK_WIDTH_MASK 0x03f0 |
54 | 52 | ||
55 | #define SNB_MSIX_CNT 4 | 53 | #define SNB_MSIX_CNT 4 |
56 | #define SNB_MAX_SPADS 16 | 54 | #define SNB_MAX_B2B_SPADS 16 |
57 | #define SNB_MAX_COMPAT_SPADS 8 | 55 | #define SNB_MAX_COMPAT_SPADS 16 |
58 | /* Reserve the uppermost bit for link interrupt */ | 56 | /* Reserve the uppermost bit for link interrupt */ |
59 | #define SNB_MAX_DB_BITS 15 | 57 | #define SNB_MAX_DB_BITS 15 |
60 | #define SNB_DB_BITS_PER_VEC 5 | 58 | #define SNB_DB_BITS_PER_VEC 5 |
59 | #define SNB_MAX_MW 2 | ||
60 | #define SNB_ERRATA_MAX_MW 1 | ||
61 | 61 | ||
62 | #define SNB_DB_HW_LINK 0x8000 | 62 | #define SNB_DB_HW_LINK 0x8000 |
63 | 63 | ||
64 | #define SNB_PCICMD_OFFSET 0x0504 | 64 | #define SNB_PCICMD_OFFSET 0x0504 |
65 | #define SNB_DEVCTRL_OFFSET 0x0598 | 65 | #define SNB_DEVCTRL_OFFSET 0x0598 |
66 | #define SNB_SLINK_STATUS_OFFSET 0x05A2 | ||
66 | #define SNB_LINK_STATUS_OFFSET 0x01A2 | 67 | #define SNB_LINK_STATUS_OFFSET 0x01A2 |
67 | 68 | ||
68 | #define SNB_PBAR2LMT_OFFSET 0x0000 | 69 | #define SNB_PBAR2LMT_OFFSET 0x0000 |
@@ -74,6 +75,9 @@ | |||
74 | #define SNB_SBAR2XLAT_OFFSET 0x0030 | 75 | #define SNB_SBAR2XLAT_OFFSET 0x0030 |
75 | #define SNB_SBAR4XLAT_OFFSET 0x0038 | 76 | #define SNB_SBAR4XLAT_OFFSET 0x0038 |
76 | #define SNB_SBAR0BASE_OFFSET 0x0040 | 77 | #define SNB_SBAR0BASE_OFFSET 0x0040 |
78 | #define SNB_SBAR0BASE_OFFSET 0x0040 | ||
79 | #define SNB_SBAR2BASE_OFFSET 0x0048 | ||
80 | #define SNB_SBAR4BASE_OFFSET 0x0050 | ||
77 | #define SNB_SBAR2BASE_OFFSET 0x0048 | 81 | #define SNB_SBAR2BASE_OFFSET 0x0048 |
78 | #define SNB_SBAR4BASE_OFFSET 0x0050 | 82 | #define SNB_SBAR4BASE_OFFSET 0x0050 |
79 | #define SNB_NTBCNTL_OFFSET 0x0058 | 83 | #define SNB_NTBCNTL_OFFSET 0x0058 |
@@ -88,19 +92,28 @@ | |||
88 | #define SNB_WCCNTRL_OFFSET 0x00e0 | 92 | #define SNB_WCCNTRL_OFFSET 0x00e0 |
89 | #define SNB_B2B_SPAD_OFFSET 0x0100 | 93 | #define SNB_B2B_SPAD_OFFSET 0x0100 |
90 | #define SNB_B2B_DOORBELL_OFFSET 0x0140 | 94 | #define SNB_B2B_DOORBELL_OFFSET 0x0140 |
91 | #define SNB_B2B_XLAT_OFFSET 0x0144 | 95 | #define SNB_B2B_XLAT_OFFSETL 0x0144 |
96 | #define SNB_B2B_XLAT_OFFSETU 0x0148 | ||
97 | |||
98 | #define SNB_MBAR01_USD_ADDR 0x000000210000000CULL | ||
99 | #define SNB_MBAR23_USD_ADDR 0x000000410000000CULL | ||
100 | #define SNB_MBAR45_USD_ADDR 0x000000810000000CULL | ||
101 | #define SNB_MBAR01_DSD_ADDR 0x000000200000000CULL | ||
102 | #define SNB_MBAR23_DSD_ADDR 0x000000400000000CULL | ||
103 | #define SNB_MBAR45_DSD_ADDR 0x000000800000000CULL | ||
92 | 104 | ||
93 | #define BWD_MSIX_CNT 34 | 105 | #define BWD_MSIX_CNT 34 |
94 | #define BWD_MAX_SPADS 16 | 106 | #define BWD_MAX_SPADS 16 |
95 | #define BWD_MAX_COMPAT_SPADS 16 | ||
96 | #define BWD_MAX_DB_BITS 34 | 107 | #define BWD_MAX_DB_BITS 34 |
97 | #define BWD_DB_BITS_PER_VEC 1 | 108 | #define BWD_DB_BITS_PER_VEC 1 |
109 | #define BWD_MAX_MW 2 | ||
98 | 110 | ||
99 | #define BWD_PCICMD_OFFSET 0xb004 | 111 | #define BWD_PCICMD_OFFSET 0xb004 |
100 | #define BWD_MBAR23_OFFSET 0xb018 | 112 | #define BWD_MBAR23_OFFSET 0xb018 |
101 | #define BWD_MBAR45_OFFSET 0xb020 | 113 | #define BWD_MBAR45_OFFSET 0xb020 |
102 | #define BWD_DEVCTRL_OFFSET 0xb048 | 114 | #define BWD_DEVCTRL_OFFSET 0xb048 |
103 | #define BWD_LINK_STATUS_OFFSET 0xb052 | 115 | #define BWD_LINK_STATUS_OFFSET 0xb052 |
116 | #define BWD_ERRCORSTS_OFFSET 0xb110 | ||
104 | 117 | ||
105 | #define BWD_SBAR2XLAT_OFFSET 0x0008 | 118 | #define BWD_SBAR2XLAT_OFFSET 0x0008 |
106 | #define BWD_SBAR4XLAT_OFFSET 0x0010 | 119 | #define BWD_SBAR4XLAT_OFFSET 0x0010 |
@@ -118,6 +131,22 @@ | |||
118 | #define BWD_B2B_SPADSEMA_OFFSET 0x80c0 | 131 | #define BWD_B2B_SPADSEMA_OFFSET 0x80c0 |
119 | #define BWD_B2B_STKYSPAD_OFFSET 0x80c4 | 132 | #define BWD_B2B_STKYSPAD_OFFSET 0x80c4 |
120 | 133 | ||
134 | #define BWD_MODPHY_PCSREG4 0x1c004 | ||
135 | #define BWD_MODPHY_PCSREG6 0x1c006 | ||
136 | |||
137 | #define BWD_IP_BASE 0xC000 | ||
138 | #define BWD_DESKEWSTS_OFFSET (BWD_IP_BASE + 0x3024) | ||
139 | #define BWD_LTSSMERRSTS0_OFFSET (BWD_IP_BASE + 0x3180) | ||
140 | #define BWD_LTSSMSTATEJMP_OFFSET (BWD_IP_BASE + 0x3040) | ||
141 | #define BWD_IBSTERRRCRVSTS0_OFFSET (BWD_IP_BASE + 0x3324) | ||
142 | |||
143 | #define BWD_DESKEWSTS_DBERR (1 << 15) | ||
144 | #define BWD_LTSSMERRSTS0_UNEXPECTEDEI (1 << 20) | ||
145 | #define BWD_LTSSMSTATEJMP_FORCEDETECT (1 << 2) | ||
146 | #define BWD_IBIST_ERR_OFLOW 0x7FFF7FFF | ||
147 | |||
148 | #define NTB_CNTL_CFG_LOCK (1 << 0) | ||
149 | #define NTB_CNTL_LINK_DISABLE (1 << 1) | ||
121 | #define NTB_CNTL_BAR23_SNOOP (1 << 2) | 150 | #define NTB_CNTL_BAR23_SNOOP (1 << 2) |
122 | #define NTB_CNTL_BAR45_SNOOP (1 << 6) | 151 | #define NTB_CNTL_BAR45_SNOOP (1 << 6) |
123 | #define BWD_CNTL_LINK_DOWN (1 << 16) | 152 | #define BWD_CNTL_LINK_DOWN (1 << 16) |
@@ -128,12 +157,3 @@ | |||
128 | #define BWD_PPD_INIT_LINK 0x0008 | 157 | #define BWD_PPD_INIT_LINK 0x0008 |
129 | #define BWD_PPD_CONN_TYPE 0x0300 | 158 | #define BWD_PPD_CONN_TYPE 0x0300 |
130 | #define BWD_PPD_DEV_TYPE 0x1000 | 159 | #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 f8d7081ee301..12a9e83c008b 100644 --- a/drivers/ntb/ntb_transport.c +++ b/drivers/ntb/ntb_transport.c | |||
@@ -47,6 +47,7 @@ | |||
47 | */ | 47 | */ |
48 | #include <linux/debugfs.h> | 48 | #include <linux/debugfs.h> |
49 | #include <linux/delay.h> | 49 | #include <linux/delay.h> |
50 | #include <linux/dmaengine.h> | ||
50 | #include <linux/dma-mapping.h> | 51 | #include <linux/dma-mapping.h> |
51 | #include <linux/errno.h> | 52 | #include <linux/errno.h> |
52 | #include <linux/export.h> | 53 | #include <linux/export.h> |
@@ -64,10 +65,14 @@ static unsigned int transport_mtu = 0x401E; | |||
64 | module_param(transport_mtu, uint, 0644); | 65 | module_param(transport_mtu, uint, 0644); |
65 | MODULE_PARM_DESC(transport_mtu, "Maximum size of NTB transport packets"); | 66 | MODULE_PARM_DESC(transport_mtu, "Maximum size of NTB transport packets"); |
66 | 67 | ||
67 | static unsigned char max_num_clients = 2; | 68 | static unsigned char max_num_clients; |
68 | module_param(max_num_clients, byte, 0644); | 69 | module_param(max_num_clients, byte, 0644); |
69 | MODULE_PARM_DESC(max_num_clients, "Maximum number of NTB transport clients"); | 70 | MODULE_PARM_DESC(max_num_clients, "Maximum number of NTB transport clients"); |
70 | 71 | ||
72 | static unsigned int copy_bytes = 1024; | ||
73 | module_param(copy_bytes, uint, 0644); | ||
74 | MODULE_PARM_DESC(copy_bytes, "Threshold under which NTB will use the CPU to copy instead of DMA"); | ||
75 | |||
71 | struct ntb_queue_entry { | 76 | struct ntb_queue_entry { |
72 | /* ntb_queue list reference */ | 77 | /* ntb_queue list reference */ |
73 | struct list_head entry; | 78 | struct list_head entry; |
@@ -76,6 +81,13 @@ struct ntb_queue_entry { | |||
76 | void *buf; | 81 | void *buf; |
77 | unsigned int len; | 82 | unsigned int len; |
78 | unsigned int flags; | 83 | unsigned int flags; |
84 | |||
85 | struct ntb_transport_qp *qp; | ||
86 | union { | ||
87 | struct ntb_payload_header __iomem *tx_hdr; | ||
88 | struct ntb_payload_header *rx_hdr; | ||
89 | }; | ||
90 | unsigned int index; | ||
79 | }; | 91 | }; |
80 | 92 | ||
81 | struct ntb_rx_info { | 93 | struct ntb_rx_info { |
@@ -86,6 +98,7 @@ struct ntb_transport_qp { | |||
86 | struct ntb_transport *transport; | 98 | struct ntb_transport *transport; |
87 | struct ntb_device *ndev; | 99 | struct ntb_device *ndev; |
88 | void *cb_data; | 100 | void *cb_data; |
101 | struct dma_chan *dma_chan; | ||
89 | 102 | ||
90 | bool client_ready; | 103 | bool client_ready; |
91 | bool qp_link; | 104 | bool qp_link; |
@@ -99,6 +112,7 @@ struct ntb_transport_qp { | |||
99 | struct list_head tx_free_q; | 112 | struct list_head tx_free_q; |
100 | spinlock_t ntb_tx_free_q_lock; | 113 | spinlock_t ntb_tx_free_q_lock; |
101 | void __iomem *tx_mw; | 114 | void __iomem *tx_mw; |
115 | dma_addr_t tx_mw_phys; | ||
102 | unsigned int tx_index; | 116 | unsigned int tx_index; |
103 | unsigned int tx_max_entry; | 117 | unsigned int tx_max_entry; |
104 | unsigned int tx_max_frame; | 118 | unsigned int tx_max_frame; |
@@ -114,6 +128,7 @@ struct ntb_transport_qp { | |||
114 | unsigned int rx_index; | 128 | unsigned int rx_index; |
115 | unsigned int rx_max_entry; | 129 | unsigned int rx_max_entry; |
116 | unsigned int rx_max_frame; | 130 | unsigned int rx_max_frame; |
131 | dma_cookie_t last_cookie; | ||
117 | 132 | ||
118 | void (*event_handler) (void *data, int status); | 133 | void (*event_handler) (void *data, int status); |
119 | struct delayed_work link_work; | 134 | struct delayed_work link_work; |
@@ -129,9 +144,14 @@ struct ntb_transport_qp { | |||
129 | u64 rx_err_no_buf; | 144 | u64 rx_err_no_buf; |
130 | u64 rx_err_oflow; | 145 | u64 rx_err_oflow; |
131 | u64 rx_err_ver; | 146 | u64 rx_err_ver; |
147 | u64 rx_memcpy; | ||
148 | u64 rx_async; | ||
132 | u64 tx_bytes; | 149 | u64 tx_bytes; |
133 | u64 tx_pkts; | 150 | u64 tx_pkts; |
134 | u64 tx_ring_full; | 151 | u64 tx_ring_full; |
152 | u64 tx_err_no_buf; | ||
153 | u64 tx_memcpy; | ||
154 | u64 tx_async; | ||
135 | }; | 155 | }; |
136 | 156 | ||
137 | struct ntb_transport_mw { | 157 | struct ntb_transport_mw { |
@@ -150,14 +170,13 @@ struct ntb_transport { | |||
150 | struct list_head client_devs; | 170 | struct list_head client_devs; |
151 | 171 | ||
152 | struct ntb_device *ndev; | 172 | struct ntb_device *ndev; |
153 | struct ntb_transport_mw mw[NTB_NUM_MW]; | 173 | struct ntb_transport_mw *mw; |
154 | struct ntb_transport_qp *qps; | 174 | struct ntb_transport_qp *qps; |
155 | unsigned int max_qps; | 175 | unsigned int max_qps; |
156 | unsigned long qp_bitmap; | 176 | unsigned long qp_bitmap; |
157 | bool transport_link; | 177 | bool transport_link; |
158 | struct delayed_work link_work; | 178 | struct delayed_work link_work; |
159 | struct work_struct link_cleanup; | 179 | struct work_struct link_cleanup; |
160 | struct dentry *debugfs_dir; | ||
161 | }; | 180 | }; |
162 | 181 | ||
163 | enum { | 182 | enum { |
@@ -183,7 +202,7 @@ enum { | |||
183 | MAX_SPAD, | 202 | MAX_SPAD, |
184 | }; | 203 | }; |
185 | 204 | ||
186 | #define QP_TO_MW(qp) ((qp) % NTB_NUM_MW) | 205 | #define QP_TO_MW(ndev, qp) ((qp) % ntb_max_mw(ndev)) |
187 | #define NTB_QP_DEF_NUM_ENTRIES 100 | 206 | #define NTB_QP_DEF_NUM_ENTRIES 100 |
188 | #define NTB_LINK_DOWN_TIMEOUT 10 | 207 | #define NTB_LINK_DOWN_TIMEOUT 10 |
189 | 208 | ||
@@ -382,7 +401,7 @@ static ssize_t debugfs_read(struct file *filp, char __user *ubuf, size_t count, | |||
382 | char *buf; | 401 | char *buf; |
383 | ssize_t ret, out_offset, out_count; | 402 | ssize_t ret, out_offset, out_count; |
384 | 403 | ||
385 | out_count = 600; | 404 | out_count = 1000; |
386 | 405 | ||
387 | buf = kmalloc(out_count, GFP_KERNEL); | 406 | buf = kmalloc(out_count, GFP_KERNEL); |
388 | if (!buf) | 407 | if (!buf) |
@@ -397,6 +416,10 @@ static ssize_t debugfs_read(struct file *filp, char __user *ubuf, size_t count, | |||
397 | out_offset += snprintf(buf + out_offset, out_count - out_offset, | 416 | out_offset += snprintf(buf + out_offset, out_count - out_offset, |
398 | "rx_pkts - \t%llu\n", qp->rx_pkts); | 417 | "rx_pkts - \t%llu\n", qp->rx_pkts); |
399 | out_offset += snprintf(buf + out_offset, out_count - out_offset, | 418 | out_offset += snprintf(buf + out_offset, out_count - out_offset, |
419 | "rx_memcpy - \t%llu\n", qp->rx_memcpy); | ||
420 | out_offset += snprintf(buf + out_offset, out_count - out_offset, | ||
421 | "rx_async - \t%llu\n", qp->rx_async); | ||
422 | out_offset += snprintf(buf + out_offset, out_count - out_offset, | ||
400 | "rx_ring_empty - %llu\n", qp->rx_ring_empty); | 423 | "rx_ring_empty - %llu\n", qp->rx_ring_empty); |
401 | out_offset += snprintf(buf + out_offset, out_count - out_offset, | 424 | out_offset += snprintf(buf + out_offset, out_count - out_offset, |
402 | "rx_err_no_buf - %llu\n", qp->rx_err_no_buf); | 425 | "rx_err_no_buf - %llu\n", qp->rx_err_no_buf); |
@@ -416,8 +439,14 @@ static ssize_t debugfs_read(struct file *filp, char __user *ubuf, size_t count, | |||
416 | out_offset += snprintf(buf + out_offset, out_count - out_offset, | 439 | out_offset += snprintf(buf + out_offset, out_count - out_offset, |
417 | "tx_pkts - \t%llu\n", qp->tx_pkts); | 440 | "tx_pkts - \t%llu\n", qp->tx_pkts); |
418 | out_offset += snprintf(buf + out_offset, out_count - out_offset, | 441 | out_offset += snprintf(buf + out_offset, out_count - out_offset, |
442 | "tx_memcpy - \t%llu\n", qp->tx_memcpy); | ||
443 | out_offset += snprintf(buf + out_offset, out_count - out_offset, | ||
444 | "tx_async - \t%llu\n", qp->tx_async); | ||
445 | out_offset += snprintf(buf + out_offset, out_count - out_offset, | ||
419 | "tx_ring_full - \t%llu\n", qp->tx_ring_full); | 446 | "tx_ring_full - \t%llu\n", qp->tx_ring_full); |
420 | out_offset += snprintf(buf + out_offset, out_count - out_offset, | 447 | out_offset += snprintf(buf + out_offset, out_count - out_offset, |
448 | "tx_err_no_buf - %llu\n", qp->tx_err_no_buf); | ||
449 | out_offset += snprintf(buf + out_offset, out_count - out_offset, | ||
421 | "tx_mw - \t%p\n", qp->tx_mw); | 450 | "tx_mw - \t%p\n", qp->tx_mw); |
422 | out_offset += snprintf(buf + out_offset, out_count - out_offset, | 451 | out_offset += snprintf(buf + out_offset, out_count - out_offset, |
423 | "tx_index - \t%u\n", qp->tx_index); | 452 | "tx_index - \t%u\n", qp->tx_index); |
@@ -475,22 +504,25 @@ static void ntb_transport_setup_qp_mw(struct ntb_transport *nt, | |||
475 | { | 504 | { |
476 | struct ntb_transport_qp *qp = &nt->qps[qp_num]; | 505 | struct ntb_transport_qp *qp = &nt->qps[qp_num]; |
477 | unsigned int rx_size, num_qps_mw; | 506 | unsigned int rx_size, num_qps_mw; |
478 | u8 mw_num = QP_TO_MW(qp_num); | 507 | u8 mw_num, mw_max; |
479 | unsigned int i; | 508 | unsigned int i; |
480 | 509 | ||
510 | mw_max = ntb_max_mw(nt->ndev); | ||
511 | mw_num = QP_TO_MW(nt->ndev, qp_num); | ||
512 | |||
481 | WARN_ON(nt->mw[mw_num].virt_addr == NULL); | 513 | WARN_ON(nt->mw[mw_num].virt_addr == NULL); |
482 | 514 | ||
483 | if (nt->max_qps % NTB_NUM_MW && mw_num < nt->max_qps % NTB_NUM_MW) | 515 | if (nt->max_qps % mw_max && mw_num < nt->max_qps % mw_max) |
484 | num_qps_mw = nt->max_qps / NTB_NUM_MW + 1; | 516 | num_qps_mw = nt->max_qps / mw_max + 1; |
485 | else | 517 | else |
486 | num_qps_mw = nt->max_qps / NTB_NUM_MW; | 518 | num_qps_mw = nt->max_qps / mw_max; |
487 | 519 | ||
488 | rx_size = (unsigned int) nt->mw[mw_num].size / num_qps_mw; | 520 | rx_size = (unsigned int) nt->mw[mw_num].size / num_qps_mw; |
489 | qp->remote_rx_info = nt->mw[mw_num].virt_addr + | 521 | qp->rx_buff = nt->mw[mw_num].virt_addr + qp_num / mw_max * rx_size; |
490 | (qp_num / NTB_NUM_MW * rx_size); | ||
491 | rx_size -= sizeof(struct ntb_rx_info); | 522 | rx_size -= sizeof(struct ntb_rx_info); |
492 | 523 | ||
493 | qp->rx_buff = qp->remote_rx_info + 1; | 524 | qp->remote_rx_info = qp->rx_buff + rx_size; |
525 | |||
494 | /* Due to housekeeping, there must be atleast 2 buffs */ | 526 | /* Due to housekeeping, there must be atleast 2 buffs */ |
495 | qp->rx_max_frame = min(transport_mtu, rx_size / 2); | 527 | qp->rx_max_frame = min(transport_mtu, rx_size / 2); |
496 | qp->rx_max_entry = rx_size / qp->rx_max_frame; | 528 | qp->rx_max_entry = rx_size / qp->rx_max_frame; |
@@ -631,7 +663,7 @@ static void ntb_transport_link_work(struct work_struct *work) | |||
631 | int rc, i; | 663 | int rc, i; |
632 | 664 | ||
633 | /* send the local info, in the opposite order of the way we read it */ | 665 | /* send the local info, in the opposite order of the way we read it */ |
634 | for (i = 0; i < NTB_NUM_MW; i++) { | 666 | for (i = 0; i < ntb_max_mw(ndev); i++) { |
635 | rc = ntb_write_remote_spad(ndev, MW0_SZ_HIGH + (i * 2), | 667 | rc = ntb_write_remote_spad(ndev, MW0_SZ_HIGH + (i * 2), |
636 | ntb_get_mw_size(ndev, i) >> 32); | 668 | ntb_get_mw_size(ndev, i) >> 32); |
637 | if (rc) { | 669 | if (rc) { |
@@ -651,10 +683,10 @@ static void ntb_transport_link_work(struct work_struct *work) | |||
651 | } | 683 | } |
652 | } | 684 | } |
653 | 685 | ||
654 | rc = ntb_write_remote_spad(ndev, NUM_MWS, NTB_NUM_MW); | 686 | rc = ntb_write_remote_spad(ndev, NUM_MWS, ntb_max_mw(ndev)); |
655 | if (rc) { | 687 | if (rc) { |
656 | dev_err(&pdev->dev, "Error writing %x to remote spad %d\n", | 688 | dev_err(&pdev->dev, "Error writing %x to remote spad %d\n", |
657 | NTB_NUM_MW, NUM_MWS); | 689 | ntb_max_mw(ndev), NUM_MWS); |
658 | goto out; | 690 | goto out; |
659 | } | 691 | } |
660 | 692 | ||
@@ -699,11 +731,11 @@ static void ntb_transport_link_work(struct work_struct *work) | |||
699 | goto out; | 731 | goto out; |
700 | } | 732 | } |
701 | 733 | ||
702 | if (val != NTB_NUM_MW) | 734 | if (val != ntb_max_mw(ndev)) |
703 | goto out; | 735 | goto out; |
704 | dev_dbg(&pdev->dev, "Remote number of mws = %d\n", val); | 736 | dev_dbg(&pdev->dev, "Remote number of mws = %d\n", val); |
705 | 737 | ||
706 | for (i = 0; i < NTB_NUM_MW; i++) { | 738 | for (i = 0; i < ntb_max_mw(ndev); i++) { |
707 | u64 val64; | 739 | u64 val64; |
708 | 740 | ||
709 | rc = ntb_read_remote_spad(ndev, MW0_SZ_HIGH + (i * 2), &val); | 741 | rc = ntb_read_remote_spad(ndev, MW0_SZ_HIGH + (i * 2), &val); |
@@ -745,7 +777,7 @@ static void ntb_transport_link_work(struct work_struct *work) | |||
745 | return; | 777 | return; |
746 | 778 | ||
747 | out1: | 779 | out1: |
748 | for (i = 0; i < NTB_NUM_MW; i++) | 780 | for (i = 0; i < ntb_max_mw(ndev); i++) |
749 | ntb_free_mw(nt, i); | 781 | ntb_free_mw(nt, i); |
750 | out: | 782 | out: |
751 | if (ntb_hw_link_status(ndev)) | 783 | if (ntb_hw_link_status(ndev)) |
@@ -794,12 +826,16 @@ static void ntb_qp_link_work(struct work_struct *work) | |||
794 | msecs_to_jiffies(NTB_LINK_DOWN_TIMEOUT)); | 826 | msecs_to_jiffies(NTB_LINK_DOWN_TIMEOUT)); |
795 | } | 827 | } |
796 | 828 | ||
797 | static void ntb_transport_init_queue(struct ntb_transport *nt, | 829 | static int ntb_transport_init_queue(struct ntb_transport *nt, |
798 | unsigned int qp_num) | 830 | unsigned int qp_num) |
799 | { | 831 | { |
800 | struct ntb_transport_qp *qp; | 832 | struct ntb_transport_qp *qp; |
801 | unsigned int num_qps_mw, tx_size; | 833 | unsigned int num_qps_mw, tx_size; |
802 | u8 mw_num = QP_TO_MW(qp_num); | 834 | u8 mw_num, mw_max; |
835 | u64 qp_offset; | ||
836 | |||
837 | mw_max = ntb_max_mw(nt->ndev); | ||
838 | mw_num = QP_TO_MW(nt->ndev, qp_num); | ||
803 | 839 | ||
804 | qp = &nt->qps[qp_num]; | 840 | qp = &nt->qps[qp_num]; |
805 | qp->qp_num = qp_num; | 841 | qp->qp_num = qp_num; |
@@ -809,27 +845,34 @@ static void ntb_transport_init_queue(struct ntb_transport *nt, | |||
809 | qp->client_ready = NTB_LINK_DOWN; | 845 | qp->client_ready = NTB_LINK_DOWN; |
810 | qp->event_handler = NULL; | 846 | qp->event_handler = NULL; |
811 | 847 | ||
812 | if (nt->max_qps % NTB_NUM_MW && mw_num < nt->max_qps % NTB_NUM_MW) | 848 | if (nt->max_qps % mw_max && mw_num < nt->max_qps % mw_max) |
813 | num_qps_mw = nt->max_qps / NTB_NUM_MW + 1; | 849 | num_qps_mw = nt->max_qps / mw_max + 1; |
814 | else | 850 | else |
815 | num_qps_mw = nt->max_qps / NTB_NUM_MW; | 851 | num_qps_mw = nt->max_qps / mw_max; |
816 | 852 | ||
817 | tx_size = (unsigned int) ntb_get_mw_size(qp->ndev, mw_num) / num_qps_mw; | 853 | tx_size = (unsigned int) ntb_get_mw_size(qp->ndev, mw_num) / num_qps_mw; |
818 | qp->rx_info = ntb_get_mw_vbase(nt->ndev, mw_num) + | 854 | qp_offset = qp_num / mw_max * tx_size; |
819 | (qp_num / NTB_NUM_MW * tx_size); | 855 | qp->tx_mw = ntb_get_mw_vbase(nt->ndev, mw_num) + qp_offset; |
856 | if (!qp->tx_mw) | ||
857 | return -EINVAL; | ||
858 | |||
859 | qp->tx_mw_phys = ntb_get_mw_base(qp->ndev, mw_num) + qp_offset; | ||
860 | if (!qp->tx_mw_phys) | ||
861 | return -EINVAL; | ||
862 | |||
820 | tx_size -= sizeof(struct ntb_rx_info); | 863 | tx_size -= sizeof(struct ntb_rx_info); |
864 | qp->rx_info = qp->tx_mw + tx_size; | ||
821 | 865 | ||
822 | qp->tx_mw = qp->rx_info + 1; | ||
823 | /* Due to housekeeping, there must be atleast 2 buffs */ | 866 | /* Due to housekeeping, there must be atleast 2 buffs */ |
824 | qp->tx_max_frame = min(transport_mtu, tx_size / 2); | 867 | qp->tx_max_frame = min(transport_mtu, tx_size / 2); |
825 | qp->tx_max_entry = tx_size / qp->tx_max_frame; | 868 | qp->tx_max_entry = tx_size / qp->tx_max_frame; |
826 | 869 | ||
827 | if (nt->debugfs_dir) { | 870 | if (ntb_query_debugfs(nt->ndev)) { |
828 | char debugfs_name[4]; | 871 | char debugfs_name[4]; |
829 | 872 | ||
830 | snprintf(debugfs_name, 4, "qp%d", qp_num); | 873 | snprintf(debugfs_name, 4, "qp%d", qp_num); |
831 | qp->debugfs_dir = debugfs_create_dir(debugfs_name, | 874 | qp->debugfs_dir = debugfs_create_dir(debugfs_name, |
832 | nt->debugfs_dir); | 875 | ntb_query_debugfs(nt->ndev)); |
833 | 876 | ||
834 | qp->debugfs_stats = debugfs_create_file("stats", S_IRUSR, | 877 | qp->debugfs_stats = debugfs_create_file("stats", S_IRUSR, |
835 | qp->debugfs_dir, qp, | 878 | qp->debugfs_dir, qp, |
@@ -846,6 +889,8 @@ static void ntb_transport_init_queue(struct ntb_transport *nt, | |||
846 | INIT_LIST_HEAD(&qp->rx_pend_q); | 889 | INIT_LIST_HEAD(&qp->rx_pend_q); |
847 | INIT_LIST_HEAD(&qp->rx_free_q); | 890 | INIT_LIST_HEAD(&qp->rx_free_q); |
848 | INIT_LIST_HEAD(&qp->tx_free_q); | 891 | INIT_LIST_HEAD(&qp->tx_free_q); |
892 | |||
893 | return 0; | ||
849 | } | 894 | } |
850 | 895 | ||
851 | int ntb_transport_init(struct pci_dev *pdev) | 896 | int ntb_transport_init(struct pci_dev *pdev) |
@@ -857,30 +902,38 @@ int ntb_transport_init(struct pci_dev *pdev) | |||
857 | if (!nt) | 902 | if (!nt) |
858 | return -ENOMEM; | 903 | return -ENOMEM; |
859 | 904 | ||
860 | if (debugfs_initialized()) | ||
861 | nt->debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL); | ||
862 | else | ||
863 | nt->debugfs_dir = NULL; | ||
864 | |||
865 | nt->ndev = ntb_register_transport(pdev, nt); | 905 | nt->ndev = ntb_register_transport(pdev, nt); |
866 | if (!nt->ndev) { | 906 | if (!nt->ndev) { |
867 | rc = -EIO; | 907 | rc = -EIO; |
868 | goto err; | 908 | goto err; |
869 | } | 909 | } |
870 | 910 | ||
871 | nt->max_qps = min(nt->ndev->max_cbs, max_num_clients); | 911 | nt->mw = kcalloc(ntb_max_mw(nt->ndev), sizeof(struct ntb_transport_mw), |
912 | GFP_KERNEL); | ||
913 | if (!nt->mw) { | ||
914 | rc = -ENOMEM; | ||
915 | goto err1; | ||
916 | } | ||
917 | |||
918 | if (max_num_clients) | ||
919 | nt->max_qps = min(ntb_max_cbs(nt->ndev), max_num_clients); | ||
920 | else | ||
921 | nt->max_qps = min(ntb_max_cbs(nt->ndev), ntb_max_mw(nt->ndev)); | ||
872 | 922 | ||
873 | nt->qps = kcalloc(nt->max_qps, sizeof(struct ntb_transport_qp), | 923 | nt->qps = kcalloc(nt->max_qps, sizeof(struct ntb_transport_qp), |
874 | GFP_KERNEL); | 924 | GFP_KERNEL); |
875 | if (!nt->qps) { | 925 | if (!nt->qps) { |
876 | rc = -ENOMEM; | 926 | rc = -ENOMEM; |
877 | goto err1; | 927 | goto err2; |
878 | } | 928 | } |
879 | 929 | ||
880 | nt->qp_bitmap = ((u64) 1 << nt->max_qps) - 1; | 930 | nt->qp_bitmap = ((u64) 1 << nt->max_qps) - 1; |
881 | 931 | ||
882 | for (i = 0; i < nt->max_qps; i++) | 932 | for (i = 0; i < nt->max_qps; i++) { |
883 | ntb_transport_init_queue(nt, i); | 933 | rc = ntb_transport_init_queue(nt, i); |
934 | if (rc) | ||
935 | goto err3; | ||
936 | } | ||
884 | 937 | ||
885 | INIT_DELAYED_WORK(&nt->link_work, ntb_transport_link_work); | 938 | INIT_DELAYED_WORK(&nt->link_work, ntb_transport_link_work); |
886 | INIT_WORK(&nt->link_cleanup, ntb_transport_link_cleanup); | 939 | INIT_WORK(&nt->link_cleanup, ntb_transport_link_cleanup); |
@@ -888,26 +941,27 @@ int ntb_transport_init(struct pci_dev *pdev) | |||
888 | rc = ntb_register_event_callback(nt->ndev, | 941 | rc = ntb_register_event_callback(nt->ndev, |
889 | ntb_transport_event_callback); | 942 | ntb_transport_event_callback); |
890 | if (rc) | 943 | if (rc) |
891 | goto err2; | 944 | goto err3; |
892 | 945 | ||
893 | INIT_LIST_HEAD(&nt->client_devs); | 946 | INIT_LIST_HEAD(&nt->client_devs); |
894 | rc = ntb_bus_init(nt); | 947 | rc = ntb_bus_init(nt); |
895 | if (rc) | 948 | if (rc) |
896 | goto err3; | 949 | goto err4; |
897 | 950 | ||
898 | if (ntb_hw_link_status(nt->ndev)) | 951 | if (ntb_hw_link_status(nt->ndev)) |
899 | schedule_delayed_work(&nt->link_work, 0); | 952 | schedule_delayed_work(&nt->link_work, 0); |
900 | 953 | ||
901 | return 0; | 954 | return 0; |
902 | 955 | ||
903 | err3: | 956 | err4: |
904 | ntb_unregister_event_callback(nt->ndev); | 957 | ntb_unregister_event_callback(nt->ndev); |
905 | err2: | 958 | err3: |
906 | kfree(nt->qps); | 959 | kfree(nt->qps); |
960 | err2: | ||
961 | kfree(nt->mw); | ||
907 | err1: | 962 | err1: |
908 | ntb_unregister_transport(nt->ndev); | 963 | ntb_unregister_transport(nt->ndev); |
909 | err: | 964 | err: |
910 | debugfs_remove_recursive(nt->debugfs_dir); | ||
911 | kfree(nt); | 965 | kfree(nt); |
912 | return rc; | 966 | return rc; |
913 | } | 967 | } |
@@ -915,41 +969,46 @@ err: | |||
915 | void ntb_transport_free(void *transport) | 969 | void ntb_transport_free(void *transport) |
916 | { | 970 | { |
917 | struct ntb_transport *nt = transport; | 971 | struct ntb_transport *nt = transport; |
918 | struct pci_dev *pdev; | 972 | struct ntb_device *ndev = nt->ndev; |
919 | int i; | 973 | int i; |
920 | 974 | ||
921 | nt->transport_link = NTB_LINK_DOWN; | 975 | nt->transport_link = NTB_LINK_DOWN; |
922 | 976 | ||
923 | /* verify that all the qp's are freed */ | 977 | /* verify that all the qp's are freed */ |
924 | for (i = 0; i < nt->max_qps; i++) | 978 | for (i = 0; i < nt->max_qps; i++) { |
925 | if (!test_bit(i, &nt->qp_bitmap)) | 979 | if (!test_bit(i, &nt->qp_bitmap)) |
926 | ntb_transport_free_queue(&nt->qps[i]); | 980 | ntb_transport_free_queue(&nt->qps[i]); |
981 | debugfs_remove_recursive(nt->qps[i].debugfs_dir); | ||
982 | } | ||
927 | 983 | ||
928 | ntb_bus_remove(nt); | 984 | ntb_bus_remove(nt); |
929 | 985 | ||
930 | cancel_delayed_work_sync(&nt->link_work); | 986 | cancel_delayed_work_sync(&nt->link_work); |
931 | 987 | ||
932 | debugfs_remove_recursive(nt->debugfs_dir); | 988 | ntb_unregister_event_callback(ndev); |
933 | |||
934 | ntb_unregister_event_callback(nt->ndev); | ||
935 | |||
936 | pdev = ntb_query_pdev(nt->ndev); | ||
937 | 989 | ||
938 | for (i = 0; i < NTB_NUM_MW; i++) | 990 | for (i = 0; i < ntb_max_mw(ndev); i++) |
939 | ntb_free_mw(nt, i); | 991 | ntb_free_mw(nt, i); |
940 | 992 | ||
941 | kfree(nt->qps); | 993 | kfree(nt->qps); |
942 | ntb_unregister_transport(nt->ndev); | 994 | kfree(nt->mw); |
995 | ntb_unregister_transport(ndev); | ||
943 | kfree(nt); | 996 | kfree(nt); |
944 | } | 997 | } |
945 | 998 | ||
946 | static void ntb_rx_copy_task(struct ntb_transport_qp *qp, | 999 | static void ntb_rx_copy_callback(void *data) |
947 | struct ntb_queue_entry *entry, void *offset) | ||
948 | { | 1000 | { |
1001 | struct ntb_queue_entry *entry = data; | ||
1002 | struct ntb_transport_qp *qp = entry->qp; | ||
949 | void *cb_data = entry->cb_data; | 1003 | void *cb_data = entry->cb_data; |
950 | unsigned int len = entry->len; | 1004 | unsigned int len = entry->len; |
1005 | struct ntb_payload_header *hdr = entry->rx_hdr; | ||
951 | 1006 | ||
952 | memcpy(entry->buf, offset, entry->len); | 1007 | /* Ensure that the data is fully copied out before clearing the flag */ |
1008 | wmb(); | ||
1009 | hdr->flags = 0; | ||
1010 | |||
1011 | iowrite32(entry->index, &qp->rx_info->entry); | ||
953 | 1012 | ||
954 | ntb_list_add(&qp->ntb_rx_free_q_lock, &entry->entry, &qp->rx_free_q); | 1013 | ntb_list_add(&qp->ntb_rx_free_q_lock, &entry->entry, &qp->rx_free_q); |
955 | 1014 | ||
@@ -957,6 +1016,86 @@ static void ntb_rx_copy_task(struct ntb_transport_qp *qp, | |||
957 | qp->rx_handler(qp, qp->cb_data, cb_data, len); | 1016 | qp->rx_handler(qp, qp->cb_data, cb_data, len); |
958 | } | 1017 | } |
959 | 1018 | ||
1019 | static void ntb_memcpy_rx(struct ntb_queue_entry *entry, void *offset) | ||
1020 | { | ||
1021 | void *buf = entry->buf; | ||
1022 | size_t len = entry->len; | ||
1023 | |||
1024 | memcpy(buf, offset, len); | ||
1025 | |||
1026 | ntb_rx_copy_callback(entry); | ||
1027 | } | ||
1028 | |||
1029 | static void ntb_async_rx(struct ntb_queue_entry *entry, void *offset, | ||
1030 | size_t len) | ||
1031 | { | ||
1032 | struct dma_async_tx_descriptor *txd; | ||
1033 | struct ntb_transport_qp *qp = entry->qp; | ||
1034 | struct dma_chan *chan = qp->dma_chan; | ||
1035 | struct dma_device *device; | ||
1036 | size_t pay_off, buff_off; | ||
1037 | dma_addr_t src, dest; | ||
1038 | dma_cookie_t cookie; | ||
1039 | void *buf = entry->buf; | ||
1040 | unsigned long flags; | ||
1041 | |||
1042 | entry->len = len; | ||
1043 | |||
1044 | if (!chan) | ||
1045 | goto err; | ||
1046 | |||
1047 | if (len < copy_bytes) | ||
1048 | goto err1; | ||
1049 | |||
1050 | device = chan->device; | ||
1051 | pay_off = (size_t) offset & ~PAGE_MASK; | ||
1052 | buff_off = (size_t) buf & ~PAGE_MASK; | ||
1053 | |||
1054 | if (!is_dma_copy_aligned(device, pay_off, buff_off, len)) | ||
1055 | goto err1; | ||
1056 | |||
1057 | dest = dma_map_single(device->dev, buf, len, DMA_FROM_DEVICE); | ||
1058 | if (dma_mapping_error(device->dev, dest)) | ||
1059 | goto err1; | ||
1060 | |||
1061 | src = dma_map_single(device->dev, offset, len, DMA_TO_DEVICE); | ||
1062 | if (dma_mapping_error(device->dev, src)) | ||
1063 | goto err2; | ||
1064 | |||
1065 | flags = DMA_COMPL_DEST_UNMAP_SINGLE | DMA_COMPL_SRC_UNMAP_SINGLE | | ||
1066 | DMA_PREP_INTERRUPT; | ||
1067 | txd = device->device_prep_dma_memcpy(chan, dest, src, len, flags); | ||
1068 | if (!txd) | ||
1069 | goto err3; | ||
1070 | |||
1071 | txd->callback = ntb_rx_copy_callback; | ||
1072 | txd->callback_param = entry; | ||
1073 | |||
1074 | cookie = dmaengine_submit(txd); | ||
1075 | if (dma_submit_error(cookie)) | ||
1076 | goto err3; | ||
1077 | |||
1078 | qp->last_cookie = cookie; | ||
1079 | |||
1080 | qp->rx_async++; | ||
1081 | |||
1082 | return; | ||
1083 | |||
1084 | err3: | ||
1085 | dma_unmap_single(device->dev, src, len, DMA_TO_DEVICE); | ||
1086 | err2: | ||
1087 | dma_unmap_single(device->dev, dest, len, DMA_FROM_DEVICE); | ||
1088 | err1: | ||
1089 | /* If the callbacks come out of order, the writing of the index to the | ||
1090 | * last completed will be out of order. This may result in the | ||
1091 | * receive stalling forever. | ||
1092 | */ | ||
1093 | dma_sync_wait(chan, qp->last_cookie); | ||
1094 | err: | ||
1095 | ntb_memcpy_rx(entry, offset); | ||
1096 | qp->rx_memcpy++; | ||
1097 | } | ||
1098 | |||
960 | static int ntb_process_rxc(struct ntb_transport_qp *qp) | 1099 | static int ntb_process_rxc(struct ntb_transport_qp *qp) |
961 | { | 1100 | { |
962 | struct ntb_payload_header *hdr; | 1101 | struct ntb_payload_header *hdr; |
@@ -995,41 +1134,45 @@ static int ntb_process_rxc(struct ntb_transport_qp *qp) | |||
995 | if (hdr->flags & LINK_DOWN_FLAG) { | 1134 | if (hdr->flags & LINK_DOWN_FLAG) { |
996 | ntb_qp_link_down(qp); | 1135 | ntb_qp_link_down(qp); |
997 | 1136 | ||
998 | ntb_list_add(&qp->ntb_rx_pend_q_lock, &entry->entry, | 1137 | goto err; |
999 | &qp->rx_pend_q); | ||
1000 | goto out; | ||
1001 | } | 1138 | } |
1002 | 1139 | ||
1003 | dev_dbg(&ntb_query_pdev(qp->ndev)->dev, | 1140 | dev_dbg(&ntb_query_pdev(qp->ndev)->dev, |
1004 | "rx offset %u, ver %u - %d payload received, buf size %d\n", | 1141 | "rx offset %u, ver %u - %d payload received, buf size %d\n", |
1005 | qp->rx_index, hdr->ver, hdr->len, entry->len); | 1142 | qp->rx_index, hdr->ver, hdr->len, entry->len); |
1006 | 1143 | ||
1007 | if (hdr->len <= entry->len) { | 1144 | qp->rx_bytes += hdr->len; |
1008 | entry->len = hdr->len; | 1145 | qp->rx_pkts++; |
1009 | ntb_rx_copy_task(qp, entry, offset); | ||
1010 | } else { | ||
1011 | ntb_list_add(&qp->ntb_rx_pend_q_lock, &entry->entry, | ||
1012 | &qp->rx_pend_q); | ||
1013 | 1146 | ||
1147 | if (hdr->len > entry->len) { | ||
1014 | qp->rx_err_oflow++; | 1148 | qp->rx_err_oflow++; |
1015 | dev_dbg(&ntb_query_pdev(qp->ndev)->dev, | 1149 | dev_dbg(&ntb_query_pdev(qp->ndev)->dev, |
1016 | "RX overflow! Wanted %d got %d\n", | 1150 | "RX overflow! Wanted %d got %d\n", |
1017 | hdr->len, entry->len); | 1151 | hdr->len, entry->len); |
1152 | |||
1153 | goto err; | ||
1018 | } | 1154 | } |
1019 | 1155 | ||
1020 | qp->rx_bytes += hdr->len; | 1156 | entry->index = qp->rx_index; |
1021 | qp->rx_pkts++; | 1157 | entry->rx_hdr = hdr; |
1158 | |||
1159 | ntb_async_rx(entry, offset, hdr->len); | ||
1022 | 1160 | ||
1023 | out: | 1161 | out: |
1162 | qp->rx_index++; | ||
1163 | qp->rx_index %= qp->rx_max_entry; | ||
1164 | |||
1165 | return 0; | ||
1166 | |||
1167 | err: | ||
1168 | ntb_list_add(&qp->ntb_rx_pend_q_lock, &entry->entry, | ||
1169 | &qp->rx_pend_q); | ||
1024 | /* Ensure that the data is fully copied out before clearing the flag */ | 1170 | /* Ensure that the data is fully copied out before clearing the flag */ |
1025 | wmb(); | 1171 | wmb(); |
1026 | hdr->flags = 0; | 1172 | hdr->flags = 0; |
1027 | iowrite32(qp->rx_index, &qp->rx_info->entry); | 1173 | iowrite32(qp->rx_index, &qp->rx_info->entry); |
1028 | 1174 | ||
1029 | qp->rx_index++; | 1175 | goto out; |
1030 | qp->rx_index %= qp->rx_max_entry; | ||
1031 | |||
1032 | return 0; | ||
1033 | } | 1176 | } |
1034 | 1177 | ||
1035 | static void ntb_transport_rx(unsigned long data) | 1178 | static void ntb_transport_rx(unsigned long data) |
@@ -1045,6 +1188,9 @@ static void ntb_transport_rx(unsigned long data) | |||
1045 | if (rc) | 1188 | if (rc) |
1046 | break; | 1189 | break; |
1047 | } | 1190 | } |
1191 | |||
1192 | if (qp->dma_chan) | ||
1193 | dma_async_issue_pending(qp->dma_chan); | ||
1048 | } | 1194 | } |
1049 | 1195 | ||
1050 | static void ntb_transport_rxc_db(void *data, int db_num) | 1196 | static void ntb_transport_rxc_db(void *data, int db_num) |
@@ -1057,23 +1203,17 @@ static void ntb_transport_rxc_db(void *data, int db_num) | |||
1057 | tasklet_schedule(&qp->rx_work); | 1203 | tasklet_schedule(&qp->rx_work); |
1058 | } | 1204 | } |
1059 | 1205 | ||
1060 | static void ntb_tx_copy_task(struct ntb_transport_qp *qp, | 1206 | static void ntb_tx_copy_callback(void *data) |
1061 | struct ntb_queue_entry *entry, | ||
1062 | void __iomem *offset) | ||
1063 | { | 1207 | { |
1064 | struct ntb_payload_header __iomem *hdr; | 1208 | struct ntb_queue_entry *entry = data; |
1209 | struct ntb_transport_qp *qp = entry->qp; | ||
1210 | struct ntb_payload_header __iomem *hdr = entry->tx_hdr; | ||
1065 | 1211 | ||
1066 | memcpy_toio(offset, entry->buf, entry->len); | 1212 | /* Ensure that the data is fully copied out before setting the flags */ |
1067 | |||
1068 | hdr = offset + qp->tx_max_frame - sizeof(struct ntb_payload_header); | ||
1069 | iowrite32(entry->len, &hdr->len); | ||
1070 | iowrite32((u32) qp->tx_pkts, &hdr->ver); | ||
1071 | |||
1072 | /* Ensure that the data is fully copied out before setting the flag */ | ||
1073 | wmb(); | 1213 | wmb(); |
1074 | iowrite32(entry->flags | DESC_DONE_FLAG, &hdr->flags); | 1214 | iowrite32(entry->flags | DESC_DONE_FLAG, &hdr->flags); |
1075 | 1215 | ||
1076 | ntb_ring_sdb(qp->ndev, qp->qp_num); | 1216 | ntb_ring_doorbell(qp->ndev, qp->qp_num); |
1077 | 1217 | ||
1078 | /* The entry length can only be zero if the packet is intended to be a | 1218 | /* The entry length can only be zero if the packet is intended to be a |
1079 | * "link down" or similar. Since no payload is being sent in these | 1219 | * "link down" or similar. Since no payload is being sent in these |
@@ -1090,15 +1230,81 @@ static void ntb_tx_copy_task(struct ntb_transport_qp *qp, | |||
1090 | ntb_list_add(&qp->ntb_tx_free_q_lock, &entry->entry, &qp->tx_free_q); | 1230 | ntb_list_add(&qp->ntb_tx_free_q_lock, &entry->entry, &qp->tx_free_q); |
1091 | } | 1231 | } |
1092 | 1232 | ||
1093 | static int ntb_process_tx(struct ntb_transport_qp *qp, | 1233 | static void ntb_memcpy_tx(struct ntb_queue_entry *entry, void __iomem *offset) |
1094 | struct ntb_queue_entry *entry) | 1234 | { |
1235 | memcpy_toio(offset, entry->buf, entry->len); | ||
1236 | |||
1237 | ntb_tx_copy_callback(entry); | ||
1238 | } | ||
1239 | |||
1240 | static void ntb_async_tx(struct ntb_transport_qp *qp, | ||
1241 | struct ntb_queue_entry *entry) | ||
1095 | { | 1242 | { |
1243 | struct ntb_payload_header __iomem *hdr; | ||
1244 | struct dma_async_tx_descriptor *txd; | ||
1245 | struct dma_chan *chan = qp->dma_chan; | ||
1246 | struct dma_device *device; | ||
1247 | size_t dest_off, buff_off; | ||
1248 | dma_addr_t src, dest; | ||
1249 | dma_cookie_t cookie; | ||
1096 | void __iomem *offset; | 1250 | void __iomem *offset; |
1251 | size_t len = entry->len; | ||
1252 | void *buf = entry->buf; | ||
1253 | unsigned long flags; | ||
1097 | 1254 | ||
1098 | offset = qp->tx_mw + qp->tx_max_frame * qp->tx_index; | 1255 | offset = qp->tx_mw + qp->tx_max_frame * qp->tx_index; |
1256 | hdr = offset + qp->tx_max_frame - sizeof(struct ntb_payload_header); | ||
1257 | entry->tx_hdr = hdr; | ||
1258 | |||
1259 | iowrite32(entry->len, &hdr->len); | ||
1260 | iowrite32((u32) qp->tx_pkts, &hdr->ver); | ||
1261 | |||
1262 | if (!chan) | ||
1263 | goto err; | ||
1264 | |||
1265 | if (len < copy_bytes) | ||
1266 | goto err; | ||
1267 | |||
1268 | device = chan->device; | ||
1269 | dest = qp->tx_mw_phys + qp->tx_max_frame * qp->tx_index; | ||
1270 | buff_off = (size_t) buf & ~PAGE_MASK; | ||
1271 | dest_off = (size_t) dest & ~PAGE_MASK; | ||
1272 | |||
1273 | if (!is_dma_copy_aligned(device, buff_off, dest_off, len)) | ||
1274 | goto err; | ||
1275 | |||
1276 | src = dma_map_single(device->dev, buf, len, DMA_TO_DEVICE); | ||
1277 | if (dma_mapping_error(device->dev, src)) | ||
1278 | goto err; | ||
1279 | |||
1280 | flags = DMA_COMPL_SRC_UNMAP_SINGLE | DMA_PREP_INTERRUPT; | ||
1281 | txd = device->device_prep_dma_memcpy(chan, dest, src, len, flags); | ||
1282 | if (!txd) | ||
1283 | goto err1; | ||
1284 | |||
1285 | txd->callback = ntb_tx_copy_callback; | ||
1286 | txd->callback_param = entry; | ||
1287 | |||
1288 | cookie = dmaengine_submit(txd); | ||
1289 | if (dma_submit_error(cookie)) | ||
1290 | goto err1; | ||
1291 | |||
1292 | dma_async_issue_pending(chan); | ||
1293 | qp->tx_async++; | ||
1099 | 1294 | ||
1100 | dev_dbg(&ntb_query_pdev(qp->ndev)->dev, "%lld - offset %p, tx %u, entry len %d flags %x buff %p\n", | 1295 | return; |
1101 | qp->tx_pkts, offset, qp->tx_index, entry->len, entry->flags, | 1296 | err1: |
1297 | dma_unmap_single(device->dev, src, len, DMA_TO_DEVICE); | ||
1298 | err: | ||
1299 | ntb_memcpy_tx(entry, offset); | ||
1300 | qp->tx_memcpy++; | ||
1301 | } | ||
1302 | |||
1303 | static int ntb_process_tx(struct ntb_transport_qp *qp, | ||
1304 | struct ntb_queue_entry *entry) | ||
1305 | { | ||
1306 | dev_dbg(&ntb_query_pdev(qp->ndev)->dev, "%lld - tx %u, entry len %d flags %x buff %p\n", | ||
1307 | qp->tx_pkts, qp->tx_index, entry->len, entry->flags, | ||
1102 | entry->buf); | 1308 | entry->buf); |
1103 | if (qp->tx_index == qp->remote_rx_info->entry) { | 1309 | if (qp->tx_index == qp->remote_rx_info->entry) { |
1104 | qp->tx_ring_full++; | 1310 | qp->tx_ring_full++; |
@@ -1114,7 +1320,7 @@ static int ntb_process_tx(struct ntb_transport_qp *qp, | |||
1114 | return 0; | 1320 | return 0; |
1115 | } | 1321 | } |
1116 | 1322 | ||
1117 | ntb_tx_copy_task(qp, entry, offset); | 1323 | ntb_async_tx(qp, entry); |
1118 | 1324 | ||
1119 | qp->tx_index++; | 1325 | qp->tx_index++; |
1120 | qp->tx_index %= qp->tx_max_entry; | 1326 | qp->tx_index %= qp->tx_max_entry; |
@@ -1200,11 +1406,18 @@ ntb_transport_create_queue(void *data, struct pci_dev *pdev, | |||
1200 | qp->tx_handler = handlers->tx_handler; | 1406 | qp->tx_handler = handlers->tx_handler; |
1201 | qp->event_handler = handlers->event_handler; | 1407 | qp->event_handler = handlers->event_handler; |
1202 | 1408 | ||
1409 | qp->dma_chan = dma_find_channel(DMA_MEMCPY); | ||
1410 | if (!qp->dma_chan) | ||
1411 | dev_info(&pdev->dev, "Unable to allocate DMA channel, using CPU instead\n"); | ||
1412 | else | ||
1413 | dmaengine_get(); | ||
1414 | |||
1203 | for (i = 0; i < NTB_QP_DEF_NUM_ENTRIES; i++) { | 1415 | for (i = 0; i < NTB_QP_DEF_NUM_ENTRIES; i++) { |
1204 | entry = kzalloc(sizeof(struct ntb_queue_entry), GFP_ATOMIC); | 1416 | entry = kzalloc(sizeof(struct ntb_queue_entry), GFP_ATOMIC); |
1205 | if (!entry) | 1417 | if (!entry) |
1206 | goto err1; | 1418 | goto err1; |
1207 | 1419 | ||
1420 | entry->qp = qp; | ||
1208 | ntb_list_add(&qp->ntb_rx_free_q_lock, &entry->entry, | 1421 | ntb_list_add(&qp->ntb_rx_free_q_lock, &entry->entry, |
1209 | &qp->rx_free_q); | 1422 | &qp->rx_free_q); |
1210 | } | 1423 | } |
@@ -1214,6 +1427,7 @@ ntb_transport_create_queue(void *data, struct pci_dev *pdev, | |||
1214 | if (!entry) | 1427 | if (!entry) |
1215 | goto err2; | 1428 | goto err2; |
1216 | 1429 | ||
1430 | entry->qp = qp; | ||
1217 | ntb_list_add(&qp->ntb_tx_free_q_lock, &entry->entry, | 1431 | ntb_list_add(&qp->ntb_tx_free_q_lock, &entry->entry, |
1218 | &qp->tx_free_q); | 1432 | &qp->tx_free_q); |
1219 | } | 1433 | } |
@@ -1259,11 +1473,26 @@ void ntb_transport_free_queue(struct ntb_transport_qp *qp) | |||
1259 | 1473 | ||
1260 | pdev = ntb_query_pdev(qp->ndev); | 1474 | pdev = ntb_query_pdev(qp->ndev); |
1261 | 1475 | ||
1262 | cancel_delayed_work_sync(&qp->link_work); | 1476 | if (qp->dma_chan) { |
1477 | struct dma_chan *chan = qp->dma_chan; | ||
1478 | /* Putting the dma_chan to NULL will force any new traffic to be | ||
1479 | * processed by the CPU instead of the DAM engine | ||
1480 | */ | ||
1481 | qp->dma_chan = NULL; | ||
1482 | |||
1483 | /* Try to be nice and wait for any queued DMA engine | ||
1484 | * transactions to process before smashing it with a rock | ||
1485 | */ | ||
1486 | dma_sync_wait(chan, qp->last_cookie); | ||
1487 | dmaengine_terminate_all(chan); | ||
1488 | dmaengine_put(); | ||
1489 | } | ||
1263 | 1490 | ||
1264 | ntb_unregister_db_callback(qp->ndev, qp->qp_num); | 1491 | ntb_unregister_db_callback(qp->ndev, qp->qp_num); |
1265 | tasklet_disable(&qp->rx_work); | 1492 | tasklet_disable(&qp->rx_work); |
1266 | 1493 | ||
1494 | cancel_delayed_work_sync(&qp->link_work); | ||
1495 | |||
1267 | while ((entry = ntb_list_rm(&qp->ntb_rx_free_q_lock, &qp->rx_free_q))) | 1496 | while ((entry = ntb_list_rm(&qp->ntb_rx_free_q_lock, &qp->rx_free_q))) |
1268 | kfree(entry); | 1497 | kfree(entry); |
1269 | 1498 | ||
@@ -1354,7 +1583,7 @@ EXPORT_SYMBOL_GPL(ntb_transport_rx_enqueue); | |||
1354 | * @len: length of the data buffer | 1583 | * @len: length of the data buffer |
1355 | * | 1584 | * |
1356 | * Enqueue a new transmit buffer onto the transport queue from which a NTB | 1585 | * Enqueue a new transmit buffer onto the transport queue from which a NTB |
1357 | * payload will be transmitted. This assumes that a lock is behing held to | 1586 | * payload will be transmitted. This assumes that a lock is being held to |
1358 | * serialize access to the qp. | 1587 | * serialize access to the qp. |
1359 | * | 1588 | * |
1360 | * RETURNS: An appropriate -ERRNO error value on error, or zero for success. | 1589 | * RETURNS: An appropriate -ERRNO error value on error, or zero for success. |
@@ -1369,8 +1598,10 @@ int ntb_transport_tx_enqueue(struct ntb_transport_qp *qp, void *cb, void *data, | |||
1369 | return -EINVAL; | 1598 | return -EINVAL; |
1370 | 1599 | ||
1371 | entry = ntb_list_rm(&qp->ntb_tx_free_q_lock, &qp->tx_free_q); | 1600 | entry = ntb_list_rm(&qp->ntb_tx_free_q_lock, &qp->tx_free_q); |
1372 | if (!entry) | 1601 | if (!entry) { |
1602 | qp->tx_err_no_buf++; | ||
1373 | return -ENOMEM; | 1603 | return -ENOMEM; |
1604 | } | ||
1374 | 1605 | ||
1375 | entry->cb_data = cb; | 1606 | entry->cb_data = cb; |
1376 | entry->buf = data; | 1607 | entry->buf = data; |
@@ -1410,7 +1641,7 @@ EXPORT_SYMBOL_GPL(ntb_transport_link_up); | |||
1410 | * | 1641 | * |
1411 | * Notify NTB transport layer of client's desire to no longer receive data on | 1642 | * Notify NTB transport layer of client's desire to no longer receive data on |
1412 | * transport queue specified. It is the client's responsibility to ensure all | 1643 | * transport queue specified. It is the client's responsibility to ensure all |
1413 | * entries on queue are purged or otherwise handled appropraitely. | 1644 | * entries on queue are purged or otherwise handled appropriately. |
1414 | */ | 1645 | */ |
1415 | void ntb_transport_link_down(struct ntb_transport_qp *qp) | 1646 | void ntb_transport_link_down(struct ntb_transport_qp *qp) |
1416 | { | 1647 | { |
@@ -1486,9 +1717,18 @@ EXPORT_SYMBOL_GPL(ntb_transport_qp_num); | |||
1486 | */ | 1717 | */ |
1487 | unsigned int ntb_transport_max_size(struct ntb_transport_qp *qp) | 1718 | unsigned int ntb_transport_max_size(struct ntb_transport_qp *qp) |
1488 | { | 1719 | { |
1720 | unsigned int max; | ||
1721 | |||
1489 | if (!qp) | 1722 | if (!qp) |
1490 | return 0; | 1723 | return 0; |
1491 | 1724 | ||
1492 | return qp->tx_max_frame - sizeof(struct ntb_payload_header); | 1725 | if (!qp->dma_chan) |
1726 | return qp->tx_max_frame - sizeof(struct ntb_payload_header); | ||
1727 | |||
1728 | /* If DMA engine usage is possible, try to find the max size for that */ | ||
1729 | max = qp->tx_max_frame - sizeof(struct ntb_payload_header); | ||
1730 | max -= max % (1 << qp->dma_chan->device->copy_align); | ||
1731 | |||
1732 | return max; | ||
1493 | } | 1733 | } |
1494 | EXPORT_SYMBOL_GPL(ntb_transport_max_size); | 1734 | EXPORT_SYMBOL_GPL(ntb_transport_max_size); |