4 * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * version: DPDK.L.1.2.3-3
40 #include <cmdline_parse.h>
42 #include <rte_common.h>
43 #include <rte_cycles.h>
44 #include <rte_interrupts.h>
48 #define TEST_INTERRUPT_CHECK_INTERVAL 1000 /* ms */
50 enum test_interrupt_handl_type {
51 TEST_INTERRUPT_HANDLE_INVALID,
52 TEST_INTERRUPT_HANDLE_VALID,
53 TEST_INTERRUPT_HANDLE_CASE1,
54 TEST_INTERRUPT_HANDLE_MAX
57 static volatile int flag;
58 static struct rte_intr_handle intr_handles[TEST_INTERRUPT_HANDLE_MAX];
60 #ifdef RTE_EXEC_ENV_LINUXAPP
71 static union intr_pipefds pfds;
74 test_interrupt_handle_sanity_check(struct rte_intr_handle *intr_handle)
76 if (!intr_handle || intr_handle->fd < 0)
83 test_interrupt_init(void)
85 if (pipe(pfds.pipefd) < 0)
88 intr_handles[TEST_INTERRUPT_HANDLE_INVALID].fd = -1;
89 intr_handles[TEST_INTERRUPT_HANDLE_INVALID].type = RTE_INTR_HANDLE_UNKNOWN;
91 intr_handles[TEST_INTERRUPT_HANDLE_VALID].fd = pfds.readfd;
92 intr_handles[TEST_INTERRUPT_HANDLE_VALID].type = RTE_INTR_HANDLE_UNKNOWN;
94 intr_handles[TEST_INTERRUPT_HANDLE_CASE1].fd = pfds.readfd;
95 intr_handles[TEST_INTERRUPT_HANDLE_CASE1].type = RTE_INTR_HANDLE_ALARM;
101 test_interrupt_deinit(void)
103 close(pfds.pipefd[0]);
104 close(pfds.pipefd[1]);
110 test_interrupt_trigger_interrupt(void)
112 if (write(pfds.writefd, "1", 1) < 0)
119 test_interrupt_handle_compare(struct rte_intr_handle *intr_handle_l,
120 struct rte_intr_handle *intr_handle_r)
122 if (!intr_handle_l || !intr_handle_r)
125 if (intr_handle_l->fd != intr_handle_r->fd ||
126 intr_handle_l->type != intr_handle_r->type)
133 /* to be implemented for baremetal later */
135 test_interrupt_handle_sanity_check(struct rte_intr_handle *intr_handle)
137 RTE_SET_USED(intr_handle);
143 test_interrupt_init(void)
149 test_interrupt_deinit(void)
155 test_interrupt_trigger_interrupt(void)
161 test_interrupt_handle_compare(struct rte_intr_handle *intr_handle_l,
162 struct rte_intr_handle *intr_handle_r)
169 #endif /* RTE_EXEC_ENV_LINUXAPP */
172 test_interrupt_callback(struct rte_intr_handle *intr_handle, void *arg)
174 if (test_interrupt_handle_sanity_check(intr_handle) < 0) {
175 printf("null or invalid intr_handle for %s\n", __FUNCTION__);
179 if (rte_intr_callback_unregister(intr_handle,
180 test_interrupt_callback, arg) <= 0) {
181 printf("fail to unregister callback\n");
185 if (test_interrupt_handle_compare(intr_handle,
186 &(intr_handles[TEST_INTERRUPT_HANDLE_VALID])) == 0) {
192 test_interrupt_callback_1(struct rte_intr_handle *intr_handle, void *arg)
194 if (test_interrupt_handle_sanity_check(intr_handle) < 0) {
195 printf("null or invalid intr_handle for %s\n", __FUNCTION__);
198 if (rte_intr_callback_unregister(intr_handle,
199 test_interrupt_callback_1, arg) <= 0) {
200 printf("fail to unregister callback\n");
206 test_interrupt_enable(void)
208 struct rte_intr_handle test_intr_handle;
210 /* check with null intr_handle */
211 if (rte_intr_enable(NULL) == 0) {
212 printf("unexpectedly enable null intr_handle successfully\n");
216 /* check with invalid intr_handle */
217 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
218 if (rte_intr_enable(&test_intr_handle) == 0) {
219 printf("unexpectedly enable invalid intr_handle "
224 /* check with valid intr_handle */
225 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
226 if (rte_intr_enable(&test_intr_handle) == 0) {
227 printf("unexpectedly enable a specific intr_handle "
232 /* check with specific valid intr_handle */
233 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_CASE1];
234 if (rte_intr_enable(&test_intr_handle) == 0) {
235 printf("unexpectedly enable a specific intr_handle "
244 test_interrupt_disable(void)
246 struct rte_intr_handle test_intr_handle;
248 /* check with null intr_handle */
249 if (rte_intr_disable(NULL) == 0) {
250 printf("unexpectedly disable null intr_handle "
255 /* check with invalid intr_handle */
256 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
257 if (rte_intr_disable(&test_intr_handle) == 0) {
258 printf("unexpectedly disable invalid intr_handle "
263 /* check with valid intr_handle */
264 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
265 if (rte_intr_disable(&test_intr_handle) == 0) {
266 printf("unexpectedly disable a specific intr_handle "
271 /* check with specific valid intr_handle */
272 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_CASE1];
273 if (rte_intr_disable(&test_intr_handle) == 0) {
274 printf("unexpectedly disable a specific intr_handle "
285 int count = 0, ret = -1;
286 struct rte_intr_handle test_intr_handle;
288 if (test_interrupt_init() < 0) {
289 printf("fail to do test init\n");
293 printf("check if callback registered can be called\n");
295 /* check if callback registered can be called */
297 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
298 if (rte_intr_callback_register(&test_intr_handle,
299 test_interrupt_callback, NULL) < 0) {
300 printf("fail to register callback\n");
303 /* trigger an interrupt and then check if the callback can be called */
304 if (test_interrupt_trigger_interrupt() < 0) {
305 printf("fail to trigger an interrupt\n");
308 /* check flag in 3 seconds */
309 while (flag == 0 && count++ < 3)
310 rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL);
312 printf("registered callback has not been called\n");
317 printf("start register/unregister test\n");
319 /* check if it will fail to register cb with intr_handle = NULL */
320 if (rte_intr_callback_register(NULL, test_interrupt_callback,
322 printf("unexpectedly register successfully with null "
327 /* check if it will fail to register cb with invalid intr_handle */
328 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
329 if (rte_intr_callback_register(&test_intr_handle,
330 test_interrupt_callback, NULL) == 0) {
331 printf("unexpectedly register successfully with invalid "
336 /* check if it will fail to register without callback */
337 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
338 if (rte_intr_callback_register(&test_intr_handle, NULL, NULL) == 0) {
339 printf("unexpectedly register successfully with "
344 /* check if it will fail to unregister cb with intr_handle = NULL */
345 if (rte_intr_callback_unregister(NULL,
346 test_interrupt_callback, NULL) > 0) {
347 printf("unexpectedly unregister successfully with "
348 "null intr_handle\n");
352 /* check if it will fail to unregister cb with invalid intr_handle */
353 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
354 if (rte_intr_callback_unregister(&test_intr_handle,
355 test_interrupt_callback, NULL) > 0) {
356 printf("unexpectedly unregister successfully with "
357 "invalid intr_handle\n");
361 /* check if it is ok to register the same intr_handle twice */
362 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
363 if (rte_intr_callback_register(&test_intr_handle,
364 test_interrupt_callback, NULL) < 0) {
365 printf("it fails to register test_interrupt_callback\n");
368 if (rte_intr_callback_register(&test_intr_handle,
369 test_interrupt_callback_1, NULL) < 0) {
370 printf("it fails to register test_interrupt_callback_1\n");
373 /* check if it will fail to unregister with invalid parameter */
374 if (rte_intr_callback_unregister(&test_intr_handle,
375 test_interrupt_callback, (void *)0xff) != 0) {
376 printf("unexpectedly unregisters successfully with invalid arg\n");
379 if (rte_intr_callback_unregister(&test_intr_handle,
380 test_interrupt_callback, NULL) <= 0) {
381 printf("it fails to unregister test_interrupt_callback\n");
384 if (rte_intr_callback_unregister(&test_intr_handle,
385 test_interrupt_callback_1, (void *)-1) <= 0) {
386 printf("it fails to unregister test_interrupt_callback_1 "
392 printf("start interrupt enable/disable test\n");
394 /* check interrupt enable/disable functions */
395 if (test_interrupt_enable() < 0)
399 if (test_interrupt_disable() < 0)
406 /* clear registered callbacks */
407 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
408 rte_intr_callback_unregister(&test_intr_handle,
409 test_interrupt_callback, (void *)-1);
410 rte_intr_callback_unregister(&test_intr_handle,
411 test_interrupt_callback_1, (void *)-1);
415 test_interrupt_deinit();