[PATCH 01/10] PCI: endpoint: Add MSI-X interfaces

2018-04-27 Thread Gustavo Pimentel
Add PCI_EPC_IRQ_MSIX type.

Add MSI-X callbacks signatures to ops structure.

Add sysfs interface for set/get MSI-X capability maximum number.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
 drivers/pci/endpoint/pci-ep-cfs.c   | 24 
 drivers/pci/endpoint/pci-epc-core.c | 57 +
 include/linux/pci-epc.h | 11 ++-
 include/linux/pci-epf.h |  1 +
 4 files changed, 92 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/endpoint/pci-ep-cfs.c 
b/drivers/pci/endpoint/pci-ep-cfs.c
index 018ea34..d1288a0 100644
--- a/drivers/pci/endpoint/pci-ep-cfs.c
+++ b/drivers/pci/endpoint/pci-ep-cfs.c
@@ -286,6 +286,28 @@ static ssize_t pci_epf_msi_interrupts_show(struct 
config_item *item,
   to_pci_epf_group(item)->epf->msi_interrupts);
 }
 
+static ssize_t pci_epf_msix_interrupts_store(struct config_item *item,
+const char *page, size_t len)
+{
+   u16 val;
+   int ret;
+
+   ret = kstrtou16(page, 0, );
+   if (ret)
+   return ret;
+
+   to_pci_epf_group(item)->epf->msix_interrupts = val;
+
+   return len;
+}
+
+static ssize_t pci_epf_msix_interrupts_show(struct config_item *item,
+   char *page)
+{
+   return sprintf(page, "%d\n",
+  to_pci_epf_group(item)->epf->msix_interrupts);
+}
+
 PCI_EPF_HEADER_R(vendorid)
 PCI_EPF_HEADER_W_u16(vendorid)
 
@@ -327,6 +349,7 @@ CONFIGFS_ATTR(pci_epf_, subsys_vendor_id);
 CONFIGFS_ATTR(pci_epf_, subsys_id);
 CONFIGFS_ATTR(pci_epf_, interrupt_pin);
 CONFIGFS_ATTR(pci_epf_, msi_interrupts);
+CONFIGFS_ATTR(pci_epf_, msix_interrupts);
 
 static struct configfs_attribute *pci_epf_attrs[] = {
_epf_attr_vendorid,
@@ -340,6 +363,7 @@ static struct configfs_attribute *pci_epf_attrs[] = {
_epf_attr_subsys_id,
_epf_attr_interrupt_pin,
_epf_attr_msi_interrupts,
+   _epf_attr_msix_interrupts,
NULL,
 };
 
diff --git a/drivers/pci/endpoint/pci-epc-core.c 
b/drivers/pci/endpoint/pci-epc-core.c
index b0ee427..7d77bd0 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -218,6 +218,63 @@ int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 
interrupts)
 EXPORT_SYMBOL_GPL(pci_epc_set_msi);
 
 /**
+ * pci_epc_get_msix() - get the number of MSI-X interrupt numbers allocated
+ * @epc: the EPC device to which MSI-X interrupts was requested
+ * @func_no: the endpoint function number in the EPC device
+ *
+ * Invoke to get the number of MSI-X interrupts allocated by the RC
+ */
+int pci_epc_get_msix(struct pci_epc *epc, u8 func_no)
+{
+   int interrupt;
+   unsigned long flags;
+
+   if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
+   return 0;
+
+   if (!epc->ops->get_msix)
+   return 0;
+
+   spin_lock_irqsave(>lock, flags);
+   interrupt = epc->ops->get_msix(epc, func_no);
+   spin_unlock_irqrestore(>lock, flags);
+
+   if (interrupt < 0)
+   return 0;
+
+   return interrupt + 1;
+}
+EXPORT_SYMBOL_GPL(pci_epc_get_msix);
+
+/**
+ * pci_epc_set_msix() - set the number of MSI-X interrupt numbers required
+ * @epc: the EPC device on which MSI-X has to be configured
+ * @func_no: the endpoint function number in the EPC device
+ * @interrupts: number of MSI-X interrupts required by the EPF
+ *
+ * Invoke to set the required number of MSI-X interrupts.
+ */
+int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts)
+{
+   int ret;
+   unsigned long flags;
+
+   if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions ||
+   interrupts < 1 || interrupts > 2048)
+   return -EINVAL;
+
+   if (!epc->ops->set_msix)
+   return 0;
+
+   spin_lock_irqsave(>lock, flags);
+   ret = epc->ops->set_msix(epc, func_no, interrupts - 1);
+   spin_unlock_irqrestore(>lock, flags);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(pci_epc_set_msix);
+
+/**
  * pci_epc_unmap_addr() - unmap CPU address from PCI address
  * @epc: the EPC device on which address is allocated
  * @func_no: the endpoint function number in the EPC device
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index af657ca..32e8961 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -17,6 +17,7 @@ enum pci_epc_irq_type {
PCI_EPC_IRQ_UNKNOWN,
PCI_EPC_IRQ_LEGACY,
PCI_EPC_IRQ_MSI,
+   PCI_EPC_IRQ_MSIX,
 };
 
 /**
@@ -30,6 +31,10 @@ enum pci_epc_irq_type {
  *  capability register
  * @get_msi: ops to get the number of MSI interrupts allocated by the RC from
  *  the MSI capability register
+ * @set_msix: ops to set the requested number of MSI-X interrupts in the
+ *  MSI-X capability register
+ *

[PATCH 09/10] tools: PCI: Add MSI-X support

2018-04-27 Thread Gustavo Pimentel
Add MSI-X support to pcitest tool.

Modify pcitest.sh script to accomodate MSI-X interrupt tests.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
 include/uapi/linux/pcitest.h |  1 +
 tools/pci/pcitest.c  | 18 +-
 tools/pci/pcitest.sh | 25 +
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/pcitest.h b/include/uapi/linux/pcitest.h
index 953cf03..d746fb1 100644
--- a/include/uapi/linux/pcitest.h
+++ b/include/uapi/linux/pcitest.h
@@ -16,5 +16,6 @@
 #define PCITEST_WRITE  _IOW('P', 0x4, unsigned long)
 #define PCITEST_READ   _IOW('P', 0x5, unsigned long)
 #define PCITEST_COPY   _IOW('P', 0x6, unsigned long)
+#define PCITEST_MSIX   _IOW('P', 0x7, int)
 
 #endif /* __UAPI_LINUX_PCITEST_H */
diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c
index 9074b47..9d145a3 100644
--- a/tools/pci/pcitest.c
+++ b/tools/pci/pcitest.c
@@ -37,6 +37,7 @@ struct pci_test {
charbarnum;
boollegacyirq;
unsigned intmsinum;
+   unsigned intmsixnum;
boolread;
boolwrite;
boolcopy;
@@ -83,6 +84,15 @@ static int run_test(struct pci_test *test)
fprintf(stdout, "%s\n", result[ret]);
}
 
+   if (test->msixnum > 0 && test->msixnum <= 2048) {
+   ret = ioctl(fd, PCITEST_MSIX, test->msixnum);
+   fprintf(stdout, "MSI-X%d:\t\t", test->msixnum);
+   if (ret < 0)
+   fprintf(stdout, "TEST FAILED\n");
+   else
+   fprintf(stdout, "%s\n", result[ret]);
+   }
+
if (test->write) {
ret = ioctl(fd, PCITEST_WRITE, test->size);
fprintf(stdout, "WRITE (%7ld bytes):\t\t", test->size);
@@ -133,7 +143,7 @@ int main(int argc, char **argv)
/* set default endpoint device */
test->device = "/dev/pci-endpoint-test.0";
 
-   while ((c = getopt(argc, argv, "D:b:m:lrwcs:")) != EOF)
+   while ((c = getopt(argc, argv, "D:b:m:x:lrwcs:")) != EOF)
switch (c) {
case 'D':
test->device = optarg;
@@ -151,6 +161,11 @@ int main(int argc, char **argv)
if (test->msinum < 1 || test->msinum > 32)
goto usage;
continue;
+   case 'x':
+   test->msixnum = atoi(optarg);
+   if (test->msixnum < 1 || test->msixnum > 2048)
+   goto usage;
+   continue;
case 'r':
test->read = true;
continue;
@@ -173,6 +188,7 @@ int main(int argc, char **argv)
"\t-D  PCI endpoint test device 
{default: /dev/pci-endpoint-test.0}\n"
"\t-b  BAR test (bar number between 
0..5)\n"
"\t-m  MSI test (msi number between 
1..32)\n"
+   "\t-x MSI-X test (msix number between 
1..2048)\n"
"\t-l   Legacy IRQ test\n"
"\t-r   Read buffer test\n"
"\t-w   Write buffer test\n"
diff --git a/tools/pci/pcitest.sh b/tools/pci/pcitest.sh
index 77e8c85..86709a2 100644
--- a/tools/pci/pcitest.sh
+++ b/tools/pci/pcitest.sh
@@ -4,6 +4,8 @@
 echo "BAR tests"
 echo
 
+modprobe pci_endpoint_test
+sleep 2
 bar=0
 
 while [ $bar -lt 6 ]
@@ -16,7 +18,14 @@ echo
 echo "Interrupt tests"
 echo
 
+rmmod pci_endpoint_test
+sleep 2
+modprobe pci_endpoint_test irq_type=0
 pcitest -l
+
+rmmod pci_endpoint_test
+sleep 2
+modprobe pci_endpoint_test irq_type=1
 msi=1
 
 while [ $msi -lt 33 ]
@@ -26,9 +35,25 @@ do
 done
 echo
 
+rmmod pci_endpoint_test
+sleep 2
+modprobe pci_endpoint_test irq_type=2
+msix=1
+
+while [ $msix -lt 2049 ]
+do
+pcitest -x $msix
+msix=`expr $msix + 1`
+done
+echo
+
 echo "Read Tests"
 echo
 
+rmmod pci_endpoint_test
+sleep 2
+modprobe pci_endpoint_test irq_type=1
+
 pcitest -r -s 1
 pcitest -r -s 1024
 pcitest -r -s 1025
-- 
2.7.4


--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 02/10] PCI: dwc: Add MSI-X callbacks handler

2018-04-27 Thread Gustavo Pimentel
Change pcie_raise_irq() signature, namely the interrupt_num variable type
from u8 to u16 to accommodate the 2048 maximum MSI-X interrupts.

Add PCIe config space capability search function.

Add sysfs set/get interface to allow to change of EP MSI-X maximum number.

Add EP MSI-X callback for triggering interruptions.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
 drivers/pci/dwc/pci-dra7xx.c   |   2 +-
 drivers/pci/dwc/pcie-artpec6.c |   2 +-
 drivers/pci/dwc/pcie-designware-ep.c   | 143 -
 drivers/pci/dwc/pcie-designware-plat.c |   4 +-
 drivers/pci/dwc/pcie-designware.h  |  14 +++-
 5 files changed, 160 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
index ed8558d..5265725 100644
--- a/drivers/pci/dwc/pci-dra7xx.c
+++ b/drivers/pci/dwc/pci-dra7xx.c
@@ -369,7 +369,7 @@ static void dra7xx_pcie_raise_msi_irq(struct dra7xx_pcie 
*dra7xx,
 }
 
 static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
-enum pci_epc_irq_type type, u8 interrupt_num)
+enum pci_epc_irq_type type, u16 interrupt_num)
 {
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
diff --git a/drivers/pci/dwc/pcie-artpec6.c b/drivers/pci/dwc/pcie-artpec6.c
index e66cede..96dc259 100644
--- a/drivers/pci/dwc/pcie-artpec6.c
+++ b/drivers/pci/dwc/pcie-artpec6.c
@@ -428,7 +428,7 @@ static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep)
 }
 
 static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
- enum pci_epc_irq_type type, u8 interrupt_num)
+ enum pci_epc_irq_type type, u16 interrupt_num)
 {
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 
diff --git a/drivers/pci/dwc/pcie-designware-ep.c 
b/drivers/pci/dwc/pcie-designware-ep.c
index 15b22a6..9b0d396 100644
--- a/drivers/pci/dwc/pcie-designware-ep.c
+++ b/drivers/pci/dwc/pcie-designware-ep.c
@@ -40,6 +40,39 @@ void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum 
pci_barno bar)
__dw_pcie_ep_reset_bar(pci, bar, 0);
 }
 
+u8 __dw_pcie_ep_find_next_cap(struct dw_pcie *pci, u8 cap_ptr,
+ u8 cap)
+{
+   u8 cap_id, next_cap_ptr;
+   u16 reg;
+
+   reg = dw_pcie_readw_dbi(pci, cap_ptr);
+   next_cap_ptr = (reg & 0xff00) >> 8;
+   cap_id = (reg & 0x00ff);
+
+   if (!next_cap_ptr || cap_id > PCI_CAP_ID_MAX)
+   return 0;
+
+   if (cap_id == cap)
+   return cap_ptr;
+
+   return __dw_pcie_ep_find_next_cap(pci, next_cap_ptr, cap);
+}
+
+u8 dw_pcie_ep_find_capability(struct dw_pcie *pci, u8 cap)
+{
+   u8 next_cap_ptr;
+   u16 reg;
+
+   reg = dw_pcie_readw_dbi(pci, PCI_CAPABILITY_LIST);
+   next_cap_ptr = (reg & 0x00ff);
+
+   if (!next_cap_ptr)
+   return 0;
+
+   return __dw_pcie_ep_find_next_cap(pci, next_cap_ptr, cap);
+}
+
 static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no,
   struct pci_epf_header *hdr)
 {
@@ -241,8 +274,47 @@ static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 
func_no, u8 encode_int)
return 0;
 }
 
+static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
+{
+   struct dw_pcie_ep *ep = epc_get_drvdata(epc);
+   struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+   u32 val, reg;
+
+   if (!ep->msix_cap)
+   return 0;
+
+   reg = ep->msix_cap + PCI_MSIX_FLAGS;
+   val = dw_pcie_readw_dbi(pci, reg);
+   if (!(val & PCI_MSIX_FLAGS_ENABLE))
+   return -EINVAL;
+
+   val &= PCI_MSIX_FLAGS_QSIZE;
+
+   return val;
+}
+
+static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts)
+{
+   struct dw_pcie_ep *ep = epc_get_drvdata(epc);
+   struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+   u32 val, reg;
+
+   if (!ep->msix_cap)
+   return 0;
+
+   reg = ep->msix_cap + PCI_MSIX_FLAGS;
+   val = dw_pcie_readw_dbi(pci, reg);
+   val &= ~PCI_MSIX_FLAGS_QSIZE;
+   val |= interrupts;
+   dw_pcie_dbi_ro_wr_en(pci);
+   dw_pcie_writew_dbi(pci, reg, val);
+   dw_pcie_dbi_ro_wr_dis(pci);
+
+   return 0;
+}
+
 static int dw_pcie_ep_raise_irq(struct pci_epc *epc, u8 func_no,
-   enum pci_epc_irq_type type, u8 interrupt_num)
+   enum pci_epc_irq_type type, u16 interrupt_num)
 {
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 
@@ -282,6 +354,8 @@ static const struct pci_epc_ops epc_ops = {
.unmap_addr = dw_pcie_ep_unmap_addr,
.set_msi= dw_pcie_ep_set_msi,
.get_msi= dw_pcie_ep_get_msi,
+   .set_msix   = dw_pcie_ep_set_msix,
+ 

[PATCH 03/10] PCI: cadence: Update cdns_pcie_ep_raise_irq function signature

2018-04-27 Thread Gustavo Pimentel
Change cdns_pcie_ep_raise_irq() signature, namely the interrupt_num variable 
type
from u8 to u16 to accommodate the 2048 maximum MSI-X interrupts.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
Acked-by: Alan Douglas <adoug...@cadence.com>
---
 drivers/pci/cadence/pcie-cadence-ep.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pci/cadence/pcie-cadence-ep.c 
b/drivers/pci/cadence/pcie-cadence-ep.c
index 3d8283e..6d6322c 100644
--- a/drivers/pci/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/cadence/pcie-cadence-ep.c
@@ -363,7 +363,7 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep 
*ep, u8 fn,
 }
 
 static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
- enum pci_epc_irq_type type, u8 interrupt_num)
+ enum pci_epc_irq_type type, u16 interrupt_num)
 {
struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 
-- 
2.7.4


--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 06/10] misc: pci_endpoint_test: Add MSI-X support

2018-04-27 Thread Gustavo Pimentel
Add MSI-X support and update driver documentation accordingly.

Add new driver parameter to allow interruption type selection.

Modify the Legacy/MSI/MSI-X test process, by:
 - Add and use a specific register located in a BAR, which defines
the interrupt type is been triggered.
 - Move the interrupt ID number from the command section to a
register located in a BAR.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
 Documentation/misc-devices/pci-endpoint-test.txt |   3 +
 drivers/misc/pci_endpoint_test.c | 121 +++
 drivers/pci/endpoint/functions/pci-epf-test.c|  78 +++
 3 files changed, 143 insertions(+), 59 deletions(-)

diff --git a/Documentation/misc-devices/pci-endpoint-test.txt 
b/Documentation/misc-devices/pci-endpoint-test.txt
index 4ebc359..fdfa0f6 100644
--- a/Documentation/misc-devices/pci-endpoint-test.txt
+++ b/Documentation/misc-devices/pci-endpoint-test.txt
@@ -10,6 +10,7 @@ The PCI driver for the test device performs the following 
tests
*) verifying addresses programmed in BAR
*) raise legacy IRQ
*) raise MSI IRQ
+   *) raise MSI-X IRQ
*) read data
*) write data
*) copy data
@@ -25,6 +26,8 @@ ioctl
  PCITEST_LEGACY_IRQ: Tests legacy IRQ
  PCITEST_MSI: Tests message signalled interrupts. The MSI number
  to be tested should be passed as argument.
+ PCITEST_MSIX: Tests message signalled interrupts. The MSI-X number
+ to be tested should be passed as argument.
  PCITEST_WRITE: Perform write tests. The size of the buffer should be passed
as argument.
  PCITEST_READ: Perform read tests. The size of the buffer should be passed
diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index 58a88ba..b003079 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -35,38 +35,44 @@
 
 #include 
 
-#define DRV_MODULE_NAME"pci-endpoint-test"
-
-#define PCI_ENDPOINT_TEST_MAGIC0x0
-
-#define PCI_ENDPOINT_TEST_COMMAND  0x4
-#define COMMAND_RAISE_LEGACY_IRQ   BIT(0)
-#define COMMAND_RAISE_MSI_IRQ  BIT(1)
-#define MSI_NUMBER_SHIFT   2
-/* 6 bits for MSI number */
-#define COMMAND_READBIT(8)
-#define COMMAND_WRITE   BIT(9)
-#define COMMAND_COPYBIT(10)
-
-#define PCI_ENDPOINT_TEST_STATUS   0x8
-#define STATUS_READ_SUCCESS BIT(0)
-#define STATUS_READ_FAILBIT(1)
-#define STATUS_WRITE_SUCCESSBIT(2)
-#define STATUS_WRITE_FAIL   BIT(3)
-#define STATUS_COPY_SUCCESS BIT(4)
-#define STATUS_COPY_FAILBIT(5)
-#define STATUS_IRQ_RAISED   BIT(6)
-#define STATUS_SRC_ADDR_INVALID BIT(7)
-#define STATUS_DST_ADDR_INVALID BIT(8)
-
-#define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR   0xc
+#define DRV_MODULE_NAME"pci-endpoint-test"
+
+#define IRQ_TYPE_LEGACY0
+#define IRQ_TYPE_MSI   1
+#define IRQ_TYPE_MSIX  2
+
+#define PCI_ENDPOINT_TEST_MAGIC0x0
+
+#define PCI_ENDPOINT_TEST_COMMAND  0x4
+#define COMMAND_RAISE_LEGACY_IRQ   BIT(0)
+#define COMMAND_RAISE_MSI_IRQ  BIT(1)
+#define COMMAND_RAISE_MSIX_IRQ BIT(2)
+#define COMMAND_READ   BIT(3)
+#define COMMAND_WRITE  BIT(4)
+#define COMMAND_COPY   BIT(5)
+
+#define PCI_ENDPOINT_TEST_STATUS   0x8
+#define STATUS_READ_SUCCESSBIT(0)
+#define STATUS_READ_FAIL   BIT(1)
+#define STATUS_WRITE_SUCCESS   BIT(2)
+#define STATUS_WRITE_FAIL  BIT(3)
+#define STATUS_COPY_SUCCESSBIT(4)
+#define STATUS_COPY_FAIL   BIT(5)
+#define STATUS_IRQ_RAISED  BIT(6)
+#define STATUS_SRC_ADDR_INVALIDBIT(7)
+#define STATUS_DST_ADDR_INVALIDBIT(8)
+
+#define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR   0x0c
 #define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR   0x10
 
 #define PCI_ENDPOINT_TEST_LOWER_DST_ADDR   0x14
 #define PCI_ENDPOINT_TEST_UPPER_DST_ADDR   0x18
 
