diff options
Diffstat (limited to 'sys/dev/sfxge/common/efx_wol.c')
-rw-r--r-- | sys/dev/sfxge/common/efx_wol.c | 92 |
1 files changed, 55 insertions, 37 deletions
diff --git a/sys/dev/sfxge/common/efx_wol.c b/sys/dev/sfxge/common/efx_wol.c index 89a80c7..2e1b4a1 100644 --- a/sys/dev/sfxge/common/efx_wol.c +++ b/sys/dev/sfxge/common/efx_wol.c @@ -1,26 +1,31 @@ /*- - * Copyright 2009 Solarflare Communications Inc. All rights reserved. + * Copyright (c) 2009-2015 Solarflare Communications Inc. + * All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * modification, are permitted provided that the following conditions are met: * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are + * those of the authors and should not be interpreted as representing official + * policies, either expressed or implied, of the FreeBSD Project. */ #include <sys/cdefs.h> @@ -67,17 +72,19 @@ efx_wol_filter_clear( __in efx_nic_t *enp) { efx_mcdi_req_t req; - uint8_t payload[MC_CMD_WOL_FILTER_RESET_IN_LEN]; + uint8_t payload[MAX(MC_CMD_WOL_FILTER_RESET_IN_LEN, + MC_CMD_WOL_FILTER_RESET_OUT_LEN)]; int rc; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL); + (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_WOL_FILTER_RESET; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_WOL_FILTER_RESET_IN_LEN; - req.emr_out_buf = NULL; - req.emr_out_length = 0; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_WOL_FILTER_RESET_OUT_LEN; MCDI_IN_SET_DWORD(req, WOL_FILTER_RESET_IN_MASK, MC_CMD_WOL_FILTER_RESET_IN_WAKE_FILTERS | @@ -114,8 +121,8 @@ efx_wol_filter_add( EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL); + (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_WOL_FILTER_SET; - (void) memset(payload, '\0', sizeof (payload)); req.emr_in_buf = payload; req.emr_in_length = MC_CMD_WOL_FILTER_SET_IN_LEN; req.emr_out_buf = payload; @@ -226,18 +233,19 @@ efx_wol_filter_remove( __in uint32_t filter_id) { efx_mcdi_req_t req; - uint8_t payload[MC_CMD_WOL_FILTER_REMOVE_IN_LEN]; + uint8_t payload[MAX(MC_CMD_WOL_FILTER_REMOVE_IN_LEN, + MC_CMD_WOL_FILTER_REMOVE_OUT_LEN)]; int rc; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL); + (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_WOL_FILTER_REMOVE; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_WOL_FILTER_REMOVE_IN_LEN; - EFX_STATIC_ASSERT(MC_CMD_WOL_FILTER_REMOVE_OUT_LEN == 0); - req.emr_out_buf = NULL; - req.emr_out_length = 0; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_WOL_FILTER_REMOVE_OUT_LEN; MCDI_IN_SET_DWORD(req, WOL_FILTER_REMOVE_IN_FILTER_ID, filter_id); @@ -273,6 +281,7 @@ efx_lightsout_offload_add( EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL); + (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_ADD_LIGHTSOUT_OFFLOAD; req.emr_in_buf = payload; req.emr_in_length = sizeof (type); @@ -282,6 +291,7 @@ efx_lightsout_offload_add( switch (type) { case EFX_LIGHTSOUT_OFFLOAD_TYPE_ARP: req.emr_in_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_LEN; + MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL, MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP); EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, @@ -292,6 +302,7 @@ efx_lightsout_offload_add( break; case EFX_LIGHTSOUT_OFFLOAD_TYPE_NS: req.emr_in_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_LEN; + MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL, MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS); EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, @@ -305,25 +316,28 @@ efx_lightsout_offload_add( paramp->elop_ns.ip, sizeof (paramp->elop_ns.ip)); break; default: - EFSYS_ASSERT3U(type, !=, type); + rc = EINVAL; + goto fail1; } efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; - goto fail1; + goto fail2; } if (req.emr_out_length_used < MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN) { rc = EMSGSIZE; - goto fail2; + goto fail3; } *filter_idp = MCDI_OUT_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_OUT_FILTER_ID); return (0); +fail3: + EFSYS_PROBE(fail3); fail2: EFSYS_PROBE(fail2); fail1: @@ -340,18 +354,19 @@ efx_lightsout_offload_remove( __in uint32_t filter_id) { efx_mcdi_req_t req; - uint8_t payload[MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN]; + uint8_t payload[MAX(MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN, + MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN)]; int rc; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL); + (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD; req.emr_in_buf = payload; - req.emr_in_length = sizeof (payload); - EFX_STATIC_ASSERT(MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN == 0); - req.emr_out_buf = NULL; - req.emr_out_length = 0; + req.emr_in_length = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN; switch (type) { case EFX_LIGHTSOUT_OFFLOAD_TYPE_ARP: @@ -363,7 +378,8 @@ efx_lightsout_offload_remove( MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS); break; default: - EFSYS_ASSERT3U(type, !=, type); + rc = EINVAL; + goto fail1; } MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_FILTER_ID, @@ -373,11 +389,13 @@ efx_lightsout_offload_remove( if (req.emr_rc != 0) { rc = req.emr_rc; - goto fail1; + goto fail2; } return (0); +fail2: + EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, int, rc); |