Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/sfxge/common/ef10_filter.c
Show First 20 Lines • Show All 1,228 Lines • ▼ Show 20 Lines | ef10_filter_insert_all_multicast( | ||||
return (0); | return (0); | ||||
fail1: | fail1: | ||||
EFSYS_PROBE1(fail1, efx_rc_t, rc); | EFSYS_PROBE1(fail1, efx_rc_t, rc); | ||||
return (rc); | return (rc); | ||||
} | } | ||||
typedef struct ef10_filter_encap_entry_s { | |||||
uint16_t ether_type; | |||||
efx_tunnel_protocol_t encap_type; | |||||
uint32_t inner_frame_match; | |||||
} ef10_filter_encap_entry_t; | |||||
#define EF10_ENCAP_FILTER_ENTRY(ipv, encap_type, inner_frame_match) \ | |||||
{ EFX_ETHER_TYPE_##ipv, EFX_TUNNEL_PROTOCOL_##encap_type, \ | |||||
EFX_FILTER_INNER_FRAME_MATCH_UNKNOWN_##inner_frame_match } | |||||
static ef10_filter_encap_entry_t ef10_filter_encap_list[] = { | |||||
EF10_ENCAP_FILTER_ENTRY(IPV4, VXLAN, UCAST_DST), | |||||
EF10_ENCAP_FILTER_ENTRY(IPV4, VXLAN, MCAST_DST), | |||||
EF10_ENCAP_FILTER_ENTRY(IPV6, VXLAN, UCAST_DST), | |||||
EF10_ENCAP_FILTER_ENTRY(IPV6, VXLAN, MCAST_DST), | |||||
EF10_ENCAP_FILTER_ENTRY(IPV4, GENEVE, UCAST_DST), | |||||
EF10_ENCAP_FILTER_ENTRY(IPV4, GENEVE, MCAST_DST), | |||||
EF10_ENCAP_FILTER_ENTRY(IPV6, GENEVE, UCAST_DST), | |||||
EF10_ENCAP_FILTER_ENTRY(IPV6, GENEVE, MCAST_DST), | |||||
EF10_ENCAP_FILTER_ENTRY(IPV4, NVGRE, UCAST_DST), | |||||
EF10_ENCAP_FILTER_ENTRY(IPV4, NVGRE, MCAST_DST), | |||||
EF10_ENCAP_FILTER_ENTRY(IPV6, NVGRE, UCAST_DST), | |||||
EF10_ENCAP_FILTER_ENTRY(IPV6, NVGRE, MCAST_DST), | |||||
}; | |||||
#undef EF10_ENCAP_FILTER_ENTRY | |||||
static __checkReturn efx_rc_t | |||||
ef10_filter_insert_encap_filters( | |||||
__in efx_nic_t *enp, | |||||
__in boolean_t mulcst, | |||||
__in efx_filter_flags_t filter_flags) | |||||
{ | |||||
ef10_filter_table_t *table = enp->en_filter.ef_ef10_filter_table; | |||||
uint32_t i; | |||||
efx_rc_t rc; | |||||
EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(ef10_filter_encap_list) <= | |||||
EFX_ARRAY_SIZE(table->eft_encap_filter_indexes)); | |||||
/* | |||||
* On Medford, full-featured firmware can identify packets as being | |||||
* tunnel encapsulated, even if no encapsulated packet offloads are in | |||||
* use. When packets are identified as such, ordinary filters are not | |||||
* applied, only ones specific to encapsulated packets. Hence we need to | |||||
* insert filters for encapsulated packets in order to receive them. | |||||
* | |||||
* Separate filters need to be inserted for each ether type, | |||||
* encapsulation type, and inner frame type (unicast or multicast). To | |||||
* keep things simple and reduce the number of filters needed, catch-all | |||||
* filters for all combinations of types are inserted, even if | |||||
* all_unicst or all_mulcst have not been set. (These catch-all filters | |||||
* may well, however, fail to insert on unprivileged functions.) | |||||
*/ | |||||
table->eft_encap_filter_count = 0; | |||||
for (i = 0; i < EFX_ARRAY_SIZE(ef10_filter_encap_list); i++) { | |||||
efx_filter_spec_t spec; | |||||
ef10_filter_encap_entry_t *encap_filter = | |||||
&ef10_filter_encap_list[i]; | |||||
/* | |||||
* Skip multicast filters if we've not been asked for | |||||
* any multicast traffic. | |||||
*/ | |||||
if ((mulcst == B_FALSE) && | |||||
(encap_filter->inner_frame_match == | |||||
EFX_FILTER_INNER_FRAME_MATCH_UNKNOWN_MCAST_DST)) | |||||
continue; | |||||
efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO, | |||||
filter_flags, | |||||
table->eft_default_rxq); | |||||
efx_filter_spec_set_ether_type(&spec, encap_filter->ether_type); | |||||
rc = efx_filter_spec_set_encap_type(&spec, | |||||
encap_filter->encap_type, | |||||
encap_filter->inner_frame_match); | |||||
if (rc != 0) | |||||
goto fail1; | |||||
rc = ef10_filter_add_internal(enp, &spec, B_TRUE, | |||||
&table->eft_encap_filter_indexes[ | |||||
table->eft_encap_filter_count]); | |||||
if (rc != 0) { | |||||
if (rc != EACCES) | |||||
goto fail2; | |||||
} else { | |||||
table->eft_encap_filter_count++; | |||||
} | |||||
} | |||||
return (0); | |||||
fail2: | |||||
EFSYS_PROBE(fail2); | |||||
fail1: | |||||
EFSYS_PROBE1(fail1, efx_rc_t, rc); | |||||
return (rc); | |||||
} | |||||
static void | static void | ||||
ef10_filter_remove_old( | ef10_filter_remove_old( | ||||
__in efx_nic_t *enp) | __in efx_nic_t *enp) | ||||
{ | { | ||||
ef10_filter_table_t *table = enp->en_filter.ef_ef10_filter_table; | ef10_filter_table_t *table = enp->en_filter.ef_ef10_filter_table; | ||||
uint32_t i; | uint32_t i; | ||||
for (i = 0; i < EFX_ARRAY_SIZE(table->eft_entry); i++) { | for (i = 0; i < EFX_ARRAY_SIZE(table->eft_entry); i++) { | ||||
▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | if (table->eft_default_rxq == NULL) { | ||||
table->eft_unicst_filter_count = 0; | table->eft_unicst_filter_count = 0; | ||||
for (i = 0; i < table->eft_mulcst_filter_count; i++) { | for (i = 0; i < table->eft_mulcst_filter_count; i++) { | ||||
(void) ef10_filter_delete_internal(enp, | (void) ef10_filter_delete_internal(enp, | ||||
table->eft_mulcst_filter_indexes[i]); | table->eft_mulcst_filter_indexes[i]); | ||||
} | } | ||||
table->eft_mulcst_filter_count = 0; | table->eft_mulcst_filter_count = 0; | ||||
for (i = 0; i < table->eft_encap_filter_count; i++) { | |||||
(void) ef10_filter_delete_internal(enp, | |||||
table->eft_encap_filter_indexes[i]); | |||||
} | |||||
table->eft_encap_filter_count = 0; | |||||
return (0); | return (0); | ||||
} | } | ||||
if (table->eft_using_rss) | if (table->eft_using_rss) | ||||
filter_flags = EFX_FILTER_FLAG_RX_RSS; | filter_flags = EFX_FILTER_FLAG_RX_RSS; | ||||
else | else | ||||
filter_flags = 0; | filter_flags = 0; | ||||
/* Mark old filters which may need to be removed */ | /* Mark old filters which may need to be removed */ | ||||
for (i = 0; i < table->eft_unicst_filter_count; i++) { | for (i = 0; i < table->eft_unicst_filter_count; i++) { | ||||
ef10_filter_set_entry_auto_old(table, | ef10_filter_set_entry_auto_old(table, | ||||
table->eft_unicst_filter_indexes[i]); | table->eft_unicst_filter_indexes[i]); | ||||
} | } | ||||
for (i = 0; i < table->eft_mulcst_filter_count; i++) { | for (i = 0; i < table->eft_mulcst_filter_count; i++) { | ||||
ef10_filter_set_entry_auto_old(table, | ef10_filter_set_entry_auto_old(table, | ||||
table->eft_mulcst_filter_indexes[i]); | table->eft_mulcst_filter_indexes[i]); | ||||
} | } | ||||
for (i = 0; i < table->eft_encap_filter_count; i++) { | |||||
ef10_filter_set_entry_auto_old(table, | |||||
table->eft_encap_filter_indexes[i]); | |||||
} | |||||
/* | /* | ||||
* Insert or renew unicast filters. | * Insert or renew unicast filters. | ||||
* | * | ||||
* Frimware does not perform chaining on unicast filters. As traffic is | * Frimware does not perform chaining on unicast filters. As traffic is | ||||
* therefore only delivered to the first matching filter, we should | * therefore only delivered to the first matching filter, we should | ||||
* always insert the specific filter for our MAC address, to try and | * always insert the specific filter for our MAC address, to try and | ||||
* ensure we get that traffic. | * ensure we get that traffic. | ||||
▲ Show 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | if (rc != 0) { | ||||
if (rc != 0) { | if (rc != 0) { | ||||
rc = ef10_filter_insert_multicast_list(enp, | rc = ef10_filter_insert_multicast_list(enp, | ||||
mulcst, brdcst, | mulcst, brdcst, | ||||
addrs, count, filter_flags, B_FALSE); | addrs, count, filter_flags, B_FALSE); | ||||
if (rc != 0) | if (rc != 0) | ||||
goto fail4; | goto fail4; | ||||
} | } | ||||
} | } | ||||
} | |||||
if (encp->enc_tunnel_encapsulations_supported != 0) { | |||||
/* Try to insert filters for encapsulated packets. */ | |||||
(void) ef10_filter_insert_encap_filters(enp, | |||||
mulcst || all_mulcst || brdcst, | |||||
filter_flags); | |||||
} | } | ||||
/* Remove old filters which were not renewed */ | /* Remove old filters which were not renewed */ | ||||
ef10_filter_remove_old(enp); | ef10_filter_remove_old(enp); | ||||
/* report if any optional flags were rejected */ | /* report if any optional flags were rejected */ | ||||
if (((all_unicst != B_FALSE) && (all_unicst_rc != 0)) || | if (((all_unicst != B_FALSE) && (all_unicst_rc != 0)) || | ||||
((all_mulcst != B_FALSE) && (all_mulcst_rc != 0))) { | ((all_mulcst != B_FALSE) && (all_mulcst_rc != 0))) { | ||||
▲ Show 20 Lines • Show All 70 Lines • Show Last 20 Lines |