common/sfc_efx/base: allocate vAdaptor on Riverhead
[dpdk.git] / drivers / common / sfc_efx / base / efx_ev.c
index 21fddfb..99a7743 100644 (file)
@@ -109,6 +109,22 @@ static const efx_ev_ops_t  __efx_ev_ef10_ops = {
 };
 #endif /* EFX_OPTS_EF10() */
 
+#if EFSYS_OPT_RIVERHEAD
+static const efx_ev_ops_t      __efx_ev_rhead_ops = {
+       rhead_ev_init,                          /* eevo_init */
+       rhead_ev_fini,                          /* eevo_fini */
+       rhead_ev_qcreate,                       /* eevo_qcreate */
+       rhead_ev_qdestroy,                      /* eevo_qdestroy */
+       rhead_ev_qprime,                        /* eevo_qprime */
+       rhead_ev_qpost,                         /* eevo_qpost */
+       rhead_ev_qpoll,                         /* eevo_qpoll */
+       rhead_ev_qmoderate,                     /* eevo_qmoderate */
+#if EFSYS_OPT_QSTATS
+       rhead_ev_qstats_update,                 /* eevo_qstats_update */
+#endif
+};
+#endif /* EFSYS_OPT_RIVERHEAD */
+
 
        __checkReturn   efx_rc_t
 efx_ev_init(
@@ -150,6 +166,12 @@ efx_ev_init(
                break;
 #endif /* EFSYS_OPT_MEDFORD2 */
 
+#if EFSYS_OPT_RIVERHEAD
+       case EFX_FAMILY_RIVERHEAD:
+               eevop = &__efx_ev_rhead_ops;
+               break;
+#endif /* EFSYS_OPT_RIVERHEAD */
+
        default:
                EFSYS_ASSERT(0);
                rc = ENOTSUP;
@@ -236,18 +258,28 @@ efx_ev_qcreate(
        EFSYS_ASSERT3U(enp->en_ev_qcount + 1, <,
            enp->en_nic_cfg.enc_evq_limit);
 
+       if (index >= encp->enc_evq_limit) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       if (us > encp->enc_evq_timer_max_us) {
+               rc = EINVAL;
+               goto fail2;
+       }
+
        switch (flags & EFX_EVQ_FLAGS_NOTIFY_MASK) {
        case EFX_EVQ_FLAGS_NOTIFY_INTERRUPT:
                break;
        case EFX_EVQ_FLAGS_NOTIFY_DISABLED:
                if (us != 0) {
                        rc = EINVAL;
-                       goto fail1;
+                       goto fail3;
                }
                break;
        default:
                rc = EINVAL;
-               goto fail2;
+               goto fail4;
        }
 
        EFSYS_ASSERT(ISP2(encp->enc_evq_max_nevs));
@@ -257,14 +289,14 @@ efx_ev_qcreate(
            ndescs < encp->enc_evq_min_nevs ||
            ndescs > encp->enc_evq_max_nevs) {
                rc = EINVAL;
-               goto fail3;
+               goto fail5;
        }
 
        /* Allocate an EVQ object */
        EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_evq_t), eep);
        if (eep == NULL) {
                rc = ENOMEM;
-               goto fail4;
+               goto fail6;
        }
 
        eep->ee_magic = EFX_EVQ_MAGIC;
@@ -287,16 +319,20 @@ efx_ev_qcreate(
 
        if ((rc = eevop->eevo_qcreate(enp, index, esmp, ndescs, id, us, flags,
            eep)) != 0)
-               goto fail5;
+               goto fail7;
 
        return (0);
 
-fail5:
-       EFSYS_PROBE(fail5);
+fail7:
+       EFSYS_PROBE(fail7);
 
        *eepp = NULL;
        enp->en_ev_qcount--;
        EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_evq_t), eep);
+fail6:
+       EFSYS_PROBE(fail6);
+fail5:
+       EFSYS_PROBE(fail5);
 fail4:
        EFSYS_PROBE(fail4);
 fail3:
@@ -387,6 +423,36 @@ efx_ev_qprefetch(
 
 #endif /* EFSYS_OPT_EV_PREFETCH */
 
+/*
+ * This method is needed to ensure that eec_initialized callback
+ * is invoked after queue creation. The callback will be invoked
+ * on Riverhead boards which have no support for INIT_DONE events
+ * and will do nothing on other boards.
+ *
+ * The client drivers must call this method after calling efx_ev_create().
+ * The call must be done with the same locks being held (if any) which are
+ * normally acquired around efx_ev_qpoll() calls to ensure that
+ * eec_initialized callback is invoked within the same locking context.
+ */
+                       void
+efx_ev_qcreate_check_init_done(
+       __in            efx_evq_t *eep,
+       __in            const efx_ev_callbacks_t *eecp,
+       __in_opt        void *arg)
+{
+       const efx_nic_cfg_t *encp;
+
+       EFSYS_ASSERT(eep != NULL);
+       EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+       EFSYS_ASSERT(eecp != NULL);
+       EFSYS_ASSERT(eecp->eec_initialized != NULL);
+
+       encp = efx_nic_cfg_get(eep->ee_enp);
+
+       if (encp->enc_evq_init_done_ev_supported == B_FALSE)
+               (void) eecp->eec_initialized(arg);
+}
+
                        void
 efx_ev_qpoll(
        __in            efx_evq_t *eep,
@@ -1189,15 +1255,11 @@ siena_ev_qcreate(
 
        _NOTE(ARGUNUSED(esmp))
 
-       if (index >= encp->enc_evq_limit) {
-               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 fail2;
+               goto fail1;
        }
 #endif
        for (size = 0;
@@ -1207,7 +1269,7 @@ siena_ev_qcreate(
                        break;
        if (id + (1 << size) >= encp->enc_buftbl_limit) {
                rc = EINVAL;
-               goto fail3;
+               goto fail2;
        }
 
        /* Set up the handler table */
@@ -1239,13 +1301,11 @@ siena_ev_qcreate(
 
        return (0);
 
-fail3:
-       EFSYS_PROBE(fail3);
-#if EFSYS_OPT_RX_SCALE
 fail2:
        EFSYS_PROBE(fail2);
-#endif
+#if EFSYS_OPT_RX_SCALE
 fail1:
+#endif
        EFSYS_PROBE1(fail1, efx_rc_t, rc);
 
        return (rc);