aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ntb
diff options
context:
space:
mode:
authorJon Mason <jon.mason@intel.com>2013-02-12 11:52:50 -0500
committerJon Mason <jon.mason@intel.com>2013-09-05 14:04:09 -0400
commit282a2feeb9bfb1d1dfbad93df206b74eaf80d564 (patch)
tree9265a6308dd746606dbcb0bac330082f97780be9 /drivers/ntb
parentac477afb0431386575ef453f50fa0052c3f0461b (diff)
NTB: Use DMA Engine to Transmit and Receive
Allocate and use a DMA engine channel to transmit and receive data over NTB. If none is allocated, fall back to using the CPU to transfer data. Signed-off-by: Jon Mason <jon.mason@intel.com> Reviewed-by: Dan Williams <dan.j.williams@intel.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Diffstat (limited to 'drivers/ntb')
-rw-r--r--drivers/ntb/ntb_hw.c17
-rw-r--r--drivers/ntb/ntb_hw.h1
-rw-r--r--drivers/ntb/ntb_transport.c324
3 files changed, 295 insertions, 47 deletions
diff --git a/drivers/ntb/ntb_hw.c b/drivers/ntb/ntb_hw.c
index ab34795cf125..0345817a8355 100644
--- a/drivers/ntb/ntb_hw.c
+++ b/drivers/ntb/ntb_hw.c
@@ -350,6 +350,23 @@ int ntb_read_remote_spad(struct ntb_device *ndev, unsigned int idx, u32 *val)
350} 350}
351 351
352/** 352/**
353 * ntb_get_mw_base() - get addr for the NTB memory window
354 * @ndev: pointer to ntb_device instance
355 * @mw: memory window number
356 *
357 * This function provides the base address of the memory window specified.
358 *
359 * RETURNS: address, or NULL on error.
360 */
361resource_size_t ntb_get_mw_base(struct ntb_device *ndev, unsigned int mw)
362{
363 if (mw >= ntb_max_mw(ndev))
364 return 0;
365
366 return pci_resource_start(ndev->pdev, MW_TO_BAR(mw));
367}
368
369/**
353 * ntb_get_mw_vbase() - get virtual addr for the NTB memory window 370 * ntb_get_mw_vbase() - get virtual addr for the NTB memory window
354 * @ndev: pointer to ntb_device instance 371 * @ndev: pointer to ntb_device instance
355 * @mw: memory window number 372 * @mw: memory window number
diff --git a/drivers/ntb/ntb_hw.h b/drivers/ntb/ntb_hw.h
index d838bc13b956..4f42ed18103a 100644
--- a/drivers/ntb/ntb_hw.h
+++ b/drivers/ntb/ntb_hw.h
@@ -240,6 +240,7 @@ int ntb_write_local_spad(struct ntb_device *ndev, unsigned int idx, u32 val);
240int ntb_read_local_spad(struct ntb_device *ndev, unsigned int idx, u32 *val); 240int ntb_read_local_spad(struct ntb_device *ndev, unsigned int idx, u32 *val);
241int ntb_write_remote_spad(struct ntb_device *ndev, unsigned int idx, u32 val); 241int ntb_write_remote_spad(struct ntb_device *ndev, unsigned int idx, u32 val);
242int ntb_read_remote_spad(struct ntb_device *ndev, unsigned int idx, u32 *val); 242int ntb_read_remote_spad(struct ntb_device *ndev, unsigned int idx, u32 *val);
243resource_size_t ntb_get_mw_base(struct ntb_device *ndev, unsigned int mw);
243void __iomem *ntb_get_mw_vbase(struct ntb_device *ndev, unsigned int mw); 244void __iomem *ntb_get_mw_vbase(struct ntb_device *ndev, unsigned int mw);
244u64 ntb_get_mw_size(struct ntb_device *ndev, unsigned int mw); 245u64 ntb_get_mw_size(struct ntb_device *ndev, unsigned int mw);
245void ntb_ring_sdb(struct ntb_device *ndev, unsigned int idx); 246void ntb_ring_sdb(struct ntb_device *ndev, unsigned int idx);
diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c
index f7380e959656..ae8657259ca0 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>
@@ -68,6 +69,10 @@ static unsigned char max_num_clients;
68module_param(max_num_clients, byte, 0644); 69module_param(max_num_clients, byte, 0644);
69MODULE_PARM_DESC(max_num_clients, "Maximum number of NTB transport clients"); 70MODULE_PARM_DESC(max_num_clients, "Maximum number of NTB transport clients");
70 71
72static unsigned int copy_bytes = 1024;
73module_param(copy_bytes, uint, 0644);
74MODULE_PARM_DESC(copy_bytes, "Threshold under which NTB will use the CPU to copy instead of DMA");
75
71struct ntb_queue_entry { 76struct 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
81struct ntb_rx_info { 93struct 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
137struct ntb_transport_mw { 157struct ntb_transport_mw {
@@ -381,7 +401,7 @@ static ssize_t debugfs_read(struct file *filp, char __user *ubuf, size_t count,
381 char *buf; 401 char *buf;
382 ssize_t ret, out_offset, out_count; 402 ssize_t ret, out_offset, out_count;
383 403
384 out_count = 600; 404 out_count = 1000;
385 405
386 buf = kmalloc(out_count, GFP_KERNEL); 406 buf = kmalloc(out_count, GFP_KERNEL);
387 if (!buf) 407 if (!buf)
@@ -396,6 +416,10 @@ static ssize_t debugfs_read(struct file *filp, char __user *ubuf, size_t count,
396 out_offset += snprintf(buf + out_offset, out_count - out_offset, 416 out_offset += snprintf(buf + out_offset, out_count - out_offset,
397 "rx_pkts - \t%llu\n", qp->rx_pkts); 417 "rx_pkts - \t%llu\n", qp->rx_pkts);
398 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,
399 "rx_ring_empty - %llu\n", qp->rx_ring_empty); 423 "rx_ring_empty - %llu\n", qp->rx_ring_empty);
400 out_offset += snprintf(buf + out_offset, out_count - out_offset, 424 out_offset += snprintf(buf + out_offset, out_count - out_offset,
401 "rx_err_no_buf - %llu\n", qp->rx_err_no_buf); 425 "rx_err_no_buf - %llu\n", qp->rx_err_no_buf);
@@ -415,8 +439,14 @@ static ssize_t debugfs_read(struct file *filp, char __user *ubuf, size_t count,
415 out_offset += snprintf(buf + out_offset, out_count - out_offset, 439 out_offset += snprintf(buf + out_offset, out_count - out_offset,
416 "tx_pkts - \t%llu\n", qp->tx_pkts); 440 "tx_pkts - \t%llu\n", qp->tx_pkts);
417 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,
418 "tx_ring_full - \t%llu\n", qp->tx_ring_full); 446 "tx_ring_full - \t%llu\n", qp->tx_ring_full);
419 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,
420 "tx_mw - \t%p\n", qp->tx_mw); 450 "tx_mw - \t%p\n", qp->tx_mw);
421 out_offset += snprintf(buf + out_offset, out_count - out_offset, 451 out_offset += snprintf(buf + out_offset, out_count - out_offset,
422 "tx_index - \t%u\n", qp->tx_index); 452 "tx_index - \t%u\n", qp->tx_index);
@@ -488,11 +518,11 @@ static void ntb_transport_setup_qp_mw(struct ntb_transport *nt,
488 num_qps_mw = nt->max_qps / mw_max; 518 num_qps_mw = nt->max_qps / mw_max;
489 519
490 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;
491 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;
492 (qp_num / mw_max * rx_size); <