#if EFX_OPTS_EF10()
/*
- * EF10 RX pseudo-header
- * ---------------------
+ * EF10 RX pseudo-header (aka Rx prefix)
+ * -------------------------------------
*
* Receive packets are prefixed by an (optional) 14 byte pseudo-header:
*
* (32bit little-endian)
*
* See "The RX Pseudo-header" in SF-109306-TC.
+ *
+ * EF10 does not support Rx prefix choice using MC_CMD_GET_RX_PREFIX_ID
+ * and query its layout using MC_CMD_QUERY_RX_PREFIX_ID.
*/
+static const efx_rx_prefix_layout_t ef10_default_rx_prefix_layout = {
+ .erpl_id = 0,
+ .erpl_length = 14,
+ .erpl_fields = {
+ [EFX_RX_PREFIX_FIELD_RSS_HASH] =
+ { 0, 32, B_FALSE },
+ [EFX_RX_PREFIX_FIELD_VLAN_STRIP_TCI] =
+ { 32, 16, B_TRUE },
+ [EFX_RX_PREFIX_FIELD_INNER_VLAN_STRIP_TCI] =
+ { 48, 16, B_TRUE },
+ [EFX_RX_PREFIX_FIELD_LENGTH] =
+ { 64, 16, B_FALSE },
+ [EFX_RX_PREFIX_FIELD_PARTIAL_TSTAMP] =
+ { 80, 32, B_FALSE },
+ }
+};
+
+#if EFSYS_OPT_RX_PACKED_STREAM
+
+/*
+ * EF10 packed stream Rx prefix layout.
+ *
+ * See SF-112241-TC Full speed capture for Huntington and Medford section 4.5.
+ */
+static const efx_rx_prefix_layout_t ef10_packed_stream_rx_prefix_layout = {
+ .erpl_id = 0,
+ .erpl_length = 8,
+ .erpl_fields = {
+#define EF10_PS_RX_PREFIX_FIELD(_efx, _ef10) \
+ EFX_RX_PREFIX_FIELD(_efx, ES_DZ_PS_RX_PREFIX_ ## _ef10, B_FALSE)
+
+ EF10_PS_RX_PREFIX_FIELD(PARTIAL_TSTAMP, TSTAMP),
+ EF10_PS_RX_PREFIX_FIELD(LENGTH, CAP_LEN),
+ EF10_PS_RX_PREFIX_FIELD(ORIG_LENGTH, ORIG_LEN),
+
+#undef EF10_PS_RX_PREFIX_FIELD
+ }
+};
+
+#endif /* EFSYS_OPT_RX_PACKED_STREAM */
+
+#if EFSYS_OPT_RX_ES_SUPER_BUFFER
+
+/*
+ * EF10 equal stride super-buffer Rx prefix layout.
+ *
+ * See SF-119419-TC DPDK Firmware Driver Interface section 3.4.
+ */
+static const efx_rx_prefix_layout_t ef10_essb_rx_prefix_layout = {
+ .erpl_id = 0,
+ .erpl_length = ES_EZ_ESSB_RX_PREFIX_LEN,
+ .erpl_fields = {
+#define EF10_ESSB_RX_PREFIX_FIELD(_efx, _ef10) \
+ EFX_RX_PREFIX_FIELD(_efx, ES_EZ_ESSB_RX_PREFIX_ ## _ef10, B_FALSE)
+
+ EF10_ESSB_RX_PREFIX_FIELD(LENGTH, DATA_LEN),
+ EF10_ESSB_RX_PREFIX_FIELD(USER_MARK, MARK),
+ EF10_ESSB_RX_PREFIX_FIELD(RSS_HASH_VALID, HASH_VALID),
+ EF10_ESSB_RX_PREFIX_FIELD(USER_MARK_VALID, MARK_VALID),
+ EF10_ESSB_RX_PREFIX_FIELD(USER_FLAG, MATCH_FLAG),
+ EF10_ESSB_RX_PREFIX_FIELD(RSS_HASH, HASH),
+
+#undef EF10_ESSB_RX_PREFIX_FIELD
+ }
+};
+
+#endif /* EFSYS_OPT_RX_ES_SUPER_BUFFER */
__checkReturn efx_rc_t
ef10_rx_prefix_pktlen(
__in efx_rxq_t *erp)
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ const efx_rx_prefix_layout_t *erpl;
efx_rc_t rc;
boolean_t disable_scatter;
boolean_t want_inner_classes;
switch (type) {
case EFX_RXQ_TYPE_DEFAULT:
+ erpl = &ef10_default_rx_prefix_layout;
if (type_data == NULL) {
rc = EINVAL;
goto fail1;
break;
#if EFSYS_OPT_RX_PACKED_STREAM
case EFX_RXQ_TYPE_PACKED_STREAM:
+ erpl = &ef10_packed_stream_rx_prefix_layout;
if (type_data == NULL) {
rc = EINVAL;
goto fail2;
#endif /* EFSYS_OPT_RX_PACKED_STREAM */
#if EFSYS_OPT_RX_ES_SUPER_BUFFER
case EFX_RXQ_TYPE_ES_SUPER_BUFFER:
+ erpl = &ef10_essb_rx_prefix_layout;
if (type_data == NULL) {
rc = EINVAL;
goto fail4;
erp->er_ev_qstate = &erp->er_eep->ee_rxq_state[label];
+ erp->er_prefix_layout = *erpl;
+
return (0);
fail11:
uint32_t enc_ev_desc_size;
uint32_t enc_rx_desc_size;
uint32_t enc_tx_desc_size;
+ /* Maximum Rx prefix size if many Rx prefixes are supported */
uint32_t enc_rx_prefix_size;
uint32_t enc_rx_buf_align_start;
uint32_t enc_rx_buf_align_end;
#define EFX_RXQ_LIMIT(_ndescs) ((_ndescs) - 16)
+/*
+ * libefx representation of the Rx prefix layout information.
+ *
+ * The information may be used inside libefx to implement Rx prefix fields
+ * accessors and by drivers which process Rx prefix itself.
+ */
+
+/*
+ * All known Rx prefix fields.
+ *
+ * An Rx prefix may have a subset of these fields.
+ */
+typedef enum efx_rx_prefix_field_e {
+ EFX_RX_PREFIX_FIELD_LENGTH = 0,
+ EFX_RX_PREFIX_FIELD_ORIG_LENGTH,
+ EFX_RX_PREFIX_FIELD_CLASS,
+ EFX_RX_PREFIX_FIELD_RSS_HASH,
+ EFX_RX_PREFIX_FIELD_RSS_HASH_VALID,
+ EFX_RX_PREFIX_FIELD_PARTIAL_TSTAMP,
+ EFX_RX_PREFIX_FIELD_VLAN_STRIP_TCI,
+ EFX_RX_PREFIX_FIELD_INNER_VLAN_STRIP_TCI,
+ EFX_RX_PREFIX_FIELD_USER_FLAG,
+ EFX_RX_PREFIX_FIELD_USER_MARK,
+ EFX_RX_PREFIX_FIELD_USER_MARK_VALID,
+ EFX_RX_PREFIX_FIELD_CSUM_FRAME,
+ EFX_RX_PREFIX_FIELD_INGRESS_VPORT,
+ EFX_RX_PREFIX_NFIELDS
+} efx_rx_prefix_field_t;
+
+/*
+ * Location and endianness of a field in Rx prefix.
+ *
+ * If width is zero, the field is not present.
+ */
+typedef struct efx_rx_prefix_field_info_s {
+ uint16_t erpfi_offset_bits;
+ uint8_t erpfi_width_bits;
+ boolean_t erpfi_big_endian;
+} efx_rx_prefix_field_info_t;
+
+/* Helper macro to define Rx prefix fields */
+#define EFX_RX_PREFIX_FIELD(_efx, _field, _big_endian) \
+ [EFX_RX_PREFIX_FIELD_ ## _efx] = { \
+ .erpfi_offset_bits = EFX_LOW_BIT(_field), \
+ .erpfi_width_bits = EFX_WIDTH(_field), \
+ .erpfi_big_endian = (_big_endian), \
+ }
+
+typedef struct efx_rx_prefix_layout_s {
+ uint32_t erpl_id;
+ uint8_t erpl_length;
+ efx_rx_prefix_field_info_t erpl_fields[EFX_RX_PREFIX_NFIELDS];
+} efx_rx_prefix_layout_t;
+
+LIBEFX_API
+extern __checkReturn efx_rc_t
+efx_rx_prefix_get_layout(
+ __in const efx_rxq_t *erp,
+ __out efx_rx_prefix_layout_t *erplp);
+
typedef enum efx_rxq_type_e {
EFX_RXQ_TYPE_DEFAULT,
EFX_RXQ_TYPE_PACKED_STREAM,
size_t er_buf_size;
efsys_mem_t *er_esmp;
efx_evq_rxq_state_t *er_ev_qstate;
+ efx_rx_prefix_layout_t er_prefix_layout;
};
#define EFX_RXQ_MAGIC 0x15022005
}
#endif /* EFSYS_OPT_RX_SCALE */
+ __checkReturn efx_rc_t
+efx_rx_prefix_get_layout(
+ __in const efx_rxq_t *erp,
+ __out efx_rx_prefix_layout_t *erplp)
+{
+ EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
+
+ *erplp = erp->er_prefix_layout;
+
+ return (0);
+}
+
#if EFSYS_OPT_SIENA
static __checkReturn efx_rc_t
* LL.LL LFSR hash (16-bit big-endian)
*/
+/*
+ * Provide Rx prefix layout with Toeplitz hash only since LSFR is
+ * used by no supported drivers.
+ *
+ * Siena does not support Rx prefix choice via MC_CMD_GET_RX_PREFIX_ID
+ * and query its layout using MC_CMD_QUERY_RX_PREFIX_ID.
+ */
+static const efx_rx_prefix_layout_t siena_toeplitz_rx_prefix_layout = {
+ .erpl_id = 0,
+ .erpl_length = 16,
+ .erpl_fields = {
+ [EFX_RX_PREFIX_FIELD_RSS_HASH] = { 12 * 8, 32, B_TRUE },
+ }
+};
+
#if EFSYS_OPT_RX_SCALE
static __checkReturn uint32_t
siena_rx_prefix_hash(
EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
erp->er_index, &oword, B_TRUE);
+ erp->er_prefix_layout = siena_toeplitz_rx_prefix_layout;
+
return (0);
#if !EFSYS_OPT_RX_SCATTER
#define EFX_AND_QWORD EFX_AND_QWORD32
#endif
+
#ifdef __cplusplus
}
#endif
#if EFSYS_OPT_RIVERHEAD
+/*
+ * Default Rx prefix layout on Riverhead if FW does not support Rx
+ * prefix choice using MC_CMD_GET_RX_PREFIX_ID and query its layout
+ * using MC_CMD_QUERY_RX_PREFIX_ID.
+ *
+ * See SF-119689-TC Riverhead Host Interface section 6.4.
+ */
+static const efx_rx_prefix_layout_t rhead_default_rx_prefix_layout = {
+ .erpl_id = 0,
+ .erpl_length = ESE_GZ_RX_PKT_PREFIX_LEN,
+ .erpl_fields = {
+#define RHEAD_RX_PREFIX_FIELD(_name, _big_endian) \
+ EFX_RX_PREFIX_FIELD(_name, ESF_GZ_RX_PREFIX_ ## _name, _big_endian)
+
+ RHEAD_RX_PREFIX_FIELD(LENGTH, B_FALSE),
+ RHEAD_RX_PREFIX_FIELD(RSS_HASH_VALID, B_FALSE),
+ RHEAD_RX_PREFIX_FIELD(USER_FLAG, B_FALSE),
+ RHEAD_RX_PREFIX_FIELD(CLASS, B_FALSE),
+ RHEAD_RX_PREFIX_FIELD(PARTIAL_TSTAMP, B_FALSE),
+ RHEAD_RX_PREFIX_FIELD(RSS_HASH, B_FALSE),
+ RHEAD_RX_PREFIX_FIELD(USER_MARK, B_FALSE),
+ RHEAD_RX_PREFIX_FIELD(INGRESS_VPORT, B_FALSE),
+ RHEAD_RX_PREFIX_FIELD(CSUM_FRAME, B_TRUE),
+ RHEAD_RX_PREFIX_FIELD(VLAN_STRIP_TCI, B_TRUE),
+
+#undef RHEAD_RX_PREFIX_FIELD
+ }
+};
+
__checkReturn efx_rc_t
rhead_rx_init(
__in efx_nic_t *enp)
erp->er_eep = eep;
erp->er_label = label;
+ erp->er_prefix_layout = rhead_default_rx_prefix_layout;
return (0);
efx_rx_fini;
efx_rx_hash_default_support_get;
efx_rx_init;
+ efx_rx_prefix_get_layout;
efx_rx_qcreate;
efx_rx_qcreate_es_super_buffer;
efx_rx_qdestroy;