xref: /dpdk/app/test/test_interrupts.c (revision db86bf263de8462345eaae7a5ab0d1c78c2be06c)
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 {
19*db86bf26SHarman 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;
30*db86bf26SHarman 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
51a9de470cSBruce Richardson test_interrupt_handle_sanity_check(struct rte_intr_handle *intr_handle)
52a9de470cSBruce Richardson {
53*db86bf26SHarman 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
63a9de470cSBruce Richardson test_interrupt_init(void)
64a9de470cSBruce Richardson {
65*db86bf26SHarman Kalra 	struct rte_intr_handle *test_intr_handle;
66*db86bf26SHarman Kalra 	int i;
67*db86bf26SHarman Kalra 
68a9de470cSBruce Richardson 	if (pipe(pfds.pipefd) < 0)
69a9de470cSBruce Richardson 		return -1;
70a9de470cSBruce Richardson 
71*db86bf26SHarman Kalra 	for (i = 0; i < TEST_INTERRUPT_HANDLE_MAX; i++) {
72*db86bf26SHarman Kalra 		intr_handles[i] =
73*db86bf26SHarman Kalra 			rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE);
74*db86bf26SHarman Kalra 		if (!intr_handles[i])
75*db86bf26SHarman Kalra 			return -1;
76*db86bf26SHarman Kalra 	}
77a9de470cSBruce Richardson 
78*db86bf26SHarman Kalra 	test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
79*db86bf26SHarman Kalra 	if (rte_intr_fd_set(test_intr_handle, -1))
80*db86bf26SHarman Kalra 		return -1;
81*db86bf26SHarman Kalra 	if (rte_intr_type_set(test_intr_handle, RTE_INTR_HANDLE_UNKNOWN))
82*db86bf26SHarman Kalra 		return -1;
83a9de470cSBruce Richardson 
84*db86bf26SHarman Kalra 	test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
85*db86bf26SHarman Kalra 	if (rte_intr_fd_set(test_intr_handle, pfds.readfd))
86*db86bf26SHarman Kalra 		return -1;
87*db86bf26SHarman Kalra 	if (rte_intr_type_set(test_intr_handle, RTE_INTR_HANDLE_UNKNOWN))
88*db86bf26SHarman Kalra 		return -1;
89a9de470cSBruce Richardson 
90*db86bf26SHarman Kalra 	test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_UIO];
91*db86bf26SHarman Kalra 	if (rte_intr_fd_set(test_intr_handle, pfds.readfd))
92*db86bf26SHarman Kalra 		return -1;
93*db86bf26SHarman Kalra 	if (rte_intr_type_set(test_intr_handle, RTE_INTR_HANDLE_UIO))
94*db86bf26SHarman Kalra 		return -1;
95a9de470cSBruce Richardson 
96*db86bf26SHarman Kalra 	test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_ALARM];
97*db86bf26SHarman Kalra 	if (rte_intr_fd_set(test_intr_handle, pfds.readfd))
98*db86bf26SHarman Kalra 		return -1;
99*db86bf26SHarman Kalra 	if (rte_intr_type_set(test_intr_handle, RTE_INTR_HANDLE_ALARM))
100*db86bf26SHarman Kalra 		return -1;
101a9de470cSBruce Richardson 
102*db86bf26SHarman Kalra 	test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_DEV_EVENT];
103*db86bf26SHarman Kalra 	if (rte_intr_fd_set(test_intr_handle, pfds.readfd))
104*db86bf26SHarman Kalra 		return -1;
105*db86bf26SHarman Kalra 	if (rte_intr_type_set(test_intr_handle, RTE_INTR_HANDLE_DEV_EVENT))
106*db86bf26SHarman Kalra 		return -1;
107*db86bf26SHarman Kalra 
108*db86bf26SHarman Kalra 	test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_CASE1];
109*db86bf26SHarman Kalra 	if (rte_intr_fd_set(test_intr_handle, pfds.writefd))
110*db86bf26SHarman Kalra 		return -1;
111*db86bf26SHarman Kalra 	if (rte_intr_type_set(test_intr_handle, RTE_INTR_HANDLE_UIO))
112*db86bf26SHarman 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
121a9de470cSBruce Richardson test_interrupt_deinit(void)
122a9de470cSBruce Richardson {
123*db86bf26SHarman Kalra 	int i;
124*db86bf26SHarman Kalra 
125*db86bf26SHarman Kalra 	for (i = 0; i < TEST_INTERRUPT_HANDLE_MAX; i++)
126*db86bf26SHarman 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
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
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 
155*db86bf26SHarman Kalra 	if (rte_intr_fd_get(intr_handle_l) !=
156*db86bf26SHarman Kalra 	    rte_intr_fd_get(intr_handle_r) ||
157*db86bf26SHarman Kalra 		rte_intr_type_get(intr_handle_l) !=
158*db86bf26SHarman 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
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
175a9de470cSBruce Richardson test_interrupt_init(void)
176a9de470cSBruce Richardson {
177a9de470cSBruce Richardson 	return 0;
178a9de470cSBruce Richardson }
179a9de470cSBruce Richardson 
180a9de470cSBruce Richardson static int
181a9de470cSBruce Richardson test_interrupt_deinit(void)
182a9de470cSBruce Richardson {
183a9de470cSBruce Richardson 	return 0;
184a9de470cSBruce Richardson }
185a9de470cSBruce Richardson 
186a9de470cSBruce Richardson static int
187a9de470cSBruce Richardson test_interrupt_trigger_interrupt(void)
188a9de470cSBruce Richardson {
189a9de470cSBruce Richardson 	return 0;
190a9de470cSBruce Richardson }
191a9de470cSBruce Richardson 
192a9de470cSBruce Richardson static int
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
207a9de470cSBruce Richardson test_interrupt_callback(void *arg)
208a9de470cSBruce Richardson {
209a9de470cSBruce Richardson 	struct rte_intr_handle *intr_handle = arg;
210*db86bf26SHarman Kalra 	struct rte_intr_handle *test_intr_handle;
211*db86bf26SHarman 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 
232*db86bf26SHarman Kalra 	test_intr_handle = intr_handles[test_intr_type];
233*db86bf26SHarman 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
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
255a9de470cSBruce Richardson test_interrupt_enable(void)
256a9de470cSBruce Richardson {
257*db86bf26SHarman 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];
267*db86bf26SHarman 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];
275*db86bf26SHarman 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];
283*db86bf26SHarman 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];
291*db86bf26SHarman 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];
299*db86bf26SHarman 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];
305*db86bf26SHarman 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
318a9de470cSBruce Richardson test_interrupt_disable(void)
319a9de470cSBruce Richardson {
320*db86bf26SHarman 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];
331*db86bf26SHarman 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];
339*db86bf26SHarman 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];
347*db86bf26SHarman 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];
355*db86bf26SHarman 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];
363*db86bf26SHarman 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];
369*db86bf26SHarman 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
382a9de470cSBruce Richardson test_interrupt_full_path_check(enum test_interrupt_handle_type intr_type)
383a9de470cSBruce Richardson {
384a9de470cSBruce Richardson 	int count;
385*db86bf26SHarman 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;
390*db86bf26SHarman Kalra 	if (rte_intr_callback_register(test_intr_handle,
391*db86bf26SHarman 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 =
405*db86bf26SHarman Kalra 		rte_intr_callback_unregister(test_intr_handle,
40673afc9dfSAaron Conole 					     test_interrupt_callback,
407*db86bf26SHarman 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
427a9de470cSBruce Richardson test_interrupt(void)
428a9de470cSBruce Richardson {
429a9de470cSBruce Richardson 	int ret = -1;
430*db86bf26SHarman Kalra 	struct rte_intr_handle *test_intr_handle;
431a9de470cSBruce Richardson 
432a9de470cSBruce Richardson 	if (test_interrupt_init() < 0) {
433a9de470cSBruce Richardson 		printf("fail to initialize for testing interrupt\n");
434*db86bf26SHarman Kalra 		goto out;
435a9de470cSBruce Richardson 	}
436a9de470cSBruce Richardson 
437a9de470cSBruce Richardson 	printf("Check unknown valid interrupt full path\n");
438a9de470cSBruce Richardson 	if (test_interrupt_full_path_check(TEST_INTERRUPT_HANDLE_VALID) < 0) {
439a9de470cSBruce Richardson 		printf("failure occurred during checking unknown valid "
440a9de470cSBruce Richardson 						"interrupt full path\n");
441a9de470cSBruce Richardson 		goto out;
442a9de470cSBruce Richardson 	}
443a9de470cSBruce Richardson 
444a9de470cSBruce Richardson 	printf("Check valid UIO interrupt full path\n");
445a9de470cSBruce Richardson 	if (test_interrupt_full_path_check(TEST_INTERRUPT_HANDLE_VALID_UIO)
446a9de470cSBruce Richardson 									< 0) {
447a9de470cSBruce Richardson 		printf("failure occurred during checking valid UIO interrupt "
448a9de470cSBruce Richardson 								"full path\n");
449a9de470cSBruce Richardson 		goto out;
450a9de470cSBruce Richardson 	}
451a9de470cSBruce Richardson 
452a9de470cSBruce Richardson 	printf("Check valid device event interrupt full path\n");
453a9de470cSBruce Richardson 	if (test_interrupt_full_path_check(
454a9de470cSBruce Richardson 		TEST_INTERRUPT_HANDLE_VALID_DEV_EVENT) < 0) {
455a9de470cSBruce Richardson 		printf("failure occurred during checking valid device event "
456a9de470cSBruce Richardson 						"interrupt full path\n");
457a9de470cSBruce Richardson 		goto out;
458a9de470cSBruce Richardson 	}
459a9de470cSBruce Richardson 
460a9de470cSBruce Richardson 	printf("Check valid alarm interrupt full path\n");
461a9de470cSBruce Richardson 	if (test_interrupt_full_path_check(
462a9de470cSBruce Richardson 		TEST_INTERRUPT_HANDLE_VALID_ALARM) < 0) {
463a9de470cSBruce Richardson 		printf("failure occurred during checking valid alarm "
464a9de470cSBruce Richardson 						"interrupt full path\n");
465a9de470cSBruce Richardson 		goto out;
466a9de470cSBruce Richardson 	}
467a9de470cSBruce Richardson 
468a9de470cSBruce Richardson 	printf("start register/unregister test\n");
469a9de470cSBruce Richardson 	/* check if it will fail to register cb with intr_handle = NULL */
470a9de470cSBruce Richardson 	if (rte_intr_callback_register(NULL, test_interrupt_callback,
471a9de470cSBruce Richardson 							NULL) == 0) {
472a9de470cSBruce Richardson 		printf("unexpectedly register successfully with null "
473a9de470cSBruce Richardson 			"intr_handle\n");
474a9de470cSBruce Richardson 		goto out;
475a9de470cSBruce Richardson 	}
476a9de470cSBruce Richardson 
477a9de470cSBruce Richardson 	/* check if it will fail to register cb with invalid intr_handle */
478a9de470cSBruce Richardson 	test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
479*db86bf26SHarman Kalra 	if (rte_intr_callback_register(test_intr_handle,
480*db86bf26SHarman Kalra 			test_interrupt_callback, test_intr_handle) == 0) {
481a9de470cSBruce Richardson 		printf("unexpectedly register successfully with invalid "
482a9de470cSBruce Richardson 			"intr_handle\n");
483a9de470cSBruce Richardson 		goto out;
484a9de470cSBruce Richardson 	}
485a9de470cSBruce Richardson 
486a9de470cSBruce Richardson 	/* check if it will fail to register without callback */
487a9de470cSBruce Richardson 	test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
488*db86bf26SHarman Kalra 	if (rte_intr_callback_register(test_intr_handle, NULL,
489*db86bf26SHarman Kalra 				       test_intr_handle) == 0) {
490a9de470cSBruce Richardson 		printf("unexpectedly register successfully with "
491a9de470cSBruce Richardson 			"null callback\n");
492a9de470cSBruce Richardson 		goto out;
493a9de470cSBruce Richardson 	}
494a9de470cSBruce Richardson 
495a9de470cSBruce Richardson 	/* check if it will fail to unregister cb with intr_handle = NULL */
496a9de470cSBruce Richardson 	if (rte_intr_callback_unregister(NULL,
497a9de470cSBruce Richardson 			test_interrupt_callback, NULL) > 0) {
498a9de470cSBruce Richardson 		printf("unexpectedly unregister successfully with "
499a9de470cSBruce Richardson 			"null intr_handle\n");
500a9de470cSBruce Richardson 		goto out;
501a9de470cSBruce Richardson 	}
502a9de470cSBruce Richardson 
503a9de470cSBruce Richardson 	/* check if it will fail to unregister cb with invalid intr_handle */
504a9de470cSBruce Richardson 	test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
505*db86bf26SHarman Kalra 	if (rte_intr_callback_unregister(test_intr_handle,
506*db86bf26SHarman Kalra 			test_interrupt_callback, test_intr_handle) > 0) {
507a9de470cSBruce Richardson 		printf("unexpectedly unregister successfully with "
508a9de470cSBruce Richardson 			"invalid intr_handle\n");
509a9de470cSBruce Richardson 		goto out;
510a9de470cSBruce Richardson 	}
511a9de470cSBruce Richardson 
512a9de470cSBruce Richardson 	/* check if it is ok to register the same intr_handle twice */
513a9de470cSBruce Richardson 	test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
514*db86bf26SHarman Kalra 	if (rte_intr_callback_register(test_intr_handle,
515*db86bf26SHarman Kalra 			test_interrupt_callback, test_intr_handle) < 0) {
516a9de470cSBruce Richardson 		printf("it fails to register test_interrupt_callback\n");
517a9de470cSBruce Richardson 		goto out;
518a9de470cSBruce Richardson 	}
519*db86bf26SHarman Kalra 	if (rte_intr_callback_register(test_intr_handle,
520*db86bf26SHarman Kalra 			test_interrupt_callback_1, test_intr_handle) < 0) {
521a9de470cSBruce Richardson 		printf("it fails to register test_interrupt_callback_1\n");
522a9de470cSBruce Richardson 		goto out;
523a9de470cSBruce Richardson 	}
524a9de470cSBruce Richardson 	/* check if it will fail to unregister with invalid parameter */
525*db86bf26SHarman Kalra 	if (rte_intr_callback_unregister(test_intr_handle,
526a9de470cSBruce Richardson 			test_interrupt_callback, (void *)0xff) != 0) {
527a9de470cSBruce Richardson 		printf("unexpectedly unregisters successfully with "
528a9de470cSBruce Richardson 							"invalid arg\n");
529a9de470cSBruce Richardson 		goto out;
530a9de470cSBruce Richardson 	}
531*db86bf26SHarman Kalra 	if (rte_intr_callback_unregister(test_intr_handle,
532*db86bf26SHarman Kalra 			test_interrupt_callback, test_intr_handle) <= 0) {
533a9de470cSBruce Richardson 		printf("it fails to unregister test_interrupt_callback\n");
534a9de470cSBruce Richardson 		goto out;
535a9de470cSBruce Richardson 	}
536*db86bf26SHarman Kalra 	if (rte_intr_callback_unregister(test_intr_handle,
537a9de470cSBruce Richardson 			test_interrupt_callback_1, (void *)-1) <= 0) {
538a9de470cSBruce Richardson 		printf("it fails to unregister test_interrupt_callback_1 "
539a9de470cSBruce Richardson 			"for all\n");
540a9de470cSBruce Richardson 		goto out;
541a9de470cSBruce Richardson 	}
542a9de470cSBruce Richardson 	rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL);
543a9de470cSBruce Richardson 
544a9de470cSBruce Richardson 	printf("start interrupt enable/disable test\n");
545a9de470cSBruce Richardson 	/* check interrupt enable/disable functions */
546a9de470cSBruce Richardson 	if (test_interrupt_enable() < 0) {
547a9de470cSBruce Richardson 		printf("fail to check interrupt enabling\n");
548a9de470cSBruce Richardson 		goto out;
549a9de470cSBruce Richardson 	}
550a9de470cSBruce Richardson 	rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL);
551a9de470cSBruce Richardson 
552a9de470cSBruce Richardson 	if (test_interrupt_disable() < 0) {
553a9de470cSBruce Richardson 		printf("fail to check interrupt disabling\n");
554a9de470cSBruce Richardson 		goto out;
555a9de470cSBruce Richardson 	}
556a9de470cSBruce Richardson 	rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL);
557a9de470cSBruce Richardson 
558a9de470cSBruce Richardson 	ret = 0;
559a9de470cSBruce Richardson 
560a9de470cSBruce Richardson out:
561a9de470cSBruce Richardson 	printf("Clearing for interrupt tests\n");
562a9de470cSBruce Richardson 	/* clear registered callbacks */
563a9de470cSBruce Richardson 	test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
564*db86bf26SHarman Kalra 	rte_intr_callback_unregister(test_intr_handle,
565a9de470cSBruce Richardson 			test_interrupt_callback, (void *)-1);
566*db86bf26SHarman Kalra 	rte_intr_callback_unregister(test_intr_handle,
567a9de470cSBruce Richardson 			test_interrupt_callback_1, (void *)-1);
568a9de470cSBruce Richardson 
569a9de470cSBruce Richardson 	test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_UIO];
570*db86bf26SHarman Kalra 	rte_intr_callback_unregister(test_intr_handle,
571a9de470cSBruce Richardson 			test_interrupt_callback, (void *)-1);
572*db86bf26SHarman Kalra 	rte_intr_callback_unregister(test_intr_handle,
573a9de470cSBruce Richardson 			test_interrupt_callback_1, (void *)-1);
574a9de470cSBruce Richardson 
575a9de470cSBruce Richardson 	test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_ALARM];
576*db86bf26SHarman Kalra 	rte_intr_callback_unregister(test_intr_handle,
577a9de470cSBruce Richardson 			test_interrupt_callback, (void *)-1);
578*db86bf26SHarman Kalra 	rte_intr_callback_unregister(test_intr_handle,
579a9de470cSBruce Richardson 			test_interrupt_callback_1, (void *)-1);
580a9de470cSBruce Richardson 
581a9de470cSBruce Richardson 	test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID_DEV_EVENT];
582*db86bf26SHarman Kalra 	rte_intr_callback_unregister(test_intr_handle,
583a9de470cSBruce Richardson 			test_interrupt_callback, (void *)-1);
584*db86bf26SHarman Kalra 	rte_intr_callback_unregister(test_intr_handle,
585a9de470cSBruce Richardson 			test_interrupt_callback_1, (void *)-1);
586a9de470cSBruce Richardson 
587a9de470cSBruce Richardson 	rte_delay_ms(2 * TEST_INTERRUPT_CHECK_INTERVAL);
588a9de470cSBruce Richardson 	/* deinit */
589a9de470cSBruce Richardson 	test_interrupt_deinit();
590a9de470cSBruce Richardson 
591a9de470cSBruce Richardson 	return ret;
592a9de470cSBruce Richardson }
593a9de470cSBruce Richardson 
594a9de470cSBruce Richardson REGISTER_TEST_COMMAND(interrupt_autotest, test_interrupt);
595