Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/sfxge/common/efx_wol.c
Property | Old Value | New Value |
---|---|---|
svn:eol-style | null | native \ No newline at end of property |
svn:mime-type | null | text/plain \ No newline at end of property |
/*- | /*- | ||||
* 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 | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions are met: | ||||
* 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. | |||||
* | * | ||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND | * 1. Redistributions of source code must retain the above copyright notice, | ||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | * this list of conditions and the following disclaimer. | ||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | * 2. Redistributions in binary form must reproduce the above copyright notice, | ||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | * this list of conditions and the following disclaimer in the documentation | ||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | * and/or other materials provided with the distribution. | ||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | * | ||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | ||||
* SUCH DAMAGE. | * 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> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include "efsys.h" | #include "efsys.h" | ||||
#include "efx.h" | #include "efx.h" | ||||
#include "efx_types.h" | #include "efx_types.h" | ||||
Show All 30 Lines | fail1: | ||||
return (rc); | return (rc); | ||||
} | } | ||||
__checkReturn int | __checkReturn int | ||||
efx_wol_filter_clear( | efx_wol_filter_clear( | ||||
__in efx_nic_t *enp) | __in efx_nic_t *enp) | ||||
{ | { | ||||
efx_mcdi_req_t req; | 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; | int rc; | ||||
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); | EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); | ||||
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL); | 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_cmd = MC_CMD_WOL_FILTER_RESET; | ||||
req.emr_in_buf = payload; | req.emr_in_buf = payload; | ||||
req.emr_in_length = MC_CMD_WOL_FILTER_RESET_IN_LEN; | req.emr_in_length = MC_CMD_WOL_FILTER_RESET_IN_LEN; | ||||
req.emr_out_buf = NULL; | req.emr_out_buf = payload; | ||||
req.emr_out_length = 0; | req.emr_out_length = MC_CMD_WOL_FILTER_RESET_OUT_LEN; | ||||
MCDI_IN_SET_DWORD(req, WOL_FILTER_RESET_IN_MASK, | MCDI_IN_SET_DWORD(req, WOL_FILTER_RESET_IN_MASK, | ||||
MC_CMD_WOL_FILTER_RESET_IN_WAKE_FILTERS | | MC_CMD_WOL_FILTER_RESET_IN_WAKE_FILTERS | | ||||
MC_CMD_WOL_FILTER_RESET_IN_LIGHTSOUT_OFFLOADS); | MC_CMD_WOL_FILTER_RESET_IN_LIGHTSOUT_OFFLOADS); | ||||
efx_mcdi_execute(enp, &req); | efx_mcdi_execute(enp, &req); | ||||
if (req.emr_rc != 0) { | if (req.emr_rc != 0) { | ||||
Show All 20 Lines | efx_wol_filter_add( | ||||
uint8_t payload[MAX(MC_CMD_WOL_FILTER_SET_IN_LEN, | uint8_t payload[MAX(MC_CMD_WOL_FILTER_SET_IN_LEN, | ||||
MC_CMD_WOL_FILTER_SET_OUT_LEN)]; | MC_CMD_WOL_FILTER_SET_OUT_LEN)]; | ||||
efx_byte_t link_mask; | efx_byte_t link_mask; | ||||
int rc; | int rc; | ||||
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); | EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); | ||||
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL); | EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL); | ||||
(void) memset(payload, 0, sizeof (payload)); | |||||
req.emr_cmd = MC_CMD_WOL_FILTER_SET; | req.emr_cmd = MC_CMD_WOL_FILTER_SET; | ||||
(void) memset(payload, '\0', sizeof (payload)); | |||||
req.emr_in_buf = payload; | req.emr_in_buf = payload; | ||||
req.emr_in_length = MC_CMD_WOL_FILTER_SET_IN_LEN; | req.emr_in_length = MC_CMD_WOL_FILTER_SET_IN_LEN; | ||||
req.emr_out_buf = payload; | req.emr_out_buf = payload; | ||||
req.emr_out_length = MC_CMD_WOL_FILTER_SET_OUT_LEN; | req.emr_out_length = MC_CMD_WOL_FILTER_SET_OUT_LEN; | ||||
switch (type) { | switch (type) { | ||||
case EFX_WOL_TYPE_MAGIC: | case EFX_WOL_TYPE_MAGIC: | ||||
MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_FILTER_MODE, | MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_FILTER_MODE, | ||||
▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
__checkReturn int | __checkReturn int | ||||
efx_wol_filter_remove( | efx_wol_filter_remove( | ||||
__in efx_nic_t *enp, | __in efx_nic_t *enp, | ||||
__in uint32_t filter_id) | __in uint32_t filter_id) | ||||
{ | { | ||||
efx_mcdi_req_t req; | 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; | int rc; | ||||
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); | EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); | ||||
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL); | 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_cmd = MC_CMD_WOL_FILTER_REMOVE; | ||||
req.emr_in_buf = payload; | req.emr_in_buf = payload; | ||||
req.emr_in_length = MC_CMD_WOL_FILTER_REMOVE_IN_LEN; | 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 = payload; | ||||
req.emr_out_buf = NULL; | req.emr_out_length = MC_CMD_WOL_FILTER_REMOVE_OUT_LEN; | ||||
req.emr_out_length = 0; | |||||
MCDI_IN_SET_DWORD(req, WOL_FILTER_REMOVE_IN_FILTER_ID, filter_id); | MCDI_IN_SET_DWORD(req, WOL_FILTER_REMOVE_IN_FILTER_ID, filter_id); | ||||
efx_mcdi_execute(enp, &req); | efx_mcdi_execute(enp, &req); | ||||
if (req.emr_rc != 0) { | if (req.emr_rc != 0) { | ||||
rc = req.emr_rc; | rc = req.emr_rc; | ||||
goto fail1; | goto fail1; | ||||
Show All 19 Lines | efx_lightsout_offload_add( | ||||
uint8_t payload[MAX(MAX(MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_LEN, | uint8_t payload[MAX(MAX(MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_LEN, | ||||
MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_LEN), | MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_LEN), | ||||
MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN)]; | MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN)]; | ||||
int rc; | int rc; | ||||
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); | EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); | ||||
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL); | 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_cmd = MC_CMD_ADD_LIGHTSOUT_OFFLOAD; | ||||
req.emr_in_buf = payload; | req.emr_in_buf = payload; | ||||
req.emr_in_length = sizeof (type); | req.emr_in_length = sizeof (type); | ||||
req.emr_out_buf = payload; | req.emr_out_buf = payload; | ||||
req.emr_out_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN; | req.emr_out_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN; | ||||
switch (type) { | switch (type) { | ||||
case EFX_LIGHTSOUT_OFFLOAD_TYPE_ARP: | case EFX_LIGHTSOUT_OFFLOAD_TYPE_ARP: | ||||
req.emr_in_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_LEN; | req.emr_in_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_LEN; | ||||
MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL, | MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL, | ||||
MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP); | MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP); | ||||
EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, | EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, | ||||
ADD_LIGHTSOUT_OFFLOAD_IN_ARP_MAC), | ADD_LIGHTSOUT_OFFLOAD_IN_ARP_MAC), | ||||
paramp->elop_arp.mac_addr); | paramp->elop_arp.mac_addr); | ||||
MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_ARP_IP, | MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_ARP_IP, | ||||
paramp->elop_arp.ip); | paramp->elop_arp.ip); | ||||
break; | break; | ||||
case EFX_LIGHTSOUT_OFFLOAD_TYPE_NS: | case EFX_LIGHTSOUT_OFFLOAD_TYPE_NS: | ||||
req.emr_in_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_LEN; | req.emr_in_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_LEN; | ||||
MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL, | MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL, | ||||
MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS); | MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS); | ||||
EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, | EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, | ||||
ADD_LIGHTSOUT_OFFLOAD_IN_NS_MAC), | ADD_LIGHTSOUT_OFFLOAD_IN_NS_MAC), | ||||
paramp->elop_ns.mac_addr); | paramp->elop_ns.mac_addr); | ||||
memcpy(MCDI_IN2(req, uint8_t, | memcpy(MCDI_IN2(req, uint8_t, | ||||
ADD_LIGHTSOUT_OFFLOAD_IN_NS_SNIPV6), | ADD_LIGHTSOUT_OFFLOAD_IN_NS_SNIPV6), | ||||
paramp->elop_ns.solicited_node, | paramp->elop_ns.solicited_node, | ||||
sizeof (paramp->elop_ns.solicited_node)); | sizeof (paramp->elop_ns.solicited_node)); | ||||
memcpy(MCDI_IN2(req, uint8_t, ADD_LIGHTSOUT_OFFLOAD_IN_NS_IPV6), | memcpy(MCDI_IN2(req, uint8_t, ADD_LIGHTSOUT_OFFLOAD_IN_NS_IPV6), | ||||
paramp->elop_ns.ip, sizeof (paramp->elop_ns.ip)); | paramp->elop_ns.ip, sizeof (paramp->elop_ns.ip)); | ||||
break; | break; | ||||
default: | default: | ||||
EFSYS_ASSERT3U(type, !=, type); | rc = EINVAL; | ||||
goto fail1; | |||||
} | } | ||||
efx_mcdi_execute(enp, &req); | efx_mcdi_execute(enp, &req); | ||||
if (req.emr_rc != 0) { | if (req.emr_rc != 0) { | ||||
rc = req.emr_rc; | rc = req.emr_rc; | ||||
goto fail1; | goto fail2; | ||||
} | } | ||||
if (req.emr_out_length_used < MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN) { | if (req.emr_out_length_used < MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN) { | ||||
rc = EMSGSIZE; | rc = EMSGSIZE; | ||||
goto fail2; | goto fail3; | ||||
} | } | ||||
*filter_idp = MCDI_OUT_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_OUT_FILTER_ID); | *filter_idp = MCDI_OUT_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_OUT_FILTER_ID); | ||||
return (0); | return (0); | ||||
fail3: | |||||
EFSYS_PROBE(fail3); | |||||
fail2: | fail2: | ||||
EFSYS_PROBE(fail2); | EFSYS_PROBE(fail2); | ||||
fail1: | fail1: | ||||
EFSYS_PROBE1(fail1, int, rc); | EFSYS_PROBE1(fail1, int, rc); | ||||
return (rc); | return (rc); | ||||
} | } | ||||
__checkReturn int | __checkReturn int | ||||
efx_lightsout_offload_remove( | efx_lightsout_offload_remove( | ||||
__in efx_nic_t *enp, | __in efx_nic_t *enp, | ||||
__in efx_lightsout_offload_type_t type, | __in efx_lightsout_offload_type_t type, | ||||
__in uint32_t filter_id) | __in uint32_t filter_id) | ||||
{ | { | ||||
efx_mcdi_req_t req; | 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; | int rc; | ||||
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); | EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); | ||||
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL); | 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_cmd = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD; | ||||
req.emr_in_buf = payload; | req.emr_in_buf = payload; | ||||
req.emr_in_length = sizeof (payload); | req.emr_in_length = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN; | ||||
EFX_STATIC_ASSERT(MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN == 0); | req.emr_out_buf = payload; | ||||
req.emr_out_buf = NULL; | req.emr_out_length = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN; | ||||
req.emr_out_length = 0; | |||||
switch (type) { | switch (type) { | ||||
case EFX_LIGHTSOUT_OFFLOAD_TYPE_ARP: | case EFX_LIGHTSOUT_OFFLOAD_TYPE_ARP: | ||||
MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL, | MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL, | ||||
MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP); | MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP); | ||||
break; | break; | ||||
case EFX_LIGHTSOUT_OFFLOAD_TYPE_NS: | case EFX_LIGHTSOUT_OFFLOAD_TYPE_NS: | ||||
MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL, | MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL, | ||||
MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS); | MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS); | ||||
break; | break; | ||||
default: | default: | ||||
EFSYS_ASSERT3U(type, !=, type); | rc = EINVAL; | ||||
goto fail1; | |||||
} | } | ||||
MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_FILTER_ID, | MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_FILTER_ID, | ||||
filter_id); | filter_id); | ||||
efx_mcdi_execute(enp, &req); | efx_mcdi_execute(enp, &req); | ||||
if (req.emr_rc != 0) { | if (req.emr_rc != 0) { | ||||
rc = req.emr_rc; | rc = req.emr_rc; | ||||
goto fail1; | goto fail2; | ||||
} | } | ||||
return (0); | return (0); | ||||
fail2: | |||||
EFSYS_PROBE(fail2); | |||||
fail1: | fail1: | ||||
EFSYS_PROBE1(fail1, int, rc); | EFSYS_PROBE1(fail1, int, rc); | ||||
return (rc); | return (rc); | ||||
} | } | ||||
void | void | ||||
Show All 11 Lines |