-#define PCI_ENDPOINT_TEST_SIZE 0x1c
-#define PCI_ENDPOINT_TEST_CHECKSUM 0x20
+#define PCI_ENDPOINT_TEST_SIZE 0x1c
+#define PCI_ENDPOINT_TEST_CHECKSUM 0x20
+
+#define PCI_ENDPOINT_TEST_IRQ_TYPE 0x24
+#define PCI_ENDPOINT_TEST_IRQ_NUMBER   0x28
 
 static DEFINE_IDA(pci_endpoint_test_ida);
 
@@ -77,6 +83,10 @@ static bool no_msi;
 module_param(no_msi, bool, 0444);
 MODULE_PARM_DESC(no_msi, "Disable MSI interrupt in pci_endpoint_test");
 
+static int irq_type = IRQ_TYPE_MS

[PATCH 04/10] PCI: dwc: Rework MSI callbacks handler

2018-04-27 Thread Gustavo Pimentel
Remove duplicate defines located on pcie-designware.h file already
available on /include/uapi/linux/pci-regs.h file.

Add pci_epc_set_msi() maximum 32 interrupts validation.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
 drivers/pci/dwc/pcie-designware-ep.c | 49 
 drivers/pci/dwc/pcie-designware.h| 11 
 drivers/pci/endpoint/pci-epc-core.c  |  3 ++-
 3 files changed, 35 insertions(+), 28 deletions(-)

diff --git a/drivers/pci/dwc/pcie-designware-ep.c 
b/drivers/pci/dwc/pcie-designware-ep.c
index 9b0d396..1ba3a7f 100644
--- a/drivers/pci/dwc/pcie-designware-ep.c
+++ b/drivers/pci/dwc/pcie-designware-ep.c
@@ -246,29 +246,38 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 
func_no,
 
 static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no)
 {
-   int val;
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+   u32 val, reg;
+
+   if (!ep->msi_cap)
+   return 0;
 
-   val = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
-   if (!(val & MSI_CAP_MSI_EN_MASK))
+   reg = ep->msi_cap + PCI_MSI_FLAGS;
+   val = dw_pcie_readw_dbi(pci, reg);
+   if (!(val & PCI_MSI_FLAGS_ENABLE))
return -EINVAL;
 
-   val = (val & MSI_CAP_MME_MASK) >> MSI_CAP_MME_SHIFT;
+   val = (val & PCI_MSI_FLAGS_QSIZE) >> 4;
+
return val;
 }
 
-static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 encode_int)
+static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
 {
-   int val;
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+   u32 val, reg;
 
-   val = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
-   val &= ~MSI_CAP_MMC_MASK;
-   val |= (encode_int << MSI_CAP_MMC_SHIFT) & MSI_CAP_MMC_MASK;
+   if (!ep->msi_cap)
+   return 0;
+
+   reg = ep->msi_cap + PCI_MSI_FLAGS;
+   val = dw_pcie_readw_dbi(pci, reg);
+   val &= ~PCI_MSI_FLAGS_QMASK;
+   val |= (interrupts << 1) & PCI_MSI_FLAGS_QMASK;
dw_pcie_dbi_ro_wr_en(pci);
-   dw_pcie_writew_dbi(pci, MSI_MESSAGE_CONTROL, val);
+   dw_pcie_writew_dbi(pci, reg, val);
dw_pcie_dbi_ro_wr_dis(pci);
 
return 0;
@@ -367,21 +376,29 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 
func_no,
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
struct pci_epc *epc = ep->epc;
u16 msg_ctrl, msg_data;
-   u32 msg_addr_lower, msg_addr_upper;
+   u32 msg_addr_lower, msg_addr_upper, reg;
u64 msg_addr;
bool has_upper;
int ret;
 
+   if (!ep->msi_cap)
+   return 0;
+
/* Raise MSI per the PCI Local Bus Specification Revision 3.0, 6.8.1. */
-   msg_ctrl = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
+   reg = ep->msi_cap + PCI_MSI_FLAGS;
+   msg_ctrl = dw_pcie_readw_dbi(pci, reg);
has_upper = !!(msg_ctrl & PCI_MSI_FLAGS_64BIT);
-   msg_addr_lower = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_L32);
+   reg = ep->msi_cap + PCI_MSI_ADDRESS_LO;
+   msg_addr_lower = dw_pcie_readl_dbi(pci, reg);
if (has_upper) {
-   msg_addr_upper = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_U32);
-   msg_data = dw_pcie_readw_dbi(pci, MSI_MESSAGE_DATA_64);
+   reg = ep->msi_cap + PCI_MSI_ADDRESS_HI;
+   msg_addr_upper = dw_pcie_readl_dbi(pci, reg);
+   reg = ep->msi_cap + PCI_MSI_DATA_64;
+   msg_data = dw_pcie_readw_dbi(pci, reg);
} else {
msg_addr_upper = 0;
-   msg_data = dw_pcie_readw_dbi(pci, MSI_MESSAGE_DATA_32);
+   reg = ep->msi_cap + PCI_MSI_DATA_32;
+   msg_data = dw_pcie_readw_dbi(pci, reg);
}
msg_addr = ((u64) msg_addr_upper) << 32 | msg_addr_lower;
ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr,
diff --git a/drivers/pci/dwc/pcie-designware.h 
b/drivers/pci/dwc/pcie-designware.h
index b22c5bb..a0ab12f 100644
--- a/drivers/pci/dwc/pcie-designware.h
+++ b/drivers/pci/dwc/pcie-designware.h
@@ -96,17 +96,6 @@
 #define PCIE_GET_ATU_INB_UNR_REG_OFFSET(region)
\
((0x3 << 20) | ((region) << 9) | (0x1 << 8))
 
-#define MSI_MESSAGE_CONTROL0x52
-#define MSI_CAP_MMC_SHIFT  1
-#define MSI_CAP_MMC_MASK   (7 << MSI_CAP_MMC_SHIFT)
-#define MSI_CAP_MME_SHIFT  4
-#define MSI_CAP_MSI_EN_MASK0x1
-#define MSI_CAP_MME_MASK   (7 << MSI_CAP_MME_SHIFT)
-#define MSI_MESSAGE_ADDR_L32   0x54
-#define MSI_MESSAGE_ADDR_U32   0x58
-#define MSI_MESSAGE_DATA_320x58
-#define MSI_MESSA

[PATCH 10/10] misc: pci_endpoint_test: Use pci_irq_vector function

2018-04-27 Thread Gustavo Pimentel
Replace "pdev->irq + index" operation by the pci_irq_vector() call,
that converts from device vector to Linux IRQ.
(suggestion made by Alan Douglas).

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
 drivers/misc/pci_endpoint_test.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index c9b6e26..cbdd0c6 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -220,7 +220,7 @@ static bool pci_endpoint_test_msi_irq(struct 
pci_endpoint_test *test,
if (!val)
return false;
 
-   if (test->last_irq - pdev->irq == msi_num - 1)
+   if (pci_irq_vector(pdev, irq_num - 1) == test->last_irq)
return true;
 
return false;
@@ -565,12 +565,12 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
}
 
for (i = 1; i < irq; i++) {
-   err = devm_request_irq(dev, pdev->irq + i,
+   err = devm_request_irq(dev, pci_irq_vector(pdev, i),
   pci_endpoint_test_irqhandler,
   IRQF_SHARED, DRV_MODULE_NAME, test);
if (err)
dev_err(dev, "Failed to request IRQ %d for MSI%s %d\n",
-   pdev->irq + i,
+   pci_irq_vector(pdev, i),
irq_type == IRQ_TYPE_MSIX ? "-X" : "", i + 1);
}
 
@@ -633,7 +633,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
}
 
for (i = 0; i < irq; i++)
-   devm_free_irq(dev, pdev->irq + i, test);
+   devm_free_irq(>dev, pci_irq_vector(pdev, i), test);
 
 err_disable_msi:
pci_disable_msi(pdev);
@@ -667,7 +667,7 @@ static void pci_endpoint_test_remove(struct pci_dev *pdev)
pci_iounmap(pdev, test->bar[bar]);
}
for (i = 0; i < test->num_irqs; i++)
-   devm_free_irq(>dev, pdev->irq + i, test);
+   devm_free_irq(>dev, pci_irq_vector(pdev, i), test);
pci_disable_msi(pdev);
pci_disable_msix(pdev);
pci_release_regions(pdev);
-- 
2.7.4


--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 07/10] misc: pci_endpoint_test: Replace lower into upper case characters

2018-04-27 Thread Gustavo Pimentel
Replace all initial lower case character into upper case in comments
and debug printks.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
 drivers/misc/pci_endpoint_test.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index b003079..c9b6e26 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -250,7 +250,7 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test 
*test, size_t size)
orig_src_addr = dma_alloc_coherent(dev, size + alignment,
   _src_phys_addr, GFP_KERNEL);
if (!orig_src_addr) {
-   dev_err(dev, "failed to allocate source buffer\n");
+   dev_err(dev, "Failed to allocate source buffer\n");
ret = false;
goto err;
}
@@ -276,7 +276,7 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test 
*test, size_t size)
orig_dst_addr = dma_alloc_coherent(dev, size + alignment,
   _dst_phys_addr, GFP_KERNEL);
if (!orig_dst_addr) {
-   dev_err(dev, "failed to allocate destination address\n");
+   dev_err(dev, "Failed to allocate destination address\n");
ret = false;
goto err_orig_src_addr;
}
@@ -340,7 +340,7 @@ static bool pci_endpoint_test_write(struct 
pci_endpoint_test *test, size_t size)
orig_addr = dma_alloc_coherent(dev, size + alignment, _phys_addr,
   GFP_KERNEL);
if (!orig_addr) {
-   dev_err(dev, "failed to allocate address\n");
+   dev_err(dev, "Failed to allocate address\n");
ret = false;
goto err;
}
@@ -403,7 +403,7 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test 
*test, size_t size)
orig_addr = dma_alloc_coherent(dev, size + alignment, _phys_addr,
   GFP_KERNEL);
if (!orig_addr) {
-   dev_err(dev, "failed to allocate destination address\n");
+   dev_err(dev, "Failed to allocate destination address\n");
ret = false;
goto err;
}
@@ -543,7 +543,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
case IRQ_TYPE_MSI:
irq = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI);
if (irq < 0)
-   dev_err(dev, "failed to get MSI interrupts\n");
+   dev_err(dev, "Failed to get MSI interrupts\n");
test->num_irqs = irq;
break;
case IRQ_TYPE_MSIX:
@@ -560,7 +560,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
err = devm_request_irq(dev, pdev->irq, pci_endpoint_test_irqhandler,
   IRQF_SHARED, DRV_MODULE_NAME, test);
if (err) {
-   dev_err(dev, "failed to request IRQ %d\n", pdev->irq);
+   dev_err(dev, "Failed to request IRQ %d\n", pdev->irq);
goto err_disable_msi;
}
 
@@ -578,7 +578,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
base = pci_ioremap_bar(pdev, bar);
if (!base) {
-   dev_err(dev, "failed to read BAR%d\n", bar);
+   dev_err(dev, "Failed to read BAR%d\n", bar);
WARN_ON(bar == test_reg_bar);
}
test->bar[bar] = base;
@@ -598,7 +598,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
id = ida_simple_get(_endpoint_test_ida, 0, 0, GFP_KERNEL);
if (id < 0) {
err = id;
-   dev_err(dev, "unable to get id\n");
+   dev_err(dev, "Unable to get id\n");
goto err_iounmap;
}
 
@@ -614,7 +614,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
 
err = misc_register(misc_device);
if (err) {
-   dev_err(dev, "failed to register device\n");
+   dev_err(dev, "Failed to register device\n");
goto err_kfree_name;
}
 
-- 
2.7.4


--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 08/10] PCI: endpoint: functions/pci-epf-test: Replace lower into upper case characters

2018-04-27 Thread Gustavo Pimentel
Replace all initial lower case character into upper case in comments
and debug printks.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
 drivers/pci/endpoint/functions/pci-epf-test.c | 26 +-
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c 
b/drivers/pci/endpoint/functions/pci-epf-test.c
index be5547f..e9ff4aa 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -92,7 +92,7 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
 
src_addr = pci_epc_mem_alloc_addr(epc, _phys_addr, reg->size);
if (!src_addr) {
-   dev_err(dev, "failed to allocate source address\n");
+   dev_err(dev, "Failed to allocate source address\n");
reg->status = STATUS_SRC_ADDR_INVALID;
ret = -ENOMEM;
goto err;
@@ -101,14 +101,14 @@ static int pci_epf_test_copy(struct pci_epf_test 
*epf_test)
ret = pci_epc_map_addr(epc, epf->func_no, src_phys_addr, reg->src_addr,
   reg->size);
if (ret) {
-   dev_err(dev, "failed to map source address\n");
+   dev_err(dev, "Failed to map source address\n");
reg->status = STATUS_SRC_ADDR_INVALID;
goto err_src_addr;
}
 
dst_addr = pci_epc_mem_alloc_addr(epc, _phys_addr, reg->size);
if (!dst_addr) {
-   dev_err(dev, "failed to allocate destination address\n");
+   dev_err(dev, "Failed to allocate destination address\n");
reg->status = STATUS_DST_ADDR_INVALID;
ret = -ENOMEM;
goto err_src_map_addr;
@@ -117,7 +117,7 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
ret = pci_epc_map_addr(epc, epf->func_no, dst_phys_addr, reg->dst_addr,
   reg->size);
if (ret) {
-   dev_err(dev, "failed to map destination address\n");
+   dev_err(dev, "Failed to map destination address\n");
reg->status = STATUS_DST_ADDR_INVALID;
goto err_dst_addr;
}
@@ -154,7 +154,7 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test)
 
src_addr = pci_epc_mem_alloc_addr(epc, _addr, reg->size);
if (!src_addr) {
-   dev_err(dev, "failed to allocate address\n");
+   dev_err(dev, "Failed to allocate address\n");
reg->status = STATUS_SRC_ADDR_INVALID;
ret = -ENOMEM;
goto err;
@@ -163,7 +163,7 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test)
ret = pci_epc_map_addr(epc, epf->func_no, phys_addr, reg->src_addr,
   reg->size);
if (ret) {
-   dev_err(dev, "failed to map address\n");
+   dev_err(dev, "Failed to map address\n");
reg->status = STATUS_SRC_ADDR_INVALID;
goto err_addr;
}
@@ -206,7 +206,7 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
 
dst_addr = pci_epc_mem_alloc_addr(epc, _addr, reg->size);
if (!dst_addr) {
-   dev_err(dev, "failed to allocate address\n");
+   dev_err(dev, "Failed to allocate address\n");
reg->status = STATUS_DST_ADDR_INVALID;
ret = -ENOMEM;
goto err;
@@ -215,7 +215,7 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
ret = pci_epc_map_addr(epc, epf->func_no, phys_addr, reg->dst_addr,
   reg->size);
if (ret) {
-   dev_err(dev, "failed to map address\n");
+   dev_err(dev, "Failed to map address\n");
reg->status = STATUS_DST_ADDR_INVALID;
goto err_addr;
}
@@ -409,7 +409,7 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
ret = pci_epc_set_bar(epc, epf->func_no, epf_bar);
if (ret) {
pci_epf_free_space(epf, epf_test->reg[bar], bar);
-   dev_err(dev, "failed to set BAR%d\n", bar);
+   dev_err(dev, "Failed to set BAR%d\n", bar);
if (bar == test_reg_bar)
return ret;
}
@@ -436,7 +436,7 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
base = pci_epf_alloc_space(epf, sizeof(struct pci_epf_test_reg),
   test_reg_bar);
if (!base) {
-   dev_err(dev, "failed to allocated register space\n");
+

[PATCH 05/10] PCI: dwc: Add legacy interrupt callback handler

2018-04-27 Thread Gustavo Pimentel
Add a legacy interrupt callback handler. Currently DesignWare IP don't
allow triggering the legacy interrupt.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
 drivers/pci/dwc/pcie-designware-ep.c   | 10 ++
 drivers/pci/dwc/pcie-designware-plat.c |  3 +--
 drivers/pci/dwc/pcie-designware.h  |  6 ++
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/dwc/pcie-designware-ep.c 
b/drivers/pci/dwc/pcie-designware-ep.c
index 1ba3a7f..b599169 100644
--- a/drivers/pci/dwc/pcie-designware-ep.c
+++ b/drivers/pci/dwc/pcie-designware-ep.c
@@ -370,6 +370,16 @@ static const struct pci_epc_ops epc_ops = {
.stop   = dw_pcie_ep_stop,
 };
 
+int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no)
+{
+   struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+   struct device *dev = pci->dev;
+
+   dev_err(dev, "EP cannot trigger legacy IRQs\n");
+
+   return -EINVAL;
+}
+
 int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 u8 interrupt_num)
 {
diff --git a/drivers/pci/dwc/pcie-designware-plat.c 
b/drivers/pci/dwc/pcie-designware-plat.c
index 654dcb5..90a8c95 100644
--- a/drivers/pci/dwc/pcie-designware-plat.c
+++ b/drivers/pci/dwc/pcie-designware-plat.c
@@ -84,8 +84,7 @@ static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, 
u8 func_no,
 
switch (type) {
case PCI_EPC_IRQ_LEGACY:
-   dev_err(pci->dev, "EP cannot trigger legacy IRQs\n");
-   return -EINVAL;
+   return dw_pcie_ep_raise_legacy_irq(ep, func_no);
case PCI_EPC_IRQ_MSI:
return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
case PCI_EPC_IRQ_MSIX:
diff --git a/drivers/pci/dwc/pcie-designware.h 
b/drivers/pci/dwc/pcie-designware.h
index a0ab12f..69e6e17 100644
--- a/drivers/pci/dwc/pcie-designware.h
+++ b/drivers/pci/dwc/pcie-designware.h
@@ -350,6 +350,7 @@ static inline int dw_pcie_allocate_domains(struct pcie_port 
*pp)
 void dw_pcie_ep_linkup(struct dw_pcie_ep *ep);
 int dw_pcie_ep_init(struct dw_pcie_ep *ep);
 void dw_pcie_ep_exit(struct dw_pcie_ep *ep);
+int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no);
 int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 u8 interrupt_num);
 int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
@@ -369,6 +370,11 @@ static inline void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
 {
 }
 
+static inline int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 
func_no)
+{
+   return 0;
+}
+
 static inline int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
   u8 interrupt_num)
 {
-- 
2.7.4


--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 00/10] Add MSI-X support on pcitest tool

2018-04-27 Thread Gustavo Pimentel
Depends of the following serie [1].

Add MSI-X support on pcitest tool.

Add new callbacks methods and handlers to trigger the MSI-X interrupts
on the EP DesignWare IP driver.

Allow to set/get MSI-X EP maximum capability number.

Rework on set/get and triggering MSI methods on EP DesignWare IP driver.

Add a new input parameter (msix) to pcitest tool to test MSI-X feature.

Update the pcitest.sh script to support MSI-X feature tests.

[1] -> https://lkml.org/lkml/2018/4/27/342

Gustavo Pimentel (10):
  PCI: endpoint: Add MSI-X interfaces
  PCI: dwc: Add MSI-X callbacks handler
  PCI: cadence: Update cdns_pcie_ep_raise_irq function signature
  PCI: dwc: Rework MSI callbacks handler
  PCI: dwc: Add legacy interrupt callback handler
  misc: pci_endpoint_test: Add MSI-X support
  misc: pci_endpoint_test: Replace lower into upper case characters
  PCI: endpoint: functions/pci-epf-test: Replace lower into upper case
characters
  tools: PCI: Add MSI-X support
  misc: pci_endpoint_test: Use pci_irq_vector function

 Documentation/misc-devices/pci-endpoint-test.txt |   3 +
 drivers/misc/pci_endpoint_test.c | 147 +++--
 drivers/pci/cadence/pcie-cadence-ep.c|   2 +-
 drivers/pci/dwc/pci-dra7xx.c |   2 +-
 drivers/pci/dwc/pcie-artpec6.c   |   2 +-
 drivers/pci/dwc/pcie-designware-ep.c | 202 +--
 drivers/pci/dwc/pcie-designware-plat.c   |   7 +-
 drivers/pci/dwc/pcie-designware.h|  31 ++--
 drivers/pci/endpoint/functions/pci-epf-test.c| 104 
 drivers/pci/endpoint/pci-ep-cfs.c|  24 +++
 drivers/pci/endpoint/pci-epc-core.c  |  60 ++-
 include/linux/pci-epc.h  |  11 +-
 include/linux/pci-epf.h  |   1 +
 include/uapi/linux/pcitest.h |   1 +
 tools/pci/pcitest.c  |  18 +-
 tools/pci/pcitest.sh |  25 +++
 16 files changed, 517 insertions(+), 123 deletions(-)

