1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Kselftest for PCI Endpoint Subsystem 4 * 5 * Copyright (c) 2022 Samsung Electronics Co., Ltd. 6 * https://www.samsung.com 7 * Author: Aman Gupta <aman1.gupta@samsung.com> 8 * 9 * Copyright (c) 2024, Linaro Ltd. 10 * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> 11 */ 12 13 #include <errno.h> 14 #include <fcntl.h> 15 #include <stdbool.h> 16 #include <stdio.h> 17 #include <stdlib.h> 18 #include <sys/ioctl.h> 19 #include <unistd.h> 20 21 #include "../../../../include/uapi/linux/pcitest.h" 22 23 #include "../kselftest_harness.h" 24 25 #define pci_ep_ioctl(cmd, arg) \ 26 ({ \ 27 ret = ioctl(self->fd, cmd, arg); \ 28 ret = ret < 0 ? -errno : 0; \ 29 }) 30 31 static const char *test_device = "/dev/pci-endpoint-test.0"; 32 static const unsigned long test_size[5] = { 1, 1024, 1025, 1024000, 1024001 }; 33 34 FIXTURE(pci_ep_bar) 35 { 36 int fd; 37 }; 38 39 FIXTURE_SETUP(pci_ep_bar) 40 { 41 self->fd = open(test_device, O_RDWR); 42 43 ASSERT_NE(-1, self->fd) TH_LOG("Can't open PCI Endpoint Test device"); 44 } 45 46 FIXTURE_TEARDOWN(pci_ep_bar) 47 { 48 close(self->fd); 49 } 50 51 FIXTURE_VARIANT(pci_ep_bar) 52 { 53 int barno; 54 }; 55 56 FIXTURE_VARIANT_ADD(pci_ep_bar, BAR0) { .barno = 0 }; 57 FIXTURE_VARIANT_ADD(pci_ep_bar, BAR1) { .barno = 1 }; 58 FIXTURE_VARIANT_ADD(pci_ep_bar, BAR2) { .barno = 2 }; 59 FIXTURE_VARIANT_ADD(pci_ep_bar, BAR3) { .barno = 3 }; 60 FIXTURE_VARIANT_ADD(pci_ep_bar, BAR4) { .barno = 4 }; 61 FIXTURE_VARIANT_ADD(pci_ep_bar, BAR5) { .barno = 5 }; 62 63 TEST_F(pci_ep_bar, BAR_TEST) 64 { 65 int ret; 66 67 pci_ep_ioctl(PCITEST_BAR, variant->barno); 68 EXPECT_FALSE(ret) TH_LOG("Test failed for BAR%d", variant->barno); 69 } 70 71 FIXTURE(pci_ep_basic) 72 { 73 int fd; 74 }; 75 76 FIXTURE_SETUP(pci_ep_basic) 77 { 78 self->fd = open(test_device, O_RDWR); 79 80 ASSERT_NE(-1, self->fd) TH_LOG("Can't open PCI Endpoint Test device"); 81 } 82 83 FIXTURE_TEARDOWN(pci_ep_basic) 84 { 85 close(self->fd); 86 } 87 88 TEST_F(pci_ep_basic, CONSECUTIVE_BAR_TEST) 89 { 90 int ret; 91 92 pci_ep_ioctl(PCITEST_BARS, 0); 93 EXPECT_FALSE(ret) TH_LOG("Consecutive BAR test failed"); 94 } 95 96 TEST_F(pci_ep_basic, LEGACY_IRQ_TEST) 97 { 98 int ret; 99 100 pci_ep_ioctl(PCITEST_SET_IRQTYPE, 0); 101 ASSERT_EQ(0, ret) TH_LOG("Can't set Legacy IRQ type"); 102 103 pci_ep_ioctl(PCITEST_LEGACY_IRQ, 0); 104 EXPECT_FALSE(ret) TH_LOG("Test failed for Legacy IRQ"); 105 } 106 107 TEST_F(pci_ep_basic, MSI_TEST) 108 { 109 int ret, i; 110 111 pci_ep_ioctl(PCITEST_SET_IRQTYPE, 1); 112 ASSERT_EQ(0, ret) TH_LOG("Can't set MSI IRQ type"); 113 114 for (i = 1; i <= 32; i++) { 115 pci_ep_ioctl(PCITEST_MSI, i); 116 EXPECT_FALSE(ret) TH_LOG("Test failed for MSI%d", i); 117 } 118 } 119 120 TEST_F(pci_ep_basic, MSIX_TEST) 121 { 122 int ret, i; 123 124 pci_ep_ioctl(PCITEST_SET_IRQTYPE, 2); 125 ASSERT_EQ(0, ret) TH_LOG("Can't set MSI-X IRQ type"); 126 127 for (i = 1; i <= 2048; i++) { 128 pci_ep_ioctl(PCITEST_MSIX, i); 129 EXPECT_FALSE(ret) TH_LOG("Test failed for MSI-X%d", i); 130 } 131 } 132 133 FIXTURE(pci_ep_data_transfer) 134 { 135 int fd; 136 }; 137 138 FIXTURE_SETUP(pci_ep_data_transfer) 139 { 140 self->fd = open(test_device, O_RDWR); 141 142 ASSERT_NE(-1, self->fd) TH_LOG("Can't open PCI Endpoint Test device"); 143 } 144 145 FIXTURE_TEARDOWN(pci_ep_data_transfer) 146 { 147 close(self->fd); 148 } 149 150 FIXTURE_VARIANT(pci_ep_data_transfer) 151 { 152 bool use_dma; 153 }; 154 155 FIXTURE_VARIANT_ADD(pci_ep_data_transfer, memcpy) 156 { 157 .use_dma = false, 158 }; 159 160 FIXTURE_VARIANT_ADD(pci_ep_data_transfer, dma) 161 { 162 .use_dma = true, 163 }; 164 165 TEST_F(pci_ep_data_transfer, READ_TEST) 166 { 167 struct pci_endpoint_test_xfer_param param = {}; 168 int ret, i; 169 170 if (variant->use_dma) 171 param.flags = PCITEST_FLAGS_USE_DMA; 172 173 pci_ep_ioctl(PCITEST_SET_IRQTYPE, 1); 174 ASSERT_EQ(0, ret) TH_LOG("Can't set MSI IRQ type"); 175 176 for (i = 0; i < ARRAY_SIZE(test_size); i++) { 177 param.size = test_size[i]; 178 pci_ep_ioctl(PCITEST_READ, ¶m); 179 EXPECT_FALSE(ret) TH_LOG("Test failed for size (%ld)", 180 test_size[i]); 181 } 182 } 183 184 TEST_F(pci_ep_data_transfer, WRITE_TEST) 185 { 186 struct pci_endpoint_test_xfer_param param = {}; 187 int ret, i; 188 189 if (variant->use_dma) 190 param.flags = PCITEST_FLAGS_USE_DMA; 191 192 pci_ep_ioctl(PCITEST_SET_IRQTYPE, 1); 193 ASSERT_EQ(0, ret) TH_LOG("Can't set MSI IRQ type"); 194 195 for (i = 0; i < ARRAY_SIZE(test_size); i++) { 196 param.size = test_size[i]; 197 pci_ep_ioctl(PCITEST_WRITE, ¶m); 198 EXPECT_FALSE(ret) TH_LOG("Test failed for size (%ld)", 199 test_size[i]); 200 } 201 } 202 203 TEST_F(pci_ep_data_transfer, COPY_TEST) 204 { 205 struct pci_endpoint_test_xfer_param param = {}; 206 int ret, i; 207 208 if (variant->use_dma) 209 param.flags = PCITEST_FLAGS_USE_DMA; 210 211 pci_ep_ioctl(PCITEST_SET_IRQTYPE, 1); 212 ASSERT_EQ(0, ret) TH_LOG("Can't set MSI IRQ type"); 213 214 for (i = 0; i < ARRAY_SIZE(test_size); i++) { 215 param.size = test_size[i]; 216 pci_ep_ioctl(PCITEST_COPY, ¶m); 217 EXPECT_FALSE(ret) TH_LOG("Test failed for size (%ld)", 218 test_size[i]); 219 } 220 } 221 TEST_HARNESS_MAIN 222