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 <[email protected]>
8 *
9 * Copyright (c) 2024, Linaro Ltd.
10 * Author: Manivannan Sadhasivam <[email protected]>
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
FIXTURE(pci_ep_bar)34 FIXTURE(pci_ep_bar)
35 {
36 int fd;
37 };
38
FIXTURE_SETUP(pci_ep_bar)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
FIXTURE_TEARDOWN(pci_ep_bar)46 FIXTURE_TEARDOWN(pci_ep_bar)
47 {
48 close(self->fd);
49 }
50
FIXTURE_VARIANT(pci_ep_bar)51 FIXTURE_VARIANT(pci_ep_bar)
52 {
53 int barno;
54 };
55
FIXTURE_VARIANT_ADD(pci_ep_bar,BAR0)56 FIXTURE_VARIANT_ADD(pci_ep_bar, BAR0) { .barno = 0 };
FIXTURE_VARIANT_ADD(pci_ep_bar,BAR1)57 FIXTURE_VARIANT_ADD(pci_ep_bar, BAR1) { .barno = 1 };
FIXTURE_VARIANT_ADD(pci_ep_bar,BAR2)58 FIXTURE_VARIANT_ADD(pci_ep_bar, BAR2) { .barno = 2 };
FIXTURE_VARIANT_ADD(pci_ep_bar,BAR3)59 FIXTURE_VARIANT_ADD(pci_ep_bar, BAR3) { .barno = 3 };
FIXTURE_VARIANT_ADD(pci_ep_bar,BAR4)60 FIXTURE_VARIANT_ADD(pci_ep_bar, BAR4) { .barno = 4 };
FIXTURE_VARIANT_ADD(pci_ep_bar,BAR5)61 FIXTURE_VARIANT_ADD(pci_ep_bar, BAR5) { .barno = 5 };
62
TEST_F(pci_ep_bar,BAR_TEST)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
FIXTURE(pci_ep_basic)71 FIXTURE(pci_ep_basic)
72 {
73 int fd;
74 };
75
FIXTURE_SETUP(pci_ep_basic)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
FIXTURE_TEARDOWN(pci_ep_basic)83 FIXTURE_TEARDOWN(pci_ep_basic)
84 {
85 close(self->fd);
86 }
87
TEST_F(pci_ep_basic,CONSECUTIVE_BAR_TEST)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
TEST_F(pci_ep_basic,LEGACY_IRQ_TEST)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
TEST_F(pci_ep_basic,MSI_TEST)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
TEST_F(pci_ep_basic,MSIX_TEST)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
FIXTURE(pci_ep_data_transfer)133 FIXTURE(pci_ep_data_transfer)
134 {
135 int fd;
136 };
137
FIXTURE_SETUP(pci_ep_data_transfer)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
FIXTURE_TEARDOWN(pci_ep_data_transfer)145 FIXTURE_TEARDOWN(pci_ep_data_transfer)
146 {
147 close(self->fd);
148 }
149
FIXTURE_VARIANT(pci_ep_data_transfer)150 FIXTURE_VARIANT(pci_ep_data_transfer)
151 {
152 bool use_dma;
153 };
154
FIXTURE_VARIANT_ADD(pci_ep_data_transfer,memcpy)155 FIXTURE_VARIANT_ADD(pci_ep_data_transfer, memcpy)
156 {
157 .use_dma = false,
158 };
159
FIXTURE_VARIANT_ADD(pci_ep_data_transfer,dma)160 FIXTURE_VARIANT_ADD(pci_ep_data_transfer, dma)
161 {
162 .use_dma = true,
163 };
164
TEST_F(pci_ep_data_transfer,READ_TEST)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
TEST_F(pci_ep_data_transfer,WRITE_TEST)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
TEST_F(pci_ep_data_transfer,COPY_TEST)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