Commit 56a451b7 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'ntb-5.7' of git://github.com/jonmason/ntb

Pull NTB updates from Jon Mason:
 "Bug fixes for a few printing issues, link status detection bug on AMD
  hardware, and a DMA address issue with ntb_perf.

  Also, large series of AMD NTB patches"

* tag 'ntb-5.7' of git://github.com/jonmason/ntb: (21 commits)
  NTB: add pci shutdown handler for AMD NTB
  NTB: send DB event when driver is loaded or un-loaded
  NTB: remove redundant setting of DB valid mask
  NTB: return link up status correctly for PRI and SEC
  NTB: add helper functions to set and clear sideinfo
  NTB: move ntb_ctrl handling to init and deinit
  NTB: handle link up, D0 and D3 events correctly
  NTB: handle link down event correctly
  NTB: remove handling of peer_sta from amd_link_is_up
  NTB: set peer_sta within event handler itself
  NTB: return the side info status from amd_poll_link
  NTB: define a new function to get link status
  NTB: Enable link up and down event notification
  NTB: clear interrupt status register
  NTB: Fix access to link status and control register
  MAINTAINERS: update maintainer list for AMD NTB driver
  NTB: ntb_transport: Use scnprintf() for avoiding potential buffer overflow
  ntb_hw_switchtec: Fix ntb_mw_clear_trans error if size == 0
  ntb_tool: Fix printk format
  NTB: ntb_perf: Fix address err in perf_copy_chunk
  ...