-- 
2.7.4


--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 01/10] PCI: dwc: Add MSI-X callbacks handler

2018-05-10 Thread Gustavo Pimentel
Hi Alan,

Sorry for the delay on the response, I only have time to proper analyze this 
now.

On 24/04/2018 10:15, Alan Douglas wrote:
> Hi,
> 
> On 10 April 2018 18:15 Gustavo Pimentel wrote:
>> Changes the pcie_raise_irq function signature, namely the interrupt_num
>> variable type from u8 to u16 to accommodate the MSI-X maximum interrupts
>> of 2048.
>>
>> Implements a PCIe config space capability iterator function to search and 
>> save
>> the MSI and MSI-X pointers. With this method the code becomes more
>> generic and flexible.
>>
>> Implements MSI-X set/get functions for sysfs interface in order to change the
>> EP entries number.
>>
>> Implements EP MSI-X interface for triggering interruptions.
>>
>> Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
>> ---
>>  drivers/pci/dwc/pci-dra7xx.c   |   2 +-
>>  drivers/pci/dwc/pcie-artpec6.c |   2 +-
>>  drivers/pci/dwc/pcie-designware-ep.c   | 145
>> -
>>  drivers/pci/dwc/pcie-designware-plat.c |   6 +-
>>  drivers/pci/dwc/pcie-designware.h  |  23 +-
>>  5 files changed, 173 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c 
>> index
>> ed8558d..5265725 100644
>> --- a/drivers/pci/dwc/pci-dra7xx.c
>> +++ b/drivers/pci/dwc/pci-dra7xx.c
>> @@ -369,7 +369,7 @@ static void dra7xx_pcie_raise_msi_irq(struct
>> dra7xx_pcie *dra7xx,  }
>>
>>  static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
>> - enum pci_epc_irq_type type, u8
>> interrupt_num)
>> + enum pci_epc_irq_type type, u16
>> interrupt_num)
>>  {
>>  struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>>  struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci); diff --git
>> a/drivers/pci/dwc/pcie-artpec6.c b/drivers/pci/dwc/pcie-artpec6.c index
>> e66cede..96dc259 100644
>> --- a/drivers/pci/dwc/pcie-artpec6.c
>> +++ b/drivers/pci/dwc/pcie-artpec6.c
>> @@ -428,7 +428,7 @@ static void artpec6_pcie_ep_init(struct dw_pcie_ep
>> *ep)  }
>>
>>  static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
>> -  enum pci_epc_irq_type type, u8
>> interrupt_num)
>> +  enum pci_epc_irq_type type, u16
>> interrupt_num)
>>  {
>>  struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>>
>> diff --git a/drivers/pci/dwc/pcie-designware-ep.c b/drivers/pci/dwc/pcie-
>> designware-ep.c
>> index 15b22a6..874d4c2 100644
>> --- a/drivers/pci/dwc/pcie-designware-ep.c
>> +++ b/drivers/pci/dwc/pcie-designware-ep.c
>> @@ -40,6 +40,44 @@ void dw_pcie_ep_reset_bar(struct dw_pcie *pci,
>> enum pci_barno bar)
>>  __dw_pcie_ep_reset_bar(pci, bar, 0);
>>  }
>>
>> +void dw_pcie_ep_find_cap_addr(struct dw_pcie_ep *ep) {
>> +struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>> +u8 next_ptr, curr_ptr, cap_id;
>> +u16 reg;
>> +
>> +memset(>cap_addr, 0, sizeof(ep->cap_addr));
>> +
>> +reg = dw_pcie_readw_dbi(pci, PCI_STATUS);
>> +if (!(reg & PCI_STATUS_CAP_LIST))
>> +return;
>> +
>> +reg = dw_pcie_readw_dbi(pci, PCI_CAPABILITY_LIST);
>> +next_ptr = (reg & 0x00ff);
>> +if (!next_ptr)
>> +return;
>> +
>> +reg = dw_pcie_readw_dbi(pci, next_ptr);
>> +curr_ptr = next_ptr;
>> +next_ptr = (reg & 0xff00) >> 8;
>> +cap_id = (reg & 0x00ff);
>> +
>> +while (next_ptr && (cap_id <= PCI_CAP_ID_MAX)) {
>> +switch (cap_id) {
>> +case PCI_CAP_ID_MSI:
>> +ep->cap_addr.msi_addr = curr_ptr;
>> +break;
>> +case PCI_CAP_ID_MSIX:
>> +ep->cap_addr.msix_addr = curr_ptr;
>> +break;
>> +}
>> +reg = dw_pcie_readw_dbi(pci, next_ptr);
>> +curr_ptr = next_ptr;
>> +next_ptr = (reg & 0xff00) >> 8;
>> +cap_id = (reg & 0x00ff);
>> +}
>> +}
>> +
>>  static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no,
>> struct pci_epf_header *hdr)
>>  {
>> @@ -241,8 +279,47 @@ static int dw_pcie_ep_set_msi(struct pci_epc *epc,
>> u8 func_no, u8 encode_int)
>>  return 0;
>>  }
>>
>> +static int dw_pcie_ep_ge

[PATCH v2 4/7] PCI: dwc: Rework MSI callbacks handler

2018-05-17 Thread Gustavo Pimentel
Remove duplicate defines located on pcie-designware.h file already
available on /include/uapi/linux/pci-regs.h file.

Add pci_epc_set_msi() maximum 32 interrupts validation.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
Change v1->v2:
 - Nothing changed, just to follow the patch set version.

 drivers/pci/dwc/pcie-designware-ep.c | 49 
 drivers/pci/dwc/pcie-designware.h| 11 
 drivers/pci/endpoint/pci-epc-core.c  |  3 ++-
 3 files changed, 35 insertions(+), 28 deletions(-)

diff --git a/drivers/pci/dwc/pcie-designware-ep.c 
b/drivers/pci/dwc/pcie-designware-ep.c
index e5f2377..a4baa0d 100644
--- a/drivers/pci/dwc/pcie-designware-ep.c
+++ b/drivers/pci/dwc/pcie-designware-ep.c
@@ -246,29 +246,38 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 
func_no,
 
 static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no)
 {
-   int val;
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+   u32 val, reg;
+
+   if (!ep->msi_cap)
+   return 0;
 
-   val = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
-   if (!(val & MSI_CAP_MSI_EN_MASK))
+   reg = ep->msi_cap + PCI_MSI_FLAGS;
+   val = dw_pcie_readw_dbi(pci, reg);
+   if (!(val & PCI_MSI_FLAGS_ENABLE))
return -EINVAL;
 
-   val = (val & MSI_CAP_MME_MASK) >> MSI_CAP_MME_SHIFT;
+   val = (val & PCI_MSI_FLAGS_QSIZE) >> 4;
+
return val;
 }
 
-static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 encode_int)
+static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
 {
-   int val;
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+   u32 val, reg;
 
-   val = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
-   val &= ~MSI_CAP_MMC_MASK;
-   val |= (encode_int << MSI_CAP_MMC_SHIFT) & MSI_CAP_MMC_MASK;
+   if (!ep->msi_cap)
+   return 0;
+
+   reg = ep->msi_cap + PCI_MSI_FLAGS;
+   val = dw_pcie_readw_dbi(pci, reg);
+   val &= ~PCI_MSI_FLAGS_QMASK;
+   val |= (interrupts << 1) & PCI_MSI_FLAGS_QMASK;
dw_pcie_dbi_ro_wr_en(pci);
-   dw_pcie_writew_dbi(pci, MSI_MESSAGE_CONTROL, val);
+   dw_pcie_writew_dbi(pci, reg, val);
dw_pcie_dbi_ro_wr_dis(pci);
 
return 0;
@@ -367,21 +376,29 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 
func_no,
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
struct pci_epc *epc = ep->epc;
u16 msg_ctrl, msg_data;
-   u32 msg_addr_lower, msg_addr_upper;
+   u32 msg_addr_lower, msg_addr_upper, reg;
u64 msg_addr;
bool has_upper;
int ret;
 
+   if (!ep->msi_cap)
+   return 0;
+
/* Raise MSI per the PCI Local Bus Specification Revision 3.0, 6.8.1. */
-   msg_ctrl = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
+   reg = ep->msi_cap + PCI_MSI_FLAGS;
+   msg_ctrl = dw_pcie_readw_dbi(pci, reg);
has_upper = !!(msg_ctrl & PCI_MSI_FLAGS_64BIT);
-   msg_addr_lower = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_L32);
+   reg = ep->msi_cap + PCI_MSI_ADDRESS_LO;
+   msg_addr_lower = dw_pcie_readl_dbi(pci, reg);
if (has_upper) {
-   msg_addr_upper = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_U32);
-   msg_data = dw_pcie_readw_dbi(pci, MSI_MESSAGE_DATA_64);
+   reg = ep->msi_cap + PCI_MSI_ADDRESS_HI;
+   msg_addr_upper = dw_pcie_readl_dbi(pci, reg);
+   reg = ep->msi_cap + PCI_MSI_DATA_64;
+   msg_data = dw_pcie_readw_dbi(pci, reg);
} else {
msg_addr_upper = 0;
-   msg_data = dw_pcie_readw_dbi(pci, MSI_MESSAGE_DATA_32);
+   reg = ep->msi_cap + PCI_MSI_DATA_32;
+   msg_data = dw_pcie_readw_dbi(pci, reg);
}
msg_addr = ((u64) msg_addr_upper) << 32 | msg_addr_lower;
ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr,
diff --git a/drivers/pci/dwc/pcie-designware.h 
b/drivers/pci/dwc/pcie-designware.h
index b22c5bb..a0ab12f 100644
--- a/drivers/pci/dwc/pcie-designware.h
+++ b/drivers/pci/dwc/pcie-designware.h
@@ -96,17 +96,6 @@
 #define PCIE_GET_ATU_INB_UNR_REG_OFFSET(region)
\
((0x3 << 20) | ((region) << 9) | (0x1 << 8))
 
-#define MSI_MESSAGE_CONTROL0x52
-#define MSI_CAP_MMC_SHIFT  1
-#define MSI_CAP_MMC_MASK   (7 << MSI_CAP_MMC_SHIFT)
-#define MSI_CAP_MME_SHIFT  4
-#define MSI_CAP_MSI_EN_MASK0x1
-#define MSI_CAP_MME_MASK   (7 << MSI_CAP_MME_SHIFT)
-#define MSI_MESSAGE_ADDR_L32   0x54
-#define MSI_MESSAGE_ADDR_U32   0x58
-#d

[PATCH v2 1/7] PCI: endpoint: Add MSI-X interfaces

2018-05-17 Thread Gustavo Pimentel
Add PCI_EPC_IRQ_MSIX type.

Add MSI-X callbacks signatures to the ops structure.

Add sysfs interface for set/get MSI-X capability maximum number.

Change pci_epc_raise_irq() signature, namely the interrupt_num variable type
from u8 to u16 to accommodate 2048 maximum MSI-X interrupts.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
Change v1->v2:
 - Nothing changed, just to follow the patch set version.

 drivers/pci/endpoint/pci-ep-cfs.c   | 24 +++
 drivers/pci/endpoint/pci-epc-core.c | 59 -
 include/linux/pci-epc.h | 13 ++--
 include/linux/pci-epf.h |  1 +
 4 files changed, 94 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/endpoint/pci-ep-cfs.c 
b/drivers/pci/endpoint/pci-ep-cfs.c
index 018ea34..d1288a0 100644
--- a/drivers/pci/endpoint/pci-ep-cfs.c
+++ b/drivers/pci/endpoint/pci-ep-cfs.c
@@ -286,6 +286,28 @@ static ssize_t pci_epf_msi_interrupts_show(struct 
config_item *item,
   to_pci_epf_group(item)->epf->msi_interrupts);
 }
 
+static ssize_t pci_epf_msix_interrupts_store(struct config_item *item,
+const char *page, size_t len)
+{
+   u16 val;
+   int ret;
+
+   ret = kstrtou16(page, 0, );
+   if (ret)
+   return ret;
+
+   to_pci_epf_group(item)->epf->msix_interrupts = val;
+
+   return len;
+}
+
+static ssize_t pci_epf_msix_interrupts_show(struct config_item *item,
+   char *page)
+{
+   return sprintf(page, "%d\n",
+  to_pci_epf_group(item)->epf->msix_interrupts);
+}
+
 PCI_EPF_HEADER_R(vendorid)
 PCI_EPF_HEADER_W_u16(vendorid)
 
@@ -327,6 +349,7 @@ CONFIGFS_ATTR(pci_epf_, subsys_vendor_id);
 CONFIGFS_ATTR(pci_epf_, subsys_id);
 CONFIGFS_ATTR(pci_epf_, interrupt_pin);
 CONFIGFS_ATTR(pci_epf_, msi_interrupts);
+CONFIGFS_ATTR(pci_epf_, msix_interrupts);
 
 static struct configfs_attribute *pci_epf_attrs[] = {
_epf_attr_vendorid,
@@ -340,6 +363,7 @@ static struct configfs_attribute *pci_epf_attrs[] = {
_epf_attr_subsys_id,
_epf_attr_interrupt_pin,
_epf_attr_msi_interrupts,
+   _epf_attr_msix_interrupts,
NULL,
 };
 
diff --git a/drivers/pci/endpoint/pci-epc-core.c 
b/drivers/pci/endpoint/pci-epc-core.c
index b0ee427..a23aa75 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -137,7 +137,7 @@ EXPORT_SYMBOL_GPL(pci_epc_start);
  * Invoke to raise an MSI or legacy interrupt
  */
 int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,
- enum pci_epc_irq_type type, u8 interrupt_num)
+ enum pci_epc_irq_type type, u16 interrupt_num)
 {
int ret;
unsigned long flags;
@@ -218,6 +218,63 @@ int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 
interrupts)
 EXPORT_SYMBOL_GPL(pci_epc_set_msi);
 
 /**
+ * pci_epc_get_msix() - get the number of MSI-X interrupt numbers allocated
+ * @epc: the EPC device to which MSI-X interrupts was requested
+ * @func_no: the endpoint function number in the EPC device
+ *
+ * Invoke to get the number of MSI-X interrupts allocated by the RC
+ */
+int pci_epc_get_msix(struct pci_epc *epc, u8 func_no)
+{
+   int interrupt;
+   unsigned long flags;
+
+   if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
+   return 0;
+
+   if (!epc->ops->get_msix)
+   return 0;
+
+   spin_lock_irqsave(>lock, flags);
+   interrupt = epc->ops->get_msix(epc, func_no);
+   spin_unlock_irqrestore(>lock, flags);
+
+   if (interrupt < 0)
+   return 0;
+
+   return interrupt + 1;
+}
+EXPORT_SYMBOL_GPL(pci_epc_get_msix);
+
+/**
+ * pci_epc_set_msix() - set the number of MSI-X interrupt numbers required
+ * @epc: the EPC device on which MSI-X has to be configured
+ * @func_no: the endpoint function number in the EPC device
+ * @interrupts: number of MSI-X interrupts required by the EPF
+ *
+ * Invoke to set the required number of MSI-X interrupts.
+ */
+int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts)
+{
+   int ret;
+   unsigned long flags;
+
+   if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions ||
+   interrupts < 1 || interrupts > 2048)
+   return -EINVAL;
+
+   if (!epc->ops->set_msix)
+   return 0;
+
+   spin_lock_irqsave(>lock, flags);
+   ret = epc->ops->set_msix(epc, func_no, interrupts - 1);
+   spin_unlock_irqrestore(>lock, flags);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(pci_epc_set_msix);
+
+/**
  * pci_epc_unmap_addr() - unmap CPU address from PCI address
  * @epc: the EPC device on which address is allocated
  * @func_no: the endpoint function number in the EPC device
diff --git a/include/linux/pci-epc.h b/include/linux/pci-e

[PATCH v2 0/7] Add MSI-X support on pcitest tool

2018-05-17 Thread Gustavo Pimentel
Patch series made against Lorenzo's branches and also depends of:
 - pci/dwc
 - pci/endpoint

Add MSI-X support on pcitest tool.

Add new callbacks methods and handlers to trigger the MSI-X interrupts
on the EP DesignWare IP driver.

Allow to set/get MSI-X EP maximum capability number.

Rework on set/get and triggering MSI methods on EP DesignWare IP driver.

Add a new input parameter (msix) to pcitest tool to test MSI-X feature.

Update the pcitest.sh script to support MSI-X feature tests.


Gustavo Pimentel (7):
  PCI: endpoint: Add MSI-X interfaces
  PCI: dwc: Add MSI-X callbacks handler
  PCI: cadence: Update cdns_pcie_ep_raise_irq function signature
  PCI: dwc: Rework MSI callbacks handler
  PCI: dwc: Add legacy interrupt callback handler
  misc: pci_endpoint_test: Add MSI-X support
  tools: PCI: Add MSI-X support

 Documentation/misc-devices/pci-endpoint-test.txt |   6 +
 drivers/misc/pci_endpoint_test.c | 261 +--
 drivers/pci/cadence/pcie-cadence-ep.c|   3 +-
 drivers/pci/dwc/pci-dra7xx.c |   2 +-
 drivers/pci/dwc/pcie-artpec6.c   |   2 +-
 drivers/pci/dwc/pcie-designware-ep.c | 205 --
 drivers/pci/dwc/pcie-designware-plat.c   |   7 +-
 drivers/pci/dwc/pcie-designware.h|  31 +--
 drivers/pci/endpoint/functions/pci-epf-test.c|  81 +--
 drivers/pci/endpoint/pci-ep-cfs.c|  24 +++
 drivers/pci/endpoint/pci-epc-core.c  |  62 +-
 include/linux/pci-epc.h  |  13 +-
 include/linux/pci-epf.h  |   1 +
 include/uapi/linux/pcitest.h |   3 +
 tools/pci/pcitest.c  |  51 -
 tools/pci/pcitest.sh |  15 ++
 16 files changed, 639 insertions(+), 128 deletions(-)

-- 
2.7.4


--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 3/7] PCI: cadence: Update cdns_pcie_ep_raise_irq function signature

2018-05-17 Thread Gustavo Pimentel
Change cdns_pcie_ep_raise_irq() signature, namely the interrupt_num
variable type from u8 to u16 to accommodate 2048 maximum MSI-X
interrupts.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
Acked-by: Alan Douglas <adoug...@cadence.com>
---
Change v1->v2:
 - Nothing changed, just to follow the patch set version.

 drivers/pci/cadence/pcie-cadence-ep.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/cadence/pcie-cadence-ep.c 
b/drivers/pci/cadence/pcie-cadence-ep.c
index 3d8283e..6b713ca 100644
--- a/drivers/pci/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/cadence/pcie-cadence-ep.c
@@ -363,7 +363,8 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep 
*ep, u8 fn,
 }
 
 static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
- enum pci_epc_irq_type type, u8 interrupt_num)
+ enum pci_epc_irq_type type,
+ u16 interrupt_num)
 {
struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 
-- 
2.7.4


--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 5/7] PCI: dwc: Add legacy interrupt callback handler

2018-05-17 Thread Gustavo Pimentel
Add a legacy interrupt callback handler. Currently DesignWare IP don't
allow trigger legacy interrupts.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
Change v1->v2:
 - Nothing changed, just to follow the patch set version.

 drivers/pci/dwc/pcie-designware-ep.c   | 10 ++
 drivers/pci/dwc/pcie-designware-plat.c |  3 +--
 drivers/pci/dwc/pcie-designware.h  |  6 ++
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/dwc/pcie-designware-ep.c 
b/drivers/pci/dwc/pcie-designware-ep.c
index a4baa0d..9822127 100644
--- a/drivers/pci/dwc/pcie-designware-ep.c
+++ b/drivers/pci/dwc/pcie-designware-ep.c
@@ -370,6 +370,16 @@ static const struct pci_epc_ops epc_ops = {
.stop   = dw_pcie_ep_stop,
 };
 
+int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no)
+{
+   struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+   struct device *dev = pci->dev;
+
+   dev_err(dev, "EP cannot trigger legacy IRQs\n");
+
+   return -EINVAL;
+}
+
 int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 u8 interrupt_num)
 {
diff --git a/drivers/pci/dwc/pcie-designware-plat.c 
b/drivers/pci/dwc/pcie-designware-plat.c
index 654dcb5..90a8c95 100644
--- a/drivers/pci/dwc/pcie-designware-plat.c
+++ b/drivers/pci/dwc/pcie-designware-plat.c
@@ -84,8 +84,7 @@ static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, 
u8 func_no,
 
switch (type) {
case PCI_EPC_IRQ_LEGACY:
-   dev_err(pci->dev, "EP cannot trigger legacy IRQs\n");
-   return -EINVAL;
+   return dw_pcie_ep_raise_legacy_irq(ep, func_no);
case PCI_EPC_IRQ_MSI:
return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
case PCI_EPC_IRQ_MSIX:
diff --git a/drivers/pci/dwc/pcie-designware.h 
b/drivers/pci/dwc/pcie-designware.h
index a0ab12f..69e6e17 100644
--- a/drivers/pci/dwc/pcie-designware.h
+++ b/drivers/pci/dwc/pcie-designware.h
@@ -350,6 +350,7 @@ static inline int dw_pcie_allocate_domains(struct pcie_port 
*pp)
 void dw_pcie_ep_linkup(struct dw_pcie_ep *ep);
 int dw_pcie_ep_init(struct dw_pcie_ep *ep);
 void dw_pcie_ep_exit(struct dw_pcie_ep *ep);
+int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no);
 int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 u8 interrupt_num);
 int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
@@ -369,6 +370,11 @@ static inline void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
 {
 }
 
+static inline int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 
func_no)
+{
+   return 0;
+}
+
 static inline int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
   u8 interrupt_num)
 {
-- 
2.7.4


--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 7/7] tools: PCI: Add MSI-X support

2018-05-17 Thread Gustavo Pimentel
Add MSI-X support to pcitest tool.

Add 2 new IOCTL commands:
 - Allow to reconfigure driver IRQ type in runtime.
 - Allow to retrieve current driver IRQ type configured.

Modify pcitest.sh script to accommodate MSI-X interrupt tests.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
Change v1->v2:
 - Allow IRQ type driver reconfiguring in runtime, follwing Kishon's
suggestion.

 include/uapi/linux/pcitest.h |  3 +++
 tools/pci/pcitest.c  | 51 +++-
 tools/pci/pcitest.sh | 15 +
 3 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/pcitest.h b/include/uapi/linux/pcitest.h
index 953cf03..cbf422e 100644
--- a/include/uapi/linux/pcitest.h
+++ b/include/uapi/linux/pcitest.h
@@ -16,5 +16,8 @@
 #define PCITEST_WRITE  _IOW('P', 0x4, unsigned long)
 #define PCITEST_READ   _IOW('P', 0x5, unsigned long)
 #define PCITEST_COPY   _IOW('P', 0x6, unsigned long)
+#define PCITEST_MSIX   _IOW('P', 0x7, int)
+#define PCITEST_SET_IRQTYPE_IOW('P', 0x8, int)
+#define PCITEST_GET_IRQTYPE_IO('P', 0x9)
 
 #endif /* __UAPI_LINUX_PCITEST_H */
diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c
index 9074b47..af146bb 100644
--- a/tools/pci/pcitest.c
+++ b/tools/pci/pcitest.c
@@ -31,12 +31,17 @@
 #define BILLION 1E9
 
 static char *result[] = { "NOT OKAY", "OKAY" };
+static char *irq[] = { "LEGACY", "MSI", "MSI-X" };
 
 struct pci_test {
char*device;
charbarnum;
boollegacyirq;
unsigned intmsinum;
+   unsigned intmsixnum;
+   int irqtype;
+   boolset_irqtype;
+   boolget_irqtype;
boolread;
boolwrite;
boolcopy;
@@ -65,6 +70,24 @@ static int run_test(struct pci_test *test)
fprintf(stdout, "%s\n", result[ret]);
}
 
+   if (test->set_irqtype) {
+   ret = ioctl(fd, PCITEST_SET_IRQTYPE, test->irqtype);
+   fprintf(stdout, "SET IRQ TYPE TO %s:\t\t", irq[test->irqtype]);
+   if (ret < 0)
+   fprintf(stdout, "FAILED\n");
+   else
+   fprintf(stdout, "%s\n", result[ret]);
+   }
+
+   if (test->get_irqtype) {
+   ret = ioctl(fd, PCITEST_GET_IRQTYPE);
+   fprintf(stdout, "GET IRQ TYPE:\t\t");
+   if (ret < 0)
+   fprintf(stdout, "FAILED\n");
+   else
+   fprintf(stdout, "%s\n", irq[ret]);
+   }
+
if (test->legacyirq) {
ret = ioctl(fd, PCITEST_LEGACY_IRQ, 0);
fprintf(stdout, "LEGACY IRQ:\t");
@@ -83,6 +106,15 @@ static int run_test(struct pci_test *test)
fprintf(stdout, "%s\n", result[ret]);
}
 
+   if (test->msixnum > 0 && test->msixnum <= 2048) {
+   ret = ioctl(fd, PCITEST_MSIX, test->msixnum);
+   fprintf(stdout, "MSI-X%d:\t\t", test->msixnum);
+   if (ret < 0)
+   fprintf(stdout, "TEST FAILED\n");
+   else
+   fprintf(stdout, "%s\n", result[ret]);
+   }
+
if (test->write) {
ret = ioctl(fd, PCITEST_WRITE, test->size);
fprintf(stdout, "WRITE (%7ld bytes):\t\t", test->size);
@@ -133,7 +165,7 @@ int main(int argc, char **argv)
/* set default endpoint device */
test->device = "/dev/pci-endpoint-test.0";
 
-   while ((c = getopt(argc, argv, "D:b:m:lrwcs:")) != EOF)
+   while ((c = getopt(argc, argv, "D:b:m:x:i:Ilrwcs:")) != EOF)
switch (c) {
case 'D':
test->device = optarg;
@@ -151,6 +183,20 @@ int main(int argc, char **argv)
if (test->msinum < 1 || test->msinum > 32)
goto usage;
continue;
+   case 'x':
+   test->msixnum = atoi(optarg);
+   if (test->msixnum < 1 || test->msixnum > 2048)
+   goto usage;
+   continue;
+   case 'i':
+   test->irqtype = atoi(optarg);
+   if (test->irqtype < 0 || test->irqtype > 2)
+   goto usage;
+   test->set_irqtype = true;
+   continue;
+   case 'I':
+   test->get_irqtype = true;
+   continue;
case 'r':
test->read = true;
continue;
@@ -173,6 +219,9 @@ int main(int argc, char **argv)
 

[PATCH v2 6/7] misc: pci_endpoint_test: Add MSI-X support

2018-05-17 Thread Gustavo Pimentel
Add MSI-X support and update driver documentation accordingly.

Add new driver parameter to allow interruption type selection.

Add 2 new IOCTL commands:
 - Allow to reconfigure driver IRQ type in runtime.
 - Allow to retrieve current driver IRQ type configured.

Change Legacy/MSI/MSI-X test process, by having in a BAR:
 - Interrupt type triggered (added).
 - Interrupt ID number (moved from the command section).

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
Change v1->v2:
 - Allow IRQ type driver reconfiguring in runtime, follwing Kishon's
suggestion.

 Documentation/misc-devices/pci-endpoint-test.txt |   6 +
 drivers/misc/pci_endpoint_test.c | 261 +--
 drivers/pci/endpoint/functions/pci-epf-test.c|  81 +--
 3 files changed, 260 insertions(+), 88 deletions(-)

diff --git a/Documentation/misc-devices/pci-endpoint-test.txt 
b/Documentation/misc-devices/pci-endpoint-test.txt
index 4ebc359..58ccca4 100644
--- a/Documentation/misc-devices/pci-endpoint-test.txt
+++ b/Documentation/misc-devices/pci-endpoint-test.txt
@@ -10,6 +10,7 @@ The PCI driver for the test device performs the following 
tests
*) verifying addresses programmed in BAR
*) raise legacy IRQ
*) raise MSI IRQ
+   *) raise MSI-X IRQ
*) read data
*) write data
*) copy data
@@ -25,6 +26,11 @@ ioctl
  PCITEST_LEGACY_IRQ: Tests legacy IRQ
  PCITEST_MSI: Tests message signalled interrupts. The MSI number
  to be tested should be passed as argument.
+ PCITEST_MSIX: Tests message signalled interrupts. The MSI-X number
+ to be tested should be passed as argument.
+ PCITEST_SET_IRQTYPE: Changes driver IRQ type configuration. The IRQ type
+ should be passed as argument (0: Legacy, 1:MSI, 2:MSI-X).
+ PCITEST_GET_IRQTYPE: Gets driver IRQ type configuration.
  PCITEST_WRITE: Perform write tests. The size of the buffer should be passed
as argument.
  PCITEST_READ: Perform read tests. The size of the buffer should be passed
diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index 7b37046..df2017f 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -35,38 +35,44 @@
 
 #include 
 
-#define DRV_MODULE_NAME"pci-endpoint-test"
-
-#define PCI_ENDPOINT_TEST_MAGIC0x0
-
-#define PCI_ENDPOINT_TEST_COMMAND  0x4
-#define COMMAND_RAISE_LEGACY_IRQ   BIT(0)
-#define COMMAND_RAISE_MSI_IRQ  BIT(1)
-#define MSI_NUMBER_SHIFT   2
-/* 6 bits for MSI number */
-#define COMMAND_READBIT(8)
-#define COMMAND_WRITE   BIT(9)
-#define COMMAND_COPYBIT(10)
-
-#define PCI_ENDPOINT_TEST_STATUS   0x8
-#define STATUS_READ_SUCCESS BIT(0)
-#define STATUS_READ_FAILBIT(1)
-#define STATUS_WRITE_SUCCESSBIT(2)
-#define STATUS_WRITE_FAIL   BIT(3)
-#define STATUS_COPY_SUCCESS BIT(4)
-#define STATUS_COPY_FAILBIT(5)
-#define STATUS_IRQ_RAISED   BIT(6)
-#define STATUS_SRC_ADDR_INVALID BIT(7)
-#define STATUS_DST_ADDR_INVALID BIT(8)
-
-#define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR   0xc
+#define DRV_MODULE_NAME"pci-endpoint-test"
+
+#define IRQ_TYPE_LEGACY0
+#define IRQ_TYPE_MSI   1
+#define IRQ_TYPE_MSIX  2
+
+#define PCI_ENDPOINT_TEST_MAGIC0x0
+
+#define PCI_ENDPOINT_TEST_COMMAND  0x4
+#define COMMAND_RAISE_LEGACY_IRQ   BIT(0)
+#define COMMAND_RAISE_MSI_IRQ  BIT(1)
+#define COMMAND_RAISE_MSIX_IRQ BIT(2)
+#define COMMAND_READ   BIT(3)
+#define COMMAND_WRITE  BIT(4)
+#define COMMAND_COPY   BIT(5)
+
+#define PCI_ENDPOINT_TEST_STATUS   0x8
+#define STATUS_READ_SUCCESSBIT(0)
+#define STATUS_READ_FAIL   BIT(1)
+#define STATUS_WRITE_SUCCESS   BIT(2)
+#define STATUS_WRITE_FAIL  BIT(3)
+#define STATUS_COPY_SUCCESSBIT(4)
+#define STATUS_COPY_FAIL   BIT(5)
+#define STATUS_IRQ_RAISED  BIT(6)
+#define STATUS_SRC_ADDR_INVALIDBIT(7)
+#define STATUS_DST_ADDR_INVALIDBIT(8)
+
+#define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR   0x0c
 #define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR   0x10
 
 #define PCI_ENDPOINT_TEST_LOWER_DST_ADDR   0x14
 #define PCI_ENDPOINT_TEST_UPPER_DST_ADDR   0x18
 
-#define PCI_ENDPOINT_TEST_SIZE 0x1c
-#define PCI_ENDPOINT_TEST_CHECKSUM 0x20
+#define PCI_ENDPOINT_TEST_SIZE 0x1c
+#define PCI_ENDPOINT_TEST_CHECKSU

[PATCH v2 2/7] PCI: dwc: Add MSI-X callbacks handler

2018-05-17 Thread Gustavo Pimentel
Change pcie_raise_irq() signature, namely the interrupt_num variable type
from u8 to u16 to accommodate 2048 maximum MSI-X interrupts.

Add PCIe config space capability search function.

Add sysfs set/get interface to allow the change of EP MSI-X maximum number.

Add EP MSI-X callback for triggering interruptions.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
Change v1->v2:
 - Nothing changed, just to follow the patch set version.

 drivers/pci/dwc/pci-dra7xx.c   |   2 +-
 drivers/pci/dwc/pcie-artpec6.c |   2 +-
 drivers/pci/dwc/pcie-designware-ep.c   | 146 -
 drivers/pci/dwc/pcie-designware-plat.c |   4 +-
 drivers/pci/dwc/pcie-designware.h  |  14 +++-
 5 files changed, 163 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
index f688204..bdf948b 100644
--- a/drivers/pci/dwc/pci-dra7xx.c
+++ b/drivers/pci/dwc/pci-dra7xx.c
@@ -370,7 +370,7 @@ static void dra7xx_pcie_raise_msi_irq(struct dra7xx_pcie 
*dra7xx,
 }
 
 static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
-enum pci_epc_irq_type type, u8 interrupt_num)
+enum pci_epc_irq_type type, u16 interrupt_num)
 {
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
diff --git a/drivers/pci/dwc/pcie-artpec6.c b/drivers/pci/dwc/pcie-artpec6.c
index 321b56c..9a2474b 100644
--- a/drivers/pci/dwc/pcie-artpec6.c
+++ b/drivers/pci/dwc/pcie-artpec6.c
@@ -428,7 +428,7 @@ static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep)
 }
 
 static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
- enum pci_epc_irq_type type, u8 interrupt_num)
+ enum pci_epc_irq_type type, u16 interrupt_num)
 {
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 
diff --git a/drivers/pci/dwc/pcie-designware-ep.c 
b/drivers/pci/dwc/pcie-designware-ep.c
index 1eec441..e5f2377 100644
--- a/drivers/pci/dwc/pcie-designware-ep.c
+++ b/drivers/pci/dwc/pcie-designware-ep.c
@@ -40,6 +40,39 @@ void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum 
pci_barno bar)
__dw_pcie_ep_reset_bar(pci, bar, 0);
 }
 
+u8 __dw_pcie_ep_find_next_cap(struct dw_pcie *pci, u8 cap_ptr,
+ u8 cap)
+{
+   u8 cap_id, next_cap_ptr;
+   u16 reg;
+
+   reg = dw_pcie_readw_dbi(pci, cap_ptr);
+   next_cap_ptr = (reg & 0xff00) >> 8;
+   cap_id = (reg & 0x00ff);
+
+   if (!next_cap_ptr || cap_id > PCI_CAP_ID_MAX)
+   return 0;
+
+   if (cap_id == cap)
+   return cap_ptr;
+
+   return __dw_pcie_ep_find_next_cap(pci, next_cap_ptr, cap);
+}
+
+u8 dw_pcie_ep_find_capability(struct dw_pcie *pci, u8 cap)
+{
+   u8 next_cap_ptr;
+   u16 reg;
+
+   reg = dw_pcie_readw_dbi(pci, PCI_CAPABILITY_LIST);
+   next_cap_ptr = (reg & 0x00ff);
+
+   if (!next_cap_ptr)
+   return 0;
+
+   return __dw_pcie_ep_find_next_cap(pci, next_cap_ptr, cap);
+}
+
 static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no,
   struct pci_epf_header *hdr)
 {
@@ -241,8 +274,47 @@ static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 
func_no, u8 encode_int)
return 0;
 }
 
+static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
+{
+   struct dw_pcie_ep *ep = epc_get_drvdata(epc);
+   struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+   u32 val, reg;
+
+   if (!ep->msix_cap)
+   return 0;
+
+   reg = ep->msix_cap + PCI_MSIX_FLAGS;
+   val = dw_pcie_readw_dbi(pci, reg);
+   if (!(val & PCI_MSIX_FLAGS_ENABLE))
+   return -EINVAL;
+
+   val &= PCI_MSIX_FLAGS_QSIZE;
+
+   return val;
+}
+
+static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts)
+{
+   struct dw_pcie_ep *ep = epc_get_drvdata(epc);
+   struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+   u32 val, reg;
+
+   if (!ep->msix_cap)
+   return 0;
+
+   reg = ep->msix_cap + PCI_MSIX_FLAGS;
+   val = dw_pcie_readw_dbi(pci, reg);
+   val &= ~PCI_MSIX_FLAGS_QSIZE;
+   val |= interrupts;
+   dw_pcie_dbi_ro_wr_en(pci);
+   dw_pcie_writew_dbi(pci, reg, val);
+   dw_pcie_dbi_ro_wr_dis(pci);
+
+   return 0;
+}
+
 static int dw_pcie_ep_raise_irq(struct pci_epc *epc, u8 func_no,
-   enum pci_epc_irq_type type, u8 interrupt_num)
+   enum pci_epc_irq_type type, u16 interrupt_num)
 {
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 
@@ -282,6 +354,8 @@ static const struct pci_epc_ops epc_ops = {
.unmap_addr = dw_pcie_ep_unmap_addr,
.set_msi= dw_pcie_ep_set_msi,
.get_msi= dw_pcie_ep_get_msi,

Re: [RFC 01/10] PCI: dwc: Add MSI-X callbacks handler

2018-04-26 Thread Gustavo Pimentel

Hi Kishon,

On 24/04/2018 12:24, Kishon Vijay Abraham I wrote:
> Hi,
> 
> On Tuesday 24 April 2018 03:06 PM, Gustavo Pimentel wrote:
>> Hi Kishon,
>>
>> On 24/04/2018 08:07, Kishon Vijay Abraham I wrote:
>>> Hi,
>>>
>>> On Monday 23 April 2018 03:06 PM, Gustavo Pimentel wrote:
>>>> Hi Kishon,
>>>>
>>>> On 16/04/2018 10:29, Kishon Vijay Abraham I wrote:
>>>>> Hi Gustavo,
>>>>>
>>>>> On Tuesday 10 April 2018 10:44 PM, Gustavo Pimentel wrote:
>>>>>> Changes the pcie_raise_irq function signature, namely the interrupt_num
>>>>>> variable type from u8 to u16 to accommodate the MSI-X maximum interrupts
>>>>>> of 2048.
>>>>>>
>>>>>> Implements a PCIe config space capability iterator function to search and
>>>>>> save the MSI and MSI-X pointers. With this method the code becomes more
>>>>>> generic and flexible.
>>>>>>
>>>>>> Implements MSI-X set/get functions for sysfs interface in order to change
>>>>>> the EP entries number.
>>>>>>
>>>>>> Implements EP MSI-X interface for triggering interruptions.
>>>>>>
>>>>>> Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
>>>>>> ---
>>>>>>  drivers/pci/dwc/pci-dra7xx.c   |   2 +-
>>>>>>  drivers/pci/dwc/pcie-artpec6.c |   2 +-
>>>>>>  drivers/pci/dwc/pcie-designware-ep.c   | 145 
>>>>>> -
>>>>>>  drivers/pci/dwc/pcie-designware-plat.c |   6 +-
>>>>>>  drivers/pci/dwc/pcie-designware.h  |  23 +-
>>>>>>  5 files changed, 173 insertions(+), 5 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
>>>>>> index ed8558d..5265725 100644
>>>>>> --- a/drivers/pci/dwc/pci-dra7xx.c
>>>>>> +++ b/drivers/pci/dwc/pci-dra7xx.c
>>>>>> @@ -369,7 +369,7 @@ static void dra7xx_pcie_raise_msi_irq(struct 
>>>>>> dra7xx_pcie *dra7xx,
>>>>>>  }
>>>>>>  
>>>>>>  static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
>>>>>> - enum pci_epc_irq_type type, u8 
>>>>>> interrupt_num)
>>>>>> + enum pci_epc_irq_type type, u16 
>>>>>> interrupt_num)
>>>>>>  {
>>>>>>  struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>>>>>>  struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
>>>>>> diff --git a/drivers/pci/dwc/pcie-artpec6.c 
>>>>>> b/drivers/pci/dwc/pcie-artpec6.c
>>>>>> index e66cede..96dc259 100644
>>>>>> --- a/drivers/pci/dwc/pcie-artpec6.c
>>>>>> +++ b/drivers/pci/dwc/pcie-artpec6.c
>>>>>> @@ -428,7 +428,7 @@ static void artpec6_pcie_ep_init(struct dw_pcie_ep 
>>>>>> *ep)
>>>>>>  }
>>>>>>  
>>>>>>  static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
>>>>>> -  enum pci_epc_irq_type type, u8 
>>>>>> interrupt_num)
>>>>>> +  enum pci_epc_irq_type type, u16 
>>>>>> interrupt_num)
>>>>>>  {
>>>>>>  struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>>>>>>  
>>>>>> diff --git a/drivers/pci/dwc/pcie-designware-ep.c 
>>>>>> b/drivers/pci/dwc/pcie-designware-ep.c
>>>>>> index 15b22a6..874d4c2 100644
>>>>>> --- a/drivers/pci/dwc/pcie-designware-ep.c
>>>>>> +++ b/drivers/pci/dwc/pcie-designware-ep.c
>>>>>> @@ -40,6 +40,44 @@ void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum 
>>>>>> pci_barno bar)
>>>>>>  __dw_pcie_ep_reset_bar(pci, bar, 0);
>>>>>>  }
>>>>>>  
>>>>>> +void dw_pcie_ep_find_cap_addr(struct dw_pcie_ep *ep)
>>>>>> +{
>>>>>
>>>>> This should be implemented in a generic way similar to 
>>>>> pci_find_capability().
>>>>> It'll be useful when we try to implement other capabilities as well.
>>&

Re: [RFC 06/10] misc: pci_endpoint_test: Add MSI-X support

2018-04-26 Thread Gustavo Pimentel
Hi Kishon,

On 24/04/2018 12:43, Kishon Vijay Abraham I wrote:
> Hi,
> 
> On Tuesday 24 April 2018 04:27 PM, Gustavo Pimentel wrote:
>> Hi Kishon,
>>
>> On 24/04/2018 08:19, Kishon Vijay Abraham I wrote:
>>> Hi,
>>>
>>> On Tuesday 17 April 2018 11:08 PM, Gustavo Pimentel wrote:
>>>> Hi Kishon,
>>>>
>>>> On 17/04/2018 11:33, Kishon Vijay Abraham I wrote:
>>>>> Hi,
>>>>>
>>>>> On Tuesday 10 April 2018 10:44 PM, Gustavo Pimentel wrote:
>>>>>> Adds the MSI-X support and updates driver documentation accordingly.
>>>>>>
>>>>>> Changes the driver parameter in order to allow the interruption type
>>>>>> selection.
>>>>>>
>>>>>> Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
>>>>>> ---
>>>>>>  Documentation/misc-devices/pci-endpoint-test.txt |   3 +
>>>>>>  drivers/misc/pci_endpoint_test.c | 102 
>>>>>> +--
>>>>>>  2 files changed, 79 insertions(+), 26 deletions(-)
>>>>>>
>>>>>> diff --git a/Documentation/misc-devices/pci-endpoint-test.txt 
>>>>>> b/Documentation/misc-devices/pci-endpoint-test.txt
>>>>>> index 4ebc359..fdfa0f6 100644
>>>>>> --- a/Documentation/misc-devices/pci-endpoint-test.txt
>>>>>> +++ b/Documentation/misc-devices/pci-endpoint-test.txt
>>>>>> @@ -10,6 +10,7 @@ The PCI driver for the test device performs the 
>>>>>> following tests
>>>>>>  *) verifying addresses programmed in BAR
>>>>>>  *) raise legacy IRQ
>>>>>>  *) raise MSI IRQ
>>>>>> +*) raise MSI-X IRQ
>>>>>>  *) read data
>>>>>>  *) write data
>>>>>>  *) copy data
>>>>>> @@ -25,6 +26,8 @@ ioctl
>>>>>>   PCITEST_LEGACY_IRQ: Tests legacy IRQ
>>>>>>   PCITEST_MSI: Tests message signalled interrupts. The MSI number
>>>>>>to be tested should be passed as argument.
>>>>>> + PCITEST_MSIX: Tests message signalled interrupts. The MSI-X number
>>>>>> +  to be tested should be passed as argument.
>>>>>>   PCITEST_WRITE: Perform write tests. The size of the buffer should be 
>>>>>> passed
>>>>>>  as argument.
>>>>>>   PCITEST_READ: Perform read tests. The size of the buffer should be 
>>>>>> passed
>>>>>> diff --git a/drivers/misc/pci_endpoint_test.c 
>>>>>> b/drivers/misc/pci_endpoint_test.c
>>>>>> index 37db0fc..a7d9354 100644
>>>>>> --- a/drivers/misc/pci_endpoint_test.c
>>>>>> +++ b/drivers/misc/pci_endpoint_test.c
>>>>>> @@ -42,11 +42,16 @@
>>>>>>  #define PCI_ENDPOINT_TEST_COMMAND   0x4
>>>>>>  #define COMMAND_RAISE_LEGACY_IRQBIT(0)
>>>>>>  #define COMMAND_RAISE_MSI_IRQ   BIT(1)
>>>>>> -#define MSI_NUMBER_SHIFT2
>>>>>> -/* 6 bits for MSI number */
>>>>>> -#define COMMAND_READBIT(8)
>>>>>> -#define COMMAND_WRITE   BIT(9)
>>>>>> -#define COMMAND_COPYBIT(10)
>>>>>> +#define COMMAND_RAISE_MSIX_IRQ  BIT(2)
>>>>>> +#define IRQ_TYPE_SHIFT  3
>>>>>> +#define IRQ_TYPE_LEGACY 0
>>>>>> +#define IRQ_TYPE_MSI1
>>>>>> +#define IRQ_TYPE_MSIX   2
>>>>>> +#define MSI_NUMBER_SHIFT5
>>>>>
>>>>> Now that you are anyways fixing this, add a new register entry for MSI 
>>>>> numbers.
>>>>> Let's not keep COMMAND and MSI's together.
>>>>
>>>> What you suggest?
>>>
>>> #define PCI_ENDPOINT_TEST_COMMAND   0x4
>>> #define COMMAND_RAISE_LEGACY_IRQBIT(0)
>>> #define COMMAND_RAISE_MSI_IRQ   BIT(1)
>>> #define COMMAND_RAISE_MSIX_IRQ  BIT(2)
>>> #define COMMAND_READBIT(3)
>>> #define COMMAND_WRITE   BIT(4)
>>> #define COMMAND_COPYBIT(5)
>>>
>>&g

Re: [PATCH 06/10] misc: pci_endpoint_test: Add MSI-X support

2018-04-30 Thread Gustavo Pimentel
Hi Alan,

On 30/04/2018 16:35, Alan Douglas wrote:
> Hi Gustavo,
> 
> On April 27, 2018, 4:57 p.m. Gustavo Pimentel wrote:
>> Add MSI-X support and update driver documentation accordingly.
>>
>> Add new driver parameter to allow interruption type selection.
>>
>> Modify the Legacy/MSI/MSI-X test process, by:
>>  - Add and use a specific register located in a BAR, which defines the 
>> interrupt
>> type is been triggered.
>>  - Move the interrupt ID number from the command section to a register
>> located in a BAR.
>>
>> Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
>> ---
>>  Documentation/misc-devices/pci-endpoint-test.txt |   3 +
>>  drivers/misc/pci_endpoint_test.c | 121 
>> +++
>>  drivers/pci/endpoint/functions/pci-epf-test.c|  78 +++
>>  3 files changed, 143 insertions(+), 59 deletions(-)
>>
> In testing these changes  I found that pci_epc_raise_irq() also needs to be
> updated in pci-epc-core.c, since it has interrupt_num parameter as u8

Yes, indeed. I updated it together with the pci-epc.h file.
Thanks Alan, well spotted!

Regards,
Gustavo

> 
> Thanks,
> Alan
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 01/10] PCI: dwc: Add MSI-X callbacks handler

2018-04-10 Thread Gustavo Pimentel
Changes the pcie_raise_irq function signature, namely the interrupt_num
variable type from u8 to u16 to accommodate the MSI-X maximum interrupts
of 2048.

Implements a PCIe config space capability iterator function to search and
save the MSI and MSI-X pointers. With this method the code becomes more
generic and flexible.

Implements MSI-X set/get functions for sysfs interface in order to change
the EP entries number.

Implements EP MSI-X interface for triggering interruptions.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
 drivers/pci/dwc/pci-dra7xx.c   |   2 +-
 drivers/pci/dwc/pcie-artpec6.c |   2 +-
 drivers/pci/dwc/pcie-designware-ep.c   | 145 -
 drivers/pci/dwc/pcie-designware-plat.c |   6 +-
 drivers/pci/dwc/pcie-designware.h  |  23 +-
 5 files changed, 173 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
index ed8558d..5265725 100644
--- a/drivers/pci/dwc/pci-dra7xx.c
+++ b/drivers/pci/dwc/pci-dra7xx.c
@@ -369,7 +369,7 @@ static void dra7xx_pcie_raise_msi_irq(struct dra7xx_pcie 
*dra7xx,
 }
 
 static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
-enum pci_epc_irq_type type, u8 interrupt_num)
+enum pci_epc_irq_type type, u16 interrupt_num)
 {
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
diff --git a/drivers/pci/dwc/pcie-artpec6.c b/drivers/pci/dwc/pcie-artpec6.c
index e66cede..96dc259 100644
--- a/drivers/pci/dwc/pcie-artpec6.c
+++ b/drivers/pci/dwc/pcie-artpec6.c
@@ -428,7 +428,7 @@ static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep)
 }
 
 static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
- enum pci_epc_irq_type type, u8 interrupt_num)
+ enum pci_epc_irq_type type, u16 interrupt_num)
 {
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 
diff --git a/drivers/pci/dwc/pcie-designware-ep.c 
b/drivers/pci/dwc/pcie-designware-ep.c
index 15b22a6..874d4c2 100644
--- a/drivers/pci/dwc/pcie-designware-ep.c
+++ b/drivers/pci/dwc/pcie-designware-ep.c
@@ -40,6 +40,44 @@ void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum 
pci_barno bar)
__dw_pcie_ep_reset_bar(pci, bar, 0);
 }
 
+void dw_pcie_ep_find_cap_addr(struct dw_pcie_ep *ep)
+{
+   struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+   u8 next_ptr, curr_ptr, cap_id;
+   u16 reg;
+
+   memset(>cap_addr, 0, sizeof(ep->cap_addr));
+
+   reg = dw_pcie_readw_dbi(pci, PCI_STATUS);
+   if (!(reg & PCI_STATUS_CAP_LIST))
+   return;
+
+   reg = dw_pcie_readw_dbi(pci, PCI_CAPABILITY_LIST);
+   next_ptr = (reg & 0x00ff);
+   if (!next_ptr)
+   return;
+
+   reg = dw_pcie_readw_dbi(pci, next_ptr);
+   curr_ptr = next_ptr;
+   next_ptr = (reg & 0xff00) >> 8;
+   cap_id = (reg & 0x00ff);
+
+   while (next_ptr && (cap_id <= PCI_CAP_ID_MAX)) {
+   switch (cap_id) {
+   case PCI_CAP_ID_MSI:
+   ep->cap_addr.msi_addr = curr_ptr;
+   break;
+   case PCI_CAP_ID_MSIX:
+   ep->cap_addr.msix_addr = curr_ptr;
+   break;
+   }
+   reg = dw_pcie_readw_dbi(pci, next_ptr);
+   curr_ptr = next_ptr;
+   next_ptr = (reg & 0xff00) >> 8;
+   cap_id = (reg & 0x00ff);
+   }
+}
+
 static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no,
   struct pci_epf_header *hdr)
 {
@@ -241,8 +279,47 @@ static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 
func_no, u8 encode_int)
return 0;
 }
 
+static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
+{
+   struct dw_pcie_ep *ep = epc_get_drvdata(epc);
+   struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+   u32 val, reg;
+
+   if (ep->cap_addr.msix_addr == 0)
+   return 0;
+
+   reg = ep->cap_addr.msix_addr + PCI_MSIX_FLAGS;
+   val = dw_pcie_readw_dbi(pci, reg);
+   if (!(val & PCI_MSIX_FLAGS_ENABLE))
+   return -EINVAL;
+
+   val &= PCI_MSIX_FLAGS_QSIZE;
+
+   return val;
+}
+
+static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts)
+{
+   struct dw_pcie_ep *ep = epc_get_drvdata(epc);
+   struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+   u32 val, reg;
+
+   if (ep->cap_addr.msix_addr == 0)
+   return 0;
+
+   reg = ep->cap_addr.msix_addr + PCI_MSIX_FLAGS;
+   val = dw_pcie_readw_dbi(pci, reg);
+   val &= ~PCI_MSIX_FLAGS_QSIZE;
+   val |= interrupts;
+   dw_pcie_dbi_ro_wr_en(pci);
+   dw_pcie_writew_dbi(pci, reg, val);
+   dw_pcie_dbi_ro_wr_di

[RFC 07/10] misc: pci_endpoint_test: Replace lower into upper case characters

2018-04-10 Thread Gustavo Pimentel
Replaces lower into upper case characters in comments and debug printks.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
 drivers/misc/pci_endpoint_test.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index a7d9354..7212a7d 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -259,7 +259,7 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test 
*test, size_t size)
orig_src_addr = dma_alloc_coherent(dev, size + alignment,
   _src_phys_addr, GFP_KERNEL);
if (!orig_src_addr) {
-   dev_err(dev, "failed to allocate source buffer\n");
+   dev_err(dev, "Failed to allocate source buffer\n");
ret = false;
goto err;
}
@@ -285,7 +285,7 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test 
*test, size_t size)
orig_dst_addr = dma_alloc_coherent(dev, size + alignment,
   _dst_phys_addr, GFP_KERNEL);
if (!orig_dst_addr) {
-   dev_err(dev, "failed to allocate destination address\n");
+   dev_err(dev, "Failed to allocate destination address\n");
ret = false;
goto err_orig_src_addr;
}
@@ -349,7 +349,7 @@ static bool pci_endpoint_test_write(struct 
pci_endpoint_test *test, size_t size)
orig_addr = dma_alloc_coherent(dev, size + alignment, _phys_addr,
   GFP_KERNEL);
if (!orig_addr) {
-   dev_err(dev, "failed to allocate address\n");
+   dev_err(dev, "Failed to allocate address\n");
ret = false;
goto err;
}
@@ -412,7 +412,7 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test 
*test, size_t size)
orig_addr = dma_alloc_coherent(dev, size + alignment, _phys_addr,
   GFP_KERNEL);
if (!orig_addr) {
-   dev_err(dev, "failed to allocate destination address\n");
+   dev_err(dev, "Failed to allocate destination address\n");
ret = false;
goto err;
}
@@ -550,7 +550,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
case IRQ_TYPE_MSI:
irq = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI);
if (irq < 0)
-   dev_err(dev, "failed to get MSI interrupts\n");
+   dev_err(dev, "Failed to get MSI interrupts\n");
test->num_irqs = irq;
break;
case IRQ_TYPE_MSIX:
@@ -567,7 +567,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
err = devm_request_irq(dev, pdev->irq, pci_endpoint_test_irqhandler,
   IRQF_SHARED, DRV_MODULE_NAME, test);
if (err) {
-   dev_err(dev, "failed to request IRQ %d\n", pdev->irq);
+   dev_err(dev, "Failed to request IRQ %d\n", pdev->irq);
goto err_disable_msi;
}
 
@@ -585,7 +585,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
base = pci_ioremap_bar(pdev, bar);
if (!base) {
-   dev_err(dev, "failed to read BAR%d\n", bar);
+   dev_err(dev, "Failed to read BAR%d\n", bar);
WARN_ON(bar == test_reg_bar);
}
test->bar[bar] = base;
@@ -605,7 +605,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
id = ida_simple_get(_endpoint_test_ida, 0, 0, GFP_KERNEL);
if (id < 0) {
err = id;
-   dev_err(dev, "unable to get id\n");
+   dev_err(dev, "Unable to get id\n");
goto err_iounmap;
}
 
@@ -621,7 +621,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
 
err = misc_register(misc_device);
if (err) {
-   dev_err(dev, "failed to register device\n");
+   dev_err(dev, "Failed to register device\n");
goto err_kfree_name;
}
 
-- 
2.7.4


--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 05/10] PCI: dwc: Add legacy interrupt callback handler

2018-04-10 Thread Gustavo Pimentel
Adds a legacy interrupt callback handler. Currently Designware IP doesn't
allow triggering the legacy interrupt.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
 drivers/pci/dwc/pcie-designware-ep.c   | 10 ++
 drivers/pci/dwc/pcie-designware-plat.c |  3 +--
 drivers/pci/dwc/pcie-designware.h  |  6 ++
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/dwc/pcie-designware-ep.c 
b/drivers/pci/dwc/pcie-designware-ep.c
index e352786..fb55259 100644
--- a/drivers/pci/dwc/pcie-designware-ep.c
+++ b/drivers/pci/dwc/pcie-designware-ep.c
@@ -375,6 +375,16 @@ static const struct pci_epc_ops epc_ops = {
.stop   = dw_pcie_ep_stop,
 };
 
+int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no)
+{
+   struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+   struct device *dev = pci->dev;
+
+   dev_err(dev, "EP cannot trigger legacy IRQs\n");
+
+   return -EINVAL;
+}
+
 int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 u8 interrupt_num)
 {
diff --git a/drivers/pci/dwc/pcie-designware-plat.c 
b/drivers/pci/dwc/pcie-designware-plat.c
index c3a4707..3874b02 100644
--- a/drivers/pci/dwc/pcie-designware-plat.c
+++ b/drivers/pci/dwc/pcie-designware-plat.c
@@ -86,8 +86,7 @@ static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, 
u8 func_no,
 
switch (type) {
case PCI_EPC_IRQ_LEGACY:
-   dev_err(pci->dev, "EP cannot trigger legacy IRQs\n");
-   return -EINVAL;
+   return dw_pcie_ep_raise_legacy_irq(ep, func_no);
case PCI_EPC_IRQ_MSI:
return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
case PCI_EPC_IRQ_MSIX:
diff --git a/drivers/pci/dwc/pcie-designware.h 
b/drivers/pci/dwc/pcie-designware.h
index 2acf18b0..808b280 100644
--- a/drivers/pci/dwc/pcie-designware.h
+++ b/drivers/pci/dwc/pcie-designware.h
@@ -354,6 +354,7 @@ static inline int dw_pcie_allocate_domains(struct pcie_port 
*pp)
 void dw_pcie_ep_linkup(struct dw_pcie_ep *ep);
 int dw_pcie_ep_init(struct dw_pcie_ep *ep);
 void dw_pcie_ep_exit(struct dw_pcie_ep *ep);
+int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no);
 int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 u8 interrupt_num);
 int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
@@ -374,6 +375,11 @@ static inline void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
 {
 }
 
+static inline int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 
func_no)
+{
+   return 0;
+}
+
 static inline int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
   u8 interrupt_num)
 {
-- 
2.7.4


--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 04/10] PCI: dwc: MSI callbacks handler rework

2018-04-10 Thread Gustavo Pimentel
Adds in pci_epc_set_msi function a maximum number of 32 interrupts
validation.

Removes duplicate defines located on pcie-designware.h file. Uses now
the defines available on /include/uapi/linux/pci-regs.h file.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
 drivers/pci/dwc/pcie-designware-ep.c | 46 +++-
 drivers/pci/dwc/pcie-designware.h| 11 -
 drivers/pci/endpoint/pci-epc-core.c  |  3 ++-
 3 files changed, 32 insertions(+), 28 deletions(-)

diff --git a/drivers/pci/dwc/pcie-designware-ep.c 
b/drivers/pci/dwc/pcie-designware-ep.c
index 874d4c2..e352786 100644
--- a/drivers/pci/dwc/pcie-designware-ep.c
+++ b/drivers/pci/dwc/pcie-designware-ep.c
@@ -251,29 +251,38 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 
func_no,
 
 static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no)
 {
-   int val;
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+   u32 val, reg;
+
+   if (ep->cap_addr.msi_addr == 0)
+   return 0;
 
-   val = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
-   if (!(val & MSI_CAP_MSI_EN_MASK))
+   reg = ep->cap_addr.msi_addr + PCI_MSI_FLAGS;
+   val = dw_pcie_readw_dbi(pci, reg);
+   if (!(val & PCI_MSI_FLAGS_ENABLE))
return -EINVAL;
 
-   val = (val & MSI_CAP_MME_MASK) >> MSI_CAP_MME_SHIFT;
+   val = (val & PCI_MSI_FLAGS_QSIZE) >> 4;
+
return val;
 }
 
-static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 encode_int)
+static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
 {
-   int val;
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+   u32 val, reg;
+
+   if (ep->cap_addr.msi_addr == 0)
+   return 0;
 
-   val = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
-   val &= ~MSI_CAP_MMC_MASK;
-   val |= (encode_int << MSI_CAP_MMC_SHIFT) & MSI_CAP_MMC_MASK;
+   reg = ep->cap_addr.msi_addr + PCI_MSI_FLAGS;
+   val = dw_pcie_readw_dbi(pci, reg);
+   val &= ~PCI_MSI_FLAGS_QMASK;
+   val |= (interrupts << 1) & PCI_MSI_FLAGS_QMASK;
dw_pcie_dbi_ro_wr_en(pci);
-   dw_pcie_writew_dbi(pci, MSI_MESSAGE_CONTROL, val);
+   dw_pcie_writew_dbi(pci, reg, val);
dw_pcie_dbi_ro_wr_dis(pci);
 
return 0;
@@ -372,21 +381,26 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 
func_no,
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
struct pci_epc *epc = ep->epc;
u16 msg_ctrl, msg_data;
-   u32 msg_addr_lower, msg_addr_upper;
+   u32 msg_addr_lower, msg_addr_upper, reg;
u64 msg_addr;
bool has_upper;
int ret;
 
/* Raise MSI per the PCI Local Bus Specification Revision 3.0, 6.8.1. */
-   msg_ctrl = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
+   reg = ep->cap_addr.msi_addr + PCI_MSI_FLAGS;
+   msg_ctrl = dw_pcie_readw_dbi(pci, reg);
has_upper = !!(msg_ctrl & PCI_MSI_FLAGS_64BIT);
-   msg_addr_lower = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_L32);
+   reg = ep->cap_addr.msi_addr + PCI_MSI_ADDRESS_LO;
+   msg_addr_lower = dw_pcie_readl_dbi(pci, reg);
if (has_upper) {
-   msg_addr_upper = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_U32);
-   msg_data = dw_pcie_readw_dbi(pci, MSI_MESSAGE_DATA_64);
+   reg = ep->cap_addr.msi_addr + PCI_MSI_ADDRESS_HI;
+   msg_addr_upper = dw_pcie_readl_dbi(pci, reg);
+   reg = ep->cap_addr.msi_addr + PCI_MSI_DATA_64;
+   msg_data = dw_pcie_readw_dbi(pci, reg);
} else {
msg_addr_upper = 0;
-   msg_data = dw_pcie_readw_dbi(pci, MSI_MESSAGE_DATA_32);
+   reg = ep->cap_addr.msi_addr + PCI_MSI_DATA_32;
+   msg_data = dw_pcie_readw_dbi(pci, reg);
}
msg_addr = ((u64) msg_addr_upper) << 32 | msg_addr_lower;
ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr,
diff --git a/drivers/pci/dwc/pcie-designware.h 
b/drivers/pci/dwc/pcie-designware.h
index 456fd94..2acf18b0 100644
--- a/drivers/pci/dwc/pcie-designware.h
+++ b/drivers/pci/dwc/pcie-designware.h
@@ -96,17 +96,6 @@
 #define PCIE_GET_ATU_INB_UNR_REG_OFFSET(region)
\
((0x3 << 20) | ((region) << 9) | (0x1 << 8))
 
-#define MSI_MESSAGE_CONTROL0x52
-#define MSI_CAP_MMC_SHIFT  1
-#define MSI_CAP_MMC_MASK   (7 << MSI_CAP_MMC_SHIFT)
-#define MSI_CAP_MME_SHIFT  4
-#define MSI_CAP_MSI_EN_MASK0x1
-#define MSI_CAP_MME_MASK   (7 << MSI_CAP_MME_SHIFT)
-#define MSI_MESSAGE_ADDR_L32   0x54
-#define MSI_MESSAGE_ADDR_U32   0x58

[RFC 02/10] PCI: cadence: Update cdns_pcie_ep_raise_irq function signature

2018-04-10 Thread Gustavo Pimentel
Changes the cdns_pcie_ep_raise_irq function signature, namely the
interrupt_num variable type from u8 to u16 to accommodate the MSI-X maximum
interrupts of 2048.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
 drivers/pci/cadence/pcie-cadence-ep.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pci/cadence/pcie-cadence-ep.c 
b/drivers/pci/cadence/pcie-cadence-ep.c
index 3d8283e..6d6322c 100644
--- a/drivers/pci/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/cadence/pcie-cadence-ep.c
@@ -363,7 +363,7 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep 
*ep, u8 fn,
 }
 
 static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
- enum pci_epc_irq_type type, u8 interrupt_num)
+ enum pci_epc_irq_type type, u16 interrupt_num)
 {
struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 
-- 
2.7.4


--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 06/10] misc: pci_endpoint_test: Add MSI-X support

2018-04-10 Thread Gustavo Pimentel
Adds the MSI-X support and updates driver documentation accordingly.

Changes the driver parameter in order to allow the interruption type
selection.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
 Documentation/misc-devices/pci-endpoint-test.txt |   3 +
 drivers/misc/pci_endpoint_test.c | 102 +--
 2 files changed, 79 insertions(+), 26 deletions(-)

diff --git a/Documentation/misc-devices/pci-endpoint-test.txt 
b/Documentation/misc-devices/pci-endpoint-test.txt
index 4ebc359..fdfa0f6 100644
--- a/Documentation/misc-devices/pci-endpoint-test.txt
+++ b/Documentation/misc-devices/pci-endpoint-test.txt
@@ -10,6 +10,7 @@ The PCI driver for the test device performs the following 
tests
*) verifying addresses programmed in BAR
*) raise legacy IRQ
*) raise MSI IRQ
+   *) raise MSI-X IRQ
*) read data
*) write data
*) copy data
@@ -25,6 +26,8 @@ ioctl
  PCITEST_LEGACY_IRQ: Tests legacy IRQ
  PCITEST_MSI: Tests message signalled interrupts. The MSI number
  to be tested should be passed as argument.
+ PCITEST_MSIX: Tests message signalled interrupts. The MSI-X number
+ to be tested should be passed as argument.
  PCITEST_WRITE: Perform write tests. The size of the buffer should be passed
as argument.
  PCITEST_READ: Perform read tests. The size of the buffer should be passed
diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index 37db0fc..a7d9354 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -42,11 +42,16 @@
 #define PCI_ENDPOINT_TEST_COMMAND  0x4
 #define COMMAND_RAISE_LEGACY_IRQ   BIT(0)
 #define COMMAND_RAISE_MSI_IRQ  BIT(1)
-#define MSI_NUMBER_SHIFT   2
-/* 6 bits for MSI number */
-#define COMMAND_READBIT(8)
-#define COMMAND_WRITE   BIT(9)
-#define COMMAND_COPYBIT(10)
+#define COMMAND_RAISE_MSIX_IRQ BIT(2)
+#define IRQ_TYPE_SHIFT 3
+#define IRQ_TYPE_LEGACY0
+#define IRQ_TYPE_MSI   1
+#define IRQ_TYPE_MSIX  2
+#define MSI_NUMBER_SHIFT   5
+/* 12 bits for MSI number */
+#define COMMAND_READBIT(17)
+#define COMMAND_WRITE   BIT(18)
+#define COMMAND_COPYBIT(19)
 
 #define PCI_ENDPOINT_TEST_STATUS   0x8
 #define STATUS_READ_SUCCESS BIT(0)
@@ -73,9 +78,9 @@ static DEFINE_IDA(pci_endpoint_test_ida);
 #define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \
miscdev)
 
-static bool no_msi;
-module_param(no_msi, bool, 0444);
-MODULE_PARM_DESC(no_msi, "Disable MSI interrupt in pci_endpoint_test");
+static int irq_type = IRQ_TYPE_MSIX;
+module_param(irq_type, int, 0444);
+MODULE_PARM_DESC(irq_type, "IRQ mode selection in pci_endpoint_test (0 - 
Legacy, 1 - MSI, 2 - MSI-X)");
 
 enum pci_barno {
BAR_0,
@@ -103,7 +108,7 @@ struct pci_endpoint_test {
 struct pci_endpoint_test_data {
enum pci_barno test_reg_bar;
size_t alignment;
-   bool no_msi;
+   int irq_type;
 };
 
 static inline u32 pci_endpoint_test_readl(struct pci_endpoint_test *test,
@@ -177,10 +182,10 @@ static bool pci_endpoint_test_bar(struct 
pci_endpoint_test *test,
 
 static bool pci_endpoint_test_legacy_irq(struct pci_endpoint_test *test)
 {
-   u32 val;
+   u32 val = COMMAND_RAISE_LEGACY_IRQ;
 
-   pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
-COMMAND_RAISE_LEGACY_IRQ);
+   val |= (IRQ_TYPE_LEGACY << IRQ_TYPE_SHIFT);
+   pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, val);
val = wait_for_completion_timeout(>irq_raised,
  msecs_to_jiffies(1000));
if (!val)
@@ -192,12 +197,12 @@ static bool pci_endpoint_test_legacy_irq(struct 
pci_endpoint_test *test)
 static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test,
  u8 msi_num)
 {
-   u32 val;
+   u32 val = COMMAND_RAISE_MSI_IRQ;
struct pci_dev *pdev = test->pdev;
 
-   pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
-msi_num << MSI_NUMBER_SHIFT |
-COMMAND_RAISE_MSI_IRQ);
+   val |= (msi_num << MSI_NUMBER_SHIFT);
+   val |= (IRQ_TYPE_MSI << IRQ_TYPE_SHIFT);
+   pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, val);
val = wait_for_completion_timeout(>irq_raised,
  msecs_to_jiffies(1000));
if (!val)
@@ -209,6 +214,26 @@ static bool pci_endpoint_test_msi_irq(struct 
pci_endpoint_test *test,
return false;
 }
 
+static boo

[RFC 10/10] tools: PCI: Add MSI-X support

2018-04-10 Thread Gustavo Pimentel
Adds MSI-X support to the pcitest tool and modified the pcitest.sh script
to accomodate this new type of interruption test.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
 include/uapi/linux/pcitest.h |  1 +
 tools/pci/pcitest.c  | 18 +-
 tools/pci/pcitest.sh | 25 +
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/pcitest.h b/include/uapi/linux/pcitest.h
index 953cf03..d746fb1 100644
--- a/include/uapi/linux/pcitest.h
+++ b/include/uapi/linux/pcitest.h
@@ -16,5 +16,6 @@
 #define PCITEST_WRITE  _IOW('P', 0x4, unsigned long)
 #define PCITEST_READ   _IOW('P', 0x5, unsigned long)
 #define PCITEST_COPY   _IOW('P', 0x6, unsigned long)
+#define PCITEST_MSIX   _IOW('P', 0x7, int)
 
 #endif /* __UAPI_LINUX_PCITEST_H */
diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c
index 9074b47..9d145a3 100644
--- a/tools/pci/pcitest.c
+++ b/tools/pci/pcitest.c
@@ -37,6 +37,7 @@ struct pci_test {
charbarnum;
boollegacyirq;
unsigned intmsinum;
+   unsigned intmsixnum;
boolread;
boolwrite;
boolcopy;
@@ -83,6 +84,15 @@ static int run_test(struct pci_test *test)
fprintf(stdout, "%s\n", result[ret]);
}
 
+   if (test->msixnum > 0 && test->msixnum <= 2048) {
+   ret = ioctl(fd, PCITEST_MSIX, test->msixnum);
+   fprintf(stdout, "MSI-X%d:\t\t", test->msixnum);
+   if (ret < 0)
+   fprintf(stdout, "TEST FAILED\n");
+   else
+   fprintf(stdout, "%s\n", result[ret]);
+   }
+
if (test->write) {
ret = ioctl(fd, PCITEST_WRITE, test->size);
fprintf(stdout, "WRITE (%7ld bytes):\t\t", test->size);
@@ -133,7 +143,7 @@ int main(int argc, char **argv)
/* set default endpoint device */
test->device = "/dev/pci-endpoint-test.0";
 
-   while ((c = getopt(argc, argv, "D:b:m:lrwcs:")) != EOF)
+   while ((c = getopt(argc, argv, "D:b:m:x:lrwcs:")) != EOF)
switch (c) {
case 'D':
test->device = optarg;
@@ -151,6 +161,11 @@ int main(int argc, char **argv)
if (test->msinum < 1 || test->msinum > 32)
goto usage;
continue;
+   case 'x':
+   test->msixnum = atoi(optarg);
+   if (test->msixnum < 1 || test->msixnum > 2048)
+   goto usage;
+   continue;
case 'r':
test->read = true;
continue;
@@ -173,6 +188,7 @@ int main(int argc, char **argv)
"\t-D  PCI endpoint test device 
{default: /dev/pci-endpoint-test.0}\n"
"\t-b  BAR test (bar number between 
0..5)\n"
"\t-m  MSI test (msi number between 
1..32)\n"
+   "\t-x MSI-X test (msix number between 
1..2048)\n"
"\t-l   Legacy IRQ test\n"
"\t-r   Read buffer test\n"
"\t-w   Write buffer test\n"
diff --git a/tools/pci/pcitest.sh b/tools/pci/pcitest.sh
index 77e8c85..86709a2 100644
--- a/tools/pci/pcitest.sh
+++ b/tools/pci/pcitest.sh
@@ -4,6 +4,8 @@
 echo "BAR tests"
 echo
 
+modprobe pci_endpoint_test
+sleep 2
 bar=0
 
 while [ $bar -lt 6 ]
@@ -16,7 +18,14 @@ echo
 echo "Interrupt tests"
 echo
 
+rmmod pci_endpoint_test
+sleep 2
+modprobe pci_endpoint_test irq_type=0
 pcitest -l
+
+rmmod pci_endpoint_test
+sleep 2
+modprobe pci_endpoint_test irq_type=1
 msi=1
 
 while [ $msi -lt 33 ]
@@ -26,9 +35,25 @@ do
 done
 echo
 
+rmmod pci_endpoint_test
+sleep 2
+modprobe pci_endpoint_test irq_type=2
+msix=1
+
+while [ $msix -lt 2049 ]
+do
+pcitest -x $msix
+msix=`expr $msix + 1`
+done
+echo
+
 echo "Read Tests"
 echo
 
+rmmod pci_endpoint_test
+sleep 2
+modprobe pci_endpoint_test irq_type=1
+
 pcitest -r -s 1
 pcitest -r -s 1024
 pcitest -r -s 1025
-- 
2.7.4


--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 08/10] PCI: endpoint: functions/pci-epf-test: Add MSI-X support

2018-04-10 Thread Gustavo Pimentel
Adds driver's MSI-X support.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
 drivers/pci/endpoint/functions/pci-epf-test.c | 87 +--
 1 file changed, 69 insertions(+), 18 deletions(-)

diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c 
b/drivers/pci/endpoint/functions/pci-epf-test.c
index 63dca44..5997c6e 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -20,11 +20,18 @@
 
 #define COMMAND_RAISE_LEGACY_IRQ   BIT(0)
 #define COMMAND_RAISE_MSI_IRQ  BIT(1)
-#define MSI_NUMBER_SHIFT   2
+#define COMMAND_RAISE_MSIX_IRQ BIT(2)
+#define IRQ_TYPE_SHIFT 3
+#define MSI_NUMBER_SHIFT   5
+#define IRQ_TYPE_MASK  (0x3 << IRQ_TYPE_SHIFT)
+#define IRQ_TYPE_LEGACY0
+#define IRQ_TYPE_MSI   1
+#define IRQ_TYPE_MSIX  2
 #define MSI_NUMBER_MASK(0x3f << MSI_NUMBER_SHIFT)
-#define COMMAND_READ   BIT(8)
-#define COMMAND_WRITE  BIT(9)
-#define COMMAND_COPY   BIT(10)
+#define MSIX_NUMBER_MASK   (0xfff << MSI_NUMBER_SHIFT)
+#define COMMAND_READ   BIT(17)
+#define COMMAND_WRITE  BIT(18)
+#define COMMAND_COPY   BIT(19)
 
 #define STATUS_READ_SUCCESSBIT(0)
 #define STATUS_READ_FAIL   BIT(1)
@@ -244,31 +251,44 @@ static int pci_epf_test_write(struct pci_epf_test 
*epf_test)
return ret;
 }
 
-static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test, u8 irq)
+static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test, u8 irq_type,
+  u16 irq)
 {
-   u8 msi_count;
struct pci_epf *epf = epf_test->epf;
+   struct device *dev = >dev;
struct pci_epc *epc = epf->epc;
enum pci_barno test_reg_bar = epf_test->test_reg_bar;
struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
 
reg->status |= STATUS_IRQ_RAISED;
-   msi_count = pci_epc_get_msi(epc, epf->func_no);
-   if (irq > msi_count || msi_count <= 0)
-   pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, 0);
-   else
+
+   switch (irq_type) {
+   case IRQ_TYPE_LEGACY:
+   pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, irq);
+   break;
+   case IRQ_TYPE_MSI:
pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI, irq);
+   break;
+   case IRQ_TYPE_MSIX:
+   pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSIX, irq);
+   break;
+   default:
+   dev_err(dev, "Failed to raise IRQ, unknown type\n");
+   break;
+   }
 }
 
 static void pci_epf_test_cmd_handler(struct work_struct *work)
 {
int ret;
-   u8 irq;
-   u8 msi_count;
+   u16 irq;
+   u8 irq_type;
+   u16 msi_count;
u32 command;
struct pci_epf_test *epf_test = container_of(work, struct pci_epf_test,
 cmd_handler.work);
struct pci_epf *epf = epf_test->epf;
+   struct device *dev = >dev;
struct pci_epc *epc = epf->epc;
enum pci_barno test_reg_bar = epf_test->test_reg_bar;
struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
@@ -280,11 +300,25 @@ static void pci_epf_test_cmd_handler(struct work_struct 
*work)
reg->command = 0;
reg->status = 0;
 
-   irq = (command & MSI_NUMBER_MASK) >> MSI_NUMBER_SHIFT;
+   irq_type = (command & IRQ_TYPE_MASK) >> IRQ_TYPE_SHIFT;
+   switch (irq_type) {
+   case IRQ_TYPE_LEGACY:
+   irq = 0;
+   break;
+   case IRQ_TYPE_MSI:
+   irq = (command & MSI_NUMBER_MASK) >> MSI_NUMBER_SHIFT;
+   break;
+   case IRQ_TYPE_MSIX:
+   irq = (command & MSIX_NUMBER_MASK) >> MSI_NUMBER_SHIFT;
+   break;
+   default:
+   dev_err(dev, "Failed to detect IRQ type\n");
+   goto reset_handler;
+   }
 
if (command & COMMAND_RAISE_LEGACY_IRQ) {
reg->status = STATUS_IRQ_RAISED;
-   pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, 0);
+   pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, irq);
goto reset_handler;
}
 
@@ -294,7 +328,7 @@ static void pci_epf_test_cmd_handler(struct work_struct 
*work)
reg->status |= STATUS_WRITE_FAIL;
else
reg->status |= STATUS_WRITE_SUCCESS;
-   pci_epf_test_raise_irq(epf_test, irq);
+   pci_epf_test_raise_irq(epf_test, irq_type, ir

[RFC 09/10] PCI: endpoint: functions/pci-epf-test: Replace lower into upper case characters

2018-04-10 Thread Gustavo Pimentel
Replaces lower into upper case characters in comments and debug printks.

Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
---
 drivers/pci/endpoint/functions/pci-epf-test.c | 26 +-
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c 
b/drivers/pci/endpoint/functions/pci-epf-test.c
index 5997c6e..e3d4af0 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -94,7 +94,7 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
 
src_addr = pci_epc_mem_alloc_addr(epc, _phys_addr, reg->size);
if (!src_addr) {
-   dev_err(dev, "failed to allocate source address\n");
+   dev_err(dev, "Failed to allocate source address\n");
reg->status = STATUS_SRC_ADDR_INVALID;
ret = -ENOMEM;
goto err;
@@ -103,14 +103,14 @@ static int pci_epf_test_copy(struct pci_epf_test 
*epf_test)
ret = pci_epc_map_addr(epc, epf->func_no, src_phys_addr, reg->src_addr,
   reg->size);
if (ret) {
-   dev_err(dev, "failed to map source address\n");
+   dev_err(dev, "Failed to map source address\n");
reg->status = STATUS_SRC_ADDR_INVALID;
goto err_src_addr;
}
 
dst_addr = pci_epc_mem_alloc_addr(epc, _phys_addr, reg->size);
if (!dst_addr) {
-   dev_err(dev, "failed to allocate destination address\n");
+   dev_err(dev, "Failed to allocate destination address\n");
reg->status = STATUS_DST_ADDR_INVALID;
ret = -ENOMEM;
goto err_src_map_addr;
@@ -119,7 +119,7 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
ret = pci_epc_map_addr(epc, epf->func_no, dst_phys_addr, reg->dst_addr,
   reg->size);
if (ret) {
-   dev_err(dev, "failed to map destination address\n");
+   dev_err(dev, "Failed to map destination address\n");
reg->status = STATUS_DST_ADDR_INVALID;
goto err_dst_addr;
}
@@ -156,7 +156,7 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test)
 
src_addr = pci_epc_mem_alloc_addr(epc, _addr, reg->size);
if (!src_addr) {
-   dev_err(dev, "failed to allocate address\n");
+   dev_err(dev, "Failed to allocate address\n");
reg->status = STATUS_SRC_ADDR_INVALID;
ret = -ENOMEM;
goto err;
@@ -165,7 +165,7 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test)
ret = pci_epc_map_addr(epc, epf->func_no, phys_addr, reg->src_addr,
   reg->size);
if (ret) {
-   dev_err(dev, "failed to map address\n");
+   dev_err(dev, "Failed to map address\n");
reg->status = STATUS_SRC_ADDR_INVALID;
goto err_addr;
}
@@ -208,7 +208,7 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
 
dst_addr = pci_epc_mem_alloc_addr(epc, _addr, reg->size);
if (!dst_addr) {
-   dev_err(dev, "failed to allocate address\n");
+   dev_err(dev, "Failed to allocate address\n");
reg->status = STATUS_DST_ADDR_INVALID;
ret = -ENOMEM;
goto err;
@@ -217,7 +217,7 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
ret = pci_epc_map_addr(epc, epf->func_no, phys_addr, reg->dst_addr,
   reg->size);
if (ret) {
-   dev_err(dev, "failed to map address\n");
+   dev_err(dev, "Failed to map address\n");
reg->status = STATUS_DST_ADDR_INVALID;
goto err_addr;
}
@@ -422,7 +422,7 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
ret = pci_epc_set_bar(epc, epf->func_no, epf_bar);
if (ret) {
pci_epf_free_space(epf, epf_test->reg[bar], bar);
-   dev_err(dev, "failed to set BAR%d\n", bar);
+   dev_err(dev, "Failed to set BAR%d\n", bar);
if (bar == test_reg_bar)
return ret;
}
@@ -449,7 +449,7 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
base = pci_epf_alloc_space(epf, sizeof(struct pci_epf_test_reg),
   test_reg_bar);
if (!base) {
-   dev_err(dev, "failed to allocated register space\n");
+   dev_err(dev, "Fail

Re: [RFC 03/10] PCI: endpoint: Add MSI-X interfaces

2018-04-17 Thread Gustavo Pimentel
Hi Kishon,

On 17/04/2018 11:24, Kishon Vijay Abraham I wrote:
> Hi,
> 
> On Tuesday 10 April 2018 10:44 PM, Gustavo Pimentel wrote:
>> Implements the generic method for calling the get/set callbacks.
>>
>> Adds the PCI_EPC_IRQ_MSIX type.
>>
>> Adds the MSI-X callbacks signatures to the ops structure.
>>
>> Adds sysfs interface for altering the number of MSI-X entries.
>>
>> Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
>> ---
>>  drivers/pci/endpoint/pci-ep-cfs.c   | 24 
>>  drivers/pci/endpoint/pci-epc-core.c | 57 
>> +
>>  include/linux/pci-epc.h | 11 ++-
>>  include/linux/pci-epf.h |  1 +
>>  4 files changed, 92 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/pci/endpoint/pci-ep-cfs.c 
>> b/drivers/pci/endpoint/pci-ep-cfs.c
>> index 018ea34..d1288a0 100644
>> --- a/drivers/pci/endpoint/pci-ep-cfs.c
>> +++ b/drivers/pci/endpoint/pci-ep-cfs.c
>> @@ -286,6 +286,28 @@ static ssize_t pci_epf_msi_interrupts_show(struct 
>> config_item *item,
>> to_pci_epf_group(item)->epf->msi_interrupts);
>>  }
>>  
>> +static ssize_t pci_epf_msix_interrupts_store(struct config_item *item,
>> + const char *page, size_t len)
>> +{
>> +u16 val;
>> +int ret;
>> +
>> +ret = kstrtou16(page, 0, );
>> +if (ret)
>> +return ret;
>> +
>> +to_pci_epf_group(item)->epf->msix_interrupts = val;
>> +
>> +return len;
>> +}
>> +
>> +static ssize_t pci_epf_msix_interrupts_show(struct config_item *item,
>> +char *page)
>> +{
>> +return sprintf(page, "%d\n",
>> +   to_pci_epf_group(item)->epf->msix_interrupts);
>> +}
>> +
>>  PCI_EPF_HEADER_R(vendorid)
>>  PCI_EPF_HEADER_W_u16(vendorid)
>>  
>> @@ -327,6 +349,7 @@ CONFIGFS_ATTR(pci_epf_, subsys_vendor_id);
>>  CONFIGFS_ATTR(pci_epf_, subsys_id);
>>  CONFIGFS_ATTR(pci_epf_, interrupt_pin);
>>  CONFIGFS_ATTR(pci_epf_, msi_interrupts);
>> +CONFIGFS_ATTR(pci_epf_, msix_interrupts);
>>  
>>  static struct configfs_attribute *pci_epf_attrs[] = {
>>  _epf_attr_vendorid,
>> @@ -340,6 +363,7 @@ static struct configfs_attribute *pci_epf_attrs[] = {
>>  _epf_attr_subsys_id,
>>  _epf_attr_interrupt_pin,
>>  _epf_attr_msi_interrupts,
>> +_epf_attr_msix_interrupts,
>>  NULL,
>>  };
>>  
>> diff --git a/drivers/pci/endpoint/pci-epc-core.c 
>> b/drivers/pci/endpoint/pci-epc-core.c
>> index b0ee427..294a383 100644
>> --- a/drivers/pci/endpoint/pci-epc-core.c
>> +++ b/drivers/pci/endpoint/pci-epc-core.c
>> @@ -218,6 +218,63 @@ int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 
>> interrupts)
>>  EXPORT_SYMBOL_GPL(pci_epc_set_msi);
>>  
>>  /**
>> + * pci_epc_get_msix() - get the number of MSI-X interrupt numbers allocated
>> + * @epc: the EPC device to which MSI-X interrupts was requested
>> + * @func_no: the endpoint function number in the EPC device
>> + *
>> + * Invoke to get the number of MSI-X interrupts allocated by the RC
>> + */
>> +int pci_epc_get_msix(struct pci_epc *epc, u8 func_no)
>> +{
>> +int interrupt;
>> +unsigned long flags;
>> +
>> +if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
>> +return 0;
>> +
>> +if (!epc->ops->get_msix)
>> +return 0;
>> +
>> +spin_lock_irqsave(>lock, flags);
>> +interrupt = epc->ops->get_msix(epc, func_no);
>> +spin_unlock_irqrestore(>lock, flags);
>> +
>> +if (interrupt < 0)
>> +return 0;
>> +
>> +return interrupt++;
> 
> return interrupt + 1?

I'll change it.

>> +}
>> +EXPORT_SYMBOL_GPL(pci_epc_get_msix);
>> +
>> +/**
>> + * pci_epc_set_msix() - set the number of MSI-X interrupt numbers required
>> + * @epc: the EPC device on which MSI-X has to be configured
>> + * @func_no: the endpoint function number in the EPC device
>> + * @interrupts: number of MSI-X interrupts required by the EPF
>> + *
>> + * Invoke to set the required number of MSI-X interrupts.
>> + */
>> +int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts)
>> +{
>> +int ret;
>> +unsigned long flags;
>> +
>> +if (IS_ERR_OR_NULL(

Re: [RFC 10/10] tools: PCI: Add MSI-X support

2018-04-24 Thread Gustavo Pimentel
Hi Alan,

On 24/04/2018 10:57, Alan Douglas wrote:
> Hi Gustavo,
> 
> On 10 April 2018 18:15, Gustavo Pimentel wrote:
>> Adds MSI-X support to the pcitest tool and modified the pcitest.sh script to
>> accomodate this new type of interruption test.
>>
>> Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
>> ---
>>  include/uapi/linux/pcitest.h |  1 +
>>  tools/pci/pcitest.c  | 18 +-
>>  tools/pci/pcitest.sh | 25 +
>>  3 files changed, 43 insertions(+), 1 deletion(-)
> I found some possible problems when testing with the Cadence EP driver.  The 
> problem
> is that pcitest uses the BARs for tests, but we also use one for the MSI-X 
> tables
> 
> In Cadence core the MSI-X table is in BAR0 by default, but this is configured 
> to a size
> of 0x80 in the test driver, since it is used as the test_reg_bar.  So, I 
> changed the 
> configuration to use BAR4 instead, which is configured to a size of 131072 
> in pci-efp-test.c, and this gives me enough space.
> 
> However, if I run the BAR tests in pcitest before running the MSI-X tests, the
> MSI-X tests fail, since the BAR content is overwritten.  It's not a problem 
> with the 
> scenario in pcitest.sh, but it would be if the module wasn't re-loaded.
> 
> So, wondering if we need to come up with some mechanism to specify that a 
> specific
> BAR will be used for MSI-X, and that its size and content shouldn't be 
> modified by
> pcitest?

I see your point. I have bypassed the problem by doing the module load/unload
(to avoid having to fight on multiple fronts).

I like your suggestion. Maybe we could have a bool variable for each BARs that
could be set to false if a resource have intent to use it.

However this change must be accepted by Kishon.

> 
> Regards,
> Alan
> 
Regards,
Gustavo

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 01/10] PCI: dwc: Add MSI-X callbacks handler

2018-04-23 Thread Gustavo Pimentel
Hi Kishon,

On 16/04/2018 10:29, Kishon Vijay Abraham I wrote:
> Hi Gustavo,
> 
> On Tuesday 10 April 2018 10:44 PM, Gustavo Pimentel wrote:
>> Changes the pcie_raise_irq function signature, namely the interrupt_num
>> variable type from u8 to u16 to accommodate the MSI-X maximum interrupts
>> of 2048.
>>
>> Implements a PCIe config space capability iterator function to search and
>> save the MSI and MSI-X pointers. With this method the code becomes more
>> generic and flexible.
>>
>> Implements MSI-X set/get functions for sysfs interface in order to change
>> the EP entries number.
>>
>> Implements EP MSI-X interface for triggering interruptions.
>>
>> Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
>> ---
>>  drivers/pci/dwc/pci-dra7xx.c   |   2 +-
>>  drivers/pci/dwc/pcie-artpec6.c |   2 +-
>>  drivers/pci/dwc/pcie-designware-ep.c   | 145 
>> -
>>  drivers/pci/dwc/pcie-designware-plat.c |   6 +-
>>  drivers/pci/dwc/pcie-designware.h  |  23 +-
>>  5 files changed, 173 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
>> index ed8558d..5265725 100644
>> --- a/drivers/pci/dwc/pci-dra7xx.c
>> +++ b/drivers/pci/dwc/pci-dra7xx.c
>> @@ -369,7 +369,7 @@ static void dra7xx_pcie_raise_msi_irq(struct dra7xx_pcie 
>> *dra7xx,
>>  }
>>  
>>  static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
>> - enum pci_epc_irq_type type, u8 interrupt_num)
>> + enum pci_epc_irq_type type, u16 interrupt_num)
>>  {
>>  struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>>  struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
>> diff --git a/drivers/pci/dwc/pcie-artpec6.c b/drivers/pci/dwc/pcie-artpec6.c
>> index e66cede..96dc259 100644
>> --- a/drivers/pci/dwc/pcie-artpec6.c
>> +++ b/drivers/pci/dwc/pcie-artpec6.c
>> @@ -428,7 +428,7 @@ static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep)
>>  }
>>  
>>  static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
>> -  enum pci_epc_irq_type type, u8 interrupt_num)
>> +  enum pci_epc_irq_type type, u16 interrupt_num)
>>  {
>>  struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>>  
>> diff --git a/drivers/pci/dwc/pcie-designware-ep.c 
>> b/drivers/pci/dwc/pcie-designware-ep.c
>> index 15b22a6..874d4c2 100644
>> --- a/drivers/pci/dwc/pcie-designware-ep.c
>> +++ b/drivers/pci/dwc/pcie-designware-ep.c
>> @@ -40,6 +40,44 @@ void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum 
>> pci_barno bar)
>>  __dw_pcie_ep_reset_bar(pci, bar, 0);
>>  }
>>  
>> +void dw_pcie_ep_find_cap_addr(struct dw_pcie_ep *ep)
>> +{
> 
> This should be implemented in a generic way similar to pci_find_capability().
> It'll be useful when we try to implement other capabilities as well.

Hum, what you suggest? Something implemented on the pci-epf-core?

> 
> Thanks
> Kishon
> 

Regards,
Gustavo

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 06/10] misc: pci_endpoint_test: Add MSI-X support

2018-04-24 Thread Gustavo Pimentel
Hi Kishon,

On 24/04/2018 08:19, Kishon Vijay Abraham I wrote:
> Hi,
> 
> On Tuesday 17 April 2018 11:08 PM, Gustavo Pimentel wrote:
>> Hi Kishon,
>>
>> On 17/04/2018 11:33, Kishon Vijay Abraham I wrote:
>>> Hi,
>>>
>>> On Tuesday 10 April 2018 10:44 PM, Gustavo Pimentel wrote:
>>>> Adds the MSI-X support and updates driver documentation accordingly.
>>>>
>>>> Changes the driver parameter in order to allow the interruption type
>>>> selection.
>>>>
>>>> Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
>>>> ---
>>>>  Documentation/misc-devices/pci-endpoint-test.txt |   3 +
>>>>  drivers/misc/pci_endpoint_test.c | 102 
>>>> +--
>>>>  2 files changed, 79 insertions(+), 26 deletions(-)
>>>>
>>>> diff --git a/Documentation/misc-devices/pci-endpoint-test.txt 
>>>> b/Documentation/misc-devices/pci-endpoint-test.txt
>>>> index 4ebc359..fdfa0f6 100644
>>>> --- a/Documentation/misc-devices/pci-endpoint-test.txt
>>>> +++ b/Documentation/misc-devices/pci-endpoint-test.txt
>>>> @@ -10,6 +10,7 @@ The PCI driver for the test device performs the 
>>>> following tests
>>>>*) verifying addresses programmed in BAR
>>>>*) raise legacy IRQ
>>>>*) raise MSI IRQ
>>>> +  *) raise MSI-X IRQ
>>>>*) read data
>>>>*) write data
>>>>*) copy data
>>>> @@ -25,6 +26,8 @@ ioctl
>>>>   PCITEST_LEGACY_IRQ: Tests legacy IRQ
>>>>   PCITEST_MSI: Tests message signalled interrupts. The MSI number
>>>>  to be tested should be passed as argument.
>>>> + PCITEST_MSIX: Tests message signalled interrupts. The MSI-X number
>>>> +to be tested should be passed as argument.
>>>>   PCITEST_WRITE: Perform write tests. The size of the buffer should be 
>>>> passed
>>>>as argument.
>>>>   PCITEST_READ: Perform read tests. The size of the buffer should be passed
>>>> diff --git a/drivers/misc/pci_endpoint_test.c 
>>>> b/drivers/misc/pci_endpoint_test.c
>>>> index 37db0fc..a7d9354 100644
>>>> --- a/drivers/misc/pci_endpoint_test.c
>>>> +++ b/drivers/misc/pci_endpoint_test.c
>>>> @@ -42,11 +42,16 @@
>>>>  #define PCI_ENDPOINT_TEST_COMMAND 0x4
>>>>  #define COMMAND_RAISE_LEGACY_IRQ  BIT(0)
>>>>  #define COMMAND_RAISE_MSI_IRQ BIT(1)
>>>> -#define MSI_NUMBER_SHIFT  2
>>>> -/* 6 bits for MSI number */
>>>> -#define COMMAND_READBIT(8)
>>>> -#define COMMAND_WRITE   BIT(9)
>>>> -#define COMMAND_COPYBIT(10)
>>>> +#define COMMAND_RAISE_MSIX_IRQBIT(2)
>>>> +#define IRQ_TYPE_SHIFT3
>>>> +#define IRQ_TYPE_LEGACY   0
>>>> +#define IRQ_TYPE_MSI  1
>>>> +#define IRQ_TYPE_MSIX 2
>>>> +#define MSI_NUMBER_SHIFT  5
>>>
>>> Now that you are anyways fixing this, add a new register entry for MSI 
>>> numbers.
>>> Let's not keep COMMAND and MSI's together.
>>
>> What you suggest?
> 
> #define PCI_ENDPOINT_TEST_COMMAND 0x4
> #define COMMAND_RAISE_LEGACY_IRQ  BIT(0)
> #define COMMAND_RAISE_MSI_IRQ BIT(1)
> #define COMMAND_RAISE_MSIX_IRQBIT(2)
> #define COMMAND_READBIT(3)
> #define COMMAND_WRITE   BIT(4)
> #define COMMAND_COPYBIT(5)
> 
> #define PCI_ENDPOINT_TEST_STATUS  0x8
> #define STATUS_READ_SUCCESS BIT(0)
> #define STATUS_READ_FAILBIT(1)
> #define STATUS_WRITE_SUCCESSBIT(2)
> #define STATUS_WRITE_FAIL   BIT(3)
> #define STATUS_COPY_SUCCESS BIT(4)
> #define STATUS_COPY_FAILBIT(5)
> #define STATUS_IRQ_RAISED   BIT(6)
> #define STATUS_SRC_ADDR_INVALID BIT(7)
> #define STATUS_DST_ADDR_INVALID BIT(8)
> 
> #define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR  0xc
> #define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR  0x10
> 
> #define PCI_ENDPOINT_TEST_LOWER_DST_ADDR  0x14
> #define PCI_ENDPOINT_TEST_UPPER_DST_ADDR  0x18
> 
> #define PCI_ENDPOINT_TEST_SIZE0x1c
> #define PCI_ENDPOINT_TEST_CHECKSUM0x20
> 
> #define PCI_END

Re: [RFC 01/10] PCI: dwc: Add MSI-X callbacks handler

2018-04-24 Thread Gustavo Pimentel
Hi Kishon,

On 24/04/2018 08:07, Kishon Vijay Abraham I wrote:
> Hi,
> 
> On Monday 23 April 2018 03:06 PM, Gustavo Pimentel wrote:
>> Hi Kishon,
>>
>> On 16/04/2018 10:29, Kishon Vijay Abraham I wrote:
>>> Hi Gustavo,
>>>
>>> On Tuesday 10 April 2018 10:44 PM, Gustavo Pimentel wrote:
>>>> Changes the pcie_raise_irq function signature, namely the interrupt_num
>>>> variable type from u8 to u16 to accommodate the MSI-X maximum interrupts
>>>> of 2048.
>>>>
>>>> Implements a PCIe config space capability iterator function to search and
>>>> save the MSI and MSI-X pointers. With this method the code becomes more
>>>> generic and flexible.
>>>>
>>>> Implements MSI-X set/get functions for sysfs interface in order to change
>>>> the EP entries number.
>>>>
>>>> Implements EP MSI-X interface for triggering interruptions.
>>>>
>>>> Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
>>>> ---
>>>>  drivers/pci/dwc/pci-dra7xx.c   |   2 +-
>>>>  drivers/pci/dwc/pcie-artpec6.c |   2 +-
>>>>  drivers/pci/dwc/pcie-designware-ep.c   | 145 
>>>> -
>>>>  drivers/pci/dwc/pcie-designware-plat.c |   6 +-
>>>>  drivers/pci/dwc/pcie-designware.h  |  23 +-
>>>>  5 files changed, 173 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
>>>> index ed8558d..5265725 100644
>>>> --- a/drivers/pci/dwc/pci-dra7xx.c
>>>> +++ b/drivers/pci/dwc/pci-dra7xx.c
>>>> @@ -369,7 +369,7 @@ static void dra7xx_pcie_raise_msi_irq(struct 
>>>> dra7xx_pcie *dra7xx,
>>>>  }
>>>>  
>>>>  static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
>>>> -   enum pci_epc_irq_type type, u8 interrupt_num)
>>>> +   enum pci_epc_irq_type type, u16 interrupt_num)
>>>>  {
>>>>struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>>>>struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
>>>> diff --git a/drivers/pci/dwc/pcie-artpec6.c 
>>>> b/drivers/pci/dwc/pcie-artpec6.c
>>>> index e66cede..96dc259 100644
>>>> --- a/drivers/pci/dwc/pcie-artpec6.c
>>>> +++ b/drivers/pci/dwc/pcie-artpec6.c
>>>> @@ -428,7 +428,7 @@ static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep)
>>>>  }
>>>>  
>>>>  static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
>>>> -enum pci_epc_irq_type type, u8 interrupt_num)
>>>> +enum pci_epc_irq_type type, u16 interrupt_num)
>>>>  {
>>>>struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>>>>  
>>>> diff --git a/drivers/pci/dwc/pcie-designware-ep.c 
>>>> b/drivers/pci/dwc/pcie-designware-ep.c
>>>> index 15b22a6..874d4c2 100644
>>>> --- a/drivers/pci/dwc/pcie-designware-ep.c
>>>> +++ b/drivers/pci/dwc/pcie-designware-ep.c
>>>> @@ -40,6 +40,44 @@ void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum 
>>>> pci_barno bar)
>>>>__dw_pcie_ep_reset_bar(pci, bar, 0);
>>>>  }
>>>>  
>>>> +void dw_pcie_ep_find_cap_addr(struct dw_pcie_ep *ep)
>>>> +{
>>>
>>> This should be implemented in a generic way similar to 
>>> pci_find_capability().
>>> It'll be useful when we try to implement other capabilities as well.
>>
>> Hum, what you suggest? Something implemented on the pci-epf-core?
> 
> yeah, Initially thought it could be implemented as a helper function in
> pci-epc-core so that both designware and cadence can use it.

That would be nice, however I couldn't find out how to access the config space,
through the pci_epf or pci_epc structs.

So, I reworked the functions like this:

(on pcie-designware-ep.c)

u8 __dw_pcie_ep_find_next_cap(struct dw_pcie *pci, u8 cap_ptr,
  u8 cap)
{
u8 cap_id, next_cap_ptr;
u16 reg;

reg = dw_pcie_readw_dbi(pci, cap_ptr);
next_cap_ptr = (reg & 0xff00) >> 8;
cap_id = (reg & 0x00ff);

if (!next_cap_ptr || cap_id > PCI_CAP_ID_MAX)
return 0;

if (cap_id == cap)
return cap_ptr;

return __dw_pcie_ep_find_next_cap(pci, next_cap_ptr, cap);
}

u8 dw_pcie_ep_find_capability(struct dw_pcie *pci,

Re: [RFC 00/10] Adds pcitest tool support for MSI-X

2018-04-24 Thread Gustavo Pimentel
Hi Alan,

On 24/04/2018 07:48, Alan Douglas wrote:
> Hi Gustavo,
> 
> On 10 April 2018 18:15 Gustavo Pimentel wrote:
>> This patch set depends the following series:
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__lkml.org_lkml_2018_4_10_421=DwIFAg=DPL6_X_6JkXFx7AXWqB0tg=bkWxpLoW-f-E3EdiDCCa0_h0PicsViasSlvIpzZvPxs=R3h7a4AkN9--FFv6jtHaknKIzx6NieDdkYxyCe4obB8=J2A11L2_WwzMdaBheYSTwfjPDA7sx3_DyoGPAYsJ9A4=>
>>  This series aims to add pcitest tool support for MSI-X.
>>
>> Includes new callbacks methods and handlers to trigger the MSI-X
>> interruptions on the EP Designware IP driver.
>>
>> Provides new methods on pci_epf_test driver that allows to set/get EP
>> maximum number of MSI-X entries (similar to set/get MSI methods).
>>
>> Reworks on MSI set/get and triggering methods on EP Designware IP driver to
>> be more generic and flexible.
>>
>> Adds a new input parameter (msix) and replicates the whole MSI mechanism
>> applied to the MSI-X feature on pcitest tool. Also updates the pcitest script
>> with the new test set applied to this new feature.
>>
>> Gustavo Pimentel (10):
>>   PCI: dwc: Add MSI-X callbacks handler
>>   PCI: cadence: Update cdns_pcie_ep_raise_irq function signature
>>   PCI: endpoint: Add MSI-X interfaces
>>   PCI: dwc: MSI callbacks handler rework
>>   PCI: dwc: Add legacy interrupt callback handler
>>   misc: pci_endpoint_test: Add MSI-X support
>>   misc: pci_endpoint_test: Replace lower into upper case characters
>>   PCI: endpoint: functions/pci-epf-test: Add MSI-X support
>>   PCI: endpoint: functions/pci-epf-test: Replace lower into upper case
>> characters
>>   tools: PCI: Add MSI-X support
>>
>>  Documentation/misc-devices/pci-endpoint-test.txt |   3 +
>>  drivers/misc/pci_endpoint_test.c | 120 ++
>>  drivers/pci/cadence/pcie-cadence-ep.c|   2 +-
>>  drivers/pci/dwc/pci-dra7xx.c |   2 +-
>>  drivers/pci/dwc/pcie-artpec6.c   |   2 +-
>>  drivers/pci/dwc/pcie-designware-ep.c | 201
>> +--
>>  drivers/pci/dwc/pcie-designware-plat.c   |   9 +-
>>  drivers/pci/dwc/pcie-designware.h|  40 +++--
>>  drivers/pci/endpoint/functions/pci-epf-test.c| 113 +
>>  drivers/pci/endpoint/pci-ep-cfs.c|  24 +++
>>  drivers/pci/endpoint/pci-epc-core.c  |  60 ++-
>>  include/linux/pci-epc.h  |  11 +-
>>  include/linux/pci-epf.h  |   1 +
>>  include/uapi/linux/pcitest.h |   1 +
>>  tools/pci/pcitest.c  |  18 +-
>>  tools/pci/pcitest.sh |  25 +++
>>  16 files changed, 528 insertions(+), 104 deletions(-)
>>
>> --
>> 2.7.4
>>
> Nice set of patches.  I have tested this with the Cadence EP driver after 
> adding MSI-X support, and found a few changes required.
> I will send you comments.

Ok, great news!

Maybe after this patch series submission we could start a new thread about new
features that could be tested/verified using pcitest. I think this could be
helpful for everybody.

> 
> Thanks,
> Alan
> 

Thanks,
Gustavo

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 06/10] misc: pci_endpoint_test: Add MSI-X support

2018-04-24 Thread Gustavo Pimentel
Hi Alan,

On 24/04/2018 07:59, Alan Douglas wrote:
> Hi Gustavo,
> 
> On 10 April 2018 18:15 Gustavo Pimentel wrote:
>>
>> Adds the MSI-X support and updates driver documentation accordingly.
>>
>> Changes the driver parameter in order to allow the interruption type
>> selection.
>>
>> Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
>> ---
>>  Documentation/misc-devices/pci-endpoint-test.txt |   3 +
>>  drivers/misc/pci_endpoint_test.c | 102 
>> +--
>>  2 files changed, 79 insertions(+), 26 deletions(-)
>>
>> diff --git a/Documentation/misc-devices/pci-endpoint-test.txt
>> b/Documentation/misc-devices/pci-endpoint-test.txt
>> index 4ebc359..fdfa0f6 100644
>> --- a/Documentation/misc-devices/pci-endpoint-test.txt
>> +++ b/Documentation/misc-devices/pci-endpoint-test.txt
>> @@ -10,6 +10,7 @@ The PCI driver for the test device performs the
>> following tests
>>  *) verifying addresses programmed in BAR
>>  *) raise legacy IRQ
>>  *) raise MSI IRQ
>> +*) raise MSI-X IRQ
>>  *) read data
>>  *) write data
>>  *) copy data
>> @@ -25,6 +26,8 @@ ioctl
>>   PCITEST_LEGACY_IRQ: Tests legacy IRQ
>>   PCITEST_MSI: Tests message signalled interrupts. The MSI number
>>to be tested should be passed as argument.
>> + PCITEST_MSIX: Tests message signalled interrupts. The MSI-X number
>> +  to be tested should be passed as argument.
>>   PCITEST_WRITE: Perform write tests. The size of the buffer should be passed
>>  as argument.
>>   PCITEST_READ: Perform read tests. The size of the buffer should be passed
>> diff --git a/drivers/misc/pci_endpoint_test.c
>> b/drivers/misc/pci_endpoint_test.c
>> index 37db0fc..a7d9354 100644
>> --- a/drivers/misc/pci_endpoint_test.c
>> +++ b/drivers/misc/pci_endpoint_test.c
>> @@ -42,11 +42,16 @@
>>  #define PCI_ENDPOINT_TEST_COMMAND   0x4
>>  #define COMMAND_RAISE_LEGACY_IRQBIT(0)
>>  #define COMMAND_RAISE_MSI_IRQ   BIT(1)
>> -#define MSI_NUMBER_SHIFT2
>> -/* 6 bits for MSI number */
>> -#define COMMAND_READBIT(8)
>> -#define COMMAND_WRITE   BIT(9)
>> -#define COMMAND_COPYBIT(10)
>> +#define COMMAND_RAISE_MSIX_IRQ  BIT(2)
>> +#define IRQ_TYPE_SHIFT  3
>> +#define IRQ_TYPE_LEGACY 0
>> +#define IRQ_TYPE_MSI1
>> +#define IRQ_TYPE_MSIX   2
>> +#define MSI_NUMBER_SHIFT5
>> +/* 12 bits for MSI number */
>> +#define COMMAND_READBIT(17)
>> +#define COMMAND_WRITE   BIT(18)
>> +#define COMMAND_COPYBIT(19)
>>
>>  #define PCI_ENDPOINT_TEST_STATUS0x8
>>  #define STATUS_READ_SUCCESS BIT(0)
>> @@ -73,9 +78,9 @@ static DEFINE_IDA(pci_endpoint_test_ida);
>>  #define to_endpoint_test(priv) container_of((priv), struct 
>> pci_endpoint_test,
>> \
>>  miscdev)
>>
>> -static bool no_msi;
>> -module_param(no_msi, bool, 0444);
>> -MODULE_PARM_DESC(no_msi, "Disable MSI interrupt in
>> pci_endpoint_test");
>> +static int irq_type = IRQ_TYPE_MSIX;
>> +module_param(irq_type, int, 0444);
>> +MODULE_PARM_DESC(irq_type, "IRQ mode selection in pci_endpoint_test
>> (0
>> +- Legacy, 1 - MSI, 2 - MSI-X)");
>>
>>  enum pci_barno {
>>  BAR_0,
>> @@ -103,7 +108,7 @@ struct pci_endpoint_test {  struct
>> pci_endpoint_test_data {
>>  enum pci_barno test_reg_bar;
>>  size_t alignment;
>> -bool no_msi;
>> +int irq_type;
>>  };
>>
>>  static inline u32 pci_endpoint_test_readl(struct pci_endpoint_test *test,
>> @@ -177,10 +182,10 @@ static bool pci_endpoint_test_bar(struct
>> pci_endpoint_test *test,
>>
>>  static bool pci_endpoint_test_legacy_irq(struct pci_endpoint_test *test)  {
>> -u32 val;
>> +u32 val = COMMAND_RAISE_LEGACY_IRQ;
>>
>> -pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
>> - COMMAND_RAISE_LEGACY_IRQ);
>> +val |= (IRQ_TYPE_LEGACY << IRQ_TYPE_SHIFT);
>> +pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, val);
>>  val = wait_for_completion_timeout(>irq_raised,
>>msecs_to_jiffies(1000));
>>  if (!val)
>> @@ -192,

Re: [RFC 01/10] PCI: dwc: Add MSI-X callbacks handler

2018-04-24 Thread Gustavo Pimentel
On 24/04/2018 10:15, Alan Douglas wrote:
> Hi,
> 
> On 10 April 2018 18:15 Gustavo Pimentel wrote:
>> Changes the pcie_raise_irq function signature, namely the interrupt_num
>> variable type from u8 to u16 to accommodate the MSI-X maximum interrupts
>> of 2048.
>>
>> Implements a PCIe config space capability iterator function to search and 
>> save
>> the MSI and MSI-X pointers. With this method the code becomes more
>> generic and flexible.
>>
>> Implements MSI-X set/get functions for sysfs interface in order to change the
>> EP entries number.
>>
>> Implements EP MSI-X interface for triggering interruptions.
>>
>> Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
>> ---
>>  drivers/pci/dwc/pci-dra7xx.c   |   2 +-
>>  drivers/pci/dwc/pcie-artpec6.c |   2 +-
>>  drivers/pci/dwc/pcie-designware-ep.c   | 145
>> -
>>  drivers/pci/dwc/pcie-designware-plat.c |   6 +-
>>  drivers/pci/dwc/pcie-designware.h  |  23 +-
>>  5 files changed, 173 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c 
>> index
>> ed8558d..5265725 100644
>> --- a/drivers/pci/dwc/pci-dra7xx.c
>> +++ b/drivers/pci/dwc/pci-dra7xx.c
>> @@ -369,7 +369,7 @@ static void dra7xx_pcie_raise_msi_irq(struct
>> dra7xx_pcie *dra7xx,  }
>>
>>  static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
>> - enum pci_epc_irq_type type, u8
>> interrupt_num)
>> + enum pci_epc_irq_type type, u16
>> interrupt_num)
>>  {
>>  struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>>  struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci); diff --git
>> a/drivers/pci/dwc/pcie-artpec6.c b/drivers/pci/dwc/pcie-artpec6.c index
>> e66cede..96dc259 100644
>> --- a/drivers/pci/dwc/pcie-artpec6.c
>> +++ b/drivers/pci/dwc/pcie-artpec6.c
>> @@ -428,7 +428,7 @@ static void artpec6_pcie_ep_init(struct dw_pcie_ep
>> *ep)  }
>>
>>  static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
>> -  enum pci_epc_irq_type type, u8
>> interrupt_num)
>> +  enum pci_epc_irq_type type, u16
>> interrupt_num)
>>  {
>>  struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>>
>> diff --git a/drivers/pci/dwc/pcie-designware-ep.c b/drivers/pci/dwc/pcie-
>> designware-ep.c
>> index 15b22a6..874d4c2 100644
>> --- a/drivers/pci/dwc/pcie-designware-ep.c
>> +++ b/drivers/pci/dwc/pcie-designware-ep.c
>> @@ -40,6 +40,44 @@ void dw_pcie_ep_reset_bar(struct dw_pcie *pci,
>> enum pci_barno bar)
>>  __dw_pcie_ep_reset_bar(pci, bar, 0);
>>  }
>>
>> +void dw_pcie_ep_find_cap_addr(struct dw_pcie_ep *ep) {
>> +struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>> +u8 next_ptr, curr_ptr, cap_id;
>> +u16 reg;
>> +
>> +memset(>cap_addr, 0, sizeof(ep->cap_addr));
>> +
>> +reg = dw_pcie_readw_dbi(pci, PCI_STATUS);
>> +if (!(reg & PCI_STATUS_CAP_LIST))
>> +return;
>> +
>> +reg = dw_pcie_readw_dbi(pci, PCI_CAPABILITY_LIST);
>> +next_ptr = (reg & 0x00ff);
>> +if (!next_ptr)
>> +return;
>> +
>> +reg = dw_pcie_readw_dbi(pci, next_ptr);
>> +curr_ptr = next_ptr;
>> +next_ptr = (reg & 0xff00) >> 8;
>> +cap_id = (reg & 0x00ff);
>> +
>> +while (next_ptr && (cap_id <= PCI_CAP_ID_MAX)) {
>> +switch (cap_id) {
>> +case PCI_CAP_ID_MSI:
>> +ep->cap_addr.msi_addr = curr_ptr;
>> +break;
>> +case PCI_CAP_ID_MSIX:
>> +ep->cap_addr.msix_addr = curr_ptr;
>> +break;
>> +}
>> +reg = dw_pcie_readw_dbi(pci, next_ptr);
>> +curr_ptr = next_ptr;
>> +next_ptr = (reg & 0xff00) >> 8;
>> +cap_id = (reg & 0x00ff);
>> +}
>> +}
>> +
>>  static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no,
>> struct pci_epf_header *hdr)
>>  {
>> @@ -241,8 +279,47 @@ static int dw_pcie_ep_set_msi(struct pci_epc *epc,
>> u8 func_no, u8 encode_int)
>>  return 0;
>>  }
>>
>> +static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no) {
>> +struct dw_pcie_ep *ep = epc_get_drvdat

Re: [RFC 06/10] misc: pci_endpoint_test: Add MSI-X support

2018-04-17 Thread Gustavo Pimentel
Hi Kishon,

On 17/04/2018 11:33, Kishon Vijay Abraham I wrote:
> Hi,
> 
> On Tuesday 10 April 2018 10:44 PM, Gustavo Pimentel wrote:
>> Adds the MSI-X support and updates driver documentation accordingly.
>>
>> Changes the driver parameter in order to allow the interruption type
>> selection.
>>
>> Signed-off-by: Gustavo Pimentel <gustavo.pimen...@synopsys.com>
>> ---
>>  Documentation/misc-devices/pci-endpoint-test.txt |   3 +
>>  drivers/misc/pci_endpoint_test.c | 102 
>> +--
>>  2 files changed, 79 insertions(+), 26 deletions(-)
>>
>> diff --git a/Documentation/misc-devices/pci-endpoint-test.txt 
>> b/Documentation/misc-devices/pci-endpoint-test.txt
>> index 4ebc359..fdfa0f6 100644
>> --- a/Documentation/misc-devices/pci-endpoint-test.txt
>> +++ b/Documentation/misc-devices/pci-endpoint-test.txt
>> @@ -10,6 +10,7 @@ The PCI driver for the test device performs the following 
>> tests
>>  *) verifying addresses programmed in BAR
>>  *) raise legacy IRQ
>>  *) raise MSI IRQ
>> +*) raise MSI-X IRQ
>>  *) read data
>>  *) write data
>>  *) copy data
>> @@ -25,6 +26,8 @@ ioctl
>>   PCITEST_LEGACY_IRQ: Tests legacy IRQ
>>   PCITEST_MSI: Tests message signalled interrupts. The MSI number
>>to be tested should be passed as argument.
>> + PCITEST_MSIX: Tests message signalled interrupts. The MSI-X number
>> +  to be tested should be passed as argument.
>>   PCITEST_WRITE: Perform write tests. The size of the buffer should be passed
>>  as argument.
>>   PCITEST_READ: Perform read tests. The size of the buffer should be passed
>> diff --git a/drivers/misc/pci_endpoint_test.c 
>> b/drivers/misc/pci_endpoint_test.c
>> index 37db0fc..a7d9354 100644
>> --- a/drivers/misc/pci_endpoint_test.c
>> +++ b/drivers/misc/pci_endpoint_test.c
>> @@ -42,11 +42,16 @@
>>  #define PCI_ENDPOINT_TEST_COMMAND   0x4
>>  #define COMMAND_RAISE_LEGACY_IRQBIT(0)
>>  #define COMMAND_RAISE_MSI_IRQ   BIT(1)
>> -#define MSI_NUMBER_SHIFT2
>> -/* 6 bits for MSI number */
>> -#define COMMAND_READBIT(8)
>> -#define COMMAND_WRITE   BIT(9)
>> -#define COMMAND_COPYBIT(10)
>> +#define COMMAND_RAISE_MSIX_IRQ  BIT(2)
>> +#define IRQ_TYPE_SHIFT  3
>> +#define IRQ_TYPE_LEGACY 0
>> +#define IRQ_TYPE_MSI1
>> +#define IRQ_TYPE_MSIX   2
>> +#define MSI_NUMBER_SHIFT5
> 
> Now that you are anyways fixing this, add a new register entry for MSI 
> numbers.
> Let's not keep COMMAND and MSI's together.

What you suggest?

>> +/* 12 bits for MSI number */
>> +#define COMMAND_READBIT(17)
>> +#define COMMAND_WRITE   BIT(18)
>> +#define COMMAND_COPYBIT(19)
> 
> This change should be done along with the pci-epf-test in a single patch.

To be clear, you're saying is this patch should be just be squashed into the
patch number 8 [1], because there is a lot of dependencies namely the defines,
that is used on the alter functions.

[1] -> https://patchwork.ozlabs.org/patch/896841/

>>  
>>  #define PCI_ENDPOINT_TEST_STATUS0x8
>>  #define STATUS_READ_SUCCESS BIT(0)
>> @@ -73,9 +78,9 @@ static DEFINE_IDA(pci_endpoint_test_ida);
>>  #define to_endpoint_test(priv) container_of((priv), struct 
>> pci_endpoint_test, \
>>  miscdev)
>>  
>> -static bool no_msi;
>> -module_param(no_msi, bool, 0444);
>> -MODULE_PARM_DESC(no_msi, "Disable MSI interrupt in pci_endpoint_test");
> 
> Let's not remove this just to make sure existing users doesn't get affected.

Hum, by making an internal conversion? Like this
no_msi = false <=> irq_type = 1
no_msi = true <=> irq_type = 0

>> +static int irq_type = IRQ_TYPE_MSIX;
>> +module_param(irq_type, int, 0444);
>> +MODULE_PARM_DESC(irq_type, "IRQ mode selection in pci_endpoint_test (0 - 
>> Legacy, 1 - MSI, 2 - MSI-X)");
>>  
>>  enum pci_barno {
>>  BAR_0,
>> @@ -103,7 +108,7 @@ struct pci_endpoint_test {
>>  struct pci_endpoint_test_data {
>>  enum pci_barno test_reg_bar;
>>  size_t alignment;
>> -bool no_msi;
>> +int irq_type;
>>  };
>>  
>>  static inline u32 pci_endpoint_test_readl(struct pci_endpoint_test *test,
>> @@ -177,10 +182,10