efx_wol.c revision 293927
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: stable/10/sys/dev/sfxge/common/efx_wol.c 293927 2016-01-14 14:16:26Z arybchik $");
33228078Sphilip
34227569Sphilip#include "efsys.h"
35227569Sphilip#include "efx.h"
36227569Sphilip#include "efx_types.h"
37227569Sphilip#include "efx_impl.h"
38227569Sphilip
39227569Sphilip#if EFSYS_OPT_WOL
40227569Sphilip
41293927Sarybchik	__checkReturn	efx_rc_t
42227569Sphilipefx_wol_init(
43227569Sphilip	__in		efx_nic_t *enp)
44227569Sphilip{
45227569Sphilip	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
46293927Sarybchik	efx_rc_t rc;
47227569Sphilip
48227569Sphilip	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
49227569Sphilip	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
50227569Sphilip	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_WOL));
51227569Sphilip
52227569Sphilip	if (~(encp->enc_features) & EFX_FEATURE_WOL) {
53227569Sphilip		rc = ENOTSUP;
54227569Sphilip		goto fail1;
55227569Sphilip	}
56227569Sphilip
57227569Sphilip	/* Current implementation is Siena specific */
58227569Sphilip	EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
59227569Sphilip
60227569Sphilip	enp->en_mod_flags |= EFX_MOD_WOL;
61227569Sphilip
62227569Sphilip	return (0);
63227569Sphilip
64227569Sphilipfail1:
65293927Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
66227569Sphilip
67227569Sphilip	return (rc);
68227569Sphilip}
69227569Sphilip
70293927Sarybchik	__checkReturn	efx_rc_t
71227569Sphilipefx_wol_filter_clear(
72227569Sphilip	__in		efx_nic_t *enp)
73227569Sphilip{
74227569Sphilip	efx_mcdi_req_t req;
75284555Sarybchik	uint8_t payload[MAX(MC_CMD_WOL_FILTER_RESET_IN_LEN,
76284555Sarybchik			    MC_CMD_WOL_FILTER_RESET_OUT_LEN)];
77293927Sarybchik	efx_rc_t rc;
78227569Sphilip
79227569Sphilip	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
80227569Sphilip	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
81227569Sphilip
82284555Sarybchik	(void) memset(payload, 0, sizeof (payload));
83227569Sphilip	req.emr_cmd = MC_CMD_WOL_FILTER_RESET;
84227569Sphilip	req.emr_in_buf = payload;
85227569Sphilip	req.emr_in_length = MC_CMD_WOL_FILTER_RESET_IN_LEN;
86284555Sarybchik	req.emr_out_buf = payload;
87284555Sarybchik	req.emr_out_length = MC_CMD_WOL_FILTER_RESET_OUT_LEN;
88227569Sphilip
89227569Sphilip	MCDI_IN_SET_DWORD(req, WOL_FILTER_RESET_IN_MASK,
90227569Sphilip			    MC_CMD_WOL_FILTER_RESET_IN_WAKE_FILTERS |
91227569Sphilip			    MC_CMD_WOL_FILTER_RESET_IN_LIGHTSOUT_OFFLOADS);
92227569Sphilip
93227569Sphilip	efx_mcdi_execute(enp, &req);
94227569Sphilip
95227569Sphilip	if (req.emr_rc != 0) {
96227569Sphilip		rc = req.emr_rc;
97227569Sphilip		goto fail1;
98227569Sphilip	}
99227569Sphilip
100227569Sphilip	return (0);
101227569Sphilip
102227569Sphilipfail1:
103293927Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
104227569Sphilip
105227569Sphilip	return (rc);
106227569Sphilip}
107227569Sphilip
108293927Sarybchik	__checkReturn	efx_rc_t
109227569Sphilipefx_wol_filter_add(
110227569Sphilip	__in		efx_nic_t *enp,
111227569Sphilip	__in		efx_wol_type_t type,
112227569Sphilip	__in		efx_wol_param_t *paramp,
113227569Sphilip	__out		uint32_t *filter_idp)
114227569Sphilip{
115227569Sphilip	efx_mcdi_req_t req;
116227569Sphilip	uint8_t payload[MAX(MC_CMD_WOL_FILTER_SET_IN_LEN,
117227569Sphilip			    MC_CMD_WOL_FILTER_SET_OUT_LEN)];
118227569Sphilip	efx_byte_t link_mask;
119293927Sarybchik	efx_rc_t rc;
120227569Sphilip
121227569Sphilip	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
122227569Sphilip	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
123227569Sphilip
124284555Sarybchik	(void) memset(payload, 0, sizeof (payload));
125227569Sphilip	req.emr_cmd = MC_CMD_WOL_FILTER_SET;
126227569Sphilip	req.emr_in_buf = payload;
127227569Sphilip	req.emr_in_length = MC_CMD_WOL_FILTER_SET_IN_LEN;
128227569Sphilip	req.emr_out_buf = payload;
129227569Sphilip	req.emr_out_length = MC_CMD_WOL_FILTER_SET_OUT_LEN;
130227569Sphilip
131227569Sphilip	switch (type) {
132227569Sphilip	case EFX_WOL_TYPE_MAGIC:
133227569Sphilip		MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_FILTER_MODE,
134227569Sphilip				    MC_CMD_FILTER_MODE_SIMPLE);
135227569Sphilip		MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_WOL_TYPE,
136227569Sphilip				    MC_CMD_WOL_TYPE_MAGIC);
137227569Sphilip		EFX_MAC_ADDR_COPY(
138227569Sphilip			MCDI_IN2(req, uint8_t, WOL_FILTER_SET_IN_MAGIC_MAC),
139227569Sphilip			paramp->ewp_magic.mac_addr);
140227569Sphilip		break;
141227569Sphilip
142227569Sphilip	case EFX_WOL_TYPE_BITMAP: {
143227569Sphilip		uint32_t swapped = 0;
144227569Sphilip		efx_dword_t *dwordp;
145227569Sphilip		unsigned int pos, bit;
146227569Sphilip
147227569Sphilip		MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_FILTER_MODE,
148227569Sphilip				    MC_CMD_FILTER_MODE_SIMPLE);
149227569Sphilip		MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_WOL_TYPE,
150227569Sphilip				    MC_CMD_WOL_TYPE_BITMAP);
151227569Sphilip
152227569Sphilip		/*
153227569Sphilip		 * MC bitmask is supposed to be bit swapped
154227569Sphilip		 * amongst 32 bit words(!)
155227569Sphilip		 */
156227569Sphilip
157227569Sphilip		dwordp = MCDI_IN2(req, efx_dword_t,
158227569Sphilip				    WOL_FILTER_SET_IN_BITMAP_MASK);
159227569Sphilip
160227569Sphilip		EFSYS_ASSERT3U(EFX_WOL_BITMAP_MASK_SIZE % 4, ==, 0);
161227569Sphilip
162227569Sphilip		for (pos = 0; pos < EFX_WOL_BITMAP_MASK_SIZE; ++pos) {
163227569Sphilip			uint8_t native = paramp->ewp_bitmap.mask[pos];
164227569Sphilip
165227569Sphilip			for (bit = 0; bit < 8; ++bit) {
166227569Sphilip				swapped <<= 1;
167227569Sphilip				swapped |= (native & 0x1);
168227569Sphilip				native >>= 1;
169227569Sphilip			}
170227569Sphilip
171227569Sphilip			if ((pos & 3) == 3) {
172227569Sphilip				EFX_POPULATE_DWORD_1(dwordp[pos >> 2],
173227569Sphilip				    EFX_DWORD_0, swapped);
174227569Sphilip				swapped = 0;
175227569Sphilip			}
176227569Sphilip		}
177227569Sphilip
178227569Sphilip		memcpy(MCDI_IN2(req, uint8_t, WOL_FILTER_SET_IN_BITMAP_BITMAP),
179227569Sphilip		    paramp->ewp_bitmap.value,
180227569Sphilip		    sizeof (paramp->ewp_bitmap.value));
181227569Sphilip
182227569Sphilip		EFSYS_ASSERT3U(paramp->ewp_bitmap.value_len, <=,
183227569Sphilip				    sizeof (paramp->ewp_bitmap.value));
184227569Sphilip		MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_BITMAP_LEN,
185227569Sphilip				    paramp->ewp_bitmap.value_len);
186227569Sphilip		}
187227569Sphilip		break;
188227569Sphilip
189227569Sphilip	case EFX_WOL_TYPE_LINK:
190227569Sphilip		MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_FILTER_MODE,
191227569Sphilip				    MC_CMD_FILTER_MODE_SIMPLE);
192227569Sphilip		MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_WOL_TYPE,
193227569Sphilip				    MC_CMD_WOL_TYPE_LINK);
194227569Sphilip
195227569Sphilip		EFX_ZERO_BYTE(link_mask);
196227569Sphilip		EFX_SET_BYTE_FIELD(link_mask, MC_CMD_WOL_FILTER_SET_IN_LINK_UP,
197227569Sphilip		    1);
198227569Sphilip		MCDI_IN_SET_BYTE(req, WOL_FILTER_SET_IN_LINK_MASK,
199227569Sphilip		    link_mask.eb_u8[0]);
200227569Sphilip		break;
201227569Sphilip
202227569Sphilip	default:
203227569Sphilip		EFSYS_ASSERT3U(type, !=, type);
204227569Sphilip	}
205227569Sphilip
206227569Sphilip	efx_mcdi_execute(enp, &req);
207227569Sphilip
208227569Sphilip	if (req.emr_rc != 0) {
209227569Sphilip		rc = req.emr_rc;
210227569Sphilip		goto fail1;
211227569Sphilip	}
212227569Sphilip
213227569Sphilip	if (req.emr_out_length_used < MC_CMD_WOL_FILTER_SET_OUT_LEN) {
214227569Sphilip		rc = EMSGSIZE;
215227569Sphilip		goto fail2;
216227569Sphilip	}
217227569Sphilip
218227569Sphilip	*filter_idp = MCDI_OUT_DWORD(req, WOL_FILTER_SET_OUT_FILTER_ID);
219227569Sphilip
220227569Sphilip	return (0);
221227569Sphilip
222227569Sphilipfail2:
223227569Sphilip	EFSYS_PROBE(fail2);
224227569Sphilipfail1:
225293927Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
226227569Sphilip
227227569Sphilip	return (rc);
228227569Sphilip}
229227569Sphilip
230293927Sarybchik	__checkReturn	efx_rc_t
231227569Sphilipefx_wol_filter_remove(
232227569Sphilip	__in		efx_nic_t *enp,
233227569Sphilip	__in		uint32_t filter_id)
234227569Sphilip{
235227569Sphilip	efx_mcdi_req_t req;
236284555Sarybchik	uint8_t payload[MAX(MC_CMD_WOL_FILTER_REMOVE_IN_LEN,
237284555Sarybchik			    MC_CMD_WOL_FILTER_REMOVE_OUT_LEN)];
238293927Sarybchik	efx_rc_t rc;
239227569Sphilip
240227569Sphilip	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
241227569Sphilip	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
242227569Sphilip
243284555Sarybchik	(void) memset(payload, 0, sizeof (payload));
244227569Sphilip	req.emr_cmd = MC_CMD_WOL_FILTER_REMOVE;
245227569Sphilip	req.emr_in_buf = payload;
246227569Sphilip	req.emr_in_length = MC_CMD_WOL_FILTER_REMOVE_IN_LEN;
247284555Sarybchik	req.emr_out_buf = payload;
248284555Sarybchik	req.emr_out_length = MC_CMD_WOL_FILTER_REMOVE_OUT_LEN;
249227569Sphilip
250227569Sphilip	MCDI_IN_SET_DWORD(req, WOL_FILTER_REMOVE_IN_FILTER_ID, filter_id);
251227569Sphilip
252227569Sphilip	efx_mcdi_execute(enp, &req);
253227569Sphilip
254227569Sphilip	if (req.emr_rc != 0) {
255227569Sphilip		rc = req.emr_rc;
256227569Sphilip		goto fail1;
257227569Sphilip	}
258227569Sphilip
259227569Sphilip	return (0);
260227569Sphilip
261227569Sphilipfail1:
262293927Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
263227569Sphilip
264227569Sphilip	return (rc);
265227569Sphilip}
266227569Sphilip
267227569Sphilip
268293927Sarybchik	__checkReturn	efx_rc_t
269227569Sphilipefx_lightsout_offload_add(
270227569Sphilip	__in		efx_nic_t *enp,
271227569Sphilip	__in		efx_lightsout_offload_type_t type,
272227569Sphilip	__in		efx_lightsout_offload_param_t *paramp,
273227569Sphilip	__out		uint32_t *filter_idp)
274227569Sphilip{
275227569Sphilip	efx_mcdi_req_t req;
276227569Sphilip	uint8_t payload[MAX(MAX(MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_LEN,
277227569Sphilip				MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_LEN),
278227569Sphilip			    MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN)];
279293927Sarybchik	efx_rc_t rc;
280227569Sphilip
281227569Sphilip	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
282227569Sphilip	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
283227569Sphilip
284284555Sarybchik	(void) memset(payload, 0, sizeof (payload));
285227569Sphilip	req.emr_cmd = MC_CMD_ADD_LIGHTSOUT_OFFLOAD;
286227569Sphilip	req.emr_in_buf = payload;
287227569Sphilip	req.emr_in_length = sizeof (type);
288227569Sphilip	req.emr_out_buf = payload;
289227569Sphilip	req.emr_out_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN;
290227569Sphilip
291227569Sphilip	switch (type) {
292227569Sphilip	case EFX_LIGHTSOUT_OFFLOAD_TYPE_ARP:
293227569Sphilip		req.emr_in_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_LEN;
294284555Sarybchik
295227569Sphilip		MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL,
296227569Sphilip				    MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP);
297227569Sphilip		EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t,
298227569Sphilip					    ADD_LIGHTSOUT_OFFLOAD_IN_ARP_MAC),
299227569Sphilip				    paramp->elop_arp.mac_addr);
300227569Sphilip		MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_ARP_IP,
301227569Sphilip				    paramp->elop_arp.ip);
302227569Sphilip		break;
303227569Sphilip	case EFX_LIGHTSOUT_OFFLOAD_TYPE_NS:
304227569Sphilip		req.emr_in_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_LEN;
305284555Sarybchik
306227569Sphilip		MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL,
307227569Sphilip				    MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS);
308227569Sphilip		EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t,
309227569Sphilip					    ADD_LIGHTSOUT_OFFLOAD_IN_NS_MAC),
310227569Sphilip				    paramp->elop_ns.mac_addr);
311227569Sphilip		memcpy(MCDI_IN2(req, uint8_t,
312227569Sphilip		    ADD_LIGHTSOUT_OFFLOAD_IN_NS_SNIPV6),
313227569Sphilip		    paramp->elop_ns.solicited_node,
314227569Sphilip		    sizeof (paramp->elop_ns.solicited_node));
315227569Sphilip		memcpy(MCDI_IN2(req, uint8_t, ADD_LIGHTSOUT_OFFLOAD_IN_NS_IPV6),
316227569Sphilip		    paramp->elop_ns.ip, sizeof (paramp->elop_ns.ip));
317227569Sphilip		break;
318227569Sphilip	default:
319284555Sarybchik		rc = EINVAL;
320284555Sarybchik		goto fail1;
321227569Sphilip	}
322227569Sphilip
323227569Sphilip	efx_mcdi_execute(enp, &req);
324227569Sphilip
325227569Sphilip	if (req.emr_rc != 0) {
326227569Sphilip		rc = req.emr_rc;
327284555Sarybchik		goto fail2;
328227569Sphilip	}
329227569Sphilip
330227569Sphilip	if (req.emr_out_length_used < MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN) {
331227569Sphilip		rc = EMSGSIZE;
332284555Sarybchik		goto fail3;
333227569Sphilip	}
334227569Sphilip
335227569Sphilip	*filter_idp = MCDI_OUT_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_OUT_FILTER_ID);
336227569Sphilip
337227569Sphilip	return (0);
338227569Sphilip
339284555Sarybchikfail3:
340284555Sarybchik	EFSYS_PROBE(fail3);
341227569Sphilipfail2:
342227569Sphilip	EFSYS_PROBE(fail2);
343227569Sphilipfail1:
344293927Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
345227569Sphilip
346227569Sphilip	return (rc);
347227569Sphilip}
348227569Sphilip
349227569Sphilip
350293927Sarybchik	__checkReturn	efx_rc_t
351227569Sphilipefx_lightsout_offload_remove(
352227569Sphilip	__in		efx_nic_t *enp,
353227569Sphilip	__in		efx_lightsout_offload_type_t type,
354227569Sphilip	__in		uint32_t filter_id)
355227569Sphilip{
356227569Sphilip	efx_mcdi_req_t req;
357284555Sarybchik	uint8_t payload[MAX(MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN,
358284555Sarybchik			    MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN)];
359293927Sarybchik	efx_rc_t rc;
360227569Sphilip
361227569Sphilip	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
362227569Sphilip	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
363227569Sphilip
364284555Sarybchik	(void) memset(payload, 0, sizeof (payload));
365227569Sphilip	req.emr_cmd = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD;
366227569Sphilip	req.emr_in_buf = payload;
367284555Sarybchik	req.emr_in_length = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN;
368284555Sarybchik	req.emr_out_buf = payload;
369284555Sarybchik	req.emr_out_length = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN;
370227569Sphilip
371227569Sphilip	switch (type) {
372227569Sphilip	case EFX_LIGHTSOUT_OFFLOAD_TYPE_ARP:
373227569Sphilip		MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL,
374227569Sphilip				    MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP);
375227569Sphilip		break;
376227569Sphilip	case EFX_LIGHTSOUT_OFFLOAD_TYPE_NS:
377227569Sphilip		MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL,
378227569Sphilip				    MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS);
379227569Sphilip		break;
380227569Sphilip	default:
381284555Sarybchik		rc = EINVAL;
382284555Sarybchik		goto fail1;
383227569Sphilip	}
384227569Sphilip
385227569Sphilip	MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_FILTER_ID,
386227569Sphilip			    filter_id);
387227569Sphilip
388227569Sphilip	efx_mcdi_execute(enp, &req);
389227569Sphilip
390227569Sphilip	if (req.emr_rc != 0) {
391227569Sphilip		rc = req.emr_rc;
392284555Sarybchik		goto fail2;
393227569Sphilip	}
394227569Sphilip
395227569Sphilip	return (0);
396227569Sphilip
397284555Sarybchikfail2:
398284555Sarybchik	EFSYS_PROBE(fail2);
399227569Sphilipfail1:
400293927Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
401227569Sphilip
402227569Sphilip	return (rc);
403227569Sphilip}
404227569Sphilip
405227569Sphilip
406227569Sphilip			void
407227569Sphilipefx_wol_fini(
408227569Sphilip	__in		efx_nic_t *enp)
409227569Sphilip{
410227569Sphilip	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
411227569Sphilip	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
412227569Sphilip	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
413227569Sphilip
414227569Sphilip	enp->en_mod_flags &= ~EFX_MOD_WOL;
415227569Sphilip}
416227569Sphilip
417227569Sphilip#endif	/* EFSYS_OPT_WOL */
418