linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] Switchtec MRPC DMA mode support
@ 2018-12-10  9:12 Wesley Sheng
  2018-12-10  9:12 ` [PATCH 1/5] switchtec: Remove immediate status check after submit a MRPC command Wesley Sheng
                   ` (5 more replies)
  0 siblings, 6 replies; 15+ messages in thread
From: Wesley Sheng @ 2018-12-10  9:12 UTC (permalink / raw)
  To: kurt.schwemmer, logang, bhelgaas, linux-pci, linux-kernel
  Cc: wesleyshenggit, wesley.sheng

Hi, Everyone,

This patch series adds support for the Switchtec MRPC DMA mode.

Switchtec switches supports 2 MRPC interaction modes: MRPC normal mode and
MRPC DMA mode, a new feature in the latest firmware versions. MRPC normal 
mode requires the host to read the MRPC command status and output data. 
In MRPC DMA mode the command status and output data are pushed directly to
host memory and issues an interrupt upon completion. The advantage of MRPC
DMA mode is avoiding potential high latency response from the Memory Read
TLP. 

Additionally, we've made the following changes:

* Improve the efficiency of filling MRPC Input buffer by enabling write 
  combining on MRPC region of BAR
* Software workaround for delay responded Memory READ TLPs that access 
  the BAR
* And several bug fixes

Regards,
Wesley

--

Changed since v1:
  - It's a resend of v1

--


Boris Glimcher (1):
  switchtec: Set DMA coherent mask in Switchtec driver

Joey Zhang (1):
  switchtec: A temporary variable should be used for the flags of
    switchtec_ioctl_event_ctl

Kelvin Cao (2):
  switchtec: Remove immediate status check after submit a MRPC command
  switchtec: Improve MRPC efficiency by leveraging write combining

Wesley Sheng (1):
  switchtec: MRPC DMA mode implementation

 drivers/pci/switch/switchtec.c | 154 ++++++++++++++++++++++++++++++++++++-----
 include/linux/switchtec.h      |  16 +++++
 2 files changed, 153 insertions(+), 17 deletions(-)

-- 
2.7.4


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1/5] switchtec: Remove immediate status check after submit a MRPC command
  2018-12-10  9:12 [PATCH 0/5] Switchtec MRPC DMA mode support Wesley Sheng
@ 2018-12-10  9:12 ` Wesley Sheng
  2018-12-10  9:12 ` [PATCH 2/5] switchtec: Set DMA coherent mask in Switchtec driver Wesley Sheng
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 15+ messages in thread
From: Wesley Sheng @ 2018-12-10  9:12 UTC (permalink / raw)
  To: kurt.schwemmer, logang, bhelgaas, linux-pci, linux-kernel
  Cc: wesleyshenggit, wesley.sheng

From: Kelvin Cao <kelvin.cao@microchip.com>

After submitting a Firmware Download MRPC command, Switchtec firmware will
delay Management EP BAR MemRd TLP responses by more than 10ms. This is a
firmware limitation. Delayed MemRd completions are problem for systems with
a low Completion Timeout (CTO).

The current driver checks the MRPC status immediately after submitting an
MRPC command, which results in the MemRd TLP that's affected by the above
limitation.

Remove the immediate status check and rely on the check after receiving an
interrupt or timing out.

This is only a software workaround to the READ issue and a proper fix of
this should be done in firmware.

Fixes: 080b47def5e5 ("MicroSemi Switchtec management interface driver")
Signed-off-by: Kelvin Cao <kelvin.cao@microchip.com>
Signed-off-by: Wesley Sheng <wesley.sheng@microchip.com>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/pci/switch/switchtec.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
index 54a8b30..d2bca2d 100644
--- a/drivers/pci/switch/switchtec.c
+++ b/drivers/pci/switch/switchtec.c
@@ -134,10 +134,6 @@ static void mrpc_cmd_submit(struct switchtec_dev *stdev)
 		    stuser->data, stuser->data_len);
 	iowrite32(stuser->cmd, &stdev->mmio_mrpc->cmd);
 
-	stuser->status = ioread32(&stdev->mmio_mrpc->status);
-	if (stuser->status != SWITCHTEC_MRPC_STATUS_INPROGRESS)
-		mrpc_complete_cmd(stdev);
-
 	schedule_delayed_work(&stdev->mrpc_timeout,
 			      msecs_to_jiffies(500));
 }
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 2/5] switchtec: Set DMA coherent mask in Switchtec driver
  2018-12-10  9:12 [PATCH 0/5] Switchtec MRPC DMA mode support Wesley Sheng
  2018-12-10  9:12 ` [PATCH 1/5] switchtec: Remove immediate status check after submit a MRPC command Wesley Sheng
@ 2018-12-10  9:12 ` Wesley Sheng
  2018-12-10  9:12 ` [PATCH 3/5] switchtec: A temporary variable should be used for the flags of switchtec_ioctl_event_ctl Wesley Sheng
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 15+ messages in thread
From: Wesley Sheng @ 2018-12-10  9:12 UTC (permalink / raw)
  To: kurt.schwemmer, logang, bhelgaas, linux-pci, linux-kernel
  Cc: wesleyshenggit, wesley.sheng

From: Boris Glimcher <Boris.Glimcher@emc.com>

Switchtec hardware supports 64-bit DMA, set the correct DMA mask.
This allows the CMA to allocate larger buffers for memory windows.

Signed-off-by: Boris Glimcher <Boris.Glimcher@emc.com>
Signed-off-by: Wesley Sheng <wesley.sheng@microchip.com>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/pci/switch/switchtec.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
index d2bca2d..480107e 100644
--- a/drivers/pci/switch/switchtec.c
+++ b/drivers/pci/switch/switchtec.c
@@ -1237,6 +1237,10 @@ static int switchtec_init_pci(struct switchtec_dev *stdev,
 	if (rc)
 		return rc;
 
+	rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
+	if (rc)
+		return rc;
+
 	pci_set_master(pdev);
 
 	stdev->mmio = pcim_iomap_table(pdev)[0];
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 3/5] switchtec: A temporary variable should be used for the flags of switchtec_ioctl_event_ctl
  2018-12-10  9:12 [PATCH 0/5] Switchtec MRPC DMA mode support Wesley Sheng
  2018-12-10  9:12 ` [PATCH 1/5] switchtec: Remove immediate status check after submit a MRPC command Wesley Sheng
  2018-12-10  9:12 ` [PATCH 2/5] switchtec: Set DMA coherent mask in Switchtec driver Wesley Sheng
@ 2018-12-10  9:12 ` Wesley Sheng
  2018-12-12 22:43   ` Bjorn Helgaas
  2018-12-10  9:12 ` [PATCH 4/5] switchtec: Improve MRPC efficiency by leveraging write combining Wesley Sheng
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Wesley Sheng @ 2018-12-10  9:12 UTC (permalink / raw)
  To: kurt.schwemmer, logang, bhelgaas, linux-pci, linux-kernel
  Cc: wesleyshenggit, wesley.sheng

