Index: head/sys/dev/sfxge/common/efx_bootcfg.c =================================================================== --- head/sys/dev/sfxge/common/efx_bootcfg.c (revision 310691) +++ head/sys/dev/sfxge/common/efx_bootcfg.c (revision 310692) @@ -1,348 +1,348 @@ /*- * Copyright (c) 2009-2016 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. * * 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 __FBSDID("$FreeBSD$"); #include "efx.h" #include "efx_impl.h" #if EFSYS_OPT_BOOTCFG /* * Maximum size of BOOTCFG block across all nics as understood by SFCgPXE. * A multiple of 0x100 so trailing 0xff characters don't contrinbute to the * checksum. */ #define BOOTCFG_MAX_SIZE 0x1000 -#define DHCP_END (uint8_t)0xff -#define DHCP_PAD (uint8_t)0 +#define DHCP_END ((uint8_t)0xff) +#define DHCP_PAD ((uint8_t)0) static __checkReturn uint8_t efx_bootcfg_csum( __in efx_nic_t *enp, __in_bcount(size) caddr_t data, __in size_t size) { _NOTE(ARGUNUSED(enp)) unsigned int pos; uint8_t checksum = 0; for (pos = 0; pos < size; pos++) checksum += data[pos]; return (checksum); } static __checkReturn efx_rc_t efx_bootcfg_verify( __in efx_nic_t *enp, __in_bcount(size) caddr_t data, __in size_t size, __out_opt size_t *usedp) { size_t offset = 0; size_t used = 0; efx_rc_t rc; /* Start parsing tags immediately after the checksum */ for (offset = 1; offset < size; ) { uint8_t tag; uint8_t length; /* Consume tag */ tag = data[offset]; if (tag == DHCP_END) { offset++; used = offset; break; } if (tag == DHCP_PAD) { offset++; continue; } /* Consume length */ if (offset + 1 >= size) { rc = ENOSPC; goto fail1; } length = data[offset + 1]; /* Consume *length */ if (offset + 1 + length >= size) { rc = ENOSPC; goto fail2; } offset += 2 + length; used = offset; } /* Checksum the entire sector, including bytes after any DHCP_END */ if (efx_bootcfg_csum(enp, data, size) != 0) { rc = EINVAL; goto fail3; } if (usedp != NULL) *usedp = used; return (0); fail3: EFSYS_PROBE(fail3); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, efx_rc_t, rc); return (rc); } efx_rc_t efx_bootcfg_read( __in efx_nic_t *enp, __out_bcount(size) caddr_t data, __in size_t size) { uint8_t *payload = NULL; size_t used_bytes; size_t sector_length; efx_rc_t rc; rc = efx_nvram_size(enp, EFX_NVRAM_BOOTROM_CFG, §or_length); if (rc != 0) goto fail1; /* * We need to read the entire BOOTCFG area to ensure we read all the * tags, because legacy bootcfg sectors are not guaranteed to end with * a DHCP_END character. If the user hasn't supplied a sufficiently * large buffer then use our own buffer. */ if (sector_length > BOOTCFG_MAX_SIZE) sector_length = BOOTCFG_MAX_SIZE; if (sector_length > size) { EFSYS_KMEM_ALLOC(enp->en_esip, sector_length, payload); if (payload == NULL) { rc = ENOMEM; goto fail2; } } else payload = (uint8_t *)data; if ((rc = efx_nvram_rw_start(enp, EFX_NVRAM_BOOTROM_CFG, NULL)) != 0) goto fail3; rc = efx_nvram_read_chunk(enp, EFX_NVRAM_BOOTROM_CFG, 0, (caddr_t)payload, sector_length); efx_nvram_rw_finish(enp, EFX_NVRAM_BOOTROM_CFG); if (rc != 0) goto fail4; /* Verify that the area is correctly formatted and checksummed */ rc = efx_bootcfg_verify(enp, (caddr_t)payload, sector_length, &used_bytes); if (rc != 0 || used_bytes == 0) { payload[0] = (uint8_t)~DHCP_END; payload[1] = DHCP_END; used_bytes = 2; } EFSYS_ASSERT(used_bytes >= 2); /* checksum and DHCP_END */ EFSYS_ASSERT(used_bytes <= sector_length); /* * Legacy bootcfg sectors don't terminate with a DHCP_END character. * Modify the returned payload so it does. BOOTCFG_MAX_SIZE is by * definition large enough for any valid (per-port) bootcfg sector, * so reinitialise the sector if there isn't room for the character. */ if (payload[used_bytes - 1] != DHCP_END) { if (used_bytes + 1 > sector_length) { payload[0] = 0; used_bytes = 1; } payload[used_bytes] = DHCP_END; ++used_bytes; } /* * Verify that the user supplied buffer is large enough for the * entire used bootcfg area, then copy into the user supplied buffer. */ if (used_bytes > size) { rc = ENOSPC; goto fail5; } if (sector_length > size) { memcpy(data, payload, used_bytes); EFSYS_KMEM_FREE(enp->en_esip, sector_length, payload); } /* Zero out the unused portion of the user buffer */ if (used_bytes < size) (void) memset(data + used_bytes, 0, size - used_bytes); /* * The checksum includes trailing data after any DHCP_END character, * which we've just modified (by truncation or appending DHCP_END). */ data[0] -= efx_bootcfg_csum(enp, data, size); return (0); fail5: EFSYS_PROBE(fail5); fail4: EFSYS_PROBE(fail4); fail3: EFSYS_PROBE(fail3); if (sector_length > size) EFSYS_KMEM_FREE(enp->en_esip, sector_length, payload); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, efx_rc_t, rc); return (rc); } efx_rc_t efx_bootcfg_write( __in efx_nic_t *enp, __in_bcount(size) caddr_t data, __in size_t size) { uint8_t *chunk; uint8_t checksum; size_t sector_length; size_t chunk_length; size_t used_bytes; size_t offset; size_t remaining; efx_rc_t rc; rc = efx_nvram_size(enp, EFX_NVRAM_BOOTROM_CFG, §or_length); if (rc != 0) goto fail1; if (sector_length > BOOTCFG_MAX_SIZE) sector_length = BOOTCFG_MAX_SIZE; if ((rc = efx_bootcfg_verify(enp, data, size, &used_bytes)) != 0) goto fail2; /* The caller *must* terminate their block with a DHCP_END character */ EFSYS_ASSERT(used_bytes >= 2); /* checksum and DHCP_END */ if ((uint8_t)data[used_bytes - 1] != DHCP_END) { rc = ENOENT; goto fail3; } /* Check that the hardware has support for this much data */ if (used_bytes > MIN(sector_length, BOOTCFG_MAX_SIZE)) { rc = ENOSPC; goto fail4; } rc = efx_nvram_rw_start(enp, EFX_NVRAM_BOOTROM_CFG, &chunk_length); if (rc != 0) goto fail5; EFSYS_KMEM_ALLOC(enp->en_esip, chunk_length, chunk); if (chunk == NULL) { rc = ENOMEM; goto fail6; } if ((rc = efx_nvram_erase(enp, EFX_NVRAM_BOOTROM_CFG)) != 0) goto fail7; /* * Write the entire sector_length bytes of data in chunks. Zero out * all data following the DHCP_END, and adjust the checksum */ checksum = efx_bootcfg_csum(enp, data, used_bytes); for (offset = 0; offset < sector_length; offset += remaining) { remaining = MIN(chunk_length, sector_length - offset); /* Fill chunk */ (void) memset(chunk, 0x0, chunk_length); if (offset < used_bytes) memcpy(chunk, data + offset, MIN(remaining, used_bytes - offset)); /* Adjust checksum */ if (offset == 0) chunk[0] -= checksum; if ((rc = efx_nvram_write_chunk(enp, EFX_NVRAM_BOOTROM_CFG, offset, (caddr_t)chunk, remaining)) != 0) goto fail8; } efx_nvram_rw_finish(enp, EFX_NVRAM_BOOTROM_CFG); EFSYS_KMEM_FREE(enp->en_esip, chunk_length, chunk); return (0); fail8: EFSYS_PROBE(fail8); fail7: EFSYS_PROBE(fail7); EFSYS_KMEM_FREE(enp->en_esip, chunk_length, chunk); fail6: EFSYS_PROBE(fail6); efx_nvram_rw_finish(enp, EFX_NVRAM_BOOTROM_CFG); fail5: EFSYS_PROBE(fail5); fail4: EFSYS_PROBE(fail4); fail3: EFSYS_PROBE(fail3); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, efx_rc_t, rc); return (rc); } #endif /* EFSYS_OPT_BOOTCFG */ Index: head/sys/dev/sfxge/common/efx_types.h =================================================================== --- head/sys/dev/sfxge/common/efx_types.h (revision 310691) +++ head/sys/dev/sfxge/common/efx_types.h (revision 310692) @@ -1,1649 +1,1649 @@ /*- * Copyright (c) 2007-2016 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. * * 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. * * Ackowledgement to Fen Systems Ltd. * * $FreeBSD$ */ #ifndef _SYS_EFX_TYPES_H #define _SYS_EFX_TYPES_H #include "efsys.h" #ifdef __cplusplus extern "C" { #endif /* * Bitfield access * * Solarflare NICs make extensive use of bitfields up to 128 bits * wide. Since there is no native 128-bit datatype on most systems, * and since 64-bit datatypes are inefficient on 32-bit systems and * vice versa, we wrap accesses in a way that uses the most efficient * datatype. * * The NICs are PCI devices and therefore little-endian. Since most * of the quantities that we deal with are DMAed to/from host memory, * we define our datatypes (efx_oword_t, efx_qword_t and efx_dword_t) * to be little-endian. * * In the less common case of using PIO for individual register * writes, we construct the little-endian datatype in host memory and * then use non-swapping register access primitives, rather than * constructing a native-endian datatype and relying on implicit * byte-swapping. (We use a similar strategy for register reads.) */ /* * NOTE: Field definitions here and elsewhere are done in terms of a lowest * bit number (LBN) and a width. */ #define EFX_DUMMY_FIELD_LBN 0 #define EFX_DUMMY_FIELD_WIDTH 0 #define EFX_BYTE_0_LBN 0 #define EFX_BYTE_0_WIDTH 8 #define EFX_BYTE_1_LBN 8 #define EFX_BYTE_1_WIDTH 8 #define EFX_BYTE_2_LBN 16 #define EFX_BYTE_2_WIDTH 8 #define EFX_BYTE_3_LBN 24 #define EFX_BYTE_3_WIDTH 8 #define EFX_BYTE_4_LBN 32 #define EFX_BYTE_4_WIDTH 8 #define EFX_BYTE_5_LBN 40 #define EFX_BYTE_5_WIDTH 8 #define EFX_BYTE_6_LBN 48 #define EFX_BYTE_6_WIDTH 8 #define EFX_BYTE_7_LBN 56 #define EFX_BYTE_7_WIDTH 8 #define EFX_WORD_0_LBN 0 #define EFX_WORD_0_WIDTH 16 #define EFX_WORD_1_LBN 16 #define EFX_WORD_1_WIDTH 16 #define EFX_WORD_2_LBN 32 #define EFX_WORD_2_WIDTH 16 #define EFX_WORD_3_LBN 48 #define EFX_WORD_3_WIDTH 16 #define EFX_DWORD_0_LBN 0 #define EFX_DWORD_0_WIDTH 32 #define EFX_DWORD_1_LBN 32 #define EFX_DWORD_1_WIDTH 32 #define EFX_DWORD_2_LBN 64 #define EFX_DWORD_2_WIDTH 32 #define EFX_DWORD_3_LBN 96 #define EFX_DWORD_3_WIDTH 32 /* There are intentionally no EFX_QWORD_0 or EFX_QWORD_1 field definitions * here as the implementaion of EFX_QWORD_FIELD and EFX_OWORD_FIELD do not * support field widths larger than 32 bits. */ /* Specified attribute (i.e. LBN ow WIDTH) of the specified field */ #define EFX_VAL(_field, _attribute) \ _field ## _ ## _attribute /* Lowest bit number of the specified field */ #define EFX_LOW_BIT(_field) \ EFX_VAL(_field, LBN) /* Width of the specified field */ #define EFX_WIDTH(_field) \ EFX_VAL(_field, WIDTH) /* Highest bit number of the specified field */ #define EFX_HIGH_BIT(_field) \ (EFX_LOW_BIT(_field) + EFX_WIDTH(_field) - 1) /* * 64-bit mask equal in width to the specified field. * * For example, a field with width 5 would have a mask of 0x000000000000001f. */ #define EFX_MASK64(_field) \ ((EFX_WIDTH(_field) == 64) ? ~((uint64_t)0) : \ (((((uint64_t)1) << EFX_WIDTH(_field))) - 1)) /* * 32-bit mask equal in width to the specified field. * * For example, a field with width 5 would have a mask of 0x0000001f. */ #define EFX_MASK32(_field) \ ((EFX_WIDTH(_field) == 32) ? ~((uint32_t)0) : \ (((((uint32_t)1) << EFX_WIDTH(_field))) - 1)) /* * 16-bit mask equal in width to the specified field. * * For example, a field with width 5 would have a mask of 0x001f. */ #define EFX_MASK16(_field) \ ((EFX_WIDTH(_field) == 16) ? 0xffffu : \ (uint16_t)((1 << EFX_WIDTH(_field)) - 1)) /* * 8-bit mask equal in width to the specified field. * * For example, a field with width 5 would have a mask of 0x1f. */ #define EFX_MASK8(_field) \ ((uint8_t)((1 << EFX_WIDTH(_field)) - 1)) #pragma pack(1) /* * A byte (i.e. 8-bit) datatype */ typedef union efx_byte_u { uint8_t eb_u8[1]; } efx_byte_t; /* * A word (i.e. 16-bit) datatype * * This datatype is defined to be little-endian. */ typedef union efx_word_u { efx_byte_t ew_byte[2]; uint16_t ew_u16[1]; uint8_t ew_u8[2]; } efx_word_t; /* * A doubleword (i.e. 32-bit) datatype * * This datatype is defined to be little-endian. */ typedef union efx_dword_u { efx_byte_t ed_byte[4]; efx_word_t ed_word[2]; uint32_t ed_u32[1]; uint16_t ed_u16[2]; uint8_t ed_u8[4]; } efx_dword_t; /* * A quadword (i.e. 64-bit) datatype * * This datatype is defined to be little-endian. */ typedef union efx_qword_u { efx_byte_t eq_byte[8]; efx_word_t eq_word[4]; efx_dword_t eq_dword[2]; #if EFSYS_HAS_UINT64 uint64_t eq_u64[1]; #endif uint32_t eq_u32[2]; uint16_t eq_u16[4]; uint8_t eq_u8[8]; } efx_qword_t; /* * An octword (i.e. 128-bit) datatype * * This datatype is defined to be little-endian. */ typedef union efx_oword_u { efx_byte_t eo_byte[16]; efx_word_t eo_word[8]; efx_dword_t eo_dword[4]; efx_qword_t eo_qword[2]; #if EFSYS_HAS_SSE2_M128 __m128i eo_u128[1]; #endif #if EFSYS_HAS_UINT64 uint64_t eo_u64[2]; #endif uint32_t eo_u32[4]; uint16_t eo_u16[8]; uint8_t eo_u8[16]; } efx_oword_t; #pragma pack() #define __SWAP16(_x) \ ((((_x) & 0xff) << 8) | \ (((_x) >> 8) & 0xff)) #define __SWAP32(_x) \ ((__SWAP16((_x) & 0xffff) << 16) | \ __SWAP16(((_x) >> 16) & 0xffff)) #define __SWAP64(_x) \ ((__SWAP32((_x) & 0xffffffff) << 32) | \ __SWAP32(((_x) >> 32) & 0xffffffff)) #define __NOSWAP16(_x) (_x) #define __NOSWAP32(_x) (_x) #define __NOSWAP64(_x) (_x) #if EFSYS_IS_BIG_ENDIAN -#define __CPU_TO_LE_16(_x) (uint16_t)__SWAP16(_x) -#define __LE_TO_CPU_16(_x) (uint16_t)__SWAP16(_x) -#define __CPU_TO_BE_16(_x) (uint16_t)__NOSWAP16(_x) -#define __BE_TO_CPU_16(_x) (uint16_t)__NOSWAP16(_x) +#define __CPU_TO_LE_16(_x) ((uint16_t)__SWAP16(_x)) +#define __LE_TO_CPU_16(_x) ((uint16_t)__SWAP16(_x)) +#define __CPU_TO_BE_16(_x) ((uint16_t)__NOSWAP16(_x)) +#define __BE_TO_CPU_16(_x) ((uint16_t)__NOSWAP16(_x)) -#define __CPU_TO_LE_32(_x) (uint32_t)__SWAP32(_x) -#define __LE_TO_CPU_32(_x) (uint32_t)__SWAP32(_x) -#define __CPU_TO_BE_32(_x) (uint32_t)__NOSWAP32(_x) -#define __BE_TO_CPU_32(_x) (uint32_t)__NOSWAP32(_x) +#define __CPU_TO_LE_32(_x) ((uint32_t)__SWAP32(_x)) +#define __LE_TO_CPU_32(_x) ((uint32_t)__SWAP32(_x)) +#define __CPU_TO_BE_32(_x) ((uint32_t)__NOSWAP32(_x)) +#define __BE_TO_CPU_32(_x) ((uint32_t)__NOSWAP32(_x)) -#define __CPU_TO_LE_64(_x) (uint64_t)__SWAP64(_x) -#define __LE_TO_CPU_64(_x) (uint64_t)__SWAP64(_x) -#define __CPU_TO_BE_64(_x) (uint64_t)__NOSWAP64(_x) -#define __BE_TO_CPU_64(_x) (uint64_t)__NOSWAP64(_x) +#define __CPU_TO_LE_64(_x) ((uint64_t)__SWAP64(_x)) +#define __LE_TO_CPU_64(_x) ((uint64_t)__SWAP64(_x)) +#define __CPU_TO_BE_64(_x) ((uint64_t)__NOSWAP64(_x)) +#define __BE_TO_CPU_64(_x) ((uint64_t)__NOSWAP64(_x)) #elif EFSYS_IS_LITTLE_ENDIAN -#define __CPU_TO_LE_16(_x) (uint16_t)__NOSWAP16(_x) -#define __LE_TO_CPU_16(_x) (uint16_t)__NOSWAP16(_x) -#define __CPU_TO_BE_16(_x) (uint16_t)__SWAP16(_x) -#define __BE_TO_CPU_16(_x) (uint16_t)__SWAP16(_x) +#define __CPU_TO_LE_16(_x) ((uint16_t)__NOSWAP16(_x)) +#define __LE_TO_CPU_16(_x) ((uint16_t)__NOSWAP16(_x)) +#define __CPU_TO_BE_16(_x) ((uint16_t)__SWAP16(_x)) +#define __BE_TO_CPU_16(_x) ((uint16_t)__SWAP16(_x)) -#define __CPU_TO_LE_32(_x) (uint32_t)__NOSWAP32(_x) -#define __LE_TO_CPU_32(_x) (uint32_t)__NOSWAP32(_x) -#define __CPU_TO_BE_32(_x) (uint32_t)__SWAP32(_x) -#define __BE_TO_CPU_32(_x) (uint32_t)__SWAP32(_x) +#define __CPU_TO_LE_32(_x) ((uint32_t)__NOSWAP32(_x)) +#define __LE_TO_CPU_32(_x) ((uint32_t)__NOSWAP32(_x)) +#define __CPU_TO_BE_32(_x) ((uint32_t)__SWAP32(_x)) +#define __BE_TO_CPU_32(_x) ((uint32_t)__SWAP32(_x)) -#define __CPU_TO_LE_64(_x) (uint64_t)__NOSWAP64(_x) -#define __LE_TO_CPU_64(_x) (uint64_t)__NOSWAP64(_x) -#define __CPU_TO_BE_64(_x) (uint64_t)__SWAP64(_x) -#define __BE_TO_CPU_64(_x) (uint64_t)__SWAP64(_x) +#define __CPU_TO_LE_64(_x) ((uint64_t)__NOSWAP64(_x)) +#define __LE_TO_CPU_64(_x) ((uint64_t)__NOSWAP64(_x)) +#define __CPU_TO_BE_64(_x) ((uint64_t)__SWAP64(_x)) +#define __BE_TO_CPU_64(_x) ((uint64_t)__SWAP64(_x)) #else #error "Neither of EFSYS_IS_{BIG,LITTLE}_ENDIAN is set" #endif #define __NATIVE_8(_x) (uint8_t)(_x) /* Format string for printing an efx_byte_t */ #define EFX_BYTE_FMT "0x%02x" /* Format string for printing an efx_word_t */ #define EFX_WORD_FMT "0x%04x" /* Format string for printing an efx_dword_t */ #define EFX_DWORD_FMT "0x%08x" /* Format string for printing an efx_qword_t */ #define EFX_QWORD_FMT "0x%08x:%08x" /* Format string for printing an efx_oword_t */ #define EFX_OWORD_FMT "0x%08x:%08x:%08x:%08x" /* Parameters for printing an efx_byte_t */ #define EFX_BYTE_VAL(_byte) \ ((unsigned int)__NATIVE_8((_byte).eb_u8[0])) /* Parameters for printing an efx_word_t */ #define EFX_WORD_VAL(_word) \ ((unsigned int)__LE_TO_CPU_16((_word).ew_u16[0])) /* Parameters for printing an efx_dword_t */ #define EFX_DWORD_VAL(_dword) \ ((unsigned int)__LE_TO_CPU_32((_dword).ed_u32[0])) /* Parameters for printing an efx_qword_t */ #define EFX_QWORD_VAL(_qword) \ ((unsigned int)__LE_TO_CPU_32((_qword).eq_u32[1])), \ ((unsigned int)__LE_TO_CPU_32((_qword).eq_u32[0])) /* Parameters for printing an efx_oword_t */ #define EFX_OWORD_VAL(_oword) \ ((unsigned int)__LE_TO_CPU_32((_oword).eo_u32[3])), \ ((unsigned int)__LE_TO_CPU_32((_oword).eo_u32[2])), \ ((unsigned int)__LE_TO_CPU_32((_oword).eo_u32[1])), \ ((unsigned int)__LE_TO_CPU_32((_oword).eo_u32[0])) /* * Stop lint complaining about some shifts. */ #ifdef __lint extern int fix_lint; #define FIX_LINT(_x) (_x + fix_lint) #else #define FIX_LINT(_x) (_x) #endif /* * Extract bit field portion [low,high) from the native-endian element * which contains bits [min,max). * * For example, suppose "element" represents the high 32 bits of a * 64-bit value, and we wish to extract the bits belonging to the bit * field occupying bits 28-45 of this 64-bit value. * * Then EFX_EXTRACT(_element, 32, 63, 28, 45) would give * * (_element) << 4 * * The result will contain the relevant bits filled in in the range * [0,high-low), with garbage in bits [high-low+1,...). */ #define EFX_EXTRACT_NATIVE(_element, _min, _max, _low, _high) \ ((FIX_LINT(_low > _max) || FIX_LINT(_high < _min)) ? \ 0U : \ ((_low > _min) ? \ ((_element) >> (_low - _min)) : \ ((_element) << (_min - _low)))) /* * Extract bit field portion [low,high) from the 64-bit little-endian * element which contains bits [min,max) */ #define EFX_EXTRACT64(_element, _min, _max, _low, _high) \ EFX_EXTRACT_NATIVE(__LE_TO_CPU_64(_element), _min, _max, _low, _high) /* * Extract bit field portion [low,high) from the 32-bit little-endian * element which contains bits [min,max) */ #define EFX_EXTRACT32(_element, _min, _max, _low, _high) \ EFX_EXTRACT_NATIVE(__LE_TO_CPU_32(_element), _min, _max, _low, _high) /* * Extract bit field portion [low,high) from the 16-bit little-endian * element which contains bits [min,max) */ #define EFX_EXTRACT16(_element, _min, _max, _low, _high) \ EFX_EXTRACT_NATIVE(__LE_TO_CPU_16(_element), _min, _max, _low, _high) /* * Extract bit field portion [low,high) from the 8-bit * element which contains bits [min,max) */ #define EFX_EXTRACT8(_element, _min, _max, _low, _high) \ EFX_EXTRACT_NATIVE(__NATIVE_8(_element), _min, _max, _low, _high) #define EFX_EXTRACT_OWORD64(_oword, _low, _high) \ (EFX_EXTRACT64((_oword).eo_u64[0], FIX_LINT(0), FIX_LINT(63), \ _low, _high) | \ EFX_EXTRACT64((_oword).eo_u64[1], FIX_LINT(64), FIX_LINT(127), \ _low, _high)) #define EFX_EXTRACT_OWORD32(_oword, _low, _high) \ (EFX_EXTRACT32((_oword).eo_u32[0], FIX_LINT(0), FIX_LINT(31), \ _low, _high) | \ EFX_EXTRACT32((_oword).eo_u32[1], FIX_LINT(32), FIX_LINT(63), \ _low, _high) | \ EFX_EXTRACT32((_oword).eo_u32[2], FIX_LINT(64), FIX_LINT(95), \ _low, _high) | \ EFX_EXTRACT32((_oword).eo_u32[3], FIX_LINT(96), FIX_LINT(127), \ _low, _high)) #define EFX_EXTRACT_QWORD64(_qword, _low, _high) \ (EFX_EXTRACT64((_qword).eq_u64[0], FIX_LINT(0), FIX_LINT(63), \ _low, _high)) #define EFX_EXTRACT_QWORD32(_qword, _low, _high) \ (EFX_EXTRACT32((_qword).eq_u32[0], FIX_LINT(0), FIX_LINT(31), \ _low, _high) | \ EFX_EXTRACT32((_qword).eq_u32[1], FIX_LINT(32), FIX_LINT(63), \ _low, _high)) #define EFX_EXTRACT_DWORD(_dword, _low, _high) \ (EFX_EXTRACT32((_dword).ed_u32[0], FIX_LINT(0), FIX_LINT(31), \ _low, _high)) #define EFX_EXTRACT_WORD(_word, _low, _high) \ (EFX_EXTRACT16((_word).ew_u16[0], FIX_LINT(0), FIX_LINT(15), \ _low, _high)) #define EFX_EXTRACT_BYTE(_byte, _low, _high) \ (EFX_EXTRACT8((_byte).eb_u8[0], FIX_LINT(0), FIX_LINT(7), \ _low, _high)) #define EFX_OWORD_FIELD64(_oword, _field) \ ((uint32_t)EFX_EXTRACT_OWORD64(_oword, EFX_LOW_BIT(_field), \ EFX_HIGH_BIT(_field)) & EFX_MASK32(_field)) #define EFX_OWORD_FIELD32(_oword, _field) \ (EFX_EXTRACT_OWORD32(_oword, EFX_LOW_BIT(_field), \ EFX_HIGH_BIT(_field)) & EFX_MASK32(_field)) #define EFX_QWORD_FIELD64(_qword, _field) \ ((uint32_t)EFX_EXTRACT_QWORD64(_qword, EFX_LOW_BIT(_field), \ EFX_HIGH_BIT(_field)) & EFX_MASK32(_field)) #define EFX_QWORD_FIELD32(_qword, _field) \ (EFX_EXTRACT_QWORD32(_qword, EFX_LOW_BIT(_field), \ EFX_HIGH_BIT(_field)) & EFX_MASK32(_field)) #define EFX_DWORD_FIELD(_dword, _field) \ (EFX_EXTRACT_DWORD(_dword, EFX_LOW_BIT(_field), \ EFX_HIGH_BIT(_field)) & EFX_MASK32(_field)) #define EFX_WORD_FIELD(_word, _field) \ (EFX_EXTRACT_WORD(_word, EFX_LOW_BIT(_field), \ EFX_HIGH_BIT(_field)) & EFX_MASK16(_field)) #define EFX_BYTE_FIELD(_byte, _field) \ (EFX_EXTRACT_BYTE(_byte, EFX_LOW_BIT(_field), \ EFX_HIGH_BIT(_field)) & EFX_MASK8(_field)) #define EFX_OWORD_IS_EQUAL64(_oword_a, _oword_b) \ ((_oword_a).eo_u64[0] == (_oword_b).eo_u64[0] && \ (_oword_a).eo_u64[1] == (_oword_b).eo_u64[1]) #define EFX_OWORD_IS_EQUAL32(_oword_a, _oword_b) \ ((_oword_a).eo_u32[0] == (_oword_b).eo_u32[0] && \ (_oword_a).eo_u32[1] == (_oword_b).eo_u32[1] && \ (_oword_a).eo_u32[2] == (_oword_b).eo_u32[2] && \ (_oword_a).eo_u32[3] == (_oword_b).eo_u32[3]) #define EFX_QWORD_IS_EQUAL64(_qword_a, _qword_b) \ ((_qword_a).eq_u64[0] == (_qword_b).eq_u64[0]) #define EFX_QWORD_IS_EQUAL32(_qword_a, _qword_b) \ ((_qword_a).eq_u32[0] == (_qword_b).eq_u32[0] && \ (_qword_a).eq_u32[1] == (_qword_b).eq_u32[1]) #define EFX_DWORD_IS_EQUAL(_dword_a, _dword_b) \ ((_dword_a).ed_u32[0] == (_dword_b).ed_u32[0]) #define EFX_WORD_IS_EQUAL(_word_a, _word_b) \ ((_word_a).ew_u16[0] == (_word_b).ew_u16[0]) #define EFX_BYTE_IS_EQUAL(_byte_a, _byte_b) \ ((_byte_a).eb_u8[0] == (_byte_b).eb_u8[0]) #define EFX_OWORD_IS_ZERO64(_oword) \ (((_oword).eo_u64[0] | \ (_oword).eo_u64[1]) == 0) #define EFX_OWORD_IS_ZERO32(_oword) \ (((_oword).eo_u32[0] | \ (_oword).eo_u32[1] | \ (_oword).eo_u32[2] | \ (_oword).eo_u32[3]) == 0) #define EFX_QWORD_IS_ZERO64(_qword) \ (((_qword).eq_u64[0]) == 0) #define EFX_QWORD_IS_ZERO32(_qword) \ (((_qword).eq_u32[0] | \ (_qword).eq_u32[1]) == 0) #define EFX_DWORD_IS_ZERO(_dword) \ (((_dword).ed_u32[0]) == 0) #define EFX_WORD_IS_ZERO(_word) \ (((_word).ew_u16[0]) == 0) #define EFX_BYTE_IS_ZERO(_byte) \ (((_byte).eb_u8[0]) == 0) #define EFX_OWORD_IS_SET64(_oword) \ (((_oword).eo_u64[0] & \ (_oword).eo_u64[1]) == ~((uint64_t)0)) #define EFX_OWORD_IS_SET32(_oword) \ (((_oword).eo_u32[0] & \ (_oword).eo_u32[1] & \ (_oword).eo_u32[2] & \ (_oword).eo_u32[3]) == ~((uint32_t)0)) #define EFX_QWORD_IS_SET64(_qword) \ (((_qword).eq_u64[0]) == ~((uint64_t)0)) #define EFX_QWORD_IS_SET32(_qword) \ (((_qword).eq_u32[0] & \ (_qword).eq_u32[1]) == ~((uint32_t)0)) #define EFX_DWORD_IS_SET(_dword) \ ((_dword).ed_u32[0] == ~((uint32_t)0)) #define EFX_WORD_IS_SET(_word) \ ((_word).ew_u16[0] == ~((uint16_t)0)) #define EFX_BYTE_IS_SET(_byte) \ ((_byte).eb_u8[0] == ~((uint8_t)0)) /* * Construct bit field portion * * Creates the portion of the bit field [low,high) that lies within * the range [min,max). */ #define EFX_INSERT_NATIVE64(_min, _max, _low, _high, _value) \ (((_low > _max) || (_high < _min)) ? \ 0U : \ ((_low > _min) ? \ (((uint64_t)(_value)) << (_low - _min)) : \ (((uint64_t)(_value)) >> (_min - _low)))) #define EFX_INSERT_NATIVE32(_min, _max, _low, _high, _value) \ (((_low > _max) || (_high < _min)) ? \ 0U : \ ((_low > _min) ? \ (((uint32_t)(_value)) << (_low - _min)) : \ (((uint32_t)(_value)) >> (_min - _low)))) #define EFX_INSERT_NATIVE16(_min, _max, _low, _high, _value) \ (((_low > _max) || (_high < _min)) ? \ 0U : \ (uint16_t)((_low > _min) ? \ ((_value) << (_low - _min)) : \ ((_value) >> (_min - _low)))) #define EFX_INSERT_NATIVE8(_min, _max, _low, _high, _value) \ (((_low > _max) || (_high < _min)) ? \ 0U : \ (uint8_t)((_low > _min) ? \ ((_value) << (_low - _min)) : \ ((_value) >> (_min - _low)))) /* * Construct bit field portion * * Creates the portion of the named bit field that lies within the * range [min,max). */ #define EFX_INSERT_FIELD_NATIVE64(_min, _max, _field, _value) \ EFX_INSERT_NATIVE64(_min, _max, EFX_LOW_BIT(_field), \ EFX_HIGH_BIT(_field), _value) #define EFX_INSERT_FIELD_NATIVE32(_min, _max, _field, _value) \ EFX_INSERT_NATIVE32(_min, _max, EFX_LOW_BIT(_field), \ EFX_HIGH_BIT(_field), _value) #define EFX_INSERT_FIELD_NATIVE16(_min, _max, _field, _value) \ EFX_INSERT_NATIVE16(_min, _max, EFX_LOW_BIT(_field), \ EFX_HIGH_BIT(_field), _value) #define EFX_INSERT_FIELD_NATIVE8(_min, _max, _field, _value) \ EFX_INSERT_NATIVE8(_min, _max, EFX_LOW_BIT(_field), \ EFX_HIGH_BIT(_field), _value) /* * Construct bit field * * Creates the portion of the named bit fields that lie within the * range [min,max). */ #define EFX_INSERT_FIELDS64(_min, _max, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9, \ _field10, _value10) \ __CPU_TO_LE_64( \ EFX_INSERT_FIELD_NATIVE64(_min, _max, _field1, _value1) | \ EFX_INSERT_FIELD_NATIVE64(_min, _max, _field2, _value2) | \ EFX_INSERT_FIELD_NATIVE64(_min, _max, _field3, _value3) | \ EFX_INSERT_FIELD_NATIVE64(_min, _max, _field4, _value4) | \ EFX_INSERT_FIELD_NATIVE64(_min, _max, _field5, _value5) | \ EFX_INSERT_FIELD_NATIVE64(_min, _max, _field6, _value6) | \ EFX_INSERT_FIELD_NATIVE64(_min, _max, _field7, _value7) | \ EFX_INSERT_FIELD_NATIVE64(_min, _max, _field8, _value8) | \ EFX_INSERT_FIELD_NATIVE64(_min, _max, _field9, _value9) | \ EFX_INSERT_FIELD_NATIVE64(_min, _max, _field10, _value10)) #define EFX_INSERT_FIELDS32(_min, _max, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9, \ _field10, _value10) \ __CPU_TO_LE_32( \ EFX_INSERT_FIELD_NATIVE32(_min, _max, _field1, _value1) | \ EFX_INSERT_FIELD_NATIVE32(_min, _max, _field2, _value2) | \ EFX_INSERT_FIELD_NATIVE32(_min, _max, _field3, _value3) | \ EFX_INSERT_FIELD_NATIVE32(_min, _max, _field4, _value4) | \ EFX_INSERT_FIELD_NATIVE32(_min, _max, _field5, _value5) | \ EFX_INSERT_FIELD_NATIVE32(_min, _max, _field6, _value6) | \ EFX_INSERT_FIELD_NATIVE32(_min, _max, _field7, _value7) | \ EFX_INSERT_FIELD_NATIVE32(_min, _max, _field8, _value8) | \ EFX_INSERT_FIELD_NATIVE32(_min, _max, _field9, _value9) | \ EFX_INSERT_FIELD_NATIVE32(_min, _max, _field10, _value10)) #define EFX_INSERT_FIELDS16(_min, _max, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9, \ _field10, _value10) \ __CPU_TO_LE_16( \ EFX_INSERT_FIELD_NATIVE16(_min, _max, _field1, _value1) | \ EFX_INSERT_FIELD_NATIVE16(_min, _max, _field2, _value2) | \ EFX_INSERT_FIELD_NATIVE16(_min, _max, _field3, _value3) | \ EFX_INSERT_FIELD_NATIVE16(_min, _max, _field4, _value4) | \ EFX_INSERT_FIELD_NATIVE16(_min, _max, _field5, _value5) | \ EFX_INSERT_FIELD_NATIVE16(_min, _max, _field6, _value6) | \ EFX_INSERT_FIELD_NATIVE16(_min, _max, _field7, _value7) | \ EFX_INSERT_FIELD_NATIVE16(_min, _max, _field8, _value8) | \ EFX_INSERT_FIELD_NATIVE16(_min, _max, _field9, _value9) | \ EFX_INSERT_FIELD_NATIVE16(_min, _max, _field10, _value10)) #define EFX_INSERT_FIELDS8(_min, _max, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9, \ _field10, _value10) \ __NATIVE_8( \ EFX_INSERT_FIELD_NATIVE8(_min, _max, _field1, _value1) | \ EFX_INSERT_FIELD_NATIVE8(_min, _max, _field2, _value2) | \ EFX_INSERT_FIELD_NATIVE8(_min, _max, _field3, _value3) | \ EFX_INSERT_FIELD_NATIVE8(_min, _max, _field4, _value4) | \ EFX_INSERT_FIELD_NATIVE8(_min, _max, _field5, _value5) | \ EFX_INSERT_FIELD_NATIVE8(_min, _max, _field6, _value6) | \ EFX_INSERT_FIELD_NATIVE8(_min, _max, _field7, _value7) | \ EFX_INSERT_FIELD_NATIVE8(_min, _max, _field8, _value8) | \ EFX_INSERT_FIELD_NATIVE8(_min, _max, _field9, _value9) | \ EFX_INSERT_FIELD_NATIVE8(_min, _max, _field10, _value10)) #define EFX_POPULATE_OWORD64(_oword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9, \ _field10, _value10) \ do { \ _NOTE(CONSTANTCONDITION) \ (_oword).eo_u64[0] = EFX_INSERT_FIELDS64(0, 63, \ _field1, _value1, _field2, _value2, \ _field3, _value3, _field4, _value4, \ _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, \ _field9, _value9, _field10, _value10); \ _NOTE(CONSTANTCONDITION) \ (_oword).eo_u64[1] = EFX_INSERT_FIELDS64(64, 127, \ _field1, _value1, _field2, _value2, \ _field3, _value3, _field4, _value4, \ _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, \ _field9, _value9, _field10, _value10); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_POPULATE_OWORD32(_oword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9, \ _field10, _value10) \ do { \ _NOTE(CONSTANTCONDITION) \ (_oword).eo_u32[0] = EFX_INSERT_FIELDS32(0, 31, \ _field1, _value1, _field2, _value2, \ _field3, _value3, _field4, _value4, \ _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, \ _field9, _value9, _field10, _value10); \ _NOTE(CONSTANTCONDITION) \ (_oword).eo_u32[1] = EFX_INSERT_FIELDS32(32, 63, \ _field1, _value1, _field2, _value2, \ _field3, _value3, _field4, _value4, \ _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, \ _field9, _value9, _field10, _value10); \ _NOTE(CONSTANTCONDITION) \ (_oword).eo_u32[2] = EFX_INSERT_FIELDS32(64, 95, \ _field1, _value1, _field2, _value2, \ _field3, _value3, _field4, _value4, \ _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, \ _field9, _value9, _field10, _value10); \ _NOTE(CONSTANTCONDITION) \ (_oword).eo_u32[3] = EFX_INSERT_FIELDS32(96, 127, \ _field1, _value1, _field2, _value2, \ _field3, _value3, _field4, _value4, \ _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, \ _field9, _value9, _field10, _value10); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_POPULATE_QWORD64(_qword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9, \ _field10, _value10) \ do { \ _NOTE(CONSTANTCONDITION) \ (_qword).eq_u64[0] = EFX_INSERT_FIELDS64(0, 63, \ _field1, _value1, _field2, _value2, \ _field3, _value3, _field4, _value4, \ _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, \ _field9, _value9, _field10, _value10); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_POPULATE_QWORD32(_qword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9, \ _field10, _value10) \ do { \ _NOTE(CONSTANTCONDITION) \ (_qword).eq_u32[0] = EFX_INSERT_FIELDS32(0, 31, \ _field1, _value1, _field2, _value2, \ _field3, _value3, _field4, _value4, \ _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, \ _field9, _value9, _field10, _value10); \ _NOTE(CONSTANTCONDITION) \ (_qword).eq_u32[1] = EFX_INSERT_FIELDS32(32, 63, \ _field1, _value1, _field2, _value2, \ _field3, _value3, _field4, _value4, \ _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, \ _field9, _value9, _field10, _value10); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_POPULATE_DWORD(_dword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9, \ _field10, _value10) \ do { \ _NOTE(CONSTANTCONDITION) \ (_dword).ed_u32[0] = EFX_INSERT_FIELDS32(0, 31, \ _field1, _value1, _field2, _value2, \ _field3, _value3, _field4, _value4, \ _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, \ _field9, _value9, _field10, _value10); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_POPULATE_WORD(_word, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9, \ _field10, _value10) \ do { \ _NOTE(CONSTANTCONDITION) \ (_word).ew_u16[0] = EFX_INSERT_FIELDS16(0, 15, \ _field1, _value1, _field2, _value2, \ _field3, _value3, _field4, _value4, \ _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, \ _field9, _value9, _field10, _value10); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_POPULATE_BYTE(_byte, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9, \ _field10, _value10) \ do { \ _NOTE(CONSTANTCONDITION) \ (_byte).eb_u8[0] = EFX_INSERT_FIELDS8(0, 7, \ _field1, _value1, _field2, _value2, \ _field3, _value3, _field4, _value4, \ _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, \ _field9, _value9, _field10, _value10); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) /* Populate an octword field with various numbers of arguments */ #define EFX_POPULATE_OWORD_10 EFX_POPULATE_OWORD #define EFX_POPULATE_OWORD_9(_oword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9) \ EFX_POPULATE_OWORD_10(_oword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9) #define EFX_POPULATE_OWORD_8(_oword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8) \ EFX_POPULATE_OWORD_9(_oword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8) #define EFX_POPULATE_OWORD_7(_oword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7) \ EFX_POPULATE_OWORD_8(_oword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7) #define EFX_POPULATE_OWORD_6(_oword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6) \ EFX_POPULATE_OWORD_7(_oword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6) #define EFX_POPULATE_OWORD_5(_oword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5) \ EFX_POPULATE_OWORD_6(_oword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5) #define EFX_POPULATE_OWORD_4(_oword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4) \ EFX_POPULATE_OWORD_5(_oword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4) #define EFX_POPULATE_OWORD_3(_oword, \ _field1, _value1, _field2, _value2, _field3, _value3) \ EFX_POPULATE_OWORD_4(_oword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3) #define EFX_POPULATE_OWORD_2(_oword, \ _field1, _value1, _field2, _value2) \ EFX_POPULATE_OWORD_3(_oword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2) #define EFX_POPULATE_OWORD_1(_oword, \ _field1, _value1) \ EFX_POPULATE_OWORD_2(_oword, EFX_DUMMY_FIELD, 0, \ _field1, _value1) #define EFX_ZERO_OWORD(_oword) \ EFX_POPULATE_OWORD_1(_oword, EFX_DUMMY_FIELD, 0) #define EFX_SET_OWORD(_oword) \ EFX_POPULATE_OWORD_4(_oword, \ EFX_DWORD_0, 0xffffffff, EFX_DWORD_1, 0xffffffff, \ EFX_DWORD_2, 0xffffffff, EFX_DWORD_3, 0xffffffff) /* Populate a quadword field with various numbers of arguments */ #define EFX_POPULATE_QWORD_10 EFX_POPULATE_QWORD #define EFX_POPULATE_QWORD_9(_qword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9) \ EFX_POPULATE_QWORD_10(_qword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9) #define EFX_POPULATE_QWORD_8(_qword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8) \ EFX_POPULATE_QWORD_9(_qword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8) #define EFX_POPULATE_QWORD_7(_qword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7) \ EFX_POPULATE_QWORD_8(_qword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7) #define EFX_POPULATE_QWORD_6(_qword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6) \ EFX_POPULATE_QWORD_7(_qword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6) #define EFX_POPULATE_QWORD_5(_qword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5) \ EFX_POPULATE_QWORD_6(_qword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5) #define EFX_POPULATE_QWORD_4(_qword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4) \ EFX_POPULATE_QWORD_5(_qword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4) #define EFX_POPULATE_QWORD_3(_qword, \ _field1, _value1, _field2, _value2, _field3, _value3) \ EFX_POPULATE_QWORD_4(_qword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3) #define EFX_POPULATE_QWORD_2(_qword, \ _field1, _value1, _field2, _value2) \ EFX_POPULATE_QWORD_3(_qword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2) #define EFX_POPULATE_QWORD_1(_qword, \ _field1, _value1) \ EFX_POPULATE_QWORD_2(_qword, EFX_DUMMY_FIELD, 0, \ _field1, _value1) #define EFX_ZERO_QWORD(_qword) \ EFX_POPULATE_QWORD_1(_qword, EFX_DUMMY_FIELD, 0) #define EFX_SET_QWORD(_qword) \ EFX_POPULATE_QWORD_2(_qword, \ EFX_DWORD_0, 0xffffffff, EFX_DWORD_1, 0xffffffff) /* Populate a dword field with various numbers of arguments */ #define EFX_POPULATE_DWORD_10 EFX_POPULATE_DWORD #define EFX_POPULATE_DWORD_9(_dword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9) \ EFX_POPULATE_DWORD_10(_dword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9) #define EFX_POPULATE_DWORD_8(_dword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8) \ EFX_POPULATE_DWORD_9(_dword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8) #define EFX_POPULATE_DWORD_7(_dword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7) \ EFX_POPULATE_DWORD_8(_dword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7) #define EFX_POPULATE_DWORD_6(_dword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6) \ EFX_POPULATE_DWORD_7(_dword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6) #define EFX_POPULATE_DWORD_5(_dword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5) \ EFX_POPULATE_DWORD_6(_dword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5) #define EFX_POPULATE_DWORD_4(_dword, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4) \ EFX_POPULATE_DWORD_5(_dword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4) #define EFX_POPULATE_DWORD_3(_dword, \ _field1, _value1, _field2, _value2, _field3, _value3) \ EFX_POPULATE_DWORD_4(_dword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3) #define EFX_POPULATE_DWORD_2(_dword, \ _field1, _value1, _field2, _value2) \ EFX_POPULATE_DWORD_3(_dword, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2) #define EFX_POPULATE_DWORD_1(_dword, \ _field1, _value1) \ EFX_POPULATE_DWORD_2(_dword, EFX_DUMMY_FIELD, 0, \ _field1, _value1) #define EFX_ZERO_DWORD(_dword) \ EFX_POPULATE_DWORD_1(_dword, EFX_DUMMY_FIELD, 0) #define EFX_SET_DWORD(_dword) \ EFX_POPULATE_DWORD_1(_dword, \ EFX_DWORD_0, 0xffffffff) /* Populate a word field with various numbers of arguments */ #define EFX_POPULATE_WORD_10 EFX_POPULATE_WORD #define EFX_POPULATE_WORD_9(_word, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9) \ EFX_POPULATE_WORD_10(_word, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9) #define EFX_POPULATE_WORD_8(_word, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8) \ EFX_POPULATE_WORD_9(_word, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8) #define EFX_POPULATE_WORD_7(_word, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7) \ EFX_POPULATE_WORD_8(_word, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7) #define EFX_POPULATE_WORD_6(_word, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6) \ EFX_POPULATE_WORD_7(_word, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6) #define EFX_POPULATE_WORD_5(_word, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5) \ EFX_POPULATE_WORD_6(_word, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5) #define EFX_POPULATE_WORD_4(_word, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4) \ EFX_POPULATE_WORD_5(_word, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4) #define EFX_POPULATE_WORD_3(_word, \ _field1, _value1, _field2, _value2, _field3, _value3) \ EFX_POPULATE_WORD_4(_word, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3) #define EFX_POPULATE_WORD_2(_word, \ _field1, _value1, _field2, _value2) \ EFX_POPULATE_WORD_3(_word, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2) #define EFX_POPULATE_WORD_1(_word, \ _field1, _value1) \ EFX_POPULATE_WORD_2(_word, EFX_DUMMY_FIELD, 0, \ _field1, _value1) #define EFX_ZERO_WORD(_word) \ EFX_POPULATE_WORD_1(_word, EFX_DUMMY_FIELD, 0) #define EFX_SET_WORD(_word) \ EFX_POPULATE_WORD_1(_word, \ EFX_WORD_0, 0xffff) /* Populate a byte field with various numbers of arguments */ #define EFX_POPULATE_BYTE_10 EFX_POPULATE_BYTE #define EFX_POPULATE_BYTE_9(_byte, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9) \ EFX_POPULATE_BYTE_10(_byte, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8, _field9, _value9) #define EFX_POPULATE_BYTE_8(_byte, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8) \ EFX_POPULATE_BYTE_9(_byte, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7, _field8, _value8) #define EFX_POPULATE_BYTE_7(_byte, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7) \ EFX_POPULATE_BYTE_8(_byte, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6, \ _field7, _value7) #define EFX_POPULATE_BYTE_6(_byte, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6) \ EFX_POPULATE_BYTE_7(_byte, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5, _field6, _value6) #define EFX_POPULATE_BYTE_5(_byte, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5) \ EFX_POPULATE_BYTE_6(_byte, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4, _field5, _value5) #define EFX_POPULATE_BYTE_4(_byte, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4) \ EFX_POPULATE_BYTE_5(_byte, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3, \ _field4, _value4) #define EFX_POPULATE_BYTE_3(_byte, \ _field1, _value1, _field2, _value2, _field3, _value3) \ EFX_POPULATE_BYTE_4(_byte, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2, _field3, _value3) #define EFX_POPULATE_BYTE_2(_byte, \ _field1, _value1, _field2, _value2) \ EFX_POPULATE_BYTE_3(_byte, EFX_DUMMY_FIELD, 0, \ _field1, _value1, _field2, _value2) #define EFX_POPULATE_BYTE_1(_byte, \ _field1, _value1) \ EFX_POPULATE_BYTE_2(_byte, EFX_DUMMY_FIELD, 0, \ _field1, _value1) #define EFX_ZERO_BYTE(_byte) \ EFX_POPULATE_BYTE_1(_byte, EFX_DUMMY_FIELD, 0) #define EFX_SET_BYTE(_byte) \ EFX_POPULATE_BYTE_1(_byte, \ EFX_BYTE_0, 0xff) /* * Modify a named field within an already-populated structure. Used * for read-modify-write operations. */ #define EFX_INSERT_FIELD64(_min, _max, _field, _value) \ __CPU_TO_LE_64(EFX_INSERT_FIELD_NATIVE64(_min, _max, _field, _value)) #define EFX_INSERT_FIELD32(_min, _max, _field, _value) \ __CPU_TO_LE_32(EFX_INSERT_FIELD_NATIVE32(_min, _max, _field, _value)) #define EFX_INSERT_FIELD16(_min, _max, _field, _value) \ __CPU_TO_LE_16(EFX_INSERT_FIELD_NATIVE16(_min, _max, _field, _value)) #define EFX_INSERT_FIELD8(_min, _max, _field, _value) \ __NATIVE_8(EFX_INSERT_FIELD_NATIVE8(_min, _max, _field, _value)) #define EFX_INPLACE_MASK64(_min, _max, _field) \ EFX_INSERT_FIELD64(_min, _max, _field, EFX_MASK64(_field)) #define EFX_INPLACE_MASK32(_min, _max, _field) \ EFX_INSERT_FIELD32(_min, _max, _field, EFX_MASK32(_field)) #define EFX_INPLACE_MASK16(_min, _max, _field) \ EFX_INSERT_FIELD16(_min, _max, _field, EFX_MASK16(_field)) #define EFX_INPLACE_MASK8(_min, _max, _field) \ EFX_INSERT_FIELD8(_min, _max, _field, EFX_MASK8(_field)) #define EFX_SET_OWORD_FIELD64(_oword, _field, _value) \ do { \ _NOTE(CONSTANTCONDITION) \ (_oword).eo_u64[0] = (((_oword).eo_u64[0] & \ ~EFX_INPLACE_MASK64(0, 63, _field)) | \ EFX_INSERT_FIELD64(0, 63, _field, _value)); \ _NOTE(CONSTANTCONDITION) \ (_oword).eo_u64[1] = (((_oword).eo_u64[1] & \ ~EFX_INPLACE_MASK64(64, 127, _field)) | \ EFX_INSERT_FIELD64(64, 127, _field, _value)); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_SET_OWORD_FIELD32(_oword, _field, _value) \ do { \ _NOTE(CONSTANTCONDITION) \ (_oword).eo_u32[0] = (((_oword).eo_u32[0] & \ ~EFX_INPLACE_MASK32(0, 31, _field)) | \ EFX_INSERT_FIELD32(0, 31, _field, _value)); \ _NOTE(CONSTANTCONDITION) \ (_oword).eo_u32[1] = (((_oword).eo_u32[1] & \ ~EFX_INPLACE_MASK32(32, 63, _field)) | \ EFX_INSERT_FIELD32(32, 63, _field, _value)); \ _NOTE(CONSTANTCONDITION) \ (_oword).eo_u32[2] = (((_oword).eo_u32[2] & \ ~EFX_INPLACE_MASK32(64, 95, _field)) | \ EFX_INSERT_FIELD32(64, 95, _field, _value)); \ _NOTE(CONSTANTCONDITION) \ (_oword).eo_u32[3] = (((_oword).eo_u32[3] & \ ~EFX_INPLACE_MASK32(96, 127, _field)) | \ EFX_INSERT_FIELD32(96, 127, _field, _value)); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_SET_QWORD_FIELD64(_qword, _field, _value) \ do { \ _NOTE(CONSTANTCONDITION) \ (_qword).eq_u64[0] = (((_qword).eq_u64[0] & \ ~EFX_INPLACE_MASK64(0, 63, _field)) | \ EFX_INSERT_FIELD64(0, 63, _field, _value)); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_SET_QWORD_FIELD32(_qword, _field, _value) \ do { \ _NOTE(CONSTANTCONDITION) \ (_qword).eq_u32[0] = (((_qword).eq_u32[0] & \ ~EFX_INPLACE_MASK32(0, 31, _field)) | \ EFX_INSERT_FIELD32(0, 31, _field, _value)); \ _NOTE(CONSTANTCONDITION) \ (_qword).eq_u32[1] = (((_qword).eq_u32[1] & \ ~EFX_INPLACE_MASK32(32, 63, _field)) | \ EFX_INSERT_FIELD32(32, 63, _field, _value)); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_SET_DWORD_FIELD(_dword, _field, _value) \ do { \ _NOTE(CONSTANTCONDITION) \ (_dword).ed_u32[0] = (((_dword).ed_u32[0] & \ ~EFX_INPLACE_MASK32(0, 31, _field)) | \ EFX_INSERT_FIELD32(0, 31, _field, _value)); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_SET_WORD_FIELD(_word, _field, _value) \ do { \ _NOTE(CONSTANTCONDITION) \ (_word).ew_u16[0] = (((_word).ew_u16[0] & \ ~EFX_INPLACE_MASK16(0, 15, _field)) | \ EFX_INSERT_FIELD16(0, 15, _field, _value)); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_SET_BYTE_FIELD(_byte, _field, _value) \ do { \ _NOTE(CONSTANTCONDITION) \ (_byte).eb_u8[0] = (((_byte).eb_u8[0] & \ ~EFX_INPLACE_MASK8(0, 7, _field)) | \ EFX_INSERT_FIELD8(0, 7, _field, _value)); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) /* * Set or clear a numbered bit within an octword. */ #define EFX_SHIFT64(_bit, _base) \ (((_bit) >= (_base) && (_bit) < (_base) + 64) ? \ ((uint64_t)1 << ((_bit) - (_base))) : \ 0U) #define EFX_SHIFT32(_bit, _base) \ (((_bit) >= (_base) && (_bit) < (_base) + 32) ? \ ((uint32_t)1 << ((_bit) - (_base))) : \ 0U) #define EFX_SHIFT16(_bit, _base) \ (((_bit) >= (_base) && (_bit) < (_base) + 16) ? \ (uint16_t)(1 << ((_bit) - (_base))) : \ 0U) #define EFX_SHIFT8(_bit, _base) \ (((_bit) >= (_base) && (_bit) < (_base) + 8) ? \ (uint8_t)(1 << ((_bit) - (_base))) : \ 0U) #define EFX_SET_OWORD_BIT64(_oword, _bit) \ do { \ _NOTE(CONSTANTCONDITION) \ (_oword).eo_u64[0] |= \ __CPU_TO_LE_64(EFX_SHIFT64(_bit, FIX_LINT(0))); \ (_oword).eo_u64[1] |= \ __CPU_TO_LE_64(EFX_SHIFT64(_bit, FIX_LINT(64))); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_SET_OWORD_BIT32(_oword, _bit) \ do { \ _NOTE(CONSTANTCONDITION) \ (_oword).eo_u32[0] |= \ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(0))); \ (_oword).eo_u32[1] |= \ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(32))); \ (_oword).eo_u32[2] |= \ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(64))); \ (_oword).eo_u32[3] |= \ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(96))); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_CLEAR_OWORD_BIT64(_oword, _bit) \ do { \ _NOTE(CONSTANTCONDITION) \ (_oword).eo_u64[0] &= \ __CPU_TO_LE_64(~EFX_SHIFT64(_bit, FIX_LINT(0))); \ (_oword).eo_u64[1] &= \ __CPU_TO_LE_64(~EFX_SHIFT64(_bit, FIX_LINT(64))); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_CLEAR_OWORD_BIT32(_oword, _bit) \ do { \ _NOTE(CONSTANTCONDITION) \ (_oword).eo_u32[0] &= \ __CPU_TO_LE_32(~EFX_SHIFT32(_bit, FIX_LINT(0))); \ (_oword).eo_u32[1] &= \ __CPU_TO_LE_32(~EFX_SHIFT32(_bit, FIX_LINT(32))); \ (_oword).eo_u32[2] &= \ __CPU_TO_LE_32(~EFX_SHIFT32(_bit, FIX_LINT(64))); \ (_oword).eo_u32[3] &= \ __CPU_TO_LE_32(~EFX_SHIFT32(_bit, FIX_LINT(96))); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_TEST_OWORD_BIT64(_oword, _bit) \ (((_oword).eo_u64[0] & \ __CPU_TO_LE_64(EFX_SHIFT64(_bit, FIX_LINT(0)))) || \ ((_oword).eo_u64[1] & \ __CPU_TO_LE_64(EFX_SHIFT64(_bit, FIX_LINT(64))))) #define EFX_TEST_OWORD_BIT32(_oword, _bit) \ (((_oword).eo_u32[0] & \ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(0)))) || \ ((_oword).eo_u32[1] & \ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(32)))) || \ ((_oword).eo_u32[2] & \ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(64)))) || \ ((_oword).eo_u32[3] & \ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(96))))) #define EFX_SET_QWORD_BIT64(_qword, _bit) \ do { \ _NOTE(CONSTANTCONDITION) \ (_qword).eq_u64[0] |= \ __CPU_TO_LE_64(EFX_SHIFT64(_bit, FIX_LINT(0))); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_SET_QWORD_BIT32(_qword, _bit) \ do { \ _NOTE(CONSTANTCONDITION) \ (_qword).eq_u32[0] |= \ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(0))); \ (_qword).eq_u32[1] |= \ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(32))); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_CLEAR_QWORD_BIT64(_qword, _bit) \ do { \ _NOTE(CONSTANTCONDITION) \ (_qword).eq_u64[0] &= \ __CPU_TO_LE_64(~EFX_SHIFT64(_bit, FIX_LINT(0))); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_CLEAR_QWORD_BIT32(_qword, _bit) \ do { \ _NOTE(CONSTANTCONDITION) \ (_qword).eq_u32[0] &= \ __CPU_TO_LE_32(~EFX_SHIFT32(_bit, FIX_LINT(0))); \ (_qword).eq_u32[1] &= \ __CPU_TO_LE_32(~EFX_SHIFT32(_bit, FIX_LINT(32))); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_TEST_QWORD_BIT64(_qword, _bit) \ (((_qword).eq_u64[0] & \ __CPU_TO_LE_64(EFX_SHIFT64(_bit, FIX_LINT(0)))) != 0) #define EFX_TEST_QWORD_BIT32(_qword, _bit) \ (((_qword).eq_u32[0] & \ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(0)))) || \ ((_qword).eq_u32[1] & \ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(32))))) #define EFX_SET_DWORD_BIT(_dword, _bit) \ do { \ (_dword).ed_u32[0] |= \ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(0))); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_CLEAR_DWORD_BIT(_dword, _bit) \ do { \ (_dword).ed_u32[0] &= \ __CPU_TO_LE_32(~EFX_SHIFT32(_bit, FIX_LINT(0))); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_TEST_DWORD_BIT(_dword, _bit) \ (((_dword).ed_u32[0] & \ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(0)))) != 0) #define EFX_SET_WORD_BIT(_word, _bit) \ do { \ (_word).ew_u16[0] |= \ __CPU_TO_LE_16(EFX_SHIFT16(_bit, FIX_LINT(0))); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_CLEAR_WORD_BIT(_word, _bit) \ do { \ (_word).ew_u32[0] &= \ __CPU_TO_LE_16(~EFX_SHIFT16(_bit, FIX_LINT(0))); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_TEST_WORD_BIT(_word, _bit) \ (((_word).ew_u16[0] & \ __CPU_TO_LE_16(EFX_SHIFT16(_bit, FIX_LINT(0)))) != 0) #define EFX_SET_BYTE_BIT(_byte, _bit) \ do { \ (_byte).eb_u8[0] |= \ __NATIVE_8(EFX_SHIFT8(_bit, FIX_LINT(0))); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_CLEAR_BYTE_BIT(_byte, _bit) \ do { \ (_byte).eb_u8[0] &= \ __NATIVE_8(~EFX_SHIFT8(_bit, FIX_LINT(0))); \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_TEST_BYTE_BIT(_byte, _bit) \ (((_byte).eb_u8[0] & \ __NATIVE_8(EFX_SHIFT8(_bit, FIX_LINT(0)))) != 0) #define EFX_OR_OWORD64(_oword1, _oword2) \ do { \ (_oword1).eo_u64[0] |= (_oword2).eo_u64[0]; \ (_oword1).eo_u64[1] |= (_oword2).eo_u64[1]; \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_OR_OWORD32(_oword1, _oword2) \ do { \ (_oword1).eo_u32[0] |= (_oword2).eo_u32[0]; \ (_oword1).eo_u32[1] |= (_oword2).eo_u32[1]; \ (_oword1).eo_u32[2] |= (_oword2).eo_u32[2]; \ (_oword1).eo_u32[3] |= (_oword2).eo_u32[3]; \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_AND_OWORD64(_oword1, _oword2) \ do { \ (_oword1).eo_u64[0] &= (_oword2).eo_u64[0]; \ (_oword1).eo_u64[1] &= (_oword2).eo_u64[1]; \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_AND_OWORD32(_oword1, _oword2) \ do { \ (_oword1).eo_u32[0] &= (_oword2).eo_u32[0]; \ (_oword1).eo_u32[1] &= (_oword2).eo_u32[1]; \ (_oword1).eo_u32[2] &= (_oword2).eo_u32[2]; \ (_oword1).eo_u32[3] &= (_oword2).eo_u32[3]; \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_OR_QWORD64(_qword1, _qword2) \ do { \ (_qword1).eq_u64[0] |= (_qword2).eq_u64[0]; \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_OR_QWORD32(_qword1, _qword2) \ do { \ (_qword1).eq_u32[0] |= (_qword2).eq_u32[0]; \ (_qword1).eq_u32[1] |= (_qword2).eq_u32[1]; \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_AND_QWORD64(_qword1, _qword2) \ do { \ (_qword1).eq_u64[0] &= (_qword2).eq_u64[0]; \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_AND_QWORD32(_qword1, _qword2) \ do { \ (_qword1).eq_u32[0] &= (_qword2).eq_u32[0]; \ (_qword1).eq_u32[1] &= (_qword2).eq_u32[1]; \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_OR_DWORD(_dword1, _dword2) \ do { \ (_dword1).ed_u32[0] |= (_dword2).ed_u32[0]; \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_AND_DWORD(_dword1, _dword2) \ do { \ (_dword1).ed_u32[0] &= (_dword2).ed_u32[0]; \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_OR_WORD(_word1, _word2) \ do { \ (_word1).ew_u16[0] |= (_word2).ew_u16[0]; \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_AND_WORD(_word1, _word2) \ do { \ (_word1).ew_u16[0] &= (_word2).ew_u16[0]; \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_OR_BYTE(_byte1, _byte2) \ do { \ (_byte1).eb_u8[0] |= (_byte2).eb_u8[0]; \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #define EFX_AND_BYTE(_byte1, _byte2) \ do { \ (_byte1).eb_u8[0] &= (_byte2).eb_u8[0]; \ _NOTE(CONSTANTCONDITION) \ } while (B_FALSE) #if EFSYS_USE_UINT64 #define EFX_OWORD_FIELD EFX_OWORD_FIELD64 #define EFX_QWORD_FIELD EFX_QWORD_FIELD64 #define EFX_OWORD_IS_EQUAL EFX_OWORD_IS_EQUAL64 #define EFX_QWORD_IS_EQUAL EFX_QWORD_IS_EQUAL64 #define EFX_OWORD_IS_ZERO EFX_OWORD_IS_ZERO64 #define EFX_QWORD_IS_ZERO EFX_QWORD_IS_ZERO64 #define EFX_OWORD_IS_SET EFX_OWORD_IS_SET64 #define EFX_QWORD_IS_SET EFX_QWORD_IS_SET64 #define EFX_POPULATE_OWORD EFX_POPULATE_OWORD64 #define EFX_POPULATE_QWORD EFX_POPULATE_QWORD64 #define EFX_SET_OWORD_FIELD EFX_SET_OWORD_FIELD64 #define EFX_SET_QWORD_FIELD EFX_SET_QWORD_FIELD64 #define EFX_SET_OWORD_BIT EFX_SET_OWORD_BIT64 #define EFX_CLEAR_OWORD_BIT EFX_CLEAR_OWORD_BIT64 #define EFX_TEST_OWORD_BIT EFX_TEST_OWORD_BIT64 #define EFX_SET_QWORD_BIT EFX_SET_QWORD_BIT64 #define EFX_CLEAR_QWORD_BIT EFX_CLEAR_QWORD_BIT64 #define EFX_TEST_QWORD_BIT EFX_TEST_QWORD_BIT64 #define EFX_OR_OWORD EFX_OR_OWORD64 #define EFX_AND_OWORD EFX_AND_OWORD64 #define EFX_OR_QWORD EFX_OR_QWORD64 #define EFX_AND_QWORD EFX_AND_QWORD64 #else #define EFX_OWORD_FIELD EFX_OWORD_FIELD32 #define EFX_QWORD_FIELD EFX_QWORD_FIELD32 #define EFX_OWORD_IS_EQUAL EFX_OWORD_IS_EQUAL32 #define EFX_QWORD_IS_EQUAL EFX_QWORD_IS_EQUAL32 #define EFX_OWORD_IS_ZERO EFX_OWORD_IS_ZERO32 #define EFX_QWORD_IS_ZERO EFX_QWORD_IS_ZERO32 #define EFX_OWORD_IS_SET EFX_OWORD_IS_SET32 #define EFX_QWORD_IS_SET EFX_QWORD_IS_SET32 #define EFX_POPULATE_OWORD EFX_POPULATE_OWORD32 #define EFX_POPULATE_QWORD EFX_POPULATE_QWORD32 #define EFX_SET_OWORD_FIELD EFX_SET_OWORD_FIELD32 #define EFX_SET_QWORD_FIELD EFX_SET_QWORD_FIELD32 #define EFX_SET_OWORD_BIT EFX_SET_OWORD_BIT32 #define EFX_CLEAR_OWORD_BIT EFX_CLEAR_OWORD_BIT32 #define EFX_TEST_OWORD_BIT EFX_TEST_OWORD_BIT32 #define EFX_SET_QWORD_BIT EFX_SET_QWORD_BIT32 #define EFX_CLEAR_QWORD_BIT EFX_CLEAR_QWORD_BIT32 #define EFX_TEST_QWORD_BIT EFX_TEST_QWORD_BIT32 #define EFX_OR_OWORD EFX_OR_OWORD32 #define EFX_AND_OWORD EFX_AND_OWORD32 #define EFX_OR_QWORD EFX_OR_QWORD32 #define EFX_AND_QWORD EFX_AND_QWORD32 #endif #ifdef __cplusplus } #endif #endif /* _SYS_EFX_TYPES_H */ Index: head/sys/dev/sfxge/common/mcdi_mon.c =================================================================== --- head/sys/dev/sfxge/common/mcdi_mon.c (revision 310691) +++ head/sys/dev/sfxge/common/mcdi_mon.c (revision 310692) @@ -1,565 +1,565 @@ /*- * Copyright (c) 2009-2016 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. * * 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 __FBSDID("$FreeBSD$"); #include "efx.h" #include "efx_impl.h" #if EFSYS_OPT_MON_MCDI #if EFSYS_OPT_MON_STATS -#define MCDI_MON_NEXT_PAGE (uint16_t)0xfffe -#define MCDI_MON_INVALID_SENSOR (uint16_t)0xfffd +#define MCDI_MON_NEXT_PAGE ((uint16_t)0xfffe) +#define MCDI_MON_INVALID_SENSOR ((uint16_t)0xfffd) #define MCDI_MON_PAGE_SIZE 0x20 /* Bitmasks of valid port(s) for each sensor */ #define MCDI_MON_PORT_NONE (0x00) #define MCDI_MON_PORT_P1 (0x01) #define MCDI_MON_PORT_P2 (0x02) #define MCDI_MON_PORT_P3 (0x04) #define MCDI_MON_PORT_P4 (0x08) #define MCDI_MON_PORT_Px (0xFFFF) /* Entry for MCDI sensor in sensor map */ #define STAT(portmask, stat) \ { (MCDI_MON_PORT_##portmask), (EFX_MON_STAT_##stat) } /* Entry for sensor next page flag in sensor map */ #define STAT_NEXT_PAGE() \ { MCDI_MON_PORT_NONE, MCDI_MON_NEXT_PAGE } /* Placeholder for gaps in the array */ #define STAT_NO_SENSOR() \ { MCDI_MON_PORT_NONE, MCDI_MON_INVALID_SENSOR } /* Map from MC sensors to monitor statistics */ static const struct mcdi_sensor_map_s { uint16_t msm_port_mask; uint16_t msm_stat; } mcdi_sensor_map[] = { /* Sensor page 0 MC_CMD_SENSOR_xxx */ STAT(Px, INT_TEMP), /* 0x00 CONTROLLER_TEMP */ STAT(Px, EXT_TEMP), /* 0x01 PHY_COMMON_TEMP */ STAT(Px, INT_COOLING), /* 0x02 CONTROLLER_COOLING */ STAT(P1, EXT_TEMP), /* 0x03 PHY0_TEMP */ STAT(P1, EXT_COOLING), /* 0x04 PHY0_COOLING */ STAT(P2, EXT_TEMP), /* 0x05 PHY1_TEMP */ STAT(P2, EXT_COOLING), /* 0x06 PHY1_COOLING */ STAT(Px, 1V), /* 0x07 IN_1V0 */ STAT(Px, 1_2V), /* 0x08 IN_1V2 */ STAT(Px, 1_8V), /* 0x09 IN_1V8 */ STAT(Px, 2_5V), /* 0x0a IN_2V5 */ STAT(Px, 3_3V), /* 0x0b IN_3V3 */ STAT(Px, 12V), /* 0x0c IN_12V0 */ STAT(Px, 1_2VA), /* 0x0d IN_1V2A */ STAT(Px, VREF), /* 0x0e IN_VREF */ STAT(Px, VAOE), /* 0x0f OUT_VAOE */ STAT(Px, AOE_TEMP), /* 0x10 AOE_TEMP */ STAT(Px, PSU_AOE_TEMP), /* 0x11 PSU_AOE_TEMP */ STAT(Px, PSU_TEMP), /* 0x12 PSU_TEMP */ STAT(Px, FAN0), /* 0x13 FAN_0 */ STAT(Px, FAN1), /* 0x14 FAN_1 */ STAT(Px, FAN2), /* 0x15 FAN_2 */ STAT(Px, FAN3), /* 0x16 FAN_3 */ STAT(Px, FAN4), /* 0x17 FAN_4 */ STAT(Px, VAOE_IN), /* 0x18 IN_VAOE */ STAT(Px, IAOE), /* 0x19 OUT_IAOE */ STAT(Px, IAOE_IN), /* 0x1a IN_IAOE */ STAT(Px, NIC_POWER), /* 0x1b NIC_POWER */ STAT(Px, 0_9V), /* 0x1c IN_0V9 */ STAT(Px, I0_9V), /* 0x1d IN_I0V9 */ STAT(Px, I1_2V), /* 0x1e IN_I1V2 */ STAT_NEXT_PAGE(), /* 0x1f Next page flag (not a sensor) */ /* Sensor page 1 MC_CMD_SENSOR_xxx */ STAT(Px, 0_9V_ADC), /* 0x20 IN_0V9_ADC */ STAT(Px, INT_TEMP2), /* 0x21 CONTROLLER_2_TEMP */ STAT(Px, VREG_TEMP), /* 0x22 VREG_INTERNAL_TEMP */ STAT(Px, VREG_0_9V_TEMP), /* 0x23 VREG_0V9_TEMP */ STAT(Px, VREG_1_2V_TEMP), /* 0x24 VREG_1V2_TEMP */ STAT(Px, INT_VPTAT), /* 0x25 CTRLR. VPTAT */ STAT(Px, INT_ADC_TEMP), /* 0x26 CTRLR. INTERNAL_TEMP */ STAT(Px, EXT_VPTAT), /* 0x27 CTRLR. VPTAT_EXTADC */ STAT(Px, EXT_ADC_TEMP), /* 0x28 CTRLR. INTERNAL_TEMP_EXTADC */ STAT(Px, AMBIENT_TEMP), /* 0x29 AMBIENT_TEMP */ STAT(Px, AIRFLOW), /* 0x2a AIRFLOW */ STAT(Px, VDD08D_VSS08D_CSR), /* 0x2b VDD08D_VSS08D_CSR */ STAT(Px, VDD08D_VSS08D_CSR_EXTADC), /* 0x2c VDD08D_VSS08D_CSR_EXTADC */ STAT(Px, HOTPOINT_TEMP), /* 0x2d HOTPOINT_TEMP */ STAT(P1, PHY_POWER_SWITCH_PORT0), /* 0x2e PHY_POWER_SWITCH_PORT0 */ STAT(P2, PHY_POWER_SWITCH_PORT1), /* 0x2f PHY_POWER_SWITCH_PORT1 */ STAT(Px, MUM_VCC), /* 0x30 MUM_VCC */ STAT(Px, 0V9_A), /* 0x31 0V9_A */ STAT(Px, I0V9_A), /* 0x32 I0V9_A */ STAT(Px, 0V9_A_TEMP), /* 0x33 0V9_A_TEMP */ STAT(Px, 0V9_B), /* 0x34 0V9_B */ STAT(Px, I0V9_B), /* 0x35 I0V9_B */ STAT(Px, 0V9_B_TEMP), /* 0x36 0V9_B_TEMP */ STAT(Px, CCOM_AVREG_1V2_SUPPLY), /* 0x37 CCOM_AVREG_1V2_SUPPLY */ STAT(Px, CCOM_AVREG_1V2_SUPPLY_EXT_ADC), /* 0x38 CCOM_AVREG_1V2_SUPPLY_EXT_ADC */ STAT(Px, CCOM_AVREG_1V8_SUPPLY), /* 0x39 CCOM_AVREG_1V8_SUPPLY */ STAT(Px, CCOM_AVREG_1V8_SUPPLY_EXT_ADC), /* 0x3a CCOM_AVREG_1V8_SUPPLY_EXT_ADC */ STAT_NO_SENSOR(), /* 0x3b (no sensor) */ STAT_NO_SENSOR(), /* 0x3c (no sensor) */ STAT_NO_SENSOR(), /* 0x3d (no sensor) */ STAT_NO_SENSOR(), /* 0x3e (no sensor) */ STAT_NEXT_PAGE(), /* 0x3f Next page flag (not a sensor) */ /* Sensor page 2 MC_CMD_SENSOR_xxx */ STAT(Px, CONTROLLER_MASTER_VPTAT), /* 0x40 MASTER_VPTAT */ STAT(Px, CONTROLLER_MASTER_INTERNAL_TEMP), /* 0x41 MASTER_INT_TEMP */ STAT(Px, CONTROLLER_MASTER_VPTAT_EXT_ADC), /* 0x42 MAST_VPTAT_EXT_ADC */ STAT(Px, CONTROLLER_MASTER_INTERNAL_TEMP_EXT_ADC), /* 0x43 MASTER_INTERNAL_TEMP_EXT_ADC */ STAT(Px, CONTROLLER_SLAVE_VPTAT), /* 0x44 SLAVE_VPTAT */ STAT(Px, CONTROLLER_SLAVE_INTERNAL_TEMP), /* 0x45 SLAVE_INTERNAL_TEMP */ STAT(Px, CONTROLLER_SLAVE_VPTAT_EXT_ADC), /* 0x46 SLAVE_VPTAT_EXT_ADC */ STAT(Px, CONTROLLER_SLAVE_INTERNAL_TEMP_EXT_ADC), /* 0x47 SLAVE_INTERNAL_TEMP_EXT_ADC */ STAT_NO_SENSOR(), /* 0x48 (no sensor) */ STAT(Px, SODIMM_VOUT), /* 0x49 SODIMM_VOUT */ STAT(Px, SODIMM_0_TEMP), /* 0x4a SODIMM_0_TEMP */ STAT(Px, SODIMM_1_TEMP), /* 0x4b SODIMM_1_TEMP */ STAT(Px, PHY0_VCC), /* 0x4c PHY0_VCC */ STAT(Px, PHY1_VCC), /* 0x4d PHY1_VCC */ STAT(Px, CONTROLLER_TDIODE_TEMP), /* 0x4e CONTROLLER_TDIODE_TEMP */ STAT(Px, BOARD_FRONT_TEMP), /* 0x4f BOARD_FRONT_TEMP */ STAT(Px, BOARD_BACK_TEMP), /* 0x50 BOARD_BACK_TEMP */ }; #define MCDI_STATIC_SENSOR_ASSERT(_field) \ EFX_STATIC_ASSERT(MC_CMD_SENSOR_STATE_ ## _field \ == EFX_MON_STAT_STATE_ ## _field) static void mcdi_mon_decode_stats( __in efx_nic_t *enp, __in_ecount(sensor_mask_size) uint32_t *sensor_mask, __in size_t sensor_mask_size, __in_opt efsys_mem_t *esmp, __out_ecount_opt(sensor_mask_size) uint32_t *stat_maskp, __inout_ecount_opt(EFX_MON_NSTATS) efx_mon_stat_value_t *stat) { efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); uint16_t port_mask; uint16_t sensor; size_t sensor_max; uint32_t stat_mask[(EFX_ARRAY_SIZE(mcdi_sensor_map) + 31) / 32]; uint32_t idx = 0; uint32_t page = 0; /* Assert the MC_CMD_SENSOR and EFX_MON_STATE namespaces agree */ MCDI_STATIC_SENSOR_ASSERT(OK); MCDI_STATIC_SENSOR_ASSERT(WARNING); MCDI_STATIC_SENSOR_ASSERT(FATAL); MCDI_STATIC_SENSOR_ASSERT(BROKEN); MCDI_STATIC_SENSOR_ASSERT(NO_READING); EFX_STATIC_ASSERT(sizeof (stat_mask[0]) * 8 == EFX_MON_MASK_ELEMENT_SIZE); sensor_max = MIN((8 * sensor_mask_size), EFX_ARRAY_SIZE(mcdi_sensor_map)); port_mask = 1U << emip->emi_port; memset(stat_mask, 0, sizeof (stat_mask)); /* * The MCDI sensor readings in the DMA buffer are a packed array of * MC_CMD_SENSOR_VALUE_ENTRY structures, which only includes entries for * supported sensors (bit set in sensor_mask). The sensor_mask and * sensor readings do not include entries for the per-page NEXT_PAGE * flag. * * sensor_mask may legitimately contain MCDI sensors that the driver * does not understand. */ for (sensor = 0; sensor < sensor_max; ++sensor) { efx_mon_stat_t id = mcdi_sensor_map[sensor].msm_stat; if ((sensor % MCDI_MON_PAGE_SIZE) == MC_CMD_SENSOR_PAGE0_NEXT) { EFSYS_ASSERT3U(id, ==, MCDI_MON_NEXT_PAGE); page++; continue; } if (~(sensor_mask[page]) & (1U << sensor)) continue; idx++; if ((port_mask & mcdi_sensor_map[sensor].msm_port_mask) == 0) continue; EFSYS_ASSERT(id < EFX_MON_NSTATS); /* * stat_mask is a bitmask indexed by EFX_MON_* monitor statistic * identifiers from efx_mon_stat_t (without NEXT_PAGE bits). * * If there is an entry in the MCDI sensor to monitor statistic * map then the sensor reading is used for the value of the * monitor statistic. */ stat_mask[id / EFX_MON_MASK_ELEMENT_SIZE] |= (1U << (id % EFX_MON_MASK_ELEMENT_SIZE)); if (stat != NULL && esmp != NULL && !EFSYS_MEM_IS_NULL(esmp)) { efx_dword_t dword; /* Get MCDI sensor reading from DMA buffer */ EFSYS_MEM_READD(esmp, 4 * (idx - 1), &dword); /* Update EFX monitor stat from MCDI sensor reading */ stat[id].emsv_value = (uint16_t)EFX_DWORD_FIELD(dword, MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE); stat[id].emsv_state = (uint16_t)EFX_DWORD_FIELD(dword, MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE); } } if (stat_maskp != NULL) { memcpy(stat_maskp, stat_mask, sizeof (stat_mask)); } } __checkReturn efx_rc_t mcdi_mon_ev( __in efx_nic_t *enp, __in efx_qword_t *eqp, __out efx_mon_stat_t *idp, __out efx_mon_stat_value_t *valuep) { efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); efx_nic_cfg_t *encp = &(enp->en_nic_cfg); uint16_t port_mask; uint16_t sensor; uint16_t state; uint16_t value; efx_mon_stat_t id; efx_rc_t rc; port_mask = (emip->emi_port == 1) ? MCDI_MON_PORT_P1 : MCDI_MON_PORT_P2; sensor = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_MONITOR); state = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_STATE); value = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_VALUE); /* Hardware must support this MCDI sensor */ EFSYS_ASSERT3U(sensor, <, (8 * encp->enc_mcdi_sensor_mask_size)); EFSYS_ASSERT((sensor % MCDI_MON_PAGE_SIZE) != MC_CMD_SENSOR_PAGE0_NEXT); EFSYS_ASSERT(encp->enc_mcdi_sensor_maskp != NULL); EFSYS_ASSERT((encp->enc_mcdi_sensor_maskp[sensor / MCDI_MON_PAGE_SIZE] & (1U << (sensor % MCDI_MON_PAGE_SIZE))) != 0); /* But we don't have to understand it */ if (sensor >= EFX_ARRAY_SIZE(mcdi_sensor_map)) { rc = ENOTSUP; goto fail1; } id = mcdi_sensor_map[sensor].msm_stat; if ((port_mask & mcdi_sensor_map[sensor].msm_port_mask) == 0) return (ENODEV); EFSYS_ASSERT(id < EFX_MON_NSTATS); *idp = id; valuep->emsv_value = value; valuep->emsv_state = state; return (0); fail1: EFSYS_PROBE1(fail1, efx_rc_t, rc); return (rc); } static __checkReturn efx_rc_t efx_mcdi_read_sensors( __in efx_nic_t *enp, __in efsys_mem_t *esmp, __in uint32_t size) { efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_READ_SENSORS_EXT_IN_LEN, MC_CMD_READ_SENSORS_EXT_OUT_LEN)]; uint32_t addr_lo, addr_hi; req.emr_cmd = MC_CMD_READ_SENSORS; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_READ_SENSORS_EXT_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_READ_SENSORS_EXT_OUT_LEN; addr_lo = (uint32_t)(EFSYS_MEM_ADDR(esmp) & 0xffffffff); addr_hi = (uint32_t)(EFSYS_MEM_ADDR(esmp) >> 32); MCDI_IN_SET_DWORD(req, READ_SENSORS_EXT_IN_DMA_ADDR_LO, addr_lo); MCDI_IN_SET_DWORD(req, READ_SENSORS_EXT_IN_DMA_ADDR_HI, addr_hi); MCDI_IN_SET_DWORD(req, READ_SENSORS_EXT_IN_LENGTH, size); efx_mcdi_execute(enp, &req); return (req.emr_rc); } static __checkReturn efx_rc_t efx_mcdi_sensor_info_npages( __in efx_nic_t *enp, __out uint32_t *npagesp) { efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_SENSOR_INFO_EXT_IN_LEN, MC_CMD_SENSOR_INFO_OUT_LENMAX)]; int page; efx_rc_t rc; EFSYS_ASSERT(npagesp != NULL); page = 0; do { (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_SENSOR_INFO; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_SENSOR_INFO_EXT_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_SENSOR_INFO_OUT_LENMAX; MCDI_IN_SET_DWORD(req, SENSOR_INFO_EXT_IN_PAGE, page++); efx_mcdi_execute_quiet(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; goto fail1; } } while (MCDI_OUT_DWORD(req, SENSOR_INFO_OUT_MASK) & (1U << MC_CMD_SENSOR_PAGE0_NEXT)); *npagesp = page; return (0); fail1: EFSYS_PROBE1(fail1, efx_rc_t, rc); return (rc); } static __checkReturn efx_rc_t efx_mcdi_sensor_info( __in efx_nic_t *enp, __out_ecount(npages) uint32_t *sensor_maskp, __in size_t npages) { efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_SENSOR_INFO_EXT_IN_LEN, MC_CMD_SENSOR_INFO_OUT_LENMAX)]; uint32_t page; efx_rc_t rc; EFSYS_ASSERT(sensor_maskp != NULL); for (page = 0; page < npages; page++) { uint32_t mask; (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_SENSOR_INFO; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_SENSOR_INFO_EXT_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_SENSOR_INFO_OUT_LENMAX; MCDI_IN_SET_DWORD(req, SENSOR_INFO_EXT_IN_PAGE, page); efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; goto fail1; } mask = MCDI_OUT_DWORD(req, SENSOR_INFO_OUT_MASK); if ((page != (npages - 1)) && ((mask & (1U << MC_CMD_SENSOR_PAGE0_NEXT)) == 0)) { rc = EINVAL; goto fail2; } sensor_maskp[page] = mask; } if (sensor_maskp[npages - 1] & (1U << MC_CMD_SENSOR_PAGE0_NEXT)) { rc = EINVAL; goto fail3; } return (0); fail3: EFSYS_PROBE(fail3); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, efx_rc_t, rc); return (rc); } __checkReturn efx_rc_t mcdi_mon_stats_update( __in efx_nic_t *enp, __in efsys_mem_t *esmp, __inout_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values) { efx_nic_cfg_t *encp = &(enp->en_nic_cfg); uint32_t size = encp->enc_mon_stat_dma_buf_size; efx_rc_t rc; if ((rc = efx_mcdi_read_sensors(enp, esmp, size)) != 0) goto fail1; EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, size); mcdi_mon_decode_stats(enp, encp->enc_mcdi_sensor_maskp, encp->enc_mcdi_sensor_mask_size, esmp, NULL, values); return (0); fail1: EFSYS_PROBE1(fail1, efx_rc_t, rc); return (rc); } __checkReturn efx_rc_t mcdi_mon_cfg_build( __in efx_nic_t *enp) { efx_nic_cfg_t *encp = &(enp->en_nic_cfg); uint32_t npages; efx_rc_t rc; switch (enp->en_family) { #if EFSYS_OPT_SIENA case EFX_FAMILY_SIENA: encp->enc_mon_type = EFX_MON_SFC90X0; break; #endif #if EFSYS_OPT_HUNTINGTON case EFX_FAMILY_HUNTINGTON: encp->enc_mon_type = EFX_MON_SFC91X0; break; #endif #if EFSYS_OPT_MEDFORD case EFX_FAMILY_MEDFORD: encp->enc_mon_type = EFX_MON_SFC92X0; break; #endif default: rc = EINVAL; goto fail1; } /* Get mc sensor mask size */ npages = 0; if ((rc = efx_mcdi_sensor_info_npages(enp, &npages)) != 0) goto fail2; encp->enc_mon_stat_dma_buf_size = npages * EFX_MON_STATS_PAGE_SIZE; encp->enc_mcdi_sensor_mask_size = npages * sizeof (uint32_t); /* Allocate mc sensor mask */ EFSYS_KMEM_ALLOC(enp->en_esip, encp->enc_mcdi_sensor_mask_size, encp->enc_mcdi_sensor_maskp); if (encp->enc_mcdi_sensor_maskp == NULL) { rc = ENOMEM; goto fail3; } /* Read mc sensor mask */ if ((rc = efx_mcdi_sensor_info(enp, encp->enc_mcdi_sensor_maskp, npages)) != 0) goto fail4; /* Build monitor statistics mask */ mcdi_mon_decode_stats(enp, encp->enc_mcdi_sensor_maskp, encp->enc_mcdi_sensor_mask_size, NULL, encp->enc_mon_stat_mask, NULL); return (0); fail4: EFSYS_PROBE(fail4); EFSYS_KMEM_FREE(enp->en_esip, encp->enc_mcdi_sensor_mask_size, encp->enc_mcdi_sensor_maskp); fail3: EFSYS_PROBE(fail3); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, efx_rc_t, rc); return (rc); } void mcdi_mon_cfg_free( __in efx_nic_t *enp) { efx_nic_cfg_t *encp = &(enp->en_nic_cfg); if (encp->enc_mcdi_sensor_maskp != NULL) { EFSYS_KMEM_FREE(enp->en_esip, encp->enc_mcdi_sensor_mask_size, encp->enc_mcdi_sensor_maskp); } } #endif /* EFSYS_OPT_MON_STATS */ #endif /* EFSYS_OPT_MON_MCDI */