Rx event on Riverhead provides a number of received packets and
no classification/offloads information is available Rx event.
Introduce a new event callback to be implemented by drivers.
The callback provides information about the number of completed
packets. libefx-based drivers should implement the new callback
for Riverhead and keep the old one for Siena and EF10 NICs.
The new callback may be used for Medford2 NO_CONT_EV Rx mode
support.
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
---
drivers/common/sfc_efx/base/efx.h | 8 ++++
drivers/common/sfc_efx/base/rhead_ev.c | 56 +++++++++++++++++++++++++-
2 files changed, 63 insertions(+), 1 deletion(-)
@@ -2277,6 +2277,13 @@ typedef __checkReturn boolean_t
__in uint32_t size,
__in uint16_t flags);
+typedef __checkReturn boolean_t
+(*efx_rx_packets_ev_t)(
+ __in_opt void *arg,
+ __in uint32_t label,
+ __in unsigned int num_packets,
+ __in uint32_t flags);
+
#if EFSYS_OPT_RX_PACKED_STREAM || EFSYS_OPT_RX_ES_SUPER_BUFFER
/*
@@ -2394,6 +2401,7 @@ typedef __checkReturn boolean_t
typedef struct efx_ev_callbacks_s {
efx_initialized_ev_t eec_initialized;
efx_rx_ev_t eec_rx;
+ efx_rx_packets_ev_t eec_rx_packets;
#if EFSYS_OPT_RX_PACKED_STREAM || EFSYS_OPT_RX_ES_SUPER_BUFFER
efx_rx_ps_ev_t eec_rx_ps;
#endif
@@ -16,6 +16,13 @@
*/
#define EFX_RHEAD_ALWAYS_INTERRUPTING_EVQ_INDEX (0)
+static __checkReturn boolean_t
+rhead_ev_rx_packets(
+ __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(
@@ -58,7 +65,7 @@ rhead_ev_qcreate(
_NOTE(ARGUNUSED(id)) /* buftbl id managed by MC */
/* Set up the handler table */
- eep->ee_rx = NULL; /* FIXME */
+ eep->ee_rx = rhead_ev_rx_packets;
eep->ee_tx = NULL; /* FIXME */
eep->ee_driver = NULL; /* FIXME */
eep->ee_drv_gen = NULL; /* FIXME */
@@ -201,6 +208,10 @@ rhead_ev_qpoll(
code = EFX_QWORD_FIELD(ev[index], ESF_GZ_E_TYPE);
switch (code) {
+ case ESE_GZ_EF100_EV_RX_PKTS:
+ should_abort = eep->ee_rx(eep,
+ &(ev[index]), eecp, arg);
+ break;
case ESE_GZ_EF100_EV_MCDI:
should_abort = eep->ee_mcdi(eep,
&(ev[index]), eecp, arg);
@@ -274,6 +285,49 @@ rhead_ev_qstats_update(
}
#endif /* EFSYS_OPT_QSTATS */
+static __checkReturn boolean_t
+rhead_ev_rx_packets(
+ __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 label;
+ uint32_t num_packets;
+ boolean_t should_abort;
+
+ EFX_EV_QSTAT_INCR(eep, EV_RX);
+
+ /* 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_RXPKTS_Q_LABEL);
+
+ /*
+ * On EF100 the EV_RX event reports the number of received
+ * packets (unlike EF10 which reports a descriptor index).
+ * The client driver is responsible for maintaining the Rx
+ * descriptor index, and computing how many descriptors are
+ * occupied by each received packet (based on the Rx buffer size
+ * and the packet length from the Rx prefix).
+ */
+ num_packets = EFX_QWORD_FIELD(*eqp, ESF_GZ_EV_RXPKTS_NUM_PKT);
+
+ /*
+ * The receive event may indicate more than one packet, and so
+ * does not contain the packet length. Read the packet length
+ * from the prefix when handling each packet.
+ */
+ EFSYS_ASSERT(eecp->eec_rx_packets != NULL);
+ should_abort = eecp->eec_rx_packets(arg, label, num_packets,
+ EFX_PKT_PREFIX_LEN);
+
+ return (should_abort);
+}
+
static __checkReturn boolean_t
rhead_ev_mcdi(
__in efx_evq_t *eep,