__in uint32_t label,
__in uint32_t id);
+typedef __checkReturn boolean_t
+(*efx_tx_ndescs_ev_t)(
+ __in_opt void *arg,
+ __in uint32_t label,
+ __in unsigned int ndescs);
+
#define EFX_EXCEPTION_RX_RECOVERY 0x00000001
#define EFX_EXCEPTION_RX_DSC_ERROR 0x00000002
#define EFX_EXCEPTION_TX_DSC_ERROR 0x00000003
efx_rx_ps_ev_t eec_rx_ps;
#endif
efx_tx_ev_t eec_tx;
+ efx_tx_ndescs_ev_t eec_tx_ndescs;
efx_exception_ev_t eec_exception;
efx_rxq_flush_done_ev_t eec_rxq_flush_done;
efx_rxq_flush_failed_ev_t eec_rxq_flush_failed;
__in const efx_ev_callbacks_t *eecp,
__in_opt void *arg);
+static __checkReturn boolean_t
+rhead_ev_tx_completion(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg);
+
static __checkReturn boolean_t
rhead_ev_mcdi(
/* Set up the handler table */
eep->ee_rx = rhead_ev_rx_packets;
- eep->ee_tx = NULL; /* FIXME */
+ eep->ee_tx = rhead_ev_tx_completion;
eep->ee_driver = NULL; /* FIXME */
eep->ee_drv_gen = NULL; /* FIXME */
eep->ee_mcdi = rhead_ev_mcdi;
should_abort = eep->ee_rx(eep,
&(ev[index]), eecp, arg);
break;
+ case ESE_GZ_EF100_EV_TX_COMPLETION:
+ should_abort = eep->ee_tx(eep,
+ &(ev[index]), eecp, arg);
+ break;
case ESE_GZ_EF100_EV_MCDI:
should_abort = eep->ee_mcdi(eep,
&(ev[index]), eecp, arg);
return (should_abort);
}
+static __checkReturn boolean_t
+rhead_ev_tx_completion(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ uint32_t num_descs;
+ uint32_t label;
+ boolean_t should_abort;
+
+ EFX_EV_QSTAT_INCR(eep, EV_TX);
+
+ /* Discard events after RXQ/TXQ errors, or hardware not available */
+ if (enp->en_reset_flags &
+ (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR | EFX_RESET_HW_UNAVAIL))
+ return (B_FALSE);
+
+ label = EFX_QWORD_FIELD(*eqp, ESF_GZ_EV_TXCMPL_Q_LABEL);
+
+ /*
+ * On EF100 the EV_TX event reports the number of completed Tx
+ * descriptors (on EF10, the event reports the low bits of the
+ * index of the last completed descriptor).
+ * The client driver completion callback will compute the
+ * descriptor index, so that is not needed here.
+ */
+ num_descs = EFX_QWORD_FIELD(*eqp, ESF_GZ_EV_TXCMPL_NUM_DESC);
+
+ EFSYS_PROBE2(tx_ndescs, uint32_t, label, unsigned int, num_descs);
+
+ EFSYS_ASSERT(eecp->eec_tx_ndescs != NULL);
+ should_abort = eecp->eec_tx_ndescs(arg, label, num_descs);
+
+ return (should_abort);
+}
+
static __checkReturn boolean_t
rhead_ev_mcdi(
__in efx_evq_t *eep,