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