X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fsfc%2Fbase%2Fefx_filter.c;h=7efb380641e8495ea6a320557e6694676a622276;hb=04ab83ea5a28dc873a0959ad3cacfa9886eeec87;hp=e31accb97a947cc1df31124e7fabb2f9fbaafea7;hpb=f4642251f8df35a8738208cc0bcb238129fe934b;p=dpdk.git diff --git a/drivers/net/sfc/base/efx_filter.c b/drivers/net/sfc/base/efx_filter.c index e31accb97a..7efb380641 100644 --- a/drivers/net/sfc/base/efx_filter.c +++ b/drivers/net/sfc/base/efx_filter.c @@ -56,7 +56,7 @@ static const efx_filter_ops_t __efx_filter_siena_ops = { }; #endif /* EFSYS_OPT_SIENA */ -#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 +#if EFX_OPTS_EF10() static const efx_filter_ops_t __efx_filter_ef10_ops = { ef10_filter_init, /* efo_init */ ef10_filter_fini, /* efo_fini */ @@ -66,7 +66,7 @@ static const efx_filter_ops_t __efx_filter_ef10_ops = { ef10_filter_supported_filters, /* efo_supported_filters */ ef10_filter_reconfigure, /* efo_reconfigure */ }; -#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */ +#endif /* EFX_OPTS_EF10() */ __checkReturn efx_rc_t efx_filter_insert( @@ -74,12 +74,33 @@ efx_filter_insert( __inout efx_filter_spec_t *spec) { const efx_filter_ops_t *efop = enp->en_efop; + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + efx_rc_t rc; EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER); EFSYS_ASSERT3P(spec, !=, NULL); EFSYS_ASSERT3U(spec->efs_flags, &, EFX_FILTER_FLAG_RX); + if ((spec->efs_flags & EFX_FILTER_FLAG_ACTION_MARK) && + !encp->enc_filter_action_mark_supported) { + rc = ENOTSUP; + goto fail1; + } + + if ((spec->efs_flags & EFX_FILTER_FLAG_ACTION_FLAG) && + !encp->enc_filter_action_flag_supported) { + rc = ENOTSUP; + goto fail2; + } + return (efop->efo_add(enp, spec, B_FALSE)); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); } __checkReturn efx_rc_t @@ -418,7 +439,7 @@ efx_filter_spec_set_encap_type( __in efx_tunnel_protocol_t encap_type, __in efx_filter_inner_frame_match_t inner_frame_match) { - uint32_t match_flags = 0; + uint32_t match_flags = EFX_FILTER_MATCH_ENCAP_TYPE; uint8_t ip_proto; efx_rc_t rc; @@ -468,6 +489,111 @@ fail1: return (rc); } +/* + * Specify inner and outer Ethernet address and VNI or VSID in tunnel filter + * specification. + */ +static __checkReturn efx_rc_t +efx_filter_spec_set_tunnel( + __inout efx_filter_spec_t *spec, + __in efx_tunnel_protocol_t encap_type, + __in const uint8_t *vni_or_vsid, + __in const uint8_t *inner_addr, + __in const uint8_t *outer_addr) +{ + efx_rc_t rc; + + EFSYS_ASSERT3P(spec, !=, NULL); + EFSYS_ASSERT3P(vni_or_vsid, !=, NULL); + EFSYS_ASSERT3P(inner_addr, !=, NULL); + EFSYS_ASSERT3P(outer_addr, !=, NULL); + + switch (encap_type) { + case EFX_TUNNEL_PROTOCOL_VXLAN: + case EFX_TUNNEL_PROTOCOL_GENEVE: + case EFX_TUNNEL_PROTOCOL_NVGRE: + break; + default: + rc = EINVAL; + goto fail1; + } + + if ((inner_addr == NULL) && (outer_addr == NULL)) { + rc = EINVAL; + goto fail2; + } + + if (vni_or_vsid != NULL) { + spec->efs_match_flags |= EFX_FILTER_MATCH_VNI_OR_VSID; + memcpy(spec->efs_vni_or_vsid, vni_or_vsid, EFX_VNI_OR_VSID_LEN); + } + if (outer_addr != NULL) { + spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_MAC; + memcpy(spec->efs_loc_mac, outer_addr, EFX_MAC_ADDR_LEN); + } + if (inner_addr != NULL) { + spec->efs_match_flags |= EFX_FILTER_MATCH_IFRM_LOC_MAC; + memcpy(spec->efs_ifrm_loc_mac, inner_addr, EFX_MAC_ADDR_LEN); + } + + spec->efs_match_flags |= EFX_FILTER_MATCH_ENCAP_TYPE; + spec->efs_encap_type = encap_type; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + +/* + * Specify inner and outer Ethernet address and VNI in VXLAN filter + * specification. + */ +__checkReturn efx_rc_t +efx_filter_spec_set_vxlan( + __inout efx_filter_spec_t *spec, + __in const uint8_t *vni, + __in const uint8_t *inner_addr, + __in const uint8_t *outer_addr) +{ + return efx_filter_spec_set_tunnel(spec, EFX_TUNNEL_PROTOCOL_VXLAN, + vni, inner_addr, outer_addr); +} + +/* + * Specify inner and outer Ethernet address and VNI in Geneve filter + * specification. + */ +__checkReturn efx_rc_t +efx_filter_spec_set_geneve( + __inout efx_filter_spec_t *spec, + __in const uint8_t *vni, + __in const uint8_t *inner_addr, + __in const uint8_t *outer_addr) +{ + return efx_filter_spec_set_tunnel(spec, EFX_TUNNEL_PROTOCOL_GENEVE, + vni, inner_addr, outer_addr); +} + +/* + * Specify inner and outer Ethernet address and vsid in NVGRE filter + * specification. + */ +__checkReturn efx_rc_t +efx_filter_spec_set_nvgre( + __inout efx_filter_spec_t *spec, + __in const uint8_t *vsid, + __in const uint8_t *inner_addr, + __in const uint8_t *outer_addr) +{ + return efx_filter_spec_set_tunnel(spec, EFX_TUNNEL_PROTOCOL_NVGRE, + vsid, inner_addr, outer_addr); +} + #if EFSYS_OPT_RX_SCALE __checkReturn efx_rc_t efx_filter_spec_set_rss_context( @@ -959,6 +1085,7 @@ siena_filter_build( default: EFSYS_ASSERT(B_FALSE); + EFX_ZERO_OWORD(*filter); return (0); }