diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index e77639e..5fd734e 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -139,7 +139,6 @@ struct sfc_intr {
 	boolean_t			lsc_intr;
 };
 
-struct sfc_evq_info;
 struct sfc_rxq_info;
 struct sfc_txq_info;
 struct sfc_dp_rx;
@@ -204,10 +203,10 @@ struct sfc_adapter {
 
 	uint32_t			evq_flags;
 	unsigned int			evq_count;
-	struct sfc_evq_info		*evq_info;
 
 	unsigned int			mgmt_evq_index;
 	rte_spinlock_t			mgmt_evq_lock;
+	struct sfc_evq			*mgmt_evq;
 
 	unsigned int			rxq_count;
 	struct sfc_rxq_info		*rxq_info;
diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c
index bf108f1..b007af8 100644
--- a/drivers/net/sfc/sfc_ev.c
+++ b/drivers/net/sfc/sfc_ev.c
@@ -566,7 +566,7 @@ void
 sfc_ev_mgmt_qpoll(struct sfc_adapter *sa)
 {
 	if (rte_spinlock_trylock(&sa->mgmt_evq_lock)) {
-		struct sfc_evq *mgmt_evq = sa->evq_info[sa->mgmt_evq_index].evq;
+		struct sfc_evq *mgmt_evq = sa->mgmt_evq;
 
 		if (mgmt_evq->init_state == SFC_EVQ_STARTED)
 			sfc_ev_qpoll(mgmt_evq);
@@ -582,33 +582,33 @@ sfc_ev_qprime(struct sfc_evq *evq)
 	return efx_ev_qprime(evq->common, evq->read_ptr);
 }
 
+/* Event queue HW index allocation scheme is described in sfc_ev.h. */
 int
-sfc_ev_qstart(struct sfc_adapter *sa, unsigned int sw_index)
+sfc_ev_qstart(struct sfc_evq *evq, unsigned int hw_index)
 {
-	const struct sfc_evq_info *evq_info;
-	struct sfc_evq *evq;
+	struct sfc_adapter *sa = evq->sa;
 	efsys_mem_t *esmp;
 	uint32_t evq_flags = sa->evq_flags;
 	unsigned int total_delay_us;
 	unsigned int delay_us;
 	int rc;
 
-	sfc_log_init(sa, "sw_index=%u", sw_index);
+	sfc_log_init(sa, "hw_index=%u", hw_index);
 
-	evq_info = &sa->evq_info[sw_index];
-	evq = evq_info->evq;
 	esmp = &evq->mem;
 
+	evq->evq_index = hw_index;
+
 	/* Clear all events */
 	(void)memset((void *)esmp->esm_base, 0xff, EFX_EVQ_SIZE(evq->entries));
 
-	if (sa->intr.lsc_intr && sw_index == sa->mgmt_evq_index)
+	if (sa->intr.lsc_intr && hw_index == sa->mgmt_evq_index)
 		evq_flags |= EFX_EVQ_FLAGS_NOTIFY_INTERRUPT;
 	else
 		evq_flags |= EFX_EVQ_FLAGS_NOTIFY_DISABLED;
 
 	/* Create the common code event queue */
-	rc = efx_ev_qcreate(sa->nic, sw_index, esmp, evq->entries,
+	rc = efx_ev_qcreate(sa->nic, hw_index, esmp, evq->entries,
 			    0 /* unused on EF10 */, 0, evq_flags,
 			    &evq->common);
 	if (rc != 0)
@@ -671,17 +671,11 @@ sfc_ev_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 }
 
 void
-sfc_ev_qstop(struct sfc_adapter *sa, unsigned int sw_index)
+sfc_ev_qstop(struct sfc_evq *evq)
 {
-	const struct sfc_evq_info *evq_info;
-	struct sfc_evq *evq;
-
-	sfc_log_init(sa, "sw_index=%u", sw_index);
-
-	SFC_ASSERT(sw_index < sa->evq_count);
+	struct sfc_adapter *sa = evq->sa;
 
-	evq_info = &sa->evq_info[sw_index];
-	evq = evq_info->evq;
+	sfc_log_init(sa, "hw_index=%u", evq->evq_index);
 
 	if (evq == NULL || evq->init_state != SFC_EVQ_STARTED)
 		return;
@@ -692,6 +686,8 @@ sfc_ev_qstop(struct sfc_adapter *sa, unsigned int sw_index)
 	evq->exception = B_FALSE;
 
 	efx_ev_qdestroy(evq->common);
+
+	evq->evq_index = 0;
 }
 
 static void
@@ -740,12 +736,12 @@ sfc_ev_start(struct sfc_adapter *sa)
 	/* Start management EVQ used for global events */
 	rte_spinlock_lock(&sa->mgmt_evq_lock);
 
-	rc = sfc_ev_qstart(sa, sa->mgmt_evq_index);
+	rc = sfc_ev_qstart(sa->mgmt_evq, sa->mgmt_evq_index);
 	if (rc != 0)
 		goto fail_mgmt_evq_start;
 
 	if (sa->intr.lsc_intr) {
-		rc = sfc_ev_qprime(sa->evq_info[sa->mgmt_evq_index].evq);
+		rc = sfc_ev_qprime(sa->mgmt_evq);
 		if (rc != 0)
 			goto fail_evq0_prime;
 	}
@@ -768,7 +764,7 @@ sfc_ev_start(struct sfc_adapter *sa)
 	return 0;
 
 fail_evq0_prime:
-	sfc_ev_qstop(sa, 0);
+	sfc_ev_qstop(sa->mgmt_evq);
 
 fail_mgmt_evq_start:
 	rte_spinlock_unlock(&sa->mgmt_evq_lock);
@@ -782,41 +778,27 @@ sfc_ev_start(struct sfc_adapter *sa)
 void
 sfc_ev_stop(struct sfc_adapter *sa)
 {
-	unsigned int sw_index;
-
 	sfc_log_init(sa, "entry");
 
 	sfc_ev_mgmt_periodic_qpoll_stop(sa);
 
-	/* Make sure that all event queues are stopped */
-	sw_index = sa->evq_count;
-	while (sw_index-- > 0) {
-		if (sw_index == sa->mgmt_evq_index) {
-			/* Locks are required for the management EVQ */
-			rte_spinlock_lock(&sa->mgmt_evq_lock);
-			sfc_ev_qstop(sa, sa->mgmt_evq_index);
-			rte_spinlock_unlock(&sa->mgmt_evq_lock);
-		} else {
-			sfc_ev_qstop(sa, sw_index);
-		}
-	}
+	rte_spinlock_lock(&sa->mgmt_evq_lock);
+	sfc_ev_qstop(sa->mgmt_evq);
+	rte_spinlock_unlock(&sa->mgmt_evq_lock);
 
 	efx_ev_fini(sa->nic);
 }
 
 int
-sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index,
+sfc_ev_qinit(struct sfc_adapter *sa,
 	     enum sfc_evq_type type, unsigned int type_index,
-	     unsigned int entries, int socket_id)
+	     unsigned int entries, int socket_id, struct sfc_evq **evqp)
 {
-	struct sfc_evq_info *evq_info;
 	struct sfc_evq *evq;
 	int rc;
 
-	sfc_log_init(sa, "sw_index=%u type=%s type_index=%u",
-		     sw_index, sfc_evq_type2str(type), type_index);
-
-	evq_info = &sa->evq_info[sw_index];
+	sfc_log_init(sa, "type=%s type_index=%u",
+		     sfc_evq_type2str(type), type_index);
 
 	SFC_ASSERT(rte_is_power_of_2(entries));
 
@@ -827,7 +809,6 @@ sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		goto fail_evq_alloc;
 
 	evq->sa = sa;
-	evq->evq_index = sw_index;
 	evq->type = type;
 	evq->entries = entries;
 
@@ -839,7 +820,9 @@ sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 
 	evq->init_state = SFC_EVQ_INITIALIZED;
 
-	evq_info->evq = evq;
+	sa->evq_count++;
+
+	*evqp = evq;
 
 	return 0;
 
@@ -853,29 +836,18 @@ sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 }
 
 void
-sfc_ev_qfini(struct sfc_adapter *sa, unsigned int sw_index)
+sfc_ev_qfini(struct sfc_evq *evq)
 {
-	struct sfc_evq *evq;
-
-	sfc_log_init(sa, "sw_index=%u", sw_index);
-
-	evq = sa->evq_info[sw_index].evq;
+	struct sfc_adapter *sa = evq->sa;
 
 	SFC_ASSERT(evq->init_state == SFC_EVQ_INITIALIZED);
 
-	sa->evq_info[sw_index].evq = NULL;
-
 	sfc_dma_free(sa, &evq->mem);
 
 	rte_free(evq);
-}
-
-static int
-sfc_ev_qinit_info(struct sfc_adapter *sa, unsigned int sw_index)
-{
-	sfc_log_init(sa, "sw_index=%u", sw_index);
 
-	return 0;
+	SFC_ASSERT(sa->evq_count > 0);
+	sa->evq_count--;
 }
 
 static int
@@ -896,19 +868,10 @@ sfc_kvarg_perf_profile_handler(__rte_unused const char *key,
 	return 0;
 }
 
-static void
-sfc_ev_qfini_info(struct sfc_adapter *sa, unsigned int sw_index)
-{
-	sfc_log_init(sa, "sw_index=%u", sw_index);
-
-	/* Nothing to cleanup */
-}
-
 int
 sfc_ev_init(struct sfc_adapter *sa)
 {
 	int rc;
-	unsigned int sw_index;
 
 	sfc_log_init(sa, "entry");
 
@@ -922,26 +885,11 @@ sfc_ev_init(struct sfc_adapter *sa)
 		goto fail_kvarg_perf_profile;
 	}
 
-	sa->evq_count = sfc_ev_qcount(sa);
 	sa->mgmt_evq_index = 0;
 	rte_spinlock_init(&sa->mgmt_evq_lock);
 
-	/* Allocate EVQ info array */
-	rc = ENOMEM;
-	sa->evq_info = rte_calloc_socket("sfc-evqs", sa->evq_count,
-					 sizeof(struct sfc_evq_info), 0,
-					 sa->socket_id);
-	if (sa->evq_info == NULL)
-		goto fail_evqs_alloc;
-
-	for (sw_index = 0; sw_index < sa->evq_count; ++sw_index) {
-		rc = sfc_ev_qinit_info(sa, sw_index);
-		if (rc != 0)
-			goto fail_ev_qinit_info;
-	}
-
-	rc = sfc_ev_qinit(sa, sa->mgmt_evq_index, SFC_EVQ_TYPE_MGMT, 0,
-			  SFC_MGMT_EVQ_ENTRIES, sa->socket_id);
+	rc = sfc_ev_qinit(sa, SFC_EVQ_TYPE_MGMT, 0, SFC_MGMT_EVQ_ENTRIES,
+			  sa->socket_id, &sa->mgmt_evq);
 	if (rc != 0)
 		goto fail_mgmt_evq_init;
 
@@ -953,15 +901,6 @@ sfc_ev_init(struct sfc_adapter *sa)
 	return 0;
 
 fail_mgmt_evq_init:
-fail_ev_qinit_info:
-	while (sw_index-- > 0)
-		sfc_ev_qfini_info(sa, sw_index);
-
-	rte_free(sa->evq_info);
-	sa->evq_info = NULL;
-
-fail_evqs_alloc:
-	sa->evq_count = 0;
 
 fail_kvarg_perf_profile:
 	sfc_log_init(sa, "failed %d", rc);
@@ -971,19 +910,11 @@ sfc_ev_init(struct sfc_adapter *sa)
 void
 sfc_ev_fini(struct sfc_adapter *sa)
 {
-	int sw_index;
-
 	sfc_log_init(sa, "entry");
 
-	/* Cleanup all event queues */
-	sw_index = sa->evq_count;
-	while (--sw_index >= 0) {
-		if (sa->evq_info[sw_index].evq != NULL)
-			sfc_ev_qfini(sa, sw_index);
-		sfc_ev_qfini_info(sa, sw_index);
-	}
+	sfc_ev_qfini(sa->mgmt_evq);
 
-	rte_free(sa->evq_info);
-	sa->evq_info = NULL;
-	sa->evq_count = 0;
+	if (sa->evq_count != 0)
+		sfc_err(sa, "%u EvQs are not destroyed before detach",
+			sa->evq_count);
 }
diff --git a/drivers/net/sfc/sfc_ev.h b/drivers/net/sfc/sfc_ev.h
index bc96213..f73201b 100644
--- a/drivers/net/sfc/sfc_ev.h
+++ b/drivers/net/sfc/sfc_ev.h
@@ -84,29 +84,16 @@ struct sfc_evq {
 	unsigned int			entries;
 };
 
-struct sfc_evq_info {
-	/* NUMA-aware EVQ data structure used on datapath */
-	struct sfc_evq		*evq;
-};
-
 /*
  * Functions below define event queue to transmit/receive queue and vice
  * versa mapping.
+ * Own event queue is allocated for management, each Rx and each Tx queue.
+ * Zero event queue is used for management events.
+ * Rx event queues from 1 to RxQ number follow management event queue.
+ * Tx event queues follow Rx event queues.
  */
 
 static inline unsigned int
-sfc_ev_qcount(struct sfc_adapter *sa)
-{
-	const struct rte_eth_dev_data *dev_data = sa->eth_dev->data;
-
-	/*
-	 * One management EVQ for global events.
-	 * Own EVQ for each Tx and Rx queue.
-	 */
-	return 1 + dev_data->nb_rx_queues + dev_data->nb_tx_queues;
-}
-
-static inline unsigned int
 sfc_evq_index_by_rxq_sw_index(__rte_unused struct sfc_adapter *sa,
 			      unsigned int rxq_sw_index)
 {
@@ -124,12 +111,12 @@ void sfc_ev_fini(struct sfc_adapter *sa);
 int sfc_ev_start(struct sfc_adapter *sa);
 void sfc_ev_stop(struct sfc_adapter *sa);
 
-int sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index,
+int sfc_ev_qinit(struct sfc_adapter *sa,
 		 enum sfc_evq_type type, unsigned int type_index,
-		 unsigned int entries, int socket_id);
-void sfc_ev_qfini(struct sfc_adapter *sa, unsigned int sw_index);
-int sfc_ev_qstart(struct sfc_adapter *sa, unsigned int sw_index);
-void sfc_ev_qstop(struct sfc_adapter *sa, unsigned int sw_index);
+		 unsigned int entries, int socket_id, struct sfc_evq **evqp);
+void sfc_ev_qfini(struct sfc_evq *evq);
+int sfc_ev_qstart(struct sfc_evq *evq, unsigned int hw_index);
+void sfc_ev_qstop(struct sfc_evq *evq);
 
 int sfc_ev_qprime(struct sfc_evq *evq);
 void sfc_ev_qpoll(struct sfc_evq *evq);
diff --git a/drivers/net/sfc/sfc_intr.c b/drivers/net/sfc/sfc_intr.c
index 0d199b4..448709c 100644
--- a/drivers/net/sfc/sfc_intr.c
+++ b/drivers/net/sfc/sfc_intr.c
@@ -55,7 +55,7 @@ sfc_intr_handle_mgmt_evq(struct sfc_adapter *sa)
 
 	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);
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 8c929f8..9ca5eeb 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -643,7 +643,7 @@ sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 
 	evq = rxq->evq;
 
-	rc = sfc_ev_qstart(sa, evq->evq_index);
+	rc = sfc_ev_qstart(evq, sfc_evq_index_by_rxq_sw_index(sa, sw_index));
 	if (rc != 0)
 		goto fail_ev_qstart;
 
@@ -681,7 +681,7 @@ sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 	sfc_rx_qflush(sa, sw_index);
 
 fail_rx_qcreate:
-	sfc_ev_qstop(sa, evq->evq_index);
+	sfc_ev_qstop(evq);
 
 fail_ev_qstart:
 	return rc;
@@ -719,7 +719,7 @@ sfc_rx_qstop(struct sfc_adapter *sa, unsigned int sw_index)
 
 	efx_rx_qdestroy(rxq->common);
 
-	sfc_ev_qstop(sa, rxq->evq->evq_index);
+	sfc_ev_qstop(rxq->evq);
 }
 
 static int
