From aa6dc1017cd3fa7b722ca877558e871f82eb1f02 Mon Sep 17 00:00:00 2001 From: Andrew Rybchenko Date: Fri, 2 Jul 2021 11:39:32 +0300 Subject: [PATCH] common/sfc_efx/base: support custom EvQ to IRQ mapping Custom mapping is actually supported for EF10 and EF100 families only. A driver (e.g. DPDK PMD) may require to customize mapping of EvQ to interrupts if, for example, extra EvQ are used for house-keeping in polling or wake up (via another EvQ) mode. Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/common/sfc_efx/base/ef10_ev.c | 4 +-- drivers/common/sfc_efx/base/ef10_impl.h | 1 + drivers/common/sfc_efx/base/efx.h | 13 ++++++++ drivers/common/sfc_efx/base/efx_ev.c | 39 ++++++++++++++++++++---- drivers/common/sfc_efx/base/efx_impl.h | 3 +- drivers/common/sfc_efx/base/rhead_ev.c | 4 +-- drivers/common/sfc_efx/base/rhead_impl.h | 1 + drivers/common/sfc_efx/version.map | 1 + 8 files changed, 55 insertions(+), 11 deletions(-) diff --git a/drivers/common/sfc_efx/base/ef10_ev.c b/drivers/common/sfc_efx/base/ef10_ev.c index c0cbc427b9..ba078940b6 100644 --- a/drivers/common/sfc_efx/base/ef10_ev.c +++ b/drivers/common/sfc_efx/base/ef10_ev.c @@ -118,10 +118,10 @@ ef10_ev_qcreate( __in uint32_t id, __in uint32_t us, __in uint32_t flags, + __in uint32_t irq, __in efx_evq_t *eep) { efx_nic_cfg_t *encp = &(enp->en_nic_cfg); - uint32_t irq = 0; uint32_t target_evq = 0; efx_rc_t rc; boolean_t low_latency; @@ -158,7 +158,7 @@ ef10_ev_qcreate( /* INIT_EVQ expects function-relative vector number */ if ((flags & EFX_EVQ_FLAGS_NOTIFY_MASK) == EFX_EVQ_FLAGS_NOTIFY_INTERRUPT) { - irq = index; + /* IRQ number is specified by caller */ } else if (index == EFX_EF10_ALWAYS_INTERRUPTING_EVQ_INDEX) { /* Use the first interrupt for always interrupting EvQ */ irq = 0; diff --git a/drivers/common/sfc_efx/base/ef10_impl.h b/drivers/common/sfc_efx/base/ef10_impl.h index 40210fbd91..7c8d51b7a5 100644 --- a/drivers/common/sfc_efx/base/ef10_impl.h +++ b/drivers/common/sfc_efx/base/ef10_impl.h @@ -111,6 +111,7 @@ ef10_ev_qcreate( __in uint32_t id, __in uint32_t us, __in uint32_t flags, + __in uint32_t irq, __in efx_evq_t *eep); LIBEFX_INTERNAL diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index 8e13075b07..6a99099ad2 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -2333,6 +2333,19 @@ efx_ev_qcreate( __in uint32_t flags, __deref_out efx_evq_t **eepp); +LIBEFX_API +extern __checkReturn efx_rc_t +efx_ev_qcreate_irq( + __in efx_nic_t *enp, + __in unsigned int index, + __in efsys_mem_t *esmp, + __in size_t ndescs, + __in uint32_t id, + __in uint32_t us, + __in uint32_t flags, + __in uint32_t irq, + __deref_out efx_evq_t **eepp); + LIBEFX_API extern void efx_ev_qpost( diff --git a/drivers/common/sfc_efx/base/efx_ev.c b/drivers/common/sfc_efx/base/efx_ev.c index 19bdea03fd..4808f8ddfc 100644 --- a/drivers/common/sfc_efx/base/efx_ev.c +++ b/drivers/common/sfc_efx/base/efx_ev.c @@ -35,6 +35,7 @@ siena_ev_qcreate( __in uint32_t id, __in uint32_t us, __in uint32_t flags, + __in uint32_t irq, __in efx_evq_t *eep); static void @@ -253,7 +254,7 @@ efx_ev_fini( __checkReturn efx_rc_t -efx_ev_qcreate( +efx_ev_qcreate_irq( __in efx_nic_t *enp, __in unsigned int index, __in efsys_mem_t *esmp, @@ -261,6 +262,7 @@ efx_ev_qcreate( __in uint32_t id, __in uint32_t us, __in uint32_t flags, + __in uint32_t irq, __deref_out efx_evq_t **eepp) { const efx_ev_ops_t *eevop = enp->en_eevop; @@ -347,7 +349,7 @@ efx_ev_qcreate( *eepp = eep; if ((rc = eevop->eevo_qcreate(enp, index, esmp, ndescs, id, us, flags, - eep)) != 0) + irq, eep)) != 0) goto fail9; return (0); @@ -377,6 +379,23 @@ fail1: return (rc); } + __checkReturn efx_rc_t +efx_ev_qcreate( + __in efx_nic_t *enp, + __in unsigned int index, + __in efsys_mem_t *esmp, + __in size_t ndescs, + __in uint32_t id, + __in uint32_t us, + __in uint32_t flags, + __deref_out efx_evq_t **eepp) +{ + uint32_t irq = index; + + return (efx_ev_qcreate_irq(enp, index, esmp, ndescs, id, us, flags, + irq, eepp)); +} + void efx_ev_qdestroy( __in efx_evq_t *eep) @@ -1278,6 +1297,7 @@ siena_ev_qcreate( __in uint32_t id, __in uint32_t us, __in uint32_t flags, + __in uint32_t irq, __in efx_evq_t *eep) { efx_nic_cfg_t *encp = &(enp->en_nic_cfg); @@ -1290,11 +1310,16 @@ siena_ev_qcreate( EFSYS_ASSERT((flags & EFX_EVQ_FLAGS_EXTENDED_WIDTH) == 0); + if (irq != index) { + rc = EINVAL; + goto fail1; + } + #if EFSYS_OPT_RX_SCALE if (enp->en_intr.ei_type == EFX_INTR_LINE && index >= EFX_MAXRSS_LEGACY) { rc = EINVAL; - goto fail1; + goto fail2; } #endif for (size = 0; @@ -1304,7 +1329,7 @@ siena_ev_qcreate( break; if (id + (1 << size) >= encp->enc_buftbl_limit) { rc = EINVAL; - goto fail2; + goto fail3; } /* Set up the handler table */ @@ -1336,11 +1361,13 @@ siena_ev_qcreate( return (0); +fail3: + EFSYS_PROBE(fail3); +#if EFSYS_OPT_RX_SCALE fail2: EFSYS_PROBE(fail2); -#if EFSYS_OPT_RX_SCALE -fail1: #endif +fail1: EFSYS_PROBE1(fail1, efx_rc_t, rc); return (rc); diff --git a/drivers/common/sfc_efx/base/efx_impl.h b/drivers/common/sfc_efx/base/efx_impl.h index 4fff9e1842..f891e2616e 100644 --- a/drivers/common/sfc_efx/base/efx_impl.h +++ b/drivers/common/sfc_efx/base/efx_impl.h @@ -87,7 +87,8 @@ typedef struct efx_ev_ops_s { void (*eevo_fini)(efx_nic_t *); efx_rc_t (*eevo_qcreate)(efx_nic_t *, unsigned int, efsys_mem_t *, size_t, uint32_t, - uint32_t, uint32_t, efx_evq_t *); + uint32_t, uint32_t, uint32_t, + efx_evq_t *); void (*eevo_qdestroy)(efx_evq_t *); efx_rc_t (*eevo_qprime)(efx_evq_t *, unsigned int); void (*eevo_qpost)(efx_evq_t *, uint16_t); diff --git a/drivers/common/sfc_efx/base/rhead_ev.c b/drivers/common/sfc_efx/base/rhead_ev.c index 533cd9e34a..3eaed9e94b 100644 --- a/drivers/common/sfc_efx/base/rhead_ev.c +++ b/drivers/common/sfc_efx/base/rhead_ev.c @@ -102,11 +102,11 @@ rhead_ev_qcreate( __in uint32_t id, __in uint32_t us, __in uint32_t flags, + __in uint32_t irq, __in efx_evq_t *eep) { const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp); size_t desc_size; - uint32_t irq = 0; uint32_t target_evq = 0; efx_rc_t rc; @@ -141,7 +141,7 @@ rhead_ev_qcreate( /* INIT_EVQ expects function-relative vector number */ if ((flags & EFX_EVQ_FLAGS_NOTIFY_MASK) == EFX_EVQ_FLAGS_NOTIFY_INTERRUPT) { - irq = index; + /* IRQ number is specified by caller */ } else if (index == EFX_RHEAD_ALWAYS_INTERRUPTING_EVQ_INDEX) { /* Use the first interrupt for always interrupting EvQ */ irq = 0; diff --git a/drivers/common/sfc_efx/base/rhead_impl.h b/drivers/common/sfc_efx/base/rhead_impl.h index 3bf9beceb0..dd38ded775 100644 --- a/drivers/common/sfc_efx/base/rhead_impl.h +++ b/drivers/common/sfc_efx/base/rhead_impl.h @@ -131,6 +131,7 @@ rhead_ev_qcreate( __in uint32_t id, __in uint32_t us, __in uint32_t flags, + __in uint32_t irq, __in efx_evq_t *eep); LIBEFX_INTERNAL diff --git a/drivers/common/sfc_efx/version.map b/drivers/common/sfc_efx/version.map index 75da5aa5c2..ae85ed18c6 100644 --- a/drivers/common/sfc_efx/version.map +++ b/drivers/common/sfc_efx/version.map @@ -7,6 +7,7 @@ INTERNAL { efx_ev_init; efx_ev_qcreate; efx_ev_qcreate_check_init_done; + efx_ev_qcreate_irq; efx_ev_qdestroy; efx_ev_qmoderate; efx_ev_qpending; -- 2.20.1