net/hns3: support fixed link speed
[dpdk.git] / lib / librte_eal / windows / eal_interrupts.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2020 Mellanox Technologies, Ltd
3  */
4
5 #include <rte_interrupts.h>
6
7 #include "eal_private.h"
8 #include "eal_windows.h"
9
10 static pthread_t intr_thread;
11
12 static HANDLE intr_iocp;
13
14 static void
15 eal_intr_process(const OVERLAPPED_ENTRY *event)
16 {
17         RTE_SET_USED(event);
18 }
19
20 static void *
21 eal_intr_thread_main(LPVOID arg __rte_unused)
22 {
23         while (1) {
24                 OVERLAPPED_ENTRY events[16];
25                 ULONG event_count, i;
26                 BOOL result;
27
28                 result = GetQueuedCompletionStatusEx(
29                         intr_iocp, events, RTE_DIM(events), &event_count,
30                         INFINITE, /* no timeout */
31                         TRUE);    /* alertable wait for alarm APCs */
32
33                 if (!result) {
34                         DWORD error = GetLastError();
35                         if (error != WAIT_IO_COMPLETION) {
36                                 RTE_LOG_WIN32_ERR("GetQueuedCompletionStatusEx()");
37                                 RTE_LOG(ERR, EAL, "Failed waiting for interrupts\n");
38                                 break;
39                         }
40
41                         /* No I/O events, all work is done in completed APCs. */
42                         continue;
43                 }
44
45                 for (i = 0; i < event_count; i++)
46                         eal_intr_process(&events[i]);
47         }
48
49         CloseHandle(intr_iocp);
50         intr_iocp = NULL;
51         return NULL;
52 }
53
54 int
55 rte_eal_intr_init(void)
56 {
57         int ret = 0;
58
59         intr_iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
60         if (intr_iocp == NULL) {
61                 RTE_LOG_WIN32_ERR("CreateIoCompletionPort()");
62                 RTE_LOG(ERR, EAL, "Cannot create interrupt IOCP\n");
63                 return -1;
64         }
65
66         ret = rte_ctrl_thread_create(&intr_thread, "eal-intr-thread", NULL,
67                         eal_intr_thread_main, NULL);
68         if (ret != 0) {
69                 rte_errno = -ret;
70                 RTE_LOG(ERR, EAL, "Cannot create interrupt thread\n");
71         }
72
73         return ret;
74 }
75
76 int
77 rte_thread_is_intr(void)
78 {
79         return pthread_equal(intr_thread, pthread_self());
80 }
81
82 int
83 rte_intr_rx_ctl(__rte_unused struct rte_intr_handle *intr_handle,
84                 __rte_unused int epfd, __rte_unused int op,
85                 __rte_unused unsigned int vec, __rte_unused void *data)
86 {
87         return -ENOTSUP;
88 }
89
90 int
91 eal_intr_thread_schedule(void (*func)(void *arg), void *arg)
92 {
93         HANDLE handle;
94
95         handle = OpenThread(THREAD_ALL_ACCESS, FALSE, intr_thread);
96         if (handle == NULL) {
97                 RTE_LOG_WIN32_ERR("OpenThread(%llu)", intr_thread);
98                 return -ENOENT;
99         }
100
101         if (!QueueUserAPC((PAPCFUNC)(ULONG_PTR)func, handle, (ULONG_PTR)arg)) {
102                 RTE_LOG_WIN32_ERR("QueueUserAPC()");
103                 return -EINVAL;
104         }
105
106         return 0;
107 }
108
109 int
110 rte_intr_callback_register(
111         __rte_unused const struct rte_intr_handle *intr_handle,
112         __rte_unused rte_intr_callback_fn cb, __rte_unused void *cb_arg)
113 {
114         return -ENOTSUP;
115 }
116
117 int
118 rte_intr_callback_unregister_pending(
119         __rte_unused const struct rte_intr_handle *intr_handle,
120         __rte_unused rte_intr_callback_fn cb_fn, __rte_unused void *cb_arg,
121         __rte_unused rte_intr_unregister_callback_fn ucb_fn)
122 {
123         return -ENOTSUP;
124 }
125
126 int
127 rte_intr_callback_unregister(
128         __rte_unused const struct rte_intr_handle *intr_handle,
129         __rte_unused rte_intr_callback_fn cb_fn, __rte_unused void *cb_arg)
130 {
131         return 0;
132 }
133
134 int
135 rte_intr_callback_unregister_sync(
136         __rte_unused const struct rte_intr_handle *intr_handle,
137         __rte_unused rte_intr_callback_fn cb_fn, __rte_unused void *cb_arg)
138 {
139         return 0;
140 }
141
142 int
143 rte_intr_enable(__rte_unused const struct rte_intr_handle *intr_handle)
144 {
145         return -ENOTSUP;
146 }
147
148 int
149 rte_intr_ack(__rte_unused const struct rte_intr_handle *intr_handle)
150 {
151         return -ENOTSUP;
152 }
153
154 int
155 rte_intr_disable(__rte_unused const struct rte_intr_handle *intr_handle)
156 {
157         return -ENOTSUP;
158 }
159
160 int
161 rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd)
162 {
163         RTE_SET_USED(intr_handle);
164         RTE_SET_USED(nb_efd);
165
166         return 0;
167 }
168
169 void
170 rte_intr_efd_disable(struct rte_intr_handle *intr_handle)
171 {
172         RTE_SET_USED(intr_handle);
173 }
174
175 int
176 rte_intr_dp_is_en(struct rte_intr_handle *intr_handle)
177 {
178         RTE_SET_USED(intr_handle);
179
180         return 0;
181 }
182
183 int
184 rte_intr_allow_others(struct rte_intr_handle *intr_handle)
185 {
186         RTE_SET_USED(intr_handle);
187
188         return 1;
189 }
190
191 int
192 rte_intr_cap_multiple(struct rte_intr_handle *intr_handle)
193 {
194         RTE_SET_USED(intr_handle);
195
196         return 0;
197 }
198
199 int
200 rte_epoll_wait(int epfd, struct rte_epoll_event *events,
201                 int maxevents, int timeout)
202 {
203         RTE_SET_USED(epfd);
204         RTE_SET_USED(events);
205         RTE_SET_USED(maxevents);
206         RTE_SET_USED(timeout);
207
208         return -ENOTSUP;
209 }
210
211 int
212 rte_epoll_wait_interruptible(int epfd, struct rte_epoll_event *events,
213                              int maxevents, int timeout)
214 {
215         RTE_SET_USED(epfd);
216         RTE_SET_USED(events);
217         RTE_SET_USED(maxevents);
218         RTE_SET_USED(timeout);
219
220         return -ENOTSUP;
221 }
222
223 int
224 rte_epoll_ctl(int epfd, int op, int fd, struct rte_epoll_event *event)
225 {
226         RTE_SET_USED(epfd);
227         RTE_SET_USED(op);
228         RTE_SET_USED(fd);
229         RTE_SET_USED(event);
230
231         return -ENOTSUP;
232 }
233
234 int
235 rte_intr_tls_epfd(void)
236 {
237         return -ENOTSUP;
238 }
239
240 void
241 rte_intr_free_epoll_fd(struct rte_intr_handle *intr_handle)
242 {
243         RTE_SET_USED(intr_handle);
244 }