[dpdk-dev] [PATCH v2 60/60] common/sfc_efx/base: handle descriptor proxy queue events
Andrew Rybchenko
arybchenko at solarflare.com
Tue Sep 22 11:34:48 CEST 2020
From: Andy Moreton <amoreton at xilinx.com>
The TXQ_DESC and VIRTQ_DESC events are used to pass host descriptors
over an extended width event queue to an application processor for
handling. See SF-122927-TC and SF-122966-SW for details.
Signed-off-by: Andy Moreton <amoreton at xilinx.com>
Signed-off-by: Andrew Rybchenko <arybchenko at solarflare.com>
---
drivers/common/sfc_efx/base/efx.h | 32 +++++++++
drivers/common/sfc_efx/base/efx_impl.h | 10 +++
drivers/common/sfc_efx/base/rhead_ev.c | 95 ++++++++++++++++++++++++++
3 files changed, 137 insertions(+)
diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h
index eea2ce3594..4278b4d66d 100644
--- a/drivers/common/sfc_efx/base/efx.h
+++ b/drivers/common/sfc_efx/base/efx.h
@@ -2487,6 +2487,33 @@ typedef __checkReturn boolean_t
#endif /* EFSYS_OPT_MAC_STATS */
+#if EFSYS_OPT_DESC_PROXY
+
+/*
+ * NOTE: This callback returns the raw descriptor data, which has not been
+ * converted to host endian. The callback must use the EFX_OWORD macros
+ * to extract the descriptor fields as host endian values.
+ */
+typedef __checkReturn boolean_t
+(*efx_desc_proxy_txq_desc_ev_t)(
+ __in_opt void *arg,
+ __in uint16_t vi_id,
+ __in efx_oword_t txq_desc);
+
+/*
+ * NOTE: This callback returns the raw descriptor data, which has not been
+ * converted to host endian. The callback must use the EFX_OWORD macros
+ * to extract the descriptor fields as host endian values.
+ */
+typedef __checkReturn boolean_t
+(*efx_desc_proxy_virtq_desc_ev_t)(
+ __in_opt void *arg,
+ __in uint16_t vi_id,
+ __in uint16_t avail,
+ __in efx_oword_t virtq_desc);
+
+#endif /* EFSYS_OPT_DESC_PROXY */
+
typedef struct efx_ev_callbacks_s {
efx_initialized_ev_t eec_initialized;
efx_rx_ev_t eec_rx;
@@ -2511,6 +2538,11 @@ typedef struct efx_ev_callbacks_s {
#if EFSYS_OPT_MAC_STATS
efx_mac_stats_ev_t eec_mac_stats;
#endif /* EFSYS_OPT_MAC_STATS */
+#if EFSYS_OPT_DESC_PROXY
+ efx_desc_proxy_txq_desc_ev_t eec_desc_proxy_txq_desc;
+ efx_desc_proxy_virtq_desc_ev_t eec_desc_proxy_virtq_desc;
+#endif /* EFSYS_OPT_DESC_PROXY */
+
} efx_ev_callbacks_t;
LIBEFX_API
diff --git a/drivers/common/sfc_efx/base/efx_impl.h b/drivers/common/sfc_efx/base/efx_impl.h
index f58586bee0..196fd4a79c 100644
--- a/drivers/common/sfc_efx/base/efx_impl.h
+++ b/drivers/common/sfc_efx/base/efx_impl.h
@@ -902,6 +902,11 @@ struct efx_nic_s {
typedef boolean_t (*efx_ev_handler_t)(efx_evq_t *, efx_qword_t *,
const efx_ev_callbacks_t *, void *);
+#if EFSYS_OPT_EV_EXTENDED_WIDTH
+typedef boolean_t (*efx_ev_ew_handler_t)(efx_evq_t *, efx_xword_t *,
+ const efx_ev_callbacks_t *, void *);
+#endif /* EFSYS_OPT_EV_EXTENDED_WIDTH */
+
typedef struct efx_evq_rxq_state_s {
unsigned int eers_rx_read_ptr;
unsigned int eers_rx_mask;
@@ -934,6 +939,11 @@ struct efx_evq_s {
efx_ev_handler_t ee_mcdi;
#endif /* EFSYS_OPT_MCDI */
+#if EFSYS_OPT_DESC_PROXY
+ efx_ev_ew_handler_t ee_ew_txq_desc;
+ efx_ev_ew_handler_t ee_ew_virtq_desc;
+#endif /* EFSYS_OPT_DESC_PROXY */
+
efx_evq_rxq_state_t ee_rxq_state[EFX_EV_RX_NLABELS];
};
diff --git a/drivers/common/sfc_efx/base/rhead_ev.c b/drivers/common/sfc_efx/base/rhead_ev.c
index 5bda315171..2b5635f1cd 100644
--- a/drivers/common/sfc_efx/base/rhead_ev.c
+++ b/drivers/common/sfc_efx/base/rhead_ev.c
@@ -58,6 +58,22 @@ rhead_ev_ew_qpoll(
__inout unsigned int *countp,
__in const efx_ev_callbacks_t *eecp,
__in_opt void *arg);
+
+#if EFSYS_OPT_DESC_PROXY
+static boolean_t
+rhead_ev_ew_txq_desc(
+ __in efx_evq_t *eep,
+ __in efx_xword_t *eventp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg);
+
+static boolean_t
+rhead_ev_ew_virtq_desc(
+ __in efx_evq_t *eep,
+ __in efx_xword_t *eventp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg);
+#endif /* EFSYS_OPT_DESC_PROXY */
#endif /* EFSYS_OPT_EV_EXTENDED_WIDTH */
@@ -115,6 +131,11 @@ rhead_ev_qcreate(
eep->ee_drv_gen = NULL; /* FIXME */
eep->ee_mcdi = rhead_ev_mcdi;
+#if EFSYS_OPT_DESC_PROXY
+ eep->ee_ew_txq_desc = rhead_ev_ew_txq_desc;
+ eep->ee_ew_virtq_desc = rhead_ev_ew_virtq_desc;
+#endif /* EFSYS_OPT_DESC_PROXY */
+
/* Set up the event queue */
/* INIT_EVQ expects function-relative vector number */
if ((flags & EFX_EVQ_FLAGS_NOTIFY_MASK) ==
@@ -345,6 +366,16 @@ rhead_ev_ew_dispatch(
rhead_ev_dispatch(eep, &eventp->ex_qword[0], eecp, arg);
break;
+#if EFSYS_OPT_DESC_PROXY
+ case ESE_GZ_EF100_EVEW_TXQ_DESC:
+ should_abort = eep->ee_ew_txq_desc(eep, eventp, eecp, arg);
+ break;
+
+ case ESE_GZ_EF100_EVEW_VIRTQ_DESC:
+ should_abort = eep->ee_ew_virtq_desc(eep, eventp, eecp, arg);
+ break;
+#endif /* EFSYS_OPT_DESC_PROXY */
+
default:
/* Omit currently unused reserved bits from the probe. */
EFSYS_PROBE7(ew_bad_event, unsigned int, eep->ee_index,
@@ -589,4 +620,68 @@ rhead_ev_mcdi(
return (ret);
}
+#if EFSYS_OPT_DESC_PROXY
+static boolean_t
+rhead_ev_ew_txq_desc(
+ __in efx_evq_t *eep,
+ __in efx_xword_t *eventp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg)
+{
+ efx_oword_t txq_desc;
+ uint16_t vi_id;
+ boolean_t should_abort;
+
+ _NOTE(ARGUNUSED(eep))
+
+ vi_id = EFX_XWORD_FIELD(*eventp, ESF_GZ_EV_TXQ_DP_VI_ID);
+
+ /*
+ * NOTE: This is the raw descriptor data, and has not been converted
+ * to host endian. The handler callback must use the EFX_OWORD macros
+ * to extract the descriptor fields as host endian values.
+ */
+ txq_desc = eventp->ex_oword[0];
+
+ EFSYS_ASSERT(eecp->eec_desc_proxy_txq_desc != NULL);
+ should_abort = eecp->eec_desc_proxy_txq_desc(arg, vi_id, txq_desc);
+
+ return (should_abort);
+}
+#endif /* EFSYS_OPT_DESC_PROXY */
+
+
+#if EFSYS_OPT_DESC_PROXY
+static boolean_t
+rhead_ev_ew_virtq_desc(
+ __in efx_evq_t *eep,
+ __in efx_xword_t *eventp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg)
+{
+ efx_oword_t virtq_desc;
+ uint16_t vi_id;
+ uint16_t avail;
+ boolean_t should_abort;
+
+ _NOTE(ARGUNUSED(eep))
+
+ vi_id = EFX_XWORD_FIELD(*eventp, ESF_GZ_EV_VQ_DP_VI_ID);
+ avail = EFX_XWORD_FIELD(*eventp, ESF_GZ_EV_VQ_DP_AVAIL_ENTRY);
+
+ /*
+ * NOTE: This is the raw descriptor data, and has not been converted
+ * to host endian. The handler callback must use the EFX_OWORD macros
+ * to extract the descriptor fields as host endian values.
+ */
+ virtq_desc = eventp->ex_oword[0];
+
+ EFSYS_ASSERT(eecp->eec_desc_proxy_virtq_desc != NULL);
+ should_abort =
+ eecp->eec_desc_proxy_virtq_desc(arg, vi_id, avail, virtq_desc);
+
+ return (should_abort);
+}
+#endif /* EFSYS_OPT_DESC_PROXY */
+
#endif /* EFSYS_OPT_RIVERHEAD */
--
2.17.1
More information about the dev
mailing list