FILE
pci_endpoint_test.c
File preview with syntax highlighting.
linux-6.19.14/tools/testing/selftests/pci_endpoint/pci_endpoint_test.c
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 : ret; \ 29}) 30 31static const char *test_device = "/dev/pci-endpoint-test.0"; 32static const unsigned long test_size[5] = { 1, 1024, 1025, 1024000, 1024001 }; 33 34FIXTURE(pci_ep_bar) 35{ 36 int fd; 37}; 38 39FIXTURE_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 46FIXTURE_TEARDOWN(pci_ep_bar) 47{ 48 close(self->fd); 49} 50 51FIXTURE_VARIANT(pci_ep_bar) 52{ 53 int barno; 54}; 55 56FIXTURE_VARIANT_ADD(pci_ep_bar, BAR0) { .barno = 0 }; 57FIXTURE_VARIANT_ADD(pci_ep_bar, BAR1) { .barno = 1 }; 58FIXTURE_VARIANT_ADD(pci_ep_bar, BAR2) { .barno = 2 }; 59FIXTURE_VARIANT_ADD(pci_ep_bar, BAR3) { .barno = 3 }; 60FIXTURE_VARIANT_ADD(pci_ep_bar, BAR4) { .barno = 4 }; 61FIXTURE_VARIANT_ADD(pci_ep_bar, BAR5) { .barno = 5 }; 62 63TEST_F(pci_ep_bar, BAR_TEST) 64{ 65 int ret; 66 67 pci_ep_ioctl(PCITEST_BAR, variant->barno); 68 if (ret == -ENODATA) 69 SKIP(return, "BAR is disabled"); 70 EXPECT_FALSE(ret) TH_LOG("Test failed for BAR%d", variant->barno); 71} 72 73FIXTURE(pci_ep_basic) 74{ 75 int fd; 76}; 77 78FIXTURE_SETUP(pci_ep_basic) 79{ 80 self->fd = open(test_device, O_RDWR); 81 82 ASSERT_NE(-1, self->fd) TH_LOG("Can't open PCI Endpoint Test device"); 83} 84 85FIXTURE_TEARDOWN(pci_ep_basic) 86{ 87 close(self->fd); 88} 89 90TEST_F(pci_ep_basic, CONSECUTIVE_BAR_TEST) 91{ 92 int ret; 93 94 pci_ep_ioctl(PCITEST_BARS, 0); 95 EXPECT_FALSE(ret) TH_LOG("Consecutive BAR test failed"); 96} 97 98TEST_F(pci_ep_basic, LEGACY_IRQ_TEST) 99{ 100 int ret; 101 102 pci_ep_ioctl(PCITEST_SET_IRQTYPE, PCITEST_IRQ_TYPE_INTX); 103 ASSERT_EQ(0, ret) TH_LOG("Can't set Legacy IRQ type"); 104 105 pci_ep_ioctl(PCITEST_GET_IRQTYPE, 0); 106 ASSERT_EQ(PCITEST_IRQ_TYPE_INTX, ret) TH_LOG("Can't get Legacy IRQ type"); 107 108 pci_ep_ioctl(PCITEST_LEGACY_IRQ, 0); 109 EXPECT_FALSE(ret) TH_LOG("Test failed for Legacy IRQ"); 110} 111 112TEST_F(pci_ep_basic, MSI_TEST) 113{ 114 int ret, i; 115 116 pci_ep_ioctl(PCITEST_SET_IRQTYPE, PCITEST_IRQ_TYPE_MSI); 117 ASSERT_EQ(0, ret) TH_LOG("Can't set MSI IRQ type"); 118 119 pci_ep_ioctl(PCITEST_GET_IRQTYPE, 0); 120 ASSERT_EQ(PCITEST_IRQ_TYPE_MSI, ret) TH_LOG("Can't get MSI IRQ type"); 121 122 for (i = 1; i <= 32; i++) { 123 pci_ep_ioctl(PCITEST_MSI, i); 124 if (ret == -EINVAL) 125 SKIP(return, "MSI%d is disabled", i); 126 EXPECT_FALSE(ret) TH_LOG("Test failed for MSI%d", i); 127 } 128} 129 130TEST_F(pci_ep_basic, MSIX_TEST) 131{ 132 int ret, i; 133 134 pci_ep_ioctl(PCITEST_SET_IRQTYPE, PCITEST_IRQ_TYPE_MSIX); 135 ASSERT_EQ(0, ret) TH_LOG("Can't set MSI-X IRQ type"); 136 137 pci_ep_ioctl(PCITEST_GET_IRQTYPE, 0); 138 ASSERT_EQ(PCITEST_IRQ_TYPE_MSIX, ret) TH_LOG("Can't get MSI-X IRQ type"); 139 140 for (i = 1; i <= 2048; i++) { 141 pci_ep_ioctl(PCITEST_MSIX, i); 142 if (ret == -EINVAL) 143 SKIP(return, "MSI-X%d is disabled", i); 144 EXPECT_FALSE(ret) TH_LOG("Test failed for MSI-X%d", i); 145 } 146} 147 148FIXTURE(pci_ep_data_transfer) 149{ 150 int fd; 151}; 152 153FIXTURE_SETUP(pci_ep_data_transfer) 154{ 155 self->fd = open(test_device, O_RDWR); 156 157 ASSERT_NE(-1, self->fd) TH_LOG("Can't open PCI Endpoint Test device"); 158} 159 160FIXTURE_TEARDOWN(pci_ep_data_transfer) 161{ 162 close(self->fd); 163} 164 165FIXTURE_VARIANT(pci_ep_data_transfer) 166{ 167 bool use_dma; 168}; 169 170FIXTURE_VARIANT_ADD(pci_ep_data_transfer, memcpy) 171{ 172 .use_dma = false, 173}; 174 175FIXTURE_VARIANT_ADD(pci_ep_data_transfer, dma) 176{ 177 .use_dma = true, 178}; 179 180TEST_F(pci_ep_data_transfer, READ_TEST) 181{ 182 struct pci_endpoint_test_xfer_param param = {}; 183 int ret, i; 184 185 if (variant->use_dma) 186 param.flags = PCITEST_FLAGS_USE_DMA; 187 188 pci_ep_ioctl(PCITEST_SET_IRQTYPE, PCITEST_IRQ_TYPE_AUTO); 189 ASSERT_EQ(0, ret) TH_LOG("Can't set AUTO IRQ type"); 190 191 for (i = 0; i < ARRAY_SIZE(test_size); i++) { 192 param.size = test_size[i]; 193 pci_ep_ioctl(PCITEST_READ, ¶m); 194 EXPECT_FALSE(ret) TH_LOG("Test failed for size (%ld)", 195 test_size[i]); 196 } 197} 198 199TEST_F(pci_ep_data_transfer, WRITE_TEST) 200{ 201 struct pci_endpoint_test_xfer_param param = {}; 202 int ret, i; 203 204 if (variant->use_dma) 205 param.flags = PCITEST_FLAGS_USE_DMA; 206 207 pci_ep_ioctl(PCITEST_SET_IRQTYPE, PCITEST_IRQ_TYPE_AUTO); 208 ASSERT_EQ(0, ret) TH_LOG("Can't set AUTO IRQ type"); 209 210 for (i = 0; i < ARRAY_SIZE(test_size); i++) { 211 param.size = test_size[i]; 212 pci_ep_ioctl(PCITEST_WRITE, ¶m); 213 EXPECT_FALSE(ret) TH_LOG("Test failed for size (%ld)", 214 test_size[i]); 215 } 216} 217 218TEST_F(pci_ep_data_transfer, COPY_TEST) 219{ 220 struct pci_endpoint_test_xfer_param param = {}; 221 int ret, i; 222 223 if (variant->use_dma) 224 param.flags = PCITEST_FLAGS_USE_DMA; 225 226 pci_ep_ioctl(PCITEST_SET_IRQTYPE, PCITEST_IRQ_TYPE_AUTO); 227 ASSERT_EQ(0, ret) TH_LOG("Can't set AUTO IRQ type"); 228 229 for (i = 0; i < ARRAY_SIZE(test_size); i++) { 230 param.size = test_size[i]; 231 pci_ep_ioctl(PCITEST_COPY, ¶m); 232 EXPECT_FALSE(ret) TH_LOG("Test failed for size (%ld)", 233 test_size[i]); 234 } 235} 236 237FIXTURE(pcie_ep_doorbell) 238{ 239 int fd; 240}; 241 242FIXTURE_SETUP(pcie_ep_doorbell) 243{ 244 self->fd = open(test_device, O_RDWR); 245 246 ASSERT_NE(-1, self->fd) TH_LOG("Can't open PCI Endpoint Test device"); 247}; 248 249FIXTURE_TEARDOWN(pcie_ep_doorbell) 250{ 251 close(self->fd); 252}; 253 254TEST_F(pcie_ep_doorbell, DOORBELL_TEST) 255{ 256 int ret; 257 258 pci_ep_ioctl(PCITEST_SET_IRQTYPE, PCITEST_IRQ_TYPE_AUTO); 259 ASSERT_EQ(0, ret) TH_LOG("Can't set AUTO IRQ type"); 260 261 pci_ep_ioctl(PCITEST_DOORBELL, 0); 262 EXPECT_FALSE(ret) TH_LOG("Test failed for Doorbell\n"); 263} 264TEST_HARNESS_MAIN
~/
Read-only file preview.