@@ -862,7 +862,6 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	int rc;
 	uint16_t buf_size;
 	struct sfc_rxq_info *rxq_info;
-	unsigned int evq_index;
 	struct sfc_evq *evq;
 	struct sfc_rxq *rxq;
 	struct sfc_dp_rx_qcreate_info info;
@@ -900,15 +899,11 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		sa->eth_dev->data->dev_conf.rxmode.enable_scatter ?
 		EFX_RXQ_TYPE_SCATTER : EFX_RXQ_TYPE_DEFAULT;
 
-	evq_index = sfc_evq_index_by_rxq_sw_index(sa, sw_index);
-
-	rc = sfc_ev_qinit(sa, evq_index, SFC_EVQ_TYPE_RX, sw_index,
-			  rxq_info->entries, socket_id);
+	rc = sfc_ev_qinit(sa, SFC_EVQ_TYPE_RX, sw_index,
+			  rxq_info->entries, socket_id, &evq);
 	if (rc != 0)
 		goto fail_ev_qinit;
 
-	evq = sa->evq_info[evq_index].evq;
-
 	rc = ENOMEM;
 	rxq = rte_zmalloc_socket("sfc-rxq", sizeof(*rxq), RTE_CACHE_LINE_SIZE,
 				 socket_id);
@@ -969,7 +964,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	rte_free(rxq);
 
 fail_rxq_alloc:
