-/*-
- * Copyright (c) 2016 Solarflare Communications Inc.
- * All rights reserved.
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright(c) 2019-2020 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.
*/
/*
rte_spinlock_lock(&sa->mgmt_evq_lock);
- evq = sa->evq_info[sa->mgmt_evq_index].evq;
+ 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);
}
static void
-sfc_intr_line_handler(struct rte_intr_handle *intr_handle, void *cb_arg)
+sfc_intr_line_handler(void *cb_arg)
{
struct sfc_adapter *sa = (struct sfc_adapter *)cb_arg;
efx_nic_t *enp = sa->nic;
boolean_t fatal;
uint32_t qmask;
unsigned int lsc_seq = sa->port.lsc_seq;
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(sa->eth_dev);
sfc_log_init(sa, "entry");
if (qmask & (1 << sa->mgmt_evq_index))
sfc_intr_handle_mgmt_evq(sa);
- if (rte_intr_enable(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_EVENT_INTR_LSC,
+ NULL);
}
}
static void
-sfc_intr_message_handler(struct rte_intr_handle *intr_handle, void *cb_arg)
+sfc_intr_message_handler(void *cb_arg)
{
struct sfc_adapter *sa = (struct sfc_adapter *)cb_arg;
efx_nic_t *enp = sa->nic;
boolean_t fatal;
unsigned int lsc_seq = sa->port.lsc_seq;
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(sa->eth_dev);
sfc_log_init(sa, "entry");
sfc_intr_handle_mgmt_evq(sa);
- if (rte_intr_enable(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");
+ sfc_notice(sa, "link status change event");
_rte_eth_dev_callback_process(sa->eth_dev,
- RTE_ETH_EVENT_INTR_LSC, NULL);
+ RTE_ETH_EVENT_INTR_LSC,
+ NULL);
}
}
if (rc != 0)
goto fail_intr_init;
- pci_dev = SFC_DEV_TO_PCI(sa->eth_dev);
+ 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)) {
+ intr_handle->intr_vec =
+ rte_calloc("intr_vec",
+ sa->eth_dev->data->nb_rx_queues, sizeof(int),
+ 0);
+ if (intr_handle->intr_vec == NULL) {
+ 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);
rte_intr_callback_unregister(intr_handle, intr->handler, (void *)sa);
fail_rte_intr_cb_reg:
+ rte_free(intr_handle->intr_vec);
+
+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;
+
+ rte_free(intr_handle->intr_vec);
+ rte_intr_efd_disable(intr_handle);
+
if (rte_intr_disable(intr_handle) != 0)
sfc_err(sa, "cannot disable interrupts");
}
int
-sfc_intr_init(struct sfc_adapter *sa)
+sfc_intr_configure(struct sfc_adapter *sa)
{
struct sfc_intr *intr = &sa->intr;
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:
}
void
-sfc_intr_fini(struct sfc_adapter *sa)
+sfc_intr_close(struct sfc_adapter *sa)
{
sfc_log_init(sa, "entry");
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
+#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;