1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2a9de470cSBruce Richardson * Copyright(c) 2010-2014 Intel Corporation
3a9de470cSBruce Richardson */
4a9de470cSBruce Richardson
5a9de470cSBruce Richardson #include <stdio.h>
6a9de470cSBruce Richardson #include <stdint.h>
7a9de470cSBruce Richardson #include <unistd.h>
8a9de470cSBruce Richardson
9a9de470cSBruce Richardson #include <rte_common.h>
10a9de470cSBruce Richardson #include <rte_cycles.h>
11a9de470cSBruce Richardson #include <rte_interrupts.h>
12a9de470cSBruce Richardson
13a9de470cSBruce Richardson #include "test.h"
14a9de470cSBruce Richardson
15a9de470cSBruce Richardson #define TEST_INTERRUPT_CHECK_INTERVAL 100 /* ms */
16a9de470cSBruce Richardson
17a9de470cSBruce Richardson /* predefined interrupt handle types */
18a9de470cSBruce Richardson enum test_interrupt_handle_type {
19db86bf26SHarman Kalra TEST_INTERRUPT_HANDLE_INVALID = 0,
20a9de470cSBruce Richardson TEST_INTERRUPT_HANDLE_VALID,
21a9de470cSBruce Richardson TEST_INTERRUPT_HANDLE_VALID_UIO,
22a9de470cSBruce Richardson TEST_INTERRUPT_HANDLE_VALID_ALARM,
23a9de470cSBruce Richardson TEST_INTERRUPT_HANDLE_VALID_DEV_EVENT,
24a9de470cSBruce Richardson TEST_INTERRUPT_HANDLE_CASE1,
25a9de470cSBruce Richardson TEST_INTERRUPT_HANDLE_MAX
26a9de470cSBruce Richardson };
27a9de470cSBruce Richardson
28a9de470cSBruce Richardson /* flag of if callback is called */
29a9de470cSBruce Richardson static volatile int flag;
30db86bf26SHarman Kalra static struct rte_intr_handle *intr_handles[TEST_INTERRUPT_HANDLE_MAX];
31a9de470cSBruce Richardson static enum test_interrupt_handle_type test_intr_type =
32a9de470cSBruce Richardson TEST_INTERRUPT_HANDLE_MAX;
33a9de470cSBruce Richardson
34742bde12SBruce Richardson #ifdef RTE_EXEC_ENV_LINUX
35a9de470cSBruce Richardson union intr_pipefds{
36a9de470cSBruce Richardson struct {
37a9de470cSBruce Richardson int pipefd[2];
38a9de470cSBruce Richardson };
39a9de470cSBruce Richardson struct {
40a9de470cSBruce Richardson int readfd;
41a9de470cSBruce Richardson int writefd;
42a9de470cSBruce Richardson };
43a9de470cSBruce Richardson };
44a9de470cSBruce Richardson
45a9de470cSBruce Richardson static union intr_pipefds pfds;
46a9de470cSBruce Richardson
47a9de470cSBruce Richardson /**
48a9de470cSBruce Richardson * Check if the interrupt handle is valid.
49a9de470cSBruce Richardson */
50a9de470cSBruce Richardson static inline int
test_interrupt_handle_sanity_check(struct rte_intr_handle * intr_handle)51a9de470cSBruce Richardson test_interrupt_handle_sanity_check(struct rte_intr_handle *intr_handle)
52a9de470cSBruce Richardson {
53db86bf26SHarman Kalra if (!intr_handle || rte_intr_fd_get(intr_handle) < 0)
54a9de470cSBruce Richardson return -1;
55a9de470cSBruce Richardson
56a9de470cSBruce Richardson return 0;
57a9de470cSBruce Richardson }
58a9de470cSBruce Richardson
59a9de470cSBruce Richardson /**
60a9de470cSBruce Richardson * Initialization for interrupt test.
61a9de470cSBruce Richardson */
62a9de470cSBruce Richardson static int
test_interrupt_init(void)63a9de470cSBruce Richardson test_interrupt_init(void)
64a9de470cSBruce Richardson {
65db86bf26SHarman Kalra struct rte_intr_handle *test_intr_handle;
66db86bf26SHarman Kalra int i;
67db86bf26SHarman Kalra
68a9de470cSBruce Richardson if (pipe(pfds.pipefd) < 0)
69a9de470cSBruce Richardson return -1;
70a9de470cSBruce Richardson
71db86bf26SHarman Kalra for (i = 0; i < TEST_INTERRUPT_HANDLE_MAX; i++) {
72db86bf26SHarman Kalra intr_handles[i] =
73db86bf26SHarman Kalra rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE);
74db86bf26SHarman Kalra if (!intr_handles[i])
75db86bf26SHarman Kalra return -1;
76db86bf26SHarman Kalra }
77a9de470cSBruce Richardson
78db86bf26SHarman Kalra test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
79db86bf26SHarman Kalra if (rte_intr_fd_set(test_intr_handle, -1))
80db86bf26SHarman Kalra return -1;
81db86bf26SHarman Kalra if (rte_intr_type_set(test_intr_handle, RTE_INTR_HANDLE_UNKNOWN))
82db86bf26SHarman Kalra return -1;
83a9de470cSBruce Richardson
84db86bf26SHarman Kalra test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
85db86bf26SHarman Kalra if (rte_intr_fd_set(test_intr_handle, pfds.readfd))
86db86bf26SHarman Kalra return -1;
87db86bf26SHarman Kalra if (rte_intr_type_set(test_intr_handle, RTE_INTR_HANDLE_UNKNOWN))
88db86bf26SHarman Kalra return -1;
89a9de470cSBruce Richardson
90db86bf26SHarman Kalra test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_UIO];
91db86bf26SHarman Kalra if (rte_intr_fd_set(test_intr_handle, pfds.readfd))
92db86bf26SHarman Kalra return -1;
93db86bf26SHarman Kalra if (rte_intr_type_set(test_intr_handle, RTE_INTR_HANDLE_UIO))
94db86bf26SHarman Kalra return -1;
95a9de470cSBruce Richardson
96db86bf26SHarman Kalra test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_ALARM];
97db86bf26SHarman Kalra if (rte_intr_fd_set(test_intr_handle, pfds.readfd))
98db86bf26SHarman Kalra return -1;
99db86bf26SHarman Kalra if (rte_intr_type_set(test_intr_handle, RTE_INTR_HANDLE_ALARM))
100db86bf26SHarman Kalra return -1;
101a9de470cSBruce Richardson
102db86bf26SHarman Kalra test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_DEV_EVENT];
103db86bf26SHarman Kalra if (rte_intr_fd_set(test_intr_handle, pfds.readfd))
104db86bf26SHarman Kalra return -1;
105db86bf26SHarman Kalra if (rte_intr_type_set(test_intr_handle, RTE_INTR_HANDLE_DEV_EVENT))
106db86bf26SHarman Kalra return -1;
107db86bf26SHarman Kalra
108db86bf26SHarman Kalra test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_CASE1];
109db86bf26SHarman Kalra if (rte_intr_fd_set(test_intr_handle, pfds.writefd))
110db86bf26SHarman Kalra return -1;
111db86bf26SHarman Kalra if (rte_intr_type_set(test_intr_handle, RTE_INTR_HANDLE_UIO))
112db86bf26SHarman Kalra return -1;
113a9de470cSBruce Richardson
114a9de470cSBruce Richardson return 0;
115a9de470cSBruce Richardson }
116a9de470cSBruce Richardson
117a9de470cSBruce Richardson /**
118a9de470cSBruce Richardson * Deinitialization for interrupt test.
119a9de470cSBruce Richardson */
120a9de470cSBruce Richardson static int
test_interrupt_deinit(void)121a9de470cSBruce Richardson test_interrupt_deinit(void)
122a9de470cSBruce Richardson {
123db86bf26SHarman Kalra int i;
124db86bf26SHarman Kalra
125db86bf26SHarman Kalra for (i = 0; i < TEST_INTERRUPT_HANDLE_MAX; i++)
126db86bf26SHarman Kalra rte_intr_instance_free(intr_handles[i]);
127a9de470cSBruce Richardson close(pfds.pipefd[0]);
128a9de470cSBruce Richardson close(pfds.pipefd[1]);
129a9de470cSBruce Richardson
130a9de470cSBruce Richardson return 0;
131a9de470cSBruce Richardson }
132a9de470cSBruce Richardson
133a9de470cSBruce Richardson /**
134a9de470cSBruce Richardson * Write the pipe to simulate an interrupt.
135a9de470cSBruce Richardson */
136a9de470cSBruce Richardson static int
test_interrupt_trigger_interrupt(void)137a9de470cSBruce Richardson test_interrupt_trigger_interrupt(void)
138a9de470cSBruce Richardson {
139a9de470cSBruce Richardson if (write(pfds.writefd, "1", 1) < 0)
140a9de470cSBruce Richardson return -1;
141a9de470cSBruce Richardson
142a9de470cSBruce Richardson return 0;
143a9de470cSBruce Richardson }
144a9de470cSBruce Richardson
145a9de470cSBruce Richardson /**
146a9de470cSBruce Richardson * Check if two interrupt handles are the same.
147a9de470cSBruce Richardson */
148a9de470cSBruce Richardson static int
test_interrupt_handle_compare(struct rte_intr_handle * intr_handle_l,struct rte_intr_handle * intr_handle_r)149a9de470cSBruce Richardson test_interrupt_handle_compare(struct rte_intr_handle *intr_handle_l,
150a9de470cSBruce Richardson struct rte_intr_handle *intr_handle_r)
151a9de470cSBruce Richardson {
152a9de470cSBruce Richardson if (!intr_handle_l || !intr_handle_r)
153a9de470cSBruce Richardson return -1;
154a9de470cSBruce Richardson
155db86bf26SHarman Kalra if (rte_intr_fd_get(intr_handle_l) !=
156db86bf26SHarman Kalra rte_intr_fd_get(intr_handle_r) ||
157db86bf26SHarman Kalra rte_intr_type_get(intr_handle_l) !=
158db86bf26SHarman Kalra rte_intr_type_get(intr_handle_r))
159a9de470cSBruce Richardson return -1;
160a9de470cSBruce Richardson
161a9de470cSBruce Richardson return 0;
162a9de470cSBruce Richardson }
163a9de470cSBruce Richardson
164a9de470cSBruce Richardson #else
165a9de470cSBruce Richardson /* to be implemented for bsd later */
166a9de470cSBruce Richardson static inline int
test_interrupt_handle_sanity_check(struct rte_intr_handle * intr_handle)167a9de470cSBruce Richardson test_interrupt_handle_sanity_check(struct rte_intr_handle *intr_handle)
168a9de470cSBruce Richardson {
169a9de470cSBruce Richardson RTE_SET_USED(intr_handle);
170a9de470cSBruce Richardson
171a9de470cSBruce Richardson return 0;
172a9de470cSBruce Richardson }
173a9de470cSBruce Richardson
174a9de470cSBruce Richardson static int
test_interrupt_init(void)175a9de470cSBruce Richardson test_interrupt_init(void)
176a9de470cSBruce Richardson {
177a9de470cSBruce Richardson return 0;
178a9de470cSBruce Richardson }
179a9de470cSBruce Richardson
180a9de470cSBruce Richardson static int
test_interrupt_deinit(void)181a9de470cSBruce Richardson test_interrupt_deinit(void)
182a9de470cSBruce Richardson {
183a9de470cSBruce Richardson return 0;
184a9de470cSBruce Richardson }
185a9de470cSBruce Richardson
186a9de470cSBruce Richardson static int
test_interrupt_trigger_interrupt(void)187a9de470cSBruce Richardson test_interrupt_trigger_interrupt(void)
188a9de470cSBruce Richardson {
189a9de470cSBruce Richardson return 0;
190a9de470cSBruce Richardson }
191a9de470cSBruce Richardson
192a9de470cSBruce Richardson static int
test_interrupt_handle_compare(struct rte_intr_handle * intr_handle_l,struct rte_intr_handle * intr_handle_r)193a9de470cSBruce Richardson test_interrupt_handle_compare(struct rte_intr_handle *intr_handle_l,
194a9de470cSBruce Richardson struct rte_intr_handle *intr_handle_r)
195a9de470cSBruce Richardson {
196a9de470cSBruce Richardson (void)intr_handle_l;
197a9de470cSBruce Richardson (void)intr_handle_r;
198a9de470cSBruce Richardson
199a9de470cSBruce Richardson return 0;
200a9de470cSBruce Richardson }
201742bde12SBruce Richardson #endif /* RTE_EXEC_ENV_LINUX */
202a9de470cSBruce Richardson
203a9de470cSBruce Richardson /**
204a9de470cSBruce Richardson * Callback for the test interrupt.
205a9de470cSBruce Richardson */
206a9de470cSBruce Richardson static void
test_interrupt_callback(void * arg)207a9de470cSBruce Richardson test_interrupt_callback(void *arg)
208a9de470cSBruce Richardson {
209a9de470cSBruce Richardson struct rte_intr_handle *intr_handle = arg;
210db86bf26SHarman Kalra struct rte_intr_handle *test_intr_handle;
211db86bf26SHarman Kalra
212a9de470cSBruce Richardson if (test_intr_type >= TEST_INTERRUPT_HANDLE_MAX) {
213a9de470cSBruce Richardson printf("invalid interrupt type\n");
214a9de470cSBruce Richardson flag = -1;
215a9de470cSBruce Richardson return;
216a9de470cSBruce Richardson }
217a9de470cSBruce Richardson
218a9de470cSBruce Richardson if (test_interrupt_handle_sanity_check(intr_handle) < 0) {
219a9de470cSBruce Richardson printf("null or invalid intr_handle for %s\n", __func__);
220a9de470cSBruce Richardson flag = -1;
221a9de470cSBruce Richardson return;
222a9de470cSBruce Richardson }
223a9de470cSBruce Richardson
224a9de470cSBruce Richardson if (rte_intr_callback_unregister(intr_handle,
225a9de470cSBruce Richardson test_interrupt_callback, arg) >= 0) {
226a9de470cSBruce Richardson printf("%s: unexpectedly able to unregister itself\n",
227a9de470cSBruce Richardson __func__);
228a9de470cSBruce Richardson flag = -1;
229a9de470cSBruce Richardson return;
230a9de470cSBruce Richardson }
231a9de470cSBruce Richardson
232db86bf26SHarman Kalra test_intr_handle = intr_handles[test_intr_type];
233db86bf26SHarman Kalra if (test_interrupt_handle_compare(intr_handle, test_intr_handle) == 0)
234a9de470cSBruce Richardson flag = 1;
235a9de470cSBruce Richardson }
236a9de470cSBruce Richardson
237a9de470cSBruce Richardson /**
238a9de470cSBruce Richardson * Callback for the test interrupt.
239a9de470cSBruce Richardson */
240a9de470cSBruce Richardson static void
test_interrupt_callback_1(void * arg)241a9de470cSBruce Richardson test_interrupt_callback_1(void *arg)
242a9de470cSBruce Richardson {
243a9de470cSBruce Richardson struct rte_intr_handle *intr_handle = arg;
244a9de470cSBruce Richardson if (test_interrupt_handle_sanity_check(intr_handle) < 0) {
245a9de470cSBruce Richardson printf("null or invalid intr_handle for %s\n", __func__);
246a9de470cSBruce Richardson flag = -1;
247a9de470cSBruce Richardson return;
248a9de470cSBruce Richardson }
249a9de470cSBruce Richardson }
250a9de470cSBruce Richardson
251a9de470cSBruce Richardson /**
252a9de470cSBruce Richardson * Tests for rte_intr_enable().
253a9de470cSBruce Richardson */
254a9de470cSBruce Richardson static int
test_interrupt_enable(void)255a9de470cSBruce Richardson test_interrupt_enable(void)
256a9de470cSBruce Richardson {
257db86bf26SHarman Kalra struct rte_intr_handle *test_intr_handle;
258a9de470cSBruce Richardson
259a9de470cSBruce Richardson /* check with null intr_handle */
260a9de470cSBruce Richardson if (rte_intr_enable(NULL) == 0) {
261a9de470cSBruce Richardson printf("unexpectedly enable null intr_handle successfully\n");
262a9de470cSBruce Richardson return -1;
263a9de470cSBruce Richardson }
264a9de470cSBruce Richardson
265a9de470cSBruce Richardson /* check with invalid intr_handle */
266a9de470cSBruce Richardson test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
267db86bf26SHarman Kalra if (rte_intr_enable(test_intr_handle) == 0) {
268a9de470cSBruce Richardson printf("unexpectedly enable invalid intr_handle "
269a9de470cSBruce Richardson "successfully\n");
270a9de470cSBruce Richardson return -1;
271a9de470cSBruce Richardson }
272a9de470cSBruce Richardson
273a9de470cSBruce Richardson /* check with valid intr_handle */
274a9de470cSBruce Richardson test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
275db86bf26SHarman Kalra if (rte_intr_enable(test_intr_handle) == 0) {
276a9de470cSBruce Richardson printf("unexpectedly enable a specific intr_handle "
277a9de470cSBruce Richardson "successfully\n");
278a9de470cSBruce Richardson return -1;
279a9de470cSBruce Richardson }
280a9de470cSBruce Richardson
281a9de470cSBruce Richardson /* check with specific valid intr_handle */
282a9de470cSBruce Richardson test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_ALARM];
283db86bf26SHarman Kalra if (rte_intr_enable(test_intr_handle) == 0) {
284a9de470cSBruce Richardson printf("unexpectedly enable a specific intr_handle "
285a9de470cSBruce Richardson "successfully\n");
286a9de470cSBruce Richardson return -1;
287a9de470cSBruce Richardson }
288a9de470cSBruce Richardson
289a9de470cSBruce Richardson /* check with specific valid intr_handle */
290a9de470cSBruce Richardson test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_DEV_EVENT];
291db86bf26SHarman Kalra if (rte_intr_enable(test_intr_handle) == 0) {
292a9de470cSBruce Richardson printf("unexpectedly enable a specific intr_handle "
293a9de470cSBruce Richardson "successfully\n");
294a9de470cSBruce Richardson return -1;
295a9de470cSBruce Richardson }
296a9de470cSBruce Richardson
297a9de470cSBruce Richardson /* check with valid handler and its type */
298a9de470cSBruce Richardson test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_CASE1];
299db86bf26SHarman Kalra if (rte_intr_enable(test_intr_handle) < 0) {
300a9de470cSBruce Richardson printf("fail to enable interrupt on a simulated handler\n");
301a9de470cSBruce Richardson return -1;
302a9de470cSBruce Richardson }
303a9de470cSBruce Richardson
304a9de470cSBruce Richardson test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_UIO];
305db86bf26SHarman Kalra if (rte_intr_enable(test_intr_handle) == 0) {
306a9de470cSBruce Richardson printf("unexpectedly enable a specific intr_handle "
307a9de470cSBruce Richardson "successfully\n");
308a9de470cSBruce Richardson return -1;
309a9de470cSBruce Richardson }
310a9de470cSBruce Richardson
311a9de470cSBruce Richardson return 0;
312a9de470cSBruce Richardson }
313a9de470cSBruce Richardson
314a9de470cSBruce Richardson /**
315a9de470cSBruce Richardson * Tests for rte_intr_disable().
316a9de470cSBruce Richardson */
317a9de470cSBruce Richardson static int
test_interrupt_disable(void)318a9de470cSBruce Richardson test_interrupt_disable(void)
319a9de470cSBruce Richardson {
320db86bf26SHarman Kalra struct rte_intr_handle *test_intr_handle;
321a9de470cSBruce Richardson
322a9de470cSBruce Richardson /* check with null intr_handle */
323a9de470cSBruce Richardson if (rte_intr_disable(NULL) == 0) {
324a9de470cSBruce Richardson printf("unexpectedly disable null intr_handle "
325a9de470cSBruce Richardson "successfully\n");
326a9de470cSBruce Richardson return -1;
327a9de470cSBruce Richardson }
328a9de470cSBruce Richardson
329a9de470cSBruce Richardson /* check with invalid intr_handle */
330a9de470cSBruce Richardson test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
331db86bf26SHarman Kalra if (rte_intr_disable(test_intr_handle) == 0) {
332a9de470cSBruce Richardson printf("unexpectedly disable invalid intr_handle "
333a9de470cSBruce Richardson "successfully\n");
334a9de470cSBruce Richardson return -1;
335a9de470cSBruce Richardson }
336a9de470cSBruce Richardson
337a9de470cSBruce Richardson /* check with valid intr_handle */
338a9de470cSBruce Richardson test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
339db86bf26SHarman Kalra if (rte_intr_disable(test_intr_handle) == 0) {
340a9de470cSBruce Richardson printf("unexpectedly disable a specific intr_handle "
341a9de470cSBruce Richardson "successfully\n");
342a9de470cSBruce Richardson return -1;
343a9de470cSBruce Richardson }
344a9de470cSBruce Richardson
345a9de470cSBruce Richardson /* check with specific valid intr_handle */
346a9de470cSBruce Richardson test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_ALARM];
347db86bf26SHarman Kalra if (rte_intr_disable(test_intr_handle) == 0) {
348a9de470cSBruce Richardson printf("unexpectedly disable a specific intr_handle "
349a9de470cSBruce Richardson "successfully\n");
350a9de470cSBruce Richardson return -1;
351a9de470cSBruce Richardson }
352a9de470cSBruce Richardson
353a9de470cSBruce Richardson /* check with specific valid intr_handle */
354a9de470cSBruce Richardson test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_DEV_EVENT];
355db86bf26SHarman Kalra if (rte_intr_disable(test_intr_handle) == 0) {
356a9de470cSBruce Richardson printf("unexpectedly disable a specific intr_handle "
357a9de470cSBruce Richardson "successfully\n");
358a9de470cSBruce Richardson return -1;
359a9de470cSBruce Richardson }
360a9de470cSBruce Richardson
361a9de470cSBruce Richardson /* check with valid handler and its type */
362a9de470cSBruce Richardson test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_CASE1];
363db86bf26SHarman Kalra if (rte_intr_disable(test_intr_handle) < 0) {
364a9de470cSBruce Richardson printf("fail to disable interrupt on a simulated handler\n");
365a9de470cSBruce Richardson return -1;
366a9de470cSBruce Richardson }
367a9de470cSBruce Richardson
368a9de470cSBruce Richardson test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_UIO];
369db86bf26SHarman Kalra if (rte_intr_disable(test_intr_handle) == 0) {
370a9de470cSBruce Richardson printf("unexpectedly disable a specific intr_handle "
371a9de470cSBruce Richardson "successfully\n");
372a9de470cSBruce Richardson return -1;
373a9de470cSBruce Richardson }
374a9de470cSBruce Richardson
375a9de470cSBruce Richardson return 0;
376a9de470cSBruce Richardson }
377a9de470cSBruce Richardson
378a9de470cSBruce Richardson /**
379a9de470cSBruce Richardson * Check the full path of a specified type of interrupt simulated.
380a9de470cSBruce Richardson */
381a9de470cSBruce Richardson static int
test_interrupt_full_path_check(enum test_interrupt_handle_type intr_type)382a9de470cSBruce Richardson test_interrupt_full_path_check(enum test_interrupt_handle_type intr_type)
383a9de470cSBruce Richardson {
384a9de470cSBruce Richardson int count;
385db86bf26SHarman Kalra struct rte_intr_handle *test_intr_handle;
386a9de470cSBruce Richardson
387a9de470cSBruce Richardson flag = 0;
388a9de470cSBruce Richardson test_intr_handle = intr_handles[intr_type];
389a9de470cSBruce Richardson test_intr_type = intr_type;
390db86bf26SHarman Kalra if (rte_intr_callback_register(test_intr_handle,
391db86bf26SHarman Kalra test_interrupt_callback, test_intr_handle) < 0) {
392a9de470cSBruce Richardson printf("fail to register callback\n");
393a9de470cSBruce Richardson return -1;
394a9de470cSBruce Richardson }
395a9de470cSBruce Richardson
396a9de470cSBruce Richardson if (test_interrupt_trigger_interrupt() < 0)
397a9de470cSBruce Richardson return -1;
398a9de470cSBruce Richardson
399a9de470cSBruce Richardson /* check flag */
400a9de470cSBruce Richardson for (count = 0; flag == 0 && count < 3; count++)
401a9de470cSBruce Richardson rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL);
402a9de470cSBruce Richardson
403a9de470cSBruce Richardson rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL);
40473afc9dfSAaron Conole while ((count =
405db86bf26SHarman Kalra rte_intr_callback_unregister(test_intr_handle,
40673afc9dfSAaron Conole test_interrupt_callback,
407db86bf26SHarman Kalra test_intr_handle)) < 0) {
40873afc9dfSAaron Conole if (count != -EAGAIN)
409a9de470cSBruce Richardson return -1;
41073afc9dfSAaron Conole }
411a9de470cSBruce Richardson
412a9de470cSBruce Richardson if (flag == 0) {
413a9de470cSBruce Richardson printf("callback has not been called\n");
414a9de470cSBruce Richardson return -1;
415a9de470cSBruce Richardson } else if (flag < 0) {
416a9de470cSBruce Richardson printf("it has internal error in callback\n");
417a9de470cSBruce Richardson return -1;
418a9de470cSBruce Richardson }
419a9de470cSBruce Richardson
420a9de470cSBruce Richardson return 0;
421a9de470cSBruce Richardson }
422a9de470cSBruce Richardson
423a9de470cSBruce Richardson /**
424a9de470cSBruce Richardson * Main function of testing interrupt.
425a9de470cSBruce Richardson */
426a9de470cSBruce Richardson static int
test_interrupt(void)427a9de470cSBruce Richardson test_interrupt(void)
428a9de470cSBruce Richardson {
429a9de470cSBruce Richardson int ret = -1;
430db86bf26SHarman Kalra struct rte_intr_handle *test_intr_handle;
431a9de470cSBruce Richardson
432d18eb797SJie Zhou if (RTE_EXEC_ENV_IS_WINDOWS)
433d18eb797SJie Zhou return TEST_SKIPPED;
434d18eb797SJie Zhou
435a9de470cSBruce Richardson if (test_interrupt_init() < 0) {
436a9de470cSBruce Richardson printf("fail to initialize for testing interrupt\n");
437db86bf26SHarman Kalra goto out;
438a9de470cSBruce Richardson }
439a9de470cSBruce Richardson
440a9de470cSBruce Richardson printf("Check unknown valid interrupt full path\n");
441a9de470cSBruce Richardson if (test_interrupt_full_path_check(TEST_INTERRUPT_HANDLE_VALID) < 0) {
442a9de470cSBruce Richardson printf("failure occurred during checking unknown valid "
443a9de470cSBruce Richardson "interrupt full path\n");
444a9de470cSBruce Richardson goto out;
445a9de470cSBruce Richardson }
446a9de470cSBruce Richardson
447a9de470cSBruce Richardson printf("Check valid UIO interrupt full path\n");
448a9de470cSBruce Richardson if (test_interrupt_full_path_check(TEST_INTERRUPT_HANDLE_VALID_UIO)
449a9de470cSBruce Richardson < 0) {
450a9de470cSBruce Richardson printf("failure occurred during checking valid UIO interrupt "
451a9de470cSBruce Richardson "full path\n");
452a9de470cSBruce Richardson goto out;
453a9de470cSBruce Richardson }
454a9de470cSBruce Richardson
455a9de470cSBruce Richardson printf("Check valid device event interrupt full path\n");
456a9de470cSBruce Richardson if (test_interrupt_full_path_check(
457a9de470cSBruce Richardson TEST_INTERRUPT_HANDLE_VALID_DEV_EVENT) < 0) {
458a9de470cSBruce Richardson printf("failure occurred during checking valid device event "
459a9de470cSBruce Richardson "interrupt full path\n");
460a9de470cSBruce Richardson goto out;
461a9de470cSBruce Richardson }
462a9de470cSBruce Richardson
463a9de470cSBruce Richardson printf("Check valid alarm interrupt full path\n");
464a9de470cSBruce Richardson if (test_interrupt_full_path_check(
465a9de470cSBruce Richardson TEST_INTERRUPT_HANDLE_VALID_ALARM) < 0) {
466a9de470cSBruce Richardson printf("failure occurred during checking valid alarm "
467a9de470cSBruce Richardson "interrupt full path\n");
468a9de470cSBruce Richardson goto out;
469a9de470cSBruce Richardson }
470a9de470cSBruce Richardson
471a9de470cSBruce Richardson printf("start register/unregister test\n");
472a9de470cSBruce Richardson /* check if it will fail to register cb with intr_handle = NULL */
473a9de470cSBruce Richardson if (rte_intr_callback_register(NULL, test_interrupt_callback,
474a9de470cSBruce Richardson NULL) == 0) {
475a9de470cSBruce Richardson printf("unexpectedly register successfully with null "
476a9de470cSBruce Richardson "intr_handle\n");
477a9de470cSBruce Richardson goto out;
478a9de470cSBruce Richardson }
479a9de470cSBruce Richardson
480a9de470cSBruce Richardson /* check if it will fail to register cb with invalid intr_handle */
481a9de470cSBruce Richardson test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
482db86bf26SHarman Kalra if (rte_intr_callback_register(test_intr_handle,
483db86bf26SHarman Kalra test_interrupt_callback, test_intr_handle) == 0) {
484a9de470cSBruce Richardson printf("unexpectedly register successfully with invalid "
485a9de470cSBruce Richardson "intr_handle\n");
486a9de470cSBruce Richardson goto out;
487a9de470cSBruce Richardson }
488a9de470cSBruce Richardson
489a9de470cSBruce Richardson /* check if it will fail to register without callback */
490a9de470cSBruce Richardson test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
491db86bf26SHarman Kalra if (rte_intr_callback_register(test_intr_handle, NULL,
492db86bf26SHarman Kalra test_intr_handle) == 0) {
493a9de470cSBruce Richardson printf("unexpectedly register successfully with "
494a9de470cSBruce Richardson "null callback\n");
495a9de470cSBruce Richardson goto out;
496a9de470cSBruce Richardson }
497a9de470cSBruce Richardson
498a9de470cSBruce Richardson /* check if it will fail to unregister cb with intr_handle = NULL */
499a9de470cSBruce Richardson if (rte_intr_callback_unregister(NULL,
500a9de470cSBruce Richardson test_interrupt_callback, NULL) > 0) {
501a9de470cSBruce Richardson printf("unexpectedly unregister successfully with "
502a9de470cSBruce Richardson "null intr_handle\n");
503a9de470cSBruce Richardson goto out;
504a9de470cSBruce Richardson }
505a9de470cSBruce Richardson
506a9de470cSBruce Richardson /* check if it will fail to unregister cb with invalid intr_handle */
507a9de470cSBruce Richardson test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
508db86bf26SHarman Kalra if (rte_intr_callback_unregister(test_intr_handle,
509db86bf26SHarman Kalra test_interrupt_callback, test_intr_handle) > 0) {
510a9de470cSBruce Richardson printf("unexpectedly unregister successfully with "
511a9de470cSBruce Richardson "invalid intr_handle\n");
512a9de470cSBruce Richardson goto out;
513a9de470cSBruce Richardson }
514a9de470cSBruce Richardson
515a9de470cSBruce Richardson /* check if it is ok to register the same intr_handle twice */
516a9de470cSBruce Richardson test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
517db86bf26SHarman Kalra if (rte_intr_callback_register(test_intr_handle,
518db86bf26SHarman Kalra test_interrupt_callback, test_intr_handle) < 0) {
519a9de470cSBruce Richardson printf("it fails to register test_interrupt_callback\n");
520a9de470cSBruce Richardson goto out;
521a9de470cSBruce Richardson }
522db86bf26SHarman Kalra if (rte_intr_callback_register(test_intr_handle,
523db86bf26SHarman Kalra test_interrupt_callback_1, test_intr_handle) < 0) {
524a9de470cSBruce Richardson printf("it fails to register test_interrupt_callback_1\n");
525a9de470cSBruce Richardson goto out;
526a9de470cSBruce Richardson }
527a9de470cSBruce Richardson /* check if it will fail to unregister with invalid parameter */
528db86bf26SHarman Kalra if (rte_intr_callback_unregister(test_intr_handle,
529a9de470cSBruce Richardson test_interrupt_callback, (void *)0xff) != 0) {
530a9de470cSBruce Richardson printf("unexpectedly unregisters successfully with "
531a9de470cSBruce Richardson "invalid arg\n");
532a9de470cSBruce Richardson goto out;
533a9de470cSBruce Richardson }
534db86bf26SHarman Kalra if (rte_intr_callback_unregister(test_intr_handle,
535db86bf26SHarman Kalra test_interrupt_callback, test_intr_handle) <= 0) {
536a9de470cSBruce Richardson printf("it fails to unregister test_interrupt_callback\n");
537a9de470cSBruce Richardson goto out;
538a9de470cSBruce Richardson }
539db86bf26SHarman Kalra if (rte_intr_callback_unregister(test_intr_handle,
540a9de470cSBruce Richardson test_interrupt_callback_1, (void *)-1) <= 0) {
541a9de470cSBruce Richardson printf("it fails to unregister test_interrupt_callback_1 "
542a9de470cSBruce Richardson "for all\n");
543a9de470cSBruce Richardson goto out;
544a9de470cSBruce Richardson }
545a9de470cSBruce Richardson rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL);
546a9de470cSBruce Richardson
547a9de470cSBruce Richardson printf("start interrupt enable/disable test\n");
548a9de470cSBruce Richardson /* check interrupt enable/disable functions */
549a9de470cSBruce Richardson if (test_interrupt_enable() < 0) {
550a9de470cSBruce Richardson printf("fail to check interrupt enabling\n");
551a9de470cSBruce Richardson goto out;
552a9de470cSBruce Richardson }
553a9de470cSBruce Richardson rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL);
554a9de470cSBruce Richardson
555a9de470cSBruce Richardson if (test_interrupt_disable() < 0) {
556a9de470cSBruce Richardson printf("fail to check interrupt disabling\n");
557a9de470cSBruce Richardson goto out;
558a9de470cSBruce Richardson }
559a9de470cSBruce Richardson rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL);
560a9de470cSBruce Richardson
561a9de470cSBruce Richardson ret = 0;
562a9de470cSBruce Richardson
563a9de470cSBruce Richardson out:
564a9de470cSBruce Richardson printf("Clearing for interrupt tests\n");
565a9de470cSBruce Richardson /* clear registered callbacks */
566a9de470cSBruce Richardson test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
567db86bf26SHarman Kalra rte_intr_callback_unregister(test_intr_handle,
568a9de470cSBruce Richardson test_interrupt_callback, (void *)-1);
569db86bf26SHarman Kalra rte_intr_callback_unregister(test_intr_handle,
570a9de470cSBruce Richardson test_interrupt_callback_1, (void *)-1);
571a9de470cSBruce Richardson
572a9de470cSBruce Richardson test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_UIO];
573db86bf26SHarman Kalra rte_intr_callback_unregister(test_intr_handle,
574a9de470cSBruce Richardson test_interrupt_callback, (void *)-1);
575db86bf26SHarman Kalra rte_intr_callback_unregister(test_intr_handle,
576a9de470cSBruce Richardson test_interrupt_callback_1, (void *)-1);
577a9de470cSBruce Richardson
578a9de470cSBruce Richardson test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_ALARM];
579db86bf26SHarman Kalra rte_intr_callback_unregister(test_intr_handle,
580a9de470cSBruce Richardson test_interrupt_callback, (void *)-1);
581db86bf26SHarman Kalra rte_intr_callback_unregister(test_intr_handle,
582a9de470cSBruce Richardson test_interrupt_callback_1, (void *)-1);
583a9de470cSBruce Richardson
584a9de470cSBruce Richardson test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_DEV_EVENT];
585db86bf26SHarman Kalra rte_intr_callback_unregister(test_intr_handle,
586a9de470cSBruce Richardson test_interrupt_callback, (void *)-1);
587db86bf26SHarman Kalra rte_intr_callback_unregister(test_intr_handle,
588a9de470cSBruce Richardson test_interrupt_callback_1, (void *)-1);
589a9de470cSBruce Richardson
590a9de470cSBruce Richardson rte_delay_ms(2 * TEST_INTERRUPT_CHECK_INTERVAL);
591a9de470cSBruce Richardson /* deinit */
592a9de470cSBruce Richardson test_interrupt_deinit();
593a9de470cSBruce Richardson
594a9de470cSBruce Richardson return ret;
595a9de470cSBruce Richardson }
596a9de470cSBruce Richardson
597*e0a8442cSBruce Richardson REGISTER_FAST_TEST(interrupt_autotest, true, true, test_interrupt);
598