Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
3 : : */
4 : :
5 : : #include <stdint.h>
6 : : #include <sys/eventfd.h>
7 : : #include <unistd.h>
8 : : #include <ethdev_pci.h>
9 : : #include <ethdev_driver.h>
10 : : #include <rte_alarm.h>
11 : : #include <fcntl.h>
12 : : #include <rte_stdatomic.h>
13 : : #include <rte_common.h>
14 : :
15 : : #include "sxe2_ethdev.h"
16 : : #include "sxe2_irq.h"
17 : : #include "sxe2_common_log.h"
18 : : #include "sxe2_queue.h"
19 : : #include "sxe2_drv_cmd.h"
20 : : #include "sxe2_ioctl_chnl_func.h"
21 : : #include "sxe2vf_regs.h"
22 : : #include "sxe2_host_regs.h"
23 : : #include "sxe2_cmd_chnl.h"
24 : : #include "sxe2_switchdev.h"
25 : :
26 : : #define SXE2_INT_EVENT_OICR_ALL (SXE2_PF_INT_OICR_SWINT | \
27 : : SXE2_PF_INT_OICR_LAN_TX_ERR | \
28 : : SXE2_PF_INT_OICR_LAN_RX_ERR | \
29 : : SXE2_PF_INT_OICR_FW)
30 : :
31 : : #define MAX_EVENT_PENDING (16)
32 : :
33 : : struct sxe2_event_element {
34 : : TAILQ_ENTRY(sxe2_event_element) next;
35 : : struct rte_eth_dev *dev;
36 : : };
37 : :
38 : : struct sxe2_event_handler {
39 : : RTE_ATOMIC(uint16_t)ndev;
40 : : rte_thread_t tid;
41 : : int32_t fd[2];
42 : : rte_spinlock_t lock;
43 : : TAILQ_HEAD(event_list, sxe2_event_element) pending;
44 : : };
45 : : static struct sxe2_event_handler event_handler = {
46 : : .fd = {-1, -1},
47 : : };
48 : :
49 : : static RTE_ATOMIC(uint32_t)event_thread_run;
50 : :
51 : 0 : static int32_t sxe2_fc_state_callback(struct rte_eth_dev *dev)
52 : : {
53 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
54 : 0 : struct sxe2_drv_vsi_fc_get_resp fc_resp = {0};
55 : 0 : int32_t ret;
56 : :
57 [ # # ]: 0 : if (!(adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_FC_STATE)) {
58 : 0 : ret = 0;
59 : 0 : goto l_end;
60 : : }
61 : 0 : ret = sxe2_drv_fc_state_get(adapter, &fc_resp);
62 [ # # ]: 0 : if (ret) {
63 : 0 : PMD_LOG_ERR(INIT, "Failed to get fc state, ret=[%d]", ret);
64 : 0 : goto l_end;
65 : : }
66 : 0 : adapter->fc_state_ctx.cfg_state = fc_resp.fc_enable;
67 [ # # ]: 0 : if (dev->data->dev_started) {
68 : 0 : PMD_LOG_NOTICE(DRV, "Interrupt event: FC status changed."
69 : : "cfg_state:%u curr_state:%u",
70 : : adapter->fc_state_ctx.cfg_state,
71 : : adapter->fc_state_ctx.curr_state);
72 : : }
73 : 0 : l_end:
74 : 0 : return ret;
75 : : }
76 : :
77 : 0 : static void sxe2_event_irq_common_handler(struct sxe2_adapter *adapter, uint64_t oicr)
78 : : {
79 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[adapter->dev_info.dev_data->port_id];
80 : :
81 [ # # ]: 0 : if (oicr & RTE_BIT32(SXE2_COM_EC_LINK_CHG)) {
82 : 0 : PMD_DEV_LOG_INFO(adapter, DRV, "OICR=%" PRIu64, oicr);
83 : 0 : (void)sxe2_drv_mac_link_status_get(adapter);
84 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY)
85 : 0 : rte_eth_dev_callback_process(dev,
86 : : RTE_ETH_EVENT_INTR_LSC,
87 : : NULL);
88 : : }
89 [ # # ]: 0 : if (oicr & RTE_BIT32(SXE2_COM_SW_MODE_SWITCHDEV)) {
90 : 0 : PMD_DEV_LOG_INFO(adapter, DRV, "event notify switchdev");
91 : 0 : (void)sxe2_switchdev_notify_callback(adapter, true);
92 : : }
93 [ # # ]: 0 : if (oicr & RTE_BIT32(SXE2_COM_SW_MODE_LEGACY)) {
94 : 0 : PMD_DEV_LOG_INFO(adapter, DRV, "event notify legacy");
95 : 0 : (void)sxe2_switchdev_notify_callback(adapter, false);
96 : : }
97 [ # # ]: 0 : if (oicr & RTE_BIT32(SXE2_COM_FC_ST_CHANGE)) {
98 : 0 : PMD_DEV_LOG_INFO(adapter, DRV, "fc event notify legacy");
99 : 0 : (void)sxe2_fc_state_callback(dev);
100 : : }
101 : 0 : }
102 : :
103 : 0 : static uint32_t sxe2_event_intr_handle(void *param __rte_unused)
104 : : {
105 : 0 : struct sxe2_event_handler *handler = &event_handler;
106 : 0 : struct sxe2_adapter *adapter;
107 : 0 : struct sxe2_event_element *pos;
108 : 0 : struct sxe2_event_element *tmp;
109 : 0 : int32_t ret = 0;
110 : 0 : uint64_t oicr = 0;
111 : 0 : TAILQ_HEAD(event_list, sxe2_event_element) pending;
112 : 0 : int8_t unused[MAX_EVENT_PENDING];
113 : 0 : ssize_t nr;
114 : :
115 [ # # ]: 0 : while (rte_atomic_load_explicit(&event_thread_run, rte_memory_order_relaxed)) {
116 : 0 : nr = read(handler->fd[0], &unused, sizeof(unused));
117 [ # # ]: 0 : if (nr <= 0)
118 : : break;
119 : :
120 : 0 : rte_spinlock_lock(&handler->lock);
121 : 0 : TAILQ_INIT(&pending);
122 [ # # ]: 0 : TAILQ_CONCAT(&pending, &handler->pending, next);
123 : 0 : rte_spinlock_unlock(&handler->lock);
124 : :
125 [ # # ]: 0 : TAILQ_FOREACH_SAFE(pos, &pending, next, tmp) {
126 [ # # ]: 0 : TAILQ_REMOVE(&pending, pos, next);
127 : 0 : adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(pos->dev);
128 : :
129 : 0 : ret = sxe2_drv_dev_other_irq_get(adapter->cdev, &oicr);
130 : 0 : sxe2_event_irq_common_handler(adapter, oicr);
131 : :
132 : 0 : rte_free(pos);
133 : : }
134 : : }
135 : :
136 : 0 : return ret;
137 : : }
138 : :
139 : 0 : static int32_t sxe2_event_intr_handler_init(void)
140 : : {
141 : 0 : struct sxe2_event_handler *handler = &event_handler;
142 : 0 : int32_t ret = 0;
143 : 0 : int err = 0;
144 : :
145 : 0 : PMD_INIT_FUNC_TRACE();
146 [ # # ]: 0 : if (rte_atomic_fetch_add_explicit(&handler->ndev, 1, rte_memory_order_acq_rel) >= 1) {
147 : 0 : ret = 0;
148 : 0 : PMD_LOG_DEBUG(INIT, "%s: ndev > 1", __func__);
149 : 0 : goto l_end;
150 : : }
151 : :
152 : : #if defined(RTE_EXEC_ENV_IS_WINDOWS) && RTE_EXEC_ENV_IS_WINDOWS != 0
153 : : err = _pipe(handler->fd, MAX_EVENT_PENDING, O_BINARY);
154 : : #else
155 : 0 : err = pipe(handler->fd);
156 : : #endif
157 [ # # ]: 0 : if (err != 0) {
158 : 0 : ret = -ECHILD;
159 : 0 : rte_atomic_fetch_sub_explicit(&handler->ndev, 1, rte_memory_order_release);
160 : 0 : PMD_LOG_ERR(INIT, "%s: pipe failed", __func__);
161 : 0 : goto l_end;
162 : : }
163 : :
164 : 0 : rte_atomic_store_explicit(&event_thread_run, 1, rte_memory_order_relaxed);
165 : :
166 : 0 : TAILQ_INIT(&handler->pending);
167 : 0 : rte_spinlock_init(&handler->lock);
168 : :
169 [ # # ]: 0 : if (rte_thread_create_internal_control(&handler->tid, "sxe2-event",
170 : : sxe2_event_intr_handle, NULL)) {
171 : 0 : PMD_LOG_ERR(INIT, "%s: thread create failed", __func__);
172 : 0 : rte_atomic_fetch_sub_explicit(&handler->ndev, 1, rte_memory_order_release);
173 : 0 : ret = -ECHILD;
174 : 0 : goto l_end;
175 : : }
176 : : ret = 0;
177 : 0 : l_end:
178 : 0 : return ret;
179 : : }
180 : :
181 : 0 : static void sxe2_event_intr_handler_uinit(void)
182 : : {
183 : 0 : struct sxe2_event_handler *handler = &event_handler;
184 : 0 : struct sxe2_event_element *pos;
185 : 0 : struct sxe2_event_element *tmp;
186 : 0 : ssize_t nw = 0;
187 : 0 : int8_t notify_byte = 0;
188 : :
189 : 0 : PMD_INIT_FUNC_TRACE();
190 [ # # ]: 0 : if (rte_atomic_fetch_sub_explicit(&handler->ndev, 1, rte_memory_order_acq_rel) > 1) {
191 : 0 : PMD_LOG_DEBUG(INIT, "event handler uinit, ndev > 0");
192 : 0 : return;
193 : : }
194 : :
195 : 0 : rte_atomic_store_explicit(&event_thread_run, 0, rte_memory_order_relaxed);
196 : 0 : nw = write(handler->fd[1], ¬ify_byte, 1);
197 : 0 : RTE_SET_USED(nw);
198 : :
199 : 0 : (void)rte_thread_join(handler->tid, NULL);
200 : :
201 [ # # ]: 0 : if (handler->fd[0] != -1) {
202 : 0 : close(handler->fd[0]);
203 : 0 : handler->fd[0] = -1;
204 : : }
205 [ # # ]: 0 : if (handler->fd[1] != -1) {
206 : 0 : close(handler->fd[1]);
207 : 0 : handler->fd[1] = -1;
208 : : }
209 : :
210 : 0 : rte_spinlock_lock(&handler->lock);
211 [ # # ]: 0 : TAILQ_FOREACH_SAFE(pos, &handler->pending, next, tmp) {
212 [ # # ]: 0 : TAILQ_REMOVE(&handler->pending, pos, next);
213 : 0 : rte_free(pos);
214 : : }
215 : 0 : rte_spinlock_unlock(&handler->lock);
216 : : }
217 : :
218 : 0 : static void sxe2_event_intr_post(struct rte_eth_dev *dev)
219 : : {
220 : 0 : struct sxe2_event_handler *handler = &event_handler;
221 : 0 : struct sxe2_event_element *elem = rte_malloc(NULL, sizeof(struct sxe2_event_element), 0);
222 : 0 : int8_t notify_byte = 0;
223 : 0 : ssize_t nw = 0;
224 : :
225 [ # # ]: 0 : if (!elem)
226 : 0 : goto l_end;
227 : :
228 : 0 : elem->dev = dev;
229 : :
230 : 0 : rte_spinlock_lock(&handler->lock);
231 : 0 : TAILQ_INSERT_TAIL(&handler->pending, elem, next);
232 : 0 : rte_spinlock_unlock(&handler->lock);
233 : :
234 : 0 : nw = write(handler->fd[1], ¬ify_byte, 1);
235 : 0 : RTE_SET_USED(nw);
236 : :
237 : 0 : l_end:
238 : 0 : return;
239 : : }
240 : :
241 : 0 : static void sxe2_interrupt_handler_other(void *arg)
242 : : {
243 : 0 : struct rte_eth_dev *dev = (struct rte_eth_dev *)arg;
244 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
245 : 0 : int32_t eventfd = adapter->irq_ctxt.other_event_fd;
246 : 0 : int32_t ret = 0;
247 : 0 : uint64_t buf = 0;
248 : :
249 : 0 : ret = read(eventfd, &buf, sizeof(buf));
250 [ # # ]: 0 : if (ret != sizeof(buf)) {
251 : 0 : PMD_DEV_LOG_ERR(adapter, DRV, "read eventfd[%d] failed, ret:%d, errno:%d.",
252 : : eventfd, ret, errno);
253 : : }
254 : :
255 : 0 : sxe2_event_intr_post(dev);
256 : 0 : }
257 : :
258 : 0 : static void sxe2_interrupt_handler_reset(void *arg)
259 : : {
260 : 0 : struct rte_eth_dev *dev = (struct rte_eth_dev *)arg;
261 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
262 : 0 : int32_t resetfd = adapter->irq_ctxt.reset_event_fd;
263 : 0 : int32_t ret = 0;
264 : 0 : uint64_t buf = 0;
265 : :
266 : 0 : ret = read(resetfd, &buf, sizeof(buf));
267 [ # # ]: 0 : if (ret != sizeof(buf)) {
268 : 0 : PMD_DEV_LOG_ERR(adapter, DRV, "read resetfd[%d] failed, ret:%d, errno:%d.",
269 : : resetfd, ret, errno);
270 : : }
271 : :
272 : 0 : sxe2_drv_cmd_close(adapter->cdev);
273 : :
274 : 0 : rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RMV, NULL);
275 : 0 : }
276 : :
277 : 0 : int32_t sxe2_sw_irq_ctxt_init(struct rte_eth_dev *dev)
278 : : {
279 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
280 : 0 : struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
281 : 0 : int32_t ret = 0;
282 : :
283 : 0 : irq_ctxt->rxq_avail_cnt = irq_ctxt->max_cnt_hw;
284 : 0 : irq_ctxt->rxq_base_idx_in_pf = irq_ctxt->base_idx_in_func;
285 : 0 : irq_ctxt->reset_event_fd = -1;
286 : 0 : irq_ctxt->other_event_fd = -1;
287 : :
288 : 0 : return ret;
289 : : }
290 : :
291 : 0 : void sxe2_sw_irq_ctxt_uninit(struct rte_eth_dev *dev)
292 : : {
293 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
294 : :
295 : 0 : memset(&adapter->irq_ctxt, 0, sizeof(adapter->irq_ctxt));
296 : 0 : adapter->irq_ctxt.reset_event_fd = -1;
297 : 0 : adapter->irq_ctxt.other_event_fd = -1;
298 : 0 : }
299 : :
300 : 0 : void sxe2_sw_irq_ctx_hw_cap_set(struct sxe2_adapter *adapter,
301 : : struct sxe2_drv_msix_caps *msix_caps)
302 : : {
303 : 0 : adapter->irq_ctxt.max_cnt_hw = msix_caps->msix_vectors_cnt;
304 : 0 : adapter->irq_ctxt.base_idx_in_func = msix_caps->base_idx_in_func;
305 : 0 : }
306 : :
307 : 0 : static int32_t sxe2_intr_handler_cfg(struct rte_intr_handle *handle,
308 : : int32_t fd, rte_intr_callback_fn cb, void *cb_arg)
309 : : {
310 : 0 : int32_t ret = 0;
311 : :
312 : 0 : ret = rte_intr_fd_set(handle, fd);
313 [ # # ]: 0 : if (ret) {
314 : 0 : PMD_LOG_ERR(INIT, "Failed to set intr_handle->fd, error %i (%s)",
315 : : errno, strerror(errno));
316 : 0 : goto err;
317 : : }
318 : :
319 : 0 : ret = rte_intr_type_set(handle, RTE_INTR_HANDLE_EXT);
320 [ # # ]: 0 : if (ret) {
321 : 0 : PMD_LOG_ERR(INIT, "Failed to set intr_handle->type, error %i (%s)",
322 : : errno, strerror(errno));
323 : 0 : goto err;
324 : : }
325 : :
326 : 0 : ret = rte_intr_callback_register(handle, cb, cb_arg);
327 [ # # ]: 0 : if (ret) {
328 : 0 : PMD_LOG_ERR(INIT, "Failed to initialize register intr callback, ret=%d", ret);
329 : 0 : goto err;
330 : : }
331 : 0 : err:
332 : 0 : return ret;
333 : : }
334 : :
335 : : static struct rte_intr_handle *
336 : 0 : sxe2_intr_handler_create(int32_t fd, rte_intr_callback_fn cb, void *cb_arg)
337 : : {
338 : 0 : struct rte_intr_handle *tmp_intr_handle = NULL;
339 : 0 : int32_t ret = 0;
340 : :
341 : 0 : tmp_intr_handle = rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE);
342 [ # # ]: 0 : if (!tmp_intr_handle) {
343 : 0 : PMD_LOG_ERR(INIT, "Failed to alloc memory for intr_handler, error %i (%s)",
344 : : errno, strerror(errno));
345 : 0 : goto err;
346 : : }
347 : :
348 : 0 : ret = rte_intr_fd_set(tmp_intr_handle, fd);
349 [ # # ]: 0 : if (ret) {
350 : 0 : PMD_LOG_ERR(INIT, "Failed to set intr_handle->fd, error %i (%s)",
351 : : errno, strerror(errno));
352 : 0 : goto err;
353 : : }
354 : :
355 : 0 : ret = rte_intr_type_set(tmp_intr_handle, RTE_INTR_HANDLE_EXT);
356 [ # # ]: 0 : if (ret) {
357 : 0 : PMD_LOG_ERR(INIT, "Failed to set intr_handle->type, error %i (%s)",
358 : : errno, strerror(errno));
359 : 0 : goto err;
360 : : }
361 : :
362 : 0 : ret = rte_intr_callback_register(tmp_intr_handle, cb, cb_arg);
363 [ # # ]: 0 : if (ret) {
364 : 0 : PMD_LOG_ERR(INIT, "Failed to initialize register intr callback, ret=%d", ret);
365 : 0 : goto err;
366 : : }
367 : :
368 : : return tmp_intr_handle;
369 : 0 : err:
370 : 0 : rte_intr_instance_free(tmp_intr_handle);
371 : 0 : return NULL;
372 : : }
373 : :
374 : 0 : static void sxe2_intr_handler_destroy(struct rte_intr_handle *intr_handle,
375 : : rte_intr_callback_fn cb, void *cb_arg)
376 : : {
377 [ # # ]: 0 : if (!intr_handle)
378 : : return;
379 : :
380 [ # # ]: 0 : if (rte_intr_fd_get(intr_handle) >= 0)
381 : 0 : (void)rte_intr_callback_unregister(intr_handle, cb, cb_arg);
382 : 0 : rte_intr_instance_free(intr_handle);
383 : : }
384 : :
385 : 0 : static int32_t sxe2_event_intr_fd_create(void)
386 : : {
387 : 0 : int32_t fd = 0;
388 : :
389 : 0 : fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
390 [ # # ]: 0 : if (fd < 0) {
391 : 0 : PMD_LOG_ERR(INIT, "Can't setup eventfd, error %i (%s)",
392 : : errno, strerror(errno));
393 : 0 : goto err;
394 : : }
395 : :
396 : : return fd;
397 : 0 : err:
398 : 0 : return -EBADF;
399 : : }
400 : :
401 : 0 : static void sxe2_event_intr_fd_destroy(int32_t fd)
402 : : {
403 : 0 : if (fd >= 0)
404 : 0 : close(fd);
405 : 0 : }
406 : :
407 : 0 : static int32_t sxe2_other_intr_register(struct rte_eth_dev *dev, int32_t fd)
408 : : {
409 : 0 : struct sxe2_adapter *adapter =
410 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
411 : 0 : int32_t ret = 0;
412 : 0 : uint64_t event = RTE_BIT32(SXE2_COM_EC_LINK_CHG) |
413 : : RTE_BIT32(SXE2_COM_SW_MODE_LEGACY) |
414 : : RTE_BIT32(SXE2_COM_SW_MODE_SWITCHDEV) |
415 : : RTE_BIT32(SXE2_COM_FC_ST_CHANGE);
416 : :
417 : 0 : ret = sxe2_drv_dev_other_irq_set(adapter->cdev, fd, event);
418 [ # # ]: 0 : if (ret) {
419 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set other irq, ret=%d", ret);
420 : 0 : goto l_end;
421 : : }
422 : :
423 : 0 : l_end:
424 : 0 : return ret;
425 : : }
426 : :
427 : 0 : static void sxe2_other_intr_unregister(struct rte_eth_dev *dev)
428 : : {
429 : 0 : struct sxe2_adapter *adapter =
430 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
431 : 0 : int32_t ret = 0;
432 : :
433 : 0 : ret = sxe2_drv_dev_other_irq_set(adapter->cdev, -1, 0);
434 [ # # ]: 0 : if (ret)
435 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set other irq, ret=%d", ret);
436 : 0 : }
437 : :
438 : 0 : static int32_t sxe2_reset_intr_register(struct rte_eth_dev *dev, int32_t fd)
439 : : {
440 : 0 : struct sxe2_adapter *adapter =
441 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
442 : 0 : int32_t ret = 0;
443 : :
444 : 0 : ret = sxe2_drv_dev_reset_irq_set(adapter->cdev, fd);
445 [ # # ]: 0 : if (ret) {
446 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set reset irq, ret=%d", ret);
447 : 0 : goto l_end;
448 : : }
449 : :
450 : 0 : l_end:
451 : 0 : return ret;
452 : : }
453 : :
454 : 0 : static void sxe2_reset_intr_unregister(struct rte_eth_dev *dev)
455 : : {
456 : 0 : struct sxe2_adapter *adapter =
457 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
458 : 0 : int32_t ret = 0;
459 : :
460 : 0 : ret = sxe2_drv_dev_reset_irq_set(adapter->cdev, -1);
461 [ # # ]: 0 : if (ret)
462 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set reset irq, ret=%d", ret);
463 : 0 : }
464 : :
465 : 0 : int32_t sxe2_intr_init(struct rte_eth_dev *dev)
466 : : {
467 : 0 : struct sxe2_adapter *adapter =
468 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
469 : 0 : struct rte_pci_device *pci_dev = container_of(dev->device, struct rte_pci_device, device);
470 : 0 : struct rte_intr_handle *reset_handle = NULL;
471 : 0 : int32_t ofd = -1;
472 : 0 : int32_t rfd = -1;
473 : 0 : int32_t ret = 0;
474 : :
475 : 0 : PMD_INIT_FUNC_TRACE();
476 : :
477 : 0 : ofd = sxe2_event_intr_fd_create();
478 [ # # ]: 0 : if (ofd < 0) {
479 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to create event intr fd");
480 : 0 : ret = -EBADF;
481 : 0 : goto l_end;
482 : : }
483 : :
484 : 0 : ret = sxe2_intr_handler_cfg(pci_dev->intr_handle,
485 : : ofd, sxe2_interrupt_handler_other, dev);
486 [ # # ]: 0 : if (ret) {
487 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to create intr handler");
488 : 0 : goto l_err_create_other_handler;
489 : : }
490 : :
491 : 0 : ret = sxe2_event_intr_handler_init();
492 [ # # ]: 0 : if (ret) {
493 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Event handler init failed, ret=%d", ret);
494 : 0 : goto l_err_event_intr_handler_init;
495 : : }
496 : :
497 : 0 : ret = sxe2_other_intr_register(dev, ofd);
498 [ # # ]: 0 : if (ret) {
499 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to register other intr, ret=%d", ret);
500 : 0 : goto l_err_register_other_intr;
501 : : }
502 : 0 : adapter->irq_ctxt.other_event_fd = ofd;
503 : :
504 : 0 : rfd = sxe2_event_intr_fd_create();
505 [ # # ]: 0 : if (rfd < 0) {
506 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to create event intr fd");
507 : 0 : ret = -EBADF;
508 : 0 : goto l_err_create_reset_fd;
509 : : }
510 : :
511 : 0 : reset_handle = sxe2_intr_handler_create(rfd, sxe2_interrupt_handler_reset, dev);
512 [ # # ]: 0 : if (!reset_handle) {
513 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to create intr handler");
514 : 0 : ret = -ENOMEM;
515 : 0 : goto l_err_create_reset_handler;
516 : : }
517 : 0 : adapter->irq_ctxt.reset_handle = reset_handle;
518 : :
519 : 0 : ret = sxe2_reset_intr_register(dev, rfd);
520 [ # # ]: 0 : if (ret) {
521 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to register reset intr, ret=%d", ret);
522 : 0 : goto l_err_register_reset_intr;
523 : : }
524 : 0 : adapter->irq_ctxt.reset_event_fd = rfd;
525 : :
526 : 0 : goto l_end;
527 : 0 : l_err_register_reset_intr:
528 : 0 : sxe2_intr_handler_destroy(reset_handle, sxe2_interrupt_handler_reset, dev);
529 : 0 : adapter->irq_ctxt.reset_handle = NULL;
530 : 0 : l_err_create_reset_handler:
531 : 0 : sxe2_event_intr_fd_destroy(rfd);
532 : 0 : l_err_create_reset_fd:
533 : 0 : sxe2_other_intr_unregister(dev);
534 : 0 : adapter->irq_ctxt.other_event_fd = -1;
535 : 0 : l_err_register_other_intr:
536 : 0 : sxe2_event_intr_handler_uinit();
537 : 0 : l_err_event_intr_handler_init:
538 : 0 : sxe2_intr_handler_destroy(pci_dev->intr_handle,
539 : : sxe2_interrupt_handler_other, dev);
540 : 0 : pci_dev->intr_handle = NULL;
541 : 0 : l_err_create_other_handler:
542 : 0 : sxe2_event_intr_fd_destroy(ofd);
543 : 0 : l_end:
544 : 0 : return ret;
545 : : }
546 : :
547 : 0 : void sxe2_intr_uninit(struct rte_eth_dev *dev)
548 : : {
549 : 0 : struct sxe2_adapter *adapter =
550 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
551 : 0 : struct rte_pci_device *pci_dev = container_of(dev->device, struct rte_pci_device, device);
552 : :
553 : 0 : sxe2_reset_intr_unregister(dev);
554 : 0 : sxe2_intr_handler_destroy(adapter->irq_ctxt.reset_handle,
555 : : sxe2_interrupt_handler_reset, dev);
556 [ # # ]: 0 : sxe2_event_intr_fd_destroy(adapter->irq_ctxt.reset_event_fd);
557 : 0 : sxe2_other_intr_unregister(dev);
558 : 0 : sxe2_event_intr_handler_uinit();
559 : 0 : sxe2_intr_handler_destroy(pci_dev->intr_handle,
560 : : sxe2_interrupt_handler_other, dev);
561 [ # # ]: 0 : sxe2_event_intr_fd_destroy(adapter->irq_ctxt.other_event_fd);
562 : :
563 : 0 : adapter->irq_ctxt.other_event_fd = -1;
564 : 0 : adapter->irq_ctxt.reset_event_fd = -1;
565 : 0 : pci_dev->intr_handle = NULL;
566 : 0 : adapter->irq_ctxt.reset_handle = NULL;
567 : 0 : }
568 : :
569 : 0 : static int32_t sxe2_rxq_intr_efd_alloc(struct rte_eth_dev *dev, int32_t *efd)
570 : : {
571 : 0 : struct sxe2_adapter *adapter =
572 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
573 : 0 : int32_t ret = 0;
574 : 0 : int32_t fd = 0;
575 : :
576 : 0 : fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
577 [ # # ]: 0 : if (fd < 0) {
578 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Can't setup eventfd, error %i (%s)",
579 : : errno, strerror(errno));
580 : 0 : ret = -EBADF;
581 : 0 : goto l_end;
582 : : }
583 : :
584 : 0 : *efd = fd;
585 : :
586 : 0 : l_end:
587 : 0 : return ret;
588 : : }
589 : :
590 : 0 : static void sxe2_rxq_intr_efd_free(int32_t efd)
591 : : {
592 : 0 : close(efd);
593 : 0 : }
594 : :
595 : 0 : static void sxe2_pci_hw_int_itr_set(struct sxe2_adapter *adapter, uint16_t msix_idx, uint16_t itr)
596 : : {
597 : 0 : sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_ITR, msix_idx, itr);
598 : 0 : }
599 : :
600 : 0 : static void sxe2_pci_hw_irq_disable(struct sxe2_adapter *adapter, uint16_t irq_idx)
601 : : {
602 : 0 : uint32_t value = (SXE2_ITR_IDX_NONE << SXE2_VF_DYN_CTL_ITR_IDX_S);
603 : :
604 : 0 : sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_DYN, irq_idx, value);
605 : : }
606 : :
607 : 0 : static void sxe2_pci_hw_irq_enable(struct sxe2_adapter *adapter, uint16_t irq_idx)
608 : : {
609 : 0 : uint32_t value = SXE2_VF_DYN_CTL_INTENABLE |
610 : : SXE2_VF_DYN_CTL_CLEARPBA |
611 : : (SXE2_ITR_IDX_NONE << SXE2_VF_DYN_CTL_ITR_IDX_S);
612 : :
613 : 0 : sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_DYN, irq_idx, value);
614 : : }
615 : :
616 : 0 : static uint32_t sxe2_pci_hw_irq_dyn_ctl_read(struct sxe2_adapter *adapter, uint16_t irq_idx)
617 : : {
618 : 0 : return sxe2_pci_map_read_reg(adapter, SXE2_PCI_MAP_RES_IRQ_DYN, irq_idx);
619 : : }
620 : :
621 : 0 : static void sxe2_pci_hw_msix_disable(struct sxe2_adapter *adapter, uint16_t irq_idx)
622 : : {
623 : 0 : sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_MSIX,
624 : : irq_idx, SXE2VF_BAR4_MSIX_DISABLE);
625 : : }
626 : :
627 : 0 : static void sxe2_pci_hw_msix_enable(struct sxe2_adapter *adapter, uint16_t irq_idx)
628 : : {
629 : 0 : sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_MSIX,
630 : : irq_idx, SXE2VF_BAR4_MSIX_ENABLE);
631 : 0 : }
632 : :
633 : 0 : static void sxe2_pci_hw_irq_trigger(struct sxe2_adapter *adapter, uint16_t irq_idx)
634 : : {
635 : 0 : sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_DYN, irq_idx,
636 : : (SXE2VF_ITR_IDX_NONE << SXE2VF_DYN_CTL_ITR_IDX_SHIFT) |
637 : : SXE2VF_DYN_CTL_SWINT_TRIG | SXE2VF_DYN_CTL_INTENABLE_MSK);
638 : : }
639 : :
640 : 0 : static void sxe2_pci_hw_irq_clear_pba(struct sxe2_adapter *adapter, uint16_t irq_idx)
641 : : {
642 : 0 : sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_DYN, irq_idx,
643 : : (SXE2VF_ITR_IDX_NONE << SXE2VF_DYN_CTL_ITR_IDX_SHIFT) |
644 : : SXE2VF_DYN_CTL_CLEARPBA | SXE2VF_DYN_CTL_INTENABLE_MSK);
645 : : }
646 : :
647 : 0 : static void sxe2_rxq_msix_cfg_unmap(struct rte_eth_dev *dev)
648 : : {
649 : 0 : struct sxe2_adapter *adapter =
650 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
651 : 0 : struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
652 : 0 : uint16_t rxq_cnt = adapter->q_ctxt.qp_cnt_assign;
653 : 0 : uint16_t i = 0;
654 : :
655 [ # # ]: 0 : for (i = 0; i < irq_ctxt->rxq_irq_cnt; i++)
656 : 0 : sxe2_pci_hw_irq_disable(adapter, irq_ctxt->rxq_msix_idx[i]);
657 : :
658 [ # # ]: 0 : for (i = 0; i < rxq_cnt; i++)
659 : 0 : (void)sxe2_drv_rxq_unbind_irq(adapter, i);
660 : 0 : }
661 : :
662 : 0 : static int32_t sxe2_rxq_msix_cfg_map(struct rte_eth_dev *dev)
663 : : {
664 : 0 : struct sxe2_adapter *adapter =
665 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
666 : 0 : struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
667 : 0 : int32_t ret = 0;
668 : 0 : uint32_t val;
669 : 0 : uint16_t rxq_cnt = dev->data->nb_rx_queues;
670 : 0 : uint16_t i = 0;
671 : 0 : uint8_t rx_low_latency = adapter->devargs.rx_low_latency;
672 : :
673 [ # # ]: 0 : for (i = 0; i < irq_ctxt->rxq_irq_cnt; i++) {
674 : 0 : sxe2_pci_hw_irq_disable(adapter, irq_ctxt->rxq_msix_idx[i]);
675 [ # # ]: 0 : if (rx_low_latency) {
676 : 0 : sxe2_pci_hw_int_itr_set(adapter, irq_ctxt->rxq_msix_idx[i],
677 : : SXE2_ITR_INTERVAL_LOW);
678 : : } else {
679 : 0 : sxe2_pci_hw_int_itr_set(adapter, irq_ctxt->rxq_msix_idx[i],
680 : : SXE2_ITR_INTERVAL_NORMAL);
681 : : }
682 : : }
683 : :
684 [ # # ]: 0 : for (i = 0; i < rxq_cnt; i++) {
685 : 0 : ret = sxe2_drv_rxq_bind_irq(adapter, i, irq_ctxt->rxq_msix_idx[i]);
686 [ # # ]: 0 : if (ret != 0) {
687 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "RXQ[%u] bind IRQ[%u] failed.",
688 : : i, irq_ctxt->rxq_msix_idx[i]);
689 : 0 : goto l_end;
690 : : }
691 : : }
692 : :
693 [ # # ]: 0 : for (i = 0; i < irq_ctxt->rxq_irq_cnt; i++)
694 : 0 : sxe2_pci_hw_irq_enable(adapter, irq_ctxt->rxq_msix_idx[i]);
695 : :
696 [ # # ]: 0 : for (i = 0; i < irq_ctxt->rxq_irq_cnt; i++) {
697 : 0 : val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, i);
698 [ # # ]: 0 : if ((val & SXE2VF_DYN_CTL_INTENABLE) == 0)
699 : 0 : continue;
700 : :
701 : 0 : sxe2_pci_hw_msix_disable(adapter, i);
702 : 0 : sxe2_pci_hw_irq_trigger(adapter, i);
703 : 0 : val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, i);
704 : 0 : sxe2_pci_hw_irq_clear_pba(adapter, i);
705 : 0 : val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, i);
706 : 0 : sxe2_pci_hw_msix_enable(adapter, i);
707 : : }
708 : :
709 : 0 : l_end:
710 [ # # ]: 0 : if (ret != 0)
711 : 0 : sxe2_rxq_msix_cfg_unmap(dev);
712 : 0 : return ret;
713 : : }
714 : :
715 : 0 : static int32_t sxe2_rxq_map_msix_intr(struct rte_eth_dev *dev,
716 : : uint16_t msix_base __rte_unused, uint16_t nb_msix,
717 : : uint16_t base_queue, uint16_t nb_queue)
718 : : {
719 : 0 : struct sxe2_adapter *adapter =
720 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
721 : 0 : struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
722 : 0 : uint32_t *msix_tbl = NULL;
723 : 0 : int32_t ret = 0;
724 : 0 : uint16_t i;
725 : :
726 [ # # # # ]: 0 : if (!nb_queue || !nb_msix || nb_queue < nb_msix) {
727 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Queue num[%u] or msix num[%u] is invalid.",
728 : : nb_queue, nb_msix);
729 : 0 : ret = -EINVAL;
730 : 0 : goto l_end;
731 : : }
732 : :
733 : 0 : msix_tbl = rte_zmalloc(NULL, sizeof(uint32_t) * nb_queue, 0);
734 [ # # ]: 0 : if (!msix_tbl) {
735 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to alloc msix_tbl memory.");
736 : 0 : ret = -ENOMEM;
737 : 0 : goto l_end;
738 : : }
739 [ # # ]: 0 : for (i = 0; i < nb_queue; i++) {
740 : 0 : msix_tbl[i] = i % nb_msix;
741 : 0 : PMD_DEV_LOG_INFO(adapter, INIT, "Queue %u is binding to vect %u",
742 : : base_queue + i, msix_tbl[i]);
743 : : }
744 : :
745 : 0 : irq_ctxt->rxq_irq_cnt = nb_msix;
746 : 0 : irq_ctxt->rxq_msix_idx = msix_tbl;
747 : :
748 : 0 : l_end:
749 : 0 : return ret;
750 : : }
751 : :
752 : 0 : static void sxe2_rxq_unmap_msix_intr(struct rte_eth_dev *dev)
753 : : {
754 : 0 : struct sxe2_adapter *adapter =
755 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
756 : 0 : struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
757 : :
758 : 0 : rte_free(irq_ctxt->rxq_msix_idx);
759 : 0 : irq_ctxt->rxq_msix_idx = NULL;
760 : 0 : irq_ctxt->rxq_irq_cnt = 0;
761 : 0 : }
762 : :
763 : 0 : static int32_t sxe2_rxq_intr_register(struct rte_eth_dev *dev)
764 : : {
765 : 0 : struct sxe2_adapter *adapter =
766 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
767 : 0 : struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
768 : 0 : struct rte_intr_handle *intr_handle = dev->intr_handle;
769 : 0 : int32_t *efd_tbl = NULL;
770 : 0 : uint16_t rxq_cnt = dev->data->nb_rx_queues;
771 : 0 : uint16_t nb_msix = irq_ctxt->rxq_irq_cnt;
772 : 0 : uint16_t i;
773 : 0 : int32_t ret = 0;
774 : :
775 [ # # ]: 0 : if (rte_intr_type_set(intr_handle, RTE_INTR_HANDLE_EXT)) {
776 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set intr_handle->type, error %i (%s)",
777 : : errno, strerror(errno));
778 : 0 : ret = -EPERM;
779 : 0 : goto l_end;
780 : : }
781 : :
782 : 0 : efd_tbl = rte_zmalloc(NULL, sizeof(int32_t) * nb_msix, 0);
783 [ # # ]: 0 : if (!efd_tbl) {
784 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to alloc efd_tbl memory.");
785 : 0 : ret = -ENOMEM;
786 : 0 : goto l_end;
787 : : }
788 : :
789 [ # # ]: 0 : for (i = 0; i < nb_msix; i++) {
790 : 0 : ret = sxe2_rxq_intr_efd_alloc(dev, &efd_tbl[i]);
791 [ # # ]: 0 : if (ret) {
792 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to alloc efd_tbl, ret=%d", ret);
793 : 0 : goto l_free_efd_tbl;
794 : : }
795 : : }
796 : :
797 [ # # ]: 0 : if (rte_intr_vec_list_alloc(intr_handle, "sxe2 rxq int", rxq_cnt)) {
798 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to allocate %d rx_queues intr_vec",
799 : : rxq_cnt);
800 : 0 : ret = -ENOMEM;
801 : 0 : goto l_free_efd_tbl;
802 : : }
803 : :
804 [ # # ]: 0 : for (i = 0; i < rxq_cnt; i++) {
805 : 0 : ret = rte_intr_vec_list_index_set(intr_handle, i,
806 : 0 : irq_ctxt->rxq_msix_idx[i] + RTE_INTR_VEC_RXTX_OFFSET);
807 [ # # ]: 0 : if (ret) {
808 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set msix_tbl, ret=%d", ret);
809 : 0 : goto l_free_efd_tbl;
810 : : }
811 : : }
812 : :
813 [ # # ]: 0 : for (i = 0; i < irq_ctxt->rxq_irq_cnt; i++) {
814 : 0 : ret = rte_intr_efds_index_set(intr_handle, i, efd_tbl[i]);
815 [ # # ]: 0 : if (ret) {
816 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set efd_tbl, ret=%d", ret);
817 : 0 : goto l_free_efd_tbl;
818 : : }
819 : : }
820 : :
821 [ # # ]: 0 : if (rte_intr_nb_efd_set(intr_handle, rxq_cnt)) {
822 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Set intr nb efd failed, error %i (%s)",
823 : : errno, strerror(errno));
824 : 0 : ret = -EPERM;
825 : 0 : goto l_free_efd_tbl;
826 : : }
827 : :
828 : 0 : ret = sxe2_drv_dev_rxq_irq_set(adapter->cdev, 0, efd_tbl, nb_msix);
829 [ # # ]: 0 : if (ret) {
830 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set rxq irq, ret=%d", ret);
831 : 0 : goto l_free_efd_tbl;
832 : : }
833 : 0 : irq_ctxt->rxq_event_fd = efd_tbl;
834 : :
835 : 0 : goto l_end;
836 : :
837 : 0 : l_free_efd_tbl:
838 : 0 : if (efd_tbl) {
839 [ # # ]: 0 : for (i = 0; i < nb_msix; i++)
840 [ # # ]: 0 : if (efd_tbl[i] >= 0)
841 : 0 : sxe2_rxq_intr_efd_free(efd_tbl[i]);
842 : 0 : rte_free(efd_tbl);
843 : : }
844 : 0 : irq_ctxt->rxq_event_fd = NULL;
845 : :
846 : 0 : rte_intr_vec_list_free(intr_handle);
847 : 0 : l_end:
848 : 0 : return ret;
849 : : }
850 : :
851 : 0 : static void sxe2_rxq_intr_unregister(struct rte_eth_dev *dev)
852 : : {
853 : 0 : struct sxe2_adapter *adapter =
854 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
855 : 0 : struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
856 : 0 : struct rte_intr_handle *intr_handle = dev->intr_handle;
857 : 0 : int32_t efd = -1;
858 : 0 : uint16_t msix_cnt = irq_ctxt->rxq_irq_cnt;
859 : 0 : uint16_t i;
860 : :
861 [ # # ]: 0 : if (irq_ctxt->rxq_event_fd) {
862 [ # # ]: 0 : for (i = 0; i < msix_cnt; i++) {
863 : 0 : (void)sxe2_drv_dev_rxq_irq_set(adapter->cdev, i, &efd, 1);
864 : 0 : sxe2_rxq_intr_efd_free(irq_ctxt->rxq_event_fd[i]);
865 : : }
866 : : }
867 : 0 : rte_free(irq_ctxt->rxq_event_fd);
868 : 0 : irq_ctxt->rxq_event_fd = NULL;
869 : :
870 : 0 : rte_intr_vec_list_free(intr_handle);
871 : :
872 : 0 : rte_intr_nb_efd_set(intr_handle, 0);
873 : 0 : rte_intr_max_intr_set(intr_handle, 0);
874 : 0 : }
875 : :
876 : 0 : int32_t sxe2_rxq_intr_enable(struct rte_eth_dev *dev)
877 : : {
878 : 0 : struct sxe2_adapter *adapter =
879 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
880 : 0 : uint16_t msix_vect = adapter->irq_ctxt.rxq_base_idx_in_pf;
881 : 0 : uint16_t msix_cnt = adapter->irq_ctxt.rxq_avail_cnt;
882 : 0 : uint16_t rxq_cnt = dev->data->nb_rx_queues;
883 : 0 : uint16_t rxq_base = adapter->q_ctxt.base_idx_in_pf;
884 : 0 : int32_t ret = 0;
885 : :
886 [ # # ]: 0 : if (!rxq_cnt)
887 : 0 : goto l_end;
888 : :
889 : 0 : msix_cnt = RTE_MIN(msix_cnt, rxq_cnt);
890 : :
891 : 0 : ret = sxe2_rxq_map_msix_intr(dev, msix_vect, msix_cnt, rxq_base, rxq_cnt);
892 [ # # ]: 0 : if (ret) {
893 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to rxq[%d] map msix[%d] intr, cnt=%d, ret=%d",
894 : : rxq_base, msix_vect, rxq_cnt, ret);
895 : 0 : goto l_end;
896 : : }
897 : :
898 [ # # ]: 0 : if (dev->data->dev_conf.intr_conf.rxq) {
899 : 0 : ret = sxe2_rxq_intr_register(dev);
900 [ # # ]: 0 : if (ret) {
901 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to register rxq[%d] intr, ret=%d",
902 : : rxq_base, ret);
903 : 0 : goto l_err_unmap;
904 : : }
905 : : }
906 : :
907 : 0 : ret = sxe2_rxq_msix_cfg_map(dev);
908 [ # # ]: 0 : if (ret) {
909 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to rxq[%d] map msix[%d] intr, ret=%d",
910 : : rxq_base, msix_vect, ret);
911 : 0 : goto l_err_unregister;
912 : : }
913 : :
914 : 0 : goto l_end;
915 : 0 : l_err_unregister:
916 [ # # ]: 0 : if (dev->data->dev_conf.intr_conf.rxq)
917 : 0 : sxe2_rxq_intr_unregister(dev);
918 : 0 : l_err_unmap:
919 : 0 : sxe2_rxq_unmap_msix_intr(dev);
920 : 0 : l_end:
921 : 0 : return ret;
922 : : }
923 : :
924 : 0 : int32_t sxe2_repr_rxq_intr_enable(struct rte_eth_dev *dev)
925 : : {
926 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
927 : 0 : uint16_t rxq_cnt = dev->data->nb_rx_queues;
928 : 0 : int32_t ret = 0;
929 : 0 : uint16_t qid = adapter->repr_priv_data->repr_q_id;
930 : 0 : uint32_t val;
931 : :
932 [ # # ]: 0 : if (!rxq_cnt)
933 : 0 : goto l_end;
934 : :
935 : 0 : sxe2_pci_hw_irq_disable(adapter, qid);
936 : 0 : sxe2_pci_hw_int_itr_set(adapter, qid, SXE2_ITR_INTERVAL_NORMAL);
937 : 0 : ret = sxe2_drv_rxq_bind_irq(adapter, qid, qid);
938 [ # # ]: 0 : if (ret != 0) {
939 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "RXQ[%u] bind IRQ[%u] failed.",
940 : : qid, qid);
941 : 0 : goto l_end;
942 : : }
943 : 0 : sxe2_pci_hw_irq_enable(adapter, qid);
944 : :
945 : 0 : val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, qid);
946 [ # # ]: 0 : if ((val & SXE2VF_DYN_CTL_INTENABLE) == 0)
947 : 0 : goto l_end;
948 : :
949 : 0 : sxe2_pci_hw_msix_disable(adapter, qid);
950 : 0 : sxe2_pci_hw_irq_trigger(adapter, qid);
951 : 0 : val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, qid);
952 : 0 : sxe2_pci_hw_irq_clear_pba(adapter, qid);
953 : 0 : val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, qid);
954 : 0 : sxe2_pci_hw_msix_enable(adapter, qid);
955 : :
956 : 0 : l_end:
957 : 0 : return ret;
958 : : }
959 : :
960 : 0 : void sxe2_rxq_intr_disable(struct rte_eth_dev *dev)
961 : : {
962 : 0 : struct sxe2_adapter *adapter =
963 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
964 : 0 : struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
965 : :
966 [ # # ]: 0 : if (!irq_ctxt->rxq_irq_cnt)
967 : 0 : goto l_end;
968 : :
969 : 0 : sxe2_rxq_msix_cfg_unmap(dev);
970 : :
971 [ # # ]: 0 : if (dev->data->dev_conf.intr_conf.rxq)
972 : 0 : sxe2_rxq_intr_unregister(dev);
973 : :
974 : 0 : sxe2_rxq_unmap_msix_intr(dev);
975 : :
976 : 0 : l_end:
977 : 0 : return;
978 : : }
979 : :
980 : 0 : void sxe2_repr_rxq_intr_disable(struct rte_eth_dev *dev)
981 : : {
982 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
983 : 0 : uint16_t qid = adapter->repr_priv_data->repr_q_id;
984 : :
985 : 0 : sxe2_pci_hw_irq_disable(adapter, qid);
986 : 0 : (void)sxe2_drv_rxq_unbind_irq(adapter, qid);
987 : 0 : }
988 : :
989 : 0 : int32_t sxe2_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
990 : : {
991 : 0 : struct sxe2_adapter *adapter =
992 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
993 : 0 : struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
994 : 0 : uint64_t buf;
995 : 0 : uint16_t irq_idx = irq_ctxt->rxq_msix_idx[queue_id];
996 : 0 : size_t read_ret;
997 : :
998 : 0 : read_ret = read(irq_ctxt->rxq_event_fd[irq_idx], &buf, sizeof(buf));
999 : 0 : (void)read_ret;
1000 : 0 : sxe2_pci_hw_irq_enable(adapter, irq_idx);
1001 : 0 : return 0;
1002 : : }
1003 : :
1004 : 0 : int32_t sxe2_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
1005 : : {
1006 : 0 : struct sxe2_adapter *adapter =
1007 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
1008 : 0 : uint32_t val;
1009 : 0 : int32_t ret = 0;
1010 : 0 : uint16_t irq_idx = adapter->irq_ctxt.rxq_msix_idx[queue_id];
1011 : :
1012 : 0 : val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, irq_idx);
1013 [ # # ]: 0 : if ((val & SXE2VF_DYN_CTL_INTENABLE) == 0) {
1014 : 0 : PMD_DEV_LOG_DEBUG(adapter, INIT, "rxq [%d] interrupt is disabled.", queue_id);
1015 : 0 : goto l_end;
1016 : : }
1017 : :
1018 : 0 : sxe2_pci_hw_msix_disable(adapter, irq_idx);
1019 : 0 : sxe2_pci_hw_irq_trigger(adapter, irq_idx);
1020 : 0 : val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, irq_idx);
1021 : 0 : sxe2_pci_hw_irq_clear_pba(adapter, irq_idx);
1022 : 0 : val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, irq_idx);
1023 : 0 : sxe2_pci_hw_msix_enable(adapter, irq_idx);
1024 : 0 : l_end:
1025 : 0 : return ret;
1026 : : }
|