-/*-
- * BSD LICENSE
+/* SPDX-License-Identifier: BSD-3-Clause
*
- * Copyright (c) 2016-2017 Solarflare Communications Inc.
- * All rights reserved.
+ * Copyright(c) 2019-2021 Xilinx, Inc.
+ * Copyright(c) 2016-2019 Solarflare Communications Inc.
*
* This software was jointly developed between OKTET Labs (under contract
* for Solarflare) and Solarflare Communications, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
- * At the momemt of writing DPDK v16.07 has notion of two types of
+ * At the moment of writing DPDK v16.07 has notion of two types of
* interrupts: LSC (link status change) and RXQ (receive indication).
* It allows to register interrupt callback for entire device which is
* not intended to be used for receive indication (i.e. link status
evq = sa->mgmt_evq;
- if (evq->init_state != SFC_EVQ_STARTED) {
- sfc_log_init(sa, "interrupt on stopped EVQ %u", evq->evq_index);
+ if (!sa->mgmt_evq_running) {
+ sfc_log_init(sa, "interrupt on not running management EVQ %u",
+ evq->evq_index);
} else {
sfc_ev_qpoll(evq);
boolean_t fatal;
uint32_t qmask;
unsigned int lsc_seq = sa->port.lsc_seq;
- struct rte_pci_device *pci_dev = SFC_DEV_TO_PCI(sa->eth_dev);
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(sa->eth_dev);
sfc_log_init(sa, "entry");
- if (sa->state != SFC_ADAPTER_STARTED &&
- sa->state != SFC_ADAPTER_STARTING &&
- sa->state != SFC_ADAPTER_STOPPING) {
+ if (sa->state != SFC_ETHDEV_STARTED &&
+ sa->state != SFC_ETHDEV_STARTING &&
+ sa->state != SFC_ETHDEV_STOPPING) {
sfc_log_init(sa,
"interrupt on stopped adapter, don't reenable");
goto exit;
if (qmask & (1 << sa->mgmt_evq_index))
sfc_intr_handle_mgmt_evq(sa);
- if (rte_intr_enable(&pci_dev->intr_handle) != 0)
+ if (rte_intr_ack(pci_dev->intr_handle) != 0)
sfc_err(sa, "cannot reenable interrupts");
sfc_log_init(sa, "done");
exit:
if (lsc_seq != sa->port.lsc_seq) {
- sfc_info(sa, "link status change event: link %s",
+ sfc_notice(sa, "link status change event: link %s",
sa->eth_dev->data->dev_link.link_status ?
"UP" : "DOWN");
- _rte_eth_dev_callback_process(sa->eth_dev,
- RTE_ETH_EVENT_INTR_LSC, NULL);
+ rte_eth_dev_callback_process(sa->eth_dev,
+ RTE_ETH_EVENT_INTR_LSC,
+ NULL);
}
}
efx_nic_t *enp = sa->nic;
boolean_t fatal;
unsigned int lsc_seq = sa->port.lsc_seq;
- struct rte_pci_device *pci_dev = SFC_DEV_TO_PCI(sa->eth_dev);
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(sa->eth_dev);
sfc_log_init(sa, "entry");
- if (sa->state != SFC_ADAPTER_STARTED &&
- sa->state != SFC_ADAPTER_STARTING &&
- sa->state != SFC_ADAPTER_STOPPING) {
+ if (sa->state != SFC_ETHDEV_STARTED &&
+ sa->state != SFC_ETHDEV_STARTING &&
+ sa->state != SFC_ETHDEV_STOPPING) {
sfc_log_init(sa, "adapter not-started, don't reenable");
goto exit;
}
sfc_intr_handle_mgmt_evq(sa);
- if (rte_intr_enable(&pci_dev->intr_handle) != 0)
+ if (rte_intr_ack(pci_dev->intr_handle) != 0)
sfc_err(sa, "cannot reenable interrupts");
sfc_log_init(sa, "done");
exit:
if (lsc_seq != sa->port.lsc_seq) {
- sfc_info(sa, "link status change event");
- _rte_eth_dev_callback_process(sa->eth_dev,
- RTE_ETH_EVENT_INTR_LSC, NULL);
+ sfc_notice(sa, "link status change event");
+ rte_eth_dev_callback_process(sa->eth_dev,
+ RTE_ETH_EVENT_INTR_LSC,
+ NULL);
}
}
if (rc != 0)
goto fail_intr_init;
- pci_dev = SFC_DEV_TO_PCI(sa->eth_dev);
- intr_handle = &pci_dev->intr_handle;
+ pci_dev = RTE_ETH_DEV_TO_PCI(sa->eth_dev);
+ intr_handle = pci_dev->intr_handle;
if (intr->handler != NULL) {
+ if (intr->rxq_intr && rte_intr_cap_multiple(intr_handle)) {
+ uint32_t intr_vector;
+
+ intr_vector = sa->eth_dev->data->nb_rx_queues;
+ rc = rte_intr_efd_enable(intr_handle, intr_vector);
+ if (rc != 0)
+ goto fail_rte_intr_efd_enable;
+ }
+ if (rte_intr_dp_is_en(intr_handle)) {
+ if (rte_intr_vec_list_alloc(intr_handle,
+ "intr_vec",
+ sa->eth_dev->data->nb_rx_queues)) {
+ sfc_err(sa,
+ "Failed to allocate %d rx_queues intr_vec",
+ sa->eth_dev->data->nb_rx_queues);
+ goto fail_intr_vector_alloc;
+ }
+
+ }
+
sfc_log_init(sa, "rte_intr_callback_register");
rc = rte_intr_callback_register(intr_handle, intr->handler,
(void *)sa);
efx_intr_enable(sa->nic);
}
- sfc_log_init(sa, "done type=%u max_intr=%d nb_efd=%u vec=%p",
- intr_handle->type, intr_handle->max_intr,
- intr_handle->nb_efd, intr_handle->intr_vec);
+ sfc_log_init(sa, "done type=%u max_intr=%d nb_efd=%u",
+ rte_intr_type_get(intr_handle),
+ rte_intr_max_intr_get(intr_handle),
+ rte_intr_nb_efd_get(intr_handle));
return 0;
fail_rte_intr_enable:
rte_intr_callback_unregister(intr_handle, intr->handler, (void *)sa);
fail_rte_intr_cb_reg:
+ rte_intr_vec_list_free(intr_handle);
+
+fail_intr_vector_alloc:
+ rte_intr_efd_disable(intr_handle);
+
+fail_rte_intr_efd_enable:
efx_intr_fini(sa->nic);
fail_intr_init:
sfc_intr_stop(struct sfc_adapter *sa)
{
struct sfc_intr *intr = &sa->intr;
- struct rte_pci_device *pci_dev = SFC_DEV_TO_PCI(sa->eth_dev);
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(sa->eth_dev);
sfc_log_init(sa, "entry");
efx_intr_disable(sa->nic);
- intr_handle = &pci_dev->intr_handle;
+ intr_handle = pci_dev->intr_handle;
+
+ rte_intr_vec_list_free(intr_handle);
+ rte_intr_efd_disable(intr_handle);
+
if (rte_intr_disable(intr_handle) != 0)
sfc_err(sa, "cannot disable interrupts");
intr->handler = NULL;
intr->lsc_intr = (sa->eth_dev->data->dev_conf.intr_conf.lsc != 0);
- if (!intr->lsc_intr) {
- sfc_info(sa, "LSC tracking using interrupts is disabled");
+ intr->rxq_intr = (sa->eth_dev->data->dev_conf.intr_conf.rxq != 0);
+
+ if (!intr->lsc_intr && !intr->rxq_intr)
goto done;
- }
switch (intr->type) {
case EFX_INTR_MESSAGE:
sfc_intr_attach(struct sfc_adapter *sa)
{
struct sfc_intr *intr = &sa->intr;
- struct rte_pci_device *pci_dev = SFC_DEV_TO_PCI(sa->eth_dev);
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(sa->eth_dev);
sfc_log_init(sa, "entry");
- switch (pci_dev->intr_handle.type) {
-#ifdef RTE_EXEC_ENV_LINUXAPP
+ switch (rte_intr_type_get(pci_dev->intr_handle)) {
+#ifdef RTE_EXEC_ENV_LINUX
+ case RTE_INTR_HANDLE_UIO_INTX:
case RTE_INTR_HANDLE_VFIO_LEGACY:
intr->type = EFX_INTR_LINE;
break;
+ case RTE_INTR_HANDLE_UIO:
case RTE_INTR_HANDLE_VFIO_MSI:
case RTE_INTR_HANDLE_VFIO_MSIX:
intr->type = EFX_INTR_MESSAGE;