#include "efx.h"
#include "efx_impl.h"
-#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
+#if EFX_OPTS_EF10()
#if EFSYS_OPT_FILTER
efx_rc_t rc;
ef10_filter_table_t *eftp;
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
- enp->en_family == EFX_FAMILY_MEDFORD ||
- enp->en_family == EFX_FAMILY_MEDFORD2);
+ EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
#define MATCH_MASK(match) (EFX_MASK32(match) << EFX_LOW_BIT(match))
EFX_STATIC_ASSERT(EFX_FILTER_MATCH_REM_HOST ==
ef10_filter_fini(
__in efx_nic_t *enp)
{
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
- enp->en_family == EFX_FAMILY_MEDFORD ||
- enp->en_family == EFX_FAMILY_MEDFORD2);
+ EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
if (enp->en_filter.ef_ef10_filter_table != NULL) {
EFSYS_KMEM_FREE(enp->en_esip, sizeof (ef10_filter_table_t),
__inout ef10_filter_handle_t *handle)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_FILTER_OP_V3_IN_LEN,
- MC_CMD_FILTER_OP_EXT_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FILTER_OP_V3_IN_LEN,
+ MC_CMD_FILTER_OP_EXT_OUT_LEN);
efx_filter_match_flags_t match_flags;
efx_rc_t rc;
- memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_FILTER_OP;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_FILTER_OP_V3_IN_LEN;
goto fail1;
}
- MCDI_IN_SET_DWORD(req, FILTER_OP_EXT_IN_PORT_ID,
- EVB_PORT_ID_ASSIGNED);
+ MCDI_IN_SET_DWORD(req, FILTER_OP_EXT_IN_PORT_ID, enp->en_vport_id);
MCDI_IN_SET_DWORD(req, FILTER_OP_EXT_IN_MATCH_FIELDS,
match_flags);
if (spec->efs_dmaq_id == EFX_FILTER_SPEC_RX_DMAQ_ID_DROP) {
__inout ef10_filter_handle_t *handle)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_FILTER_OP_EXT_IN_LEN,
- MC_CMD_FILTER_OP_EXT_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FILTER_OP_EXT_IN_LEN,
+ MC_CMD_FILTER_OP_EXT_OUT_LEN);
efx_rc_t rc;
- memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_FILTER_OP;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_FILTER_OP_EXT_IN_LEN;
efsys_lock_state_t state;
efx_rc_t rc;
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
- enp->en_family == EFX_FAMILY_MEDFORD ||
- enp->en_family == EFX_FAMILY_MEDFORD2);
+ EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
for (tbl_id = 0; tbl_id < EFX_EF10_FILTER_TBL_ROWS; tbl_id++) {
efsys_lock_state_t state;
boolean_t locked = B_FALSE;
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
- enp->en_family == EFX_FAMILY_MEDFORD ||
- enp->en_family == EFX_FAMILY_MEDFORD2);
+ EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
hash = ef10_filter_hash(spec);
* else a free slot to insert at. If any of them are busy,
* we have to wait and retry.
*/
- for (;;) {
- ins_index = -1;
- depth = 1;
- EFSYS_LOCK(enp->en_eslp, state);
- locked = B_TRUE;
+retry:
+ EFSYS_LOCK(enp->en_eslp, state);
+ locked = B_TRUE;
- for (;;) {
- i = (hash + depth) & (EFX_EF10_FILTER_TBL_ROWS - 1);
- saved_spec = ef10_filter_entry_spec(eftp, i);
+ ins_index = -1;
- if (!saved_spec) {
- if (ins_index < 0) {
- ins_index = i;
- }
- } else if (ef10_filter_equal(spec, saved_spec)) {
- if (ef10_filter_entry_is_busy(eftp, i))
- break;
- if (saved_spec->efs_priority
- == EFX_FILTER_PRI_AUTO) {
- ins_index = i;
- goto found;
- } else if (ef10_filter_is_exclusive(spec)) {
- if (may_replace) {
- ins_index = i;
- goto found;
- } else {
- rc = EEXIST;
- goto fail1;
- }
- }
+ for (depth = 1; depth <= EF10_FILTER_SEARCH_LIMIT; depth++) {
+ i = (hash + depth) & (EFX_EF10_FILTER_TBL_ROWS - 1);
+ saved_spec = ef10_filter_entry_spec(eftp, i);
+
+ if (saved_spec == NULL) {
+ if (ins_index < 0)
+ ins_index = i;
+ } else if (ef10_filter_equal(spec, saved_spec)) {
+ if (ef10_filter_entry_is_busy(eftp, i)) {
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ locked = B_FALSE;
+ goto retry;
+ }
- /* Leave existing */
+ if (saved_spec->efs_priority == EFX_FILTER_PRI_AUTO) {
+ ins_index = i;
+ goto found;
}
- /*
- * Once we reach the maximum search depth, use
- * the first suitable slot or return EBUSY if
- * there was none.
- */
- if (depth == EF10_FILTER_SEARCH_LIMIT) {
- if (ins_index < 0) {
- rc = EBUSY;
- goto fail2;
+ if (ef10_filter_is_exclusive(spec)) {
+ if (may_replace) {
+ ins_index = i;
+ goto found;
+ } else {
+ rc = EEXIST;
+ goto fail1;
}
- goto found;
}
- depth++;
+
+ /* Leave existing */
}
- EFSYS_UNLOCK(enp->en_eslp, state);
- locked = B_FALSE;
+ }
+
+ /*
+ * Once we reach the maximum search depth, use the first suitable slot
+ * or return EBUSY if there was none.
+ */
+ if (ins_index < 0) {
+ rc = EBUSY;
+ goto fail2;
}
found:
efsys_lock_state_t state;
boolean_t locked = B_FALSE;
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
- enp->en_family == EFX_FAMILY_MEDFORD ||
- enp->en_family == EFX_FAMILY_MEDFORD2);
+ EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
hash = ef10_filter_hash(spec);
__out size_t *list_lengthp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_PARSER_DISP_INFO_IN_LEN,
- MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMAX)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PARSER_DISP_INFO_IN_LEN,
+ MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMAX);
size_t matches_count;
size_t list_size;
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_PARSER_DISP_INFO;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_PARSER_DISP_INFO_IN_LEN;
efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
filter_flags,
eftp->eft_default_rxq);
- efx_filter_spec_set_eth_local(&spec, EFX_FILTER_SPEC_VID_UNSPEC, addr);
+ rc = efx_filter_spec_set_eth_local(&spec, EFX_FILTER_SPEC_VID_UNSPEC,
+ addr);
+ if (rc != 0)
+ goto fail1;
rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
&eftp->eft_unicst_filter_indexes[eftp->eft_unicst_filter_count]);
if (rc != 0)
- goto fail1;
+ goto fail2;
eftp->eft_unicst_filter_count++;
EFSYS_ASSERT(eftp->eft_unicst_filter_count <=
return (0);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
filter_flags,
eftp->eft_default_rxq);
- efx_filter_spec_set_uc_def(&spec);
+ rc = efx_filter_spec_set_uc_def(&spec);
+ if (rc != 0)
+ goto fail1;
rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
&eftp->eft_unicst_filter_indexes[eftp->eft_unicst_filter_count]);
if (rc != 0)
- goto fail1;
+ goto fail2;
eftp->eft_unicst_filter_count++;
EFSYS_ASSERT(eftp->eft_unicst_filter_count <=
return (0);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
filter_flags,
eftp->eft_default_rxq);
- efx_filter_spec_set_eth_local(&spec,
+ rc = efx_filter_spec_set_eth_local(&spec,
EFX_FILTER_SPEC_VID_UNSPEC,
&addrs[i * EFX_MAC_ADDR_LEN]);
+ if (rc != 0) {
+ if (rollback == B_TRUE) {
+ /* Only stop upon failure if told to rollback */
+ goto rollback;
+ } else {
+ /*
+ * Don't try to add a filter with a corrupt
+ * specification.
+ */
+ continue;
+ }
+ }
rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
&filter_index);
eftp->eft_default_rxq);
EFX_MAC_BROADCAST_ADDR_SET(addr);
- efx_filter_spec_set_eth_local(&spec, EFX_FILTER_SPEC_VID_UNSPEC,
- addr);
+ rc = efx_filter_spec_set_eth_local(&spec,
+ EFX_FILTER_SPEC_VID_UNSPEC, addr);
+ if ((rc != 0) && (rollback == B_TRUE)) {
+ /* Only stop upon failure if told to rollback */
+ goto rollback;
+ }
rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
&filter_index);
efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
filter_flags,
eftp->eft_default_rxq);
- efx_filter_spec_set_mc_def(&spec);
+ rc = efx_filter_spec_set_mc_def(&spec);
+ if (rc != 0)
+ goto fail1;
rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
&eftp->eft_mulcst_filter_indexes[0]);
if (rc != 0)
- goto fail1;
+ goto fail2;
eftp->eft_mulcst_filter_count = 1;
eftp->eft_using_all_mulcst = B_TRUE;
return (0);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
/*
* Insert or renew unicast filters.
*
- * Frimware does not perform chaining on unicast filters. As traffic is
+ * Firmware does not perform chaining on unicast filters. As traffic is
* therefore only delivered to the first matching filter, we should
* always insert the specific filter for our MAC address, to try and
* ensure we get that traffic.
#endif /* EFSYS_OPT_FILTER */
-#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
+#endif /* EFX_OPTS_EF10() */