From: Joey Zhang <joey.zhang@microchip.com>

For nr_idxs is larger than 1 switchtec_ioctl_event_ctl event flags will be
used by each event indexes. In current implementation the event flags are
overwritten by first call of the function event_ctl().

Preserve the event flag value with a temporary variable.

Fixes: 52eabba5bcdb ("switchtec: Add IOCTLs to the Switchtec driver")
Signed-off-by: Joey Zhang <joey.zhang@microchip.com>
Signed-off-by: Wesley Sheng <wesley.sheng@microchip.com>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/pci/switch/switchtec.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
index 480107e..a908670 100644
--- a/drivers/pci/switch/switchtec.c
+++ b/drivers/pci/switch/switchtec.c
@@ -796,6 +796,7 @@ static int ioctl_event_ctl(struct switchtec_dev *stdev,
 {
 	int ret;
 	int nr_idxs;
+	unsigned int event_flags;
 	struct switchtec_ioctl_event_ctl ctl;
 
 	if (copy_from_user(&ctl, uctl, sizeof(ctl)))
@@ -817,7 +818,9 @@ static int ioctl_event_ctl(struct switchtec_dev *stdev,
 		else
 			return -EINVAL;
 
+		event_flags = ctl.flags;
 		for (ctl.index = 0; ctl.index < nr_idxs; ctl.index++) {
+			ctl.flags = event_flags;
 			ret = event_ctl(stdev, &ctl);
 			if (ret < 0)
 				return ret;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 4/5] switchtec: Improve MRPC efficiency by leveraging write combining
  2018-12-10  9:12 [PATCH 0/5] Switchtec MRPC DMA mode support Wesley Sheng
                   ` (2 preceding siblings ...)
  2018-12-10  9:12 ` [PATCH 3/5] switchtec: A temporary variable should be used for the flags of switchtec_ioctl_event_ctl Wesley Sheng
@ 2018-12-10  9:12 ` Wesley Sheng
  2018-12-10  9:12 ` [PATCH 5/5] switchtec: MRPC DMA mode implementation Wesley Sheng
  2018-12-13 15:20 ` [PATCH 0/5] Switchtec MRPC DMA mode support Bjorn Helgaas
  5 siblings, 0 replies; 15+ messages in thread
From: Wesley Sheng @ 2018-12-10  9:12 UTC (permalink / raw)
  To: kurt.schwemmer, logang, bhelgaas, linux-pci, linux-kernel
  Cc: wesleyshenggit, wesley.sheng

From: Kelvin Cao <kelvin.cao@microchip.com>

MRPC Input buffer is mostly memory without any side effects, thus we can
improve the access time by enabling write combining on only this region of
the BAR.

In a few places, we still need to flush the WC buffer. To do this, we
simply read from the Outbound Doorbell register seeing reads to this
register are processed by low latency hardware.

Signed-off-by: Kelvin Cao <kelvin.cao@microchip.com>
Signed-off-by: Wesley Sheng <wesley.sheng@microchip.com>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/pci/switch/switchtec.c | 41 +++++++++++++++++++++++++++++++++++------
 1 file changed, 35 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
index a908670..0b8862b 100644
--- a/drivers/pci/switch/switchtec.c
+++ b/drivers/pci/switch/switchtec.c
@@ -113,6 +113,19 @@ static void stuser_set_state(struct switchtec_user *stuser,
 
 static void mrpc_complete_cmd(struct switchtec_dev *stdev);
 
+static void flush_wc_buf(struct switchtec_dev *stdev)
+{
+	struct ntb_dbmsg_regs __iomem *mmio_dbmsg;
+
+	/*
+	 * odb (outbound doorbell) register is processed by low latency
+	 * hardware and w/o side effect
+	 */
+	mmio_dbmsg = (void __iomem *)stdev->mmio_ntb +
+		SWITCHTEC_NTB_REG_DBMSG_OFFSET;
+	ioread32(&mmio_dbmsg->odb);
+}
+
 static void mrpc_cmd_submit(struct switchtec_dev *stdev)
 {
 	/* requires the mrpc_mutex to already be held when called */
@@ -132,6 +145,7 @@ static void mrpc_cmd_submit(struct switchtec_dev *stdev)
 	stdev->mrpc_busy = 1;
 	memcpy_toio(&stdev->mmio_mrpc->input_data,
 		    stuser->data, stuser->data_len);
+	flush_wc_buf(stdev);
 	iowrite32(stuser->cmd, &stdev->mmio_mrpc->cmd);
 
 	schedule_delayed_work(&stdev->mrpc_timeout,
@@ -1231,23 +1245,38 @@ static int switchtec_init_pci(struct switchtec_dev *stdev,
 			      struct pci_dev *pdev)
 {
 	int rc;
+	void __iomem *map;
+	unsigned long res_start, res_len;
 
 	rc = pcim_enable_device(pdev);
 	if (rc)
 		return rc;
 
-	rc = pcim_iomap_regions(pdev, 0x1, KBUILD_MODNAME);
-	if (rc)
-		return rc;
-
 	rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
 	if (rc)
 		return rc;
 
 	pci_set_master(pdev);
 
-	stdev->mmio = pcim_iomap_table(pdev)[0];
-	stdev->mmio_mrpc = stdev->mmio + SWITCHTEC_GAS_MRPC_OFFSET;
+	res_start = pci_resource_start(pdev, 0);
+	res_len = pci_resource_len(pdev, 0);
+
+	if (!devm_request_mem_region(&pdev->dev, res_start,
+				     res_len, KBUILD_MODNAME))
+		return -EBUSY;
+
+	stdev->mmio_mrpc = devm_ioremap_wc(&pdev->dev, res_start,
+					   SWITCHTEC_GAS_TOP_CFG_OFFSET);
+	if (!stdev->mmio_mrpc)
+		return -ENOMEM;
+
+	map = devm_ioremap(&pdev->dev,
+			   res_start + SWITCHTEC_GAS_TOP_CFG_OFFSET,
+			   res_len - SWITCHTEC_GAS_TOP_CFG_OFFSET);
+	if (!map)
+		return -ENOMEM;
+
+	stdev->mmio = map - SWITCHTEC_GAS_TOP_CFG_OFFSET;
 	stdev->mmio_sw_event = stdev->mmio + SWITCHTEC_GAS_SW_EVENT_OFFSET;
 	stdev->mmio_sys_info = stdev->mmio + SWITCHTEC_GAS_SYS_INFO_OFFSET;
 	stdev->mmio_flash_info = stdev->mmio + SWITCHTEC_GAS_FLASH_INFO_OFFSET;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 5/5] switchtec: MRPC DMA mode implementation
  2018-12-10  9:12 [PATCH 0/5] Switchtec MRPC DMA mode support Wesley Sheng
                   ` (3 preceding siblings ...)
  2018-12-10  9:12 ` [PATCH 4/5] switchtec: Improve MRPC efficiency by leveraging write combining Wesley Sheng
@ 2018-12-10  9:12 ` Wesley Sheng
  2018-12-12 22:52   ` Bjorn Helgaas
  2018-12-13 15:17   ` Bjorn Helgaas
  2018-12-13 15:20 ` [PATCH 0/5] Switchtec MRPC DMA mode support Bjorn Helgaas
  5 siblings, 2 replies; 15+ messages in thread
From: Wesley Sheng @ 2018-12-10  9:12 UTC (permalink / raw)
  To: kurt.schwemmer, logang, bhelgaas, linux-pci, linux-kernel
  Cc: wesleyshenggit, wesley.sheng

MRPC normal mode requires the host to read the MRPC command status and
output data from BAR. This results in high latency responses from the
Memory Read TLP and potential Completion Timeout (CTO).

MRPC DMA mode implementation includes:
Macro definitions for registers and data structures corresponding to
MRPC DMA mode.

Add module parameter use_dma_mrpc to select between MRPC DMA mode and
MRPC normal mode.

Add MRPC mode functionality to:
* Retrieve MRPC DMA mode version
* Allocate DMA buffer, ISR registration, and enable DMA function during
  initialization
* Check MRPC execution status and collect execution results from DMA buffer
* Release DMA buffer and disable DMA function when unloading module

MRPC DMA mode is a new feature of firmware and the driver will fall back
to MRPC normal mode if there is no support in the legacy firmware.

Include <linux/io-64-nonatomic-lo-hi.h> so that readq/writeq is replaced
by two readl/writel on systems that do not support it.

Signed-off-by: Wesley Sheng <wesley.sheng@microchip.com>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/pci/switch/switchtec.c | 108 +++++++++++++++++++++++++++++++++++++----
 include/linux/switchtec.h      |  16 ++++++
 2 files changed, 114 insertions(+), 10 deletions(-)

diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
index 0b8862b..6b726cb 100644
--- a/drivers/pci/switch/switchtec.c
+++ b/drivers/pci/switch/switchtec.c
@@ -13,7 +13,7 @@
 #include <linux/uaccess.h>
 #include <linux/poll.h>
 #include <linux/wait.h>
-
+#include <linux/io-64-nonatomic-lo-hi.h>
 #include <linux/nospec.h>
 
 MODULE_DESCRIPTION("Microsemi Switchtec(tm) PCIe Management Driver");
@@ -25,6 +25,11 @@ static int max_devices = 16;
 module_param(max_devices, int, 0644);
 MODULE_PARM_DESC(max_devices, "max number of switchtec device instances");
 
+static bool use_dma_mrpc = 1;
+module_param(use_dma_mrpc, bool, 0644);
+MODULE_PARM_DESC(use_dma_mrpc,
+		 "Enable the use of the DMA MRPC feature");
+
 static dev_t switchtec_devt;
 static DEFINE_IDA(switchtec_minor_ida);
 
@@ -141,6 +146,11 @@ static void mrpc_cmd_submit(struct switchtec_dev *stdev)
 	stuser = list_entry(stdev->mrpc_queue.next, struct switchtec_user,
 			    list);
 
+	if (stdev->dma_mrpc) {
+		stdev->dma_mrpc->status = SWITCHTEC_MRPC_STATUS_INPROGRESS;
+		memset(stdev->dma_mrpc->data, 0xFF, SWITCHTEC_MRPC_PAYLOAD_SIZE);
+	}
+
 	stuser_set_state(stuser, MRPC_RUNNING);
 	stdev->mrpc_busy = 1;
 	memcpy_toio(&stdev->mmio_mrpc->input_data,
@@ -180,7 +190,11 @@ static void mrpc_complete_cmd(struct switchtec_dev *stdev)
 	stuser = list_entry(stdev->mrpc_queue.next, struct switchtec_user,
 			    list);
 
-	stuser->status = ioread32(&stdev->mmio_mrpc->status);
+	if (stdev->dma_mrpc)
+		stuser->status = stdev->dma_mrpc->status;
+	else
+		stuser->status = ioread32(&stdev->mmio_mrpc->status);
+
 	if (stuser->status == SWITCHTEC_MRPC_STATUS_INPROGRESS)
 		return;
 
@@ -190,13 +204,19 @@ static void mrpc_complete_cmd(struct switchtec_dev *stdev)
 	if (stuser->status != SWITCHTEC_MRPC_STATUS_DONE)
 		goto out;
 
-	stuser->return_code = ioread32(&stdev->mmio_mrpc->ret_value);
+	if (stdev->dma_mrpc)
+		stuser->return_code = stdev->dma_mrpc->rtn_code;
+	else
+		stuser->return_code = ioread32(&stdev->mmio_mrpc->ret_value);
 	if (stuser->return_code != 0)
 		goto out;
 
-	memcpy_fromio(stuser->data, &stdev->mmio_mrpc->output_data,
-		      stuser->read_len);
-
+	if (stdev->dma_mrpc)
+		memcpy(stuser->data, &stdev->dma_mrpc->data,
+			      stuser->read_len);
+	else
+		memcpy_fromio(stuser->data, &stdev->mmio_mrpc->output_data,
+			      stuser->read_len);
 out:
 	complete_all(&stuser->comp);
 	list_del_init(&stuser->list);
@@ -231,7 +251,10 @@ static void mrpc_timeout_work(struct work_struct *work)
 
 	mutex_lock(&stdev->mrpc_mutex);
 
-	status = ioread32(&stdev->mmio_mrpc->status);
+	if (stdev->dma_mrpc)
+		status = stdev->dma_mrpc->status;
+	else
+		status = ioread32(&stdev->mmio_mrpc->status);
 	if (status == SWITCHTEC_MRPC_STATUS_INPROGRESS) {
 		schedule_delayed_work(&stdev->mrpc_timeout,
 				      msecs_to_jiffies(500));
@@ -239,7 +262,6 @@ static void mrpc_timeout_work(struct work_struct *work)
 	}
 
 	mrpc_complete_cmd(stdev);
-
 out:
 	mutex_unlock(&stdev->mrpc_mutex);
 }
@@ -1030,10 +1052,24 @@ static void enable_link_state_events(struct switchtec_dev *stdev)
 	}
 }
 
+static void enable_dma_mrpc(struct switchtec_dev *stdev)
+{
+	writeq(stdev->dma_mrpc_dma_addr, &stdev->mmio_mrpc->dma_addr);
+	flush_wc_buf(stdev);
+	iowrite32(SWITCHTEC_DMA_MRPC_EN, &stdev->mmio_mrpc->dma_en);
+}
+
 static void stdev_release(struct device *dev)
 {
 	struct switchtec_dev *stdev = to_stdev(dev);
 
+	if (stdev->dma_mrpc) {
+		iowrite32(0, &stdev->mmio_mrpc->dma_en);
+		flush_wc_buf(stdev);
+		writeq(0, &stdev->mmio_mrpc->dma_addr);
+		dma_free_coherent(&stdev->pdev->dev, sizeof(*stdev->dma_mrpc),
+				stdev->dma_mrpc, stdev->dma_mrpc_dma_addr);
+	}
 	kfree(stdev);
 }
 
@@ -1189,10 +1225,27 @@ static irqreturn_t switchtec_event_isr(int irq, void *dev)
 	return ret;
 }
 
+
+static irqreturn_t switchtec_dma_mrpc_isr(int irq, void *dev)
+{
+	struct switchtec_dev *stdev = dev;
+	irqreturn_t ret = IRQ_NONE;
+
+	iowrite32(SWITCHTEC_EVENT_CLEAR |
+		  SWITCHTEC_EVENT_EN_IRQ,
+		  &stdev->mmio_part_cfg->mrpc_comp_hdr);
+	schedule_work(&stdev->mrpc_work);
+
+	ret = IRQ_HANDLED;
+	return ret;
+}
+
 static int switchtec_init_isr(struct switchtec_dev *stdev)
 {
 	int nvecs;
 	int event_irq;
+	int dma_mrpc_irq;
+	int rc;
 
 	nvecs = pci_alloc_irq_vectors(stdev->pdev, 1, 4,
 				      PCI_IRQ_MSIX | PCI_IRQ_MSI);
@@ -1207,9 +1260,29 @@ static int switchtec_init_isr(struct switchtec_dev *stdev)
 	if (event_irq < 0)
 		return event_irq;
 
-	return devm_request_irq(&stdev->pdev->dev, event_irq,
+	rc = devm_request_irq(&stdev->pdev->dev, event_irq,
 				switchtec_event_isr, 0,
 				KBUILD_MODNAME, stdev);
+
+	if (rc)
+		return rc;
+
+	if (!stdev->dma_mrpc)
+		return rc;
+
+	dma_mrpc_irq = ioread32(&stdev->mmio_mrpc->dma_vector);
+	if (dma_mrpc_irq < 0 || dma_mrpc_irq >= nvecs)
+		return -EFAULT;
+
+	dma_mrpc_irq  = pci_irq_vector(stdev->pdev, dma_mrpc_irq);
+	if (dma_mrpc_irq < 0)
+		return dma_mrpc_irq;
+
+	rc = devm_request_irq(&stdev->pdev->dev, dma_mrpc_irq,
+				switchtec_dma_mrpc_isr, 0,
+				KBUILD_MODNAME, stdev);
+
+	return rc;
 }
 
 static void init_pff(struct switchtec_dev *stdev)
@@ -1294,6 +1367,19 @@ static int switchtec_init_pci(struct switchtec_dev *stdev,
 
 	pci_set_drvdata(pdev, stdev);
 
+	if (!use_dma_mrpc)
+		return 0;
+
+	if (!(ioread32(&stdev->mmio_mrpc->dma_ver) ? true : false))
+		return 0;
+
+	stdev->dma_mrpc = dma_zalloc_coherent(&stdev->pdev->dev,
+					      sizeof(*stdev->dma_mrpc),
+					      &stdev->dma_mrpc_dma_addr,
+					      GFP_KERNEL);
+	if (stdev->dma_mrpc == NULL)
+		return -ENOMEM;
+
 	return 0;
 }
 
@@ -1325,6 +1411,9 @@ static int switchtec_pci_probe(struct pci_dev *pdev,
 		  &stdev->mmio_part_cfg->mrpc_comp_hdr);
 	enable_link_state_events(stdev);
 
+	if (stdev->dma_mrpc)
+		enable_dma_mrpc(stdev);
+
 	rc = cdev_device_add(&stdev->cdev, &stdev->dev);
 	if (rc)
 		goto err_devadd;
@@ -1350,7 +1439,6 @@ static void switchtec_pci_remove(struct pci_dev *pdev)
 	cdev_device_del(&stdev->cdev, &stdev->dev);
 	ida_simple_remove(&switchtec_minor_ida, MINOR(stdev->dev.devt));
 	dev_info(&stdev->dev, "unregistered.\n");
-
 	stdev_kill(stdev);
 	put_device(&stdev->dev);
 }
diff --git a/include/linux/switchtec.h b/include/linux/switchtec.h
index ab400af..eee0412 100644
--- a/include/linux/switchtec.h
+++ b/include/linux/switchtec.h
@@ -29,6 +29,7 @@
 #define SWITCHTEC_EVENT_EN_IRQ   BIT(3)
 #define SWITCHTEC_EVENT_FATAL    BIT(4)
 
+#define SWITCHTEC_DMA_MRPC_EN	BIT(0)
 enum {
 	SWITCHTEC_GAS_MRPC_OFFSET       = 0x0000,
 	SWITCHTEC_GAS_TOP_CFG_OFFSET    = 0x1000,
@@ -46,6 +47,10 @@ struct mrpc_regs {
 	u32 cmd;
 	u32 status;
 	u32 ret_value;
+	u32 dma_en;
+	u64 dma_addr;
+	u32 dma_vector;
+	u32 dma_ver;
 } __packed;
 
 enum mrpc_status {
@@ -342,6 +347,14 @@ struct pff_csr_regs {
 
 struct switchtec_ntb;
 
+struct dma_mrpc_output {
+	u32 status;
+	u32 cmd_id;
+	u32 rtn_code;
+	u32 output_size;
+	u8 data[SWITCHTEC_MRPC_PAYLOAD_SIZE];
+};
+
 struct switchtec_dev {
 	struct pci_dev *pdev;
 	struct device dev;
@@ -381,6 +394,9 @@ struct switchtec_dev {
 	u8 link_event_count[SWITCHTEC_MAX_PFF_CSR];
 
 	struct switchtec_ntb *sndev;
+
+	struct dma_mrpc_output *dma_mrpc;
+	dma_addr_t dma_mrpc_dma_addr;
 };
 
 static inline struct switchtec_dev *to_stdev(struct device *dev)
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 3/5] switchtec: A temporary variable should be used for the flags of switchtec_ioctl_event_ctl
  2018-12-10  9:12 ` [PATCH 3/5] switchtec: A temporary variable should be used for the flags of switchtec_ioctl_event_ctl Wesley Sheng
@ 2018-12-12 22:43   ` Bjorn Helgaas
  2018-12-12 22:52     ` Logan Gunthorpe
  0 siblings, 1 reply; 15+ messages in thread
From: Bjorn Helgaas @ 2018-12-12 22:43 UTC (permalink / raw)
  To: Wesley Sheng
  Cc: kurt.schwemmer, logang, linux-pci, linux-kernel, wesleyshenggit

On Mon, Dec 10, 2018 at 05:12:22PM +0800, Wesley Sheng wrote:
> From: Joey Zhang <joey.zhang@microchip.com>
> 
> For nr_idxs is larger than 1 switchtec_ioctl_event_ctl event flags will be
> used by each event indexes. In current implementation the event flags are
> overwritten by first call of the function event_ctl().
> 
> Preserve the event flag value with a temporary variable.
> 
> Fixes: 52eabba5bcdb ("switchtec: Add IOCTLs to the Switchtec driver")
> Signed-off-by: Joey Zhang <joey.zhang@microchip.com>
> Signed-off-by: Wesley Sheng <wesley.sheng@microchip.com>
> Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
> ---
>  drivers/pci/switch/switchtec.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
> index 480107e..a908670 100644
> --- a/drivers/pci/switch/switchtec.c
> +++ b/drivers/pci/switch/switchtec.c
> @@ -796,6 +796,7 @@ static int ioctl_event_ctl(struct switchtec_dev *stdev,
>  {
>  	int ret;
>  	int nr_idxs;
> +	unsigned int event_flags;
>  	struct switchtec_ioctl_event_ctl ctl;
>  
>  	if (copy_from_user(&ctl, uctl, sizeof(ctl)))
> @@ -817,7 +818,9 @@ static int ioctl_event_ctl(struct switchtec_dev *stdev,
>  		else
>  			return -EINVAL;
>  
> +		event_flags = ctl.flags;
>  		for (ctl.index = 0; ctl.index < nr_idxs; ctl.index++) {
> +			ctl.flags = event_flags;
>  			ret = event_ctl(stdev, &ctl);

event_ctl() overwrites several other things, in addition to ctl.flags:

  ctl.data[]
  ctl.occurred
  ctl.count

Is that what you intend?  It looks like only the values from the *last*
call of event_ctl() will be copied back to the user buffer.

>  			if (ret < 0)
>  				return ret;
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 5/5] switchtec: MRPC DMA mode implementation
  2018-12-10  9:12 ` [PATCH 5/5] switchtec: MRPC DMA mode implementation Wesley Sheng
@ 2018-12-12 22:52   ` Bjorn Helgaas
  2018-12-12 22:58     ` Logan Gunthorpe
  2018-12-13 15:17   ` Bjorn Helgaas
  1 sibling, 1 reply; 15+ messages in thread
From: Bjorn Helgaas @ 2018-12-12 22:52 UTC (permalink / raw)
  To: Wesley Sheng
  Cc: kurt.schwemmer, logang, linux-pci, linux-kernel, wesleyshenggit

On Mon, Dec 10, 2018 at 05:12:24PM +0800, Wesley Sheng wrote:
> MRPC normal mode requires the host to read the MRPC command status and
> output data from BAR. This results in high latency responses from the
> Memory Read TLP and potential Completion Timeout (CTO).
> 
> MRPC DMA mode implementation includes:
> Macro definitions for registers and data structures corresponding to
> MRPC DMA mode.
> 
> Add module parameter use_dma_mrpc to select between MRPC DMA mode and
> MRPC normal mode.
> 
> Add MRPC mode functionality to:
> * Retrieve MRPC DMA mode version
> * Allocate DMA buffer, ISR registration, and enable DMA function during
>   initialization
> * Check MRPC execution status and collect execution results from DMA buffer
> * Release DMA buffer and disable DMA function when unloading module
> 
> MRPC DMA mode is a new feature of firmware and the driver will fall back
> to MRPC normal mode if there is no support in the legacy firmware.
> 
> Include <linux/io-64-nonatomic-lo-hi.h> so that readq/writeq is replaced
> by two readl/writel on systems that do not support it.
> 
> Signed-off-by: Wesley Sheng <wesley.sheng@microchip.com>
> Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
> ---
>  drivers/pci/switch/switchtec.c | 108 +++++++++++++++++++++++++++++++++++++----
>  include/linux/switchtec.h      |  16 ++++++
>  2 files changed, 114 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
> index 0b8862b..6b726cb 100644
> --- a/drivers/pci/switch/switchtec.c
> +++ b/drivers/pci/switch/switchtec.c
> @@ -13,7 +13,7 @@
>  #include <linux/uaccess.h>
>  #include <linux/poll.h>
>  #include <linux/wait.h>
> -
> +#include <linux/io-64-nonatomic-lo-hi.h>
>  #include <linux/nospec.h>
>  
>  MODULE_DESCRIPTION("Microsemi Switchtec(tm) PCIe Management Driver");
> @@ -25,6 +25,11 @@ static int max_devices = 16;
>  module_param(max_devices, int, 0644);
>  MODULE_PARM_DESC(max_devices, "max number of switchtec device instances");
>  
> +static bool use_dma_mrpc = 1;
> +module_param(use_dma_mrpc, bool, 0644);
> +MODULE_PARM_DESC(use_dma_mrpc,
> +		 "Enable the use of the DMA MRPC feature");

What's the purpose of the module parameter?  Can't you automatically
figure out whether the firmware supports DMA mode?

Module parameters make life difficult for users and lead to code
that's rarely used and poorly tested, so I think we should avoid them
whenever we can.

If you *can't* automatically figure out when to use DMA, please make
it clear in the changelog that the "use_dma_mrpc" parameter is
required with legacy firmware.  And in that case, it seems like it
should be named "disable_dma" or similar, since it defaults to being
enabled.

Bjorn

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 3/5] switchtec: A temporary variable should be used for the flags of switchtec_ioctl_event_ctl
  2018-12-12 22:43   ` Bjorn Helgaas
@ 2018-12-12 22:52     ` Logan Gunthorpe
  0 siblings, 0 replies; 15+ messages in thread
From: Logan Gunthorpe @ 2018-12-12 22:52 UTC (permalink / raw)
  To: Bjorn Helgaas, Wesley Sheng
  Cc: kurt.schwemmer, linux-pci, linux-kernel, wesleyshenggit



On 2018-12-12 3:43 p.m., Bjorn Helgaas wrote:
> On Mon, Dec 10, 2018 at 05:12:22PM +0800, Wesley Sheng wrote:
>> From: Joey Zhang <joey.zhang@microchip.com>
>>
>> For nr_idxs is larger than 1 switchtec_ioctl_event_ctl event flags will be
>> used by each event indexes. In current implementation the event flags are
>> overwritten by first call of the function event_ctl().
>>
>> Preserve the event flag value with a temporary variable.
>>
>> Fixes: 52eabba5bcdb ("switchtec: Add IOCTLs to the Switchtec driver")
>> Signed-off-by: Joey Zhang <joey.zhang@microchip.com>
>> Signed-off-by: Wesley Sheng <wesley.sheng@microchip.com>
>> Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
>> ---
>>  drivers/pci/switch/switchtec.c | 3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
>> index 480107e..a908670 100644
>> --- a/drivers/pci/switch/switchtec.c
>> +++ b/drivers/pci/switch/switchtec.c
>> @@ -796,6 +796,7 @@ static int ioctl_event_ctl(struct switchtec_dev *stdev,
>>  {
>>  	int ret;
>>  	int nr_idxs;
>> +	unsigned int event_flags;
>>  	struct switchtec_ioctl_event_ctl ctl;
>>  
>>  	if (copy_from_user(&ctl, uctl, sizeof(ctl)))
>> @@ -817,7 +818,9 @@ static int ioctl_event_ctl(struct switchtec_dev *stdev,
>>  		else
>>  			return -EINVAL;
>>  
>> +		event_flags = ctl.flags;
>>  		for (ctl.index = 0; ctl.index < nr_idxs; ctl.index++) {
>> +			ctl.flags = event_flags;
>>  			ret = event_ctl(stdev, &ctl);
> 
> event_ctl() overwrites several other things, in addition to ctl.flags:
> 
>   ctl.data[]
>   ctl.occurred
>   ctl.count
> 
> Is that what you intend?  It looks like only the values from the *last*
> call of event_ctl() will be copied back to the user buffer.

Yeah, it's just SWITCHTEC_IOCTL_EVENT_IDX_ALL is perhaps a strange abuse
of the interface. The intention being that if you are querying
information about an event you'd use it's specific index. If you are
trying to set flags you can set them for all event of a specific type at
once using IDX_ALL.

Looking at it now it looks pretty ugly (and I'm not sure what I was
thinking when I wrote it). But it's what we have and this patch fixes a
bug where we aren't actually enabling/disabling all events when that's
what the user is asking for.

Logan

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 5/5] switchtec: MRPC DMA mode implementation
  2018-12-12 22:52   ` Bjorn Helgaas
@ 2018-12-12 22:58     ` Logan Gunthorpe
  2018-12-13 15:16       ` Bjorn Helgaas
  0 siblings, 1 reply; 15+ messages in thread
From: Logan Gunthorpe @ 2018-12-12 22:58 UTC (permalink / raw)
  To: Bjorn Helgaas, Wesley Sheng
  Cc: kurt.schwemmer, linux-pci, linux-kernel, wesleyshenggit



On 2018-12-12 3:52 p.m., Bjorn Helgaas wrote:
> On Mon, Dec 10, 2018 at 05:12:24PM +0800, Wesley Sheng wrote:
>> MRPC normal mode requires the host to read the MRPC command status and
>> output data from BAR. This results in high latency responses from the
>> Memory Read TLP and potential Completion Timeout (CTO).
>>
>> MRPC DMA mode implementation includes:
>> Macro definitions for registers and data structures corresponding to
>> MRPC DMA mode.
>>
>> Add module parameter use_dma_mrpc to select between MRPC DMA mode and
>> MRPC normal mode.
>>
>> Add MRPC mode functionality to:
>> * Retrieve MRPC DMA mode version
>> * Allocate DMA buffer, ISR registration, and enable DMA function during
>>   initialization
>> * Check MRPC execution status and collect execution results from DMA buffer
>> * Release DMA buffer and disable DMA function when unloading module
>>
>> MRPC DMA mode is a new feature of firmware and the driver will fall back
>> to MRPC normal mode if there is no support in the legacy firmware.
>>
>> Include <linux/io-64-nonatomic-lo-hi.h> so that readq/writeq is replaced
>> by two readl/writel on systems that do not support it.
>>
>> Signed-off-by: Wesley Sheng <wesley.sheng@microchip.com>
>> Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
>> ---
>>  drivers/pci/switch/switchtec.c | 108 +++++++++++++++++++++++++++++++++++++----
>>  include/linux/switchtec.h      |  16 ++++++
>>  2 files changed, 114 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
>> index 0b8862b..6b726cb 100644
>> --- a/drivers/pci/switch/switchtec.c
>> +++ b/drivers/pci/switch/switchtec.c
>> @@ -13,7 +13,7 @@
>>  #include <linux/uaccess.h>
>>  #include <linux/poll.h>
>>  #include <linux/wait.h>
>> -
>> +#include <linux/io-64-nonatomic-lo-hi.h>
>>  #include <linux/nospec.h>
>>  
>>  MODULE_DESCRIPTION("Microsemi Switchtec(tm) PCIe Management Driver");
>> @@ -25,6 +25,11 @@ static int max_devices = 16;
>>  module_param(max_devices, int, 0644);
>>  MODULE_PARM_DESC(max_devices, "max number of switchtec device instances");
>>  
>> +static bool use_dma_mrpc = 1;
>> +module_param(use_dma_mrpc, bool, 0644);
>> +MODULE_PARM_DESC(use_dma_mrpc,
>> +		 "Enable the use of the DMA MRPC feature");
> 
> What's the purpose of the module parameter?  Can't you automatically
> figure out whether the firmware supports DMA mode?
> 
> Module parameters make life difficult for users and lead to code
> that's rarely used and poorly tested, so I think we should avoid them
> whenever we can.
> 
> If you *can't* automatically figure out when to use DMA, please make
> it clear in the changelog that the "use_dma_mrpc" parameter is
> required with legacy firmware.  And in that case, it seems like it
> should be named "disable_dma" or similar, since it defaults to being
> enabled.

The code should already automatically determine whether the firmware
supports DMA or not. This parameter is just to aid debugging/testing so
we can run the module without DMA even if the firmware indicates it has
support.

It's not that critical so I'm sure we can remove it at this point if you
don't think that's a good enough justification.

Logan

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 5/5] switchtec: MRPC DMA mode implementation
  2018-12-12 22:58     ` Logan Gunthorpe
@ 2018-12-13 15:16       ` Bjorn Helgaas
  0 siblings, 0 replies; 15+ messages in thread
From: Bjorn Helgaas @ 2018-12-13 15:16 UTC (permalink / raw)
  To: Logan Gunthorpe
  Cc: Wesley Sheng, kurt.schwemmer, linux-pci, linux-kernel, wesleyshenggit

On Wed, Dec 12, 2018 at 03:58:22PM -0700, Logan Gunthorpe wrote:
> On 2018-12-12 3:52 p.m., Bjorn Helgaas wrote:
> > On Mon, Dec 10, 2018 at 05:12:24PM +0800, Wesley Sheng wrote:
> >> MRPC normal mode requires the host to read the MRPC command status and
> >> output data from BAR. This results in high latency responses from the
> >> Memory Read TLP and potential Completion Timeout (CTO).
> >>
> >> MRPC DMA mode implementation includes:
> >> Macro definitions for registers and data structures corresponding to
> >> MRPC DMA mode.
> >>
> >> Add module parameter use_dma_mrpc to select between MRPC DMA mode and
> >> MRPC normal mode.
> >>
> >> Add MRPC mode functionality to:
> >> * Retrieve MRPC DMA mode version
> >> * Allocate DMA buffer, ISR registration, and enable DMA function during
> >>   initialization
> >> * Check MRPC execution status and collect execution results from DMA buffer
> >> * Release DMA buffer and disable DMA function when unloading module
> >>
> >> MRPC DMA mode is a new feature of firmware and the driver will fall back
> >> to MRPC normal mode if there is no support in the legacy firmware.
> >>
> >> Include <linux/io-64-nonatomic-lo-hi.h> so that readq/writeq is replaced
> >> by two readl/writel on systems that do not support it.
> >>
> >> Signed-off-by: Wesley Sheng <wesley.sheng@microchip.com>
> >> Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
> >> ---
> >>  drivers/pci/switch/switchtec.c | 108 +++++++++++++++++++++++++++++++++++++----
> >>  include/linux/switchtec.h      |  16 ++++++
> >>  2 files changed, 114 insertions(+), 10 deletions(-)
> >>
> >> diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
> >> index 0b8862b..6b726cb 100644
> >> --- a/drivers/pci/switch/switchtec.c
> >> +++ b/drivers/pci/switch/switchtec.c
> >> @@ -13,7 +13,7 @@
> >>  #include <linux/uaccess.h>
> >>  #include <linux/poll.h>
> >>  #include <linux/wait.h>
> >> -
> >> +#include <linux/io-64-nonatomic-lo-hi.h>
> >>  #include <linux/nospec.h>
> >>  
> >>  MODULE_DESCRIPTION("Microsemi Switchtec(tm) PCIe Management Driver");
> >> @@ -25,6 +25,11 @@ static int max_devices = 16;
> >>  module_param(max_devices, int, 0644);
> >>  MODULE_PARM_DESC(max_devices, "max number of switchtec device instances");
> >>  
> >> +static bool use_dma_mrpc = 1;
> >> +module_param(use_dma_mrpc, bool, 0644);
> >> +MODULE_PARM_DESC(use_dma_mrpc,
> >> +		 "Enable the use of the DMA MRPC feature");
> > 
> > What's the purpose of the module parameter?  Can't you automatically
> > figure out whether the firmware supports DMA mode?
> > 
> > Module parameters make life difficult for users and lead to code
> > that's rarely used and poorly tested, so I think we should avoid them
> > whenever we can.
> > 
> > If you *can't* automatically figure out when to use DMA, please make
> > it clear in the changelog that the "use_dma_mrpc" parameter is
> > required with legacy firmware.  And in that case, it seems like it
> > should be named "disable_dma" or similar, since it defaults to being
> > enabled.
> 
> The code should already automatically determine whether the firmware
> supports DMA or not. This parameter is just to aid debugging/testing so
> we can run the module without DMA even if the firmware indicates it has
> support.
> 
> It's not that critical so I'm sure we can remove it at this point if you
> don't think that's a good enough justification.

You and Kurt are the maintainers of this, so it's up to you.  I
personally probably would not add a parameter that's only for
debugging, but at the end of the day I only want to double-check
that this is all as you intend.

I reworked the changelog as follows.


commit a5fa833d8008b9f8e211e2fbc7bc1f45f6457133
Author: Wesley Sheng <wesley.sheng@microchip.com>
Date:   Mon Dec 10 17:12:24 2018 +0800

    switchtec: Add MRPC DMA mode support
    
    MRPC normal mode requires the host to read the MRPC command status and
    output data from BAR.  This results in high latency responses from the
    Memory Read TLP and potential Completion Timeout (CTO).
    
    Add support for MRPC DMA mode, including related macro definitions and data
    structures and code to:
    
      * Retrieve MRPC DMA mode version from adapter firmware
      * Allocate DMA buffer, register ISR, and enable DMA during init
      * Check MRPC execution status and collect execution results from DMA buffer
      * Release DMA buffer and disable DMA function when unloading module
    
    MRPC DMA mode is a new feature of firmware, and the driver will fall back
    to MRPC normal mode if there is no support in the legacy firmware.
    
    Add a module parameter, "use_dma_mrpc", to select between MRPC DMA mode and
    MRPC normal mode.  Since the driver automatically detects DMA support in
    the firmware, this parameter is just for debugging and testing.
    
    Include <linux/io-64-nonatomic-lo-hi.h> so that readq/writeq is replaced by
    two readl/writel on systems that do not support it.
    
    Signed-off-by: Wesley Sheng <wesley.sheng@microchip.com>
    [bhelgaas: changelog]
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    Reviewed-by: Logan Gunthorpe <logang@deltatee.com>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 5/5] switchtec: MRPC DMA mode implementation
  2018-12-10  9:12 ` [PATCH 5/5] switchtec: MRPC DMA mode implementation Wesley Sheng
  2018-12-12 22:52   ` Bjorn Helgaas
@ 2018-12-13 15:17   ` Bjorn Helgaas
  2018-12-13 16:46     ` Logan Gunthorpe
  1 sibling, 1 reply; 15+ messages in thread
From: Bjorn Helgaas @ 2018-12-13 15:17 UTC (permalink / raw)
  To: Wesley Sheng
  Cc: kurt.schwemmer, logang, linux-pci, linux-kernel, wesleyshenggit

On Mon, Dec 10, 2018 at 05:12:24PM +0800, Wesley Sheng wrote:
> MRPC normal mode requires the host to read the MRPC command status and
> output data from BAR. This results in high latency responses from the
> Memory Read TLP and potential Completion Timeout (CTO).
> 
> MRPC DMA mode implementation includes:
> Macro definitions for registers and data structures corresponding to
> MRPC DMA mode.
> 
> Add module parameter use_dma_mrpc to select between MRPC DMA mode and
> MRPC normal mode.
> 
> Add MRPC mode functionality to:
> * Retrieve MRPC DMA mode version
> * Allocate DMA buffer, ISR registration, and enable DMA function during
>   initialization
> * Check MRPC execution status and collect execution results from DMA buffer
> * Release DMA buffer and disable DMA function when unloading module
> 
> MRPC DMA mode is a new feature of firmware and the driver will fall back
> to MRPC normal mode if there is no support in the legacy firmware.
> 
> Include <linux/io-64-nonatomic-lo-hi.h> so that readq/writeq is replaced
> by two readl/writel on systems that do not support it.
> 
> Signed-off-by: Wesley Sheng <wesley.sheng@microchip.com>
> Reviewed-by: Logan Gunthorpe <logang@deltatee.com>

>  static void init_pff(struct switchtec_dev *stdev)
> @@ -1294,6 +1367,19 @@ static int switchtec_init_pci(struct switchtec_dev *stdev,
>  
>  	pci_set_drvdata(pdev, stdev);
>  
> +	if (!use_dma_mrpc)
> +		return 0;
> +
> +	if (!(ioread32(&stdev->mmio_mrpc->dma_ver) ? true : false))
> +		return 0;

This is ... harder to decode than necessary.  It's obvious that the
intent is to return if the adapter firmware doesn't support DMA, but I
lost interest before I could verify that it works as intended.

Bjorn

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/5] Switchtec MRPC DMA mode support
  2018-12-10  9:12 [PATCH 0/5] Switchtec MRPC DMA mode support Wesley Sheng
                   ` (4 preceding siblings ...)
  2018-12-10  9:12 ` [PATCH 5/5] switchtec: MRPC DMA mode implementation Wesley Sheng
@ 2018-12-13 15:20 ` Bjorn Helgaas
  5 siblings, 0 replies; 15+ messages in thread
From: Bjorn Helgaas @ 2018-12-13 15:20 UTC (permalink / raw)
  To: Wesley Sheng
  Cc: kurt.schwemmer, logang, linux-pci, linux-kernel, wesleyshenggit

On Mon, Dec 10, 2018 at 05:12:19PM +0800, Wesley Sheng wrote:
> Hi, Everyone,
> 
> This patch series adds support for the Switchtec MRPC DMA mode.
> 
> Switchtec switches supports 2 MRPC interaction modes: MRPC normal mode and
> MRPC DMA mode, a new feature in the latest firmware versions. MRPC normal 
> mode requires the host to read the MRPC command status and output data. 
> In MRPC DMA mode the command status and output data are pushed directly to
> host memory and issues an interrupt upon completion. The advantage of MRPC
> DMA mode is avoiding potential high latency response from the Memory Read
> TLP. 
> 
> Additionally, we've made the following changes:
> 
> * Improve the efficiency of filling MRPC Input buffer by enabling write 
>   combining on MRPC region of BAR
> * Software workaround for delay responded Memory READ TLPs that access 
>   the BAR
> * And several bug fixes
> 
> Regards,
> Wesley
> 
> --
> 
> Changed since v1:
>   - It's a resend of v1
> 
> --
> 
> 
> Boris Glimcher (1):
>   switchtec: Set DMA coherent mask in Switchtec driver
> 
> Joey Zhang (1):
>   switchtec: A temporary variable should be used for the flags of
>     switchtec_ioctl_event_ctl
> 
> Kelvin Cao (2):
>   switchtec: Remove immediate status check after submit a MRPC command
>   switchtec: Improve MRPC efficiency by leveraging write combining
> 
> Wesley Sheng (1):
>   switchtec: MRPC DMA mode implementation
> 
>  drivers/pci/switch/switchtec.c | 154 ++++++++++++++++++++++++++++++++++++-----
>  include/linux/switchtec.h      |  16 +++++
>  2 files changed, 153 insertions(+), 17 deletions(-)

I applied all these on pci/switchtec for v4.21, thanks!

If you want to change anything, let me know.  I'm happy to replace or
update patches.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 5/5] switchtec: MRPC DMA mode implementation
  2018-12-13 15:17   ` Bjorn Helgaas
@ 2018-12-13 16:46     ` Logan Gunthorpe
  0 siblings, 0 replies; 15+ messages in thread
From: Logan Gunthorpe @ 2018-12-13 16:46 UTC (permalink / raw)
  To: Bjorn Helgaas, Wesley Sheng
  Cc: kurt.schwemmer, linux-pci, linux-kernel, wesleyshenggit



On 2018-12-13 8:17 a.m., Bjorn Helgaas wrote:
>>  static void init_pff(struct switchtec_dev *stdev)
>> @@ -1294,6 +1367,19 @@ static int switchtec_init_pci(struct switchtec_dev *stdev,
>>  
>>  	pci_set_drvdata(pdev, stdev);
>>  
>> +	if (!use_dma_mrpc)
>> +		return 0;
>> +
>> +	if (!(ioread32(&stdev->mmio_mrpc->dma_ver) ? true : false))
>> +		return 0;
> 
> This is ... harder to decode than necessary.  It's obvious that the
> intent is to return if the adapter firmware doesn't support DMA, but I
> lost interest before I could verify that it works as intended.

Oh, ick, yes. I must have missed that in my review.

@Wesley, that would definitely be something worth cleaning up. That
ternary operator doesn't make any sense.

Thanks, Bjorn, for the review and picking up the series.

Logan

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 2/5] switchtec: Set DMA coherent mask in Switchtec driver
  2018-11-15  9:43 Wesley Sheng
@ 2018-11-15  9:44 ` Wesley Sheng
  0 siblings, 0 replies; 15+ messages in thread
From: Wesley Sheng @ 2018-11-15  9:44 UTC (permalink / raw)
  To: kurt.schwemmer, logang, bhelgaas, linux-pci, linux-kernel
  Cc: wesleyshenggit, wesley.sheng

From: Boris Glimcher <Boris.Glimcher@emc.com>

Switchtec hardware supports 64-bit DMA, set the correct DMA mask.
This allows the CMA to allocate larger buffers for memory windows.

Signed-off-by: Boris Glimcher <Boris.Glimcher@emc.com>
Signed-off-by: Wesley Sheng <wesley.sheng@microchip.com>
---
 drivers/pci/switch/switchtec.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
index d2bca2d..480107e 100644
--- a/drivers/pci/switch/switchtec.c
+++ b/drivers/pci/switch/switchtec.c
@@ -1237,6 +1237,10 @@ static int switchtec_init_pci(struct switchtec_dev *stdev,
 	if (rc)
 		return rc;
 
+	rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
+	if (rc)
+		return rc;
+
 	pci_set_master(pdev);
 
 	stdev->mmio = pcim_iomap_table(pdev)[0];
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2018-12-13 16:46 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-10  9:12 [PATCH 0/5] Switchtec MRPC DMA mode support Wesley Sheng
2018-12-10  9:12 ` [PATCH 1/5] switchtec: Remove immediate status check after submit a MRPC command Wesley Sheng
2018-12-10  9:12 ` [PATCH 2/5] switchtec: Set DMA coherent mask in Switchtec driver Wesley Sheng
2018-12-10  9:12 ` [PATCH 3/5] switchtec: A temporary variable should be used for the flags of switchtec_ioctl_event_ctl Wesley Sheng
2018-12-12 22:43   ` Bjorn Helgaas
2018-12-12 22:52     ` Logan Gunthorpe
2018-12-10  9:12 ` [PATCH 4/5] switchtec: Improve MRPC efficiency by leveraging write combining Wesley Sheng
2018-12-10  9:12 ` [PATCH 5/5] switchtec: MRPC DMA mode implementation Wesley Sheng
2018-12-12 22:52   ` Bjorn Helgaas
2018-12-12 22:58     ` Logan Gunthorpe
2018-12-13 15:16       ` Bjorn Helgaas
2018-12-13 15:17   ` Bjorn Helgaas
2018-12-13 16:46     ` Logan Gunthorpe
2018-12-13 15:20 ` [PATCH 0/5] Switchtec MRPC DMA mode support Bjorn Helgaas
  -- strict thread matches above, loose matches on Subject: below --
2018-11-15  9:43 Wesley Sheng
2018-11-15  9:44 ` [PATCH 2/5] switchtec: Set DMA coherent mask in Switchtec driver Wesley Sheng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).