uint32_t enc_vf;
uint32_t enc_privilege_mask;
#endif /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */
+ boolean_t enc_evq_init_done_ev_supported;
boolean_t enc_bug26807_workaround;
boolean_t enc_bug35388_workaround;
boolean_t enc_bug41750_workaround;
#endif /* EFSYS_OPT_EV_PREFETCH */
+LIBEFX_API
+extern void
+efx_ev_qcreate_check_init_done(
+ __in efx_evq_t *eep,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg);
+
LIBEFX_API
extern void
efx_ev_qpoll(
#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,
uint32_t bandwidth;
efx_rc_t rc;
+ /*
+ * Event queue creation is complete when an
+ * EVQ_INIT_DONE_EV event is received.
+ */
+ encp->enc_evq_init_done_ev_supported = B_TRUE;
+
/*
* Enable firmware workarounds for hardware errata.
* Expected responses are:
uint32_t bandwidth;
efx_rc_t rc;
+ /*
+ * Event queue creation is complete when an
+ * EVQ_INIT_DONE_EV event is received.
+ */
+ encp->enc_evq_init_done_ev_supported = B_TRUE;
+
/*
* Enable firmware workarounds for hardware errata.
* Expected responses are:
uint32_t bandwidth;
efx_rc_t rc;
+ /*
+ * Event queue creation is complete when an
+ * EVQ_INIT_DONE_EV event is received.
+ */
+ encp->enc_evq_init_done_ev_supported = B_TRUE;
+
/*
* Enable firmware workarounds for hardware errata.
* Expected responses are:
encp->enc_buftbl_limit = UINT32_MAX;
+ /*
+ * Riverhead event queue creation completes
+ * immediately (no initial event).
+ */
+ encp->enc_evq_init_done_ev_supported = B_FALSE;
+
/*
* Enable firmware workarounds for hardware errata.
* Expected responses are:
encp->enc_rx_scale_additional_modes_supported = B_FALSE;
#endif /* EFSYS_OPT_RX_SCALE */
+ /*
+ * Event queue creation is complete when an
+ * EVQ_INIT_DONE_EV event is received.
+ */
+ encp->enc_evq_init_done_ev_supported = B_TRUE;
+
encp->enc_tx_dma_desc_size_max = EFX_MASK32(FSF_AZ_TX_KER_BYTE_COUNT);
/* Fragments must not span 4k boundaries. */
encp->enc_tx_dma_desc_boundary = 4096;
efx_ev_fini;
efx_ev_init;
efx_ev_qcreate;
+ efx_ev_qcreate_check_init_done;
efx_ev_qdestroy;
efx_ev_qmoderate;
efx_ev_qpending;
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->callbacks = &sfc_ev_callbacks;
}
- evq->init_state = SFC_EVQ_STARTING;
+ /*
+ * Poll once to ensure that eec_initialized callback is invoked in
+ * case if the hardware does not support INIT_DONE events. If the
+ * hardware supports INIT_DONE events, this will do nothing, and the
+ * corresponding event will be processed by sfc_ev_qpoll() below.
+ */
+ efx_ev_qcreate_check_init_done(evq->common, evq->callbacks, evq);
/* Wait for the initialization event */
total_delay_us = 0;
return 0;
fail_timedout:
- evq->init_state = SFC_EVQ_INITIALIZED;
efx_ev_qdestroy(evq->common);
fail_ev_qcreate:
+ evq->init_state = SFC_EVQ_INITIALIZED;
sfc_log_init(sa, "failed %d", rc);
return rc;
}