[v3,36/60] common/sfc_efx/base: handle Tx complete on Riverhead
diff mbox series

Message ID 1600949555-28043-37-git-send-email-arybchenko@solarflare.com
State Accepted
Delegated to: Ferruh Yigit
Headers show
Series
  • common/sfc_efx: support Riverhead NIC family
Related show

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Andrew Rybchenko Sept. 24, 2020, 12:12 p.m. UTC
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 <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
---
 drivers/common/sfc_efx/base/efx.h      |  7 ++++
 drivers/common/sfc_efx/base/rhead_ev.c | 51 +++++++++++++++++++++++++-
 2 files changed, 57 insertions(+), 1 deletion(-)

Patch
diff mbox series

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,