common/sfc_efx/base: handle Tx complete on Riverhead
authorAndrew Rybchenko <arybchenko@solarflare.com>
Thu, 24 Sep 2020 12:12:11 +0000 (13:12 +0100)
committerFerruh Yigit <ferruh.yigit@intel.com>
Wed, 30 Sep 2020 17:19:12 +0000 (19:19 +0200)
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
drivers/common/sfc_efx/base/rhead_ev.c

index 983b723..2437980 100644 (file)
@@ -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;
index 44a79e2..380729d 100644 (file)
@@ -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,