-	sfc_ev_qfini(sa, evq_index);
+	sfc_ev_qfini(evq);
 
 fail_ev_qinit:
 	rxq_info->entries = 0;
@@ -999,9 +994,11 @@ sfc_rx_qfini(struct sfc_adapter *sa, unsigned int sw_index)
 	rxq_info->entries = 0;
 
 	sfc_dma_free(sa, &rxq->mem);
-	rte_free(rxq);
 
-	sfc_ev_qfini(sa, sfc_evq_index_by_rxq_sw_index(sa, sw_index));
+	sfc_ev_qfini(rxq->evq);
+	rxq->evq = NULL;
+
+	rte_free(rxq);
 }
 
 #if EFSYS_OPT_RX_SCALE
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 2c45e1a..9597029 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -134,7 +134,6 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	struct sfc_txq_info *txq_info;
 	struct sfc_evq *evq;
 	struct sfc_txq *txq;
-	unsigned int evq_index = sfc_evq_index_by_txq_sw_index(sa, sw_index);
 	int rc = 0;
 	struct sfc_dp_tx_qcreate_info info;
 
@@ -150,13 +149,11 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	SFC_ASSERT(nb_tx_desc <= sa->txq_max_entries);
 	txq_info->entries = nb_tx_desc;
 
-	rc = sfc_ev_qinit(sa, evq_index, SFC_EVQ_TYPE_TX, sw_index,
-			  txq_info->entries, socket_id);
+	rc = sfc_ev_qinit(sa, SFC_EVQ_TYPE_TX, sw_index,
+			  txq_info->entries, socket_id, &evq);
 	if (rc != 0)
 		goto fail_ev_qinit;
 
