3c17492dde5c8bfb6667a53e8c95957eccd8ada9
[dpdk.git] / lib / eal / include / rte_interrupts.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4
5 #ifndef _RTE_INTERRUPTS_H_
6 #define _RTE_INTERRUPTS_H_
7
8 #include <stdbool.h>
9
10 #include <rte_bitops.h>
11 #include <rte_common.h>
12 #include <rte_compat.h>
13 #include <rte_epoll.h>
14
15 /**
16  * @file
17  *
18  * The RTE interrupt interface provides functions to register/unregister
19  * callbacks for a specific interrupt.
20  */
21
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25
26 /** Interrupt handle */
27 struct rte_intr_handle;
28
29 /** Interrupt instance allocation flags
30  * @see rte_intr_instance_alloc
31  */
32
33 /** Interrupt instance will not be shared between primary and secondary processes. */
34 #define RTE_INTR_INSTANCE_F_PRIVATE     UINT32_C(0)
35 /** Interrupt instance will be shared between primary and secondary processes. */
36 #define RTE_INTR_INSTANCE_F_SHARED      RTE_BIT32(0)
37
38 /** Function to be registered for the specific interrupt */
39 typedef void (*rte_intr_callback_fn)(void *cb_arg);
40
41 /**
42  * Function to call after a callback is unregistered.
43  * Can be used to close fd and free cb_arg.
44  */
45 typedef void (*rte_intr_unregister_callback_fn)(struct rte_intr_handle *intr_handle,
46                                                 void *cb_arg);
47
48 #include "rte_eal_interrupts.h"
49
50 /**
51  * It registers the callback for the specific interrupt. Multiple
52  * callbacks can be registered at the same time.
53  * @param intr_handle
54  *  Pointer to the interrupt handle.
55  * @param cb
56  *  callback address.
57  * @param cb_arg
58  *  address of parameter for callback.
59  *
60  * @return
61  *  - On success, zero.
62  *  - On failure, a negative value.
63  */
64 int rte_intr_callback_register(const struct rte_intr_handle *intr_handle,
65                                 rte_intr_callback_fn cb, void *cb_arg);
66
67 /**
68  * It unregisters the callback according to the specified interrupt handle.
69  *
70  * @param intr_handle
71  *  pointer to the interrupt handle.
72  * @param cb
73  *  callback address.
74  * @param cb_arg
75  *  address of parameter for callback, (void *)-1 means to remove all
76  *  registered which has the same callback address.
77  *
78  * @return
79  *  - On success, return the number of callback entities removed.
80  *  - On failure, a negative value.
81  */
82 int rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle,
83                                 rte_intr_callback_fn cb, void *cb_arg);
84
85 /**
86  * Unregister the callback according to the specified interrupt handle,
87  * after it's no longer active. Fail if source is not active.
88  *
89  * @param intr_handle
90  *  pointer to the interrupt handle.
91  * @param cb_fn
92  *  callback address.
93  * @param cb_arg
94  *  address of parameter for callback, (void *)-1 means to remove all
95  *  registered which has the same callback address.
96  * @param ucb_fn
97  *  callback to call before cb is unregistered (optional).
98  *  can be used to close fd and free cb_arg.
99  *
100  * @return
101  *  - On success, return the number of callback entities marked for remove.
102  *  - On failure, a negative value.
103  */
104 __rte_experimental
105 int
106 rte_intr_callback_unregister_pending(const struct rte_intr_handle *intr_handle,
107                                 rte_intr_callback_fn cb_fn, void *cb_arg,
108                                 rte_intr_unregister_callback_fn ucb_fn);
109
110 /**
111  * @warning
112  * @b EXPERIMENTAL: this API may change without prior notice
113  *
114  * Loop until rte_intr_callback_unregister() succeeds.
115  * After a call to this function,
116  * the callback provided by the specified interrupt handle is unregistered.
117  *
118  * @param intr_handle
119  *  pointer to the interrupt handle.
120  * @param cb
121  *  callback address.
122  * @param cb_arg
123  *  address of parameter for callback, (void *)-1 means to remove all
124  *  registered which has the same callback address.
125  *
126  * @return
127  *  - On success, return the number of callback entities removed.
128  *  - On failure, a negative value.
129  */
130 __rte_experimental
131 int
132 rte_intr_callback_unregister_sync(const struct rte_intr_handle *intr_handle,
133                                 rte_intr_callback_fn cb, void *cb_arg);
134
135 /**
136  * It enables the interrupt for the specified handle.
137  *
138  * @param intr_handle
139  *  pointer to the interrupt handle.
140  *
141  * @return
142  *  - On success, zero.
143  *  - On failure, a negative value.
144  */
145 int rte_intr_enable(const struct rte_intr_handle *intr_handle);
146
147 /**
148  * It disables the interrupt for the specified handle.
149  *
150  * @param intr_handle
151  *  pointer to the interrupt handle.
152  *
153  * @return
154  *  - On success, zero.
155  *  - On failure, a negative value.
156  */
157 int rte_intr_disable(const struct rte_intr_handle *intr_handle);
158
159 /**
160  * @warning
161  * @b EXPERIMENTAL: this API may change without prior notice
162  *
163  * It acknowledges an interrupt raised for the specified handle.
164  *
165  * This function should be called at the end of each interrupt handler either
166  * from application or driver, so that currently raised interrupt is acked and
167  * further new interrupts are raised.
168  *
169  * @param intr_handle
170  *  pointer to the interrupt handle.
171  *
172  * @return
173  *  - On success, zero.
174  *  - On failure, a negative value.
175  */
176 __rte_experimental
177 int rte_intr_ack(const struct rte_intr_handle *intr_handle);
178
179 /**
180  * @warning
181  * @b EXPERIMENTAL: this API may change without prior notice
182  *
183  * Check if currently executing in interrupt context
184  *
185  * @return
186  *  - non zero in case of interrupt context
187  *  - zero in case of process context
188  */
189 __rte_experimental
190 int
191 rte_thread_is_intr(void);
192
193 /**
194  * @warning
195  * @b EXPERIMENTAL: this API may change without prior notice
196  *
197  * It allocates memory for interrupt instance. API takes flag as an argument
198  * which define from where memory should be allocated i.e. using DPDK memory
199  * management library APIs or normal heap allocation.
200  * Default memory allocation for event fds and event list array is done which
201  * can be realloced later based on size of MSIX interrupts supported by a PCI
202  * device.
203  *
204  * This function should be called from application or driver, before calling
205  * any of the interrupt APIs.
206  *
207  * @param flags
208  *  See RTE_INTR_INSTANCE_F_* flags definitions.
209  *
210  * @return
211  *  - On success, address of interrupt handle.
212  *  - On failure, NULL.
213  */
214 __rte_experimental
215 struct rte_intr_handle *
216 rte_intr_instance_alloc(uint32_t flags);
217
218 /**
219  * @warning
220  * @b EXPERIMENTAL: this API may change without prior notice
221  *
222  * This API is used to free the memory allocated for interrupt handle
223  * resources.
224  *
225  * @param intr_handle
226  *  Interrupt handle address.
227  *
228  */
229 __rte_experimental
230 void
231 rte_intr_instance_free(struct rte_intr_handle *intr_handle);
232
233 /**
234  * @warning
235  * @b EXPERIMENTAL: this API may change without prior notice
236  *
237  * This API is used to set the fd field of interrupt handle with user provided
238  * file descriptor.
239  *
240  * @param intr_handle
241  *  pointer to the interrupt handle.
242  * @param fd
243  *  file descriptor value provided by user.
244  *
245  * @return
246  *  - On success, zero.
247  *  - On failure, a negative value and rte_errno is set.
248  */
249 __rte_experimental
250 int
251 rte_intr_fd_set(struct rte_intr_handle *intr_handle, int fd);
252
253 /**
254  * @warning
255  * @b EXPERIMENTAL: this API may change without prior notice
256  *
257  * Returns the fd field of the given interrupt handle instance.
258  *
259  * @param intr_handle
260  *  pointer to the interrupt handle.
261  *
262  * @return
263  *  - On success, fd field.
264  *  - On failure, a negative value.
265  */
266 __rte_experimental
267 int
268 rte_intr_fd_get(const struct rte_intr_handle *intr_handle);
269
270 /**
271  * @warning
272  * @b EXPERIMENTAL: this API may change without prior notice
273  *
274  * This API is used to set the type field of interrupt handle with user provided
275  * interrupt type.
276  *
277  * @param intr_handle
278  *  pointer to the interrupt handle.
279  * @param type
280  *  interrupt type
281  *
282  * @return
283  *  - On success, zero.
284  *  - On failure, a negative value and rte_errno is set.
285  */
286 __rte_experimental
287 int
288 rte_intr_type_set(struct rte_intr_handle *intr_handle,
289                   enum rte_intr_handle_type type);
290
291 /**
292  * @warning
293  * @b EXPERIMENTAL: this API may change without prior notice
294  *
295  * Returns the type field of the given interrupt handle instance.
296  *
297  * @param intr_handle
298  *  pointer to the interrupt handle.
299  *
300  * @return
301  *  - On success, interrupt type
302  *  - On failure, RTE_INTR_HANDLE_UNKNOWN.
303  */
304 __rte_experimental
305 enum rte_intr_handle_type
306 rte_intr_type_get(const struct rte_intr_handle *intr_handle);
307
308 /**
309  * @internal
310  * The function returns the per thread epoll instance.
311  *
312  * @return
313  *   epfd the epoll instance referred to.
314  */
315 __rte_internal
316 int
317 rte_intr_tls_epfd(void);
318
319 /**
320  * @internal
321  * @param intr_handle
322  *   Pointer to the interrupt handle.
323  * @param epfd
324  *   Epoll instance fd which the intr vector associated to.
325  * @param op
326  *   The operation be performed for the vector.
327  *   Operation type of {ADD, DEL}.
328  * @param vec
329  *   RX intr vector number added to the epoll instance wait list.
330  * @param data
331  *   User raw data.
332  * @return
333  *   - On success, zero.
334  *   - On failure, a negative value.
335  */
336 __rte_internal
337 int
338 rte_intr_rx_ctl(struct rte_intr_handle *intr_handle,
339                 int epfd, int op, unsigned int vec, void *data);
340
341 /**
342  * @internal
343  * It deletes registered eventfds.
344  *
345  * @param intr_handle
346  *   Pointer to the interrupt handle.
347  */
348 __rte_internal
349 void
350 rte_intr_free_epoll_fd(struct rte_intr_handle *intr_handle);
351
352 /**
353  * @internal
354  * It enables the packet I/O interrupt event if it's necessary.
355  * It creates event fd for each interrupt vector when MSIX is used,
356  * otherwise it multiplexes a single event fd.
357  *
358  * @param intr_handle
359  *   Pointer to the interrupt handle.
360  * @param nb_efd
361  *   Number of interrupt vector trying to enable.
362  *   The value 0 is not allowed.
363  * @return
364  *   - On success, zero.
365  *   - On failure, a negative value.
366  */
367 __rte_internal
368 int
369 rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd);
370
371 /**
372  * @internal
373  * It disables the packet I/O interrupt event.
374  * It deletes registered eventfds and closes the open fds.
375  *
376  * @param intr_handle
377  *   Pointer to the interrupt handle.
378  */
379 __rte_internal
380 void
381 rte_intr_efd_disable(struct rte_intr_handle *intr_handle);
382
383 /**
384  * @internal
385  * The packet I/O interrupt on datapath is enabled or not.
386  *
387  * @param intr_handle
388  *   Pointer to the interrupt handle.
389  */
390 __rte_internal
391 int
392 rte_intr_dp_is_en(struct rte_intr_handle *intr_handle);
393
394 /**
395  * @internal
396  * The interrupt handle instance allows other causes or not.
397  * Other causes stand for any none packet I/O interrupts.
398  *
399  * @param intr_handle
400  *   Pointer to the interrupt handle.
401  */
402 __rte_internal
403 int
404 rte_intr_allow_others(struct rte_intr_handle *intr_handle);
405
406 /**
407  * @internal
408  * The multiple interrupt vector capability of interrupt handle instance.
409  * It returns zero if no multiple interrupt vector support.
410  *
411  * @param intr_handle
412  *   Pointer to the interrupt handle.
413  */
414 __rte_internal
415 int
416 rte_intr_cap_multiple(struct rte_intr_handle *intr_handle);
417
418 /**
419  * @internal
420  * Creates a clone of src by allocating a new handle and copying src content.
421  *
422  * @param src
423  *  Source interrupt handle to be cloned.
424  *
425  * @return
426  *  - On success, address of interrupt handle.
427  *  - On failure, NULL.
428  */
429 __rte_internal
430 struct rte_intr_handle *
431 rte_intr_instance_dup(const struct rte_intr_handle *src);
432
433 /**
434  * @internal
435  * This API is used to set the device fd field of interrupt handle with user
436  * provided dev fd. Device fd corresponds to VFIO device fd or UIO config fd.
437  *
438  * @param intr_handle
439  *  pointer to the interrupt handle.
440  * @param fd
441  *  interrupt type
442  *
443  * @return
444  *  - On success, zero.
445  *  - On failure, a negative value and rte_errno is set.
446  */
447 __rte_internal
448 int
449 rte_intr_dev_fd_set(struct rte_intr_handle *intr_handle, int fd);
450
451 /**
452  * @internal
453  * Returns the device fd field of the given interrupt handle instance.
454  *
455  * @param intr_handle
456  *  pointer to the interrupt handle.
457  *
458  * @return
459  *  - On success, dev fd.
460  *  - On failure, a negative value and rte_errno is set.
461  */
462 __rte_internal
463 int
464 rte_intr_dev_fd_get(const struct rte_intr_handle *intr_handle);
465
466 /**
467  * @internal
468  * This API is used to set the max intr field of interrupt handle with user
469  * provided max intr value.
470  *
471  * @param intr_handle
472  *  pointer to the interrupt handle.
473  * @param max_intr
474  *  interrupt type
475  *
476  * @return
477  *  - On success, zero.
478  *  - On failure, a negative value and rte_errno is set.
479  */
480 __rte_internal
481 int
482 rte_intr_max_intr_set(struct rte_intr_handle *intr_handle, int max_intr);
483
484 /**
485  * @internal
486  * Returns the max intr field of the given interrupt handle instance.
487  *
488  * @param intr_handle
489  *  pointer to the interrupt handle.
490  *
491  * @return
492  *  - On success, max intr.
493  *  - On failure, a negative value and rte_errno is set.
494  */
495 __rte_internal
496 int
497 rte_intr_max_intr_get(const struct rte_intr_handle *intr_handle);
498
499 /**
500  * @internal
501  * This API is used to set the number of event fd field of interrupt handle
502  * with user provided available event file descriptor value.
503  *
504  * @param intr_handle
505  *  pointer to the interrupt handle.
506  * @param nb_efd
507  *  Available event fd
508  *
509  * @return
510  *  - On success, zero.
511  *  - On failure, a negative value and rte_errno is set.
512  */
513 __rte_internal
514 int
515 rte_intr_nb_efd_set(struct rte_intr_handle *intr_handle, int nb_efd);
516
517 /**
518  * @internal
519  * Returns the number of available event fd field of the given interrupt handle
520  * instance.
521  *
522  * @param intr_handle
523  *  pointer to the interrupt handle.
524  *
525  * @return
526  *  - On success, nb_efd
527  *  - On failure, a negative value and rte_errno is set.
528  */
529 __rte_internal
530 int
531 rte_intr_nb_efd_get(const struct rte_intr_handle *intr_handle);
532
533 /**
534  * @internal
535  * Returns the number of interrupt vector field of the given interrupt handle
536  * instance. This field is to configured on device probe time, and based on
537  * this value efds and elist arrays are dynamically allocated. By default
538  * this value is set to RTE_MAX_RXTX_INTR_VEC_ID.
539  * For eg. in case of PCI device, its msix size is queried and efds/elist
540  * arrays are allocated accordingly.
541  *
542  * @param intr_handle
543  *  pointer to the interrupt handle.
544  *
545  * @return
546  *  - On success, nb_intr
547  *  - On failure, a negative value and rte_errno is set.
548  */
549 __rte_internal
550 int
551 rte_intr_nb_intr_get(const struct rte_intr_handle *intr_handle);
552
553 /**
554  * @internal
555  * This API is used to set the event fd counter size field of interrupt handle
556  * with user provided efd counter size.
557  *
558  * @param intr_handle
559  *  pointer to the interrupt handle.
560  * @param efd_counter_size
561  *  size of efd counter.
562  *
563  * @return
564  *  - On success, zero.
565  *  - On failure, a negative value and rte_errno is set.
566  */
567 __rte_internal
568 int
569 rte_intr_efd_counter_size_set(struct rte_intr_handle *intr_handle,
570                               uint8_t efd_counter_size);
571
572 /**
573  * @internal
574  * Returns the event fd counter size field of the given interrupt handle
575  * instance.
576  *
577  * @param intr_handle
578  *  pointer to the interrupt handle.
579  *
580  * @return
581  *  - On success, efd_counter_size
582  *  - On failure, a negative value and rte_errno is set.
583  */
584 __rte_internal
585 int
586 rte_intr_efd_counter_size_get(const struct rte_intr_handle *intr_handle);
587
588 /**
589  * @internal
590  * This API is used to set the event fd array index with the given fd.
591  *
592  * @param intr_handle
593  *  pointer to the interrupt handle.
594  * @param index
595  *  efds array index to be set
596  * @param fd
597  *  event fd
598  *
599  * @return
600  *  - On success, zero.
601  *  - On failure, a negative value and rte_errno is set.
602  */
603 __rte_internal
604 int
605 rte_intr_efds_index_set(struct rte_intr_handle *intr_handle, int index, int fd);
606
607 /**
608  * @internal
609  * Returns the fd value of event fds array at a given index.
610  *
611  * @param intr_handle
612  *  pointer to the interrupt handle.
613  * @param index
614  *  efds array index to be returned
615  *
616  * @return
617  *  - On success, fd
618  *  - On failure, a negative value and rte_errno is set.
619  */
620 __rte_internal
621 int
622 rte_intr_efds_index_get(const struct rte_intr_handle *intr_handle, int index);
623
624 /**
625  * @internal
626  * This API is used to set the epoll event object array index with the given
627  * elist instance.
628  *
629  * @param intr_handle
630  *  pointer to the interrupt handle.
631  * @param index
632  *  elist array index to be set
633  * @param elist
634  *  epoll event instance of struct rte_epoll_event
635  *
636  * @return
637  *  - On success, zero.
638  *  - On failure, a negative value and rte_errno is set.
639  */
640 __rte_internal
641 int
642 rte_intr_elist_index_set(struct rte_intr_handle *intr_handle, int index,
643                          struct rte_epoll_event elist);
644
645 /**
646  * @internal
647  * Returns the address of epoll event instance from elist array at a given
648  * index.
649  *
650  * @param intr_handle
651  *  pointer to the interrupt handle.
652  * @param index
653  *  elist array index to be returned
654  *
655  * @return
656  *  - On success, elist
657  *  - On failure, a negative value and rte_errno is set.
658  */
659 __rte_internal
660 struct rte_epoll_event *
661 rte_intr_elist_index_get(struct rte_intr_handle *intr_handle, int index);
662
663 /**
664  * @internal
665  * Allocates the memory of interrupt vector list array, with size defining the
666  * number of elements required in the array.
667  *
668  * @param intr_handle
669  *  pointer to the interrupt handle.
670  * @param name
671  *  Name assigned to the allocation, or NULL.
672  * @param size
673  *  Number of element required in the array.
674  *
675  * @return
676  *  - On success, zero
677  *  - On failure, a negative value and rte_errno is set.
678  */
679 __rte_internal
680 int
681 rte_intr_vec_list_alloc(struct rte_intr_handle *intr_handle, const char *name,
682                         int size);
683
684 /**
685  * @internal
686  * Sets the vector value at given index of interrupt vector list field of given
687  * interrupt handle.
688  *
689  * @param intr_handle
690  *  pointer to the interrupt handle.
691  * @param index
692  *  intr_vec array index to be set
693  * @param vec
694  *  Interrupt vector value.
695  *
696  * @return
697  *  - On success, zero
698  *  - On failure, a negative value and rte_errno is set.
699  */
700 __rte_internal
701 int
702 rte_intr_vec_list_index_set(struct rte_intr_handle *intr_handle, int index,
703                             int vec);
704
705 /**
706  * @internal
707  * Returns the vector value at the given index of interrupt vector list array.
708  *
709  * @param intr_handle
710  *  pointer to the interrupt handle.
711  * @param index
712  *  intr_vec array index to be returned
713  *
714  * @return
715  *  - On success, interrupt vector
716  *  - On failure, a negative value and rte_errno is set.
717  */
718 __rte_internal
719 int
720 rte_intr_vec_list_index_get(const struct rte_intr_handle *intr_handle,
721                             int index);
722
723 /**
724  * @internal
725  * Frees the memory allocated for interrupt vector list array.
726  *
727  * @param intr_handle
728  *  pointer to the interrupt handle.
729  *
730  * @return
731  *  - On success, zero
732  *  - On failure, a negative value and rte_errno is set.
733  */
734 __rte_internal
735 void
736 rte_intr_vec_list_free(struct rte_intr_handle *intr_handle);
737
738 /**
739  * @internal
740  * This API returns the Windows handle of the given interrupt instance.
741  *
742  * @param intr_handle
743  *  pointer to the interrupt handle.
744  *
745  * @return
746  *  - On success, Windows handle.
747  *  - On failure, NULL.
748  */
749 __rte_internal
750 void *
751 rte_intr_instance_windows_handle_get(struct rte_intr_handle *intr_handle);
752
753 /**
754  * @internal
755  * This API set the Windows handle for the given interrupt instance.
756  *
757  * @param intr_handle
758  *  pointer to the interrupt handle.
759  * @param windows_handle
760  *  Windows handle to be set.
761  *
762  * @return
763  *  - On success, zero
764  *  - On failure, a negative value and rte_errno is set.
765  */
766 __rte_internal
767 int
768 rte_intr_instance_windows_handle_set(struct rte_intr_handle *intr_handle,
769                                      void *windows_handle);
770
771 #ifdef __cplusplus
772 }
773 #endif
774
775 #endif