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