xref: /linux/tools/testing/selftests/pci_endpoint/pci_endpoint_test.c (revision 647d69605c70368d54fc012fce8a43e8e5955b04)
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, &param);
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, &param);
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, &param);
217 		EXPECT_FALSE(ret) TH_LOG("Test failed for size (%ld)",
218 					 test_size[i]);
219 	}
220 }
221 TEST_HARNESS_MAIN
222