[v4,05/20] net/sfc: explicitly control IRQ used for Rx queues

Message ID 20210702083948.546667-6-andrew.rybchenko@oktetlabs.ru (mailing list archive)
State Accepted, archived
Delegated to: David Marchand
Headers
Series net/sfc: support flow API COUNT action |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Andrew Rybchenko July 2, 2021, 8:39 a.m. UTC
  Interrupts support has assumptions on interrupt numbers used
for LSC and Rx queues. The first interrupt is used for LSC,
subsequent interrupts are used for Rx queues.

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
---
 drivers/net/sfc/sfc_ev.c | 32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)
  

Patch

diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c
index 9a8149f052..71f706e403 100644
--- a/drivers/net/sfc/sfc_ev.c
+++ b/drivers/net/sfc/sfc_ev.c
@@ -648,6 +648,7 @@  sfc_ev_qstart(struct sfc_evq *evq, unsigned int hw_index)
 	struct sfc_adapter *sa = evq->sa;
 	efsys_mem_t *esmp;
 	uint32_t evq_flags = sa->evq_flags;
+	uint32_t irq = 0;
 	unsigned int total_delay_us;
 	unsigned int delay_us;
 	int rc;
@@ -662,20 +663,35 @@  sfc_ev_qstart(struct sfc_evq *evq, unsigned int hw_index)
 	(void)memset((void *)esmp->esm_base, 0xff,
 		     efx_evq_size(sa->nic, evq->entries, evq_flags));
 
-	if ((sa->intr.lsc_intr && hw_index == sa->mgmt_evq_index) ||
-	    (sa->intr.rxq_intr && evq->dp_rxq != NULL &&
-	     sfc_ethdev_rx_qid_by_rxq_sw_index(sfc_sa2shared(sa),
-		evq->dp_rxq->dpq.queue_id) != SFC_ETHDEV_QID_INVALID))
+	if (sa->intr.lsc_intr && hw_index == sa->mgmt_evq_index) {
 		evq_flags |= EFX_EVQ_FLAGS_NOTIFY_INTERRUPT;
-	else
+		irq = 0;
+	} else if (sa->intr.rxq_intr && evq->dp_rxq != NULL) {
+		sfc_ethdev_qid_t ethdev_qid;
+
+		ethdev_qid =
+			sfc_ethdev_rx_qid_by_rxq_sw_index(sfc_sa2shared(sa),
+				evq->dp_rxq->dpq.queue_id);
+		if (ethdev_qid != SFC_ETHDEV_QID_INVALID) {
+			evq_flags |= EFX_EVQ_FLAGS_NOTIFY_INTERRUPT;
+			/*
+			 * The first interrupt is used for management EvQ
+			 * (LSC etc). RxQ interrupts follow it.
+			 */
+			irq = 1 + ethdev_qid;
+		} else {
+			evq_flags |= EFX_EVQ_FLAGS_NOTIFY_DISABLED;
+		}
+	} else {
 		evq_flags |= EFX_EVQ_FLAGS_NOTIFY_DISABLED;
+	}
 
 	evq->init_state = SFC_EVQ_STARTING;
 
 	/* Create the common code event queue */
-	rc = efx_ev_qcreate(sa->nic, hw_index, esmp, evq->entries,
-			    0 /* unused on EF10 */, 0, evq_flags,
-			    &evq->common);
+	rc = efx_ev_qcreate_irq(sa->nic, hw_index, esmp, evq->entries,
+				0 /* unused on EF10 */, 0, evq_flags,
+				irq, &evq->common);
 	if (rc != 0)
 		goto fail_ev_qcreate;