parents dba43fc4 b350f0a3
...@@ -11896,6 +11896,7 @@ F: scripts/nsdeps ...@@ -11896,6 +11896,7 @@ F: scripts/nsdeps
F: Documentation/core-api/symbol-namespaces.rst F: Documentation/core-api/symbol-namespaces.rst
NTB AMD DRIVER NTB AMD DRIVER
M: Sanjay R Mehta <sanju.mehta@amd.com>
M: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> M: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
L: linux-ntb@googlegroups.com L: linux-ntb@googlegroups.com
S: Supported S: Supported
......
This diff is collapsed.
...@@ -53,11 +53,8 @@ ...@@ -53,11 +53,8 @@
#include <linux/pci.h> #include <linux/pci.h>
#define AMD_LINK_HB_TIMEOUT msecs_to_jiffies(1000) #define AMD_LINK_HB_TIMEOUT msecs_to_jiffies(1000)
#define AMD_LINK_STATUS_OFFSET 0x68
#define NTB_LIN_STA_ACTIVE_BIT 0x00000002
#define NTB_LNK_STA_SPEED_MASK 0x000F0000 #define NTB_LNK_STA_SPEED_MASK 0x000F0000
#define NTB_LNK_STA_WIDTH_MASK 0x03F00000 #define NTB_LNK_STA_WIDTH_MASK 0x03F00000
#define NTB_LNK_STA_ACTIVE(x) (!!((x) & NTB_LIN_STA_ACTIVE_BIT))
#define NTB_LNK_STA_SPEED(x) (((x) & NTB_LNK_STA_SPEED_MASK) >> 16) #define NTB_LNK_STA_SPEED(x) (((x) & NTB_LNK_STA_SPEED_MASK) >> 16)
#define NTB_LNK_STA_WIDTH(x) (((x) & NTB_LNK_STA_WIDTH_MASK) >> 20) #define NTB_LNK_STA_WIDTH(x) (((x) & NTB_LNK_STA_WIDTH_MASK) >> 20)
...@@ -196,6 +193,7 @@ struct amd_ntb_dev { ...@@ -196,6 +193,7 @@ struct amd_ntb_dev {
u64 db_valid_mask; u64 db_valid_mask;
u64 db_mask; u64 db_mask;
u64 db_last_bit;
u32 int_mask; u32 int_mask;
struct msix_entry *msix; struct msix_entry *msix;
...@@ -218,4 +216,8 @@ struct amd_ntb_dev { ...@@ -218,4 +216,8 @@ struct amd_ntb_dev {
#define ntb_ndev(__ntb) container_of(__ntb, struct amd_ntb_dev, ntb) #define ntb_ndev(__ntb) container_of(__ntb, struct amd_ntb_dev, ntb)
#define hb_ndev(__work) container_of(__work, struct amd_ntb_dev, hb_timer.work) #define hb_ndev(__work) container_of(__work, struct amd_ntb_dev, hb_timer.work)
static void amd_set_side_info_reg(struct amd_ntb_dev *ndev, bool peer);
static void amd_clear_side_info_reg(struct amd_ntb_dev *ndev, bool peer);
static int amd_poll_link(struct amd_ntb_dev *ndev);
#endif #endif
...@@ -285,7 +285,7 @@ static int switchtec_ntb_mw_set_trans(struct ntb_dev *ntb, int pidx, int widx, ...@@ -285,7 +285,7 @@ static int switchtec_ntb_mw_set_trans(struct ntb_dev *ntb, int pidx, int widx,
if (widx >= switchtec_ntb_mw_count(ntb, pidx)) if (widx >= switchtec_ntb_mw_count(ntb, pidx))
return -EINVAL; return -EINVAL;
if (xlate_pos < 12) if (size != 0 && xlate_pos < 12)
return -EINVAL; return -EINVAL;
if (!IS_ALIGNED(addr, BIT_ULL(xlate_pos))) { if (!IS_ALIGNED(addr, BIT_ULL(xlate_pos))) {
......
...@@ -481,70 +481,70 @@ static ssize_t debugfs_read(struct file *filp, char __user *ubuf, size_t count, ...@@ -481,70 +481,70 @@ static ssize_t debugfs_read(struct file *filp, char __user *ubuf, size_t count,
return -ENOMEM; return -ENOMEM;
out_offset = 0; out_offset = 0;
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"\nNTB QP stats:\n\n"); "\nNTB QP stats:\n\n");
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"rx_bytes - \t%llu\n", qp->rx_bytes); "rx_bytes - \t%llu\n", qp->rx_bytes);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"rx_pkts - \t%llu\n", qp->rx_pkts); "rx_pkts - \t%llu\n", qp->rx_pkts);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"rx_memcpy - \t%llu\n", qp->rx_memcpy); "rx_memcpy - \t%llu\n", qp->rx_memcpy);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"rx_async - \t%llu\n", qp->rx_async); "rx_async - \t%llu\n", qp->rx_async);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"rx_ring_empty - %llu\n", qp->rx_ring_empty); "rx_ring_empty - %llu\n", qp->rx_ring_empty);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"rx_err_no_buf - %llu\n", qp->rx_err_no_buf); "rx_err_no_buf - %llu\n", qp->rx_err_no_buf);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"rx_err_oflow - \t%llu\n", qp->rx_err_oflow); "rx_err_oflow - \t%llu\n", qp->rx_err_oflow);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"rx_err_ver - \t%llu\n", qp->rx_err_ver); "rx_err_ver - \t%llu\n", qp->rx_err_ver);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"rx_buff - \t0x%p\n", qp->rx_buff); "rx_buff - \t0x%p\n", qp->rx_buff);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"rx_index - \t%u\n", qp->rx_index); "rx_index - \t%u\n", qp->rx_index);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"rx_max_entry - \t%u\n", qp->rx_max_entry); "rx_max_entry - \t%u\n", qp->rx_max_entry);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"rx_alloc_entry - \t%u\n\n", qp->rx_alloc_entry); "rx_alloc_entry - \t%u\n\n", qp->rx_alloc_entry);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"tx_bytes - \t%llu\n", qp->tx_bytes); "tx_bytes - \t%llu\n", qp->tx_bytes);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"tx_pkts - \t%llu\n", qp->tx_pkts); "tx_pkts - \t%llu\n", qp->tx_pkts);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"tx_memcpy - \t%llu\n", qp->tx_memcpy); "tx_memcpy - \t%llu\n", qp->tx_memcpy);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"tx_async - \t%llu\n", qp->tx_async); "tx_async - \t%llu\n", qp->tx_async);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"tx_ring_full - \t%llu\n", qp->tx_ring_full); "tx_ring_full - \t%llu\n", qp->tx_ring_full);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"tx_err_no_buf - %llu\n", qp->tx_err_no_buf); "tx_err_no_buf - %llu\n", qp->tx_err_no_buf);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"tx_mw - \t0x%p\n", qp->tx_mw); "tx_mw - \t0x%p\n", qp->tx_mw);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"tx_index (H) - \t%u\n", qp->tx_index); "tx_index (H) - \t%u\n", qp->tx_index);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"RRI (T) - \t%u\n", "RRI (T) - \t%u\n",
qp->remote_rx_info->entry); qp->remote_rx_info->entry);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"tx_max_entry - \t%u\n", qp->tx_max_entry); "tx_max_entry - \t%u\n", qp->tx_max_entry);
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"free tx - \t%u\n", "free tx - \t%u\n",
ntb_transport_tx_free_entry(qp)); ntb_transport_tx_free_entry(qp));
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"\n"); "\n");
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"Using TX DMA - \t%s\n", "Using TX DMA - \t%s\n",
qp->tx_dma_chan ? "Yes" : "No"); qp->tx_dma_chan ? "Yes" : "No");
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"Using RX DMA - \t%s\n", "Using RX DMA - \t%s\n",
qp->rx_dma_chan ? "Yes" : "No"); qp->rx_dma_chan ? "Yes" : "No");
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"QP Link - \t%s\n", "QP Link - \t%s\n",
qp->link_is_up ? "Up" : "Down"); qp->link_is_up ? "Up" : "Down");
out_offset += snprintf(buf + out_offset, out_count - out_offset, out_offset += scnprintf(buf + out_offset, out_count - out_offset,
"\n"); "\n");
if (out_offset > out_count) if (out_offset > out_count)
......
...@@ -149,7 +149,8 @@ struct perf_peer { ...@@ -149,7 +149,8 @@ struct perf_peer {
u64 outbuf_xlat; u64 outbuf_xlat;
resource_size_t outbuf_size; resource_size_t outbuf_size;
void __iomem *outbuf; void __iomem *outbuf;
phys_addr_t out_phys_addr;
dma_addr_t dma_dst_addr;
/* Inbound MW params */ /* Inbound MW params */
dma_addr_t inbuf_xlat; dma_addr_t inbuf_xlat;
resource_size_t inbuf_size; resource_size_t inbuf_size;
...@@ -782,6 +783,10 @@ static int perf_copy_chunk(struct perf_thread *pthr, ...@@ -782,6 +783,10 @@ static int perf_copy_chunk(struct perf_thread *pthr,
struct dmaengine_unmap_data *unmap; struct dmaengine_unmap_data *unmap;
struct device *dma_dev; struct device *dma_dev;
int try = 0, ret = 0; int try = 0, ret = 0;
struct perf_peer *peer = pthr->perf->test_peer;
void __iomem *vbase;
void __iomem *dst_vaddr;
dma_addr_t dst_dma_addr;
if (!use_dma) { if (!use_dma) {
memcpy_toio(dst, src, len); memcpy_toio(dst, src, len);
...@@ -794,6 +799,10 @@ static int perf_copy_chunk(struct perf_thread *pthr, ...@@ -794,6 +799,10 @@ static int perf_copy_chunk(struct perf_thread *pthr,
offset_in_page(dst), len)) offset_in_page(dst), len))
return -EIO; return -EIO;
vbase = peer->outbuf;
dst_vaddr = dst;
dst_dma_addr = peer->dma_dst_addr + (dst_vaddr - vbase);
unmap = dmaengine_get_unmap_data(dma_dev, 2, GFP_NOWAIT); unmap = dmaengine_get_unmap_data(dma_dev, 2, GFP_NOWAIT);
if (!unmap) if (!unmap)
return -ENOMEM; return -ENOMEM;
...@@ -807,8 +816,7 @@ static int perf_copy_chunk(struct perf_thread *pthr, ...@@ -807,8 +816,7 @@ static int perf_copy_chunk(struct perf_thread *pthr,
} }
unmap->to_cnt = 1; unmap->to_cnt = 1;
unmap->addr[1] = dma_map_page(dma_dev, virt_to_page(dst), unmap->addr[1] = dst_dma_addr;
offset_in_page(dst), len, DMA_FROM_DEVICE);
if (dma_mapping_error(dma_dev, unmap->addr[1])) { if (dma_mapping_error(dma_dev, unmap->addr[1])) {
ret = -EIO; ret = -EIO;
goto err_free_resource; goto err_free_resource;
...@@ -865,6 +873,7 @@ static int perf_init_test(struct perf_thread *pthr) ...@@ -865,6 +873,7 @@ static int perf_init_test(struct perf_thread *pthr)
{ {
struct perf_ctx *perf = pthr->perf; struct perf_ctx *perf = pthr->perf;
dma_cap_mask_t dma_mask; dma_cap_mask_t dma_mask;
struct perf_peer *peer = pthr->perf->test_peer;
pthr->src = kmalloc_node(perf->test_peer->outbuf_size, GFP_KERNEL, pthr->src = kmalloc_node(perf->test_peer->outbuf_size, GFP_KERNEL,
dev_to_node(&perf->ntb->dev)); dev_to_node(&perf->ntb->dev));
...@@ -882,15 +891,33 @@ static int perf_init_test(struct perf_thread *pthr) ...@@ -882,15 +891,33 @@ static int perf_init_test(struct perf_thread *pthr)
if (!pthr->dma_chan) { if (!pthr->dma_chan) {
dev_err(&perf->ntb->dev, "%d: Failed to get DMA channel\n", dev_err(&perf->ntb->dev, "%d: Failed to get DMA channel\n",
pthr->tidx); pthr->tidx);
atomic_dec(&perf->tsync); goto err_free;
wake_up(&perf->twait);
kfree(pthr->src);
return -ENODEV;
} }
peer->dma_dst_addr =
dma_map_resource(pthr->dma_chan->device->dev,
peer->out_phys_addr, peer->outbuf_size,
DMA_FROM_DEVICE, 0);
if (dma_mapping_error(pthr->dma_chan->device->dev,
peer->dma_dst_addr)) {
dev_err(pthr->dma_chan->device->dev, "%d: Failed to map DMA addr\n",
pthr->tidx);
peer->dma_dst_addr = 0;
dma_release_channel(pthr->dma_chan);
goto err_free;
}
dev_dbg(pthr->dma_chan->device->dev, "%d: Map MMIO %pa to DMA addr %pad\n",
pthr->tidx,
&peer->out_phys_addr,
&peer->dma_dst_addr);
atomic_set(&pthr->dma_sync, 0); atomic_set(&pthr->dma_sync, 0);
return 0; return 0;
err_free:
atomic_dec(&perf->tsync);
wake_up(&perf->twait);
kfree(pthr->src);
return -ENODEV;
} }
static int perf_run_test(struct perf_thread *pthr) static int perf_run_test(struct perf_thread *pthr)
...@@ -978,8 +1005,13 @@ static void perf_clear_test(struct perf_thread *pthr) ...@@ -978,8 +1005,13 @@ static void perf_clear_test(struct perf_thread *pthr)
* We call it anyway just to be sure of the transfers completion. * We call it anyway just to be sure of the transfers completion.
*/ */
(void)dmaengine_terminate_sync(pthr->dma_chan); (void)dmaengine_terminate_sync(pthr->dma_chan);
if (pthr->perf->test_peer->dma_dst_addr)
dma_release_channel(pthr->dma_chan); dma_unmap_resource(pthr->dma_chan->device->dev,
pthr->perf->test_peer->dma_dst_addr,
pthr->perf->test_peer->outbuf_size,
DMA_FROM_DEVICE, 0);
if (pthr->dma_chan)
dma_release_channel(pthr->dma_chan);
no_dma_notify: no_dma_notify:
atomic_dec(&perf->tsync); atomic_dec(&perf->tsync);
...@@ -1194,6 +1226,9 @@ static ssize_t perf_dbgfs_read_info(struct file *filep, char __user *ubuf, ...@@ -1194,6 +1226,9 @@ static ssize_t perf_dbgfs_read_info(struct file *filep, char __user *ubuf,
pos += scnprintf(buf + pos, buf_size - pos, pos += scnprintf(buf + pos, buf_size - pos,
"\tOut buffer addr 0x%pK\n", peer->outbuf); "\tOut buffer addr 0x%pK\n", peer->outbuf);
pos += scnprintf(buf + pos, buf_size - pos,
"\tOut buff phys addr %pa[p]\n", &peer->out_phys_addr);
pos += scnprintf(buf + pos, buf_size - pos, pos += scnprintf(buf + pos, buf_size - pos,
"\tOut buffer size %pa\n", &peer->outbuf_size); "\tOut buffer size %pa\n", &peer->outbuf_size);
...@@ -1388,6 +1423,8 @@ static int perf_setup_peer_mw(struct perf_peer *peer) ...@@ -1388,6 +1423,8 @@ static int perf_setup_peer_mw(struct perf_peer *peer)
if (!peer->outbuf) if (!peer->outbuf)
return -ENOMEM; return -ENOMEM;
peer->out_phys_addr = phys_addr;
if (max_mw_size && peer->outbuf_size > max_mw_size) { if (max_mw_size && peer->outbuf_size > max_mw_size) {
peer->outbuf_size = max_mw_size; peer->outbuf_size = max_mw_size;
dev_warn(&peer->perf->ntb->dev, dev_warn(&peer->perf->ntb->dev,
......
...@@ -678,19 +678,19 @@ static ssize_t tool_mw_trans_read(struct file *filep, char __user *ubuf, ...@@ -678,19 +678,19 @@ static ssize_t tool_mw_trans_read(struct file *filep, char __user *ubuf,
&inmw->dma_base); &inmw->dma_base);
off += scnprintf(buf + off, buf_size - off, off += scnprintf(buf + off, buf_size - off,
"Window Size \t%pa[p]\n", "Window Size \t%pap\n",
&inmw->size); &inmw->size);
off += scnprintf(buf + off, buf_size - off, off += scnprintf(buf + off, buf_size - off,
"Alignment \t%pa[p]\n", "Alignment \t%pap\n",
&addr_align); &addr_align);
off += scnprintf(buf + off, buf_size - off, off += scnprintf(buf + off, buf_size - off,
"Size Alignment \t%pa[p]\n", "Size Alignment \t%pap\n",
&size_align); &size_align);
off += scnprintf(buf + off, buf_size - off, off += scnprintf(buf + off, buf_size - off,
"Size Max \t%pa[p]\n", "Size Max \t%pap\n",
&size_max); &size_max);
ret = simple_read_from_buffer(ubuf, size, offp, buf, off); ret = simple_read_from_buffer(ubuf, size, offp, buf, off);
...@@ -907,16 +907,16 @@ static ssize_t tool_peer_mw_trans_read(struct file *filep, char __user *ubuf, ...@@ -907,16 +907,16 @@ static ssize_t tool_peer_mw_trans_read(struct file *filep, char __user *ubuf,
"Virtual address \t0x%pK\n", outmw->io_base); "Virtual address \t0x%pK\n", outmw->io_base);
off += scnprintf(buf + off, buf_size - off, off += scnprintf(buf + off, buf_size - off,
"Phys Address \t%pa[p]\n", &map_base); "Phys Address \t%pap\n", &map_base);
off += scnprintf(buf + off, buf_size - off, off += scnprintf(buf + off, buf_size - off,
"Mapping Size \t%pa[p]\n", &map_size); "Mapping Size \t%pap\n", &map_size);
off += scnprintf(buf + off, buf_size - off, off += scnprintf(buf + off, buf_size - off,
"Translation Address \t0x%016llx\n", outmw->tr_base); "Translation Address \t0x%016llx\n", outmw->tr_base);
off += scnprintf(buf + off, buf_size - off, off += scnprintf(buf + off, buf_size - off,
"Window Size \t%pa[p]\n", &outmw->size); "Window Size \t%pap\n", &outmw->size);
ret = simple_read_from_buffer(ubuf, size, offp, buf, off); ret = simple_read_from_buffer(ubuf, size, offp, buf, off);
kfree(buf); kfree(buf);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment