]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
misc: pci_endpoint_test: Add support for PCITEST_IRQ_TYPE_AUTO
authorNiklas Cassel <cassel@kernel.org>
Mon, 10 Mar 2025 11:10:24 +0000 (12:10 +0100)
committerKrzysztof Wilczyński <kwilczynski@kernel.org>
Wed, 26 Mar 2025 06:11:54 +0000 (06:11 +0000)
For PCITEST_MSI we really want to set PCITEST_SET_IRQTYPE explicitly
to PCITEST_IRQ_TYPE_MSI, since we want to test if MSI works.

For PCITEST_MSIX we really want to set PCITEST_SET_IRQTYPE explicitly
to PCITEST_IRQ_TYPE_MSIX, since we want to test if MSI works.

For PCITEST_LEGACY_IRQ we really want to set PCITEST_SET_IRQTYPE
explicitly to PCITEST_IRQ_TYPE_INTX, since we want to test if INTx
works.

However, for PCITEST_WRITE, PCITEST_READ, PCITEST_COPY, we really don't
care which IRQ type that is used, we just want to use a IRQ type that is
supported by the EPC.

The old behavior was to always use MSI for PCITEST_WRITE, PCITEST_READ,
PCITEST_COPY, was to always set IRQ type to MSI before doing the actual
test, however, there are EPC drivers that do not support MSI.

Add a new PCITEST_IRQ_TYPE_AUTO, that will use the CAPS register to see
which IRQ types the endpoint supports, and use one of the supported IRQ
types.

For backwards compatibility, if the endpoint does not expose any supported
IRQ type in the CAPS register, simply fallback to using MSI, as it was
unconditionally done before.

Signed-off-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Link: https://lore.kernel.org/r/20250310111016.859445-16-cassel@kernel.org
drivers/misc/pci_endpoint_test.c
include/uapi/linux/pcitest.h
tools/testing/selftests/pci_endpoint/pci_endpoint_test.c

index abcf1d91de379129e9820ef7e2f56642f041217b..1b57850dea9f9051bc07cf6711ec25682d92cc5c 100644 (file)
@@ -66,6 +66,9 @@
 
 #define PCI_ENDPOINT_TEST_CAPS                 0x30
 #define CAP_UNALIGNED_ACCESS                   BIT(0)
+#define CAP_MSI                                        BIT(1)
+#define CAP_MSIX                               BIT(2)
+#define CAP_INTX                               BIT(3)
 
 #define PCI_DEVICE_ID_TI_AM654                 0xb00c
 #define PCI_DEVICE_ID_TI_J7200                 0xb00f
@@ -113,6 +116,7 @@ struct pci_endpoint_test {
        struct miscdevice miscdev;
        enum pci_barno test_reg_bar;
        size_t alignment;
+       u32 ep_caps;
        const char *name;
 };
 
@@ -803,11 +807,23 @@ static int pci_endpoint_test_set_irq(struct pci_endpoint_test *test,
        int ret;
 
        if (req_irq_type < PCITEST_IRQ_TYPE_INTX ||
-           req_irq_type > PCITEST_IRQ_TYPE_MSIX) {
+           req_irq_type > PCITEST_IRQ_TYPE_AUTO) {
                dev_err(dev, "Invalid IRQ type option\n");
                return -EINVAL;
        }
 
+       if (req_irq_type == PCITEST_IRQ_TYPE_AUTO) {
+               if (test->ep_caps & CAP_MSI)
+                       req_irq_type = PCITEST_IRQ_TYPE_MSI;
+               else if (test->ep_caps & CAP_MSIX)
+                       req_irq_type = PCITEST_IRQ_TYPE_MSIX;
+               else if (test->ep_caps & CAP_INTX)
+                       req_irq_type = PCITEST_IRQ_TYPE_INTX;
+               else
+                       /* fallback to MSI if no caps defined */
+                       req_irq_type = PCITEST_IRQ_TYPE_MSI;
+       }
+
        if (test->irq_type == req_irq_type)
                return 0;
 
@@ -893,13 +909,12 @@ static void pci_endpoint_test_get_capabilities(struct pci_endpoint_test *test)
 {
        struct pci_dev *pdev = test->pdev;
        struct device *dev = &pdev->dev;
-       u32 caps;
 
-       caps = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_CAPS);
-       dev_dbg(dev, "PCI_ENDPOINT_TEST_CAPS: %#x\n", caps);
+       test->ep_caps = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_CAPS);
+       dev_dbg(dev, "PCI_ENDPOINT_TEST_CAPS: %#x\n", test->ep_caps);
 
        /* CAP_UNALIGNED_ACCESS is set if the EP can do unaligned access */
