2 * Copyright (c) 2007-2016 Solarflare Communications Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * The views and conclusions contained in the software and documentation are
27 * those of the authors and should not be interpreted as representing official
28 * policies, either expressed or implied, of the FreeBSD Project.
37 __checkReturn efx_rc_t
40 __inout efx_filter_spec_t *spec)
42 const efx_filter_ops_t *efop = enp->en_efop;
44 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
45 EFSYS_ASSERT3P(spec, !=, NULL);
46 EFSYS_ASSERT3U(spec->efs_flags, &, EFX_FILTER_FLAG_RX);
48 return (efop->efo_add(enp, spec, B_FALSE));
51 __checkReturn efx_rc_t
54 __inout efx_filter_spec_t *spec)
56 const efx_filter_ops_t *efop = enp->en_efop;
58 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
59 EFSYS_ASSERT3P(spec, !=, NULL);
60 EFSYS_ASSERT3U(spec->efs_flags, &, EFX_FILTER_FLAG_RX);
62 return (efop->efo_delete(enp, spec));
65 __checkReturn efx_rc_t
71 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
73 if ((rc = enp->en_efop->efo_restore(enp)) != 0)
79 EFSYS_PROBE1(fail1, efx_rc_t, rc);
84 __checkReturn efx_rc_t
88 const efx_filter_ops_t *efop;
91 /* Check that efx_filter_spec_t is 64 bytes. */
92 EFX_STATIC_ASSERT(sizeof (efx_filter_spec_t) == 64);
94 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
95 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
96 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_FILTER));
98 switch (enp->en_family) {
106 if ((rc = efop->efo_init(enp)) != 0)
110 enp->en_mod_flags |= EFX_MOD_FILTER;
116 EFSYS_PROBE1(fail1, efx_rc_t, rc);
119 enp->en_mod_flags &= ~EFX_MOD_FILTER;
127 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
128 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
129 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
131 enp->en_efop->efo_fini(enp);
134 enp->en_mod_flags &= ~EFX_MOD_FILTER;
137 __checkReturn efx_rc_t
138 efx_filter_supported_filters(
140 __out uint32_t *list,
141 __out size_t *length)
145 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
146 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
147 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
148 EFSYS_ASSERT(enp->en_efop->efo_supported_filters != NULL);
150 if ((rc = enp->en_efop->efo_supported_filters(enp, list, length)) != 0)
156 EFSYS_PROBE1(fail1, efx_rc_t, rc);
161 __checkReturn efx_rc_t
162 efx_filter_reconfigure(
164 __in_ecount(6) uint8_t const *mac_addr,
165 __in boolean_t all_unicst,
166 __in boolean_t mulcst,
167 __in boolean_t all_mulcst,
168 __in boolean_t brdcst,
169 __in_ecount(6*count) uint8_t const *addrs,
174 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
175 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
176 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
178 if (enp->en_efop->efo_reconfigure != NULL) {
179 if ((rc = enp->en_efop->efo_reconfigure(enp, mac_addr,
189 EFSYS_PROBE1(fail1, efx_rc_t, rc);
195 efx_filter_spec_init_rx(
196 __out efx_filter_spec_t *spec,
197 __in efx_filter_priority_t priority,
198 __in efx_filter_flags_t flags,
201 EFSYS_ASSERT3P(spec, !=, NULL);
202 EFSYS_ASSERT3P(erp, !=, NULL);
203 EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS |
204 EFX_FILTER_FLAG_RX_SCATTER)) == 0);
206 memset(spec, 0, sizeof (*spec));
207 spec->efs_priority = priority;
208 spec->efs_flags = EFX_FILTER_FLAG_RX | flags;
209 spec->efs_rss_context = EFX_FILTER_SPEC_RSS_CONTEXT_DEFAULT;
210 spec->efs_dmaq_id = (uint16_t)erp->er_index;
214 efx_filter_spec_init_tx(
215 __out efx_filter_spec_t *spec,
218 EFSYS_ASSERT3P(spec, !=, NULL);
219 EFSYS_ASSERT3P(etp, !=, NULL);
221 memset(spec, 0, sizeof (*spec));
222 spec->efs_priority = EFX_FILTER_PRI_REQUIRED;
223 spec->efs_flags = EFX_FILTER_FLAG_TX;
224 spec->efs_dmaq_id = (uint16_t)etp->et_index;
229 * Specify IPv4 host, transport protocol and port in a filter specification
231 __checkReturn efx_rc_t
232 efx_filter_spec_set_ipv4_local(
233 __inout efx_filter_spec_t *spec,
238 EFSYS_ASSERT3P(spec, !=, NULL);
240 spec->efs_match_flags |=
241 EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
242 EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT;
243 spec->efs_ether_type = EFX_ETHER_TYPE_IPV4;
244 spec->efs_ip_proto = proto;
245 spec->efs_loc_host.eo_u32[0] = host;
246 spec->efs_loc_port = port;
251 * Specify IPv4 hosts, transport protocol and ports in a filter specification
253 __checkReturn efx_rc_t
254 efx_filter_spec_set_ipv4_full(
255 __inout efx_filter_spec_t *spec,
262 EFSYS_ASSERT3P(spec, !=, NULL);
264 spec->efs_match_flags |=
265 EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
266 EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT |
267 EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT;
268 spec->efs_ether_type = EFX_ETHER_TYPE_IPV4;
269 spec->efs_ip_proto = proto;
270 spec->efs_loc_host.eo_u32[0] = lhost;
271 spec->efs_loc_port = lport;
272 spec->efs_rem_host.eo_u32[0] = rhost;
273 spec->efs_rem_port = rport;
278 * Specify local Ethernet address and/or VID in filter specification
280 __checkReturn efx_rc_t
281 efx_filter_spec_set_eth_local(
282 __inout efx_filter_spec_t *spec,
284 __in const uint8_t *addr)
286 EFSYS_ASSERT3P(spec, !=, NULL);
287 EFSYS_ASSERT3P(addr, !=, NULL);
289 if (vid == EFX_FILTER_SPEC_VID_UNSPEC && addr == NULL)
292 if (vid != EFX_FILTER_SPEC_VID_UNSPEC) {
293 spec->efs_match_flags |= EFX_FILTER_MATCH_OUTER_VID;
294 spec->efs_outer_vid = vid;
297 spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_MAC;
298 memcpy(spec->efs_loc_mac, addr, EFX_MAC_ADDR_LEN);
304 * Specify matching otherwise-unmatched unicast in a filter specification
306 __checkReturn efx_rc_t
307 efx_filter_spec_set_uc_def(
308 __inout efx_filter_spec_t *spec)
310 EFSYS_ASSERT3P(spec, !=, NULL);
312 spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_MAC_IG;
317 * Specify matching otherwise-unmatched multicast in a filter specification
319 __checkReturn efx_rc_t
320 efx_filter_spec_set_mc_def(
321 __inout efx_filter_spec_t *spec)
323 EFSYS_ASSERT3P(spec, !=, NULL);
325 spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_MAC_IG;
326 spec->efs_loc_mac[0] = 1;
332 #endif /* EFSYS_OPT_FILTER */