interrupts: rename device specific file descriptor
[dpdk.git] / lib / eal / common / eal_common_interrupts.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4
5 #include <stdlib.h>
6 #include <string.h>
7
8 #include <rte_errno.h>
9 #include <rte_interrupts.h>
10 #include <rte_log.h>
11 #include <rte_malloc.h>
12
13 #include "eal_interrupts.h"
14
15 /* Macros to check for valid interrupt handle */
16 #define CHECK_VALID_INTR_HANDLE(intr_handle) do { \
17         if (intr_handle == NULL) { \
18                 RTE_LOG(DEBUG, EAL, "Interrupt instance unallocated\n"); \
19                 rte_errno = EINVAL; \
20                 goto fail; \
21         } \
22 } while (0)
23
24 #define RTE_INTR_INSTANCE_KNOWN_FLAGS (RTE_INTR_INSTANCE_F_PRIVATE \
25         | RTE_INTR_INSTANCE_F_SHARED \
26         )
27
28 #define RTE_INTR_INSTANCE_USES_RTE_MEMORY(flags) \
29         (!!(flags & RTE_INTR_INSTANCE_F_SHARED))
30
31 struct rte_intr_handle *rte_intr_instance_alloc(uint32_t flags)
32 {
33         struct rte_intr_handle *intr_handle;
34         bool uses_rte_memory;
35
36         /* Check the flag passed by user, it should be part of the
37          * defined flags.
38          */
39         if ((flags & ~RTE_INTR_INSTANCE_KNOWN_FLAGS) != 0) {
40                 RTE_LOG(DEBUG, EAL, "Invalid alloc flag passed 0x%x\n", flags);
41                 rte_errno = EINVAL;
42                 return NULL;
43         }
44
45         uses_rte_memory = RTE_INTR_INSTANCE_USES_RTE_MEMORY(flags);
46         if (uses_rte_memory)
47                 intr_handle = rte_zmalloc(NULL, sizeof(*intr_handle), 0);
48         else
49                 intr_handle = calloc(1, sizeof(*intr_handle));
50         if (intr_handle == NULL) {
51                 RTE_LOG(ERR, EAL, "Failed to allocate intr_handle\n");
52                 rte_errno = ENOMEM;
53                 return NULL;
54         }
55
56         intr_handle->alloc_flags = flags;
57         intr_handle->nb_intr = RTE_MAX_RXTX_INTR_VEC_ID;
58
59         return intr_handle;
60 }
61
62 struct rte_intr_handle *rte_intr_instance_dup(const struct rte_intr_handle *src)
63 {
64         struct rte_intr_handle *intr_handle;
65
66         if (src == NULL) {
67                 RTE_LOG(DEBUG, EAL, "Source interrupt instance unallocated\n");
68                 rte_errno = EINVAL;
69                 return NULL;
70         }
71
72         intr_handle = rte_intr_instance_alloc(src->alloc_flags);
73         if (intr_handle != NULL) {
74                 intr_handle->fd = src->fd;
75                 intr_handle->dev_fd = src->dev_fd;
76                 intr_handle->type = src->type;
77                 intr_handle->max_intr = src->max_intr;
78                 intr_handle->nb_efd = src->nb_efd;
79                 intr_handle->efd_counter_size = src->efd_counter_size;
80                 memcpy(intr_handle->efds, src->efds, src->nb_intr);
81                 memcpy(intr_handle->elist, src->elist, src->nb_intr);
82         }
83
84         return intr_handle;
85 }
86
87 void rte_intr_instance_free(struct rte_intr_handle *intr_handle)
88 {
89         if (intr_handle == NULL)
90                 return;
91         if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags))
92                 rte_free(intr_handle);
93         else
94                 free(intr_handle);
95 }
96
97 int rte_intr_fd_set(struct rte_intr_handle *intr_handle, int fd)
98 {
99         CHECK_VALID_INTR_HANDLE(intr_handle);
100
101         intr_handle->fd = fd;
102
103         return 0;
104 fail:
105         return -rte_errno;
106 }
107
108 int rte_intr_fd_get(const struct rte_intr_handle *intr_handle)
109 {
110         CHECK_VALID_INTR_HANDLE(intr_handle);
111
112         return intr_handle->fd;
113 fail:
114         return -1;
115 }
116
117 int rte_intr_type_set(struct rte_intr_handle *intr_handle,
118         enum rte_intr_handle_type type)
119 {
120         CHECK_VALID_INTR_HANDLE(intr_handle);
121
122         intr_handle->type = type;
123
124         return 0;
125 fail:
126         return -rte_errno;
127 }
128
129 enum rte_intr_handle_type rte_intr_type_get(
130         const struct rte_intr_handle *intr_handle)
131 {
132         CHECK_VALID_INTR_HANDLE(intr_handle);
133
134         return intr_handle->type;
135 fail:
136         return RTE_INTR_HANDLE_UNKNOWN;
137 }
138
139 int rte_intr_dev_fd_set(struct rte_intr_handle *intr_handle, int fd)
140 {
141         CHECK_VALID_INTR_HANDLE(intr_handle);
142
143         intr_handle->dev_fd = fd;
144
145         return 0;
146 fail:
147         return -rte_errno;
148 }
149
150 int rte_intr_dev_fd_get(const struct rte_intr_handle *intr_handle)
151 {
152         CHECK_VALID_INTR_HANDLE(intr_handle);
153
154         return intr_handle->dev_fd;
155 fail:
156         return -1;
157 }
158
159 int rte_intr_max_intr_set(struct rte_intr_handle *intr_handle,
160                                  int max_intr)
161 {
162         CHECK_VALID_INTR_HANDLE(intr_handle);
163
164         if (max_intr > intr_handle->nb_intr) {
165                 RTE_LOG(DEBUG, EAL, "Maximum interrupt vector ID (%d) exceeds "
166                         "the number of available events (%d)\n", max_intr,
167                         intr_handle->nb_intr);
168                 rte_errno = ERANGE;
169                 goto fail;
170         }
171
172         intr_handle->max_intr = max_intr;
173
174         return 0;
175 fail:
176         return -rte_errno;
177 }
178
179 int rte_intr_max_intr_get(const struct rte_intr_handle *intr_handle)
180 {
181         CHECK_VALID_INTR_HANDLE(intr_handle);
182
183         return intr_handle->max_intr;
184 fail:
185         return -rte_errno;
186 }
187
188 int rte_intr_nb_efd_set(struct rte_intr_handle *intr_handle, int nb_efd)
189 {
190         CHECK_VALID_INTR_HANDLE(intr_handle);
191
192         intr_handle->nb_efd = nb_efd;
193
194         return 0;
195 fail:
196         return -rte_errno;
197 }
198
199 int rte_intr_nb_efd_get(const struct rte_intr_handle *intr_handle)
200 {
201         CHECK_VALID_INTR_HANDLE(intr_handle);
202
203         return intr_handle->nb_efd;
204 fail:
205         return -rte_errno;
206 }
207
208 int rte_intr_nb_intr_get(const struct rte_intr_handle *intr_handle)
209 {
210         CHECK_VALID_INTR_HANDLE(intr_handle);
211
212         return intr_handle->nb_intr;
213 fail:
214         return -rte_errno;
215 }
216
217 int rte_intr_efd_counter_size_set(struct rte_intr_handle *intr_handle,
218         uint8_t efd_counter_size)
219 {
220         CHECK_VALID_INTR_HANDLE(intr_handle);
221
222         intr_handle->efd_counter_size = efd_counter_size;
223
224         return 0;
225 fail:
226         return -rte_errno;
227 }
228
229 int rte_intr_efd_counter_size_get(const struct rte_intr_handle *intr_handle)
230 {
231         CHECK_VALID_INTR_HANDLE(intr_handle);
232
233         return intr_handle->efd_counter_size;
234 fail:
235         return -rte_errno;
236 }
237
238 int rte_intr_efds_index_get(const struct rte_intr_handle *intr_handle,
239         int index)
240 {
241         CHECK_VALID_INTR_HANDLE(intr_handle);
242
243         if (index >= intr_handle->nb_intr) {
244                 RTE_LOG(DEBUG, EAL, "Invalid index %d, max limit %d\n", index,
245                         intr_handle->nb_intr);
246                 rte_errno = EINVAL;
247                 goto fail;
248         }
249
250         return intr_handle->efds[index];
251 fail:
252         return -rte_errno;
253 }
254
255 int rte_intr_efds_index_set(struct rte_intr_handle *intr_handle,
256         int index, int fd)
257 {
258         CHECK_VALID_INTR_HANDLE(intr_handle);
259
260         if (index >= intr_handle->nb_intr) {
261                 RTE_LOG(DEBUG, EAL, "Invalid index %d, max limit %d\n", index,
262                         intr_handle->nb_intr);
263                 rte_errno = ERANGE;
264                 goto fail;
265         }
266
267         intr_handle->efds[index] = fd;
268
269         return 0;
270 fail:
271         return -rte_errno;
272 }
273
274 struct rte_epoll_event *rte_intr_elist_index_get(
275         struct rte_intr_handle *intr_handle, int index)
276 {
277         CHECK_VALID_INTR_HANDLE(intr_handle);
278
279         if (index >= intr_handle->nb_intr) {
280                 RTE_LOG(DEBUG, EAL, "Invalid index %d, max limit %d\n", index,
281                         intr_handle->nb_intr);
282                 rte_errno = ERANGE;
283                 goto fail;
284         }
285
286         return &intr_handle->elist[index];
287 fail:
288         return NULL;
289 }
290
291 int rte_intr_elist_index_set(struct rte_intr_handle *intr_handle,
292         int index, struct rte_epoll_event elist)
293 {
294         CHECK_VALID_INTR_HANDLE(intr_handle);
295
296         if (index >= intr_handle->nb_intr) {
297                 RTE_LOG(DEBUG, EAL, "Invalid index %d, max limit %d\n", index,
298                         intr_handle->nb_intr);
299                 rte_errno = ERANGE;
300                 goto fail;
301         }
302
303         intr_handle->elist[index] = elist;
304
305         return 0;
306 fail:
307         return -rte_errno;
308 }
309
310 int rte_intr_vec_list_alloc(struct rte_intr_handle *intr_handle,
311         const char *name, int size)
312 {
313         CHECK_VALID_INTR_HANDLE(intr_handle);
314
315         /* Vector list already allocated */
316         if (intr_handle->intr_vec != NULL)
317                 return 0;
318
319         if (size > intr_handle->nb_intr) {
320                 RTE_LOG(DEBUG, EAL, "Invalid size %d, max limit %d\n", size,
321                         intr_handle->nb_intr);
322                 rte_errno = ERANGE;
323                 goto fail;
324         }
325
326         if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags))
327                 intr_handle->intr_vec = rte_zmalloc(name, size * sizeof(int), 0);
328         else
329                 intr_handle->intr_vec = calloc(size, sizeof(int));
330         if (intr_handle->intr_vec == NULL) {
331                 RTE_LOG(ERR, EAL, "Failed to allocate %d intr_vec\n", size);
332                 rte_errno = ENOMEM;
333                 goto fail;
334         }
335
336         intr_handle->vec_list_size = size;
337
338         return 0;
339 fail:
340         return -rte_errno;
341 }
342
343 int rte_intr_vec_list_index_get(const struct rte_intr_handle *intr_handle,
344                                 int index)
345 {
346         CHECK_VALID_INTR_HANDLE(intr_handle);
347
348         if (index >= intr_handle->vec_list_size) {
349                 RTE_LOG(DEBUG, EAL, "Index %d greater than vec list size %d\n",
350                         index, intr_handle->vec_list_size);
351                 rte_errno = ERANGE;
352                 goto fail;
353         }
354
355         return intr_handle->intr_vec[index];
356 fail:
357         return -rte_errno;
358 }
359
360 int rte_intr_vec_list_index_set(struct rte_intr_handle *intr_handle,
361                                 int index, int vec)
362 {
363         CHECK_VALID_INTR_HANDLE(intr_handle);
364
365         if (index >= intr_handle->vec_list_size) {
366                 RTE_LOG(DEBUG, EAL, "Index %d greater than vec list size %d\n",
367                         index, intr_handle->vec_list_size);
368                 rte_errno = ERANGE;
369                 goto fail;
370         }
371
372         intr_handle->intr_vec[index] = vec;
373
374         return 0;
375 fail:
376         return -rte_errno;
377 }
378
379 void rte_intr_vec_list_free(struct rte_intr_handle *intr_handle)
380 {
381         if (intr_handle == NULL)
382                 return;
383         if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags))
384                 rte_free(intr_handle->intr_vec);
385         else
386                 free(intr_handle->intr_vec);
387         intr_handle->intr_vec = NULL;
388         intr_handle->vec_list_size = 0;
389 }
390
391 void *rte_intr_instance_windows_handle_get(struct rte_intr_handle *intr_handle)
392 {
393         CHECK_VALID_INTR_HANDLE(intr_handle);
394
395         return intr_handle->windows_handle;
396 fail:
397         return NULL;
398 }
399
400 int rte_intr_instance_windows_handle_set(struct rte_intr_handle *intr_handle,
401         void *windows_handle)
402 {
403         CHECK_VALID_INTR_HANDLE(intr_handle);
404
405         intr_handle->windows_handle = windows_handle;
406
407         return 0;
408 fail:
409         return -rte_errno;
410 }