-       if (caps & CAP_UNALIGNED_ACCESS)
+       if (test->ep_caps & CAP_UNALIGNED_ACCESS)
                test->alignment = 0;
 }
 
index 304bf9be0f9a02c0f7261d6825caf45a560e6aac..d3aa8715a525ea47485db734a42d13d333399112 100644 (file)
@@ -27,6 +27,7 @@
 #define PCITEST_IRQ_TYPE_INTX          0
 #define PCITEST_IRQ_TYPE_MSI           1
 #define PCITEST_IRQ_TYPE_MSIX          2
+#define PCITEST_IRQ_TYPE_AUTO          3
 
 #define PCITEST_FLAGS_USE_DMA  0x00000001
 
index fdf4bc6aa9d2a37d2c0bc89554b6ae21a6a28346..ac26481d29d9dce5d07de563048850c55c58c22d 100644 (file)
@@ -181,8 +181,8 @@ TEST_F(pci_ep_data_transfer, READ_TEST)
        if (variant->use_dma)
                param.flags = PCITEST_FLAGS_USE_DMA;
 
-       pci_ep_ioctl(PCITEST_SET_IRQTYPE, PCITEST_IRQ_TYPE_MSI);
-       ASSERT_EQ(0, ret) TH_LOG("Can't set MSI IRQ type");
+       pci_ep_ioctl(PCITEST_SET_IRQTYPE, PCITEST_IRQ_TYPE_AUTO);
+       ASSERT_EQ(0, ret) TH_LOG("Can't set AUTO IRQ type");
 
        for (i = 0; i < ARRAY_SIZE(test_size); i++) {
                param.size = test_size[i];
@@ -200,8 +200,8 @@ TEST_F(pci_ep_data_transfer, WRITE_TEST)
        if (variant->use_dma)
                param.flags = PCITEST_FLAGS_USE_DMA;
 
-       pci_ep_ioctl(PCITEST_SET_IRQTYPE, PCITEST_IRQ_TYPE_MSI);
-       ASSERT_EQ(0, ret) TH_LOG("Can't set MSI IRQ type");
+       pci_ep_ioctl(PCITEST_SET_IRQTYPE, PCITEST_IRQ_TYPE_AUTO);
+       ASSERT_EQ(0, ret) TH_LOG("Can't set AUTO IRQ type");
 
        for (i = 0; i < ARRAY_SIZE(test_size); i++) {
                param.size = test_size[i];
@@ -219,8 +219,8 @@ TEST_F(pci_ep_data_transfer, COPY_TEST)
        if (variant->use_dma)
                param.flags = PCITEST_FLAGS_USE_DMA;
 
-       pci_ep_ioctl(PCITEST_SET_IRQTYPE, PCITEST_IRQ_TYPE_MSI);
-       ASSERT_EQ(0, ret) TH_LOG("Can't set MSI IRQ type");
+       pci_ep_ioctl(PCITEST_SET_IRQTYPE, PCITEST_IRQ_TYPE_AUTO);
+       ASSERT_EQ(0, ret) TH_LOG("Can't set AUTO IRQ type");
 
        for (i = 0; i < ARRAY_SIZE(test_size); i++) {
                param.size = test_size[i];