1227569Sphilip/*-
2284555Sarybchik * Copyright (c) 2009-2015 Solarflare Communications Inc.
3284555Sarybchik * All rights reserved.
4227569Sphilip *
5227569Sphilip * Redistribution and use in source and binary forms, with or without
6284555Sarybchik * modification, are permitted provided that the following conditions are met:
7227569Sphilip *
8284555Sarybchik * 1. Redistributions of source code must retain the above copyright notice,
9284555Sarybchik *    this list of conditions and the following disclaimer.
10284555Sarybchik * 2. Redistributions in binary form must reproduce the above copyright notice,
11284555Sarybchik *    this list of conditions and the following disclaimer in the documentation
12284555Sarybchik *    and/or other materials provided with the distribution.
13284555Sarybchik *
14284555Sarybchik * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15284555Sarybchik * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16284555Sarybchik * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17284555Sarybchik * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18284555Sarybchik * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19284555Sarybchik * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20284555Sarybchik * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21284555Sarybchik * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22284555Sarybchik * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23284555Sarybchik * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24284555Sarybchik * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25284555Sarybchik *
26284555Sarybchik * The views and conclusions contained in the software and documentation are
27284555Sarybchik * those of the authors and should not be interpreted as representing official
28284555Sarybchik * policies, either expressed or implied, of the FreeBSD Project.
29227569Sphilip */
30227569Sphilip
31228078Sphilip#include <sys/cdefs.h>
32228078Sphilip__FBSDID("$FreeBSD: releng/10.3/sys/dev/sfxge/common/efx_wol.c 294016 2016-01-14 16:27:43Z arybchik $");
33228078Sphilip
34227569Sphilip#include "efx.h"
35227569Sphilip#include "efx_impl.h"
36227569Sphilip
37227569Sphilip#if EFSYS_OPT_WOL
38227569Sphilip
39293927Sarybchik	__checkReturn	efx_rc_t
40227569Sphilipefx_wol_init(
41227569Sphilip	__in		efx_nic_t *enp)
42227569Sphilip{
43227569Sphilip	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
44293927Sarybchik	efx_rc_t rc;
45227569Sphilip
46227569Sphilip	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
47227569Sphilip	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
48227569Sphilip	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_WOL));
49227569Sphilip
50227569Sphilip	if (~(encp->enc_features) & EFX_FEATURE_WOL) {
51227569Sphilip		rc = ENOTSUP;
52227569Sphilip		goto fail1;
53227569Sphilip	}
54227569Sphilip
55227569Sphilip	/* Current implementation is Siena specific */
56227569Sphilip	EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
57227569Sphilip
58227569Sphilip	enp->en_mod_flags |= EFX_MOD_WOL;
59227569Sphilip
60227569Sphilip	return (0);
61227569Sphilip
62227569Sphilipfail1:
63293927Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
64227569Sphilip
65227569Sphilip	return (rc);
66227569Sphilip}
67227569Sphilip
68293927Sarybchik	__checkReturn	efx_rc_t
69227569Sphilipefx_wol_filter_clear(
70227569Sphilip	__in		efx_nic_t *enp)
71227569Sphilip{
72227569Sphilip	efx_mcdi_req_t req;
73284555Sarybchik	uint8_t payload[MAX(MC_CMD_WOL_FILTER_RESET_IN_LEN,
74284555Sarybchik			    MC_CMD_WOL_FILTER_RESET_OUT_LEN)];
75293927Sarybchik	efx_rc_t rc;
76227569Sphilip
77227569Sphilip	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
78227569Sphilip	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
79227569Sphilip
80284555Sarybchik	(void) memset(payload, 0, sizeof (payload));
81227569Sphilip	req.emr_cmd = MC_CMD_WOL_FILTER_RESET;
82227569Sphilip	req.emr_in_buf = payload;
83227569Sphilip	req.emr_in_length = MC_CMD_WOL_FILTER_RESET_IN_LEN;
84284555Sarybchik	req.emr_out_buf = payload;
85284555Sarybchik	req.emr_out_length = MC_CMD_WOL_FILTER_RESET_OUT_LEN;
86227569Sphilip
87227569Sphilip	MCDI_IN_SET_DWORD(req, WOL_FILTER_RESET_IN_MASK,
88227569Sphilip			    MC_CMD_WOL_FILTER_RESET_IN_WAKE_FILTERS |
89227569Sphilip			    MC_CMD_WOL_FILTER_RESET_IN_LIGHTSOUT_OFFLOADS);
90227569Sphilip
91227569Sphilip	efx_mcdi_execute(enp, &req);
92227569Sphilip
93227569Sphilip	if (req.emr_rc != 0) {
94227569Sphilip		rc = req.emr_rc;
95227569Sphilip		goto fail1;
96227569Sphilip	}
97227569Sphilip
98227569Sphilip	return (0);
99227569Sphilip
100227569Sphilipfail1:
101293927Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
102227569Sphilip
103227569Sphilip	return (rc);
104227569Sphilip}
105227569Sphilip
106293927Sarybchik	__checkReturn	efx_rc_t
107227569Sphilipefx_wol_filter_add(
108227569Sphilip	__in		efx_nic_t *enp,
109227569Sphilip	__in		efx_wol_type_t type,
110227569Sphilip	__in		efx_wol_param_t *paramp,
111227569Sphilip	__out		uint32_t *filter_idp)
112227569Sphilip{
113227569Sphilip	efx_mcdi_req_t req;
114227569Sphilip	uint8_t payload[MAX(MC_CMD_WOL_FILTER_SET_IN_LEN,
115227569Sphilip			    MC_CMD_WOL_FILTER_SET_OUT_LEN)];
116227569Sphilip	efx_byte_t link_mask;
117293927Sarybchik	efx_rc_t rc;
118227569Sphilip
119227569Sphilip	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
120227569Sphilip	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
121227569Sphilip
122284555Sarybchik	(void) memset(payload, 0, sizeof (payload));
123227569Sphilip	req.emr_cmd = MC_CMD_WOL_FILTER_SET;
124227569Sphilip	req.emr_in_buf = payload;
125227569Sphilip	req.emr_in_length = MC_CMD_WOL_FILTER_SET_IN_LEN;
126227569Sphilip	req.emr_out_buf = payload;
127227569Sphilip	req.emr_out_length = MC_CMD_WOL_FILTER_SET_OUT_LEN;
128227569Sphilip
129227569Sphilip	switch (type) {
130227569Sphilip	case EFX_WOL_TYPE_MAGIC:
131227569Sphilip		MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_FILTER_MODE,
132227569Sphilip				    MC_CMD_FILTER_MODE_SIMPLE);
133227569Sphilip		MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_WOL_TYPE,
134227569Sphilip				    MC_CMD_WOL_TYPE_MAGIC);
135227569Sphilip		EFX_MAC_ADDR_COPY(
136227569Sphilip			MCDI_IN2(req, uint8_t, WOL_FILTER_SET_IN_MAGIC_MAC),
137227569Sphilip			paramp->ewp_magic.mac_addr);
138227569Sphilip		break;
139227569Sphilip
140227569Sphilip	case EFX_WOL_TYPE_BITMAP: {
141227569Sphilip		uint32_t swapped = 0;
142227569Sphilip		efx_dword_t *dwordp;
143227569Sphilip		unsigned int pos, bit;
144227569Sphilip
145227569Sphilip		MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_FILTER_MODE,
146227569Sphilip				    MC_CMD_FILTER_MODE_SIMPLE);
147227569Sphilip		MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_WOL_TYPE,
148227569Sphilip				    MC_CMD_WOL_TYPE_BITMAP);
149227569Sphilip
150227569Sphilip		/*
151227569Sphilip		 * MC bitmask is supposed to be bit swapped
152227569Sphilip		 * amongst 32 bit words(!)
153227569Sphilip		 */
154227569Sphilip
155227569Sphilip		dwordp = MCDI_IN2(req, efx_dword_t,
156227569Sphilip				    WOL_FILTER_SET_IN_BITMAP_MASK);
157227569Sphilip
158227569Sphilip		EFSYS_ASSERT3U(EFX_WOL_BITMAP_MASK_SIZE % 4, ==, 0);
159227569Sphilip
160227569Sphilip		for (pos = 0; pos < EFX_WOL_BITMAP_MASK_SIZE; ++pos) {
161227569Sphilip			uint8_t native = paramp->ewp_bitmap.mask[pos];
162227569Sphilip
163227569Sphilip			for (bit = 0; bit < 8; ++bit) {
164227569Sphilip				swapped <<= 1;
165227569Sphilip				swapped |= (native & 0x1);
166227569Sphilip				native >>= 1;
167227569Sphilip			}
168227569Sphilip
169227569Sphilip			if ((pos & 3) == 3) {
170227569Sphilip				EFX_POPULATE_DWORD_1(dwordp[pos >> 2],
171227569Sphilip				    EFX_DWORD_0, swapped);
172227569Sphilip				swapped = 0;
173227569Sphilip			}
174227569Sphilip		}
175227569Sphilip
176227569Sphilip		memcpy(MCDI_IN2(req, uint8_t, WOL_FILTER_SET_IN_BITMAP_BITMAP),
177227569Sphilip		    paramp->ewp_bitmap.value,
178227569Sphilip		    sizeof (paramp->ewp_bitmap.value));
179227569Sphilip
180227569Sphilip		EFSYS_ASSERT3U(paramp->ewp_bitmap.value_len, <=,
181227569Sphilip				    sizeof (paramp->ewp_bitmap.value));
182227569Sphilip		MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_BITMAP_LEN,
183227569Sphilip				    paramp->ewp_bitmap.value_len);
184227569Sphilip		}
185227569Sphilip		break;
186227569Sphilip
187227569Sphilip	case EFX_WOL_TYPE_LINK:
188227569Sphilip		MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_FILTER_MODE,
189227569Sphilip				    MC_CMD_FILTER_MODE_SIMPLE);
190227569Sphilip		MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_WOL_TYPE,
191227569Sphilip				    MC_CMD_WOL_TYPE_LINK);
192227569Sphilip
193227569Sphilip		EFX_ZERO_BYTE(link_mask);
194227569Sphilip		EFX_SET_BYTE_FIELD(link_mask, MC_CMD_WOL_FILTER_SET_IN_LINK_UP,
195227569Sphilip		    1);
196227569Sphilip		MCDI_IN_SET_BYTE(req, WOL_FILTER_SET_IN_LINK_MASK,
197227569Sphilip		    link_mask.eb_u8[0]);
198227569Sphilip		break;
199227569Sphilip
200227569Sphilip	default:
201227569Sphilip		EFSYS_ASSERT3U(type, !=, type);
202227569Sphilip	}
203227569Sphilip
204227569Sphilip	efx_mcdi_execute(enp, &req);
205227569Sphilip
206227569Sphilip	if (req.emr_rc != 0) {
207227569Sphilip		rc = req.emr_rc;
208227569Sphilip		goto fail1;
209227569Sphilip	}
210227569Sphilip
211227569Sphilip	if (req.emr_out_length_used < MC_CMD_WOL_FILTER_SET_OUT_LEN) {
212227569Sphilip		rc = EMSGSIZE;
213227569Sphilip		goto fail2;
214227569Sphilip	}
215227569Sphilip
216227569Sphilip	*filter_idp = MCDI_OUT_DWORD(req, WOL_FILTER_SET_OUT_FILTER_ID);
217227569Sphilip
218227569Sphilip	return (0);
219227569Sphilip
220227569Sphilipfail2:
221227569Sphilip	EFSYS_PROBE(fail2);
222227569Sphilipfail1:
223293927Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
224227569Sphilip
225227569Sphilip	return (rc);
226227569Sphilip}
227227569Sphilip
228293927Sarybchik	__checkReturn	efx_rc_t
229227569Sphilipefx_wol_filter_remove(
230227569Sphilip	__in		efx_nic_t *enp,
231227569Sphilip	__in		uint32_t filter_id)
232227569Sphilip{
233227569Sphilip	efx_mcdi_req_t req;
234284555Sarybchik	uint8_t payload[MAX(MC_CMD_WOL_FILTER_REMOVE_IN_LEN,
235284555Sarybchik			    MC_CMD_WOL_FILTER_REMOVE_OUT_LEN)];
236293927Sarybchik	efx_rc_t rc;
237227569Sphilip
238227569Sphilip	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
239227569Sphilip	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
240227569Sphilip
241284555Sarybchik	(void) memset(payload, 0, sizeof (payload));
242227569Sphilip	req.emr_cmd = MC_CMD_WOL_FILTER_REMOVE;
243227569Sphilip	req.emr_in_buf = payload;
244227569Sphilip	req.emr_in_length = MC_CMD_WOL_FILTER_REMOVE_IN_LEN;
245284555Sarybchik	req.emr_out_buf = payload;
246284555Sarybchik	req.emr_out_length = MC_CMD_WOL_FILTER_REMOVE_OUT_LEN;
247227569Sphilip
248227569Sphilip	MCDI_IN_SET_DWORD(req, WOL_FILTER_REMOVE_IN_FILTER_ID, filter_id);
249227569Sphilip
250227569Sphilip	efx_mcdi_execute(enp, &req);
251227569Sphilip
252227569Sphilip	if (req.emr_rc != 0) {
253227569Sphilip		rc = req.emr_rc;
254227569Sphilip		goto fail1;
255227569Sphilip	}
256227569Sphilip
257227569Sphilip	return (0);
258227569Sphilip
259227569Sphilipfail1:
260293927Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
261227569Sphilip
262227569Sphilip	return (rc);
263227569Sphilip}
264227569Sphilip
265227569Sphilip
266293927Sarybchik	__checkReturn	efx_rc_t
267227569Sphilipefx_lightsout_offload_add(
268227569Sphilip	__in		efx_nic_t *enp,
269227569Sphilip	__in		efx_lightsout_offload_type_t type,
270227569Sphilip	__in		efx_lightsout_offload_param_t *paramp,
271227569Sphilip	__out		uint32_t *filter_idp)
272227569Sphilip{
273227569Sphilip	efx_mcdi_req_t req;
274227569Sphilip	uint8_t payload[MAX(MAX(MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_LEN,
275227569Sphilip				MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_LEN),
276227569Sphilip			    MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN)];
277293927Sarybchik	efx_rc_t rc;
278227569Sphilip
279227569Sphilip	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
280227569Sphilip	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
281227569Sphilip
282284555Sarybchik	(void) memset(payload, 0, sizeof (payload));
283227569Sphilip	req.emr_cmd = MC_CMD_ADD_LIGHTSOUT_OFFLOAD;
284227569Sphilip	req.emr_in_buf = payload;
285227569Sphilip	req.emr_in_length = sizeof (type);
286227569Sphilip	req.emr_out_buf = payload;
287227569Sphilip	req.emr_out_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN;
288227569Sphilip
289227569Sphilip	switch (type) {
290227569Sphilip	case EFX_LIGHTSOUT_OFFLOAD_TYPE_ARP:
291227569Sphilip		req.emr_in_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_LEN;
292284555Sarybchik
293227569Sphilip		MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL,
294227569Sphilip				    MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP);
295227569Sphilip		EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t,
296227569Sphilip					    ADD_LIGHTSOUT_OFFLOAD_IN_ARP_MAC),
297227569Sphilip				    paramp->elop_arp.mac_addr);
298227569Sphilip		MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_ARP_IP,
299227569Sphilip				    paramp->elop_arp.ip);
300227569Sphilip		break;
301227569Sphilip	case EFX_LIGHTSOUT_OFFLOAD_TYPE_NS:
302227569Sphilip		req.emr_in_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_LEN;
303284555Sarybchik
304227569Sphilip		MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL,
305227569Sphilip				    MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS);
306227569Sphilip		EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t,
307227569Sphilip					    ADD_LIGHTSOUT_OFFLOAD_IN_NS_MAC),
308227569Sphilip				    paramp->elop_ns.mac_addr);
309227569Sphilip		memcpy(MCDI_IN2(req, uint8_t,
310227569Sphilip		    ADD_LIGHTSOUT_OFFLOAD_IN_NS_SNIPV6),
311227569Sphilip		    paramp->elop_ns.solicited_node,
312227569Sphilip		    sizeof (paramp->elop_ns.solicited_node));
313227569Sphilip		memcpy(MCDI_IN2(req, uint8_t, ADD_LIGHTSOUT_OFFLOAD_IN_NS_IPV6),
314227569Sphilip		    paramp->elop_ns.ip, sizeof (paramp->elop_ns.ip));
315227569Sphilip		break;
316227569Sphilip	default:
317284555Sarybchik		rc = EINVAL;
318284555Sarybchik		goto fail1;
319227569Sphilip	}
320227569Sphilip
321227569Sphilip	efx_mcdi_execute(enp, &req);
322227569Sphilip
323227569Sphilip	if (req.emr_rc != 0) {
324227569Sphilip		rc = req.emr_rc;
325284555Sarybchik		goto fail2;
326227569Sphilip	}
327227569Sphilip
328227569Sphilip	if (req.emr_out_length_used < MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN) {
329227569Sphilip		rc = EMSGSIZE;
330284555Sarybchik		goto fail3;
331227569Sphilip	}
332227569Sphilip
333227569Sphilip	*filter_idp = MCDI_OUT_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_OUT_FILTER_ID);
334227569Sphilip
335227569Sphilip	return (0);
336227569Sphilip
337284555Sarybchikfail3:
338284555Sarybchik	EFSYS_PROBE(fail3);
339227569Sphilipfail2:
340227569Sphilip	EFSYS_PROBE(fail2);
341227569Sphilipfail1:
342293927Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
343227569Sphilip
344227569Sphilip	return (rc);
345227569Sphilip}
346227569Sphilip
347227569Sphilip
348293927Sarybchik	__checkReturn	efx_rc_t
349227569Sphilipefx_lightsout_offload_remove(
350227569Sphilip	__in		efx_nic_t *enp,
351227569Sphilip	__in		efx_lightsout_offload_type_t type,
352227569Sphilip	__in		uint32_t filter_id)
353227569Sphilip{
354227569Sphilip	efx_mcdi_req_t req;
355284555Sarybchik	uint8_t payload[MAX(MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN,
356284555Sarybchik			    MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN)];
357293927Sarybchik	efx_rc_t rc;
358227569Sphilip
359227569Sphilip	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
360227569Sphilip	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
361227569Sphilip
362284555Sarybchik	(void) memset(payload, 0, sizeof (payload));
363227569Sphilip	req.emr_cmd = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD;
364227569Sphilip	req.emr_in_buf = payload;
365284555Sarybchik	req.emr_in_length = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN;
366284555Sarybchik	req.emr_out_buf = payload;
367284555Sarybchik	req.emr_out_length = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN;
368227569Sphilip
369227569Sphilip	switch (type) {
370227569Sphilip	case EFX_LIGHTSOUT_OFFLOAD_TYPE_ARP:
371227569Sphilip		MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL,
372227569Sphilip				    MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP);
373227569Sphilip		break;
374227569Sphilip	case EFX_LIGHTSOUT_OFFLOAD_TYPE_NS:
375227569Sphilip		MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL,
376227569Sphilip				    MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS);
377227569Sphilip		break;
378227569Sphilip	default:
379284555Sarybchik		rc = EINVAL;
380284555Sarybchik		goto fail1;
381227569Sphilip	}
382227569Sphilip
383227569Sphilip	MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_FILTER_ID,
384227569Sphilip			    filter_id);
385227569Sphilip
386227569Sphilip	efx_mcdi_execute(enp, &req);
387227569Sphilip
388227569Sphilip	if (req.emr_rc != 0) {
389227569Sphilip		rc = req.emr_rc;
390284555Sarybchik		goto fail2;
391227569Sphilip	}
392227569Sphilip
393227569Sphilip	return (0);
394227569Sphilip
395284555Sarybchikfail2:
396284555Sarybchik	EFSYS_PROBE(fail2);
397227569Sphilipfail1:
398293927Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
399227569Sphilip
400227569Sphilip	return (rc);
401227569Sphilip}
402227569Sphilip
403227569Sphilip
404227569Sphilip			void
405227569Sphilipefx_wol_fini(
406227569Sphilip	__in		efx_nic_t *enp)
407227569Sphilip{
408227569Sphilip	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
409227569Sphilip	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
410227569Sphilip	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
411227569Sphilip
412227569Sphilip	enp->en_mod_flags &= ~EFX_MOD_WOL;
413227569Sphilip}
414227569Sphilip
415227569Sphilip#endif	/* EFSYS_OPT_WOL */
416