/* SPDX-License-Identifier: BSD-3-Clause
*
- * Copyright(c) 2019-2020 Xilinx, Inc.
+ * Copyright(c) 2019-2021 Xilinx, Inc.
* Copyright(c) 2007-2019 Solarflare Communications Inc.
*/
ndescs, id, flags, eep, erp)) != 0)
goto fail4;
+ /* Sanity check queue creation result */
+ if (flags & EFX_RXQ_FLAG_RSS_HASH) {
+ const efx_rx_prefix_layout_t *erplp = &erp->er_prefix_layout;
+ const efx_rx_prefix_field_info_t *rss_hash_field;
+
+ rss_hash_field =
+ &erplp->erpl_fields[EFX_RX_PREFIX_FIELD_RSS_HASH];
+ if (rss_hash_field->erpfi_width_bits == 0)
+ goto fail5;
+ }
+
enp->en_rx_qcount++;
*erpp = erp;
return (0);
+fail5:
+ EFSYS_PROBE(fail5);
+
+ erxop->erxo_qdestroy(erp);
fail4:
EFSYS_PROBE(fail4);
switch (type) {
case EFX_RXQ_TYPE_DEFAULT:
erp->er_buf_size = type_data->ertd_default.ed_buf_size;
+ /*
+ * Ignore EFX_RXQ_FLAG_RSS_HASH since if RSS hash is calculated
+ * it is always delivered from HW in the pseudo-header.
+ */
break;
default:
goto fail2;
}
- if (flags & EFX_RXQ_FLAG_SCATTER) {
#if EFSYS_OPT_RX_SCATTER
- jumbo = B_TRUE;
+#define SUPPORTED_RXQ_FLAGS EFX_RXQ_FLAG_SCATTER
#else
+#define SUPPORTED_RXQ_FLAGS EFX_RXQ_FLAG_NONE
+#endif
+ /* Reject flags for unsupported queue features */
+ if ((flags & ~SUPPORTED_RXQ_FLAGS) != 0) {
rc = EINVAL;
goto fail3;
-#endif /* EFSYS_OPT_RX_SCATTER */
}
+#undef SUPPORTED_RXQ_FLAGS
+
+ if (flags & EFX_RXQ_FLAG_SCATTER)
+ jumbo = B_TRUE;
/* Set up the new descriptor queue */
EFX_POPULATE_OWORD_7(oword,
return (0);
-#if !EFSYS_OPT_RX_SCATTER
fail3:
EFSYS_PROBE(fail3);
-#endif
fail2:
EFSYS_PROBE(fail2);
fail1:
}
#endif /* EFSYS_OPT_SIENA */
+
+static __checkReturn boolean_t
+efx_rx_prefix_layout_fields_match(
+ __in const efx_rx_prefix_field_info_t *erpfip1,
+ __in const efx_rx_prefix_field_info_t *erpfip2)
+{
+ if (erpfip1->erpfi_offset_bits != erpfip2->erpfi_offset_bits)
+ return (B_FALSE);
+
+ if (erpfip1->erpfi_width_bits != erpfip2->erpfi_width_bits)
+ return (B_FALSE);
+
+ if (erpfip1->erpfi_big_endian != erpfip2->erpfi_big_endian)
+ return (B_FALSE);
+
+ return (B_TRUE);
+}
+
+ __checkReturn uint32_t
+efx_rx_prefix_layout_check(
+ __in const efx_rx_prefix_layout_t *available,
+ __in const efx_rx_prefix_layout_t *wanted)
+{
+ uint32_t result = 0;
+ unsigned int i;
+
+ EFX_STATIC_ASSERT(EFX_RX_PREFIX_NFIELDS < sizeof (result) * 8);
+ for (i = 0; i < EFX_RX_PREFIX_NFIELDS; ++i) {
+ /* Skip the field if driver does not want to use it */
+ if (wanted->erpl_fields[i].erpfi_width_bits == 0)
+ continue;
+
+ if (efx_rx_prefix_layout_fields_match(
+ &available->erpl_fields[i],
+ &wanted->erpl_fields[i]) == B_FALSE)
+ result |= (1U << i);
+ }
+
+ return (result);
+}