LCOV - code coverage report
Current view: top level - drivers/net/sxe2 - sxe2_irq.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 642 0.0 %
Date: 2026-10-01 18:19:24 Functions: 0 33 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 186 0.0 %

           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], &notify_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], &notify_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                 :            : }

Generated by: LCOV version 1.14