1*49ef7e06SGarrett D'Amore /*
2*49ef7e06SGarrett D'Amore * Copyright (c) 2009-2015 Solarflare Communications Inc.
3*49ef7e06SGarrett D'Amore * All rights reserved.
4*49ef7e06SGarrett D'Amore *
5*49ef7e06SGarrett D'Amore * Redistribution and use in source and binary forms, with or without
6*49ef7e06SGarrett D'Amore * modification, are permitted provided that the following conditions are met:
7*49ef7e06SGarrett D'Amore *
8*49ef7e06SGarrett D'Amore * 1. Redistributions of source code must retain the above copyright notice,
9*49ef7e06SGarrett D'Amore * this list of conditions and the following disclaimer.
10*49ef7e06SGarrett D'Amore * 2. Redistributions in binary form must reproduce the above copyright notice,
11*49ef7e06SGarrett D'Amore * this list of conditions and the following disclaimer in the documentation
12*49ef7e06SGarrett D'Amore * and/or other materials provided with the distribution.
13*49ef7e06SGarrett D'Amore *
14*49ef7e06SGarrett D'Amore * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15*49ef7e06SGarrett D'Amore * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16*49ef7e06SGarrett D'Amore * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17*49ef7e06SGarrett D'Amore * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18*49ef7e06SGarrett D'Amore * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19*49ef7e06SGarrett D'Amore * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20*49ef7e06SGarrett D'Amore * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21*49ef7e06SGarrett D'Amore * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22*49ef7e06SGarrett D'Amore * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23*49ef7e06SGarrett D'Amore * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24*49ef7e06SGarrett D'Amore * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*49ef7e06SGarrett D'Amore *
26*49ef7e06SGarrett D'Amore * The views and conclusions contained in the software and documentation are
27*49ef7e06SGarrett D'Amore * those of the authors and should not be interpreted as representing official
28*49ef7e06SGarrett D'Amore * policies, either expressed or implied, of the FreeBSD Project.
29*49ef7e06SGarrett D'Amore */
30*49ef7e06SGarrett D'Amore
31*49ef7e06SGarrett D'Amore #include "efx.h"
32*49ef7e06SGarrett D'Amore #include "efx_impl.h"
33*49ef7e06SGarrett D'Amore
34*49ef7e06SGarrett D'Amore #if EFSYS_OPT_WOL
35*49ef7e06SGarrett D'Amore
36*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_wol_init(__in efx_nic_t * enp)37*49ef7e06SGarrett D'Amore efx_wol_init(
38*49ef7e06SGarrett D'Amore __in efx_nic_t *enp)
39*49ef7e06SGarrett D'Amore {
40*49ef7e06SGarrett D'Amore efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
41*49ef7e06SGarrett D'Amore efx_rc_t rc;
42*49ef7e06SGarrett D'Amore
43*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
44*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
45*49ef7e06SGarrett D'Amore EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_WOL));
46*49ef7e06SGarrett D'Amore
47*49ef7e06SGarrett D'Amore if (~(encp->enc_features) & EFX_FEATURE_WOL) {
48*49ef7e06SGarrett D'Amore rc = ENOTSUP;
49*49ef7e06SGarrett D'Amore goto fail1;
50*49ef7e06SGarrett D'Amore }
51*49ef7e06SGarrett D'Amore
52*49ef7e06SGarrett D'Amore /* Current implementation is Siena specific */
53*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
54*49ef7e06SGarrett D'Amore
55*49ef7e06SGarrett D'Amore enp->en_mod_flags |= EFX_MOD_WOL;
56*49ef7e06SGarrett D'Amore
57*49ef7e06SGarrett D'Amore return (0);
58*49ef7e06SGarrett D'Amore
59*49ef7e06SGarrett D'Amore fail1:
60*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
61*49ef7e06SGarrett D'Amore
62*49ef7e06SGarrett D'Amore return (rc);
63*49ef7e06SGarrett D'Amore }
64*49ef7e06SGarrett D'Amore
65*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_wol_filter_clear(__in efx_nic_t * enp)66*49ef7e06SGarrett D'Amore efx_wol_filter_clear(
67*49ef7e06SGarrett D'Amore __in efx_nic_t *enp)
68*49ef7e06SGarrett D'Amore {
69*49ef7e06SGarrett D'Amore efx_mcdi_req_t req;
70*49ef7e06SGarrett D'Amore uint8_t payload[MAX(MC_CMD_WOL_FILTER_RESET_IN_LEN,
71*49ef7e06SGarrett D'Amore MC_CMD_WOL_FILTER_RESET_OUT_LEN)];
72*49ef7e06SGarrett D'Amore efx_rc_t rc;
73*49ef7e06SGarrett D'Amore
74*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
75*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
76*49ef7e06SGarrett D'Amore
77*49ef7e06SGarrett D'Amore (void) memset(payload, 0, sizeof (payload));
78*49ef7e06SGarrett D'Amore req.emr_cmd = MC_CMD_WOL_FILTER_RESET;
79*49ef7e06SGarrett D'Amore req.emr_in_buf = payload;
80*49ef7e06SGarrett D'Amore req.emr_in_length = MC_CMD_WOL_FILTER_RESET_IN_LEN;
81*49ef7e06SGarrett D'Amore req.emr_out_buf = payload;
82*49ef7e06SGarrett D'Amore req.emr_out_length = MC_CMD_WOL_FILTER_RESET_OUT_LEN;
83*49ef7e06SGarrett D'Amore
84*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, WOL_FILTER_RESET_IN_MASK,
85*49ef7e06SGarrett D'Amore MC_CMD_WOL_FILTER_RESET_IN_WAKE_FILTERS |
86*49ef7e06SGarrett D'Amore MC_CMD_WOL_FILTER_RESET_IN_LIGHTSOUT_OFFLOADS);
87*49ef7e06SGarrett D'Amore
88*49ef7e06SGarrett D'Amore efx_mcdi_execute(enp, &req);
89*49ef7e06SGarrett D'Amore
90*49ef7e06SGarrett D'Amore if (req.emr_rc != 0) {
91*49ef7e06SGarrett D'Amore rc = req.emr_rc;
92*49ef7e06SGarrett D'Amore goto fail1;
93*49ef7e06SGarrett D'Amore }
94*49ef7e06SGarrett D'Amore
95*49ef7e06SGarrett D'Amore return (0);
96*49ef7e06SGarrett D'Amore
97*49ef7e06SGarrett D'Amore fail1:
98*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
99*49ef7e06SGarrett D'Amore
100*49ef7e06SGarrett D'Amore return (rc);
101*49ef7e06SGarrett D'Amore }
102*49ef7e06SGarrett D'Amore
103*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_wol_filter_add(__in efx_nic_t * enp,__in efx_wol_type_t type,__in efx_wol_param_t * paramp,__out uint32_t * filter_idp)104*49ef7e06SGarrett D'Amore efx_wol_filter_add(
105*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
106*49ef7e06SGarrett D'Amore __in efx_wol_type_t type,
107*49ef7e06SGarrett D'Amore __in efx_wol_param_t *paramp,
108*49ef7e06SGarrett D'Amore __out uint32_t *filter_idp)
109*49ef7e06SGarrett D'Amore {
110*49ef7e06SGarrett D'Amore efx_mcdi_req_t req;
111*49ef7e06SGarrett D'Amore uint8_t payload[MAX(MC_CMD_WOL_FILTER_SET_IN_LEN,
112*49ef7e06SGarrett D'Amore MC_CMD_WOL_FILTER_SET_OUT_LEN)];
113*49ef7e06SGarrett D'Amore efx_byte_t link_mask;
114*49ef7e06SGarrett D'Amore efx_rc_t rc;
115*49ef7e06SGarrett D'Amore
116*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
117*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
118*49ef7e06SGarrett D'Amore
119*49ef7e06SGarrett D'Amore (void) memset(payload, 0, sizeof (payload));
120*49ef7e06SGarrett D'Amore req.emr_cmd = MC_CMD_WOL_FILTER_SET;
121*49ef7e06SGarrett D'Amore req.emr_in_buf = payload;
122*49ef7e06SGarrett D'Amore req.emr_in_length = MC_CMD_WOL_FILTER_SET_IN_LEN;
123*49ef7e06SGarrett D'Amore req.emr_out_buf = payload;
124*49ef7e06SGarrett D'Amore req.emr_out_length = MC_CMD_WOL_FILTER_SET_OUT_LEN;
125*49ef7e06SGarrett D'Amore
126*49ef7e06SGarrett D'Amore switch (type) {
127*49ef7e06SGarrett D'Amore case EFX_WOL_TYPE_MAGIC:
128*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_FILTER_MODE,
129*49ef7e06SGarrett D'Amore MC_CMD_FILTER_MODE_SIMPLE);
130*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_WOL_TYPE,
131*49ef7e06SGarrett D'Amore MC_CMD_WOL_TYPE_MAGIC);
132*49ef7e06SGarrett D'Amore EFX_MAC_ADDR_COPY(
133*49ef7e06SGarrett D'Amore MCDI_IN2(req, uint8_t, WOL_FILTER_SET_IN_MAGIC_MAC),
134*49ef7e06SGarrett D'Amore paramp->ewp_magic.mac_addr);
135*49ef7e06SGarrett D'Amore break;
136*49ef7e06SGarrett D'Amore
137*49ef7e06SGarrett D'Amore case EFX_WOL_TYPE_BITMAP: {
138*49ef7e06SGarrett D'Amore uint32_t swapped = 0;
139*49ef7e06SGarrett D'Amore efx_dword_t *dwordp;
140*49ef7e06SGarrett D'Amore unsigned int pos, bit;
141*49ef7e06SGarrett D'Amore
142*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_FILTER_MODE,
143*49ef7e06SGarrett D'Amore MC_CMD_FILTER_MODE_SIMPLE);
144*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_WOL_TYPE,
145*49ef7e06SGarrett D'Amore MC_CMD_WOL_TYPE_BITMAP);
146*49ef7e06SGarrett D'Amore
147*49ef7e06SGarrett D'Amore /*
148*49ef7e06SGarrett D'Amore * MC bitmask is supposed to be bit swapped
149*49ef7e06SGarrett D'Amore * amongst 32 bit words(!)
150*49ef7e06SGarrett D'Amore */
151*49ef7e06SGarrett D'Amore
152*49ef7e06SGarrett D'Amore dwordp = MCDI_IN2(req, efx_dword_t,
153*49ef7e06SGarrett D'Amore WOL_FILTER_SET_IN_BITMAP_MASK);
154*49ef7e06SGarrett D'Amore
155*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(EFX_WOL_BITMAP_MASK_SIZE % 4, ==, 0);
156*49ef7e06SGarrett D'Amore
157*49ef7e06SGarrett D'Amore for (pos = 0; pos < EFX_WOL_BITMAP_MASK_SIZE; ++pos) {
158*49ef7e06SGarrett D'Amore uint8_t native = paramp->ewp_bitmap.mask[pos];
159*49ef7e06SGarrett D'Amore
160*49ef7e06SGarrett D'Amore for (bit = 0; bit < 8; ++bit) {
161*49ef7e06SGarrett D'Amore swapped <<= 1;
162*49ef7e06SGarrett D'Amore swapped |= (native & 0x1);
163*49ef7e06SGarrett D'Amore native >>= 1;
164*49ef7e06SGarrett D'Amore }
165*49ef7e06SGarrett D'Amore
166*49ef7e06SGarrett D'Amore if ((pos & 3) == 3) {
167*49ef7e06SGarrett D'Amore EFX_POPULATE_DWORD_1(dwordp[pos >> 2],
168*49ef7e06SGarrett D'Amore EFX_DWORD_0, swapped);
169*49ef7e06SGarrett D'Amore swapped = 0;
170*49ef7e06SGarrett D'Amore }
171*49ef7e06SGarrett D'Amore }
172*49ef7e06SGarrett D'Amore
173*49ef7e06SGarrett D'Amore (void) memcpy(MCDI_IN2(req, uint8_t,
174*49ef7e06SGarrett D'Amore WOL_FILTER_SET_IN_BITMAP_BITMAP),
175*49ef7e06SGarrett D'Amore paramp->ewp_bitmap.value,
176*49ef7e06SGarrett D'Amore sizeof (paramp->ewp_bitmap.value));
177*49ef7e06SGarrett D'Amore
178*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(paramp->ewp_bitmap.value_len, <=,
179*49ef7e06SGarrett D'Amore sizeof (paramp->ewp_bitmap.value));
180*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_BITMAP_LEN,
181*49ef7e06SGarrett D'Amore paramp->ewp_bitmap.value_len);
182*49ef7e06SGarrett D'Amore }
183*49ef7e06SGarrett D'Amore break;
184*49ef7e06SGarrett D'Amore
185*49ef7e06SGarrett D'Amore case EFX_WOL_TYPE_LINK:
186*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_FILTER_MODE,
187*49ef7e06SGarrett D'Amore MC_CMD_FILTER_MODE_SIMPLE);
188*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_WOL_TYPE,
189*49ef7e06SGarrett D'Amore MC_CMD_WOL_TYPE_LINK);
190*49ef7e06SGarrett D'Amore
191*49ef7e06SGarrett D'Amore EFX_ZERO_BYTE(link_mask);
192*49ef7e06SGarrett D'Amore EFX_SET_BYTE_FIELD(link_mask, MC_CMD_WOL_FILTER_SET_IN_LINK_UP,
193*49ef7e06SGarrett D'Amore 1);
194*49ef7e06SGarrett D'Amore MCDI_IN_SET_BYTE(req, WOL_FILTER_SET_IN_LINK_MASK,
195*49ef7e06SGarrett D'Amore link_mask.eb_u8[0]);
196*49ef7e06SGarrett D'Amore break;
197*49ef7e06SGarrett D'Amore
198*49ef7e06SGarrett D'Amore default:
199*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(type, !=, type);
200*49ef7e06SGarrett D'Amore }
201*49ef7e06SGarrett D'Amore
202*49ef7e06SGarrett D'Amore efx_mcdi_execute(enp, &req);
203*49ef7e06SGarrett D'Amore
204*49ef7e06SGarrett D'Amore if (req.emr_rc != 0) {
205*49ef7e06SGarrett D'Amore rc = req.emr_rc;
206*49ef7e06SGarrett D'Amore goto fail1;
207*49ef7e06SGarrett D'Amore }
208*49ef7e06SGarrett D'Amore
209*49ef7e06SGarrett D'Amore if (req.emr_out_length_used < MC_CMD_WOL_FILTER_SET_OUT_LEN) {
210*49ef7e06SGarrett D'Amore rc = EMSGSIZE;
211*49ef7e06SGarrett D'Amore goto fail2;
212*49ef7e06SGarrett D'Amore }
213*49ef7e06SGarrett D'Amore
214*49ef7e06SGarrett D'Amore *filter_idp = MCDI_OUT_DWORD(req, WOL_FILTER_SET_OUT_FILTER_ID);
215*49ef7e06SGarrett D'Amore
216*49ef7e06SGarrett D'Amore return (0);
217*49ef7e06SGarrett D'Amore
218*49ef7e06SGarrett D'Amore fail2:
219*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail2);
220*49ef7e06SGarrett D'Amore fail1:
221*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
222*49ef7e06SGarrett D'Amore
223*49ef7e06SGarrett D'Amore return (rc);
224*49ef7e06SGarrett D'Amore }
225*49ef7e06SGarrett D'Amore
226*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_wol_filter_remove(__in efx_nic_t * enp,__in uint32_t filter_id)227*49ef7e06SGarrett D'Amore efx_wol_filter_remove(
228*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
229*49ef7e06SGarrett D'Amore __in uint32_t filter_id)
230*49ef7e06SGarrett D'Amore {
231*49ef7e06SGarrett D'Amore efx_mcdi_req_t req;
232*49ef7e06SGarrett D'Amore uint8_t payload[MAX(MC_CMD_WOL_FILTER_REMOVE_IN_LEN,
233*49ef7e06SGarrett D'Amore MC_CMD_WOL_FILTER_REMOVE_OUT_LEN)];
234*49ef7e06SGarrett D'Amore efx_rc_t rc;
235*49ef7e06SGarrett D'Amore
236*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
237*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
238*49ef7e06SGarrett D'Amore
239*49ef7e06SGarrett D'Amore (void) memset(payload, 0, sizeof (payload));
240*49ef7e06SGarrett D'Amore req.emr_cmd = MC_CMD_WOL_FILTER_REMOVE;
241*49ef7e06SGarrett D'Amore req.emr_in_buf = payload;
242*49ef7e06SGarrett D'Amore req.emr_in_length = MC_CMD_WOL_FILTER_REMOVE_IN_LEN;
243*49ef7e06SGarrett D'Amore req.emr_out_buf = payload;
244*49ef7e06SGarrett D'Amore req.emr_out_length = MC_CMD_WOL_FILTER_REMOVE_OUT_LEN;
245*49ef7e06SGarrett D'Amore
246*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, WOL_FILTER_REMOVE_IN_FILTER_ID, filter_id);
247*49ef7e06SGarrett D'Amore
248*49ef7e06SGarrett D'Amore efx_mcdi_execute(enp, &req);
249*49ef7e06SGarrett D'Amore
250*49ef7e06SGarrett D'Amore if (req.emr_rc != 0) {
251*49ef7e06SGarrett D'Amore rc = req.emr_rc;
252*49ef7e06SGarrett D'Amore goto fail1;
253*49ef7e06SGarrett D'Amore }
254*49ef7e06SGarrett D'Amore
255*49ef7e06SGarrett D'Amore return (0);
256*49ef7e06SGarrett D'Amore
257*49ef7e06SGarrett D'Amore fail1:
258*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
259*49ef7e06SGarrett D'Amore
260*49ef7e06SGarrett D'Amore return (rc);
261*49ef7e06SGarrett D'Amore }
262*49ef7e06SGarrett D'Amore
263*49ef7e06SGarrett D'Amore
264*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_lightsout_offload_add(__in efx_nic_t * enp,__in efx_lightsout_offload_type_t type,__in efx_lightsout_offload_param_t * paramp,__out uint32_t * filter_idp)265*49ef7e06SGarrett D'Amore efx_lightsout_offload_add(
266*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
267*49ef7e06SGarrett D'Amore __in efx_lightsout_offload_type_t type,
268*49ef7e06SGarrett D'Amore __in efx_lightsout_offload_param_t *paramp,
269*49ef7e06SGarrett D'Amore __out uint32_t *filter_idp)
270*49ef7e06SGarrett D'Amore {
271*49ef7e06SGarrett D'Amore efx_mcdi_req_t req;
272*49ef7e06SGarrett D'Amore uint8_t payload[MAX(MAX(MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_LEN,
273*49ef7e06SGarrett D'Amore MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_LEN),
274*49ef7e06SGarrett D'Amore MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN)];
275*49ef7e06SGarrett D'Amore efx_rc_t rc;
276*49ef7e06SGarrett D'Amore
277*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
278*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
279*49ef7e06SGarrett D'Amore
280*49ef7e06SGarrett D'Amore (void) memset(payload, 0, sizeof (payload));
281*49ef7e06SGarrett D'Amore req.emr_cmd = MC_CMD_ADD_LIGHTSOUT_OFFLOAD;
282*49ef7e06SGarrett D'Amore req.emr_in_buf = payload;
283*49ef7e06SGarrett D'Amore req.emr_in_length = sizeof (type);
284*49ef7e06SGarrett D'Amore req.emr_out_buf = payload;
285*49ef7e06SGarrett D'Amore req.emr_out_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN;
286*49ef7e06SGarrett D'Amore
287*49ef7e06SGarrett D'Amore switch (type) {
288*49ef7e06SGarrett D'Amore case EFX_LIGHTSOUT_OFFLOAD_TYPE_ARP:
289*49ef7e06SGarrett D'Amore req.emr_in_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_LEN;
290*49ef7e06SGarrett D'Amore
291*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL,
292*49ef7e06SGarrett D'Amore MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP);
293*49ef7e06SGarrett D'Amore EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t,
294*49ef7e06SGarrett D'Amore ADD_LIGHTSOUT_OFFLOAD_IN_ARP_MAC),
295*49ef7e06SGarrett D'Amore paramp->elop_arp.mac_addr);
296*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_ARP_IP,
297*49ef7e06SGarrett D'Amore paramp->elop_arp.ip);
298*49ef7e06SGarrett D'Amore break;
299*49ef7e06SGarrett D'Amore case EFX_LIGHTSOUT_OFFLOAD_TYPE_NS:
300*49ef7e06SGarrett D'Amore req.emr_in_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_LEN;
301*49ef7e06SGarrett D'Amore
302*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL,
303*49ef7e06SGarrett D'Amore MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS);
304*49ef7e06SGarrett D'Amore EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t,
305*49ef7e06SGarrett D'Amore ADD_LIGHTSOUT_OFFLOAD_IN_NS_MAC),
306*49ef7e06SGarrett D'Amore paramp->elop_ns.mac_addr);
307*49ef7e06SGarrett D'Amore (void) memcpy(MCDI_IN2(req, uint8_t,
308*49ef7e06SGarrett D'Amore ADD_LIGHTSOUT_OFFLOAD_IN_NS_SNIPV6),
309*49ef7e06SGarrett D'Amore paramp->elop_ns.solicited_node,
310*49ef7e06SGarrett D'Amore sizeof (paramp->elop_ns.solicited_node));
311*49ef7e06SGarrett D'Amore (void) memcpy(MCDI_IN2(req, uint8_t,
312*49ef7e06SGarrett D'Amore ADD_LIGHTSOUT_OFFLOAD_IN_NS_IPV6),
313*49ef7e06SGarrett D'Amore paramp->elop_ns.ip, sizeof (paramp->elop_ns.ip));
314*49ef7e06SGarrett D'Amore break;
315*49ef7e06SGarrett D'Amore default:
316*49ef7e06SGarrett D'Amore rc = EINVAL;
317*49ef7e06SGarrett D'Amore goto fail1;
318*49ef7e06SGarrett D'Amore }
319*49ef7e06SGarrett D'Amore
320*49ef7e06SGarrett D'Amore efx_mcdi_execute(enp, &req);
321*49ef7e06SGarrett D'Amore
322*49ef7e06SGarrett D'Amore if (req.emr_rc != 0) {
323*49ef7e06SGarrett D'Amore rc = req.emr_rc;
324*49ef7e06SGarrett D'Amore goto fail2;
325*49ef7e06SGarrett D'Amore }
326*49ef7e06SGarrett D'Amore
327*49ef7e06SGarrett D'Amore if (req.emr_out_length_used < MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN) {
328*49ef7e06SGarrett D'Amore rc = EMSGSIZE;
329*49ef7e06SGarrett D'Amore goto fail3;
330*49ef7e06SGarrett D'Amore }
331*49ef7e06SGarrett D'Amore
332*49ef7e06SGarrett D'Amore *filter_idp = MCDI_OUT_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_OUT_FILTER_ID);
333*49ef7e06SGarrett D'Amore
334*49ef7e06SGarrett D'Amore return (0);
335*49ef7e06SGarrett D'Amore
336*49ef7e06SGarrett D'Amore fail3:
337*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail3);
338*49ef7e06SGarrett D'Amore fail2:
339*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail2);
340*49ef7e06SGarrett D'Amore fail1:
341*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
342*49ef7e06SGarrett D'Amore
343*49ef7e06SGarrett D'Amore return (rc);
344*49ef7e06SGarrett D'Amore }
345*49ef7e06SGarrett D'Amore
346*49ef7e06SGarrett D'Amore
347*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_lightsout_offload_remove(__in efx_nic_t * enp,__in efx_lightsout_offload_type_t type,__in uint32_t filter_id)348*49ef7e06SGarrett D'Amore efx_lightsout_offload_remove(
349*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
350*49ef7e06SGarrett D'Amore __in efx_lightsout_offload_type_t type,
351*49ef7e06SGarrett D'Amore __in uint32_t filter_id)
352*49ef7e06SGarrett D'Amore {
353*49ef7e06SGarrett D'Amore efx_mcdi_req_t req;
354*49ef7e06SGarrett D'Amore uint8_t payload[MAX(MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN,
355*49ef7e06SGarrett D'Amore MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN)];
356*49ef7e06SGarrett D'Amore efx_rc_t rc;
357*49ef7e06SGarrett D'Amore
358*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
359*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
360*49ef7e06SGarrett D'Amore
361*49ef7e06SGarrett D'Amore (void) memset(payload, 0, sizeof (payload));
362*49ef7e06SGarrett D'Amore req.emr_cmd = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD;
363*49ef7e06SGarrett D'Amore req.emr_in_buf = payload;
364*49ef7e06SGarrett D'Amore req.emr_in_length = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN;
365*49ef7e06SGarrett D'Amore req.emr_out_buf = payload;
366*49ef7e06SGarrett D'Amore req.emr_out_length = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN;
367*49ef7e06SGarrett D'Amore
368*49ef7e06SGarrett D'Amore switch (type) {
369*49ef7e06SGarrett D'Amore case EFX_LIGHTSOUT_OFFLOAD_TYPE_ARP:
370*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL,
371*49ef7e06SGarrett D'Amore MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP);
372*49ef7e06SGarrett D'Amore break;
373*49ef7e06SGarrett D'Amore case EFX_LIGHTSOUT_OFFLOAD_TYPE_NS:
374*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL,
375*49ef7e06SGarrett D'Amore MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS);
376*49ef7e06SGarrett D'Amore break;
377*49ef7e06SGarrett D'Amore default:
378*49ef7e06SGarrett D'Amore rc = EINVAL;
379*49ef7e06SGarrett D'Amore goto fail1;
380*49ef7e06SGarrett D'Amore }
381*49ef7e06SGarrett D'Amore
382*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_FILTER_ID,
383*49ef7e06SGarrett D'Amore filter_id);
384*49ef7e06SGarrett D'Amore
385*49ef7e06SGarrett D'Amore efx_mcdi_execute(enp, &req);
386*49ef7e06SGarrett D'Amore
387*49ef7e06SGarrett D'Amore if (req.emr_rc != 0) {
388*49ef7e06SGarrett D'Amore rc = req.emr_rc;
389*49ef7e06SGarrett D'Amore goto fail2;
390*49ef7e06SGarrett D'Amore }
391*49ef7e06SGarrett D'Amore
392*49ef7e06SGarrett D'Amore return (0);
393*49ef7e06SGarrett D'Amore
394*49ef7e06SGarrett D'Amore fail2:
395*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail2);
396*49ef7e06SGarrett D'Amore fail1:
397*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
398*49ef7e06SGarrett D'Amore
399*49ef7e06SGarrett D'Amore return (rc);
400*49ef7e06SGarrett D'Amore }
401*49ef7e06SGarrett D'Amore
402*49ef7e06SGarrett D'Amore
403*49ef7e06SGarrett D'Amore void
efx_wol_fini(__in efx_nic_t * enp)404*49ef7e06SGarrett D'Amore efx_wol_fini(
405*49ef7e06SGarrett D'Amore __in efx_nic_t *enp)
406*49ef7e06SGarrett D'Amore {
407*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
408*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
409*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
410*49ef7e06SGarrett D'Amore
411*49ef7e06SGarrett D'Amore enp->en_mod_flags &= ~EFX_MOD_WOL;
412*49ef7e06SGarrett D'Amore }
413*49ef7e06SGarrett D'Amore
414*49ef7e06SGarrett D'Amore #endif /* EFSYS_OPT_WOL */
415