common/sfc_efx/base: support custom EvQ to IRQ mapping
authorAndrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Fri, 2 Jul 2021 08:39:32 +0000 (11:39 +0300)
committerDavid Marchand <david.marchand@redhat.com>
Tue, 20 Jul 2021 10:20:31 +0000 (12:20 +0200)
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 <andrew.rybchenko@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
drivers/common/sfc_efx/base/ef10_ev.c
drivers/common/sfc_efx/base/ef10_impl.h
drivers/common/sfc_efx/base/efx.h
drivers/common/sfc_efx/base/efx_ev.c
drivers/common/sfc_efx/base/efx_impl.h
drivers/common/sfc_efx/base/rhead_ev.c
drivers/common/sfc_efx/base/rhead_impl.h
drivers/common/sfc_efx/version.map

index c0cbc42..ba07894 100644 (file)
@@ -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;
index 40210fb..7c8d51b 100644 (file)
@@ -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
index 8e13075..6a99099 100644 (file)
@@ -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(
index 19bdea0..4808f8d 100644 (file)
@@ -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);
index 4fff9e1..f891e26 100644 (file)
@@ -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);
index 533cd9e..3eaed9e 100644 (file)
@@ -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;
index 3bf9bec..dd38ded 100644 (file)
@@ -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
index 75da5aa..ae85ed1 100644 (file)
@@ -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;