-	evq = sa->evq_info[evq_index].evq;
-
 	rc = ENOMEM;
 	txq = rte_zmalloc_socket("sfc-txq", sizeof(*txq), 0, socket_id);
 	if (txq == NULL)
@@ -209,7 +206,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	rte_free(txq);
 
 fail_txq_alloc:
-	sfc_ev_qfini(sa, evq_index);
+	sfc_ev_qfini(evq);
 
 fail_ev_qinit:
 	txq_info->entries = 0;
@@ -241,9 +238,11 @@ sfc_tx_qfini(struct sfc_adapter *sa, unsigned int sw_index)
 	txq_info->entries = 0;
 
 	sfc_dma_free(sa, &txq->mem);
-	rte_free(txq);
 
-	sfc_ev_qfini(sa, sfc_evq_index_by_txq_sw_index(sa, sw_index));
+	sfc_ev_qfini(txq->evq);
+	txq->evq = NULL;
+
+	rte_free(txq);
 }
 
 static int
@@ -379,7 +378,7 @@ sfc_tx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 
 	evq = txq->evq;
 
-	rc = sfc_ev_qstart(sa, evq->evq_index);
+	rc = sfc_ev_qstart(evq, sfc_evq_index_by_txq_sw_index(sa, sw_index));
 	if (rc != 0)
 		goto fail_ev_qstart;
 
@@ -429,7 +428,7 @@ sfc_tx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 	efx_tx_qdestroy(txq->common);
 
 fail_tx_qcreate:
-	sfc_ev_qstop(sa, evq->evq_index);
+	sfc_ev_qstop(evq);
 
 fail_ev_qstart:
 	return rc;
@@ -497,7 +496,7 @@ sfc_tx_qstop(struct sfc_adapter *sa, unsigned int sw_index)
 
 	efx_tx_qdestroy(txq->common);
 
-	sfc_ev_qstop(sa, txq->evq->evq_index);
+	sfc_ev_qstop(txq->evq);
 
 	/*
 	 * It seems to be used by DPDK for debug purposes only ('rte_ether')
