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.
39 #include <cmdline_parse.h>
41 #include <rte_common.h>
42 #include <rte_cycles.h>
43 #include <rte_interrupts.h>
47 #define TEST_INTERRUPT_CHECK_INTERVAL 1000 /* ms */
49 enum test_interrupt_handl_type {
50 TEST_INTERRUPT_HANDLE_INVALID,
51 TEST_INTERRUPT_HANDLE_VALID,
52 TEST_INTERRUPT_HANDLE_CASE1,
53 TEST_INTERRUPT_HANDLE_MAX
56 static volatile int flag;
57 static struct rte_intr_handle intr_handles[TEST_INTERRUPT_HANDLE_MAX];
59 #ifdef RTE_EXEC_ENV_LINUXAPP
70 static union intr_pipefds pfds;
73 test_interrupt_handle_sanity_check(struct rte_intr_handle *intr_handle)
75 if (!intr_handle || intr_handle->fd < 0)
82 test_interrupt_init(void)
84 if (pipe(pfds.pipefd) < 0)
87 intr_handles[TEST_INTERRUPT_HANDLE_INVALID].fd = -1;
88 intr_handles[TEST_INTERRUPT_HANDLE_INVALID].type = RTE_INTR_HANDLE_UNKNOWN;
90 intr_handles[TEST_INTERRUPT_HANDLE_VALID].fd = pfds.readfd;
91 intr_handles[TEST_INTERRUPT_HANDLE_VALID].type = RTE_INTR_HANDLE_UNKNOWN;
93 intr_handles[TEST_INTERRUPT_HANDLE_CASE1].fd = pfds.readfd;
94 intr_handles[TEST_INTERRUPT_HANDLE_CASE1].type = RTE_INTR_HANDLE_ALARM;
100 test_interrupt_deinit(void)
102 close(pfds.pipefd[0]);
103 close(pfds.pipefd[1]);
109 test_interrupt_trigger_interrupt(void)
111 if (write(pfds.writefd, "1", 1) < 0)
118 test_interrupt_handle_compare(struct rte_intr_handle *intr_handle_l,
119 struct rte_intr_handle *intr_handle_r)
121 if (!intr_handle_l || !intr_handle_r)
124 if (intr_handle_l->fd != intr_handle_r->fd ||
125 intr_handle_l->type != intr_handle_r->type)
132 /* to be implemented for baremetal later */
134 test_interrupt_handle_sanity_check(struct rte_intr_handle *intr_handle)
136 RTE_SET_USED(intr_handle);
142 test_interrupt_init(void)
148 test_interrupt_deinit(void)
154 test_interrupt_trigger_interrupt(void)
160 test_interrupt_handle_compare(struct rte_intr_handle *intr_handle_l,
161 struct rte_intr_handle *intr_handle_r)
168 #endif /* RTE_EXEC_ENV_LINUXAPP */
171 test_interrupt_callback(struct rte_intr_handle *intr_handle, void *arg)
173 if (test_interrupt_handle_sanity_check(intr_handle) < 0) {
174 printf("null or invalid intr_handle for %s\n", __FUNCTION__);
178 if (rte_intr_callback_unregister(intr_handle,
179 test_interrupt_callback, arg) <= 0) {
180 printf("fail to unregister callback\n");
184 if (test_interrupt_handle_compare(intr_handle,
185 &(intr_handles[TEST_INTERRUPT_HANDLE_VALID])) == 0) {
191 test_interrupt_callback_1(struct rte_intr_handle *intr_handle, void *arg)
193 if (test_interrupt_handle_sanity_check(intr_handle) < 0) {
194 printf("null or invalid intr_handle for %s\n", __FUNCTION__);
197 if (rte_intr_callback_unregister(intr_handle,
198 test_interrupt_callback_1, arg) <= 0) {
199 printf("fail to unregister callback\n");
205 test_interrupt_enable(void)
207 struct rte_intr_handle test_intr_handle;
209 /* check with null intr_handle */
210 if (rte_intr_enable(NULL) == 0) {
211 printf("unexpectedly enable null intr_handle successfully\n");
215 /* check with invalid intr_handle */
216 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
217 if (rte_intr_enable(&test_intr_handle) == 0) {
218 printf("unexpectedly enable invalid intr_handle "
223 /* check with valid intr_handle */
224 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
225 if (rte_intr_enable(&test_intr_handle) == 0) {
226 printf("unexpectedly enable a specific intr_handle "
231 /* check with specific valid intr_handle */
232 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_CASE1];
233 if (rte_intr_enable(&test_intr_handle) == 0) {
234 printf("unexpectedly enable a specific intr_handle "
243 test_interrupt_disable(void)
245 struct rte_intr_handle test_intr_handle;
247 /* check with null intr_handle */
248 if (rte_intr_disable(NULL) == 0) {
249 printf("unexpectedly disable null intr_handle "
254 /* check with invalid intr_handle */
255 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
256 if (rte_intr_disable(&test_intr_handle) == 0) {
257 printf("unexpectedly disable invalid intr_handle "
262 /* check with valid intr_handle */
263 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
264 if (rte_intr_disable(&test_intr_handle) == 0) {
265 printf("unexpectedly disable a specific intr_handle "
270 /* check with specific valid intr_handle */
271 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_CASE1];
272 if (rte_intr_disable(&test_intr_handle) == 0) {
273 printf("unexpectedly disable a specific intr_handle "
284 int count = 0, ret = -1;
285 struct rte_intr_handle test_intr_handle;
287 if (test_interrupt_init() < 0) {
288 printf("fail to do test init\n");
292 printf("check if callback registered can be called\n");
294 /* check if callback registered can be called */
296 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
297 if (rte_intr_callback_register(&test_intr_handle,
298 test_interrupt_callback, NULL) < 0) {
299 printf("fail to register callback\n");
302 /* trigger an interrupt and then check if the callback can be called */
303 if (test_interrupt_trigger_interrupt() < 0) {
304 printf("fail to trigger an interrupt\n");
307 /* check flag in 3 seconds */
308 while (flag == 0 && count++ < 3)
309 rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL);
311 printf("registered callback has not been called\n");
316 printf("start register/unregister test\n");
318 /* check if it will fail to register cb with intr_handle = NULL */
319 if (rte_intr_callback_register(NULL, test_interrupt_callback,
321 printf("unexpectedly register successfully with null "
326 /* check if it will fail to register cb with invalid intr_handle */
327 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
328 if (rte_intr_callback_register(&test_intr_handle,
329 test_interrupt_callback, NULL) == 0) {
330 printf("unexpectedly register successfully with invalid "
335 /* check if it will fail to register without callback */
336 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
337 if (rte_intr_callback_register(&test_intr_handle, NULL, NULL) == 0) {
338 printf("unexpectedly register successfully with "
343 /* check if it will fail to unregister cb with intr_handle = NULL */
344 if (rte_intr_callback_unregister(NULL,
345 test_interrupt_callback, NULL) > 0) {
346 printf("unexpectedly unregister successfully with "
347 "null intr_handle\n");
351 /* check if it will fail to unregister cb with invalid intr_handle */
352 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
353 if (rte_intr_callback_unregister(&test_intr_handle,
354 test_interrupt_callback, NULL) > 0) {
355 printf("unexpectedly unregister successfully with "
356 "invalid intr_handle\n");
360 /* check if it is ok to register the same intr_handle twice */
361 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
362 if (rte_intr_callback_register(&test_intr_handle,
363 test_interrupt_callback, NULL) < 0) {
364 printf("it fails to register test_interrupt_callback\n");
367 if (rte_intr_callback_register(&test_intr_handle,
368 test_interrupt_callback_1, NULL) < 0) {
369 printf("it fails to register test_interrupt_callback_1\n");
372 /* check if it will fail to unregister with invalid parameter */
373 if (rte_intr_callback_unregister(&test_intr_handle,
374 test_interrupt_callback, (void *)0xff) != 0) {
375 printf("unexpectedly unregisters successfully with invalid arg\n");
378 if (rte_intr_callback_unregister(&test_intr_handle,
379 test_interrupt_callback, NULL) <= 0) {
380 printf("it fails to unregister test_interrupt_callback\n");
383 if (rte_intr_callback_unregister(&test_intr_handle,
384 test_interrupt_callback_1, (void *)-1) <= 0) {
385 printf("it fails to unregister test_interrupt_callback_1 "
391 printf("start interrupt enable/disable test\n");
393 /* check interrupt enable/disable functions */
394 if (test_interrupt_enable() < 0)
398 if (test_interrupt_disable() < 0)
405 /* clear registered callbacks */
406 test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
407 rte_intr_callback_unregister(&test_intr_handle,
408 test_interrupt_callback, (void *)-1);
409 rte_intr_callback_unregister(&test_intr_handle,
410 test_interrupt_callback_1, (void *)-1);
414 test_interrupt_deinit();