diff options
| author | Jon Mason <jon.mason@intel.com> | 2013-02-12 11:52:50 -0500 |
|---|---|---|
| committer | Jon Mason <jon.mason@intel.com> | 2013-09-05 14:04:09 -0400 |
| commit | 282a2feeb9bfb1d1dfbad93df206b74eaf80d564 (patch) | |
| tree | 9265a6308dd746606dbcb0bac330082f97780be9 /drivers/ntb | |
| parent | ac477afb0431386575ef453f50fa0052c3f0461b (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.c | 17 | ||||
| -rw-r--r-- | drivers/ntb/ntb_hw.h | 1 | ||||
| -rw-r--r-- | drivers/ntb/ntb_transport.c | 324 |
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 | */ | ||
| 361 | resource_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); | |||
| 240 | 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); |
| 241 | 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); |
| 242 | 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); | ||
| 243 | 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); |
| 244 | u64 ntb_get_mw_size(struct ntb_device *ndev, unsigned int mw); | 245 | u64 ntb_get_mw_size(struct ntb_device *ndev, unsigned int mw); |
| 245 | void ntb_ring_sdb(struct ntb_device *ndev, unsigned int idx); | 246 | void 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; | |||
| 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 { |
| @@ -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); | < | |
