From 96a8519deafcc826bd4841e68e454df15655f917 Mon Sep 17 00:00:00 2001 From: Andrew Rybchenko Date: Thu, 24 Sep 2020 13:12:11 +0100 Subject: [PATCH] common/sfc_efx/base: handle Tx complete on Riverhead Introduce a new event callback which has the same prototype, but provides number of completed descriptors instead of the last completed descriptor index. When all libefx-based drivers implement the new callback, libefx may be updated to use it for Siena and EF10 family NICs and the old one may be removed. Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/common/sfc_efx/base/efx.h | 7 ++++ drivers/common/sfc_efx/base/rhead_ev.c | 51 +++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index 983b723145..2437980c9e 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -2319,6 +2319,12 @@ typedef __checkReturn boolean_t __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 @@ -2406,6 +2412,7 @@ typedef struct efx_ev_callbacks_s { 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; diff --git a/drivers/common/sfc_efx/base/rhead_ev.c b/drivers/common/sfc_efx/base/rhead_ev.c index 44a79e2e5d..380729d174 100644 --- a/drivers/common/sfc_efx/base/rhead_ev.c +++ b/drivers/common/sfc_efx/base/rhead_ev.c @@ -23,6 +23,13 @@ rhead_ev_rx_packets( __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( @@ -66,7 +73,7 @@ rhead_ev_qcreate( /* 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; @@ -212,6 +219,10 @@ rhead_ev_qpoll( 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); @@ -328,6 +339,44 @@ rhead_ev_rx_packets( 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, -- 2.20.1