From e948693ed767ef8364d5fc71e363ed941432a6e8 Mon Sep 17 00:00:00 2001 From: Philip Paeps Date: Wed, 16 Nov 2011 17:11:13 +0000 Subject: Add the sfxge(4) device driver, providing support for 10Gb Ethernet adapters based on Solarflare SFC9000 family controllers. The driver supports jumbo frames, transmit/receive checksum offload, TCP Segmentation Offload (TSO), Large Receive Offload (LRO), VLAN checksum offload, VLAN TSO, and Receive Side Scaling (RSS) using MSI-X interrupts. This work was sponsored by Solarflare Communications, Inc. My sincere thanks to Ben Hutchings for doing a lot of the hard work! Sponsored by: Solarflare Communications, Inc. MFC after: 3 weeks --- sys/conf/files | 31 + sys/dev/sfxge/common/efsys.h | 800 +++++++ sys/dev/sfxge/common/efx.h | 1893 +++++++++++++++++ sys/dev/sfxge/common/efx_bootcfg.c | 342 +++ sys/dev/sfxge/common/efx_ev.c | 1112 ++++++++++ sys/dev/sfxge/common/efx_filter.c | 1017 +++++++++ sys/dev/sfxge/common/efx_impl.h | 734 +++++++ sys/dev/sfxge/common/efx_intr.c | 354 ++++ sys/dev/sfxge/common/efx_mac.c | 684 ++++++ sys/dev/sfxge/common/efx_mcdi.c | 733 +++++++ sys/dev/sfxge/common/efx_mcdi.h | 238 +++ sys/dev/sfxge/common/efx_mon.c | 269 +++ sys/dev/sfxge/common/efx_nic.c | 674 ++++++ sys/dev/sfxge/common/efx_nvram.c | 372 ++++ sys/dev/sfxge/common/efx_phy.c | 752 +++++++ sys/dev/sfxge/common/efx_port.c | 226 ++ sys/dev/sfxge/common/efx_regs.h | 3846 ++++++++++++++++++++++++++++++++++ sys/dev/sfxge/common/efx_regs_ef10.h | 2682 ++++++++++++++++++++++++ sys/dev/sfxge/common/efx_regs_mcdi.h | 2786 ++++++++++++++++++++++++ sys/dev/sfxge/common/efx_regs_pci.h | 2376 +++++++++++++++++++++ sys/dev/sfxge/common/efx_rx.c | 816 ++++++++ sys/dev/sfxge/common/efx_sram.c | 294 +++ sys/dev/sfxge/common/efx_tx.c | 430 ++++ sys/dev/sfxge/common/efx_types.h | 1605 ++++++++++++++ sys/dev/sfxge/common/efx_vpd.c | 999 +++++++++ sys/dev/sfxge/common/efx_wol.c | 396 ++++ sys/dev/sfxge/common/siena_flash.h | 132 ++ sys/dev/sfxge/common/siena_impl.h | 477 +++++ sys/dev/sfxge/common/siena_mac.c | 545 +++++ sys/dev/sfxge/common/siena_mon.c | 248 +++ sys/dev/sfxge/common/siena_nic.c | 964 +++++++++ sys/dev/sfxge/common/siena_nvram.c | 985 +++++++++ sys/dev/sfxge/common/siena_phy.c | 857 ++++++++ sys/dev/sfxge/common/siena_sram.c | 172 ++ sys/dev/sfxge/common/siena_vpd.c | 603 ++++++ sys/dev/sfxge/sfxge.c | 775 +++++++ sys/dev/sfxge/sfxge.h | 304 +++ sys/dev/sfxge/sfxge_dma.c | 202 ++ sys/dev/sfxge/sfxge_ev.c | 862 ++++++++ sys/dev/sfxge/sfxge_intr.c | 577 +++++ sys/dev/sfxge/sfxge_mcdi.c | 250 +++ sys/dev/sfxge/sfxge_port.c | 788 +++++++ sys/dev/sfxge/sfxge_rx.c | 1233 +++++++++++ sys/dev/sfxge/sfxge_rx.h | 189 ++ sys/dev/sfxge/sfxge_tx.c | 1491 +++++++++++++ sys/dev/sfxge/sfxge_tx.h | 185 ++ sys/modules/Makefile | 1 + sys/modules/sfxge/Makefile | 25 + 48 files changed, 38326 insertions(+) create mode 100644 sys/dev/sfxge/common/efsys.h create mode 100644 sys/dev/sfxge/common/efx.h create mode 100644 sys/dev/sfxge/common/efx_bootcfg.c create mode 100644 sys/dev/sfxge/common/efx_ev.c create mode 100644 sys/dev/sfxge/common/efx_filter.c create mode 100644 sys/dev/sfxge/common/efx_impl.h create mode 100644 sys/dev/sfxge/common/efx_intr.c create mode 100644 sys/dev/sfxge/common/efx_mac.c create mode 100644 sys/dev/sfxge/common/efx_mcdi.c create mode 100644 sys/dev/sfxge/common/efx_mcdi.h create mode 100644 sys/dev/sfxge/common/efx_mon.c create mode 100644 sys/dev/sfxge/common/efx_nic.c create mode 100644 sys/dev/sfxge/common/efx_nvram.c create mode 100644 sys/dev/sfxge/common/efx_phy.c create mode 100644 sys/dev/sfxge/common/efx_port.c create mode 100644 sys/dev/sfxge/common/efx_regs.h create mode 100644 sys/dev/sfxge/common/efx_regs_ef10.h create mode 100644 sys/dev/sfxge/common/efx_regs_mcdi.h create mode 100644 sys/dev/sfxge/common/efx_regs_pci.h create mode 100644 sys/dev/sfxge/common/efx_rx.c create mode 100644 sys/dev/sfxge/common/efx_sram.c create mode 100644 sys/dev/sfxge/common/efx_tx.c create mode 100644 sys/dev/sfxge/common/efx_types.h create mode 100644 sys/dev/sfxge/common/efx_vpd.c create mode 100644 sys/dev/sfxge/common/efx_wol.c create mode 100644 sys/dev/sfxge/common/siena_flash.h create mode 100644 sys/dev/sfxge/common/siena_impl.h create mode 100644 sys/dev/sfxge/common/siena_mac.c create mode 100644 sys/dev/sfxge/common/siena_mon.c create mode 100644 sys/dev/sfxge/common/siena_nic.c create mode 100644 sys/dev/sfxge/common/siena_nvram.c create mode 100644 sys/dev/sfxge/common/siena_phy.c create mode 100644 sys/dev/sfxge/common/siena_sram.c create mode 100644 sys/dev/sfxge/common/siena_vpd.c create mode 100644 sys/dev/sfxge/sfxge.c create mode 100644 sys/dev/sfxge/sfxge.h create mode 100644 sys/dev/sfxge/sfxge_dma.c create mode 100644 sys/dev/sfxge/sfxge_ev.c create mode 100644 sys/dev/sfxge/sfxge_intr.c create mode 100644 sys/dev/sfxge/sfxge_mcdi.c create mode 100644 sys/dev/sfxge/sfxge_port.c create mode 100644 sys/dev/sfxge/sfxge_rx.c create mode 100644 sys/dev/sfxge/sfxge_rx.h create mode 100644 sys/dev/sfxge/sfxge_tx.c create mode 100644 sys/dev/sfxge/sfxge_tx.h create mode 100644 sys/modules/sfxge/Makefile (limited to 'sys') diff --git a/sys/conf/files b/sys/conf/files index 1f2bd0b84379..b448be6bc32d 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1671,6 +1671,37 @@ dev/scd/scd.c optional scd isa dev/scd/scd_isa.c optional scd isa dev/sdhci/sdhci.c optional sdhci pci dev/sf/if_sf.c optional sf pci +dev/sfxge/common/efx_bootcfg.c optional sfxge inet pci +dev/sfxge/common/efx_ev.c optional sfxge inet pci +dev/sfxge/common/efx_filter.c optional sfxge inet pci +dev/sfxge/common/efx_intr.c optional sfxge inet pci +dev/sfxge/common/efx_mac.c optional sfxge inet pci +dev/sfxge/common/efx_mcdi.c optional sfxge inet pci +dev/sfxge/common/efx_mon.c optional sfxge inet pci +dev/sfxge/common/efx_nic.c optional sfxge inet pci +dev/sfxge/common/efx_nvram.c optional sfxge inet pci +dev/sfxge/common/efx_phy.c optional sfxge inet pci +dev/sfxge/common/efx_port.c optional sfxge inet pci +dev/sfxge/common/efx_rx.c optional sfxge inet pci +dev/sfxge/common/efx_sram.c optional sfxge inet pci +dev/sfxge/common/efx_tx.c optional sfxge inet pci +dev/sfxge/common/efx_vpd.c optional sfxge inet pci +dev/sfxge/common/efx_wol.c optional sfxge inet pci +dev/sfxge/common/siena_mac.c optional sfxge inet pci +dev/sfxge/common/siena_mon.c optional sfxge inet pci +dev/sfxge/common/siena_nic.c optional sfxge inet pci +dev/sfxge/common/siena_nvram.c optional sfxge inet pci +dev/sfxge/common/siena_phy.c optional sfxge inet pci +dev/sfxge/common/siena_sram.c optional sfxge inet pci +dev/sfxge/common/siena_vpd.c optional sfxge inet pci +dev/sfxge/sfxge.c optional sfxge inet pci +dev/sfxge/sfxge_dma.c optional sfxge inet pci +dev/sfxge/sfxge_ev.c optional sfxge inet pci +dev/sfxge/sfxge_intr.c optional sfxge inet pci +dev/sfxge/sfxge_mcdi.c optional sfxge inet pci +dev/sfxge/sfxge_port.c optional sfxge inet pci +dev/sfxge/sfxge_rx.c optional sfxge inet pci +dev/sfxge/sfxge_tx.c optional sfxge inet pci dev/sge/if_sge.c optional sge pci dev/si/si.c optional si dev/si/si2_z280.c optional si diff --git a/sys/dev/sfxge/common/efsys.h b/sys/dev/sfxge/common/efsys.h new file mode 100644 index 000000000000..bed5e6a13b9c --- /dev/null +++ b/sys/dev/sfxge/common/efsys.h @@ -0,0 +1,800 @@ +/*- + * Copyright (c) 2010-2011 Solarflare Communications, Inc. + * All rights reserved. + * + * This software was developed in part by Philip Paeps under contract for + * Solarflare Communications, Inc. + * + * 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SYS_EFSYS_H +#define _SYS_EFSYS_H + +#include +__FBSDID("$FreeBSD$"); + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define EFSYS_HAS_UINT64 1 +#define EFSYS_USE_UINT64 0 +#if _BYTE_ORDER == _BIG_ENDIAN +#define EFSYS_IS_BIG_ENDIAN 1 +#define EFSYS_IS_LITTLE_ENDIAN 0 +#elif _BYTE_ORDER == _LITTLE_ENDIAN +#define EFSYS_IS_BIG_ENDIAN 0 +#define EFSYS_IS_LITTLE_ENDIAN 1 +#endif +#include "efx_types.h" + +/* Common code requires this */ +#if __FreeBSD_version < 800068 +#define memmove(d, s, l) bcopy(s, d, l) +#endif + +/* FreeBSD equivalents of Solaris things */ +#ifndef _NOTE +#define _NOTE(s) +#endif + +#ifndef B_FALSE +#define B_FALSE FALSE +#endif +#ifndef B_TRUE +#define B_TRUE TRUE +#endif + +#ifndef IS_P2ALIGNED +#define IS_P2ALIGNED(v, a) ((((uintptr_t)(v)) & ((uintptr_t)(a) - 1)) == 0) +#endif + +#ifndef P2ROUNDUP +#define P2ROUNDUP(x, align) (-(-(x) & -(align))) +#endif + +#ifndef IS2P +#define ISP2(x) (((x) & ((x) - 1)) == 0) +#endif + +#define ENOTACTIVE EINVAL + +/* Memory type to use on FreeBSD */ +MALLOC_DECLARE(M_SFXGE); + +/* Machine dependend prefetch wrappers */ +#if defined(__i386) || defined(__amd64) +static __inline void +prefetch_read_many(void *addr) +{ + __asm__( + "prefetcht0 (%0)" + : + : "r" (addr)); +} + +static __inline void +prefetch_read_once(void *addr) +{ + __asm__( + "prefetchnta (%0)" + : + : "r" (addr)); +} +#endif + +#if defined(__i386__) || defined(__amd64__) +#include +#include +#endif +static __inline void +sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map, + struct mbuf *m, bus_dma_segment_t *seg) +{ +#if defined(__i386__) || defined(__amd64__) + seg->ds_addr = pmap_kextract(mtod(m, vm_offset_t)); + seg->ds_len = m->m_len; +#else + int nsegstmp; + + bus_dmamap_load_mbuf_sg(tag, map, m, seg, &nsegstmp, 0); +#endif +} + +/* Modifiers used for DOS builds */ +#define __cs +#define __far + +/* Modifiers used for Windows builds */ +#define __in +#define __in_opt +#define __in_ecount(_n) +#define __in_ecount_opt(_n) +#define __in_bcount(_n) +#define __in_bcount_opt(_n) + +#define __out +#define __out_opt +#define __out_ecount(_n) +#define __out_ecount_opt(_n) +#define __out_bcount(_n) +#define __out_bcount_opt(_n) + +#define __deref_out + +#define __inout +#define __inout_opt +#define __inout_ecount(_n) +#define __inout_ecount_opt(_n) +#define __inout_bcount(_n) +#define __inout_bcount_opt(_n) +#define __inout_bcount_full_opt(_n) + +#define __deref_out_bcount_opt(n) + +#define __checkReturn + +#define __drv_when(_p, _c) + +/* Code inclusion options */ + + +#define EFSYS_OPT_NAMES 1 + +#define EFSYS_OPT_FALCON 0 +#define EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE 0 +#define EFSYS_OPT_SIENA 1 +#ifdef DEBUG +#define EFSYS_OPT_CHECK_REG 1 +#else +#define EFSYS_OPT_CHECK_REG 0 +#endif + +#define EFSYS_OPT_MCDI 1 + +#define EFSYS_OPT_MAC_FALCON_GMAC 0 +#define EFSYS_OPT_MAC_FALCON_XMAC 0 +#define EFSYS_OPT_MAC_STATS 1 + +#define EFSYS_OPT_LOOPBACK 0 + +#define EFSYS_OPT_MON_NULL 0 +#define EFSYS_OPT_MON_LM87 0 +#define EFSYS_OPT_MON_MAX6647 0 +#define EFSYS_OPT_MON_SIENA 0 +#define EFSYS_OPT_MON_STATS 0 + +#define EFSYS_OPT_PHY_NULL 0 +#define EFSYS_OPT_PHY_QT2022C2 0 +#define EFSYS_OPT_PHY_SFX7101 0 +#define EFSYS_OPT_PHY_TXC43128 0 +#define EFSYS_OPT_PHY_PM8358 0 +#define EFSYS_OPT_PHY_SFT9001 0 +#define EFSYS_OPT_PHY_QT2025C 0 +#define EFSYS_OPT_PHY_STATS 1 +#define EFSYS_OPT_PHY_PROPS 0 +#define EFSYS_OPT_PHY_BIST 1 +#define EFSYS_OPT_PHY_LED_CONTROL 1 +#define EFSYS_OPT_PHY_FLAGS 0 + +#define EFSYS_OPT_VPD 1 +#define EFSYS_OPT_NVRAM 1 +#define EFSYS_OPT_NVRAM_FALCON_BOOTROM 0 +#define EFSYS_OPT_NVRAM_SFT9001 0 +#define EFSYS_OPT_NVRAM_SFX7101 0 +#define EFSYS_OPT_BOOTCFG 0 + +#define EFSYS_OPT_PCIE_TUNE 0 +#define EFSYS_OPT_DIAG 0 +#define EFSYS_OPT_WOL 1 +#define EFSYS_OPT_RX_SCALE 1 +#define EFSYS_OPT_QSTATS 1 +#define EFSYS_OPT_FILTER 0 +#define EFSYS_OPT_RX_SCATTER 0 +#define EFSYS_OPT_RX_HDR_SPLIT 0 + +#define EFSYS_OPT_EV_PREFETCH 0 + +#define EFSYS_OPT_DECODE_INTR_FATAL 1 + +/* ID */ + +typedef struct __efsys_identifier_s efsys_identifier_t; + +/* PROBE */ + +#ifndef KDTRACE_HOOKS + +#define EFSYS_PROBE(_name) + +#define EFSYS_PROBE1(_name, _type1, _arg1) + +#define EFSYS_PROBE2(_name, _type1, _arg1, _type2, _arg2) + +#define EFSYS_PROBE3(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3) + +#define EFSYS_PROBE4(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3, _type4, _arg4) + +#define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3, _type4, _arg4, _type5, _arg5) + +#define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3, _type4, _arg4, _type5, _arg5, \ + _type6, _arg6) + +#define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3, _type4, _arg4, _type5, _arg5, \ + _type6, _arg6, _type7, _arg7) + +#else /* KDTRACE_HOOKS */ + +#define EFSYS_PROBE(_name) \ + DTRACE_PROBE(_name) + +#define EFSYS_PROBE1(_name, _type1, _arg1) \ + DTRACE_PROBE1(_name, _type1, _arg1) + +#define EFSYS_PROBE2(_name, _type1, _arg1, _type2, _arg2) \ + DTRACE_PROBE2(_name, _type1, _arg1, _type2, _arg2) + +#define EFSYS_PROBE3(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3) \ + DTRACE_PROBE3(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3) + +#define EFSYS_PROBE4(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3, _type4, _arg4) \ + DTRACE_PROBE4(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3, _type4, _arg4) + +#ifdef DTRACE_PROBE5 +#define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3, _type4, _arg4, _type5, _arg5) \ + DTRACE_PROBE5(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3, _type4, _arg4, _type5, _arg5) +#else +#define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3, _type4, _arg4, _type5, _arg5) \ + DTRACE_PROBE4(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3, _type4, _arg4) +#endif + +#ifdef DTRACE_PROBE6 +#define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3, _type4, _arg4, _type5, _arg5, \ + _type6, _arg6) \ + DTRACE_PROBE6(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3, _type4, _arg4, _type5, _arg5, \ + _type6, _arg6) +#else +#define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3, _type4, _arg4, _type5, _arg5, \ + _type6, _arg6) \ + EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3, _type4, _arg4, _type5, _arg5) +#endif + +#ifdef DTRACE_PROBE7 +#define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3, _type4, _arg4, _type5, _arg5, \ + _type6, _arg6, _type7, _arg7) \ + DTRACE_PROBE7(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3, _type4, _arg4, _type5, _arg5, \ + _type6, _arg6, _type7, _arg7) +#else +#define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3, _type4, _arg4, _type5, _arg5, \ + _type6, _arg6, _type7, _arg7) \ + EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \ + _type3, _arg3, _type4, _arg4, _type5, _arg5, \ + _type6, _arg6) +#endif + +#endif /* KDTRACE_HOOKS */ + +/* DMA */ + +typedef uint64_t efsys_dma_addr_t; + +typedef struct efsys_mem_s { + bus_dma_tag_t esm_tag; + bus_dmamap_t esm_map; + caddr_t esm_base; + efsys_dma_addr_t esm_addr; + size_t esm_size; +} efsys_mem_t; + + +#define EFSYS_MEM_ZERO(_esmp, _size) \ + do { \ + (void) memset((_esmp)->esm_base, 0, (_size)); \ + \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_MEM_READD(_esmp, _offset, _edp) \ + do { \ + uint32_t *addr; \ + \ + _NOTE(CONSTANTCONDITION) \ + KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_dword_t)), \ + ("not power of 2 aligned")); \ + \ + addr = (void *)((_esmp)->esm_base + (_offset)); \ + \ + (_edp)->ed_u32[0] = *addr; \ + \ + EFSYS_PROBE2(mem_readd, unsigned int, (_offset), \ + uint32_t, (_edp)->ed_u32[0]); \ + \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_MEM_READQ(_esmp, _offset, _eqp) \ + do { \ + uint32_t *addr; \ + \ + _NOTE(CONSTANTCONDITION) \ + KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)), \ + ("not power of 2 aligned")); \ + \ + addr = (void *)((_esmp)->esm_base + (_offset)); \ + \ + (_eqp)->eq_u32[0] = *addr++; \ + (_eqp)->eq_u32[1] = *addr; \ + \ + EFSYS_PROBE3(mem_readq, unsigned int, (_offset), \ + uint32_t, (_eqp)->eq_u32[1], \ + uint32_t, (_eqp)->eq_u32[0]); \ + \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_MEM_READO(_esmp, _offset, _eop) \ + do { \ + uint32_t *addr; \ + \ + _NOTE(CONSTANTCONDITION) \ + KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)), \ + ("not power of 2 aligned")); \ + \ + addr = (void *)((_esmp)->esm_base + (_offset)); \ + \ + (_eop)->eo_u32[0] = *addr++; \ + (_eop)->eo_u32[1] = *addr++; \ + (_eop)->eo_u32[2] = *addr++; \ + (_eop)->eo_u32[3] = *addr; \ + \ + EFSYS_PROBE5(mem_reado, unsigned int, (_offset), \ + uint32_t, (_eop)->eo_u32[3], \ + uint32_t, (_eop)->eo_u32[2], \ + uint32_t, (_eop)->eo_u32[1], \ + uint32_t, (_eop)->eo_u32[0]); \ + \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_MEM_WRITED(_esmp, _offset, _edp) \ + do { \ + uint32_t *addr; \ + \ + _NOTE(CONSTANTCONDITION) \ + KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_dword_t)), \ + ("not power of 2 aligned")); \ + \ + EFSYS_PROBE2(mem_writed, unsigned int, (_offset), \ + uint32_t, (_edp)->ed_u32[0]); \ + \ + addr = (void *)((_esmp)->esm_base + (_offset)); \ + \ + *addr = (_edp)->ed_u32[0]; \ + \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_MEM_WRITEQ(_esmp, _offset, _eqp) \ + do { \ + uint32_t *addr; \ + \ + _NOTE(CONSTANTCONDITION) \ + KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)), \ + ("not power of 2 aligned")); \ + \ + EFSYS_PROBE3(mem_writeq, unsigned int, (_offset), \ + uint32_t, (_eqp)->eq_u32[1], \ + uint32_t, (_eqp)->eq_u32[0]); \ + \ + addr = (void *)((_esmp)->esm_base + (_offset)); \ + \ + *addr++ = (_eqp)->eq_u32[0]; \ + *addr = (_eqp)->eq_u32[1]; \ + \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_MEM_WRITEO(_esmp, _offset, _eop) \ + do { \ + uint32_t *addr; \ + \ + _NOTE(CONSTANTCONDITION) \ + KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)), \ + ("not power of 2 aligned")); \ + \ + EFSYS_PROBE5(mem_writeo, unsigned int, (_offset), \ + uint32_t, (_eop)->eo_u32[3], \ + uint32_t, (_eop)->eo_u32[2], \ + uint32_t, (_eop)->eo_u32[1], \ + uint32_t, (_eop)->eo_u32[0]); \ + \ + addr = (void *)((_esmp)->esm_base + (_offset)); \ + \ + *addr++ = (_eop)->eo_u32[0]; \ + *addr++ = (_eop)->eo_u32[1]; \ + *addr++ = (_eop)->eo_u32[2]; \ + *addr = (_eop)->eo_u32[3]; \ + \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_MEM_ADDR(_esmp) \ + ((_esmp)->esm_addr) + +/* BAR */ + +typedef struct efsys_bar_s { + struct mtx esb_lock; + bus_space_tag_t esb_tag; + bus_space_handle_t esb_handle; + int esb_rid; + struct resource *esb_res; +} efsys_bar_t; + +#define EFSYS_BAR_READD(_esbp, _offset, _edp, _lock) \ + do { \ + _NOTE(CONSTANTCONDITION) \ + KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_dword_t)), \ + ("not power of 2 aligned")); \ + \ + _NOTE(CONSTANTCONDITION) \ + if (_lock) \ + mtx_lock(&((_esbp)->esb_lock)); \ + \ + (_edp)->ed_u32[0] = bus_space_read_4((_esbp)->esb_tag, \ + (_esbp)->esb_handle, (_offset)); \ + \ + EFSYS_PROBE2(bar_readd, unsigned int, (_offset), \ + uint32_t, (_edp)->ed_u32[0]); \ + \ + _NOTE(CONSTANTCONDITION) \ + if (_lock) \ + mtx_unlock(&((_esbp)->esb_lock)); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_BAR_READQ(_esbp, _offset, _eqp) \ + do { \ + _NOTE(CONSTANTCONDITION) \ + KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)), \ + ("not power of 2 aligned")); \ + \ + mtx_lock(&((_esbp)->esb_lock)); \ + \ + (_eqp)->eq_u32[0] = bus_space_read_4((_esbp)->esb_tag, \ + (_esbp)->esb_handle, (_offset)); \ + (_eqp)->eq_u32[1] = bus_space_read_4((_esbp)->esb_tag, \ + (_esbp)->esb_handle, (_offset+4)); \ + \ + EFSYS_PROBE3(bar_readq, unsigned int, (_offset), \ + uint32_t, (_eqp)->eq_u32[1], \ + uint32_t, (_eqp)->eq_u32[0]); \ + \ + mtx_unlock(&((_esbp)->esb_lock)); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_BAR_READO(_esbp, _offset, _eop, _lock) \ + do { \ + _NOTE(CONSTANTCONDITION) \ + KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)), \ + ("not power of 2 aligned")); \ + \ + _NOTE(CONSTANTCONDITION) \ + if (_lock) \ + mtx_lock(&((_esbp)->esb_lock)); \ + \ + (_eop)->eo_u32[0] = bus_space_read_4((_esbp)->esb_tag, \ + (_esbp)->esb_handle, (_offset)); \ + (_eop)->eo_u32[1] = bus_space_read_4((_esbp)->esb_tag, \ + (_esbp)->esb_handle, (_offset+4)); \ + (_eop)->eo_u32[2] = bus_space_read_4((_esbp)->esb_tag, \ + (_esbp)->esb_handle, (_offset+8)); \ + (_eop)->eo_u32[3] = bus_space_read_4((_esbp)->esb_tag, \ + (_esbp)->esb_handle, (_offset+12)); \ + \ + EFSYS_PROBE5(bar_reado, unsigned int, (_offset), \ + uint32_t, (_eop)->eo_u32[3], \ + uint32_t, (_eop)->eo_u32[2], \ + uint32_t, (_eop)->eo_u32[1], \ + uint32_t, (_eop)->eo_u32[0]); \ + \ + _NOTE(CONSTANTCONDITION) \ + if (_lock) \ + mtx_unlock(&((_esbp)->esb_lock)); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_BAR_WRITED(_esbp, _offset, _edp, _lock) \ + do { \ + _NOTE(CONSTANTCONDITION) \ + KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_dword_t)), \ + ("not power of 2 aligned")); \ + \ + _NOTE(CONSTANTCONDITION) \ + if (_lock) \ + mtx_lock(&((_esbp)->esb_lock)); \ + \ + EFSYS_PROBE2(bar_writed, unsigned int, (_offset), \ + uint32_t, (_edp)->ed_u32[0]); \ + \ + bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\ + (_offset), (_edp)->ed_u32[0]); \ + \ + _NOTE(CONSTANTCONDITION) \ + if (_lock) \ + mtx_unlock(&((_esbp)->esb_lock)); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_BAR_WRITEQ(_esbp, _offset, _eqp) \ + do { \ + _NOTE(CONSTANTCONDITION) \ + KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)), \ + ("not power of 2 aligned")); \ + \ + mtx_lock(&((_esbp)->esb_lock)); \ + \ + EFSYS_PROBE3(bar_writeq, unsigned int, (_offset), \ + uint32_t, (_eqp)->eq_u32[1], \ + uint32_t, (_eqp)->eq_u32[0]); \ + \ + bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\ + (_offset), (_eqp)->eq_u32[0]); \ + bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\ + (_offset+4), (_eqp)->eq_u32[1]); \ + \ + mtx_unlock(&((_esbp)->esb_lock)); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_BAR_WRITEO(_esbp, _offset, _eop, _lock) \ + do { \ + _NOTE(CONSTANTCONDITION) \ + KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)), \ + ("not power of 2 aligned")); \ + \ + _NOTE(CONSTANTCONDITION) \ + if (_lock) \ + mtx_lock(&((_esbp)->esb_lock)); \ + \ + EFSYS_PROBE5(bar_writeo, unsigned int, (_offset), \ + uint32_t, (_eop)->eo_u32[3], \ + uint32_t, (_eop)->eo_u32[2], \ + uint32_t, (_eop)->eo_u32[1], \ + uint32_t, (_eop)->eo_u32[0]); \ + \ + bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\ + (_offset), (_eop)->eo_u32[0]); \ + bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\ + (_offset+4), (_eop)->eo_u32[1]); \ + bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\ + (_offset+8), (_eop)->eo_u32[2]); \ + bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\ + (_offset+12), (_eop)->eo_u32[3]); \ + \ + _NOTE(CONSTANTCONDITION) \ + if (_lock) \ + mtx_unlock(&((_esbp)->esb_lock)); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +/* SPIN */ + +#define EFSYS_SPIN(_us) \ + do { \ + DELAY(_us); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_SLEEP EFSYS_SPIN + +/* BARRIERS */ + +/* Strict ordering guaranteed by devacc.devacc_attr_dataorder */ +#define EFSYS_MEM_READ_BARRIER() +#define EFSYS_PIO_WRITE_BARRIER() + +/* TIMESTAMP */ + +typedef clock_t efsys_timestamp_t; + +#define EFSYS_TIMESTAMP(_usp) \ + do { \ + clock_t now; \ + \ + now = ticks; \ + *(_usp) = now * hz / 1000000; \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +/* KMEM */ + +#define EFSYS_KMEM_ALLOC(_esip, _size, _p) \ + do { \ + (_esip) = (_esip); \ + (_p) = malloc((_size), M_SFXGE, M_WAITOK|M_ZERO); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_KMEM_FREE(_esip, _size, _p) \ + do { \ + (void) (_esip); \ + (void) (_size); \ + free((_p), M_SFXGE); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +/* LOCK */ + +typedef struct mtx efsys_lock_t; + +#define EFSYS_LOCK_MAGIC 0x000010c4 + +#define EFSYS_LOCK(_lockp, _state) \ + do { \ + mtx_lock(_lockp); \ + (_state) = EFSYS_LOCK_MAGIC; \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_UNLOCK(_lockp, _state) \ + do { \ + if ((_state) != EFSYS_LOCK_MAGIC) \ + KASSERT(B_FALSE, ("not locked")); \ + mtx_unlock(_lockp); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +/* PREEMPT */ + +#define EFSYS_PREEMPT_DISABLE(_state) \ + do { \ + (_state) = (_state); \ + critical_enter(); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_PREEMPT_ENABLE(_state) \ + do { \ + (_state) = (_state); \ + critical_exit(_state); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +/* STAT */ + +typedef uint64_t efsys_stat_t; + +#define EFSYS_STAT_INCR(_knp, _delta) \ + do { \ + *(_knp) += (_delta); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_STAT_DECR(_knp, _delta) \ + do { \ + *(_knp) -= (_delta); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_STAT_SET(_knp, _val) \ + do { \ + *(_knp) = (_val); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_STAT_SET_QWORD(_knp, _valp) \ + do { \ + *(_knp) = le64toh((_valp)->eq_u64[0]); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_STAT_SET_DWORD(_knp, _valp) \ + do { \ + *(_knp) = le32toh((_valp)->ed_u32[0]); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_STAT_INCR_QWORD(_knp, _valp) \ + do { \ + *(_knp) += le64toh((_valp)->eq_u64[0]); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFSYS_STAT_SUBR_QWORD(_knp, _valp) \ + do { \ + *(_knp) -= le64toh((_valp)->eq_u64[0]); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +/* ERR */ + +extern void sfxge_err(efsys_identifier_t *, unsigned int, + uint32_t, uint32_t); + +#if EFSYS_OPT_DECODE_INTR_FATAL +#define EFSYS_ERR(_esip, _code, _dword0, _dword1) \ + do { \ + sfxge_err((_esip), (_code), (_dword0), (_dword1)); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) +#endif + +/* ASSERT */ + +#define EFSYS_ASSERT(_exp) do { \ + if (!(_exp)) \ + panic(#_exp); \ + } while (0) + +#define EFSYS_ASSERT3(_x, _op, _y, _t) do { \ + const _t __x = (_t)(_x); \ + const _t __y = (_t)(_y); \ + if (!(__x _op __y)) \ + panic("assertion failed at %s:%u", __FILE__, __LINE__); \ + } while(0) + +#define EFSYS_ASSERT3U(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, uint64_t) +#define EFSYS_ASSERT3S(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, int64_t) +#define EFSYS_ASSERT3P(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, uintptr_t) + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_EFSYS_H */ diff --git a/sys/dev/sfxge/common/efx.h b/sys/dev/sfxge/common/efx.h new file mode 100644 index 000000000000..18c248b4b321 --- /dev/null +++ b/sys/dev/sfxge/common/efx.h @@ -0,0 +1,1893 @@ +/*- + * Copyright 2006-2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SYS_EFX_H +#define _SYS_EFX_H + +#include "efsys.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define EFX_STATIC_ASSERT(_cond) ((void)sizeof(char[(_cond) ? 1 : -1])) + +#define EFX_ARRAY_SIZE(_array) (sizeof(_array) / sizeof((_array)[0])) + +#ifndef EFSYS_MEM_IS_NULL +#define EFSYS_MEM_IS_NULL(_esmp) ((_esmp)->esm_base == NULL) +#endif + +typedef enum efx_family_e { + EFX_FAMILY_INVALID, + EFX_FAMILY_FALCON, + EFX_FAMILY_SIENA, + EFX_FAMILY_NTYPES +} efx_family_t; + +extern __checkReturn int +efx_family( + __in uint16_t venid, + __in uint16_t devid, + __out efx_family_t *efp); + +extern __checkReturn int +efx_infer_family( + __in efsys_bar_t *esbp, + __out efx_family_t *efp); + +#define EFX_PCI_VENID_SFC 0x1924 +#define EFX_PCI_DEVID_FALCON 0x0710 +#define EFX_PCI_DEVID_BETHPAGE 0x0803 +#define EFX_PCI_DEVID_SIENA 0x0813 +#define EFX_PCI_DEVID_SIENA_F1_UNINIT 0x0810 + +#define EFX_MEM_BAR 2 + +/* Error codes */ + +enum { + EFX_ERR_INVALID, + EFX_ERR_SRAM_OOB, + EFX_ERR_BUFID_DC_OOB, + EFX_ERR_MEM_PERR, + EFX_ERR_RBUF_OWN, + EFX_ERR_TBUF_OWN, + EFX_ERR_RDESQ_OWN, + EFX_ERR_TDESQ_OWN, + EFX_ERR_EVQ_OWN, + EFX_ERR_EVFF_OFLO, + EFX_ERR_ILL_ADDR, + EFX_ERR_SRAM_PERR, + EFX_ERR_NCODES +}; + +/* NIC */ + +typedef struct efx_nic_s efx_nic_t; + +extern __checkReturn int +efx_nic_create( + __in efx_family_t family, + __in efsys_identifier_t *esip, + __in efsys_bar_t *esbp, + __in efsys_lock_t *eslp, + __deref_out efx_nic_t **enpp); + +extern __checkReturn int +efx_nic_probe( + __in efx_nic_t *enp); + +#if EFSYS_OPT_PCIE_TUNE + +extern __checkReturn int +efx_nic_pcie_tune( + __in efx_nic_t *enp, + unsigned int nlanes); + +extern __checkReturn int +efx_nic_pcie_extended_sync( + __in efx_nic_t *enp); + +#endif /* EFSYS_OPT_PCIE_TUNE */ + +extern __checkReturn int +efx_nic_init( + __in efx_nic_t *enp); + +extern __checkReturn int +efx_nic_reset( + __in efx_nic_t *enp); + +#if EFSYS_OPT_DIAG + +extern __checkReturn int +efx_nic_register_test( + __in efx_nic_t *enp); + +#endif /* EFSYS_OPT_DIAG */ + +extern void +efx_nic_fini( + __in efx_nic_t *enp); + +extern void +efx_nic_unprobe( + __in efx_nic_t *enp); + +extern void +efx_nic_destroy( + __in efx_nic_t *enp); + +#if EFSYS_OPT_MCDI + +typedef struct efx_mcdi_req_s efx_mcdi_req_t; + +typedef enum efx_mcdi_exception_e { + EFX_MCDI_EXCEPTION_MC_REBOOT, + EFX_MCDI_EXCEPTION_MC_BADASSERT, +} efx_mcdi_exception_t; + +typedef struct efx_mcdi_transport_s { + void *emt_context; + void (*emt_execute)(void *, efx_mcdi_req_t *); + void (*emt_ev_cpl)(void *); + void (*emt_exception)(void *, efx_mcdi_exception_t); +} efx_mcdi_transport_t; + +extern __checkReturn int +efx_mcdi_init( + __in efx_nic_t *enp, + __in const efx_mcdi_transport_t *mtp); + +extern __checkReturn int +efx_mcdi_reboot( + __in efx_nic_t *enp); + +extern void +efx_mcdi_request_start( + __in efx_nic_t *enp, + __in efx_mcdi_req_t *emrp, + __in boolean_t ev_cpl); + +extern __checkReturn boolean_t +efx_mcdi_request_poll( + __in efx_nic_t *enp); + +extern __checkReturn boolean_t +efx_mcdi_request_abort( + __in efx_nic_t *enp); + +extern void +efx_mcdi_fini( + __in efx_nic_t *enp); + +#endif /* EFSYS_OPT_MCDI */ + +/* INTR */ + +#define EFX_NINTR_FALCON 64 +#define EFX_NINTR_SIENA 1024 + +typedef enum efx_intr_type_e { + EFX_INTR_INVALID = 0, + EFX_INTR_LINE, + EFX_INTR_MESSAGE, + EFX_INTR_NTYPES +} efx_intr_type_t; + +#define EFX_INTR_SIZE (sizeof (efx_oword_t)) + +extern __checkReturn int +efx_intr_init( + __in efx_nic_t *enp, + __in efx_intr_type_t type, + __in efsys_mem_t *esmp); + +extern void +efx_intr_enable( + __in efx_nic_t *enp); + +extern void +efx_intr_disable( + __in efx_nic_t *enp); + +extern void +efx_intr_disable_unlocked( + __in efx_nic_t *enp); + +#define EFX_INTR_NEVQS 32 + +extern __checkReturn int +efx_intr_trigger( + __in efx_nic_t *enp, + __in unsigned int level); + +extern void +efx_intr_status_line( + __in efx_nic_t *enp, + __out boolean_t *fatalp, + __out uint32_t *maskp); + +extern void +efx_intr_status_message( + __in efx_nic_t *enp, + __in unsigned int message, + __out boolean_t *fatalp); + +extern void +efx_intr_fatal( + __in efx_nic_t *enp); + +extern void +efx_intr_fini( + __in efx_nic_t *enp); + +/* MAC */ + +#if EFSYS_OPT_MAC_STATS + +/* START MKCONFIG GENERATED EfxHeaderMacBlock bb8d39428b6fdcf5 */ +typedef enum efx_mac_stat_e { + EFX_MAC_RX_OCTETS, + EFX_MAC_RX_PKTS, + EFX_MAC_RX_UNICST_PKTS, + EFX_MAC_RX_MULTICST_PKTS, + EFX_MAC_RX_BRDCST_PKTS, + EFX_MAC_RX_PAUSE_PKTS, + EFX_MAC_RX_LE_64_PKTS, + EFX_MAC_RX_65_TO_127_PKTS, + EFX_MAC_RX_128_TO_255_PKTS, + EFX_MAC_RX_256_TO_511_PKTS, + EFX_MAC_RX_512_TO_1023_PKTS, + EFX_MAC_RX_1024_TO_15XX_PKTS, + EFX_MAC_RX_GE_15XX_PKTS, + EFX_MAC_RX_ERRORS, + EFX_MAC_RX_FCS_ERRORS, + EFX_MAC_RX_DROP_EVENTS, + EFX_MAC_RX_FALSE_CARRIER_ERRORS, + EFX_MAC_RX_SYMBOL_ERRORS, + EFX_MAC_RX_ALIGN_ERRORS, + EFX_MAC_RX_INTERNAL_ERRORS, + EFX_MAC_RX_JABBER_PKTS, + EFX_MAC_RX_LANE0_CHAR_ERR, + EFX_MAC_RX_LANE1_CHAR_ERR, + EFX_MAC_RX_LANE2_CHAR_ERR, + EFX_MAC_RX_LANE3_CHAR_ERR, + EFX_MAC_RX_LANE0_DISP_ERR, + EFX_MAC_RX_LANE1_DISP_ERR, + EFX_MAC_RX_LANE2_DISP_ERR, + EFX_MAC_RX_LANE3_DISP_ERR, + EFX_MAC_RX_MATCH_FAULT, + EFX_MAC_RX_NODESC_DROP_CNT, + EFX_MAC_TX_OCTETS, + EFX_MAC_TX_PKTS, + EFX_MAC_TX_UNICST_PKTS, + EFX_MAC_TX_MULTICST_PKTS, + EFX_MAC_TX_BRDCST_PKTS, + EFX_MAC_TX_PAUSE_PKTS, + EFX_MAC_TX_LE_64_PKTS, + EFX_MAC_TX_65_TO_127_PKTS, + EFX_MAC_TX_128_TO_255_PKTS, + EFX_MAC_TX_256_TO_511_PKTS, + EFX_MAC_TX_512_TO_1023_PKTS, + EFX_MAC_TX_1024_TO_15XX_PKTS, + EFX_MAC_TX_GE_15XX_PKTS, + EFX_MAC_TX_ERRORS, + EFX_MAC_TX_SGL_COL_PKTS, + EFX_MAC_TX_MULT_COL_PKTS, + EFX_MAC_TX_EX_COL_PKTS, + EFX_MAC_TX_LATE_COL_PKTS, + EFX_MAC_TX_DEF_PKTS, + EFX_MAC_TX_EX_DEF_PKTS, + EFX_MAC_NSTATS +} efx_mac_stat_t; + +/* END MKCONFIG GENERATED EfxHeaderMacBlock */ + +#endif /* EFSYS_OPT_MAC_STATS */ + +typedef enum efx_link_mode_e { + EFX_LINK_UNKNOWN = 0, + EFX_LINK_DOWN, + EFX_LINK_10HDX, + EFX_LINK_10FDX, + EFX_LINK_100HDX, + EFX_LINK_100FDX, + EFX_LINK_1000HDX, + EFX_LINK_1000FDX, + EFX_LINK_10000FDX, + EFX_LINK_NMODES +} efx_link_mode_t; + +#define EFX_MAC_SDU_MAX 9202 + +#define EFX_MAC_PDU(_sdu) \ + P2ROUNDUP(((_sdu) \ + + /* EtherII */ 14 \ + + /* VLAN */ 4 \ + + /* CRC */ 4 \ + + /* bug16011 */ 16), \ + (1 << 3)) + +#define EFX_MAC_PDU_MIN 60 +#define EFX_MAC_PDU_MAX EFX_MAC_PDU(EFX_MAC_SDU_MAX) + +extern __checkReturn int +efx_mac_pdu_set( + __in efx_nic_t *enp, + __in size_t pdu); + +extern __checkReturn int +efx_mac_addr_set( + __in efx_nic_t *enp, + __in uint8_t *addr); + +extern __checkReturn int +efx_mac_filter_set( + __in efx_nic_t *enp, + __in boolean_t unicst, + __in boolean_t brdcst); + +extern __checkReturn int +efx_mac_drain( + __in efx_nic_t *enp, + __in boolean_t enabled); + +extern __checkReturn int +efx_mac_up( + __in efx_nic_t *enp, + __out boolean_t *mac_upp); + +#define EFX_FCNTL_RESPOND 0x00000001 +#define EFX_FCNTL_GENERATE 0x00000002 + +extern __checkReturn int +efx_mac_fcntl_set( + __in efx_nic_t *enp, + __in unsigned int fcntl, + __in boolean_t autoneg); + +extern void +efx_mac_fcntl_get( + __in efx_nic_t *enp, + __out unsigned int *fcntl_wantedp, + __out unsigned int *fcntl_linkp); + +#define EFX_MAC_HASH_BITS (1 << 8) + +extern __checkReturn int +efx_mac_hash_set( + __in efx_nic_t *enp, + __in_ecount(EFX_MAC_HASH_BITS) unsigned int const *bucket); + +#if EFSYS_OPT_MAC_STATS + +#if EFSYS_OPT_NAMES + +extern __checkReturn const char __cs * +efx_mac_stat_name( + __in efx_nic_t *enp, + __in unsigned int id); + +#endif /* EFSYS_OPT_NAMES */ + +#define EFX_MAC_STATS_SIZE 0x400 + +/* + * Upload mac statistics supported by the hardware into the given buffer. + * + * The reference buffer must be at least %EFX_MAC_STATS_SIZE bytes, + * and page aligned. + * + * The hardware will only DMA statistics that it understands (of course). + * Drivers should not make any assumptions about which statistics are + * supported, especially when the statistics are generated by firmware. + * + * Thus, drivers should zero this buffer before use, so that not-understood + * statistics read back as zero. + */ +extern __checkReturn int +efx_mac_stats_upload( + __in efx_nic_t *enp, + __in efsys_mem_t *esmp); + +extern __checkReturn int +efx_mac_stats_periodic( + __in efx_nic_t *enp, + __in efsys_mem_t *esmp, + __in uint16_t period_ms, + __in boolean_t events); + +extern __checkReturn int +efx_mac_stats_update( + __in efx_nic_t *enp, + __in efsys_mem_t *esmp, + __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat, + __out_opt uint32_t *generationp); + +#endif /* EFSYS_OPT_MAC_STATS */ + +/* MON */ + +typedef enum efx_mon_type_e { + EFX_MON_INVALID = 0, + EFX_MON_NULL, + EFX_MON_LM87, + EFX_MON_MAX6647, + EFX_MON_SFC90X0, + EFX_MON_NTYPES +} efx_mon_type_t; + +#if EFSYS_OPT_NAMES + +extern const char __cs * +efx_mon_name( + __in efx_nic_t *enp); + +#endif /* EFSYS_OPT_NAMES */ + +extern __checkReturn int +efx_mon_init( + __in efx_nic_t *enp); + +#if EFSYS_OPT_MON_STATS + +#define EFX_MON_STATS_SIZE 0x100 + +/* START MKCONFIG GENERATED MonitorHeaderStatsBlock 16a14e61aa4f8d80 */ +typedef enum efx_mon_stat_e { + EFX_MON_STAT_2_5V, + EFX_MON_STAT_VCCP1, + EFX_MON_STAT_VCC, + EFX_MON_STAT_5V, + EFX_MON_STAT_12V, + EFX_MON_STAT_VCCP2, + EFX_MON_STAT_EXT_TEMP, + EFX_MON_STAT_INT_TEMP, + EFX_MON_STAT_AIN1, + EFX_MON_STAT_AIN2, + EFX_MON_STAT_INT_COOLING, + EFX_MON_STAT_EXT_COOLING, + EFX_MON_STAT_1V, + EFX_MON_STAT_1_2V, + EFX_MON_STAT_1_8V, + EFX_MON_STAT_3_3V, + EFX_MON_NSTATS +} efx_mon_stat_t; + +/* END MKCONFIG GENERATED MonitorHeaderStatsBlock */ + +typedef enum efx_mon_stat_state_e { + EFX_MON_STAT_STATE_OK = 0, + EFX_MON_STAT_STATE_WARNING = 1, + EFX_MON_STAT_STATE_FATAL = 2, + EFX_MON_STAT_STATE_BROKEN = 3, +} efx_mon_stat_state_t; + +typedef struct efx_mon_stat_value_t { + uint16_t emsv_value; + uint16_t emsv_state; +} efx_mon_stat_value_t; + +#if EFSYS_OPT_NAMES + +extern const char __cs * +efx_mon_stat_name( + __in efx_nic_t *enp, + __in efx_mon_stat_t id); + +#endif /* EFSYS_OPT_NAMES */ + +extern __checkReturn int +efx_mon_stats_update( + __in efx_nic_t *enp, + __in efsys_mem_t *esmp, + __out_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values); + +#endif /* EFSYS_OPT_MON_STATS */ + +extern void +efx_mon_fini( + __in efx_nic_t *enp); + +/* PHY */ + +#define PMA_PMD_MMD 1 +#define PCS_MMD 3 +#define PHY_XS_MMD 4 +#define DTE_XS_MMD 5 +#define AN_MMD 7 +#define CL22EXT_MMD 29 + +#define MAXMMD ((1 << 5) - 1) + +/* PHY types */ +#define EFX_PHY_NULL 0x0 +#define EFX_PHY_TXC43128 0x1 +#define EFX_PHY_SFX7101 0x3 +#define EFX_PHY_QT2022C2 0x4 +#define EFX_PHY_SFT9001A 0x8 +#define EFX_PHY_QT2025C 0x9 +#define EFX_PHY_SFT9001B 0xa +#define EFX_PHY_QLX111V 0xc + +extern __checkReturn int +efx_phy_verify( + __in efx_nic_t *enp); + +#if EFSYS_OPT_PHY_LED_CONTROL + +typedef enum efx_phy_led_mode_e { + EFX_PHY_LED_DEFAULT = 0, + EFX_PHY_LED_OFF, + EFX_PHY_LED_ON, + EFX_PHY_LED_FLASH, + EFX_PHY_LED_NMODES +} efx_phy_led_mode_t; + +extern __checkReturn int +efx_phy_led_set( + __in efx_nic_t *enp, + __in efx_phy_led_mode_t mode); + +#endif /* EFSYS_OPT_PHY_LED_CONTROL */ + +extern __checkReturn int +efx_port_init( + __in efx_nic_t *enp); + +#if EFSYS_OPT_LOOPBACK + +typedef enum efx_loopback_type_e { + EFX_LOOPBACK_OFF = 0, + EFX_LOOPBACK_DATA = 1, + EFX_LOOPBACK_GMAC = 2, + EFX_LOOPBACK_XGMII = 3, + EFX_LOOPBACK_XGXS = 4, + EFX_LOOPBACK_XAUI = 5, + EFX_LOOPBACK_GMII = 6, + EFX_LOOPBACK_SGMII = 7, + EFX_LOOPBACK_XGBR = 8, + EFX_LOOPBACK_XFI = 9, + EFX_LOOPBACK_XAUI_FAR = 10, + EFX_LOOPBACK_GMII_FAR = 11, + EFX_LOOPBACK_SGMII_FAR = 12, + EFX_LOOPBACK_XFI_FAR = 13, + EFX_LOOPBACK_GPHY = 14, + EFX_LOOPBACK_PHY_XS = 15, + EFX_LOOPBACK_PCS = 16, + EFX_LOOPBACK_PMA_PMD = 17, + EFX_LOOPBACK_NTYPES +} efx_loopback_type_t; + +#define EFX_LOOPBACK_MAC_MASK \ + ((1 << EFX_LOOPBACK_DATA) | \ + (1 << EFX_LOOPBACK_GMAC) | \ + (1 << EFX_LOOPBACK_XGMII) | \ + (1 << EFX_LOOPBACK_XGXS) | \ + (1 << EFX_LOOPBACK_XAUI) | \ + (1 << EFX_LOOPBACK_GMII) | \ + (1 << EFX_LOOPBACK_SGMII) | \ + (1 << EFX_LOOPBACK_XGBR) | \ + (1 << EFX_LOOPBACK_XFI) | \ + (1 << EFX_LOOPBACK_XAUI_FAR) | \ + (1 << EFX_LOOPBACK_GMII_FAR) | \ + (1 << EFX_LOOPBACK_SGMII_FAR) | \ + (1 << EFX_LOOPBACK_XFI_FAR)) + +#define EFX_LOOPBACK_MASK \ + ((1 << EFX_LOOPBACK_NTYPES) - 1) + +extern __checkReturn int +efx_port_loopback_set( + __in efx_nic_t *enp, + __in efx_link_mode_t link_mode, + __in efx_loopback_type_t type); + +#if EFSYS_OPT_NAMES + +extern __checkReturn const char __cs * +efx_loopback_type_name( + __in efx_nic_t *enp, + __in efx_loopback_type_t type); + +#endif /* EFSYS_OPT_NAMES */ + +#endif /* EFSYS_OPT_LOOPBACK */ + +extern __checkReturn int +efx_port_poll( + __in efx_nic_t *enp, + __out efx_link_mode_t *link_modep); + +extern void +efx_port_fini( + __in efx_nic_t *enp); + +typedef enum efx_phy_cap_type_e { + EFX_PHY_CAP_INVALID = 0, + EFX_PHY_CAP_10HDX, + EFX_PHY_CAP_10FDX, + EFX_PHY_CAP_100HDX, + EFX_PHY_CAP_100FDX, + EFX_PHY_CAP_1000HDX, + EFX_PHY_CAP_1000FDX, + EFX_PHY_CAP_10000FDX, + EFX_PHY_CAP_PAUSE, + EFX_PHY_CAP_ASYM, + EFX_PHY_CAP_AN, + EFX_PHY_CAP_NTYPES +} efx_phy_cap_type_t; + + +#define EFX_PHY_CAP_CURRENT 0x00000000 +#define EFX_PHY_CAP_DEFAULT 0x00000001 +#define EFX_PHY_CAP_PERM 0x00000002 + +extern void +efx_phy_adv_cap_get( + __in efx_nic_t *enp, + __in uint32_t flag, + __out uint32_t *maskp); + +extern __checkReturn int +efx_phy_adv_cap_set( + __in efx_nic_t *enp, + __in uint32_t mask); + +extern void +efx_phy_lp_cap_get( + __in efx_nic_t *enp, + __out uint32_t *maskp); + +extern __checkReturn int +efx_phy_oui_get( + __in efx_nic_t *enp, + __out uint32_t *ouip); + +typedef enum efx_phy_media_type_e { + EFX_PHY_MEDIA_INVALID = 0, + EFX_PHY_MEDIA_XAUI, + EFX_PHY_MEDIA_CX4, + EFX_PHY_MEDIA_KX4, + EFX_PHY_MEDIA_XFP, + EFX_PHY_MEDIA_SFP_PLUS, + EFX_PHY_MEDIA_BASE_T, + EFX_PHY_MEDIA_NTYPES +} efx_phy_media_type_t; + +/* Get the type of medium currently used. If the board has ports for + * modules, a module is present, and we recognise the media type of + * the module, then this will be the media type of the module. + * Otherwise it will be the media type of the port. + */ +extern void +efx_phy_media_type_get( + __in efx_nic_t *enp, + __out efx_phy_media_type_t *typep); + +#if EFSYS_OPT_PHY_STATS + +/* START MKCONFIG GENERATED PhyHeaderStatsBlock 30ed56ad501f8e36 */ +typedef enum efx_phy_stat_e { + EFX_PHY_STAT_OUI, + EFX_PHY_STAT_PMA_PMD_LINK_UP, + EFX_PHY_STAT_PMA_PMD_RX_FAULT, + EFX_PHY_STAT_PMA_PMD_TX_FAULT, + EFX_PHY_STAT_PMA_PMD_REV_A, + EFX_PHY_STAT_PMA_PMD_REV_B, + EFX_PHY_STAT_PMA_PMD_REV_C, + EFX_PHY_STAT_PMA_PMD_REV_D, + EFX_PHY_STAT_PCS_LINK_UP, + EFX_PHY_STAT_PCS_RX_FAULT, + EFX_PHY_STAT_PCS_TX_FAULT, + EFX_PHY_STAT_PCS_BER, + EFX_PHY_STAT_PCS_BLOCK_ERRORS, + EFX_PHY_STAT_PHY_XS_LINK_UP, + EFX_PHY_STAT_PHY_XS_RX_FAULT, + EFX_PHY_STAT_PHY_XS_TX_FAULT, + EFX_PHY_STAT_PHY_XS_ALIGN, + EFX_PHY_STAT_PHY_XS_SYNC_A, + EFX_PHY_STAT_PHY_XS_SYNC_B, + EFX_PHY_STAT_PHY_XS_SYNC_C, + EFX_PHY_STAT_PHY_XS_SYNC_D, + EFX_PHY_STAT_AN_LINK_UP, + EFX_PHY_STAT_AN_MASTER, + EFX_PHY_STAT_AN_LOCAL_RX_OK, + EFX_PHY_STAT_AN_REMOTE_RX_OK, + EFX_PHY_STAT_CL22EXT_LINK_UP, + EFX_PHY_STAT_SNR_A, + EFX_PHY_STAT_SNR_B, + EFX_PHY_STAT_SNR_C, + EFX_PHY_STAT_SNR_D, + EFX_PHY_STAT_PMA_PMD_SIGNAL_A, + EFX_PHY_STAT_PMA_PMD_SIGNAL_B, + EFX_PHY_STAT_PMA_PMD_SIGNAL_C, + EFX_PHY_STAT_PMA_PMD_SIGNAL_D, + EFX_PHY_STAT_AN_COMPLETE, + EFX_PHY_STAT_PMA_PMD_REV_MAJOR, + EFX_PHY_STAT_PMA_PMD_REV_MINOR, + EFX_PHY_STAT_PMA_PMD_REV_MICRO, + EFX_PHY_STAT_PCS_FW_VERSION_0, + EFX_PHY_STAT_PCS_FW_VERSION_1, + EFX_PHY_STAT_PCS_FW_VERSION_2, + EFX_PHY_STAT_PCS_FW_VERSION_3, + EFX_PHY_STAT_PCS_FW_BUILD_YY, + EFX_PHY_STAT_PCS_FW_BUILD_MM, + EFX_PHY_STAT_PCS_FW_BUILD_DD, + EFX_PHY_STAT_PCS_OP_MODE, + EFX_PHY_NSTATS +} efx_phy_stat_t; + +/* END MKCONFIG GENERATED PhyHeaderStatsBlock */ + +#if EFSYS_OPT_NAMES + +extern const char __cs * +efx_phy_stat_name( + __in efx_nic_t *enp, + __in efx_phy_stat_t stat); + +#endif /* EFSYS_OPT_NAMES */ + +#define EFX_PHY_STATS_SIZE 0x100 + +extern __checkReturn int +efx_phy_stats_update( + __in efx_nic_t *enp, + __in efsys_mem_t *esmp, + __out_ecount(EFX_PHY_NSTATS) uint32_t *stat); + +#endif /* EFSYS_OPT_PHY_STATS */ + +#if EFSYS_OPT_PHY_PROPS + +#if EFSYS_OPT_NAMES + +extern const char __cs * +efx_phy_prop_name( + __in efx_nic_t *enp, + __in unsigned int id); + +#endif /* EFSYS_OPT_NAMES */ + +#define EFX_PHY_PROP_DEFAULT 0x00000001 + +extern __checkReturn int +efx_phy_prop_get( + __in efx_nic_t *enp, + __in unsigned int id, + __in uint32_t flags, + __out uint32_t *valp); + +extern __checkReturn int +efx_phy_prop_set( + __in efx_nic_t *enp, + __in unsigned int id, + __in uint32_t val); + +#endif /* EFSYS_OPT_PHY_PROPS */ + +#if EFSYS_OPT_PHY_BIST + +typedef enum efx_phy_bist_type_e { + EFX_PHY_BIST_TYPE_UNKNOWN, + EFX_PHY_BIST_TYPE_NORMAL, + EFX_PHY_BIST_TYPE_CABLE_SHORT, + EFX_PHY_BIST_TYPE_CABLE_LONG, + EFX_PHY_BIST_TYPE_NTYPES, +} efx_phy_bist_type_t; + +typedef enum efx_phy_bist_result_e { + EFX_PHY_BIST_RESULT_UNKNOWN, + EFX_PHY_BIST_RESULT_RUNNING, + EFX_PHY_BIST_RESULT_PASSED, + EFX_PHY_BIST_RESULT_FAILED, +} efx_phy_bist_result_t; + +typedef enum efx_phy_cable_status_e { + EFX_PHY_CABLE_STATUS_OK, + EFX_PHY_CABLE_STATUS_INVALID, + EFX_PHY_CABLE_STATUS_OPEN, + EFX_PHY_CABLE_STATUS_INTRAPAIRSHORT, + EFX_PHY_CABLE_STATUS_INTERPAIRSHORT, + EFX_PHY_CABLE_STATUS_BUSY, +} efx_phy_cable_status_t; + +typedef enum efx_phy_bist_value_e { + EFX_PHY_BIST_CABLE_LENGTH_A, + EFX_PHY_BIST_CABLE_LENGTH_B, + EFX_PHY_BIST_CABLE_LENGTH_C, + EFX_PHY_BIST_CABLE_LENGTH_D, + EFX_PHY_BIST_CABLE_STATUS_A, + EFX_PHY_BIST_CABLE_STATUS_B, + EFX_PHY_BIST_CABLE_STATUS_C, + EFX_PHY_BIST_CABLE_STATUS_D, + EFX_PHY_BIST_FAULT_CODE, + EFX_PHY_BIST_NVALUES, +} efx_phy_bist_value_t; + +extern __checkReturn int +efx_phy_bist_start( + __in efx_nic_t *enp, + __in efx_phy_bist_type_t type); + +extern __checkReturn int +efx_phy_bist_poll( + __in efx_nic_t *enp, + __in efx_phy_bist_type_t type, + __out efx_phy_bist_result_t *resultp, + __out_opt uint32_t *value_maskp, + __out_ecount_opt(count) unsigned long *valuesp, + __in size_t count); + +extern void +efx_phy_bist_stop( + __in efx_nic_t *enp, + __in efx_phy_bist_type_t type); + +#endif /* EFSYS_OPT_PHY_BIST */ + +#define EFX_FEATURE_IPV6 0x00000001 +#define EFX_FEATURE_LFSR_HASH_INSERT 0x00000002 +#define EFX_FEATURE_LINK_EVENTS 0x00000004 +#define EFX_FEATURE_PERIODIC_MAC_STATS 0x00000008 +#define EFX_FEATURE_WOL 0x00000010 +#define EFX_FEATURE_MCDI 0x00000020 +#define EFX_FEATURE_LOOKAHEAD_SPLIT 0x00000040 +#define EFX_FEATURE_MAC_HEADER_FILTERS 0x00000080 + +typedef struct efx_nic_cfg_s { + uint32_t enc_board_type; + uint32_t enc_phy_type; +#if EFSYS_OPT_NAMES + char enc_phy_name[21]; +#endif + char enc_phy_revision[21]; + efx_mon_type_t enc_mon_type; +#if EFSYS_OPT_MON_STATS + uint32_t enc_mon_stat_mask; +#endif + unsigned int enc_features; + uint8_t enc_mac_addr[6]; + uint8_t enc_port; + uint32_t enc_evq_limit; + uint32_t enc_txq_limit; + uint32_t enc_rxq_limit; + uint32_t enc_buftbl_limit; + uint32_t enc_evq_moderation_max; +#if EFSYS_OPT_LOOPBACK + uint32_t enc_loopback_types[EFX_LINK_NMODES]; +#endif /* EFSYS_OPT_LOOPBACK */ +#if EFSYS_OPT_PHY_FLAGS + uint32_t enc_phy_flags_mask; +#endif /* EFSYS_OPT_PHY_FLAGS */ +#if EFSYS_OPT_PHY_LED_CONTROL + uint32_t enc_led_mask; +#endif /* EFSYS_OPT_PHY_LED_CONTROL */ +#if EFSYS_OPT_PHY_STATS + uint64_t enc_phy_stat_mask; +#endif /* EFSYS_OPT_PHY_STATS */ +#if EFSYS_OPT_PHY_PROPS + unsigned int enc_phy_nprops; +#endif /* EFSYS_OPT_PHY_PROPS */ +#if EFSYS_OPT_SIENA + uint8_t enc_siena_channel; +#if EFSYS_OPT_PHY_STATS + uint32_t enc_siena_phy_stat_mask; +#endif /* EFSYS_OPT_PHY_STATS */ +#if EFSYS_OPT_MON_STATS + uint32_t enc_siena_mon_stat_mask; +#endif /* EFSYS_OPT_MON_STATS */ +#endif /* EFSYS_OPT_SIENA */ +#if EFSYS_OPT_PHY_BIST + uint32_t enc_bist_mask; +#endif /* EFSYS_OPT_PHY_BIST */ +} efx_nic_cfg_t; + +extern const efx_nic_cfg_t * +efx_nic_cfg_get( + __in efx_nic_t *enp); + +#if EFSYS_OPT_VPD + +typedef enum efx_vpd_tag_e { + EFX_VPD_ID = 0x02, + EFX_VPD_END = 0x0f, + EFX_VPD_RO = 0x10, + EFX_VPD_RW = 0x11, +} efx_vpd_tag_t; + +typedef uint16_t efx_vpd_keyword_t; + +typedef struct efx_vpd_value_s { + efx_vpd_tag_t evv_tag; + efx_vpd_keyword_t evv_keyword; + uint8_t evv_length; + uint8_t evv_value[0x100]; +} efx_vpd_value_t; + + +#define EFX_VPD_KEYWORD(x, y) ((x) | ((y) << 8)) + +extern __checkReturn int +efx_vpd_init( + __in efx_nic_t *enp); + +extern __checkReturn int +efx_vpd_size( + __in efx_nic_t *enp, + __out size_t *sizep); + +extern __checkReturn int +efx_vpd_read( + __in efx_nic_t *enp, + __out_bcount(size) caddr_t data, + __in size_t size); + +extern __checkReturn int +efx_vpd_verify( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size); + +extern __checkReturn int +efx_vpd_reinit( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size); + +extern __checkReturn int +efx_vpd_get( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size, + __inout efx_vpd_value_t *evvp); + +extern __checkReturn int +efx_vpd_set( + __in efx_nic_t *enp, + __inout_bcount(size) caddr_t data, + __in size_t size, + __in efx_vpd_value_t *evvp); + +extern __checkReturn int +efx_vpd_next( + __in efx_nic_t *enp, + __inout_bcount(size) caddr_t data, + __in size_t size, + __out efx_vpd_value_t *evvp, + __inout unsigned int *contp); + +extern __checkReturn int +efx_vpd_write( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size); + +extern void +efx_vpd_fini( + __in efx_nic_t *enp); + +#endif /* EFSYS_OPT_VPD */ + +/* NVRAM */ + +#if EFSYS_OPT_NVRAM + +typedef enum efx_nvram_type_e { + EFX_NVRAM_INVALID = 0, + EFX_NVRAM_BOOTROM, + EFX_NVRAM_BOOTROM_CFG, + EFX_NVRAM_MC_FIRMWARE, + EFX_NVRAM_MC_GOLDEN, + EFX_NVRAM_PHY, + EFX_NVRAM_NULLPHY, + EFX_NVRAM_NTYPES, +} efx_nvram_type_t; + +extern __checkReturn int +efx_nvram_init( + __in efx_nic_t *enp); + +#if EFSYS_OPT_DIAG + +extern __checkReturn int +efx_nvram_test( + __in efx_nic_t *enp); + +#endif /* EFSYS_OPT_DIAG */ + +extern __checkReturn int +efx_nvram_size( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __out size_t *sizep); + +extern __checkReturn int +efx_nvram_rw_start( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __out_opt size_t *pref_chunkp); + +extern void +efx_nvram_rw_finish( + __in efx_nic_t *enp, + __in efx_nvram_type_t type); + +extern __checkReturn int +efx_nvram_get_version( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __out uint32_t *subtypep, + __out_ecount(4) uint16_t version[4]); + +extern __checkReturn int +efx_nvram_read_chunk( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __in unsigned int offset, + __out_bcount(size) caddr_t data, + __in size_t size); + +extern __checkReturn int +efx_nvram_set_version( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __out uint16_t version[4]); + +extern __checkReturn int +efx_nvram_erase( + __in efx_nic_t *enp, + __in efx_nvram_type_t type); + +extern __checkReturn int +efx_nvram_write_chunk( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __in unsigned int offset, + __in_bcount(size) caddr_t data, + __in size_t size); + +extern void +efx_nvram_fini( + __in efx_nic_t *enp); + +#endif /* EFSYS_OPT_NVRAM */ + +#if EFSYS_OPT_BOOTCFG + +extern int +efx_bootcfg_read( + __in efx_nic_t *enp, + __out_bcount(size) caddr_t data, + __in size_t size); + +extern int +efx_bootcfg_write( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size); + +#endif /* EFSYS_OPT_BOOTCFG */ + +#if EFSYS_OPT_WOL + +typedef enum efx_wol_type_e { + EFX_WOL_TYPE_INVALID, + EFX_WOL_TYPE_MAGIC, + EFX_WOL_TYPE_BITMAP, + EFX_WOL_TYPE_LINK, + EFX_WOL_NTYPES, +} efx_wol_type_t; + +typedef enum efx_lightsout_offload_type_e { + EFX_LIGHTSOUT_OFFLOAD_TYPE_INVALID, + EFX_LIGHTSOUT_OFFLOAD_TYPE_ARP, + EFX_LIGHTSOUT_OFFLOAD_TYPE_NS, +} efx_lightsout_offload_type_t; + +#define EFX_WOL_BITMAP_MASK_SIZE (48) +#define EFX_WOL_BITMAP_VALUE_SIZE (128) + +typedef union efx_wol_param_u { + struct { + uint8_t mac_addr[6]; + } ewp_magic; + struct { + uint8_t mask[EFX_WOL_BITMAP_MASK_SIZE]; /* 1 bit per byte */ + uint8_t value[EFX_WOL_BITMAP_VALUE_SIZE]; /* value to match */ + uint8_t value_len; + } ewp_bitmap; +} efx_wol_param_t; + +typedef union efx_lightsout_offload_param_u { + struct { + uint8_t mac_addr[6]; + uint32_t ip; + } elop_arp; + struct { + uint8_t mac_addr[6]; + uint32_t solicited_node[4]; + uint32_t ip[4]; + } elop_ns; +} efx_lightsout_offload_param_t; + +extern __checkReturn int +efx_wol_init( + __in efx_nic_t *enp); + +extern __checkReturn int +efx_wol_filter_clear( + __in efx_nic_t *enp); + +extern __checkReturn int +efx_wol_filter_add( + __in efx_nic_t *enp, + __in efx_wol_type_t type, + __in efx_wol_param_t *paramp, + __out uint32_t *filter_idp); + +extern __checkReturn int +efx_wol_filter_remove( + __in efx_nic_t *enp, + __in uint32_t filter_id); + +extern __checkReturn int +efx_lightsout_offload_add( + __in efx_nic_t *enp, + __in efx_lightsout_offload_type_t type, + __in efx_lightsout_offload_param_t *paramp, + __out uint32_t *filter_idp); + +extern __checkReturn int +efx_lightsout_offload_remove( + __in efx_nic_t *enp, + __in efx_lightsout_offload_type_t type, + __in uint32_t filter_id); + +extern void +efx_wol_fini( + __in efx_nic_t *enp); + +#endif /* EFSYS_OPT_WOL */ + +#if EFSYS_OPT_DIAG + +typedef enum efx_pattern_type_t { + EFX_PATTERN_BYTE_INCREMENT = 0, + EFX_PATTERN_ALL_THE_SAME, + EFX_PATTERN_BIT_ALTERNATE, + EFX_PATTERN_BYTE_ALTERNATE, + EFX_PATTERN_BYTE_CHANGING, + EFX_PATTERN_BIT_SWEEP, + EFX_PATTERN_NTYPES +} efx_pattern_type_t; + +typedef void +(*efx_sram_pattern_fn_t)( + __in size_t row, + __in boolean_t negate, + __out efx_qword_t *eqp); + +extern __checkReturn int +efx_sram_test( + __in efx_nic_t *enp, + __in efx_pattern_type_t type); + +#endif /* EFSYS_OPT_DIAG */ + +extern __checkReturn int +efx_sram_buf_tbl_set( + __in efx_nic_t *enp, + __in uint32_t id, + __in efsys_mem_t *esmp, + __in size_t n); + +extern void +efx_sram_buf_tbl_clear( + __in efx_nic_t *enp, + __in uint32_t id, + __in size_t n); + +#define EFX_BUF_TBL_SIZE 0x20000 + +#define EFX_BUF_SIZE 4096 + +/* EV */ + +typedef struct efx_evq_s efx_evq_t; + +#if EFSYS_OPT_QSTATS + +/* START MKCONFIG GENERATED EfxHeaderEventQueueBlock d5614a5d669c8ca3 */ +typedef enum efx_ev_qstat_e { + EV_ALL, + EV_RX, + EV_RX_OK, + EV_RX_RECOVERY, + EV_RX_FRM_TRUNC, + EV_RX_TOBE_DISC, + EV_RX_PAUSE_FRM_ERR, + EV_RX_BUF_OWNER_ID_ERR, + EV_RX_IPV4_HDR_CHKSUM_ERR, + EV_RX_TCP_UDP_CHKSUM_ERR, + EV_RX_ETH_CRC_ERR, + EV_RX_IP_FRAG_ERR, + EV_RX_MCAST_PKT, + EV_RX_MCAST_HASH_MATCH, + EV_RX_TCP_IPV4, + EV_RX_TCP_IPV6, + EV_RX_UDP_IPV4, + EV_RX_UDP_IPV6, + EV_RX_OTHER_IPV4, + EV_RX_OTHER_IPV6, + EV_RX_NON_IP, + EV_RX_OVERRUN, + EV_TX, + EV_TX_WQ_FF_FULL, + EV_TX_PKT_ERR, + EV_TX_PKT_TOO_BIG, + EV_TX_UNEXPECTED, + EV_GLOBAL, + EV_GLOBAL_PHY, + EV_GLOBAL_MNT, + EV_GLOBAL_RX_RECOVERY, + EV_DRIVER, + EV_DRIVER_SRM_UPD_DONE, + EV_DRIVER_TX_DESCQ_FLS_DONE, + EV_DRIVER_RX_DESCQ_FLS_DONE, + EV_DRIVER_RX_DESCQ_FLS_FAILED, + EV_DRIVER_RX_DSC_ERROR, + EV_DRIVER_TX_DSC_ERROR, + EV_DRV_GEN, + EV_MCDI_RESPONSE, + EV_NQSTATS +} efx_ev_qstat_t; + +/* END MKCONFIG GENERATED EfxHeaderEventQueueBlock */ + +#endif /* EFSYS_OPT_QSTATS */ + +extern __checkReturn int +efx_ev_init( + __in efx_nic_t *enp); + +extern void +efx_ev_fini( + __in efx_nic_t *enp); + +#define EFX_MASK(_max, _min) (-((_max) << 1) ^ -(_min)) + +#define EFX_EVQ_MAXNEVS 32768 +#define EFX_EVQ_MINNEVS 512 + +#define EFX_EVQ_NEVS_MASK EFX_MASK(EFX_EVQ_MAXNEVS, EFX_EVQ_MINNEVS) + +#define EFX_EVQ_SIZE(_nevs) ((_nevs) * sizeof (efx_qword_t)) +#define EFX_EVQ_NBUFS(_nevs) (EFX_EVQ_SIZE(_nevs) / EFX_BUF_SIZE) + +extern __checkReturn int +efx_ev_qcreate( + __in efx_nic_t *enp, + __in unsigned int index, + __in efsys_mem_t *esmp, + __in size_t n, + __in uint32_t id, + __deref_out efx_evq_t **eepp); + +extern void +efx_ev_qpost( + __in efx_evq_t *eep, + __in uint16_t data); + +typedef __checkReturn boolean_t +(*efx_initialized_ev_t)( + __in_opt void *arg); + +#define EFX_PKT_UNICAST 0x0004 +#define EFX_PKT_START 0x0008 + +#define EFX_PKT_VLAN_TAGGED 0x0010 +#define EFX_CKSUM_TCPUDP 0x0020 +#define EFX_CKSUM_IPV4 0x0040 +#define EFX_PKT_CONT 0x0080 + +#define EFX_CHECK_VLAN 0x0100 +#define EFX_PKT_TCP 0x0200 +#define EFX_PKT_UDP 0x0400 +#define EFX_PKT_IPV4 0x0800 + +#define EFX_PKT_IPV6 0x1000 +#define EFX_ADDR_MISMATCH 0x4000 +#define EFX_DISCARD 0x8000 + +#define EFX_EV_RX_NLABELS 32 +#define EFX_EV_TX_NLABELS 32 + +typedef __checkReturn boolean_t +(*efx_rx_ev_t)( + __in_opt void *arg, + __in uint32_t label, + __in uint32_t id, + __in uint32_t size, + __in uint16_t flags); + +typedef __checkReturn boolean_t +(*efx_tx_ev_t)( + __in_opt void *arg, + __in uint32_t label, + __in uint32_t id); + +#define EFX_EXCEPTION_RX_RECOVERY 0x00000001 +#define EFX_EXCEPTION_RX_DSC_ERROR 0x00000002 +#define EFX_EXCEPTION_TX_DSC_ERROR 0x00000003 +#define EFX_EXCEPTION_UNKNOWN_SENSOREVT 0x00000004 +#define EFX_EXCEPTION_FWALERT_SRAM 0x00000005 +#define EFX_EXCEPTION_UNKNOWN_FWALERT 0x00000006 + +typedef __checkReturn boolean_t +(*efx_exception_ev_t)( + __in_opt void *arg, + __in uint32_t label, + __in uint32_t data); + +typedef __checkReturn boolean_t +(*efx_rxq_flush_done_ev_t)( + __in_opt void *arg, + __in uint32_t label); + +typedef __checkReturn boolean_t +(*efx_rxq_flush_failed_ev_t)( + __in_opt void *arg, + __in uint32_t label); + +typedef __checkReturn boolean_t +(*efx_txq_flush_done_ev_t)( + __in_opt void *arg, + __in uint32_t label); + +typedef __checkReturn boolean_t +(*efx_software_ev_t)( + __in_opt void *arg, + __in uint16_t magic); + +typedef __checkReturn boolean_t +(*efx_sram_ev_t)( + __in_opt void *arg, + __in uint32_t code); + +#define EFX_SRAM_CLEAR 0 +#define EFX_SRAM_UPDATE 1 +#define EFX_SRAM_ILLEGAL_CLEAR 2 + +typedef __checkReturn boolean_t +(*efx_wake_up_ev_t)( + __in_opt void *arg, + __in uint32_t label); + +typedef __checkReturn boolean_t +(*efx_timer_ev_t)( + __in_opt void *arg, + __in uint32_t label); + +typedef __checkReturn boolean_t +(*efx_link_change_ev_t)( + __in_opt void *arg, + __in efx_link_mode_t link_mode); + +#if EFSYS_OPT_MON_STATS + +typedef __checkReturn boolean_t +(*efx_monitor_ev_t)( + __in_opt void *arg, + __in efx_mon_stat_t id, + __in efx_mon_stat_value_t value); + +#endif /* EFSYS_OPT_MON_STATS */ + +#if EFSYS_OPT_MAC_STATS + +typedef __checkReturn boolean_t +(*efx_mac_stats_ev_t)( + __in_opt void *arg, + __in uint32_t generation + ); + +#endif /* EFSYS_OPT_MAC_STATS */ + +typedef struct efx_ev_callbacks_s { + efx_initialized_ev_t eec_initialized; + efx_rx_ev_t eec_rx; + efx_tx_ev_t eec_tx; + efx_exception_ev_t eec_exception; + efx_rxq_flush_done_ev_t eec_rxq_flush_done; + efx_rxq_flush_failed_ev_t eec_rxq_flush_failed; + efx_txq_flush_done_ev_t eec_txq_flush_done; + efx_software_ev_t eec_software; + efx_sram_ev_t eec_sram; + efx_wake_up_ev_t eec_wake_up; + efx_timer_ev_t eec_timer; + efx_link_change_ev_t eec_link_change; +#if EFSYS_OPT_MON_STATS + efx_monitor_ev_t eec_monitor; +#endif /* EFSYS_OPT_MON_STATS */ +#if EFSYS_OPT_MAC_STATS + efx_mac_stats_ev_t eec_mac_stats; +#endif /* EFSYS_OPT_MON_STATS */ +} efx_ev_callbacks_t; + +extern __checkReturn boolean_t +efx_ev_qpending( + __in efx_evq_t *eep, + __in unsigned int count); + +#if EFSYS_OPT_EV_PREFETCH + +extern void +efx_ev_qprefetch( + __in efx_evq_t *eep, + __in unsigned int count); + +#endif /* EFSYS_OPT_EV_PREFETCH */ + +extern void +efx_ev_qpoll( + __in efx_evq_t *eep, + __inout unsigned int *countp, + __in const efx_ev_callbacks_t *eecp, + __in_opt void *arg); + +extern __checkReturn int +efx_ev_qmoderate( + __in efx_evq_t *eep, + __in unsigned int us); + +extern __checkReturn int +efx_ev_qprime( + __in efx_evq_t *eep, + __in unsigned int count); + +#if EFSYS_OPT_QSTATS + +#if EFSYS_OPT_NAMES + +extern const char __cs * +efx_ev_qstat_name( + __in efx_nic_t *enp, + __in unsigned int id); + +#endif /* EFSYS_OPT_NAMES */ + +extern void +efx_ev_qstats_update( + __in efx_evq_t *eep, + __inout_ecount(EV_NQSTATS) efsys_stat_t *stat); + +#endif /* EFSYS_OPT_QSTATS */ + +extern void +efx_ev_qdestroy( + __in efx_evq_t *eep); + +/* RX */ + +typedef struct efx_rxq_s efx_rxq_t; + +extern __checkReturn int +efx_rx_init( + __in efx_nic_t *enp); + +extern void +efx_rx_fini( + __in efx_nic_t *enp); + +#if EFSYS_OPT_RX_HDR_SPLIT + __checkReturn int +efx_rx_hdr_split_enable( + __in efx_nic_t *enp, + __in unsigned int hdr_buf_size, + __in unsigned int pld_buf_size); + +#endif /* EFSYS_OPT_RX_HDR_SPLIT */ + +#if EFSYS_OPT_RX_SCATTER + __checkReturn int +efx_rx_scatter_enable( + __in efx_nic_t *enp, + __in unsigned int buf_size); +#endif /* EFSYS_OPT_RX_SCATTER */ + +#if EFSYS_OPT_RX_SCALE + +typedef enum efx_rx_hash_alg_e { + EFX_RX_HASHALG_LFSR = 0, + EFX_RX_HASHALG_TOEPLITZ +} efx_rx_hash_alg_t; + +typedef enum efx_rx_hash_type_e { + EFX_RX_HASH_IPV4 = 0, + EFX_RX_HASH_TCPIPV4, + EFX_RX_HASH_IPV6, + EFX_RX_HASH_TCPIPV6, +} efx_rx_hash_type_t; + +#define EFX_RSS_TBL_SIZE 128 /* Rows in RX indirection table */ +#define EFX_MAXRSS 64 /* RX indirection entry range */ +#define EFX_MAXRSS_LEGACY 16 /* See bug16611 and bug17213 */ + +extern __checkReturn int +efx_rx_scale_mode_set( + __in efx_nic_t *enp, + __in efx_rx_hash_alg_t alg, + __in efx_rx_hash_type_t type, + __in boolean_t insert); + +extern __checkReturn int +efx_rx_scale_tbl_set( + __in efx_nic_t *enp, + __in_ecount(n) unsigned int *table, + __in size_t n); + +extern __checkReturn int +efx_rx_scale_toeplitz_ipv4_key_set( + __in efx_nic_t *enp, + __in_ecount(n) uint8_t *key, + __in size_t n); + +extern __checkReturn int +efx_rx_scale_toeplitz_ipv6_key_set( + __in efx_nic_t *enp, + __in_ecount(n) uint8_t *key, + __in size_t n); + +/* + * The prefix is a byte array of one of the forms: + * + * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + * XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.TT.TT.TT.TT + * XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.LL.LL + * + * where: + * + * TT.TT.TT.TT is a 32-bit Toeplitz hash + * LL.LL is a 16-bit LFSR hash + * + * Hash values are in network (big-endian) byte order. + */ + +#define EFX_RX_PREFIX_SIZE 16 + +#define EFX_RX_HASH_VALUE(_func, _buffer) \ + (((_func) == EFX_RX_HASHALG_LFSR) ? \ + ((uint16_t)(((_buffer)[14] << 8) | (_buffer)[15])) : \ + ((uint32_t)(((_buffer)[12] << 24) | \ + ((_buffer)[13] << 16) | \ + ((_buffer)[14] << 8) | \ + (_buffer)[15]))) + +#define EFX_RX_HASH_SIZE(_func) \ + (((_func) == EFX_RX_HASHALG_LFSR) ? \ + sizeof (uint16_t) : \ + sizeof (uint32_t)) + +#endif /* EFSYS_OPT_RX_SCALE */ + +#define EFX_RXQ_MAXNDESCS 4096 +#define EFX_RXQ_MINNDESCS 512 + +#define EFX_RXQ_NDESCS_MASK EFX_MASK(EFX_RXQ_MAXNDESCS, EFX_RXQ_MINNDESCS) + +#define EFX_RXQ_SIZE(_ndescs) ((_ndescs) * sizeof (efx_qword_t)) +#define EFX_RXQ_NBUFS(_ndescs) (EFX_RXQ_SIZE(_ndescs) / EFX_BUF_SIZE) +#define EFX_RXQ_LIMIT(_ndescs) ((_ndescs) - 16) + +typedef enum efx_rxq_type_e { + EFX_RXQ_TYPE_DEFAULT, + EFX_RXQ_TYPE_SPLIT_HEADER, + EFX_RXQ_TYPE_SPLIT_PAYLOAD, + EFX_RXQ_TYPE_SCATTER, + EFX_RXQ_NTYPES +} efx_rxq_type_t; + +extern __checkReturn int +efx_rx_qcreate( + __in efx_nic_t *enp, + __in unsigned int index, + __in unsigned int label, + __in efx_rxq_type_t type, + __in efsys_mem_t *esmp, + __in size_t n, + __in uint32_t id, + __in efx_evq_t *eep, + __deref_out efx_rxq_t **erpp); + +typedef struct efx_buffer_s { + efsys_dma_addr_t eb_addr; + size_t eb_size; + boolean_t eb_eop; +} efx_buffer_t; + +extern void +efx_rx_qpost( + __in efx_rxq_t *erp, + __in_ecount(n) efsys_dma_addr_t *addrp, + __in size_t size, + __in unsigned int n, + __in unsigned int completed, + __in unsigned int added); + +extern void +efx_rx_qpush( + __in efx_rxq_t *erp, + __in unsigned int added); + +extern void +efx_rx_qflush( + __in efx_rxq_t *erp); + +extern void +efx_rx_qenable( + __in efx_rxq_t *erp); + +extern void +efx_rx_qdestroy( + __in efx_rxq_t *erp); + +/* TX */ + +typedef struct efx_txq_s efx_txq_t; + +#if EFSYS_OPT_QSTATS + +/* START MKCONFIG GENERATED EfxHeaderTransmitQueueBlock 536c5fa5014944bf */ +typedef enum efx_tx_qstat_e { + TX_POST, + TX_UNALIGNED_SPLIT, + TX_NQSTATS +} efx_tx_qstat_t; + +/* END MKCONFIG GENERATED EfxHeaderTransmitQueueBlock */ + +#endif /* EFSYS_OPT_QSTATS */ + +extern __checkReturn int +efx_tx_init( + __in efx_nic_t *enp); + +extern void +efx_tx_fini( + __in efx_nic_t *enp); + +#define EFX_TXQ_MAXNDESCS 4096 +#define EFX_TXQ_MINNDESCS 512 + +#define EFX_TXQ_NDESCS_MASK EFX_MASK(EFX_TXQ_MAXNDESCS, EFX_TXQ_MINNDESCS) + +#define EFX_TXQ_SIZE(_ndescs) ((_ndescs) * sizeof (efx_qword_t)) +#define EFX_TXQ_NBUFS(_ndescs) (EFX_TXQ_SIZE(_ndescs) / EFX_BUF_SIZE) +#define EFX_TXQ_LIMIT(_ndescs) ((_ndescs) - 16) + +extern __checkReturn int +efx_tx_qcreate( + __in efx_nic_t *enp, + __in unsigned int index, + __in unsigned int label, + __in efsys_mem_t *esmp, + __in size_t n, + __in uint32_t id, + __in uint16_t flags, + __in efx_evq_t *eep, + __deref_out efx_txq_t **etpp); + +extern __checkReturn int +efx_tx_qpost( + __in efx_txq_t *etp, + __in_ecount(n) efx_buffer_t *eb, + __in unsigned int n, + __in unsigned int completed, + __inout unsigned int *addedp); + +extern void +efx_tx_qpush( + __in efx_txq_t *etp, + __in unsigned int added); + +extern void +efx_tx_qflush( + __in efx_txq_t *etp); + +extern void +efx_tx_qenable( + __in efx_txq_t *etp); + +#if EFSYS_OPT_QSTATS + +#if EFSYS_OPT_NAMES + +extern const char __cs * +efx_tx_qstat_name( + __in efx_nic_t *etp, + __in unsigned int id); + +#endif /* EFSYS_OPT_NAMES */ + +extern void +efx_tx_qstats_update( + __in efx_txq_t *etp, + __inout_ecount(TX_NQSTATS) efsys_stat_t *stat); + +#endif /* EFSYS_OPT_QSTATS */ + +extern void +efx_tx_qdestroy( + __in efx_txq_t *etp); + + +/* FILTER */ + +#if EFSYS_OPT_FILTER + +typedef enum efx_filter_flag_e { + EFX_FILTER_FLAG_RX_RSS = 0x01, /* use RSS to spread across + * multiple queues */ + EFX_FILTER_FLAG_RX_SCATTER = 0x02, /* enable RX scatter */ + EFX_FILTER_FLAG_RX_OVERRIDE_IP = 0x04, /* MAC filter overrides + * any matching IP filter */ +} efx_filter_flag_t; + +typedef struct efx_filter_spec_s { + uint8_t efs_type; + uint8_t efs_flags; + uint16_t efs_dmaq_id; + uint32_t efs_dword[3]; +} efx_filter_spec_t; + +extern __checkReturn int +efx_filter_init( + __in efx_nic_t *enp); + +extern void +efx_filter_fini( + __in efx_nic_t *enp); + +extern __checkReturn int +efx_rx_filter_insert( + __in efx_rxq_t *erp, + __inout efx_filter_spec_t *spec); + +extern __checkReturn int +efx_rx_filter_remove( + __in efx_rxq_t *erp, + __inout efx_filter_spec_t *spec); + + void +efx_filter_restore( + __in efx_nic_t *enp); + +extern void +efx_filter_spec_rx_ipv4_tcp_full( + __inout efx_filter_spec_t *spec, + __in unsigned int flags, + __in uint32_t src_ip, + __in uint16_t src_tcp, + __in uint32_t dest_ip, + __in uint16_t dest_tcp); + +extern void +efx_filter_spec_rx_ipv4_tcp_wild( + __inout efx_filter_spec_t *spec, + __in unsigned int flags, + __in uint32_t dest_ip, + __in uint16_t dest_tcp); + +extern void +efx_filter_spec_rx_ipv4_udp_full( + __inout efx_filter_spec_t *spec, + __in unsigned int flags, + __in uint32_t src_ip, + __in uint16_t src_udp, + __in uint32_t dest_ip, + __in uint16_t dest_udp); + +extern void +efx_filter_spec_rx_ipv4_udp_wild( + __inout efx_filter_spec_t *spec, + __in unsigned int flags, + __in uint32_t dest_ip, + __in uint16_t dest_udp); + +extern void +efx_filter_spec_rx_mac_full( + __inout efx_filter_spec_t *spec, + __in unsigned int flags, + __in uint16_t vlan_id, + __in uint8_t *dest_mac); + +extern void +efx_filter_spec_rx_mac_wild( + __inout efx_filter_spec_t *spec, + __in unsigned int flags, + __in uint8_t *dest_mac); + + +extern __checkReturn int +efx_tx_filter_insert( + __in efx_txq_t *etp, + __inout efx_filter_spec_t *spec); + +extern __checkReturn int +efx_tx_filter_remove( + __in efx_txq_t *etp, + __inout efx_filter_spec_t *spec); + +extern void +efx_filter_spec_tx_ipv4_tcp_full( + __inout efx_filter_spec_t *spec, + __in uint32_t src_ip, + __in uint16_t src_tcp, + __in uint32_t dest_ip, + __in uint16_t dest_tcp); + +extern void +efx_filter_spec_tx_ipv4_tcp_wild( + __inout efx_filter_spec_t *spec, + __in uint32_t src_ip, + __in uint16_t src_tcp); + +extern void +efx_filter_spec_tx_ipv4_udp_full( + __inout efx_filter_spec_t *spec, + __in uint32_t src_ip, + __in uint16_t src_udp, + __in uint32_t dest_ip, + __in uint16_t dest_udp); + +extern void +efx_filter_spec_tx_ipv4_udp_wild( + __inout efx_filter_spec_t *spec, + __in uint32_t src_ip, + __in uint16_t src_udp); + +extern void +efx_filter_spec_tx_mac_full( + __inout efx_filter_spec_t *spec, + __in uint16_t vlan_id, + __in uint8_t *src_mac); + +extern void +efx_filter_spec_tx_mac_wild( + __inout efx_filter_spec_t *spec, + __in uint8_t *src_mac); + +#endif /* EFSYS_OPT_FILTER */ + + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_EFX_H */ diff --git a/sys/dev/sfxge/common/efx_bootcfg.c b/sys/dev/sfxge/common/efx_bootcfg.c new file mode 100644 index 000000000000..1a6a79c7cac0 --- /dev/null +++ b/sys/dev/sfxge/common/efx_bootcfg.c @@ -0,0 +1,342 @@ +/*- + * Copyright 2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "efsys.h" +#include "efx.h" +#include "efx_types.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 + +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 int +efx_bootcfg_verify( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size, + __out size_t *usedp) +{ + size_t offset = 0; + size_t used = 0; + int rc; + + /* Start parsing tags immediatly 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, int, rc); + + return (rc); +} + + int +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; + int 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, int, rc); + + return (rc); +} + + int +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; + int 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, int, rc); + + return (rc); +} + +#endif /* EFSYS_OPT_BOOTCFG */ diff --git a/sys/dev/sfxge/common/efx_ev.c b/sys/dev/sfxge/common/efx_ev.c new file mode 100644 index 000000000000..2203bc1721f0 --- /dev/null +++ b/sys/dev/sfxge/common/efx_ev.c @@ -0,0 +1,1112 @@ +/*- + * Copyright 2007-2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "efsys.h" +#include "efx.h" +#include "efx_types.h" +#include "efx_regs.h" +#include "efx_impl.h" + +#if EFSYS_OPT_QSTATS +#define EFX_EV_QSTAT_INCR(_eep, _stat) \ + do { \ + (_eep)->ee_stat[_stat]++; \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) +#else +#define EFX_EV_QSTAT_INCR(_eep, _stat) +#endif + + __checkReturn int +efx_ev_init( + __in efx_nic_t *enp) +{ + efx_oword_t oword; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); + + if (enp->en_mod_flags & EFX_MOD_EV) { + rc = EINVAL; + goto fail1; + } + + EFSYS_ASSERT3U(enp->en_ev_qcount, ==, 0); + + /* + * Program the event queue for receive and transmit queue + * flush events. + */ + EFX_BAR_READO(enp, FR_AZ_DP_CTRL_REG, &oword); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_FLS_EVQ_ID, 0); + EFX_BAR_WRITEO(enp, FR_AZ_DP_CTRL_REG, &oword); + + enp->en_mod_flags |= EFX_MOD_EV; + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +static __checkReturn boolean_t +efx_ev_rx_not_ok( + __in efx_evq_t *eep, + __in efx_qword_t *eqp, + __in uint32_t label, + __in uint32_t id, + __inout uint16_t *flagsp) +{ + boolean_t ignore = B_FALSE; + + if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_TOBE_DISC) != 0) { + EFX_EV_QSTAT_INCR(eep, EV_RX_TOBE_DISC); + EFSYS_PROBE(tobe_disc); + /* Assume this is a unicast address mismatch, unless below + * we find either FSF_AZ_RX_EV_ETH_CRC_ERR or + * EV_RX_PAUSE_FRM_ERR is set. + */ + (*flagsp) |= EFX_ADDR_MISMATCH; + } + + if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_FRM_TRUNC) != 0) { + EFSYS_PROBE2(frm_trunc, uint32_t, label, uint32_t, id); + EFX_EV_QSTAT_INCR(eep, EV_RX_FRM_TRUNC); + (*flagsp) |= EFX_DISCARD; + +#if (EFSYS_OPT_RX_HDR_SPLIT || EFSYS_OPT_RX_SCATTER) + /* Lookout for payload queue ran dry errors and ignore them. + * + * Sadly for the header/data split cases, the descriptor + * pointer in this event refers to the header queue and + * therefore cannot be easily detected as duplicate. + * So we drop these and rely on the receive processing seeing + * a subsequent packet with FSF_AZ_RX_EV_SOP set to discard + * the partially received packet. + */ + if ((EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_SOP) == 0) && + (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_JUMBO_CONT) == 0) && + (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_BYTE_CNT) == 0)) + ignore = B_TRUE; +#endif /* EFSYS_OPT_RX_HDR_SPLIT || EFSYS_OPT_RX_SCATTER */ + } + + if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_ETH_CRC_ERR) != 0) { + EFX_EV_QSTAT_INCR(eep, EV_RX_ETH_CRC_ERR); + EFSYS_PROBE(crc_err); + (*flagsp) &= ~EFX_ADDR_MISMATCH; + (*flagsp) |= EFX_DISCARD; + } + + if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_PAUSE_FRM_ERR) != 0) { + EFX_EV_QSTAT_INCR(eep, EV_RX_PAUSE_FRM_ERR); + EFSYS_PROBE(pause_frm_err); + (*flagsp) &= ~EFX_ADDR_MISMATCH; + (*flagsp) |= EFX_DISCARD; + } + + if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_BUF_OWNER_ID_ERR) != 0) { + EFX_EV_QSTAT_INCR(eep, EV_RX_BUF_OWNER_ID_ERR); + EFSYS_PROBE(owner_id_err); + (*flagsp) |= EFX_DISCARD; + } + + if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_IP_HDR_CHKSUM_ERR) != 0) { + EFX_EV_QSTAT_INCR(eep, EV_RX_IPV4_HDR_CHKSUM_ERR); + EFSYS_PROBE(ipv4_err); + (*flagsp) &= ~EFX_CKSUM_IPV4; + } + + if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_TCP_UDP_CHKSUM_ERR) != 0) { + EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_UDP_CHKSUM_ERR); + EFSYS_PROBE(udp_chk_err); + (*flagsp) &= ~EFX_CKSUM_TCPUDP; + } + + if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_IP_FRAG_ERR) != 0) { + EFX_EV_QSTAT_INCR(eep, EV_RX_IP_FRAG_ERR); + + /* + * If IP is fragmented FSF_AZ_RX_EV_IP_FRAG_ERR is set. This + * causes FSF_AZ_RX_EV_PKT_OK to be clear. This is not an error + * condition. + */ + (*flagsp) &= ~(EFX_PKT_TCP | EFX_PKT_UDP | EFX_CKSUM_TCPUDP); + } + + return (ignore); +} + +static __checkReturn boolean_t +efx_ev_rx( + __in efx_evq_t *eep, + __in efx_qword_t *eqp, + __in const efx_ev_callbacks_t *eecp, + __in_opt void *arg) +{ + efx_nic_t *enp = eep->ee_enp; + uint32_t id; + uint32_t size; + uint32_t label; + boolean_t ok; +#if (EFSYS_OPT_RX_HDR_SPLIT || EFSYS_OPT_RX_SCATTER) + boolean_t sop; + boolean_t jumbo_cont; +#endif /* EFSYS_OPT_RX_HDR_SPLIT || EFSYS_OPT_RX_SCATTER */ + uint32_t hdr_type; + boolean_t is_v6; + uint16_t flags; + boolean_t ignore; + boolean_t should_abort; + + EFX_EV_QSTAT_INCR(eep, EV_RX); + + /* Basic packet information */ + id = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_DESC_PTR); + size = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_BYTE_CNT); + label = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_Q_LABEL); + ok = (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_PKT_OK) != 0); + +#if (EFSYS_OPT_RX_HDR_SPLIT || EFSYS_OPT_RX_SCATTER) + sop = (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_SOP) != 0); + jumbo_cont = (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_JUMBO_CONT) != 0); +#endif /* EFSYS_OPT_RX_HDR_SPLIT || EFSYS_OPT_RX_SCATTER */ + + hdr_type = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_HDR_TYPE); + + is_v6 = (enp->en_family != EFX_FAMILY_FALCON && + EFX_QWORD_FIELD(*eqp, FSF_CZ_RX_EV_IPV6_PKT) != 0); + + /* + * If packet is marked as OK and packet type is TCP/IP or + * UDP/IP or other IP, then we can rely on the hardware checksums. + */ + switch (hdr_type) { + case FSE_AZ_RX_EV_HDR_TYPE_IPV4V6_TCP: + flags = EFX_PKT_TCP | EFX_CKSUM_TCPUDP; + if (is_v6) { + EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_IPV6); + flags |= EFX_PKT_IPV6; + } else { + EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_IPV4); + flags |= EFX_PKT_IPV4 | EFX_CKSUM_IPV4; + } + break; + + case FSE_AZ_RX_EV_HDR_TYPE_IPV4V6_UDP: + flags = EFX_PKT_UDP | EFX_CKSUM_TCPUDP; + if (is_v6) { + EFX_EV_QSTAT_INCR(eep, EV_RX_UDP_IPV6); + flags |= EFX_PKT_IPV6; + } else { + EFX_EV_QSTAT_INCR(eep, EV_RX_UDP_IPV4); + flags |= EFX_PKT_IPV4 | EFX_CKSUM_IPV4; + } + break; + + case FSE_AZ_RX_EV_HDR_TYPE_IPV4V6_OTHER: + if (is_v6) { + EFX_EV_QSTAT_INCR(eep, EV_RX_OTHER_IPV6); + flags = EFX_PKT_IPV6; + } else { + EFX_EV_QSTAT_INCR(eep, EV_RX_OTHER_IPV4); + flags = EFX_PKT_IPV4 | EFX_CKSUM_IPV4; + } + break; + + case FSE_AZ_RX_EV_HDR_TYPE_OTHER: + EFX_EV_QSTAT_INCR(eep, EV_RX_NON_IP); + flags = 0; + break; + + default: + EFSYS_ASSERT(B_FALSE); + flags = 0; + break; + } + +#if EFSYS_OPT_RX_SCATTER || EFSYS_OPT_RX_HDR_SPLIT + /* Report scatter and header/lookahead split buffer flags */ + if (sop) + flags |= EFX_PKT_START; + if (jumbo_cont) + flags |= EFX_PKT_CONT; +#endif /* EFSYS_OPT_RX_SCATTER || EFSYS_OPT_RX_HDR_SPLIT */ + + /* Detect errors included in the FSF_AZ_RX_EV_PKT_OK indication */ + if (!ok) { + ignore = efx_ev_rx_not_ok(eep, eqp, label, id, &flags); + if (ignore) { + EFSYS_PROBE4(rx_complete, uint32_t, label, uint32_t, id, + uint32_t, size, uint16_t, flags); + + return (B_FALSE); + } + } + + /* If we're not discarding the packet then it is ok */ + if (~flags & EFX_DISCARD) + EFX_EV_QSTAT_INCR(eep, EV_RX_OK); + + /* Detect multicast packets that didn't match the filter */ + if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_MCAST_PKT) != 0) { + EFX_EV_QSTAT_INCR(eep, EV_RX_MCAST_PKT); + + if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_MCAST_HASH_MATCH) != 0) { + EFX_EV_QSTAT_INCR(eep, EV_RX_MCAST_HASH_MATCH); + } else { + EFSYS_PROBE(mcast_mismatch); + flags |= EFX_ADDR_MISMATCH; + } + } else { + flags |= EFX_PKT_UNICAST; + } + + /* + * The packet parser in Siena can abort parsing packets under + * certain error conditions, setting the PKT_NOT_PARSED bit + * (which clears PKT_OK). If this is set, then don't trust + * the PKT_TYPE field. + */ + if (enp->en_family != EFX_FAMILY_FALCON && !ok) { + uint32_t parse_err; + + parse_err = EFX_QWORD_FIELD(*eqp, FSF_CZ_RX_EV_PKT_NOT_PARSED); + if (parse_err != 0) + flags |= EFX_CHECK_VLAN; + } + + if (~flags & EFX_CHECK_VLAN) { + uint32_t pkt_type; + + pkt_type = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_PKT_TYPE); + if (pkt_type >= FSE_AZ_RX_EV_PKT_TYPE_VLAN) + flags |= EFX_PKT_VLAN_TAGGED; + } + + EFSYS_PROBE4(rx_complete, uint32_t, label, uint32_t, id, + uint32_t, size, uint16_t, flags); + + EFSYS_ASSERT(eecp->eec_rx != NULL); + should_abort = eecp->eec_rx(arg, label, id, size, flags); + + return (should_abort); +} + +static __checkReturn boolean_t +efx_ev_tx( + __in efx_evq_t *eep, + __in efx_qword_t *eqp, + __in const efx_ev_callbacks_t *eecp, + __in_opt void *arg) +{ + uint32_t id; + uint32_t label; + boolean_t should_abort; + + EFX_EV_QSTAT_INCR(eep, EV_TX); + + if (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_COMP) != 0 && + EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_PKT_ERR) == 0 && + EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_PKT_TOO_BIG) == 0 && + EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_WQ_FF_FULL) == 0) { + + id = EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_DESC_PTR); + label = EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_Q_LABEL); + + EFSYS_PROBE2(tx_complete, uint32_t, label, uint32_t, id); + + EFSYS_ASSERT(eecp->eec_tx != NULL); + should_abort = eecp->eec_tx(arg, label, id); + + return (should_abort); + } + + if (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_COMP) != 0) + EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index, + uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1), + uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0)); + + if (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_PKT_ERR) != 0) + EFX_EV_QSTAT_INCR(eep, EV_TX_PKT_ERR); + + if (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_PKT_TOO_BIG) != 0) + EFX_EV_QSTAT_INCR(eep, EV_TX_PKT_TOO_BIG); + + if (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_WQ_FF_FULL) != 0) + EFX_EV_QSTAT_INCR(eep, EV_TX_WQ_FF_FULL); + + EFX_EV_QSTAT_INCR(eep, EV_TX_UNEXPECTED); + return (B_FALSE); +} + +static __checkReturn boolean_t +efx_ev_global( + __in efx_evq_t *eep, + __in efx_qword_t *eqp, + __in const efx_ev_callbacks_t *eecp, + __in_opt void *arg) +{ + efx_nic_t *enp = eep->ee_enp; + efx_port_t *epp = &(enp->en_port); + boolean_t should_abort; + + EFX_EV_QSTAT_INCR(eep, EV_GLOBAL); + should_abort = B_FALSE; + + /* Check for a link management event */ + if (EFX_QWORD_FIELD(*eqp, FSF_BZ_GLB_EV_XG_MNT_INTR) != 0) { + EFX_EV_QSTAT_INCR(eep, EV_GLOBAL_MNT); + + EFSYS_PROBE(xg_mgt); + + epp->ep_mac_poll_needed = B_TRUE; + } + + return (should_abort); +} + +static __checkReturn boolean_t +efx_ev_driver( + __in efx_evq_t *eep, + __in efx_qword_t *eqp, + __in const efx_ev_callbacks_t *eecp, + __in_opt void *arg) +{ + boolean_t should_abort; + + EFX_EV_QSTAT_INCR(eep, EV_DRIVER); + should_abort = B_FALSE; + + switch (EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBCODE)) { + case FSE_AZ_TX_DESCQ_FLS_DONE_EV: { + uint32_t label; + + EFX_EV_QSTAT_INCR(eep, EV_DRIVER_TX_DESCQ_FLS_DONE); + + label = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA); + + EFSYS_PROBE1(tx_descq_fls_done, uint32_t, label); + + EFSYS_ASSERT(eecp->eec_txq_flush_done != NULL); + should_abort = eecp->eec_txq_flush_done(arg, label); + + break; + } + case FSE_AZ_RX_DESCQ_FLS_DONE_EV: { + uint32_t label; + uint32_t failed; + + label = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_RX_DESCQ_ID); + failed = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL); + + EFSYS_ASSERT(eecp->eec_rxq_flush_done != NULL); + EFSYS_ASSERT(eecp->eec_rxq_flush_failed != NULL); + + if (failed) { + EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_FAILED); + + EFSYS_PROBE1(rx_descq_fls_failed, uint32_t, label); + + should_abort = eecp->eec_rxq_flush_failed(arg, label); + } else { + EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_DONE); + + EFSYS_PROBE1(rx_descq_fls_done, uint32_t, label); + + should_abort = eecp->eec_rxq_flush_done(arg, label); + } + + break; + } + case FSE_AZ_EVQ_INIT_DONE_EV: + EFSYS_ASSERT(eecp->eec_initialized != NULL); + should_abort = eecp->eec_initialized(arg); + + break; + + case FSE_AZ_EVQ_NOT_EN_EV: + EFSYS_PROBE(evq_not_en); + break; + + case FSE_AZ_SRM_UPD_DONE_EV: { + uint32_t code; + + EFX_EV_QSTAT_INCR(eep, EV_DRIVER_SRM_UPD_DONE); + + code = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA); + + EFSYS_ASSERT(eecp->eec_sram != NULL); + should_abort = eecp->eec_sram(arg, code); + + break; + } + case FSE_AZ_WAKE_UP_EV: { + uint32_t id; + + id = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA); + + EFSYS_ASSERT(eecp->eec_wake_up != NULL); + should_abort = eecp->eec_wake_up(arg, id); + + break; + } + case FSE_AZ_TX_PKT_NON_TCP_UDP: + EFSYS_PROBE(tx_pkt_non_tcp_udp); + break; + + case FSE_AZ_TIMER_EV: { + uint32_t id; + + id = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA); + + EFSYS_ASSERT(eecp->eec_timer != NULL); + should_abort = eecp->eec_timer(arg, id); + + break; + } + case FSE_AZ_RX_DSC_ERROR_EV: + EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DSC_ERROR); + + EFSYS_PROBE(rx_dsc_error); + + EFSYS_ASSERT(eecp->eec_exception != NULL); + should_abort = eecp->eec_exception(arg, + EFX_EXCEPTION_RX_DSC_ERROR, 0); + + break; + + case FSE_AZ_TX_DSC_ERROR_EV: + EFX_EV_QSTAT_INCR(eep, EV_DRIVER_TX_DSC_ERROR); + + EFSYS_PROBE(tx_dsc_error); + + EFSYS_ASSERT(eecp->eec_exception != NULL); + should_abort = eecp->eec_exception(arg, + EFX_EXCEPTION_TX_DSC_ERROR, 0); + + break; + + default: + break; + } + + return (should_abort); +} + +static __checkReturn boolean_t +efx_ev_drv_gen( + __in efx_evq_t *eep, + __in efx_qword_t *eqp, + __in const efx_ev_callbacks_t *eecp, + __in_opt void *arg) +{ + uint32_t data; + boolean_t should_abort; + + EFX_EV_QSTAT_INCR(eep, EV_DRV_GEN); + + data = EFX_QWORD_FIELD(*eqp, FSF_AZ_EV_DATA_DW0); + if (data >= ((uint32_t)1 << 16)) { + EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index, + uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1), + uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0)); + return (B_TRUE); + } + + EFSYS_ASSERT(eecp->eec_software != NULL); + should_abort = eecp->eec_software(arg, (uint16_t)data); + + return (should_abort); +} + +#if EFSYS_OPT_MCDI + +static __checkReturn boolean_t +efx_ev_mcdi( + __in efx_evq_t *eep, + __in efx_qword_t *eqp, + __in const efx_ev_callbacks_t *eecp, + __in_opt void *arg) +{ + efx_nic_t *enp = eep->ee_enp; + unsigned code; + boolean_t should_abort = B_FALSE; + + EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); + + if (enp->en_family != EFX_FAMILY_SIENA) + goto out; + + EFX_EV_QSTAT_INCR(eep, EV_MCDI_RESPONSE); + + code = EFX_QWORD_FIELD(*eqp, MCDI_EVENT_CODE); + switch (code) { + case MCDI_EVENT_CODE_BADSSERT: + efx_mcdi_ev_death(enp, EINTR); + break; + + case MCDI_EVENT_CODE_CMDDONE: + efx_mcdi_ev_cpl(enp, + MCDI_EV_FIELD(*eqp, CMDDONE_SEQ), + MCDI_EV_FIELD(*eqp, CMDDONE_DATALEN), + MCDI_EV_FIELD(*eqp, CMDDONE_ERRNO)); + break; + + case MCDI_EVENT_CODE_LINKCHANGE: { + efx_link_mode_t link_mode; + + siena_phy_link_ev(enp, eqp, &link_mode); + should_abort = eecp->eec_link_change(arg, link_mode); + break; + } + case MCDI_EVENT_CODE_SENSOREVT: { +#if EFSYS_OPT_MON_STATS + efx_mon_stat_t id; + efx_mon_stat_value_t value; + int rc; + + if ((rc = siena_mon_ev(enp, eqp, &id, &value)) == 0) + should_abort = eecp->eec_monitor(arg, id, value); + else if (rc == ENOTSUP) { + should_abort = eecp->eec_exception(arg, + EFX_EXCEPTION_UNKNOWN_SENSOREVT, + MCDI_EV_FIELD(eqp, DATA)); + } else + EFSYS_ASSERT(rc == ENODEV); /* Wrong port */ +#else + should_abort = B_FALSE; +#endif + break; + } + case MCDI_EVENT_CODE_SCHEDERR: + /* Informational only */ + break; + + case MCDI_EVENT_CODE_REBOOT: + efx_mcdi_ev_death(enp, EIO); + break; + + case MCDI_EVENT_CODE_MAC_STATS_DMA: +#if EFSYS_OPT_MAC_STATS + if (eecp->eec_mac_stats != NULL) { + eecp->eec_mac_stats(arg, + MCDI_EV_FIELD(eqp, MAC_STATS_DMA_GENERATION)); + } +#endif + break; + + case MCDI_EVENT_CODE_FWALERT: { + uint32_t reason = MCDI_EV_FIELD(eqp, FWALERT_REASON); + + if (reason == MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS) + should_abort = eecp->eec_exception(arg, + EFX_EXCEPTION_FWALERT_SRAM, + MCDI_EV_FIELD(eqp, FWALERT_DATA)); + else + should_abort = eecp->eec_exception(arg, + EFX_EXCEPTION_UNKNOWN_FWALERT, + MCDI_EV_FIELD(eqp, DATA)); + break; + } + + default: + EFSYS_PROBE1(mc_pcol_error, int, code); + break; + } + +out: + return (should_abort); +} + +#endif /* EFSYS_OPT_SIENA */ + + __checkReturn int +efx_ev_qprime( + __in efx_evq_t *eep, + __in unsigned int count) +{ + efx_nic_t *enp = eep->ee_enp; + uint32_t rptr; + efx_dword_t dword; + int rc; + + EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC); + + if (!(enp->en_mod_flags & EFX_MOD_INTR)) { + rc = EINVAL; + goto fail1; + } + + rptr = count & eep->ee_mask; + + EFX_POPULATE_DWORD_1(dword, FRF_AZ_EVQ_RPTR, rptr); + + EFX_BAR_TBL_WRITED(enp, FR_AZ_EVQ_RPTR_REG, eep->ee_index, + &dword, B_FALSE); + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn boolean_t +efx_ev_qpending( + __in efx_evq_t *eep, + __in unsigned int count) +{ + size_t offset; + efx_qword_t qword; + + EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC); + + offset = (count & eep->ee_mask) * sizeof (efx_qword_t); + EFSYS_MEM_READQ(eep->ee_esmp, offset, &qword); + + return (EFX_QWORD_FIELD(qword, EFX_DWORD_0) != 0xffffffff && + EFX_QWORD_FIELD(qword, EFX_DWORD_1) != 0xffffffff); +} + +#if EFSYS_OPT_EV_PREFETCH + + void +efx_ev_qprefetch( + __in efx_evq_t *eep, + __in unsigned int count) +{ + unsigned int offset; + + EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC); + + offset = (count & eep->ee_mask) * sizeof (efx_qword_t); + EFSYS_MEM_PREFETCH(eep->ee_esmp, offset); +} + +#endif /* EFSYS_OPT_EV_PREFETCH */ + +#define EFX_EV_BATCH 8 + +#define EFX_EV_PRESENT(_qword) \ + (EFX_QWORD_FIELD((_qword), EFX_DWORD_0) != 0xffffffff && \ + EFX_QWORD_FIELD((_qword), EFX_DWORD_1) != 0xffffffff) + + void +efx_ev_qpoll( + __in efx_evq_t *eep, + __inout unsigned int *countp, + __in const efx_ev_callbacks_t *eecp, + __in_opt void *arg) +{ + efx_qword_t ev[EFX_EV_BATCH]; + unsigned int batch; + unsigned int total; + unsigned int count; + unsigned int index; + size_t offset; + + EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC); + EFSYS_ASSERT(countp != NULL); + EFSYS_ASSERT(eecp != NULL); + + count = *countp; + do { + /* Read up until the end of the batch period */ + batch = EFX_EV_BATCH - (count & (EFX_EV_BATCH - 1)); + offset = (count & eep->ee_mask) * sizeof (efx_qword_t); + for (total = 0; total < batch; ++total) { + EFSYS_MEM_READQ(eep->ee_esmp, offset, &(ev[total])); + + if (!EFX_EV_PRESENT(ev[total])) + break; + + EFSYS_PROBE3(event, unsigned int, eep->ee_index, + uint32_t, EFX_QWORD_FIELD(ev[total], EFX_DWORD_1), + uint32_t, EFX_QWORD_FIELD(ev[total], EFX_DWORD_0)); + + offset += sizeof (efx_qword_t); + } + +#if EFSYS_OPT_EV_PREFETCH && (EFSYS_OPT_EV_PREFETCH_PERIOD > 1) + /* + * Prefetch the next batch when we get within PREFETCH_PERIOD + * of a completed batch. If the batch is smaller, then prefetch + * immediately. + */ + if (total == batch && total < EFSYS_OPT_EV_PREFETCH_PERIOD) + EFSYS_MEM_PREFETCH(eep->ee_esmp, offset); +#endif /* EFSYS_OPT_EV_PREFETCH */ + + /* Process the batch of events */ + for (index = 0; index < total; ++index) { + boolean_t should_abort; + uint32_t code; + efx_ev_handler_t handler; + +#if EFSYS_OPT_EV_PREFETCH + /* Prefetch if we've now reached the batch period */ + if (total == batch && + index + EFSYS_OPT_EV_PREFETCH_PERIOD == total) { + offset = (count + batch) & eep->ee_mask; + offset *= sizeof (efx_qword_t); + + EFSYS_MEM_PREFETCH(eep->ee_esmp, offset); + } +#endif /* EFSYS_OPT_EV_PREFETCH */ + + EFX_EV_QSTAT_INCR(eep, EV_ALL); + + code = EFX_QWORD_FIELD(ev[index], FSF_AZ_EV_CODE); + handler = eep->ee_handler[code]; + EFSYS_ASSERT(handler != NULL); + should_abort = handler(eep, &(ev[index]), eecp, arg); + if (should_abort) { + /* Ignore subsequent events */ + total = index + 1; + break; + } + } + + /* + * Now that the hardware has most likely moved onto dma'ing + * into the next cache line, clear the processed events. Take + * care to only clear out events that we've processed + */ + EFX_SET_QWORD(ev[0]); + offset = (count & eep->ee_mask) * sizeof (efx_qword_t); + for (index = 0; index < total; ++index) { + EFSYS_MEM_WRITEQ(eep->ee_esmp, offset, &(ev[0])); + offset += sizeof (efx_qword_t); + } + + count += total; + + } while (total == batch); + + *countp = count; +} + + void +efx_ev_qpost( + __in efx_evq_t *eep, + __in uint16_t data) +{ + efx_nic_t *enp = eep->ee_enp; + efx_qword_t ev; + efx_oword_t oword; + + EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC); + + EFX_POPULATE_QWORD_2(ev, FSF_AZ_EV_CODE, FSE_AZ_EV_CODE_DRV_GEN_EV, + FSF_AZ_EV_DATA_DW0, (uint32_t)data); + + EFX_POPULATE_OWORD_3(oword, FRF_AZ_DRV_EV_QID, eep->ee_index, + EFX_DWORD_0, EFX_QWORD_FIELD(ev, EFX_DWORD_0), + EFX_DWORD_1, EFX_QWORD_FIELD(ev, EFX_DWORD_1)); + + EFX_BAR_WRITEO(enp, FR_AZ_DRV_EV_REG, &oword); +} + + __checkReturn int +efx_ev_qmoderate( + __in efx_evq_t *eep, + __in unsigned int us) +{ + efx_nic_t *enp = eep->ee_enp; + unsigned int locked; + efx_dword_t dword; + int rc; + + EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC); + + if (us > enp->en_nic_cfg.enc_evq_moderation_max) { + rc = EINVAL; + goto fail1; + } + + /* If the value is zero then disable the timer */ + if (us == 0) { + if (enp->en_family == EFX_FAMILY_FALCON) + EFX_POPULATE_DWORD_2(dword, + FRF_AB_TC_TIMER_MODE, FFE_AB_TIMER_MODE_DIS, + FRF_AB_TC_TIMER_VAL, 0); + else + EFX_POPULATE_DWORD_2(dword, + FRF_CZ_TC_TIMER_MODE, FFE_CZ_TIMER_MODE_DIS, + FRF_CZ_TC_TIMER_VAL, 0); + } else { + uint32_t timer_val; + + /* Calculate the timer value in quanta */ + us -= (us % EFX_EV_TIMER_QUANTUM); + if (us < EFX_EV_TIMER_QUANTUM) + us = EFX_EV_TIMER_QUANTUM; + + timer_val = us / EFX_EV_TIMER_QUANTUM; + + /* Moderation value is base 0 so we need to deduct 1 */ + if (enp->en_family == EFX_FAMILY_FALCON) + EFX_POPULATE_DWORD_2(dword, + FRF_AB_TC_TIMER_MODE, FFE_AB_TIMER_MODE_INT_HLDOFF, + FRF_AB_TIMER_VAL, timer_val - 1); + else + EFX_POPULATE_DWORD_2(dword, + FRF_CZ_TC_TIMER_MODE, FFE_CZ_TIMER_MODE_INT_HLDOFF, + FRF_CZ_TC_TIMER_VAL, timer_val - 1); + } + + locked = (eep->ee_index == 0) ? 1 : 0; + + EFX_BAR_TBL_WRITED(enp, FR_BZ_TIMER_COMMAND_REGP0, + eep->ee_index, &dword, locked); + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_ev_qcreate( + __in efx_nic_t *enp, + __in unsigned int index, + __in efsys_mem_t *esmp, + __in size_t n, + __in uint32_t id, + __deref_out efx_evq_t **eepp) +{ + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + uint32_t size; + efx_evq_t *eep; + efx_oword_t oword; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_EV); + + EFSYS_ASSERT3U(enp->en_ev_qcount + 1, <, encp->enc_evq_limit); + + if (!ISP2(n) || !(n & EFX_EVQ_NEVS_MASK)) { + rc = EINVAL; + goto fail1; + } + if (index >= encp->enc_evq_limit) { + rc = EINVAL; + goto fail2; + } +#if EFSYS_OPT_RX_SCALE + if (enp->en_intr.ei_type == EFX_INTR_LINE && + index >= EFX_MAXRSS_LEGACY) { + rc = EINVAL; + goto fail3; + } +#endif + for (size = 0; (1 << size) <= (EFX_EVQ_MAXNEVS / EFX_EVQ_MINNEVS); + size++) + if ((1 << size) == (int)(n / EFX_EVQ_MINNEVS)) + break; + if (id + (1 << size) >= encp->enc_buftbl_limit) { + rc = EINVAL; + goto fail4; + } + + /* Allocate an EVQ object */ + EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_evq_t), eep); + if (eep == NULL) { + rc = ENOMEM; + goto fail5; + } + + eep->ee_magic = EFX_EVQ_MAGIC; + eep->ee_enp = enp; + eep->ee_index = index; + eep->ee_mask = n - 1; + eep->ee_esmp = esmp; + + /* Set up the handler table */ + eep->ee_handler[FSE_AZ_EV_CODE_RX_EV] = efx_ev_rx; + eep->ee_handler[FSE_AZ_EV_CODE_TX_EV] = efx_ev_tx; + eep->ee_handler[FSE_AZ_EV_CODE_DRIVER_EV] = efx_ev_driver; + eep->ee_handler[FSE_AZ_EV_CODE_GLOBAL_EV] = efx_ev_global; + eep->ee_handler[FSE_AZ_EV_CODE_DRV_GEN_EV] = efx_ev_drv_gen; +#if EFSYS_OPT_MCDI + eep->ee_handler[FSE_AZ_EV_CODE_MCDI_EVRESPONSE] = efx_ev_mcdi; +#endif /* EFSYS_OPT_SIENA */ + + /* Set up the new event queue */ + if (enp->en_family != EFX_FAMILY_FALCON) { + EFX_POPULATE_OWORD_1(oword, FRF_CZ_TIMER_Q_EN, 1); + EFX_BAR_TBL_WRITEO(enp, FR_AZ_TIMER_TBL, index, &oword); + } + + EFX_POPULATE_OWORD_3(oword, FRF_AZ_EVQ_EN, 1, FRF_AZ_EVQ_SIZE, size, + FRF_AZ_EVQ_BUF_BASE_ID, id); + + EFX_BAR_TBL_WRITEO(enp, FR_AZ_EVQ_PTR_TBL, index, &oword); + + enp->en_ev_qcount++; + *eepp = eep; + return (0); + +fail5: + EFSYS_PROBE(fail5); +fail4: + EFSYS_PROBE(fail4); +#if EFSYS_OPT_RX_SCALE +fail3: + EFSYS_PROBE(fail3); +#endif +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#if EFSYS_OPT_NAMES +/* START MKCONFIG GENERATED EfxEventQueueStatNamesBlock 67e9bdcd920059bd */ +static const char __cs * __cs __efx_ev_qstat_name[] = { + "all", + "rx", + "rx_ok", + "rx_recovery", + "rx_frm_trunc", + "rx_tobe_disc", + "rx_pause_frm_err", + "rx_buf_owner_id_err", + "rx_ipv4_hdr_chksum_err", + "rx_tcp_udp_chksum_err", + "rx_eth_crc_err", + "rx_ip_frag_err", + "rx_mcast_pkt", + "rx_mcast_hash_match", + "rx_tcp_ipv4", + "rx_tcp_ipv6", + "rx_udp_ipv4", + "rx_udp_ipv6", + "rx_other_ipv4", + "rx_other_ipv6", + "rx_non_ip", + "rx_overrun", + "tx", + "tx_wq_ff_full", + "tx_pkt_err", + "tx_pkt_too_big", + "tx_unexpected", + "global", + "global_phy", + "global_mnt", + "global_rx_recovery", + "driver", + "driver_srm_upd_done", + "driver_tx_descq_fls_done", + "driver_rx_descq_fls_done", + "driver_rx_descq_fls_failed", + "driver_rx_dsc_error", + "driver_tx_dsc_error", + "drv_gen", + "mcdi_response", +}; +/* END MKCONFIG GENERATED EfxEventQueueStatNamesBlock */ + + const char __cs * +efx_ev_qstat_name( + __in efx_nic_t *enp, + __in unsigned int id) +{ + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(id, <, EV_NQSTATS); + + return (__efx_ev_qstat_name[id]); +} +#endif /* EFSYS_OPT_NAMES */ + +#if EFSYS_OPT_QSTATS + void +efx_ev_qstats_update( + __in efx_evq_t *eep, + __inout_ecount(EV_NQSTATS) efsys_stat_t *stat) +{ + unsigned int id; + + EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC); + + for (id = 0; id < EV_NQSTATS; id++) { + efsys_stat_t *essp = &stat[id]; + + EFSYS_STAT_INCR(essp, eep->ee_stat[id]); + eep->ee_stat[id] = 0; + } +} +#endif /* EFSYS_OPT_QSTATS */ + + void +efx_ev_qdestroy( + __in efx_evq_t *eep) +{ + efx_nic_t *enp = eep->ee_enp; + efx_oword_t oword; + + EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC); + + EFSYS_ASSERT(enp->en_ev_qcount != 0); + --enp->en_ev_qcount; + + /* Purge event queue */ + EFX_ZERO_OWORD(oword); + + EFX_BAR_TBL_WRITEO(enp, FR_AZ_EVQ_PTR_TBL, + eep->ee_index, &oword); + + if (enp->en_family != EFX_FAMILY_FALCON) { + EFX_ZERO_OWORD(oword); + EFX_BAR_TBL_WRITEO(enp, FR_AZ_TIMER_TBL, + eep->ee_index, &oword); + } + + /* Free the EVQ object */ + EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_evq_t), eep); +} + + void +efx_ev_fini( + __in efx_nic_t *enp) +{ + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_EV); + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX)); + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX)); + EFSYS_ASSERT3U(enp->en_ev_qcount, ==, 0); + + enp->en_mod_flags &= ~EFX_MOD_EV; +} diff --git a/sys/dev/sfxge/common/efx_filter.c b/sys/dev/sfxge/common/efx_filter.c new file mode 100644 index 000000000000..e915e9c36393 --- /dev/null +++ b/sys/dev/sfxge/common/efx_filter.c @@ -0,0 +1,1017 @@ +/*- + * Copyright 2007-2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "efsys.h" +#include "efx.h" +#include "efx_types.h" +#include "efx_regs.h" +#include "efx_impl.h" + + +#if EFSYS_OPT_FILTER + +/* "Fudge factors" - difference between programmed value and actual depth. + * Due to pipelined implementation we need to program H/W with a value that + * is larger than the hop limit we want. + */ +#define FILTER_CTL_SRCH_FUDGE_WILD 3 +#define FILTER_CTL_SRCH_FUDGE_FULL 1 + +/* Hard maximum hop limit. Hardware will time-out beyond 200-something. + * We also need to avoid infinite loops in efx_filter_search() when the + * table is full. + */ +#define FILTER_CTL_SRCH_MAX 200 + +/* The filter hash function is LFSR polynomial x^16 + x^3 + 1 of a 32-bit + * key derived from the n-tuple. */ +static uint16_t +efx_filter_tbl_hash( + __in uint32_t key) +{ + uint16_t tmp; + + /* First 16 rounds */ + tmp = 0x1fff ^ (uint16_t)(key >> 16); + tmp = tmp ^ tmp >> 3 ^ tmp >> 6; + tmp = tmp ^ tmp >> 9; + + /* Last 16 rounds */ + tmp = tmp ^ tmp << 13 ^ (uint16_t)(key & 0xffff); + tmp = tmp ^ tmp >> 3 ^ tmp >> 6; + tmp = tmp ^ tmp >> 9; + + return (tmp); +} + + +/* To allow for hash collisions, filter search continues at these + * increments from the first possible entry selected by the hash. */ +static uint16_t +efx_filter_tbl_increment( + __in uint32_t key) +{ + return ((uint16_t)(key * 2 - 1)); +} + +static __checkReturn boolean_t +efx_filter_test_used( + __in efx_filter_tbl_t *eftp, + __in unsigned int index) +{ + EFSYS_ASSERT3P(eftp->eft_bitmap, !=, NULL); + return ((eftp->eft_bitmap[index / 32] & (1 << (index % 32))) != 0); +} + +static void +efx_filter_set_used( + __in efx_filter_tbl_t *eftp, + __in unsigned int index) +{ + EFSYS_ASSERT3P(eftp->eft_bitmap, !=, NULL); + eftp->eft_bitmap[index / 32] |= (1 << (index % 32)); + ++eftp->eft_used; +} + +static void +efx_filter_clear_used( + __in efx_filter_tbl_t *eftp, + __in unsigned int index) +{ + EFSYS_ASSERT3P(eftp->eft_bitmap, !=, NULL); + eftp->eft_bitmap[index / 32] &= ~(1 << (index % 32)); + + --eftp->eft_used; + EFSYS_ASSERT3U(eftp->eft_used, >=, 0); +} + + +static efx_filter_tbl_id_t +efx_filter_tbl_id( + __in efx_filter_type_t type) +{ + efx_filter_tbl_id_t tbl_id; + + switch (type) + { + case EFX_FILTER_RX_TCP_FULL: + case EFX_FILTER_RX_TCP_WILD: + case EFX_FILTER_RX_UDP_FULL: + case EFX_FILTER_RX_UDP_WILD: + tbl_id = EFX_FILTER_TBL_RX_IP; + break; + +#if EFSYS_OPT_SIENA + case EFX_FILTER_RX_MAC_FULL: + case EFX_FILTER_RX_MAC_WILD: + tbl_id = EFX_FILTER_TBL_RX_MAC; + break; + + case EFX_FILTER_TX_TCP_FULL: + case EFX_FILTER_TX_TCP_WILD: + case EFX_FILTER_TX_UDP_FULL: + case EFX_FILTER_TX_UDP_WILD: + tbl_id = EFX_FILTER_TBL_TX_IP; + break; + + case EFX_FILTER_TX_MAC_FULL: + case EFX_FILTER_TX_MAC_WILD: + tbl_id = EFX_FILTER_TBL_RX_MAC; + break; +#endif /* EFSYS_OPT_SIENA */ + + default: + EFSYS_ASSERT(B_FALSE); + break; + } + return (tbl_id); +} + +static void +efx_filter_reset_search_depth( + __inout efx_filter_t *efp, + __in efx_filter_tbl_id_t tbl_id) +{ + switch (tbl_id) + { + case EFX_FILTER_TBL_RX_IP: + efp->ef_depth[EFX_FILTER_RX_TCP_FULL] = 0; + efp->ef_depth[EFX_FILTER_RX_TCP_WILD] = 0; + efp->ef_depth[EFX_FILTER_RX_UDP_FULL] = 0; + efp->ef_depth[EFX_FILTER_RX_UDP_WILD] = 0; + break; + +#if EFSYS_OPT_SIENA + case EFX_FILTER_TBL_RX_MAC: + efp->ef_depth[EFX_FILTER_RX_MAC_FULL] = 0; + efp->ef_depth[EFX_FILTER_RX_MAC_WILD] = 0; + break; + + case EFX_FILTER_TBL_TX_IP: + efp->ef_depth[EFX_FILTER_TX_TCP_FULL] = 0; + efp->ef_depth[EFX_FILTER_TX_TCP_WILD] = 0; + efp->ef_depth[EFX_FILTER_TX_UDP_FULL] = 0; + efp->ef_depth[EFX_FILTER_TX_UDP_WILD] = 0; + break; + + case EFX_FILTER_TBL_TX_MAC: + efp->ef_depth[EFX_FILTER_TX_MAC_FULL] = 0; + efp->ef_depth[EFX_FILTER_TX_MAC_WILD] = 0; + break; +#endif /* EFSYS_OPT_SIENA */ + + default: + EFSYS_ASSERT(B_FALSE); + break; + } +} + +static void +efx_filter_push_rx_limits( + __in efx_nic_t *enp) +{ + efx_filter_t *efp = &enp->en_filter; + efx_oword_t oword; + + EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword); + + EFX_SET_OWORD_FIELD(oword, FRF_AZ_TCP_FULL_SRCH_LIMIT, + efp->ef_depth[EFX_FILTER_RX_TCP_FULL] + + FILTER_CTL_SRCH_FUDGE_FULL); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_TCP_WILD_SRCH_LIMIT, + efp->ef_depth[EFX_FILTER_RX_TCP_WILD] + + FILTER_CTL_SRCH_FUDGE_WILD); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_UDP_FULL_SRCH_LIMIT, + efp->ef_depth[EFX_FILTER_RX_UDP_FULL] + + FILTER_CTL_SRCH_FUDGE_FULL); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_UDP_WILD_SRCH_LIMIT, + efp->ef_depth[EFX_FILTER_RX_UDP_WILD] + + FILTER_CTL_SRCH_FUDGE_WILD); + +#if EFSYS_OPT_SIENA + if (efp->ef_tbl[EFX_FILTER_TBL_RX_MAC].eft_size) { + EFX_SET_OWORD_FIELD(oword, + FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT, + efp->ef_depth[EFX_FILTER_RX_MAC_FULL] + + FILTER_CTL_SRCH_FUDGE_FULL); + EFX_SET_OWORD_FIELD(oword, + FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT, + efp->ef_depth[EFX_FILTER_RX_MAC_WILD] + + FILTER_CTL_SRCH_FUDGE_WILD); + } +#endif /* EFSYS_OPT_SIENA */ + + EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword); +} + +static void +efx_filter_push_tx_limits( + __in efx_nic_t *enp) +{ + efx_filter_t *efp = &enp->en_filter; + efx_oword_t oword; + + if (efp->ef_tbl[EFX_FILTER_TBL_TX_IP].eft_size == 0) + return; + + EFX_BAR_READO(enp, FR_AZ_TX_CFG_REG, &oword); + + EFX_SET_OWORD_FIELD(oword, FRF_CZ_TX_TCPIP_FILTER_FULL_SEARCH_RANGE, + efp->ef_depth[EFX_FILTER_TX_TCP_FULL] + + FILTER_CTL_SRCH_FUDGE_FULL); + EFX_SET_OWORD_FIELD(oword, FRF_CZ_TX_TCPIP_FILTER_WILD_SEARCH_RANGE, + efp->ef_depth[EFX_FILTER_TX_TCP_WILD] + + FILTER_CTL_SRCH_FUDGE_WILD); + EFX_SET_OWORD_FIELD(oword, FRF_CZ_TX_UDPIP_FILTER_FULL_SEARCH_RANGE, + efp->ef_depth[EFX_FILTER_TX_UDP_FULL] + + FILTER_CTL_SRCH_FUDGE_FULL); + EFX_SET_OWORD_FIELD(oword, FRF_CZ_TX_UDPIP_FILTER_WILD_SEARCH_RANGE, + efp->ef_depth[EFX_FILTER_TX_UDP_WILD] + + FILTER_CTL_SRCH_FUDGE_WILD); + + EFX_BAR_WRITEO(enp, FR_AZ_TX_CFG_REG, &oword); +} + +/* Build a filter entry and return its n-tuple key. */ +static __checkReturn uint32_t +efx_filter_build( + __out efx_oword_t *filter, + __in efx_filter_spec_t *spec) +{ + uint32_t dword3; + uint32_t key; + uint8_t type = spec->efs_type; + uint8_t flags = spec->efs_flags; + + switch (efx_filter_tbl_id(type)) { + case EFX_FILTER_TBL_RX_IP: { + boolean_t is_udp = (type == EFX_FILTER_RX_UDP_FULL || + type == EFX_FILTER_RX_UDP_WILD); + EFX_POPULATE_OWORD_7(*filter, + FRF_BZ_RSS_EN, (flags & EFX_FILTER_FLAG_RX_RSS) ? 1 : 0, + FRF_BZ_SCATTER_EN, (flags & EFX_FILTER_FLAG_RX_SCATTER) ? 1 : 0, + FRF_AZ_TCP_UDP, is_udp, + FRF_AZ_RXQ_ID, spec->efs_dmaq_id, + EFX_DWORD_2, spec->efs_dword[2], + EFX_DWORD_1, spec->efs_dword[1], + EFX_DWORD_0, spec->efs_dword[0]); + dword3 = is_udp; + break; + } + +#if EFSYS_OPT_SIENA + case EFX_FILTER_TBL_RX_MAC: { + boolean_t is_wild = (type == EFX_FILTER_RX_MAC_WILD); + EFX_POPULATE_OWORD_8(*filter, + FRF_CZ_RMFT_RSS_EN, (flags & EFX_FILTER_FLAG_RX_RSS) ? 1 : 0, + FRF_CZ_RMFT_SCATTER_EN, (flags & EFX_FILTER_FLAG_RX_SCATTER) ? 1 : 0, + FRF_CZ_RMFT_IP_OVERRIDE, (flags & EFX_FILTER_FLAG_RX_OVERRIDE_IP) ? 1 : 0, + FRF_CZ_RMFT_RXQ_ID, spec->efs_dmaq_id, + FRF_CZ_RMFT_WILDCARD_MATCH, is_wild, + FRF_CZ_RMFT_DEST_MAC_DW1, spec->efs_dword[2], + FRF_CZ_RMFT_DEST_MAC_DW0, spec->efs_dword[1], + FRF_CZ_RMFT_VLAN_ID, spec->efs_dword[0]); + dword3 = is_wild; + break; + } +#endif /* EFSYS_OPT_SIENA */ + + case EFX_FILTER_TBL_TX_IP: { + boolean_t is_udp = (type == EFX_FILTER_TX_UDP_FULL || + type == EFX_FILTER_TX_UDP_WILD); + EFX_POPULATE_OWORD_5(*filter, + FRF_CZ_TIFT_TCP_UDP, is_udp, + FRF_CZ_TIFT_TXQ_ID, spec->efs_dmaq_id, + EFX_DWORD_2, spec->efs_dword[2], + EFX_DWORD_1, spec->efs_dword[1], + EFX_DWORD_0, spec->efs_dword[0]); + dword3 = is_udp | spec->efs_dmaq_id << 1; + break; + } + +#if EFSYS_OPT_SIENA + case EFX_FILTER_TBL_TX_MAC: { + boolean_t is_wild = (type == EFX_FILTER_TX_MAC_WILD); + EFX_POPULATE_OWORD_5(*filter, + FRF_CZ_TMFT_TXQ_ID, spec->efs_dmaq_id, + FRF_CZ_TMFT_WILDCARD_MATCH, is_wild, + FRF_CZ_TMFT_SRC_MAC_DW1, spec->efs_dword[2], + FRF_CZ_TMFT_SRC_MAC_DW0, spec->efs_dword[1], + FRF_CZ_TMFT_VLAN_ID, spec->efs_dword[0]); + dword3 = is_wild | spec->efs_dmaq_id << 1; + break; + } +#endif /* EFSYS_OPT_SIENA */ + + default: + EFSYS_ASSERT(B_FALSE); + } + + key = spec->efs_dword[0] ^ spec->efs_dword[1] ^ spec->efs_dword[2] ^ dword3; + return (key); +} + +static __checkReturn int +efx_filter_push_entry( + __inout efx_nic_t *enp, + __in efx_filter_type_t type, + __in int index, + __in efx_oword_t *eop) +{ + int rc; + + switch (type) + { + case EFX_FILTER_RX_TCP_FULL: + case EFX_FILTER_RX_TCP_WILD: + case EFX_FILTER_RX_UDP_FULL: + case EFX_FILTER_RX_UDP_WILD: + EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_FILTER_TBL0, index, eop); + break; + +#if EFSYS_OPT_SIENA + case EFX_FILTER_RX_MAC_FULL: + case EFX_FILTER_RX_MAC_WILD: + EFX_BAR_TBL_WRITEO(enp, FR_CZ_RX_MAC_FILTER_TBL0, index, eop); + break; + + case EFX_FILTER_TX_TCP_FULL: + case EFX_FILTER_TX_TCP_WILD: + case EFX_FILTER_TX_UDP_FULL: + case EFX_FILTER_TX_UDP_WILD: + EFX_BAR_TBL_WRITEO(enp, FR_CZ_TX_FILTER_TBL0, index, eop); + break; + + case EFX_FILTER_TX_MAC_FULL: + case EFX_FILTER_TX_MAC_WILD: + EFX_BAR_TBL_WRITEO(enp, FR_CZ_TX_MAC_FILTER_TBL0, index, eop); + break; +#endif /* EFSYS_OPT_SIENA */ + + default: + rc = ENOTSUP; + goto fail1; + } + return (0); + +fail1: + return (rc); +} + + +static __checkReturn boolean_t +efx_filter_equal( + __in const efx_filter_spec_t *left, + __in const efx_filter_spec_t *right) +{ + efx_filter_tbl_id_t tbl_id = efx_filter_tbl_id(left->efs_type); + + if (left->efs_type != right->efs_type) + return (B_FALSE); + + if (memcmp(left->efs_dword, right->efs_dword, sizeof(left->efs_dword))) + return (B_FALSE); + + if ((tbl_id == EFX_FILTER_TBL_TX_IP || + tbl_id == EFX_FILTER_TBL_TX_MAC) && + left->efs_dmaq_id != right->efs_dmaq_id) + return (B_FALSE); + + return (B_TRUE); +} + +static __checkReturn int +efx_filter_search( + __in efx_filter_tbl_t *eftp, + __in efx_filter_spec_t *spec, + __in uint32_t key, + __in boolean_t for_insert, + __out int *filter_index, + __out int *depth_required) +{ + unsigned hash, incr, filter_idx, depth; + + hash = efx_filter_tbl_hash(key); + incr = efx_filter_tbl_increment(key); + + filter_idx = hash & (eftp->eft_size - 1); + depth = 1; + + for (;;) { + /* Return success if entry is used and matches this spec + * or entry is unused and we are trying to insert. + */ + if (efx_filter_test_used(eftp, filter_idx) ? + efx_filter_equal(spec, &eftp->eft_spec[filter_idx]) : + for_insert) { + *filter_index = filter_idx; + *depth_required = depth; + return (0); + } + + /* Return failure if we reached the maximum search depth */ + if (depth == FILTER_CTL_SRCH_MAX) + return for_insert ? EBUSY : ENOENT; + + filter_idx = (filter_idx + incr) & (eftp->eft_size - 1); + ++depth; + } +} + + __checkReturn int +efx_filter_insert_filter( + __in efx_nic_t *enp, + __in efx_filter_spec_t *spec, + __in boolean_t replace) +{ + efx_filter_t *efp = &enp->en_filter; + efx_filter_tbl_id_t tbl_id = efx_filter_tbl_id(spec->efs_type); + efx_filter_tbl_t *eftp = &efp->ef_tbl[tbl_id]; + efx_filter_spec_t *saved_spec; + efx_oword_t filter; + int filter_idx; + unsigned int depth; + int state; + uint32_t key; + int rc; + + if (eftp->eft_size == 0) + return (EINVAL); + + key = efx_filter_build(&filter, spec); + + EFSYS_LOCK(enp->en_eslp, state); + + rc = efx_filter_search(eftp, spec, key, B_TRUE, &filter_idx, &depth); + if (rc != 0) + goto done; + + EFSYS_ASSERT3U(filter_idx, <, eftp->eft_size); + saved_spec = &eftp->eft_spec[filter_idx]; + + if (efx_filter_test_used(eftp, filter_idx)) { + if (replace == B_FALSE) { + rc = EEXIST; + goto done; + } + } + efx_filter_set_used(eftp, filter_idx); + *saved_spec = *spec; + + if (efp->ef_depth[spec->efs_type] < depth) { + efp->ef_depth[spec->efs_type] = depth; + if (tbl_id == EFX_FILTER_TBL_TX_IP || + tbl_id == EFX_FILTER_TBL_TX_MAC) + efx_filter_push_tx_limits(enp); + else + efx_filter_push_rx_limits(enp); + } + + efx_filter_push_entry(enp, spec->efs_type, filter_idx, &filter); + +done: + EFSYS_UNLOCK(enp->en_eslp, state); + return (rc); +} + +static void +efx_filter_clear_entry( + __in efx_nic_t *enp, + __in efx_filter_tbl_t *eftp, + __in int index) +{ + efx_oword_t filter; + + if (efx_filter_test_used(eftp, index)) { + efx_filter_clear_used(eftp, index); + + EFX_ZERO_OWORD(filter); + efx_filter_push_entry(enp, eftp->eft_spec[index].efs_type, + index, &filter); + + memset(&eftp->eft_spec[index], 0, sizeof(eftp->eft_spec[0])); + } +} + + __checkReturn int +efx_filter_remove_filter( + __in efx_nic_t *enp, + __in efx_filter_spec_t *spec) +{ + efx_filter_t *efp = &enp->en_filter; + efx_filter_tbl_id_t tbl_id = efx_filter_tbl_id(spec->efs_type); + efx_filter_tbl_t *eftp = &efp->ef_tbl[tbl_id]; + efx_filter_spec_t *saved_spec; + efx_oword_t filter; + int filter_idx, depth; + int state; + uint32_t key; + int rc; + + key = efx_filter_build(&filter, spec); + + EFSYS_LOCK(enp->en_eslp, state); + + rc = efx_filter_search(eftp, spec, key, B_FALSE, &filter_idx, &depth); + if (rc != 0) + goto out; + + saved_spec = &eftp->eft_spec[filter_idx]; + + efx_filter_clear_entry(enp, eftp, filter_idx); + if (eftp->eft_used == 0) + efx_filter_reset_search_depth(efp, tbl_id); + + rc = 0; + +out: + EFSYS_UNLOCK(enp->en_eslp, state); + return (rc); +} + + void +efx_filter_remove_index( + __inout efx_nic_t *enp, + __in efx_filter_type_t type, + __in int index) +{ + efx_filter_t *efp = &enp->en_filter; + enum efx_filter_tbl_id tbl_id = efx_filter_tbl_id(type); + efx_filter_tbl_t *eftp = &efp->ef_tbl[tbl_id]; + int state; + + if (index < 0) + return; + + EFSYS_LOCK(enp->en_eslp, state); + + efx_filter_clear_entry(enp, eftp, index); + if (eftp->eft_used == 0) + efx_filter_reset_search_depth(efp, tbl_id); + + EFSYS_UNLOCK(enp->en_eslp, state); +} + + void +efx_filter_tbl_clear( + __inout efx_nic_t *enp, + __in efx_filter_tbl_id_t tbl_id) +{ + efx_filter_t *efp = &enp->en_filter; + efx_filter_tbl_t *eftp = &efp->ef_tbl[tbl_id]; + int index; + int state; + + EFSYS_LOCK(enp->en_eslp, state); + + for (index = 0; index < eftp->eft_size; ++index) { + efx_filter_clear_entry(enp, eftp, index); + } + + if (eftp->eft_used == 0) + efx_filter_reset_search_depth(efp, tbl_id); + + EFSYS_UNLOCK(enp->en_eslp, state); +} + +/* Restore filter state after a reset */ + void +efx_filter_restore( + __in efx_nic_t *enp) +{ + efx_filter_t *efp = &enp->en_filter; + efx_filter_tbl_id_t tbl_id; + efx_filter_tbl_t *eftp; + efx_filter_spec_t *spec; + efx_oword_t filter; + int filter_idx; + int state; + + EFSYS_LOCK(enp->en_eslp, state); + + for (tbl_id = 0; tbl_id < EFX_FILTER_NTBLS; tbl_id++) { + eftp = &efp->ef_tbl[tbl_id]; + for (filter_idx = 0; filter_idx < eftp->eft_size; filter_idx++) { + if (!efx_filter_test_used(eftp, filter_idx)) + continue; + + spec = &eftp->eft_spec[filter_idx]; + efx_filter_build(&filter, spec); + efx_filter_push_entry(enp, spec->efs_type, + filter_idx, &filter); + } + } + + efx_filter_push_rx_limits(enp); + efx_filter_push_tx_limits(enp); + + EFSYS_UNLOCK(enp->en_eslp, state); +} + + void +efx_filter_redirect_index( + __inout efx_nic_t *enp, + __in efx_filter_type_t type, + __in int filter_index, + __in int rxq_index) +{ + efx_filter_t *efp = &enp->en_filter; + efx_filter_tbl_t *eftp = + &efp->ef_tbl[efx_filter_tbl_id(type)]; + efx_filter_spec_t *spec; + efx_oword_t filter; + int state; + + EFSYS_LOCK(enp->en_eslp, state); + + spec = &eftp->eft_spec[filter_index]; + spec->efs_dmaq_id = (uint16_t)rxq_index; + + efx_filter_build(&filter, spec); + efx_filter_push_entry(enp, spec->efs_type, filter_index, &filter); + + EFSYS_UNLOCK(enp->en_eslp, state); +} + + __checkReturn int +efx_filter_init( + __in efx_nic_t *enp) +{ + efx_filter_t *efp = &enp->en_filter; + efx_filter_tbl_t *eftp; + int tbl_id; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_FILTER)); + + switch (enp->en_family) + { +#if EFSYS_OPT_FALCON + case EFX_FAMILY_FALCON: + eftp = &efp->ef_tbl[EFX_FILTER_TBL_RX_IP]; + eftp->eft_size = FR_AZ_RX_FILTER_TBL0_ROWS; + break; +#endif /* EFSYS_OPT_FALCON */ + +#if EFSYS_OPT_SIENA + case EFX_FAMILY_SIENA: + eftp = &efp->ef_tbl[EFX_FILTER_TBL_RX_IP]; + eftp->eft_size = FR_AZ_RX_FILTER_TBL0_ROWS; + + eftp = &efp->ef_tbl[EFX_FILTER_TBL_RX_MAC]; + eftp->eft_size = FR_CZ_RX_MAC_FILTER_TBL0_ROWS; + + eftp = &efp->ef_tbl[EFX_FILTER_TBL_TX_IP]; + eftp->eft_size = FR_CZ_TX_FILTER_TBL0_ROWS; + + eftp = &efp->ef_tbl[EFX_FILTER_TBL_TX_MAC]; + eftp->eft_size = FR_CZ_TX_MAC_FILTER_TBL0_ROWS; + break; +#endif /* EFSYS_OPT_SIENA */ + + default: + rc = ENOTSUP; + goto fail1; + } + + for (tbl_id = 0; tbl_id < EFX_FILTER_NTBLS; tbl_id++) { + unsigned int bitmap_size; + + eftp = &efp->ef_tbl[tbl_id]; + if (eftp->eft_size == 0) + continue; + + EFX_STATIC_ASSERT(sizeof(eftp->eft_bitmap[0]) == sizeof(uint32_t)); + bitmap_size = (eftp->eft_size + (sizeof(uint32_t) * 8) - 1) / 8; + + EFSYS_KMEM_ALLOC(enp->en_esip, bitmap_size, eftp->eft_bitmap); + if (!eftp->eft_bitmap) { + rc = ENOMEM; + goto fail2; + } + + EFSYS_KMEM_ALLOC(enp->en_esip, eftp->eft_size * sizeof(*eftp->eft_spec), + eftp->eft_spec); + if (!eftp->eft_spec) { + rc = ENOMEM; + goto fail2; + } + memset(eftp->eft_spec, 0, eftp->eft_size * sizeof(*eftp->eft_spec)); + } + enp->en_mod_flags |= EFX_MOD_FILTER; + + return (0); + +fail2: + EFSYS_PROBE(fail2); + efx_filter_fini(enp); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + return (rc); +} + + void +efx_filter_fini( + __in efx_nic_t *enp) +{ + efx_filter_t *efp = &enp->en_filter; + efx_filter_tbl_id_t tbl_id; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + + for (tbl_id = 0; tbl_id < EFX_FILTER_NTBLS; tbl_id++) { + efx_filter_tbl_t *eftp = &efp->ef_tbl[tbl_id]; + unsigned int bitmap_size; + + EFX_STATIC_ASSERT(sizeof(eftp->eft_bitmap[0]) == sizeof(uint32_t)); + bitmap_size = (eftp->eft_size + (sizeof(uint32_t) * 8) - 1) / 8; + + EFSYS_KMEM_FREE(enp->en_esip, bitmap_size, eftp->eft_bitmap); + eftp->eft_bitmap = NULL; + + EFSYS_KMEM_FREE(enp->en_esip, eftp->eft_size * sizeof(*eftp->eft_spec), + eftp->eft_spec); + eftp->eft_spec = NULL; + } + + enp->en_mod_flags &= ~EFX_MOD_FILTER; +} + +extern void +efx_filter_spec_rx_ipv4_tcp_full( + __inout efx_filter_spec_t *spec, + __in unsigned int flags, + __in uint32_t src_ip, + __in uint16_t src_tcp, + __in uint32_t dest_ip, + __in uint16_t dest_tcp) +{ + EFSYS_ASSERT3P(spec, !=, NULL); + EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS | + EFX_FILTER_FLAG_RX_SCATTER)) == 0); + + spec->efs_type = EFX_FILTER_RX_TCP_FULL; + spec->efs_flags = (uint8_t)flags; + spec->efs_dword[0] = src_tcp | src_ip << 16; + spec->efs_dword[1] = dest_tcp << 16 | src_ip >> 16; + spec->efs_dword[2] = dest_ip; +} + +extern void +efx_filter_spec_rx_ipv4_tcp_wild( + __inout efx_filter_spec_t *spec, + __in unsigned int flags, + __in uint32_t dest_ip, + __in uint16_t dest_tcp) +{ + EFSYS_ASSERT3P(spec, !=, NULL); + EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS | + EFX_FILTER_FLAG_RX_SCATTER)) == 0); + + spec->efs_type = EFX_FILTER_RX_TCP_WILD; + spec->efs_flags = (uint8_t)flags; + spec->efs_dword[0] = 0; + spec->efs_dword[1] = dest_tcp << 16; + spec->efs_dword[2] = dest_ip; +} + +extern void +efx_filter_spec_rx_ipv4_udp_full( + __inout efx_filter_spec_t *spec, + __in unsigned int flags, + __in uint32_t src_ip, + __in uint16_t src_udp, + __in uint32_t dest_ip, + __in uint16_t dest_udp) +{ + EFSYS_ASSERT3P(spec, !=, NULL); + EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS | + EFX_FILTER_FLAG_RX_SCATTER)) == 0); + + spec->efs_type = EFX_FILTER_RX_UDP_FULL; + spec->efs_flags = (uint8_t)flags; + spec->efs_dword[0] = src_udp | src_ip << 16; + spec->efs_dword[1] = dest_udp << 16 | src_ip >> 16; + spec->efs_dword[2] = dest_ip; +} + +extern void +efx_filter_spec_rx_ipv4_udp_wild( + __inout efx_filter_spec_t *spec, + __in unsigned int flags, + __in uint32_t dest_ip, + __in uint16_t dest_udp) +{ + EFSYS_ASSERT3P(spec, !=, NULL); + EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS | + EFX_FILTER_FLAG_RX_SCATTER)) == 0); + + spec->efs_type = EFX_FILTER_RX_UDP_WILD; + spec->efs_flags = (uint8_t)flags; + spec->efs_dword[0] = dest_udp; + spec->efs_dword[1] = 0; + spec->efs_dword[2] = dest_ip; +} + +#if EFSYS_OPT_SIENA +extern void +efx_filter_spec_rx_mac_full( + __inout efx_filter_spec_t *spec, + __in unsigned int flags, + __in uint16_t vlan_id, + __in uint8_t *dest_mac) +{ + EFSYS_ASSERT3P(spec, !=, NULL); + EFSYS_ASSERT3P(dest_mac, !=, NULL); + EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS | + EFX_FILTER_FLAG_RX_SCATTER | + EFX_FILTER_FLAG_RX_OVERRIDE_IP)) == 0); + + spec->efs_type = EFX_FILTER_RX_MAC_FULL; + spec->efs_flags = (uint8_t)flags; + spec->efs_dword[0] = vlan_id; + spec->efs_dword[1] = + dest_mac[2] << 24 | + dest_mac[3] << 16 | + dest_mac[4] << 8 | + dest_mac[5]; + spec->efs_dword[2] = + dest_mac[0] << 8 | + dest_mac[1]; +} +#endif /* EFSYS_OPT_SIENA */ + +#if EFSYS_OPT_SIENA +extern void +efx_filter_spec_rx_mac_wild( + __inout efx_filter_spec_t *spec, + __in unsigned int flags, + __in uint8_t *dest_mac) +{ + EFSYS_ASSERT3P(spec, !=, NULL); + EFSYS_ASSERT3P(dest_mac, !=, NULL); + EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS | + EFX_FILTER_FLAG_RX_SCATTER | + EFX_FILTER_FLAG_RX_OVERRIDE_IP)) == 0); + + spec->efs_type = EFX_FILTER_RX_MAC_WILD; + spec->efs_flags = (uint8_t)flags; + spec->efs_dword[0] = 0; + spec->efs_dword[1] = + dest_mac[2] << 24 | + dest_mac[3] << 16 | + dest_mac[4] << 8 | + dest_mac[5]; + spec->efs_dword[2] = + dest_mac[0] << 8 | + dest_mac[1]; +} +#endif /* EFSYS_OPT_SIENA */ + +#if EFSYS_OPT_SIENA +extern void +efx_filter_spec_tx_ipv4_tcp_full( + __inout efx_filter_spec_t *spec, + __in uint32_t src_ip, + __in uint16_t src_tcp, + __in uint32_t dest_ip, + __in uint16_t dest_tcp) +{ + EFSYS_ASSERT3P(spec, !=, NULL); + + spec->efs_type = EFX_FILTER_TX_TCP_FULL; + spec->efs_flags = 0; + spec->efs_dword[0] = src_tcp | src_ip << 16; + spec->efs_dword[1] = dest_tcp << 16 | src_ip >> 16; + spec->efs_dword[2] = dest_ip; +} +#endif /* EFSYS_OPT_SIENA */ + +#if EFSYS_OPT_SIENA +extern void +efx_filter_spec_tx_ipv4_tcp_wild( + __inout efx_filter_spec_t *spec, + __in uint32_t src_ip, + __in uint16_t src_tcp) +{ + EFSYS_ASSERT3P(spec, !=, NULL); + + spec->efs_type = EFX_FILTER_TX_TCP_WILD; + spec->efs_flags = 0; + spec->efs_dword[0] = 0; + spec->efs_dword[1] = src_tcp << 16; + spec->efs_dword[2] = src_ip; +} +#endif /* EFSYS_OPT_SIENA */ + +#if EFSYS_OPT_SIENA +extern void +efx_filter_spec_tx_ipv4_udp_full( + __inout efx_filter_spec_t *spec, + __in uint32_t src_ip, + __in uint16_t src_udp, + __in uint32_t dest_ip, + __in uint16_t dest_udp) +{ + EFSYS_ASSERT3P(spec, !=, NULL); + + spec->efs_type = EFX_FILTER_TX_UDP_FULL; + spec->efs_flags = 0; + spec->efs_dword[0] = src_udp | src_ip << 16; + spec->efs_dword[1] = dest_udp << 16 | src_ip >> 16; + spec->efs_dword[2] = dest_ip; +} +#endif /* EFSYS_OPT_SIENA */ + +#if EFSYS_OPT_SIENA +extern void +efx_filter_spec_tx_ipv4_udp_wild( + __inout efx_filter_spec_t *spec, + __in uint32_t src_ip, + __in uint16_t src_udp) +{ + EFSYS_ASSERT3P(spec, !=, NULL); + + spec->efs_type = EFX_FILTER_TX_UDP_WILD; + spec->efs_flags = 0; + spec->efs_dword[0] = src_udp; + spec->efs_dword[1] = 0; + spec->efs_dword[2] = src_ip; +} +#endif /* EFSYS_OPT_SIENA */ + +#if EFSYS_OPT_SIENA +extern void +efx_filter_spec_tx_mac_full( + __inout efx_filter_spec_t *spec, + __in uint16_t vlan_id, + __in uint8_t *src_mac) +{ + EFSYS_ASSERT3P(spec, !=, NULL); + EFSYS_ASSERT3P(src_mac, !=, NULL); + + spec->efs_type = EFX_FILTER_TX_MAC_FULL; + spec->efs_flags = 0; + spec->efs_dword[0] = vlan_id; + spec->efs_dword[1] = + src_mac[2] << 24 | + src_mac[3] << 16 | + src_mac[4] << 8 | + src_mac[5]; + spec->efs_dword[2] = + src_mac[0] << 8 | + src_mac[1]; +} +#endif /* EFSYS_OPT_SIENA */ + +#if EFSYS_OPT_SIENA +extern void +efx_filter_spec_tx_mac_wild( + __inout efx_filter_spec_t *spec, + __in uint8_t *src_mac) +{ + EFSYS_ASSERT3P(spec, !=, NULL); + EFSYS_ASSERT3P(src_mac, !=, NULL); + + spec->efs_type = EFX_FILTER_TX_MAC_WILD; + spec->efs_flags = 0; + spec->efs_dword[0] = 0; + spec->efs_dword[1] = + src_mac[2] << 24 | + src_mac[3] << 16 | + src_mac[4] << 8 | + src_mac[5]; + spec->efs_dword[2] = + src_mac[0] << 8 | + src_mac[1]; +} +#endif /* EFSYS_OPT_SIENA */ + + +#endif /* EFSYS_OPT_FILTER */ diff --git a/sys/dev/sfxge/common/efx_impl.h b/sys/dev/sfxge/common/efx_impl.h new file mode 100644 index 000000000000..5858e96ec7d0 --- /dev/null +++ b/sys/dev/sfxge/common/efx_impl.h @@ -0,0 +1,734 @@ +/*- + * Copyright 2007-2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SYS_EFX_IMPL_H +#define _SYS_EFX_IMPL_H + +#include "efsys.h" +#include "efx.h" +#include "efx_regs.h" + +#if EFSYS_OPT_FALCON +#include "falcon_impl.h" +#endif /* EFSYS_OPT_FALCON */ + +#if EFSYS_OPT_SIENA +#include "siena_impl.h" +#endif /* EFSYS_OPT_SIENA */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define EFX_MOD_MCDI 0x00000001 +#define EFX_MOD_PROBE 0x00000002 +#define EFX_MOD_NVRAM 0x00000004 +#define EFX_MOD_VPD 0x00000008 +#define EFX_MOD_NIC 0x00000010 +#define EFX_MOD_INTR 0x00000020 +#define EFX_MOD_EV 0x00000040 +#define EFX_MOD_RX 0x00000080 +#define EFX_MOD_TX 0x00000100 +#define EFX_MOD_PORT 0x00000200 +#define EFX_MOD_MON 0x00000400 +#define EFX_MOD_WOL 0x00000800 +#define EFX_MOD_FILTER 0x00001000 + +#define EFX_RESET_MAC 0x00000001 +#define EFX_RESET_PHY 0x00000002 + +typedef enum efx_mac_type_e { + EFX_MAC_INVALID = 0, + EFX_MAC_FALCON_GMAC, + EFX_MAC_FALCON_XMAC, + EFX_MAC_SIENA, + EFX_MAC_NTYPES +} efx_mac_type_t; + +typedef struct efx_mac_ops_s { + int (*emo_reset)(efx_nic_t *); /* optional */ + int (*emo_poll)(efx_nic_t *, efx_link_mode_t *); + int (*emo_up)(efx_nic_t *, boolean_t *); + int (*emo_reconfigure)(efx_nic_t *); +#if EFSYS_OPT_LOOPBACK + int (*emo_loopback_set)(efx_nic_t *, efx_link_mode_t, + efx_loopback_type_t); +#endif /* EFSYS_OPT_LOOPBACK */ +#if EFSYS_OPT_MAC_STATS + int (*emo_stats_upload)(efx_nic_t *, efsys_mem_t *); + int (*emo_stats_periodic)(efx_nic_t *, efsys_mem_t *, + uint16_t, boolean_t); + int (*emo_stats_update)(efx_nic_t *, efsys_mem_t *, + efsys_stat_t *, uint32_t *); +#endif /* EFSYS_OPT_MAC_STATS */ +} efx_mac_ops_t; + +typedef struct efx_phy_ops_s { + int (*epo_power)(efx_nic_t *, boolean_t); /* optional */ + int (*epo_reset)(efx_nic_t *); + int (*epo_reconfigure)(efx_nic_t *); + int (*epo_verify)(efx_nic_t *); + int (*epo_uplink_check)(efx_nic_t *, + boolean_t *); /* optional */ + int (*epo_downlink_check)(efx_nic_t *, efx_link_mode_t *, + unsigned int *, uint32_t *); + int (*epo_oui_get)(efx_nic_t *, uint32_t *); +#if EFSYS_OPT_PHY_STATS + int (*epo_stats_update)(efx_nic_t *, efsys_mem_t *, + uint32_t *); +#endif /* EFSYS_OPT_PHY_STATS */ +#if EFSYS_OPT_PHY_PROPS +#if EFSYS_OPT_NAMES + const char __cs *(*epo_prop_name)(efx_nic_t *, unsigned int); +#endif /* EFSYS_OPT_PHY_PROPS */ + int (*epo_prop_get)(efx_nic_t *, unsigned int, uint32_t, + uint32_t *); + int (*epo_prop_set)(efx_nic_t *, unsigned int, uint32_t); +#endif /* EFSYS_OPT_PHY_PROPS */ +#if EFSYS_OPT_PHY_BIST + int (*epo_bist_start)(efx_nic_t *, efx_phy_bist_type_t); + int (*epo_bist_poll)(efx_nic_t *, efx_phy_bist_type_t, + efx_phy_bist_result_t *, uint32_t *, + unsigned long *, size_t); + void (*epo_bist_stop)(efx_nic_t *, efx_phy_bist_type_t); +#endif /* EFSYS_OPT_PHY_BIST */ +} efx_phy_ops_t; + +typedef struct efx_port_s { + efx_mac_type_t ep_mac_type; + uint32_t ep_phy_type; + uint8_t ep_port; + uint32_t ep_mac_pdu; + uint8_t ep_mac_addr[6]; + efx_link_mode_t ep_link_mode; + boolean_t ep_unicst; + boolean_t ep_brdcst; + unsigned int ep_fcntl; + boolean_t ep_fcntl_autoneg; + efx_oword_t ep_multicst_hash[2]; +#if EFSYS_OPT_LOOPBACK + efx_loopback_type_t ep_loopback_type; + efx_link_mode_t ep_loopback_link_mode; +#endif /* EFSYS_OPT_LOOPBACK */ +#if EFSYS_OPT_PHY_FLAGS + uint32_t ep_phy_flags; +#endif /* EFSYS_OPT_PHY_FLAGS */ +#if EFSYS_OPT_PHY_LED_CONTROL + efx_phy_led_mode_t ep_phy_led_mode; +#endif /* EFSYS_OPT_PHY_LED_CONTROL */ + efx_phy_media_type_t ep_fixed_port_type; + efx_phy_media_type_t ep_module_type; + uint32_t ep_adv_cap_mask; + uint32_t ep_lp_cap_mask; + uint32_t ep_default_adv_cap_mask; + uint32_t ep_phy_cap_mask; +#if EFSYS_OPT_PHY_TXC43128 || EFSYS_OPT_PHY_QT2025C + union { + struct { + unsigned int bug10934_count; + } ep_txc43128; + struct { + unsigned int bug17190_count; + } ep_qt2025c; + }; +#endif + boolean_t ep_mac_poll_needed; /* falcon only */ + boolean_t ep_mac_up; /* falcon only */ + uint32_t ep_fwver; /* falcon only */ + boolean_t ep_mac_drain; + boolean_t ep_mac_stats_pending; +#if EFSYS_OPT_PHY_BIST + efx_phy_bist_type_t ep_current_bist; +#endif + efx_mac_ops_t *ep_emop; + efx_phy_ops_t *ep_epop; +} efx_port_t; + +typedef struct efx_mon_ops_s { + int (*emo_reset)(efx_nic_t *); + int (*emo_reconfigure)(efx_nic_t *); +#if EFSYS_OPT_MON_STATS + int (*emo_stats_update)(efx_nic_t *, efsys_mem_t *, + efx_mon_stat_value_t *); +#endif /* EFSYS_OPT_MON_STATS */ +} efx_mon_ops_t; + +typedef struct efx_mon_s { + efx_mon_type_t em_type; + efx_mon_ops_t *em_emop; +} efx_mon_t; + +typedef struct efx_intr_s { + efx_intr_type_t ei_type; + efsys_mem_t *ei_esmp; + unsigned int ei_level; +} efx_intr_t; + +typedef struct efx_nic_ops_s { + int (*eno_probe)(efx_nic_t *); + int (*eno_reset)(efx_nic_t *); + int (*eno_init)(efx_nic_t *); +#if EFSYS_OPT_DIAG + int (*eno_sram_test)(efx_nic_t *, efx_sram_pattern_fn_t); + int (*eno_register_test)(efx_nic_t *); +#endif /* EFSYS_OPT_DIAG */ + void (*eno_fini)(efx_nic_t *); + void (*eno_unprobe)(efx_nic_t *); +} efx_nic_ops_t; + +#define EFX_TXQ_LIMIT_TARGET 259 +#define EFX_RXQ_LIMIT_TARGET 768 + +#if EFSYS_OPT_FILTER + +typedef enum efx_filter_type_e { + EFX_FILTER_RX_TCP_FULL, /* TCP/IPv4 4-tuple {dIP,dTCP,sIP,sTCP} */ + EFX_FILTER_RX_TCP_WILD, /* TCP/IPv4 dest {dIP,dTCP, -, -} */ + EFX_FILTER_RX_UDP_FULL, /* UDP/IPv4 4-tuple {dIP,dUDP,sIP,sUDP} */ + EFX_FILTER_RX_UDP_WILD, /* UDP/IPv4 dest {dIP,dUDP, -, -} */ + +#if EFSYS_OPT_SIENA + EFX_FILTER_RX_MAC_FULL, /* Ethernet {dMAC,VLAN} */ + EFX_FILTER_RX_MAC_WILD, /* Ethernet {dMAC, -} */ + + EFX_FILTER_TX_TCP_FULL, /* TCP/IPv4 {dIP,dTCP,sIP,sTCP} */ + EFX_FILTER_TX_TCP_WILD, /* TCP/IPv4 { -, -,sIP,sTCP} */ + EFX_FILTER_TX_UDP_FULL, /* UDP/IPv4 {dIP,dTCP,sIP,sTCP} */ + EFX_FILTER_TX_UDP_WILD, /* UDP/IPv4 source (host, port) */ + + EFX_FILTER_TX_MAC_FULL, /* Ethernet source (MAC address, VLAN ID) */ + EFX_FILTER_TX_MAC_WILD, /* Ethernet source (MAC address) */ +#endif /* EFSYS_OPT_SIENA */ + + EFX_FILTER_NTYPES +} efx_filter_type_t; + +typedef enum efx_filter_tbl_id_e { + EFX_FILTER_TBL_RX_IP = 0, + EFX_FILTER_TBL_RX_MAC, + EFX_FILTER_TBL_TX_IP, + EFX_FILTER_TBL_TX_MAC, + EFX_FILTER_NTBLS +} efx_filter_tbl_id_t; + +typedef struct efx_filter_tbl_s { + int eft_size; /* number of entries */ + int eft_used; /* active count */ + uint32_t *eft_bitmap; /* active bitmap */ + efx_filter_spec_t *eft_spec; /* array of saved specs */ +} efx_filter_tbl_t; + +typedef struct efx_filter_s { + efx_filter_tbl_t ef_tbl[EFX_FILTER_NTBLS]; + unsigned int ef_depth[EFX_FILTER_NTYPES]; +} efx_filter_t; + + +extern __checkReturn int +efx_filter_insert_filter( + __in efx_nic_t *enp, + __in efx_filter_spec_t *spec, + __in boolean_t replace); + +extern __checkReturn int +efx_filter_remove_filter( + __in efx_nic_t *enp, + __in efx_filter_spec_t *spec); + +extern void +efx_filter_remove_index( + __inout efx_nic_t *enp, + __in efx_filter_type_t type, + __in int filter_idx); + +extern void +efx_filter_redirect_index( + __inout efx_nic_t *enp, + __in efx_filter_type_t type, + __in int filter_index, + __in int rxq_index); + +extern __checkReturn int +efx_filter_clear_tbl( + __in efx_nic_t *enp, + __in efx_filter_tbl_id_t tbl); + +#endif /* EFSYS_OPT_FILTER */ + +#if EFSYS_OPT_NVRAM +typedef struct efx_nvram_ops_s { +#if EFSYS_OPT_DIAG + int (*envo_test)(efx_nic_t *); +#endif /* EFSYS_OPT_DIAG */ + int (*envo_size)(efx_nic_t *, efx_nvram_type_t, size_t *); + int (*envo_get_version)(efx_nic_t *, efx_nvram_type_t, + uint32_t *, uint16_t *); + int (*envo_rw_start)(efx_nic_t *, efx_nvram_type_t, size_t *); + int (*envo_read_chunk)(efx_nic_t *, efx_nvram_type_t, + unsigned int, caddr_t, size_t); + int (*envo_erase)(efx_nic_t *, efx_nvram_type_t); + int (*envo_write_chunk)(efx_nic_t *, efx_nvram_type_t, + unsigned int, caddr_t, size_t); + void (*envo_rw_finish)(efx_nic_t *, efx_nvram_type_t); + int (*envo_set_version)(efx_nic_t *, efx_nvram_type_t, uint16_t *); + +} efx_nvram_ops_t; +#endif /* EFSYS_OPT_NVRAM */ + +#if EFSYS_OPT_VPD +typedef struct efx_vpd_ops_s { + int (*evpdo_init)(efx_nic_t *); + int (*evpdo_size)(efx_nic_t *, size_t *); + int (*evpdo_read)(efx_nic_t *, caddr_t, size_t); + int (*evpdo_verify)(efx_nic_t *, caddr_t, size_t); + int (*evpdo_reinit)(efx_nic_t *, caddr_t, size_t); + int (*evpdo_get)(efx_nic_t *, caddr_t, size_t, efx_vpd_value_t *); + int (*evpdo_set)(efx_nic_t *, caddr_t, size_t, efx_vpd_value_t *); + int (*evpdo_next)(efx_nic_t *, caddr_t, size_t, efx_vpd_value_t *, + unsigned int *); + int (*evpdo_write)(efx_nic_t *, caddr_t, size_t); + void (*evpdo_fini)(efx_nic_t *); +} efx_vpd_ops_t; +#endif /* EFSYS_OPT_VPD */ + +struct efx_nic_s { + uint32_t en_magic; + efx_family_t en_family; + uint32_t en_features; + efsys_identifier_t *en_esip; + efsys_lock_t *en_eslp; + efsys_bar_t *en_esbp; + unsigned int en_mod_flags; + unsigned int en_reset_flags; + efx_nic_cfg_t en_nic_cfg; + efx_port_t en_port; + efx_mon_t en_mon; + efx_intr_t en_intr; + uint32_t en_ev_qcount; + uint32_t en_rx_qcount; + uint32_t en_tx_qcount; + efx_nic_ops_t *en_enop; +#if EFSYS_OPT_FILTER + efx_filter_t en_filter; +#endif /* EFSYS_OPT_FILTER */ +#if EFSYS_OPT_NVRAM + efx_nvram_type_t en_nvram_locked; + efx_nvram_ops_t *en_envop; +#endif /* EFSYS_OPT_NVRAM */ +#if EFSYS_OPT_VPD + efx_vpd_ops_t *en_evpdop; +#endif /* EFSYS_OPT_VPD */ + union { +#if EFSYS_OPT_FALCON + struct { + falcon_spi_dev_t enu_fsd[FALCON_SPI_NTYPES]; + falcon_i2c_t enu_fip; + boolean_t enu_i2c_locked; +#if EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE + const uint8_t *enu_forced_cfg; +#endif /* EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE */ + uint8_t enu_mon_devid; +#if EFSYS_OPT_PCIE_TUNE + unsigned int enu_nlanes; +#endif /* EFSYS_OPT_PCIE_TUNE */ + uint16_t enu_board_rev; + boolean_t enu_internal_sram; + uint8_t enu_sram_num_bank; + uint8_t enu_sram_bank_size; + } falcon; +#endif /* EFSYS_OPT_FALCON */ +#if EFSYS_OPT_SIENA + struct { +#if EFSYS_OPT_MCDI + efx_mcdi_iface_t enu_mip; +#endif /* EFSYS_OPT_MCDI */ +#if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD + unsigned int enu_partn_mask; +#endif /* EFSYS_OPT_NVRAM || EFSYS_OPT_VPD */ +#if EFSYS_OPT_VPD + caddr_t enu_svpd; + size_t enu_svpd_length; +#endif /* EFSYS_OPT_VPD */ + } siena; +#endif /* EFSYS_OPT_SIENA */ + } en_u; +}; + + +#define EFX_NIC_MAGIC 0x02121996 + +typedef boolean_t (*efx_ev_handler_t)(efx_evq_t *, efx_qword_t *, + const efx_ev_callbacks_t *, void *); + +struct efx_evq_s { + uint32_t ee_magic; + efx_nic_t *ee_enp; + unsigned int ee_index; + unsigned int ee_mask; + efsys_mem_t *ee_esmp; +#if EFSYS_OPT_QSTATS + uint32_t ee_stat[EV_NQSTATS]; +#endif /* EFSYS_OPT_QSTATS */ + efx_ev_handler_t ee_handler[1 << FSF_AZ_EV_CODE_WIDTH]; +}; + +#define EFX_EVQ_MAGIC 0x08081997 + +#define EFX_EV_TIMER_QUANTUM 5 + +struct efx_rxq_s { + uint32_t er_magic; + efx_nic_t *er_enp; + unsigned int er_index; + unsigned int er_mask; + efsys_mem_t *er_esmp; +}; + +#define EFX_RXQ_MAGIC 0x15022005 + +struct efx_txq_s { + uint32_t et_magic; + efx_nic_t *et_enp; + unsigned int et_index; + unsigned int et_mask; + efsys_mem_t *et_esmp; +#if EFSYS_OPT_QSTATS + uint32_t et_stat[TX_NQSTATS]; +#endif /* EFSYS_OPT_QSTATS */ +}; + +#define EFX_TXQ_MAGIC 0x05092005 + +#define EFX_MAC_ADDR_COPY(_dst, _src) \ + do { \ + (_dst)[0] = (_src)[0]; \ + (_dst)[1] = (_src)[1]; \ + (_dst)[2] = (_src)[2]; \ + (_dst)[3] = (_src)[3]; \ + (_dst)[4] = (_src)[4]; \ + (_dst)[5] = (_src)[5]; \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#if EFSYS_OPT_CHECK_REG +#define EFX_CHECK_REG(_enp, _reg) \ + do { \ + const char __cs *name = #_reg; \ + char min = name[4]; \ + char max = name[5]; \ + char rev; \ + \ + switch ((_enp)->en_family) { \ + case EFX_FAMILY_FALCON: \ + rev = 'B'; \ + break; \ + \ + case EFX_FAMILY_SIENA: \ + rev = 'C'; \ + break; \ + \ + default: \ + rev = '?'; \ + break; \ + } \ + \ + EFSYS_ASSERT3S(rev, >=, min); \ + EFSYS_ASSERT3S(rev, <=, max); \ + \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) +#else +#define EFX_CHECK_REG(_enp, _reg) do { \ + _NOTE(CONSTANTCONDITION) \ + } while(B_FALSE) +#endif + +#define EFX_BAR_READD(_enp, _reg, _edp, _lock) \ + do { \ + EFX_CHECK_REG((_enp), (_reg)); \ + EFSYS_BAR_READD((_enp)->en_esbp, _reg ## _OFST, \ + (_edp), (_lock)); \ + EFSYS_PROBE3(efx_bar_readd, const char *, #_reg, \ + uint32_t, _reg ## _OFST, \ + uint32_t, (_edp)->ed_u32[0]); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFX_BAR_WRITED(_enp, _reg, _edp, _lock) \ + do { \ + EFX_CHECK_REG((_enp), (_reg)); \ + EFSYS_PROBE3(efx_bar_writed, const char *, #_reg, \ + uint32_t, _reg ## _OFST, \ + uint32_t, (_edp)->ed_u32[0]); \ + EFSYS_BAR_WRITED((_enp)->en_esbp, _reg ## _OFST, \ + (_edp), (_lock)); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFX_BAR_READQ(_enp, _reg, _eqp) \ + do { \ + EFX_CHECK_REG((_enp), (_reg)); \ + EFSYS_BAR_READQ((_enp)->en_esbp, _reg ## _OFST, \ + (_eqp)); \ + EFSYS_PROBE4(efx_bar_readq, const char *, #_reg, \ + uint32_t, _reg ## _OFST, \ + uint32_t, (_eqp)->eq_u32[1], \ + uint32_t, (_eqp)->eq_u32[0]); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFX_BAR_WRITEQ(_enp, _reg, _eqp) \ + do { \ + EFX_CHECK_REG((_enp), (_reg)); \ + EFSYS_PROBE4(efx_bar_writeq, const char *, #_reg, \ + uint32_t, _reg ## _OFST, \ + uint32_t, (_eqp)->eq_u32[1], \ + uint32_t, (_eqp)->eq_u32[0]); \ + EFSYS_BAR_WRITEQ((_enp)->en_esbp, _reg ## _OFST, \ + (_eqp)); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFX_BAR_READO(_enp, _reg, _eop) \ + do { \ + EFX_CHECK_REG((_enp), (_reg)); \ + EFSYS_BAR_READO((_enp)->en_esbp, _reg ## _OFST, \ + (_eop), B_TRUE); \ + EFSYS_PROBE6(efx_bar_reado, const char *, #_reg, \ + uint32_t, _reg ## _OFST, \ + uint32_t, (_eop)->eo_u32[3], \ + uint32_t, (_eop)->eo_u32[2], \ + uint32_t, (_eop)->eo_u32[1], \ + uint32_t, (_eop)->eo_u32[0]); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFX_BAR_WRITEO(_enp, _reg, _eop) \ + do { \ + EFX_CHECK_REG((_enp), (_reg)); \ + EFSYS_PROBE6(efx_bar_writeo, const char *, #_reg, \ + uint32_t, _reg ## _OFST, \ + uint32_t, (_eop)->eo_u32[3], \ + uint32_t, (_eop)->eo_u32[2], \ + uint32_t, (_eop)->eo_u32[1], \ + uint32_t, (_eop)->eo_u32[0]); \ + EFSYS_BAR_WRITEO((_enp)->en_esbp, _reg ## _OFST, \ + (_eop), B_TRUE); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFX_BAR_TBL_READD(_enp, _reg, _index, _edp, _lock) \ + do { \ + EFX_CHECK_REG((_enp), (_reg)); \ + EFSYS_BAR_READD((_enp)->en_esbp, \ + (_reg ## _OFST + ((_index) * _reg ## _STEP)), \ + (_edp), (_lock)); \ + EFSYS_PROBE4(efx_bar_tbl_readd, const char *, #_reg, \ + uint32_t, (_index), \ + uint32_t, _reg ## _OFST, \ + uint32_t, (_edp)->ed_u32[0]); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFX_BAR_TBL_WRITED(_enp, _reg, _index, _edp, _lock) \ + do { \ + EFX_CHECK_REG((_enp), (_reg)); \ + EFSYS_PROBE4(efx_bar_tbl_writed, const char *, #_reg, \ + uint32_t, (_index), \ + uint32_t, _reg ## _OFST, \ + uint32_t, (_edp)->ed_u32[0]); \ + EFSYS_BAR_WRITED((_enp)->en_esbp, \ + (_reg ## _OFST + ((_index) * _reg ## _STEP)), \ + (_edp), (_lock)); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFX_BAR_TBL_WRITED3(_enp, _reg, _index, _edp, _lock) \ + do { \ + EFX_CHECK_REG((_enp), (_reg)); \ + EFSYS_PROBE4(efx_bar_tbl_writed, const char *, #_reg, \ + uint32_t, (_index), \ + uint32_t, _reg ## _OFST, \ + uint32_t, (_edp)->ed_u32[0]); \ + EFSYS_BAR_WRITED((_enp)->en_esbp, \ + (_reg ## _OFST + \ + (3 * sizeof (efx_dword_t)) + \ + ((_index) * _reg ## _STEP)), \ + (_edp), (_lock)); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFX_BAR_TBL_READQ(_enp, _reg, _index, _eqp) \ + do { \ + EFX_CHECK_REG((_enp), (_reg)); \ + EFSYS_BAR_READQ((_enp)->en_esbp, \ + (_reg ## _OFST + ((_index) * _reg ## _STEP)), \ + (_eqp)); \ + EFSYS_PROBE5(efx_bar_tbl_readq, const char *, #_reg, \ + uint32_t, (_index), \ + uint32_t, _reg ## _OFST, \ + uint32_t, (_eqp)->eq_u32[1], \ + uint32_t, (_eqp)->eq_u32[0]); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFX_BAR_TBL_WRITEQ(_enp, _reg, _index, _eqp) \ + do { \ + EFX_CHECK_REG((_enp), (_reg)); \ + EFSYS_PROBE5(efx_bar_tbl_writeq, const char *, #_reg, \ + uint32_t, (_index), \ + uint32_t, _reg ## _OFST, \ + uint32_t, (_eqp)->eq_u32[1], \ + uint32_t, (_eqp)->eq_u32[0]); \ + EFSYS_BAR_WRITEQ((_enp)->en_esbp, \ + (_reg ## _OFST + ((_index) * _reg ## _STEP)), \ + (_eqp)); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFX_BAR_TBL_READO(_enp, _reg, _index, _eop) \ + do { \ + EFX_CHECK_REG((_enp), (_reg)); \ + EFSYS_BAR_READO((_enp)->en_esbp, \ + (_reg ## _OFST + ((_index) * _reg ## _STEP)), \ + (_eop), B_TRUE); \ + EFSYS_PROBE7(efx_bar_tbl_reado, const char *, #_reg, \ + uint32_t, (_index), \ + uint32_t, _reg ## _OFST, \ + uint32_t, (_eop)->eo_u32[3], \ + uint32_t, (_eop)->eo_u32[2], \ + uint32_t, (_eop)->eo_u32[1], \ + uint32_t, (_eop)->eo_u32[0]); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFX_BAR_TBL_WRITEO(_enp, _reg, _index, _eop) \ + do { \ + EFX_CHECK_REG((_enp), (_reg)); \ + EFSYS_PROBE7(efx_bar_tbl_writeo, const char *, #_reg, \ + uint32_t, (_index), \ + uint32_t, _reg ## _OFST, \ + uint32_t, (_eop)->eo_u32[3], \ + uint32_t, (_eop)->eo_u32[2], \ + uint32_t, (_eop)->eo_u32[1], \ + uint32_t, (_eop)->eo_u32[0]); \ + EFSYS_BAR_WRITEO((_enp)->en_esbp, \ + (_reg ## _OFST + ((_index) * _reg ## _STEP)), \ + (_eop), B_TRUE); \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +extern __checkReturn int +efx_mac_select( + __in efx_nic_t *enp); + +extern __checkReturn int +efx_phy_probe( + __in efx_nic_t *enp); + +extern void +efx_phy_unprobe( + __in efx_nic_t *enp); + +#if EFSYS_OPT_VPD + +/* VPD utility functions */ + +extern __checkReturn int +efx_vpd_hunk_length( + __in_bcount(size) caddr_t data, + __in size_t size, + __out size_t *lengthp); + +extern __checkReturn int +efx_vpd_hunk_verify( + __in_bcount(size) caddr_t data, + __in size_t size, + __out_opt boolean_t *cksummedp); + +extern __checkReturn int +efx_vpd_hunk_reinit( + __in caddr_t data, + __in size_t size, + __in boolean_t wantpid); + +extern __checkReturn int +efx_vpd_hunk_get( + __in_bcount(size) caddr_t data, + __in size_t size, + __in efx_vpd_tag_t tag, + __in efx_vpd_keyword_t keyword, + __out unsigned int *payloadp, + __out uint8_t *paylenp); + +extern __checkReturn int +efx_vpd_hunk_next( + __in_bcount(size) caddr_t data, + __in size_t size, + __out efx_vpd_tag_t *tagp, + __out efx_vpd_keyword_t *keyword, + __out_bcount_opt(*paylenp) unsigned int *payloadp, + __out_opt uint8_t *paylenp, + __inout unsigned int *contp); + +extern __checkReturn int +efx_vpd_hunk_set( + __in_bcount(size) caddr_t data, + __in size_t size, + __in efx_vpd_value_t *evvp); + +#endif /* EFSYS_OPT_VPD */ + +#if EFSYS_OPT_DIAG + +extern efx_sram_pattern_fn_t __cs __efx_sram_pattern_fns[]; + +typedef struct efx_register_set_s { + unsigned int address; + unsigned int step; + unsigned int rows; + efx_oword_t mask; +} efx_register_set_t; + +extern __checkReturn int +efx_nic_test_registers( + __in efx_nic_t *enp, + __in efx_register_set_t *rsp, + __in size_t count); + +extern __checkReturn int +efx_nic_test_tables( + __in efx_nic_t *enp, + __in efx_register_set_t *rsp, + __in efx_pattern_type_t pattern, + __in size_t count); + +#endif /* EFSYS_OPT_DIAG */ + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_EFX_IMPL_H */ diff --git a/sys/dev/sfxge/common/efx_intr.c b/sys/dev/sfxge/common/efx_intr.c new file mode 100644 index 000000000000..77780b1c8b5c --- /dev/null +++ b/sys/dev/sfxge/common/efx_intr.c @@ -0,0 +1,354 @@ +/*- + * Copyright 2007-2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "efsys.h" +#include "efx.h" +#include "efx_types.h" +#include "efx_regs.h" +#include "efx_impl.h" + + __checkReturn int +efx_intr_init( + __in efx_nic_t *enp, + __in efx_intr_type_t type, + __in efsys_mem_t *esmp) +{ + efx_intr_t *eip = &(enp->en_intr); + efx_oword_t oword; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); + + if (enp->en_mod_flags & EFX_MOD_INTR) { + rc = EINVAL; + goto fail1; + } + + enp->en_mod_flags |= EFX_MOD_INTR; + + eip->ei_type = type; + eip->ei_esmp = esmp; + + /* + * bug17213 workaround. + * + * Under legacy interrupts, don't share a level between fatal + * interrupts and event queue interrupts. Under MSI-X, they + * must share, or we won't get an interrupt. + */ + if (enp->en_family == EFX_FAMILY_SIENA && + eip->ei_type == EFX_INTR_LINE) + eip->ei_level = 0x1f; + else + eip->ei_level = 0; + + /* Enable all the genuinely fatal interrupts */ + EFX_SET_OWORD(oword); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_ILL_ADR_INT_KER_EN, 0); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_RBUF_OWN_INT_KER_EN, 0); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_TBUF_OWN_INT_KER_EN, 0); + if (enp->en_family >= EFX_FAMILY_SIENA) + EFX_SET_OWORD_FIELD(oword, FRF_CZ_SRAM_PERR_INT_P_KER_EN, 0); + EFX_BAR_WRITEO(enp, FR_AZ_FATAL_INTR_REG_KER, &oword); + + /* Set up the interrupt address register */ + EFX_POPULATE_OWORD_3(oword, + FRF_AZ_NORM_INT_VEC_DIS_KER, (type == EFX_INTR_MESSAGE) ? 1 : 0, + FRF_AZ_INT_ADR_KER_DW0, EFSYS_MEM_ADDR(esmp) & 0xffffffff, + FRF_AZ_INT_ADR_KER_DW1, EFSYS_MEM_ADDR(esmp) >> 32); + EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword); + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + void +efx_intr_enable( + __in efx_nic_t *enp) +{ + efx_intr_t *eip = &(enp->en_intr); + efx_oword_t oword; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); + + EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword); + + EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 1); + EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword); +} + + void +efx_intr_disable( + __in efx_nic_t *enp) +{ + efx_oword_t oword; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); + + EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0); + EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword); + + EFSYS_SPIN(10); +} + + void +efx_intr_disable_unlocked( + __in efx_nic_t *enp) +{ + efx_oword_t oword; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); + + EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST, + &oword, B_FALSE); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0); + EFSYS_BAR_WRITEO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST, + &oword, B_FALSE); +} + + __checkReturn int +efx_intr_trigger( + __in efx_nic_t *enp, + __in unsigned int level) +{ + efx_intr_t *eip = &(enp->en_intr); + efx_oword_t oword; + unsigned int count; + uint32_t sel; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); + + /* bug16757: No event queues can be initialized */ + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV)); + + switch (enp->en_family) { + case EFX_FAMILY_FALCON: + if (level > EFX_NINTR_FALCON) { + rc = EINVAL; + goto fail1; + } + break; + + case EFX_FAMILY_SIENA: + if (level > EFX_NINTR_SIENA) { + rc = EINVAL; + goto fail1; + } + break; + + default: + EFSYS_ASSERT(B_FALSE); + break; + } + + if (level > EFX_MASK32(FRF_AZ_KER_INT_LEVE_SEL)) + return (ENOTSUP); /* avoid EFSYS_PROBE() */ + + sel = level; + + /* Trigger a test interrupt */ + EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, sel); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER, 1); + EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword); + + /* + * Wait up to 100ms for the interrupt to be raised before restoring + * KER_INT_LEVE_SEL. Ignore a failure to raise (the caller will + * observe this soon enough anyway), but always reset KER_INT_LEVE_SEL + */ + count = 0; + do { + EFSYS_SPIN(100); /* 100us */ + + EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword); + } while (EFX_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER) && ++count < 1000); + + EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level); + EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword); + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +static __checkReturn boolean_t +efx_intr_check_fatal( + __in efx_nic_t *enp) +{ + efx_intr_t *eip = &(enp->en_intr); + efsys_mem_t *esmp = eip->ei_esmp; + efx_oword_t oword; + + /* Read the syndrome */ + EFSYS_MEM_READO(esmp, 0, &oword); + + if (EFX_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT) != 0) { + EFSYS_PROBE(fatal); + + /* Clear the fatal interrupt condition */ + EFX_SET_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT, 0); + EFSYS_MEM_WRITEO(esmp, 0, &oword); + + return (B_TRUE); + } + + return (B_FALSE); +} + + void +efx_intr_status_line( + __in efx_nic_t *enp, + __out boolean_t *fatalp, + __out uint32_t *qmaskp) +{ + efx_intr_t *eip = &(enp->en_intr); + efx_dword_t dword; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); + + /* + * Read the queue mask and implicitly acknowledge the + * interrupt. + */ + EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE); + *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0); + + EFSYS_PROBE1(qmask, uint32_t, *qmaskp); + + if (*qmaskp & (1U << eip->ei_level)) + *fatalp = efx_intr_check_fatal(enp); + else + *fatalp = B_FALSE; +} + + void +efx_intr_status_message( + __in efx_nic_t *enp, + __in unsigned int message, + __out boolean_t *fatalp) +{ + efx_intr_t *eip = &(enp->en_intr); + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); + + if (message == eip->ei_level) + *fatalp = efx_intr_check_fatal(enp); + else + *fatalp = B_FALSE; +} + + void +efx_intr_fatal( + __in efx_nic_t *enp) +{ +#if EFSYS_OPT_DECODE_INTR_FATAL + efx_oword_t fatal; + efx_oword_t mem_per; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); + + EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal); + EFX_ZERO_OWORD(mem_per); + + if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0 || + EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0) + EFX_BAR_READO(enp, FR_AZ_MEM_STAT_REG, &mem_per); + + if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRAM_OOB_INT_KER) != 0) + EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_OOB, 0, 0); + + if (EFX_OWORD_FIELD(fatal, FRF_AZ_BUFID_DC_OOB_INT_KER) != 0) + EFSYS_ERR(enp->en_esip, EFX_ERR_BUFID_DC_OOB, 0, 0); + + if (EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0) + EFSYS_ERR(enp->en_esip, EFX_ERR_MEM_PERR, + EFX_OWORD_FIELD(mem_per, EFX_DWORD_0), + EFX_OWORD_FIELD(mem_per, EFX_DWORD_1)); + + if (EFX_OWORD_FIELD(fatal, FRF_AZ_RBUF_OWN_INT_KER) != 0) + EFSYS_ERR(enp->en_esip, EFX_ERR_RBUF_OWN, 0, 0); + + if (EFX_OWORD_FIELD(fatal, FRF_AZ_TBUF_OWN_INT_KER) != 0) + EFSYS_ERR(enp->en_esip, EFX_ERR_TBUF_OWN, 0, 0); + + if (EFX_OWORD_FIELD(fatal, FRF_AZ_RDESCQ_OWN_INT_KER) != 0) + EFSYS_ERR(enp->en_esip, EFX_ERR_RDESQ_OWN, 0, 0); + + if (EFX_OWORD_FIELD(fatal, FRF_AZ_TDESCQ_OWN_INT_KER) != 0) + EFSYS_ERR(enp->en_esip, EFX_ERR_TDESQ_OWN, 0, 0); + + if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVQ_OWN_INT_KER) != 0) + EFSYS_ERR(enp->en_esip, EFX_ERR_EVQ_OWN, 0, 0); + + if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVF_OFLO_INT_KER) != 0) + EFSYS_ERR(enp->en_esip, EFX_ERR_EVFF_OFLO, 0, 0); + + if (EFX_OWORD_FIELD(fatal, FRF_AZ_ILL_ADR_INT_KER) != 0) + EFSYS_ERR(enp->en_esip, EFX_ERR_ILL_ADDR, 0, 0); + + if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0) + EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_PERR, + EFX_OWORD_FIELD(mem_per, EFX_DWORD_0), + EFX_OWORD_FIELD(mem_per, EFX_DWORD_1)); +#else + EFSYS_ASSERT(0); +#endif +} + + void +efx_intr_fini( + __in efx_nic_t *enp) +{ + efx_oword_t oword; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); + + /* Clear the interrupt address register */ + EFX_ZERO_OWORD(oword); + EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword); + + enp->en_mod_flags &= ~EFX_MOD_INTR; +} diff --git a/sys/dev/sfxge/common/efx_mac.c b/sys/dev/sfxge/common/efx_mac.c new file mode 100644 index 000000000000..685258467d62 --- /dev/null +++ b/sys/dev/sfxge/common/efx_mac.c @@ -0,0 +1,684 @@ +/*- + * Copyright 2007-2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "efsys.h" +#include "efx.h" +#include "efx_types.h" +#include "efx_impl.h" + +#if EFSYS_OPT_MAC_FALCON_GMAC +#include "falcon_gmac.h" +#endif + +#if EFSYS_OPT_MAC_FALCON_XMAC +#include "falcon_xmac.h" +#endif + +#if EFSYS_OPT_MAC_FALCON_GMAC +static efx_mac_ops_t __cs __efx_falcon_gmac_ops = { + falcon_gmac_reset, /* emo_reset */ + falcon_mac_poll, /* emo_poll */ + falcon_mac_up, /* emo_up */ + falcon_gmac_reconfigure, /* emo_reconfigure */ +#if EFSYS_OPT_LOOPBACK + falcon_mac_loopback_set, /* emo_loopback_set */ +#endif /* EFSYS_OPT_LOOPBACK */ +#if EFSYS_OPT_MAC_STATS + falcon_mac_stats_upload, /* emo_stats_upload */ + NULL, /* emo_stats_periodic */ + falcon_gmac_stats_update /* emo_stats_update */ +#endif /* EFSYS_OPT_MAC_STATS */ +}; +#endif /* EFSYS_OPT_MAC_FALCON_GMAC */ + +#if EFSYS_OPT_MAC_FALCON_XMAC +static efx_mac_ops_t __cs __efx_falcon_xmac_ops = { + falcon_xmac_reset, /* emo_reset */ + falcon_mac_poll, /* emo_poll */ + falcon_mac_up, /* emo_up */ + falcon_xmac_reconfigure, /* emo_reconfigure */ +#if EFSYS_OPT_LOOPBACK + falcon_mac_loopback_set, /* emo_loopback_set */ +#endif /* EFSYS_OPT_LOOPBACK */ +#if EFSYS_OPT_MAC_STATS + falcon_mac_stats_upload, /* emo_stats_upload */ + NULL, /* emo_stats_periodic */ + falcon_xmac_stats_update /* emo_stats_update */ +#endif /* EFSYS_OPT_MAC_STATS */ +}; +#endif /* EFSYS_OPT_MAC_FALCON_XMAC */ + +#if EFSYS_OPT_SIENA +static efx_mac_ops_t __cs __efx_siena_mac_ops = { + NULL, /* emo_reset */ + siena_mac_poll, /* emo_poll */ + siena_mac_up, /* emo_up */ + siena_mac_reconfigure, /* emo_reconfigure */ +#if EFSYS_OPT_LOOPBACK + siena_mac_loopback_set, /* emo_loopback_set */ +#endif /* EFSYS_OPT_LOOPBACK */ +#if EFSYS_OPT_MAC_STATS + siena_mac_stats_upload, /* emo_stats_upload */ + siena_mac_stats_periodic, /* emo_stats_periodic */ + siena_mac_stats_update /* emo_stats_update */ +#endif /* EFSYS_OPT_MAC_STATS */ +}; +#endif /* EFSYS_OPT_SIENA */ + +static efx_mac_ops_t __cs * __cs __efx_mac_ops[] = { + NULL, +#if EFSYS_OPT_MAC_FALCON_GMAC + &__efx_falcon_gmac_ops, +#else + NULL, +#endif /* EFSYS_OPT_MAC_FALCON_GMAC */ +#if EFSYS_OPT_MAC_FALCON_XMAC + &__efx_falcon_xmac_ops, +#else + NULL, +#endif /* EFSYS_OPT_MAC_FALCON_XMAC */ +#if EFSYS_OPT_SIENA + &__efx_siena_mac_ops, +#else + NULL, +#endif /* EFSYS_OPT_SIENA */ +}; + + __checkReturn int +efx_mac_pdu_set( + __in efx_nic_t *enp, + __in size_t pdu) +{ + efx_port_t *epp = &(enp->en_port); + efx_mac_ops_t *emop = epp->ep_emop; + uint32_t old_pdu; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + EFSYS_ASSERT(emop != NULL); + + if (pdu < EFX_MAC_PDU_MIN) { + rc = EINVAL; + goto fail1; + } + + if (pdu > EFX_MAC_PDU_MAX) { + rc = EINVAL; + goto fail2; + } + + old_pdu = epp->ep_mac_pdu; + epp->ep_mac_pdu = (uint32_t)pdu; + if ((rc = emop->emo_reconfigure(enp)) != 0) + goto fail3; + + return (0); + +fail3: + EFSYS_PROBE(fail3); + + epp->ep_mac_pdu = old_pdu; + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_mac_addr_set( + __in efx_nic_t *enp, + __in uint8_t *addr) +{ + efx_port_t *epp = &(enp->en_port); + efx_mac_ops_t *emop = epp->ep_emop; + uint8_t old_addr[6]; + uint32_t oui; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + if (addr[0] & 0x01) { + rc = EINVAL; + goto fail1; + } + + oui = addr[0] << 16 | addr[1] << 8 | addr[2]; + if (oui == 0x000000) { + rc = EINVAL; + goto fail2; + } + + EFX_MAC_ADDR_COPY(old_addr, epp->ep_mac_addr); + EFX_MAC_ADDR_COPY(epp->ep_mac_addr, addr); + if ((rc = emop->emo_reconfigure(enp)) != 0) + goto fail3; + + return (0); + +fail3: + EFSYS_PROBE(fail3); + + EFX_MAC_ADDR_COPY(epp->ep_mac_addr, old_addr); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_mac_filter_set( + __in efx_nic_t *enp, + __in boolean_t unicst, + __in boolean_t brdcst) +{ + efx_port_t *epp = &(enp->en_port); + efx_mac_ops_t *emop = epp->ep_emop; + boolean_t old_unicst; + boolean_t old_brdcst; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + old_unicst = unicst; + old_brdcst = brdcst; + + epp->ep_unicst = unicst; + epp->ep_brdcst = brdcst; + + if ((rc = emop->emo_reconfigure(enp)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + epp->ep_unicst = old_unicst; + epp->ep_brdcst = old_brdcst; + + return (rc); +} + + __checkReturn int +efx_mac_drain( + __in efx_nic_t *enp, + __in boolean_t enabled) +{ + efx_port_t *epp = &(enp->en_port); + efx_mac_ops_t *emop = epp->ep_emop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + EFSYS_ASSERT(emop != NULL); + + if (epp->ep_mac_drain == enabled) + return (0); + + epp->ep_mac_drain = enabled; + + if (enabled && emop->emo_reset != NULL) { + if ((rc = emop->emo_reset(enp)) != 0) + goto fail1; + + EFSYS_ASSERT(enp->en_reset_flags & EFX_RESET_MAC); + enp->en_reset_flags &= ~EFX_RESET_PHY; + } + + if ((rc = emop->emo_reconfigure(enp)) != 0) + goto fail2; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_mac_up( + __in efx_nic_t *enp, + __out boolean_t *mac_upp) +{ + efx_port_t *epp = &(enp->en_port); + efx_mac_ops_t *emop = epp->ep_emop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + if ((rc = emop->emo_up(enp, mac_upp)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_mac_fcntl_set( + __in efx_nic_t *enp, + __in unsigned int fcntl, + __in boolean_t autoneg) +{ + efx_port_t *epp = &(enp->en_port); + efx_mac_ops_t *emop = epp->ep_emop; + efx_phy_ops_t *epop = epp->ep_epop; + unsigned int old_fcntl; + boolean_t old_autoneg; + unsigned int old_adv_cap; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + if ((fcntl & ~(EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE)) != 0) { + rc = EINVAL; + goto fail1; + } + + /* + * Ignore a request to set flow control autonegotiation + * if the PHY doesn't support it. + */ + if (~epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN)) + autoneg = B_FALSE; + + old_fcntl = epp->ep_fcntl; + old_autoneg = autoneg; + old_adv_cap = epp->ep_adv_cap_mask; + + epp->ep_fcntl = fcntl; + epp->ep_fcntl_autoneg = autoneg; + + /* + * If the PHY supports autonegotiation, then encode the flow control + * settings in the advertised capabilities, and restart AN. Otherwise, + * just push the new settings directly to the MAC. + */ + if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN)) { + if (fcntl & EFX_FCNTL_RESPOND) + epp->ep_adv_cap_mask |= (1 << EFX_PHY_CAP_PAUSE | + 1 << EFX_PHY_CAP_ASYM); + else + epp->ep_adv_cap_mask &= ~(1 << EFX_PHY_CAP_PAUSE | + 1 << EFX_PHY_CAP_ASYM); + + if (fcntl & EFX_FCNTL_GENERATE) + epp->ep_adv_cap_mask ^= (1 << EFX_PHY_CAP_ASYM); + + if ((rc = epop->epo_reconfigure(enp)) != 0) + goto fail2; + + } else { + if ((rc = emop->emo_reconfigure(enp)) != 0) + goto fail2; + } + + return (0); + +fail2: + EFSYS_PROBE(fail2); + + epp->ep_fcntl = old_fcntl; + epp->ep_fcntl_autoneg = old_autoneg; + epp->ep_adv_cap_mask = old_adv_cap; + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + void +efx_mac_fcntl_get( + __in efx_nic_t *enp, + __out unsigned int *fcntl_wantedp, + __out unsigned int *fcntl_linkp) +{ + efx_port_t *epp = &(enp->en_port); + unsigned int wanted; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + /* + * If the PHY supports auto negotiation, then the requested flow + * control settings are encoded in the advertised capabilities. + */ + if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN)) { + wanted = 0; + + if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE)) + wanted = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE; + if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_ASYM)) + wanted ^= EFX_FCNTL_GENERATE; + } else + wanted = epp->ep_fcntl; + + *fcntl_linkp = epp->ep_fcntl; + *fcntl_wantedp = wanted; +} + + __checkReturn int +efx_mac_hash_set( + __in efx_nic_t *enp, + __in_ecount(EFX_MAC_HASH_BITS) unsigned int const *bucket) +{ + efx_port_t *epp = &(enp->en_port); + efx_mac_ops_t *emop = epp->ep_emop; + efx_oword_t old_hash[2]; + unsigned int index; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + memcpy(old_hash, epp->ep_multicst_hash, sizeof (old_hash)); + + /* Set the lower 128 bits of the hash */ + EFX_ZERO_OWORD(epp->ep_multicst_hash[0]); + for (index = 0; index < 128; index++) { + if (bucket[index] != 0) + EFX_SET_OWORD_BIT(epp->ep_multicst_hash[0], index); + } + + /* Set the upper 128 bits of the hash */ + EFX_ZERO_OWORD(epp->ep_multicst_hash[1]); + for (index = 0; index < 128; index++) { + if (bucket[index + 128] != 0) + EFX_SET_OWORD_BIT(epp->ep_multicst_hash[1], index); + } + + if ((rc = emop->emo_reconfigure(enp)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + memcpy(epp->ep_multicst_hash, old_hash, sizeof (old_hash)); + + return (rc); +} + +#if EFSYS_OPT_MAC_STATS + +#if EFSYS_OPT_NAMES + +/* START MKCONFIG GENERATED EfxMacStatNamesBlock adf707adba80813e */ +static const char __cs * __cs __efx_mac_stat_name[] = { + "rx_octets", + "rx_pkts", + "rx_unicst_pkts", + "rx_multicst_pkts", + "rx_brdcst_pkts", + "rx_pause_pkts", + "rx_le_64_pkts", + "rx_65_to_127_pkts", + "rx_128_to_255_pkts", + "rx_256_to_511_pkts", + "rx_512_to_1023_pkts", + "rx_1024_to_15xx_pkts", + "rx_ge_15xx_pkts", + "rx_errors", + "rx_fcs_errors", + "rx_drop_events", + "rx_false_carrier_errors", + "rx_symbol_errors", + "rx_align_errors", + "rx_internal_errors", + "rx_jabber_pkts", + "rx_lane0_char_err", + "rx_lane1_char_err", + "rx_lane2_char_err", + "rx_lane3_char_err", + "rx_lane0_disp_err", + "rx_lane1_disp_err", + "rx_lane2_disp_err", + "rx_lane3_disp_err", + "rx_match_fault", + "rx_nodesc_drop_cnt", + "tx_octets", + "tx_pkts", + "tx_unicst_pkts", + "tx_multicst_pkts", + "tx_brdcst_pkts", + "tx_pause_pkts", + "tx_le_64_pkts", + "tx_65_to_127_pkts", + "tx_128_to_255_pkts", + "tx_256_to_511_pkts", + "tx_512_to_1023_pkts", + "tx_1024_to_15xx_pkts", + "tx_ge_15xx_pkts", + "tx_errors", + "tx_sgl_col_pkts", + "tx_mult_col_pkts", + "tx_ex_col_pkts", + "tx_late_col_pkts", + "tx_def_pkts", + "tx_ex_def_pkts", +}; +/* END MKCONFIG GENERATED EfxMacStatNamesBlock */ + + __checkReturn const char __cs * +efx_mac_stat_name( + __in efx_nic_t *enp, + __in unsigned int id) +{ + _NOTE(ARGUNUSED(enp)) + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + + EFSYS_ASSERT3U(id, <, EFX_MAC_NSTATS); + return (__efx_mac_stat_name[id]); +} + +#endif /* EFSYS_OPT_STAT_NAME */ + + __checkReturn int +efx_mac_stats_upload( + __in efx_nic_t *enp, + __in efsys_mem_t *esmp) +{ + efx_port_t *epp = &(enp->en_port); + efx_mac_ops_t *emop = epp->ep_emop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + EFSYS_ASSERT(emop != NULL); + + /* + * Don't assert !ep_mac_stats_pending, because the client might + * have failed to finalise statistics when previously stopping + * the port. + */ + if ((rc = emop->emo_stats_upload(enp, esmp)) != 0) + goto fail1; + + epp->ep_mac_stats_pending = B_TRUE; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_mac_stats_periodic( + __in efx_nic_t *enp, + __in efsys_mem_t *esmp, + __in uint16_t period_ms, + __in boolean_t events) +{ + efx_port_t *epp = &(enp->en_port); + efx_mac_ops_t *emop = epp->ep_emop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + EFSYS_ASSERT(emop != NULL); + + if (emop->emo_stats_periodic == NULL) { + rc = EINVAL; + goto fail1; + } + + if ((rc = emop->emo_stats_periodic(enp, esmp, period_ms, events)) != 0) + goto fail2; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + + __checkReturn int +efx_mac_stats_update( + __in efx_nic_t *enp, + __in efsys_mem_t *esmp, + __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *essp, + __in uint32_t *generationp) +{ + efx_port_t *epp = &(enp->en_port); + efx_mac_ops_t *emop = epp->ep_emop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + EFSYS_ASSERT(emop != NULL); + + rc = emop->emo_stats_update(enp, esmp, essp, generationp); + if (rc == 0) + epp->ep_mac_stats_pending = B_FALSE; + + return (rc); +} + +#endif /* EFSYS_OPT_MAC_STATS */ + + __checkReturn int +efx_mac_select( + __in efx_nic_t *enp) +{ + efx_port_t *epp = &(enp->en_port); + efx_mac_type_t type = EFX_MAC_INVALID; + efx_mac_ops_t *emop; + int rc = EINVAL; + +#if EFSYS_OPT_SIENA + if (enp->en_family == EFX_FAMILY_SIENA) { + type = EFX_MAC_SIENA; + goto chosen; + } +#endif + +#if EFSYS_OPT_FALCON + switch (epp->ep_link_mode) { +#if EFSYS_OPT_MAC_FALCON_GMAC + case EFX_LINK_100HDX: + case EFX_LINK_100FDX: + case EFX_LINK_1000HDX: + case EFX_LINK_1000FDX: + type = EFX_MAC_FALCON_GMAC; + goto chosen; +#endif /* EFSYS_OPT_FALCON_GMAC */ + +#if EFSYS_OPT_MAC_FALCON_XMAC + case EFX_LINK_10000FDX: + type = EFX_MAC_FALCON_XMAC; + goto chosen; +#endif /* EFSYS_OPT_FALCON_XMAC */ + + default: +#if EFSYS_OPT_MAC_FALCON_GMAC && EFSYS_OPT_MAC_FALCON_XMAC + /* Only initialise a MAC supported by the PHY */ + if (epp->ep_phy_cap_mask & + ((1 << EFX_PHY_CAP_1000FDX) | + (1 << EFX_PHY_CAP_1000HDX) | + (1 << EFX_PHY_CAP_100FDX) | + (1 << EFX_PHY_CAP_100HDX) | + (1 << EFX_PHY_CAP_10FDX) | + (1 << EFX_PHY_CAP_10FDX))) + type = EFX_MAC_FALCON_GMAC; + else + type = EFX_MAC_FALCON_XMAC; +#elif EFSYS_OPT_MAC_FALCON_GMAC + type = EFX_MAC_FALCON_GMAC; +#else + type = EFX_MAC_FALCON_XMAC; +#endif + goto chosen; + } +#endif /* EFSYS_OPT_FALCON */ + +chosen: + EFSYS_ASSERT(type != EFX_MAC_INVALID); + EFSYS_ASSERT3U(type, <, EFX_MAC_NTYPES); + emop = epp->ep_emop = (efx_mac_ops_t *)__efx_mac_ops[type]; + EFSYS_ASSERT(emop != NULL); + + epp->ep_mac_type = type; + + if (emop->emo_reset != NULL) { + if ((rc = emop->emo_reset(enp)) != 0) + goto fail1; + + EFSYS_ASSERT(enp->en_reset_flags & EFX_RESET_MAC); + enp->en_reset_flags &= ~EFX_RESET_MAC; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} diff --git a/sys/dev/sfxge/common/efx_mcdi.c b/sys/dev/sfxge/common/efx_mcdi.c new file mode 100644 index 000000000000..7d01e9b0e96b --- /dev/null +++ b/sys/dev/sfxge/common/efx_mcdi.c @@ -0,0 +1,733 @@ +/*- + * Copyright 2008-2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "efsys.h" +#include "efx.h" +#include "efx_types.h" +#include "efx_regs.h" +#include "efx_regs_mcdi.h" +#include "efx_impl.h" + +#if EFSYS_OPT_MCDI + +/* Shared memory layout */ + +#define MCDI_P1_DBL_OFST 0x0 +#define MCDI_P2_DBL_OFST 0x1 +#define MCDI_P1_PDU_OFST 0x2 +#define MCDI_P2_PDU_OFST 0x42 +#define MCDI_P1_REBOOT_OFST 0x1fe +#define MCDI_P2_REBOOT_OFST 0x1ff + +/* A reboot/assertion causes the MCDI status word to be set after the + * command word is set or a REBOOT event is sent. If we notice a reboot + * via these mechanisms then wait 10ms for the status word to be set. + */ +#define MCDI_STATUS_SLEEP_US 10000 + + void +efx_mcdi_request_start( + __in efx_nic_t *enp, + __in efx_mcdi_req_t *emrp, + __in boolean_t ev_cpl) +{ + efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip); + efx_dword_t dword; + unsigned int seq; + unsigned int xflags; + unsigned int pdur; + unsigned int dbr; + unsigned int pos; + int state; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI); + EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI); + + switch (emip->emi_port) { + case 1: + pdur = MCDI_P1_PDU_OFST; + dbr = MCDI_P1_DBL_OFST; + break; + case 2: + pdur = MCDI_P2_PDU_OFST; + dbr = MCDI_P2_DBL_OFST; + break; + default: + EFSYS_ASSERT(0); + pdur = dbr = 0; + }; + + /* + * efx_mcdi_request_start() is naturally serialised against both + * efx_mcdi_request_poll() and efx_mcdi_ev_cpl()/efx_mcdi_ev_death(), + * by virtue of there only being one oustanding MCDI request. + * Unfortunately, upper layers may also call efx_mcdi_request_abort() + * at any time, to timeout a pending mcdi request, That request may + * then subsequently complete, meaning efx_mcdi_ev_cpl() or + * efx_mcdi_ev_death() may end up running in parallel with + * efx_mcdi_request_start(). This race is handled by ensuring that + * %emi_pending_req, %emi_ev_cpl and %emi_seq are protected by the + * en_eslp lock. + */ + EFSYS_LOCK(enp->en_eslp, state); + EFSYS_ASSERT(emip->emi_pending_req == NULL); + emip->emi_pending_req = emrp; + emip->emi_ev_cpl = ev_cpl; + emip->emi_poll_cnt = 0; + seq = emip->emi_seq++ & 0xf; + EFSYS_UNLOCK(enp->en_eslp, state); + + xflags = 0; + if (ev_cpl) + xflags |= MCDI_HEADER_XFLAGS_EVREQ; + + /* Construct the header in shared memory */ + EFX_POPULATE_DWORD_6(dword, + MCDI_HEADER_CODE, emrp->emr_cmd, + MCDI_HEADER_RESYNC, 1, + MCDI_HEADER_DATALEN, emrp->emr_in_length, + MCDI_HEADER_SEQ, seq, + MCDI_HEADER_RESPONSE, 0, + MCDI_HEADER_XFLAGS, xflags); + EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, pdur, &dword, B_TRUE); + + for (pos = 0; pos < emrp->emr_in_length; pos += sizeof (efx_dword_t)) { + memcpy(&dword, MCDI_IN(*emrp, efx_dword_t, pos), + MIN(sizeof (dword), emrp->emr_in_length - pos)); + EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, + pdur + 1 + (pos >> 2), &dword, B_FALSE); + } + + /* Ring the doorbell */ + EFX_POPULATE_DWORD_1(dword, EFX_DWORD_0, 0xd004be11); + EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, dbr, &dword, B_FALSE); +} + +static void +efx_mcdi_request_copyout( + __in efx_nic_t *enp, + __in efx_mcdi_req_t *emrp) +{ + efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip); + unsigned int pos; + unsigned int pdur; + efx_dword_t data; + + pdur = (emip->emi_port == 1) ? MCDI_P1_PDU_OFST : MCDI_P2_PDU_OFST; + + /* Copy payload out if caller supplied buffer */ + if (emrp->emr_out_buf != NULL) { + size_t bytes = MIN(emrp->emr_out_length_used, + emrp->emr_out_length); + for (pos = 0; pos < bytes; pos += sizeof (efx_dword_t)) { + EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, + pdur + 1 + (pos >> 2), &data, B_FALSE); + memcpy(MCDI_OUT(*emrp, efx_dword_t, pos), &data, + MIN(sizeof (data), bytes - pos)); + } + } +} + +static int +efx_mcdi_request_errcode( + __in unsigned int err) +{ + + switch (err) { + case MC_CMD_ERR_ENOENT: + return (ENOENT); + case MC_CMD_ERR_EINTR: + return (EINTR); + case MC_CMD_ERR_EACCES: + return (EACCES); + case MC_CMD_ERR_EBUSY: + return (EBUSY); + case MC_CMD_ERR_EINVAL: + return (EINVAL); + case MC_CMD_ERR_EDEADLK: + return (EDEADLK); + case MC_CMD_ERR_ENOSYS: + return (ENOTSUP); + case MC_CMD_ERR_ETIME: + return (ETIMEDOUT); +#ifdef WITH_MCDI_V2 + case MC_CMD_ERR_EAGAIN: + return (EAGAIN); + case MC_CMD_ERR_ENOSPC: + return (ENOSPC); +#endif + default: + EFSYS_PROBE1(mc_pcol_error, int, err); + return (EIO); + } +} + +static void +efx_mcdi_raise_exception( + __in efx_nic_t *enp, + __in_opt efx_mcdi_req_t *emrp, + __in int rc) +{ + efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip); + const efx_mcdi_transport_t *emtp = emip->emi_mtp; + efx_mcdi_exception_t exception; + + /* Reboot or Assertion failure only */ + EFSYS_ASSERT(rc == EIO || rc == EINTR); + + /* + * If MC_CMD_REBOOT causes a reboot (dependent on parameters), + * then the EIO is not worthy of an exception. + */ + if (emrp != NULL && emrp->emr_cmd == MC_CMD_REBOOT && rc == EIO) + return; + + exception = (rc == EIO) + ? EFX_MCDI_EXCEPTION_MC_REBOOT + : EFX_MCDI_EXCEPTION_MC_BADASSERT; + + emtp->emt_exception(emtp->emt_context, exception); +} + +static int +efx_mcdi_poll_reboot( + __in efx_nic_t *enp) +{ + efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip); + unsigned int rebootr; + efx_dword_t dword; + uint32_t value; + + EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2); + rebootr = ((emip->emi_port == 1) + ? MCDI_P1_REBOOT_OFST + : MCDI_P2_REBOOT_OFST); + + EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, rebootr, &dword, B_FALSE); + value = EFX_DWORD_FIELD(dword, EFX_DWORD_0); + + if (value == 0) + return (0); + + EFX_ZERO_DWORD(dword); + EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, rebootr, &dword, B_FALSE); + + if (value == MC_STATUS_DWORD_ASSERT) + return (EINTR); + else + return (EIO); +} + + __checkReturn boolean_t +efx_mcdi_request_poll( + __in efx_nic_t *enp) +{ + efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip); + efx_mcdi_req_t *emrp; + efx_dword_t dword; + unsigned int pdur; + unsigned int seq; + unsigned int length; + int state; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI); + EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); + EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI); + + /* Serialise against post-watchdog efx_mcdi_ev* */ + EFSYS_LOCK(enp->en_eslp, state); + + EFSYS_ASSERT(emip->emi_pending_req != NULL); + EFSYS_ASSERT(!emip->emi_ev_cpl); + emrp = emip->emi_pending_req; + + /* Check for reboot atomically w.r.t efx_mcdi_request_start */ + if (emip->emi_poll_cnt++ == 0) { + if ((rc = efx_mcdi_poll_reboot(enp)) != 0) { + emip->emi_pending_req = NULL; + EFSYS_UNLOCK(enp->en_eslp, state); + + goto fail1; + } + } + + EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2); + pdur = (emip->emi_port == 1) ? MCDI_P1_PDU_OFST : MCDI_P2_PDU_OFST; + + /* Read the command header */ + EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, pdur, &dword, B_FALSE); + if (EFX_DWORD_FIELD(dword, MCDI_HEADER_RESPONSE) == 0) { + EFSYS_UNLOCK(enp->en_eslp, state); + return (B_FALSE); + } + + /* Request complete */ + emip->emi_pending_req = NULL; + seq = (emip->emi_seq - 1) & 0xf; + + /* Check for synchronous reboot */ + if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR) != 0 && + EFX_DWORD_FIELD(dword, MCDI_HEADER_DATALEN) == 0) { + /* Consume status word */ + EFSYS_SPIN(MCDI_STATUS_SLEEP_US); + efx_mcdi_poll_reboot(enp); + EFSYS_UNLOCK(enp->en_eslp, state); + rc = EIO; + goto fail2; + } + + EFSYS_UNLOCK(enp->en_eslp, state); + + /* Check that the returned data is consistent */ + if (EFX_DWORD_FIELD(dword, MCDI_HEADER_CODE) != emrp->emr_cmd || + EFX_DWORD_FIELD(dword, MCDI_HEADER_SEQ) != seq) { + /* Response is for a different request */ + rc = EIO; + goto fail3; + } + + length = EFX_DWORD_FIELD(dword, MCDI_HEADER_DATALEN); + if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR)) { + efx_dword_t errdword; + int errcode; + + EFSYS_ASSERT3U(length, ==, 4); + EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, + pdur + 1 + (MC_CMD_ERR_CODE_OFST >> 2), + &errdword, B_FALSE); + errcode = EFX_DWORD_FIELD(errdword, EFX_DWORD_0); + rc = efx_mcdi_request_errcode(errcode); + EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd, int, errcode); + goto fail4; + + } else { + emrp->emr_out_length_used = length; + emrp->emr_rc = 0; + efx_mcdi_request_copyout(enp, emrp); + } + + goto out; + +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + /* Fill out error state */ + emrp->emr_rc = rc; + emrp->emr_out_length_used = 0; + + /* Reboot/Assertion */ + if (rc == EIO || rc == EINTR) + efx_mcdi_raise_exception(enp, emrp, rc); + +out: + return (B_TRUE); +} + + void +efx_mcdi_execute( + __in efx_nic_t *enp, + __in efx_mcdi_req_t *emrp) +{ + efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip); + const efx_mcdi_transport_t *emtp = emip->emi_mtp; + + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI); + EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); + EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI); + + emtp->emt_execute(emtp->emt_context, emrp); +} + + void +efx_mcdi_ev_cpl( + __in efx_nic_t *enp, + __in unsigned int seq, + __in unsigned int outlen, + __in int errcode) +{ + efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip); + const efx_mcdi_transport_t *emtp = emip->emi_mtp; + efx_mcdi_req_t *emrp; + int state; + + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI); + EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); + EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI); + + /* + * Serialise against efx_mcdi_request_poll()/efx_mcdi_request_start() + * when we're completing an aborted request. + */ + EFSYS_LOCK(enp->en_eslp, state); + if (emip->emi_pending_req == NULL || !emip->emi_ev_cpl || + (seq != ((emip->emi_seq - 1) & 0xf))) { + EFSYS_ASSERT(emip->emi_aborted > 0); + if (emip->emi_aborted > 0) + --emip->emi_aborted; + EFSYS_UNLOCK(enp->en_eslp, state); + return; + } + + emrp = emip->emi_pending_req; + emip->emi_pending_req = NULL; + EFSYS_UNLOCK(enp->en_eslp, state); + + /* + * Fill out the remaining hdr fields, and copyout the payload + * if the user supplied an output buffer. + */ + if (errcode != 0) { + EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd, + int, errcode); + emrp->emr_out_length_used = 0; + emrp->emr_rc = efx_mcdi_request_errcode(errcode); + } else { + emrp->emr_out_length_used = outlen; + emrp->emr_rc = 0; + efx_mcdi_request_copyout(enp, emrp); + } + + emtp->emt_ev_cpl(emtp->emt_context); +} + + void +efx_mcdi_ev_death( + __in efx_nic_t *enp, + __in int rc) +{ + efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip); + const efx_mcdi_transport_t *emtp = emip->emi_mtp; + efx_mcdi_req_t *emrp = NULL; + boolean_t ev_cpl; + int state; + + /* + * The MCDI request (if there is one) has been terminated, either + * by a BADASSERT or REBOOT event. + * + * If there is an oustanding event-completed MCDI operation, then we + * will never receive the completion event (because both MCDI + * completions and BADASSERT events are sent to the same evq). So + * complete this MCDI op. + * + * This function might run in parallel with efx_mcdi_request_poll() + * for poll completed mcdi requests, and also with + * efx_mcdi_request_start() for post-watchdog completions. + */ + EFSYS_LOCK(enp->en_eslp, state); + emrp = emip->emi_pending_req; + ev_cpl = emip->emi_ev_cpl; + if (emrp != NULL && emip->emi_ev_cpl) { + emip->emi_pending_req = NULL; + + emrp->emr_out_length_used = 0; + emrp->emr_rc = rc; + ++emip->emi_aborted; + } + + /* Since we're running in parallel with a request, consume the + * status word before dropping the lock. + */ + if (rc == EIO || rc == EINTR) { + EFSYS_SPIN(MCDI_STATUS_SLEEP_US); + (void) efx_mcdi_poll_reboot(enp); + } + + EFSYS_UNLOCK(enp->en_eslp, state); + + efx_mcdi_raise_exception(enp, emrp, rc); + + if (emrp != NULL && ev_cpl) + emtp->emt_ev_cpl(emtp->emt_context); +} + + __checkReturn int +efx_mcdi_version( + __in efx_nic_t *enp, + __out_ecount_opt(4) uint16_t versionp[4], + __out_opt uint32_t *buildp, + __out_opt efx_mcdi_boot_t *statusp) +{ + uint8_t outbuf[MAX(MC_CMD_GET_VERSION_OUT_LEN, + MC_CMD_GET_BOOT_STATUS_OUT_LEN)]; + efx_mcdi_req_t req; + efx_word_t *ver_words; + uint16_t version[4]; + uint32_t build; + efx_mcdi_boot_t status; + int rc; + + EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); + EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI); + + EFX_STATIC_ASSERT(MC_CMD_GET_VERSION_IN_LEN == 0); + req.emr_cmd = MC_CMD_GET_VERSION; + req.emr_in_buf = NULL; + req.emr_in_length = 0; + req.emr_out_buf = outbuf; + req.emr_out_length = MC_CMD_GET_VERSION_OUT_LEN; + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + /* bootrom support */ + if (req.emr_out_length_used == MC_CMD_GET_VERSION_V0_OUT_LEN) { + version[0] = version[1] = version[2] = version[3] = 0; + build = MCDI_OUT_DWORD(req, GET_VERSION_OUT_FIRMWARE); + + goto version; + } + + if (req.emr_out_length_used < MC_CMD_GET_VERSION_OUT_LEN) { + rc = EMSGSIZE; + goto fail2; + } + + ver_words = MCDI_OUT2(req, efx_word_t, GET_VERSION_OUT_VERSION); + version[0] = EFX_WORD_FIELD(ver_words[0], EFX_WORD_0); + version[1] = EFX_WORD_FIELD(ver_words[1], EFX_WORD_0); + version[2] = EFX_WORD_FIELD(ver_words[2], EFX_WORD_0); + version[3] = EFX_WORD_FIELD(ver_words[3], EFX_WORD_0); + build = MCDI_OUT_DWORD(req, GET_VERSION_OUT_FIRMWARE); + +version: + /* The bootrom doesn't understand BOOT_STATUS */ + if (build == MC_CMD_GET_VERSION_OUT_FIRMWARE_BOOTROM) { + status = EFX_MCDI_BOOT_ROM; + goto out; + } + + req.emr_cmd = MC_CMD_GET_BOOT_STATUS; + EFX_STATIC_ASSERT(MC_CMD_GET_BOOT_STATUS_IN_LEN == 0); + req.emr_in_buf = NULL; + req.emr_in_length = 0; + req.emr_out_buf = outbuf; + req.emr_out_length = MC_CMD_GET_BOOT_STATUS_OUT_LEN; + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail3; + } + + if (req.emr_out_length_used < MC_CMD_GET_BOOT_STATUS_OUT_LEN) { + rc = EMSGSIZE; + goto fail4; + } + + if (MCDI_OUT_DWORD_FIELD(req, GET_BOOT_STATUS_OUT_FLAGS, + GET_BOOT_STATUS_OUT_FLAGS_PRIMARY)) + status = EFX_MCDI_BOOT_PRIMARY; + else + status = EFX_MCDI_BOOT_SECONDARY; + +out: + if (versionp != NULL) + memcpy(versionp, version, sizeof (version)); + if (buildp != NULL) + *buildp = build; + if (statusp != NULL) + *statusp = status; + + return (0); + +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_mcdi_init( + __in efx_nic_t *enp, + __in const efx_mcdi_transport_t *mtp) +{ + efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip); + efx_oword_t oword; + unsigned int portnum; + int rc; + + EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0); + enp->en_mod_flags |= EFX_MOD_MCDI; + + if (enp->en_family == EFX_FAMILY_FALCON) + return (0); + + emip->emi_mtp = mtp; + + /* Determine the port number to use for MCDI */ + EFX_BAR_READO(enp, FR_AZ_CS_DEBUG_REG, &oword); + portnum = EFX_OWORD_FIELD(oword, FRF_CZ_CS_PORT_NUM); + + if (portnum == 0) { + /* Presumably booted from ROM; only MCDI port 1 will work */ + emip->emi_port = 1; + } else if (portnum <= 2) { + emip->emi_port = portnum; + } else { + rc = EINVAL; + goto fail1; + } + + /* + * Wipe the atomic reboot status so subsequent MCDI requests succeed. + * BOOT_STATUS is preserved so eno_nic_probe() can boot out of the + * assertion handler. + */ + (void) efx_mcdi_poll_reboot(enp); + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + enp->en_mod_flags &= ~EFX_MOD_MCDI; + + return (rc); +} + + + __checkReturn int +efx_mcdi_reboot( + __in efx_nic_t *enp) +{ + uint8_t payload[MC_CMD_REBOOT_IN_LEN]; + efx_mcdi_req_t req; + int rc; + + /* + * We could require the caller to have caused en_mod_flags=0 to + * call this function. This doesn't help the other port though, + * who's about to get the MC ripped out from underneath them. + * Since they have to cope with the subsequent fallout of MCDI + * failures, we should as well. + */ + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + + req.emr_cmd = MC_CMD_REBOOT; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_REBOOT_IN_LEN; + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + MCDI_IN_SET_DWORD(req, REBOOT_IN_FLAGS, 0); + + efx_mcdi_execute(enp, &req); + + /* Invert EIO */ + if (req.emr_rc != EIO) { + rc = EIO; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn boolean_t +efx_mcdi_request_abort( + __in efx_nic_t *enp) +{ + efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip); + efx_mcdi_req_t *emrp; + boolean_t aborted; + int state; + + EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); + EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI); + + /* + * efx_mcdi_ev_* may have already completed this event, and be + * spinning/blocked on the upper layer lock. So it *is* legitimate + * to for emi_pending_req to be NULL. If there is a pending event + * completed request, then provide a "credit" to allow + * efx_mcdi_ev_cpl() to accept a single spurious completion. + */ + EFSYS_LOCK(enp->en_eslp, state); + emrp = emip->emi_pending_req; + aborted = (emrp != NULL); + if (aborted) { + emip->emi_pending_req = NULL; + + /* Error the request */ + emrp->emr_out_length_used = 0; + emrp->emr_rc = ETIMEDOUT; + + /* Provide a credit for seqno/emr_pending_req mismatches */ + if (emip->emi_ev_cpl) + ++emip->emi_aborted; + + /* + * The upper layer has called us, so we don't + * need to complete the request. + */ + } + EFSYS_UNLOCK(enp->en_eslp, state); + + return (aborted); +} + + void +efx_mcdi_fini( + __in efx_nic_t *enp) +{ + efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip); + + EFSYS_ASSERT3U(enp->en_mod_flags, ==, EFX_MOD_MCDI); + enp->en_mod_flags &= ~EFX_MOD_MCDI; + + if (~(enp->en_features) & EFX_FEATURE_MCDI) + return; + + emip->emi_mtp = NULL; + emip->emi_port = 0; + emip->emi_aborted = 0; +} + +#endif /* EFSYS_OPT_MCDI */ diff --git a/sys/dev/sfxge/common/efx_mcdi.h b/sys/dev/sfxge/common/efx_mcdi.h new file mode 100644 index 000000000000..ef0ba908a763 --- /dev/null +++ b/sys/dev/sfxge/common/efx_mcdi.h @@ -0,0 +1,238 @@ +/*- + * Copyright 2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SYS_EFX_MCDI_H +#define _SYS_EFX_MCDI_H + +#include "efx.h" +#include "efx_regs.h" +#include "efx_regs_mcdi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Number of retries attempted for init code */ +#define EFX_MCDI_REQ_RETRY_INIT 2 + +struct efx_mcdi_req_s { + /* Inputs: Command #, input buffer and length */ + unsigned int emr_cmd; + uint8_t *emr_in_buf; + size_t emr_in_length; + /* Outputs: retcode, buffer, length, and length used*/ + int emr_rc; + uint8_t *emr_out_buf; + size_t emr_out_length; + size_t emr_out_length_used; +}; + +typedef struct efx_mcdi_iface_s { + const efx_mcdi_transport_t *emi_mtp; + unsigned int emi_port; + unsigned int emi_seq; + efx_mcdi_req_t *emi_pending_req; + boolean_t emi_ev_cpl; + int emi_aborted; + uint32_t emi_poll_cnt; +} efx_mcdi_iface_t; + +extern void +efx_mcdi_execute( + __in efx_nic_t *enp, + __in efx_mcdi_req_t *emrp); + +extern void +efx_mcdi_ev_cpl( + __in efx_nic_t *enp, + __in unsigned int seq, + __in unsigned int outlen, + __in int errcode); + +extern void +efx_mcdi_ev_death( + __in efx_nic_t *enp, + __in int rc); + +typedef enum efx_mcdi_boot_e { + EFX_MCDI_BOOT_PRIMARY, + EFX_MCDI_BOOT_SECONDARY, + EFX_MCDI_BOOT_ROM, +} efx_mcdi_boot_t; + +extern __checkReturn int +efx_mcdi_version( + __in efx_nic_t *enp, + __out_ecount_opt(4) uint16_t versionp[4], + __out_opt uint32_t *buildp, + __out_opt efx_mcdi_boot_t *statusp); + +#define MCDI_IN(_emr, _type, _ofst) \ + ((_type *)((_emr).emr_in_buf + (_ofst))) + +#define MCDI_IN2(_emr, _type, _ofst) \ + MCDI_IN(_emr, _type, MC_CMD_ ## _ofst ## _OFST) + +#define MCDI_IN_SET_BYTE(_emr, _ofst, _value) \ + EFX_POPULATE_BYTE_1(*MCDI_IN2(_emr, efx_byte_t, _ofst), \ + EFX_BYTE_0, _value) + +#define MCDI_IN_SET_DWORD(_emr, _ofst, _value) \ + EFX_POPULATE_DWORD_1(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ + EFX_DWORD_0, _value) + +#define MCDI_IN_POPULATE_DWORD_1(_emr, _ofst, _field1, _value1) \ + EFX_POPULATE_DWORD_1(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ + MC_CMD_ ## _field1, _value1) + +#define MCDI_IN_POPULATE_DWORD_2(_emr, _ofst, _field1, _value1, \ + _field2, _value2) \ + EFX_POPULATE_DWORD_2(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ + MC_CMD_ ## _field1, _value1, \ + MC_CMD_ ## _field2, _value2) + +#define MCDI_IN_POPULATE_DWORD_3(_emr, _ofst, _field1, _value1, \ + _field2, _value2, _field3, _value3) \ + EFX_POPULATE_DWORD_3(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ + MC_CMD_ ## _field1, _value1, \ + MC_CMD_ ## _field2, _value2, \ + MC_CMD_ ## _field3, _value3) + +#define MCDI_IN_POPULATE_DWORD_4(_emr, _ofst, _field1, _value1, \ + _field2, _value2, _field3, _value3, _field4, _value4) \ + EFX_POPULATE_DWORD_4(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ + MC_CMD_ ## _field1, _value1, \ + MC_CMD_ ## _field2, _value2, \ + MC_CMD_ ## _field3, _value3, \ + MC_CMD_ ## _field4, _value4) + +#define MCDI_IN_POPULATE_DWORD_5(_emr, _ofst, _field1, _value1, \ + _field2, _value2, _field3, _value3, _field4, _value4, \ + _field5, _value5) \ + EFX_POPULATE_DWORD_5(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ + MC_CMD_ ## _field1, _value1, \ + MC_CMD_ ## _field2, _value2, \ + MC_CMD_ ## _field3, _value3, \ + MC_CMD_ ## _field4, _value4, \ + MC_CMD_ ## _field5, _value5) + +#define MCDI_IN_POPULATE_DWORD_6(_emr, _ofst, _field1, _value1, \ + _field2, _value2, _field3, _value3, _field4, _value4, \ + _field5, _value5, _field6, _value6) \ + EFX_POPULATE_DWORD_6(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ + MC_CMD_ ## _field1, _value1, \ + MC_CMD_ ## _field2, _value2, \ + MC_CMD_ ## _field3, _value3, \ + MC_CMD_ ## _field4, _value4, \ + MC_CMD_ ## _field5, _value5, \ + MC_CMD_ ## _field6, _value6) + +#define MCDI_IN_POPULATE_DWORD_7(_emr, _ofst, _field1, _value1, \ + _field2, _value2, _field3, _value3, _field4, _value4, \ + _field5, _value5, _field6, _value6, _field7, _value7) \ + EFX_POPULATE_DWORD_7(MCDI_IN2(_emr, efx_dword_t, _ofst), \ + MC_CMD_ ## _field1, _value1, \ + MC_CMD_ ## _field2, _value2, \ + MC_CMD_ ## _field3, _value3, \ + MC_CMD_ ## _field4, _value4, \ + MC_CMD_ ## _field5, _value5, \ + MC_CMD_ ## _field6, _value6, \ + MC_CMD_ ## _field7, _value7) + +#define MCDI_IN_POPULATE_DWORD_8(_emr, _ofst, _field1, _value1, \ + _field2, _value2, _field3, _value3, _field4, _value4, \ + _field5, _value5, _field6, _value6, _field7, _value7, \ + _field8, _value8) \ + EFX_POPULATE_DWORD_8(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ + MC_CMD_ ## _field1, _value1, \ + MC_CMD_ ## _field2, _value2, \ + MC_CMD_ ## _field3, _value3, \ + MC_CMD_ ## _field4, _value4, \ + MC_CMD_ ## _field5, _value5, \ + MC_CMD_ ## _field6, _value6, \ + MC_CMD_ ## _field7, _value7, \ + MC_CMD_ ## _field8, _value8) + +#define MCDI_IN_POPULATE_DWORD_9(_emr, _ofst, _field1, _value1, \ + _field2, _value2, _field3, _value3, _field4, _value4, \ + _field5, _value5, _field6, _value6, _field7, _value7, \ + _field8, _value8, _field9, _value9) \ + EFX_POPULATE_DWORD_9(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ + MC_CMD_ ## _field1, _value1, \ + MC_CMD_ ## _field2, _value2, \ + MC_CMD_ ## _field3, _value3, \ + MC_CMD_ ## _field4, _value4, \ + MC_CMD_ ## _field5, _value5, \ + MC_CMD_ ## _field6, _value6, \ + MC_CMD_ ## _field7, _value7, \ + MC_CMD_ ## _field8, _value8, \ + MC_CMD_ ## _field9, _value9) + +#define MCDI_IN_POPULATE_DWORD_10(_emr, _ofst, _field1, _value1, \ + _field2, _value2, _field3, _value3, _field4, _value4, \ + _field5, _value5, _field6, _value6, _field7, _value7, \ + _field8, _value8, _field9, _value9, _field10, _value10) \ + EFX_POPULATE_DWORD_10(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ + MC_CMD_ ## _field1, _value1, \ + MC_CMD_ ## _field2, _value2, \ + MC_CMD_ ## _field3, _value3, \ + MC_CMD_ ## _field4, _value4, \ + MC_CMD_ ## _field5, _value5, \ + MC_CMD_ ## _field6, _value6, \ + MC_CMD_ ## _field7, _value7, \ + MC_CMD_ ## _field8, _value8, \ + MC_CMD_ ## _field9, _value9, \ + MC_CMD_ ## _field10, _value10) + +#define MCDI_OUT(_emr, _type, _ofst) \ + ((_type *)((_emr).emr_out_buf + (_ofst))) + +#define MCDI_OUT2(_emr, _type, _ofst) \ + MCDI_OUT(_emr, _type, MC_CMD_ ## _ofst ## _OFST) + +#define MCDI_OUT_BYTE(_emr, _ofst) \ + EFX_BYTE_FIELD(*MCDI_OUT2(_emr, efx_byte_t, _ofst), \ + EFX_BYTE_0) + +#define MCDI_OUT_WORD(_emr, _ofst) \ + EFX_WORD_FIELD(*MCDI_OUT2(_emr, efx_word_t, _ofst), \ + EFX_WORD_0) + +#define MCDI_OUT_DWORD(_emr, _ofst) \ + EFX_DWORD_FIELD(*MCDI_OUT2(_emr, efx_dword_t, _ofst), \ + EFX_DWORD_0) + +#define MCDI_OUT_DWORD_FIELD(_emr, _ofst, _field) \ + EFX_DWORD_FIELD(*MCDI_OUT2(_emr, efx_dword_t, _ofst), \ + MC_CMD_ ## _field) + +#define MCDI_EV_FIELD(_eqp, _field) \ + EFX_QWORD_FIELD(*eqp, MCDI_EVENT_ ## _field) + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_EFX_MCDI_H */ diff --git a/sys/dev/sfxge/common/efx_mon.c b/sys/dev/sfxge/common/efx_mon.c new file mode 100644 index 000000000000..0d3221ae0445 --- /dev/null +++ b/sys/dev/sfxge/common/efx_mon.c @@ -0,0 +1,269 @@ +/*- + * Copyright 2007-2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "efsys.h" +#include "efx.h" +#include "efx_types.h" +#include "efx_regs.h" +#include "efx_impl.h" + +#if EFSYS_OPT_MON_NULL +#include "nullmon.h" +#endif + +#if EFSYS_OPT_MON_LM87 +#include "lm87.h" +#endif + +#if EFSYS_OPT_MON_MAX6647 +#include "max6647.h" +#endif + +#if EFSYS_OPT_NAMES + +static const char __cs * __cs __efx_mon_name[] = { + "", + "nullmon", + "lm87", + "max6647", + "sfx90x0" +}; + + const char __cs * +efx_mon_name( + __in efx_nic_t *enp) +{ + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + + EFSYS_ASSERT(encp->enc_mon_type != EFX_MON_INVALID); + EFSYS_ASSERT3U(encp->enc_mon_type, <, EFX_MON_NTYPES); + return (__efx_mon_name[encp->enc_mon_type]); +} + +#endif /* EFSYS_OPT_NAMES */ + +#if EFSYS_OPT_MON_NULL +static efx_mon_ops_t __cs __efx_mon_null_ops = { + nullmon_reset, /* emo_reset */ + nullmon_reconfigure, /* emo_reconfigure */ +#if EFSYS_OPT_MON_STATS + nullmon_stats_update /* emo_stat_update */ +#endif /* EFSYS_OPT_MON_STATS */ +}; +#endif + +#if EFSYS_OPT_MON_LM87 +static efx_mon_ops_t __cs __efx_mon_lm87_ops = { + lm87_reset, /* emo_reset */ + lm87_reconfigure, /* emo_reconfigure */ +#if EFSYS_OPT_MON_STATS + lm87_stats_update /* emo_stat_update */ +#endif /* EFSYS_OPT_MON_STATS */ +}; +#endif + +#if EFSYS_OPT_MON_MAX6647 +static efx_mon_ops_t __cs __efx_mon_max6647_ops = { + max6647_reset, /* emo_reset */ + max6647_reconfigure, /* emo_reconfigure */ +#if EFSYS_OPT_MON_STATS + max6647_stats_update /* emo_stat_update */ +#endif /* EFSYS_OPT_MON_STATS */ +}; +#endif + +#if EFSYS_OPT_MON_SIENA +static efx_mon_ops_t __cs __efx_mon_siena_ops = { + siena_mon_reset, /* emo_reset */ + siena_mon_reconfigure, /* emo_reconfigure */ +#if EFSYS_OPT_MON_STATS + siena_mon_stats_update /* emo_stat_update */ +#endif /* EFSYS_OPT_MON_STATS */ +}; +#endif + + +static efx_mon_ops_t __cs * __cs __efx_mon_ops[] = { + NULL, +#if EFSYS_OPT_MON_NULL + &__efx_mon_null_ops, +#else + NULL, +#endif +#if EFSYS_OPT_MON_LM87 + &__efx_mon_lm87_ops, +#else + NULL, +#endif +#if EFSYS_OPT_MON_MAX6647 + &__efx_mon_max6647_ops, +#else + NULL, +#endif +#if EFSYS_OPT_MON_SIENA + &__efx_mon_siena_ops +#else + NULL +#endif +}; + + __checkReturn int +efx_mon_init( + __in efx_nic_t *enp) +{ + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + efx_mon_t *emp = &(enp->en_mon); + efx_mon_ops_t *emop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + + if (enp->en_mod_flags & EFX_MOD_MON) { + rc = EINVAL; + goto fail1; + } + + enp->en_mod_flags |= EFX_MOD_MON; + + emp->em_type = encp->enc_mon_type; + + EFSYS_ASSERT(encp->enc_mon_type != EFX_MON_INVALID); + EFSYS_ASSERT3U(emp->em_type, <, EFX_MON_NTYPES); + if ((emop = (efx_mon_ops_t *)__efx_mon_ops[emp->em_type]) == NULL) { + rc = ENOTSUP; + goto fail2; + } + + if ((rc = emop->emo_reset(enp)) != 0) + goto fail3; + + if ((rc = emop->emo_reconfigure(enp)) != 0) + goto fail4; + + emp->em_emop = emop; + return (0); + +fail4: + EFSYS_PROBE(fail5); + + (void) emop->emo_reset(enp); + +fail3: + EFSYS_PROBE(fail4); +fail2: + EFSYS_PROBE(fail3); + + emp->em_type = EFX_MON_INVALID; + + enp->en_mod_flags &= ~EFX_MOD_MON; + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#if EFSYS_OPT_MON_STATS + +#if EFSYS_OPT_NAMES + +/* START MKCONFIG GENERATED MonitorStatNamesBlock 08518fd1fb4e2612 */ +static const char __cs * __cs __mon_stat_name[] = { + "value_2_5v", + "value_vccp1", + "value_vcc", + "value_5v", + "value_12v", + "value_vccp2", + "value_ext_temp", + "value_int_temp", + "value_ain1", + "value_ain2", + "controller_cooling", + "ext_cooling", + "1v", + "1_2v", + "1_8v", + "3_3v", +}; + +/* END MKCONFIG GENERATED MonitorStatNamesBlock */ + +extern const char __cs * +efx_mon_stat_name( + __in efx_nic_t *enp, + __in efx_mon_stat_t id) +{ + _NOTE(ARGUNUSED(enp)) + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + + EFSYS_ASSERT3U(id, <, EFX_MON_NSTATS); + return (__mon_stat_name[id]); +} + +#endif /* EFSYS_OPT_NAMES */ + + __checkReturn int +efx_mon_stats_update( + __in efx_nic_t *enp, + __in efsys_mem_t *esmp, + __out_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values) +{ + efx_mon_t *emp = &(enp->en_mon); + efx_mon_ops_t *emop = emp->em_emop; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MON); + + return (emop->emo_stats_update(enp, esmp, values)); +} + +#endif /* EFSYS_OPT_MON_STATS */ + + void +efx_mon_fini( + __in efx_nic_t *enp) +{ + efx_mon_t *emp = &(enp->en_mon); + efx_mon_ops_t *emop = emp->em_emop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MON); + + emp->em_emop = NULL; + + rc = emop->emo_reset(enp); + if (rc != 0) + EFSYS_PROBE1(fail1, int, rc); + + emp->em_type = EFX_MON_INVALID; + + enp->en_mod_flags &= ~EFX_MOD_MON; +} diff --git a/sys/dev/sfxge/common/efx_nic.c b/sys/dev/sfxge/common/efx_nic.c new file mode 100644 index 000000000000..07ce00921486 --- /dev/null +++ b/sys/dev/sfxge/common/efx_nic.c @@ -0,0 +1,674 @@ +/*- + * Copyright 2007-2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "efsys.h" +#include "efx.h" +#include "efx_types.h" +#include "efx_regs.h" +#include "efx_impl.h" + + __checkReturn int +efx_family( + __in uint16_t venid, + __in uint16_t devid, + __out efx_family_t *efp) +{ +#if EFSYS_OPT_FALCON + if (venid == EFX_PCI_VENID_SFC && devid == EFX_PCI_DEVID_FALCON) { + *efp = EFX_FAMILY_FALCON; + return (0); + } +#endif +#if EFSYS_OPT_SIENA + if (venid == EFX_PCI_VENID_SFC && devid == EFX_PCI_DEVID_BETHPAGE) { + *efp = EFX_FAMILY_SIENA; + return (0); + } + if (venid == EFX_PCI_VENID_SFC && devid == EFX_PCI_DEVID_SIENA) { + *efp = EFX_FAMILY_SIENA; + return (0); + } + if (venid == EFX_PCI_VENID_SFC && + devid == EFX_PCI_DEVID_SIENA_F1_UNINIT) { + *efp = EFX_FAMILY_SIENA; + return (0); + } +#endif + return (ENOTSUP); +} + +/* + * To support clients which aren't provided with any PCI context infer + * the hardware family by inspecting the hardware. Obviously the caller + * must be damn sure they're really talking to a supported device. + */ + __checkReturn int +efx_infer_family( + __in efsys_bar_t *esbp, + __out efx_family_t *efp) +{ + efx_family_t family; + efx_oword_t oword; + unsigned int portnum; + int rc; + + EFSYS_BAR_READO(esbp, FR_AZ_CS_DEBUG_REG_OFST, &oword, B_TRUE); + portnum = EFX_OWORD_FIELD(oword, FRF_CZ_CS_PORT_NUM); + switch (portnum) { +#if EFSYS_OPT_FALCON + case 0: + family = EFX_FAMILY_FALCON; + break; +#endif +#if EFSYS_OPT_SIENA + case 1: + case 2: + family = EFX_FAMILY_SIENA; + break; +#endif + default: + rc = ENOTSUP; + goto fail1; + } + + if (efp != NULL) + *efp = family; + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +/* + * The built-in default value device id for port 1 of Siena is 0x0810. + * manftest needs to be able to cope with that. + */ + +#define EFX_BIU_MAGIC0 0x01234567 +#define EFX_BIU_MAGIC1 0xfedcba98 + +static __checkReturn int +efx_nic_biu_test( + __in efx_nic_t *enp) +{ + efx_oword_t oword; + int rc; + + /* + * Write magic values to scratch registers 0 and 1, then + * verify that the values were written correctly. Interleave + * the accesses to ensure that the BIU is not just reading + * back the cached value that was last written. + */ + EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC0); + EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword); + + EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC1); + EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword); + + EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword); + if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC0) { + rc = EIO; + goto fail1; + } + + EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword); + if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC1) { + rc = EIO; + goto fail2; + } + + /* + * Perform the same test, with the values swapped. This + * ensures that subsequent tests don't start with the correct + * values already written into the scratch registers. + */ + EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC1); + EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword); + + EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC0); + EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword); + + EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword); + if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC1) { + rc = EIO; + goto fail3; + } + + EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword); + if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC0) { + rc = EIO; + goto fail4; + } + + return (0); + +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#if EFSYS_OPT_FALCON + +static efx_nic_ops_t __cs __efx_nic_falcon_ops = { + falcon_nic_probe, /* eno_probe */ + falcon_nic_reset, /* eno_reset */ + falcon_nic_init, /* eno_init */ +#if EFSYS_OPT_DIAG + falcon_sram_test, /* eno_sram_test */ + falcon_nic_register_test, /* eno_register_test */ +#endif /* EFSYS_OPT_DIAG */ + falcon_nic_fini, /* eno_fini */ + falcon_nic_unprobe, /* eno_unprobe */ +}; + +#endif /* EFSYS_OPT_FALCON */ + +#if EFSYS_OPT_SIENA + +static efx_nic_ops_t __cs __efx_nic_siena_ops = { + siena_nic_probe, /* eno_probe */ + siena_nic_reset, /* eno_reset */ + siena_nic_init, /* eno_init */ +#if EFSYS_OPT_DIAG + siena_sram_test, /* eno_sram_test */ + siena_nic_register_test, /* eno_register_test */ +#endif /* EFSYS_OPT_DIAG */ + siena_nic_fini, /* eno_fini */ + siena_nic_unprobe, /* eno_unprobe */ +}; + +#endif /* EFSYS_OPT_SIENA */ + + __checkReturn int +efx_nic_create( + __in efx_family_t family, + __in efsys_identifier_t *esip, + __in efsys_bar_t *esbp, + __in efsys_lock_t *eslp, + __deref_out efx_nic_t **enpp) +{ + efx_nic_t *enp; + int rc; + + EFSYS_ASSERT3U(family, >, EFX_FAMILY_INVALID); + EFSYS_ASSERT3U(family, <, EFX_FAMILY_NTYPES); + + /* Allocate a NIC object */ + EFSYS_KMEM_ALLOC(esip, sizeof (efx_nic_t), enp); + + if (enp == NULL) { + rc = ENOMEM; + goto fail1; + } + + enp->en_magic = EFX_NIC_MAGIC; + + switch (family) { +#if EFSYS_OPT_FALCON + case EFX_FAMILY_FALCON: + enp->en_enop = (efx_nic_ops_t *)&__efx_nic_falcon_ops; + enp->en_features = 0; + break; +#endif /* EFSYS_OPT_FALCON */ + +#if EFSYS_OPT_SIENA + case EFX_FAMILY_SIENA: + enp->en_enop = (efx_nic_ops_t *)&__efx_nic_siena_ops; + enp->en_features = EFX_FEATURE_IPV6 | + EFX_FEATURE_LFSR_HASH_INSERT | + EFX_FEATURE_LINK_EVENTS | EFX_FEATURE_PERIODIC_MAC_STATS | + EFX_FEATURE_WOL | EFX_FEATURE_MCDI | + EFX_FEATURE_LOOKAHEAD_SPLIT | EFX_FEATURE_MAC_HEADER_FILTERS; + break; +#endif /* EFSYS_OPT_SIENA */ + + default: + rc = ENOTSUP; + goto fail2; + } + + enp->en_family = family; + enp->en_esip = esip; + enp->en_esbp = esbp; + enp->en_eslp = eslp; + + *enpp = enp; + + return (0); + +fail2: + EFSYS_PROBE(fail3); + + enp->en_magic = 0; + + /* Free the NIC object */ + EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_nic_probe( + __in efx_nic_t *enp) +{ + efx_nic_ops_t *enop; + efx_oword_t oword; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); +#if EFSYS_OPT_MCDI + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI); +#endif /* EFSYS_OPT_MCDI */ + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROBE)); + + /* Test BIU */ + if ((rc = efx_nic_biu_test(enp)) != 0) + goto fail1; + + /* Clear the region register */ + EFX_POPULATE_OWORD_4(oword, + FRF_AZ_ADR_REGION0, 0, + FRF_AZ_ADR_REGION1, (1 << 16), + FRF_AZ_ADR_REGION2, (2 << 16), + FRF_AZ_ADR_REGION3, (3 << 16)); + EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword); + + enop = enp->en_enop; + if ((rc = enop->eno_probe(enp)) != 0) + goto fail2; + + if ((rc = efx_phy_probe(enp)) != 0) + goto fail3; + + enp->en_mod_flags |= EFX_MOD_PROBE; + + return (0); + +fail3: + EFSYS_PROBE(fail3); + + enop->eno_unprobe(enp); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#if EFSYS_OPT_PCIE_TUNE + + __checkReturn int +efx_nic_pcie_tune( + __in efx_nic_t *enp, + unsigned int nlanes) +{ + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC)); + +#if EFSYS_OPT_FALCON + if (enp->en_family == EFX_FAMILY_FALCON) + return (falcon_nic_pcie_tune(enp, nlanes)); +#endif + return (ENOTSUP); +} + + __checkReturn int +efx_nic_pcie_extended_sync( + __in efx_nic_t *enp) +{ + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC)); + +#if EFSYS_OPT_SIENA + if (enp->en_family == EFX_FAMILY_SIENA) + return (siena_nic_pcie_extended_sync(enp)); +#endif + + return (ENOTSUP); +} + +#endif /* EFSYS_OPT_PCIE_TUNE */ + + __checkReturn int +efx_nic_init( + __in efx_nic_t *enp) +{ + efx_nic_ops_t *enop = enp->en_enop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + + if (enp->en_mod_flags & EFX_MOD_NIC) { + rc = EINVAL; + goto fail1; + } + + if ((rc = enop->eno_init(enp)) != 0) + goto fail2; + + enp->en_mod_flags |= EFX_MOD_NIC; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + void +efx_nic_fini( + __in efx_nic_t *enp) +{ + efx_nic_ops_t *enop = enp->en_enop; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE); + EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_NIC); + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR)); + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV)); + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX)); + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX)); + + enop->eno_fini(enp); + + enp->en_mod_flags &= ~EFX_MOD_NIC; +} + + void +efx_nic_unprobe( + __in efx_nic_t *enp) +{ + efx_nic_ops_t *enop = enp->en_enop; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); +#if EFSYS_OPT_MCDI + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI); +#endif /* EFSYS_OPT_MCDI */ + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC)); + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR)); + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV)); + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX)); + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX)); + + efx_phy_unprobe(enp); + + enop->eno_unprobe(enp); + + enp->en_mod_flags &= ~EFX_MOD_PROBE; +} + + void +efx_nic_destroy( + __in efx_nic_t *enp) +{ + efsys_identifier_t *esip = enp->en_esip; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0); + + enp->en_family = 0; + enp->en_esip = NULL; + enp->en_esbp = NULL; + enp->en_eslp = NULL; + + enp->en_enop = NULL; + + enp->en_magic = 0; + + /* Free the NIC object */ + EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp); +} + + __checkReturn int +efx_nic_reset( + __in efx_nic_t *enp) +{ + efx_nic_ops_t *enop = enp->en_enop; + unsigned int mod_flags; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE); + /* + * All modules except the MCDI, PROBE, NVRAM, VPD, MON (which we + * do not reset here) must have been shut down or never initialized. + * + * A rule of thumb here is: If the controller or MC reboots, is *any* + * state lost. If it's lost and needs reapplying, then the module + * *must* not be initialised during the reset. + */ + mod_flags = enp->en_mod_flags; + mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM | + EFX_MOD_VPD | EFX_MOD_MON); + EFSYS_ASSERT3U(mod_flags, ==, 0); + if (mod_flags != 0) { + rc = EINVAL; + goto fail1; + } + + if ((rc = enop->eno_reset(enp)) != 0) + goto fail2; + + enp->en_reset_flags |= EFX_RESET_MAC; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + const efx_nic_cfg_t * +efx_nic_cfg_get( + __in efx_nic_t *enp) +{ + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + + return (&(enp->en_nic_cfg)); +} + +#if EFSYS_OPT_DIAG + + __checkReturn int +efx_nic_register_test( + __in efx_nic_t *enp) +{ + efx_nic_ops_t *enop = enp->en_enop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC)); + + if ((rc = enop->eno_register_test(enp)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_nic_test_registers( + __in efx_nic_t *enp, + __in efx_register_set_t *rsp, + __in size_t count) +{ + unsigned int bit; + efx_oword_t original; + efx_oword_t reg; + efx_oword_t buf; + int rc; + + while (count > 0) { + /* This function is only suitable for registers */ + EFSYS_ASSERT(rsp->rows == 1); + + /* bit sweep on and off */ + EFSYS_BAR_READO(enp->en_esbp, rsp->address, &original, + B_TRUE); + for (bit = 0; bit < 128; bit++) { + /* Is this bit in the mask? */ + if (~(rsp->mask.eo_u32[bit >> 5]) & (1 << bit)) + continue; + + /* Test this bit can be set in isolation */ + reg = original; + EFX_AND_OWORD(reg, rsp->mask); + EFX_SET_OWORD_BIT(reg, bit); + + EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, ®, + B_TRUE); + EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf, + B_TRUE); + + EFX_AND_OWORD(buf, rsp->mask); + if (memcmp(®, &buf, sizeof (reg))) { + rc = EIO; + goto fail1; + } + + /* Test this bit can be cleared in isolation */ + EFX_OR_OWORD(reg, rsp->mask); + EFX_CLEAR_OWORD_BIT(reg, bit); + + EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, ®, + B_TRUE); + EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf, + B_TRUE); + + EFX_AND_OWORD(buf, rsp->mask); + if (memcmp(®, &buf, sizeof (reg))) { + rc = EIO; + goto fail2; + } + } + + /* Restore the old value */ + EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, + B_TRUE); + + --count; + ++rsp; + } + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + /* Restore the old value */ + EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, B_TRUE); + + return (rc); +} + + __checkReturn int +efx_nic_test_tables( + __in efx_nic_t *enp, + __in efx_register_set_t *rsp, + __in efx_pattern_type_t pattern, + __in size_t count) +{ + efx_sram_pattern_fn_t func; + unsigned int index; + unsigned int address; + efx_oword_t reg; + efx_oword_t buf; + int rc; + + EFSYS_ASSERT(pattern < EFX_PATTERN_NTYPES); + func = __efx_sram_pattern_fns[pattern]; + + while (count > 0) { + /* Write */ + address = rsp->address; + for (index = 0; index < rsp->rows; ++index) { + func(2 * index + 0, B_FALSE, ®.eo_qword[0]); + func(2 * index + 1, B_FALSE, ®.eo_qword[1]); + EFX_AND_OWORD(reg, rsp->mask); + EFSYS_BAR_WRITEO(enp->en_esbp, address, ®, B_TRUE); + + address += rsp->step; + } + + /* Read */ + address = rsp->address; + for (index = 0; index < rsp->rows; ++index) { + func(2 * index + 0, B_FALSE, ®.eo_qword[0]); + func(2 * index + 1, B_FALSE, ®.eo_qword[1]); + EFX_AND_OWORD(reg, rsp->mask); + EFSYS_BAR_READO(enp->en_esbp, address, &buf, B_TRUE); + if (memcmp(®, &buf, sizeof (reg))) { + rc = EIO; + goto fail1; + } + + address += rsp->step; + } + + ++rsp; + --count; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#endif /* EFSYS_OPT_DIAG */ diff --git a/sys/dev/sfxge/common/efx_nvram.c b/sys/dev/sfxge/common/efx_nvram.c new file mode 100644 index 000000000000..d4cf7412b545 --- /dev/null +++ b/sys/dev/sfxge/common/efx_nvram.c @@ -0,0 +1,372 @@ +/*- + * Copyright 2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "efsys.h" +#include "efx.h" +#include "efx_types.h" +#include "efx_regs.h" +#include "efx_impl.h" + +#if EFSYS_OPT_NVRAM + +#if EFSYS_OPT_FALCON + +static efx_nvram_ops_t __cs __efx_nvram_falcon_ops = { +#if EFSYS_OPT_DIAG + falcon_nvram_test, /* envo_test */ +#endif /* EFSYS_OPT_DIAG */ + falcon_nvram_size, /* envo_size */ + falcon_nvram_get_version, /* envo_get_version */ + falcon_nvram_rw_start, /* envo_rw_start */ + falcon_nvram_read_chunk, /* envo_read_chunk */ + falcon_nvram_erase, /* envo_erase */ + falcon_nvram_write_chunk, /* envo_write_chunk */ + falcon_nvram_rw_finish, /* envo_rw_finish */ + falcon_nvram_set_version, /* envo_set_version */ +}; + +#endif /* EFSYS_OPT_FALCON */ + +#if EFSYS_OPT_SIENA + +static efx_nvram_ops_t __cs __efx_nvram_siena_ops = { +#if EFSYS_OPT_DIAG + siena_nvram_test, /* envo_test */ +#endif /* EFSYS_OPT_DIAG */ + siena_nvram_size, /* envo_size */ + siena_nvram_get_version, /* envo_get_version */ + siena_nvram_rw_start, /* envo_rw_start */ + siena_nvram_read_chunk, /* envo_read_chunk */ + siena_nvram_erase, /* envo_erase */ + siena_nvram_write_chunk, /* envo_write_chunk */ + siena_nvram_rw_finish, /* envo_rw_finish */ + siena_nvram_set_version, /* envo_set_version */ +}; + +#endif /* EFSYS_OPT_SIENA */ + + __checkReturn int +efx_nvram_init( + __in efx_nic_t *enp) +{ + efx_nvram_ops_t *envop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NVRAM)); + + switch (enp->en_family) { +#if EFSYS_OPT_FALCON + case EFX_FAMILY_FALCON: + envop = (efx_nvram_ops_t *)&__efx_nvram_falcon_ops; + break; +#endif /* EFSYS_OPT_FALCON */ + +#if EFSYS_OPT_SIENA + case EFX_FAMILY_SIENA: + envop = (efx_nvram_ops_t *)&__efx_nvram_siena_ops; + break; +#endif /* EFSYS_OPT_SIENA */ + + default: + EFSYS_ASSERT(0); + rc = ENOTSUP; + goto fail1; + } + + enp->en_envop = envop; + enp->en_mod_flags |= EFX_MOD_NVRAM; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#if EFSYS_OPT_DIAG + + __checkReturn int +efx_nvram_test( + __in efx_nic_t *enp) +{ + efx_nvram_ops_t *envop = enp->en_envop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM); + + if ((rc = envop->envo_test(enp)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#endif /* EFSYS_OPT_DIAG */ + + __checkReturn int +efx_nvram_size( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __out size_t *sizep) +{ + efx_nvram_ops_t *envop = enp->en_envop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM); + + EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES); + + if ((rc = envop->envo_size(enp, type, sizep)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_nvram_get_version( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __out uint32_t *subtypep, + __out_ecount(4) uint16_t version[4]) +{ + efx_nvram_ops_t *envop = enp->en_envop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM); + + EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES); + + if ((rc = envop->envo_get_version(enp, type, subtypep, version)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_nvram_rw_start( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __out_opt size_t *chunk_sizep) +{ + efx_nvram_ops_t *envop = enp->en_envop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM); + + EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES); + EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID); + + EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID); + + if ((rc = envop->envo_rw_start(enp, type, chunk_sizep)) != 0) + goto fail1; + + enp->en_nvram_locked = type; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_nvram_read_chunk( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __in unsigned int offset, + __out_bcount(size) caddr_t data, + __in size_t size) +{ + efx_nvram_ops_t *envop = enp->en_envop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM); + + EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES); + EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID); + + EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type); + + if ((rc = envop->envo_read_chunk(enp, type, offset, data, size)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_nvram_erase( + __in efx_nic_t *enp, + __in efx_nvram_type_t type) +{ + efx_nvram_ops_t *envop = enp->en_envop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM); + + EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES); + EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID); + + EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type); + + if ((rc = envop->envo_erase(enp, type)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_nvram_write_chunk( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __in unsigned int offset, + __in_bcount(size) caddr_t data, + __in size_t size) +{ + efx_nvram_ops_t *envop = enp->en_envop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM); + + EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES); + EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID); + + EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type); + + if ((rc = envop->envo_write_chunk(enp, type, offset, data, size)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + void +efx_nvram_rw_finish( + __in efx_nic_t *enp, + __in efx_nvram_type_t type) +{ + efx_nvram_ops_t *envop = enp->en_envop; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM); + + EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES); + EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID); + + EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type); + + envop->envo_rw_finish(enp, type); + + enp->en_nvram_locked = EFX_NVRAM_INVALID; +} + + __checkReturn int +efx_nvram_set_version( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __out uint16_t version[4]) +{ + efx_nvram_ops_t *envop = enp->en_envop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM); + + EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES); + + /* + * The Siena implementation of envo_set_version() will attempt to + * acquire the NVRAM_UPDATE lock for the DYNAMIC_CONFIG sector. + * Therefore, you can't have already acquired the NVRAM_UPDATE lock. + */ + EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID); + + if ((rc = envop->envo_set_version(enp, type, version)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +void +efx_nvram_fini( + __in efx_nic_t *enp) +{ + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM); + + EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID); + + enp->en_envop = NULL; + enp->en_mod_flags &= ~EFX_MOD_NVRAM; +} + +#endif /* EFSYS_OPT_NVRAM */ diff --git a/sys/dev/sfxge/common/efx_phy.c b/sys/dev/sfxge/common/efx_phy.c new file mode 100644 index 000000000000..0b098ecf423c --- /dev/null +++ b/sys/dev/sfxge/common/efx_phy.c @@ -0,0 +1,752 @@ +/*- + * Copyright 2007-2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "efsys.h" +#include "efx.h" +#include "efx_types.h" +#include "efx_regs.h" +#include "efx_impl.h" +#if EFSYS_OPT_FALCON +#include "falcon_nvram.h" +#endif + +#if EFSYS_OPT_MAC_FALCON_XMAC +#include "falcon_xmac.h" +#endif + +#if EFSYS_OPT_MAC_FALCON_GMAC +#include "falcon_gmac.h" +#endif + +#if EFSYS_OPT_PHY_NULL +#include "nullphy.h" +#endif + +#if EFSYS_OPT_PHY_QT2022C2 +#include "qt2022c2.h" +#endif + +#if EFSYS_OPT_PHY_SFX7101 +#include "sfx7101.h" +#endif + +#if EFSYS_OPT_PHY_TXC43128 +#include "txc43128.h" +#endif + +#if EFSYS_OPT_PHY_SFT9001 +#include "sft9001.h" +#endif + +#if EFSYS_OPT_PHY_QT2025C +#include "qt2025c.h" +#endif + +#if EFSYS_OPT_PHY_NULL +static efx_phy_ops_t __cs __efx_phy_null_ops = { + NULL, /* epo_power */ + nullphy_reset, /* epo_reset */ + nullphy_reconfigure, /* epo_reconfigure */ + nullphy_verify, /* epo_verify */ + NULL, /* epo_uplink_check */ + nullphy_downlink_check, /* epo_downlink_check */ + nullphy_oui_get, /* epo_oui_get */ +#if EFSYS_OPT_PHY_STATS + nullphy_stats_update, /* epo_stats_update */ +#endif /* EFSYS_OPT_PHY_STATS */ +#if EFSYS_OPT_PHY_PROPS +#if EFSYS_OPT_NAMES + nullphy_prop_name, /* epo_prop_name */ +#endif + nullphy_prop_get, /* epo_prop_get */ + nullphy_prop_set, /* epo_prop_set */ +#endif /* EFSYS_OPT_PHY_PROPS */ +#if EFSYS_OPT_PHY_BIST + NULL, /* epo_bist_start */ + NULL, /* epo_bist_poll */ + NULL, /* epo_bist_stop */ +#endif /* EFSYS_OPT_PHY_BIST */ +}; +#endif /* EFSYS_OPT_PHY_NULL */ + +#if EFSYS_OPT_PHY_QT2022C2 +static efx_phy_ops_t __cs __efx_phy_qt2022c2_ops = { + NULL, /* epo_power */ + qt2022c2_reset, /* epo_reset */ + qt2022c2_reconfigure, /* epo_reconfigure */ + qt2022c2_verify, /* epo_verify */ + qt2022c2_uplink_check, /* epo_uplink_check */ + qt2022c2_downlink_check, /* epo_downlink_check */ + qt2022c2_oui_get, /* epo_oui_get */ +#if EFSYS_OPT_PHY_STATS + qt2022c2_stats_update, /* epo_stats_update */ +#endif /* EFSYS_OPT_PHY_STATS */ +#if EFSYS_OPT_PHY_PROPS +#if EFSYS_OPT_NAMES + qt2022c2_prop_name, /* epo_prop_name */ +#endif + qt2022c2_prop_get, /* epo_prop_get */ + qt2022c2_prop_set, /* epo_prop_set */ +#endif /* EFSYS_OPT_PHY_PROPS */ +#if EFSYS_OPT_PHY_BIST + NULL, /* epo_bist_start */ + NULL, /* epo_bist_poll */ + NULL, /* epo_bist_stop */ +#endif /* EFSYS_OPT_PHY_BIST */ +}; +#endif /* EFSYS_OPT_PHY_QT2022C2 */ + +#if EFSYS_OPT_PHY_SFX7101 +static efx_phy_ops_t __cs __efx_phy_sfx7101_ops = { + sfx7101_power, /* epo_power */ + sfx7101_reset, /* epo_reset */ + sfx7101_reconfigure, /* epo_reconfigure */ + sfx7101_verify, /* epo_verify */ + sfx7101_uplink_check, /* epo_uplink_check */ + sfx7101_downlink_check, /* epo_downlink_check */ + sfx7101_oui_get, /* epo_oui_get */ +#if EFSYS_OPT_PHY_STATS + sfx7101_stats_update, /* epo_stats_update */ +#endif /* EFSYS_OPT_PHY_STATS */ +#if EFSYS_OPT_PHY_PROPS +#if EFSYS_OPT_NAMES + sfx7101_prop_name, /* epo_prop_name */ +#endif + sfx7101_prop_get, /* epo_prop_get */ + sfx7101_prop_set, /* epo_prop_set */ +#endif /* EFSYS_OPT_PHY_PROPS */ +#if EFSYS_OPT_PHY_BIST + NULL, /* epo_bist_start */ + NULL, /* epo_bist_poll */ + NULL, /* epo_bist_stop */ +#endif /* EFSYS_OPT_PHY_BIST */ +}; +#endif /* EFSYS_OPT_PHY_SFX7101 */ + +#if EFSYS_OPT_PHY_TXC43128 +static efx_phy_ops_t __cs __efx_phy_txc43128_ops = { + NULL, /* epo_power */ + txc43128_reset, /* epo_reset */ + txc43128_reconfigure, /* epo_reconfigure */ + txc43128_verify, /* epo_verify */ + txc43128_uplink_check, /* epo_uplink_check */ + txc43128_downlink_check, /* epo_downlink_check */ + txc43128_oui_get, /* epo_oui_get */ +#if EFSYS_OPT_PHY_STATS + txc43128_stats_update, /* epo_stats_update */ +#endif /* EFSYS_OPT_PHY_STATS */ +#if EFSYS_OPT_PHY_PROPS +#if EFSYS_OPT_NAMES + txc43128_prop_name, /* epo_prop_name */ +#endif + txc43128_prop_get, /* epo_prop_get */ + txc43128_prop_set, /* epo_prop_set */ +#endif /* EFSYS_OPT_PHY_PROPS */ +#if EFSYS_OPT_PHY_BIST + NULL, /* epo_bist_start */ + NULL, /* epo_bist_poll */ + NULL, /* epo_bist_stop */ +#endif /* EFSYS_OPT_PHY_BIST */ +}; +#endif /* EFSYS_OPT_PHY_TXC43128 */ + +#if EFSYS_OPT_PHY_SFT9001 +static efx_phy_ops_t __cs __efx_phy_sft9001_ops = { + NULL, /* epo_power */ + sft9001_reset, /* epo_reset */ + sft9001_reconfigure, /* epo_reconfigure */ + sft9001_verify, /* epo_verify */ + sft9001_uplink_check, /* epo_uplink_check */ + sft9001_downlink_check, /* epo_downlink_check */ + sft9001_oui_get, /* epo_oui_get */ +#if EFSYS_OPT_PHY_STATS + sft9001_stats_update, /* epo_stats_update */ +#endif /* EFSYS_OPT_PHY_STATS */ +#if EFSYS_OPT_PHY_PROPS +#if EFSYS_OPT_NAMES + sft9001_prop_name, /* epo_prop_name */ +#endif + sft9001_prop_get, /* epo_prop_get */ + sft9001_prop_set, /* epo_prop_set */ +#endif /* EFSYS_OPT_PHY_PROPS */ +#if EFSYS_OPT_PHY_BIST + sft9001_bist_start, /* epo_bist_start */ + sft9001_bist_poll, /* epo_bist_poll */ + sft9001_bist_stop, /* epo_bist_stop */ +#endif /* EFSYS_OPT_PHY_BIST */ +}; +#endif /* EFSYS_OPT_PHY_SFT9001 */ + +#if EFSYS_OPT_PHY_QT2025C +static efx_phy_ops_t __cs __efx_phy_qt2025c_ops = { + NULL, /* epo_power */ + qt2025c_reset, /* epo_reset */ + qt2025c_reconfigure, /* epo_reconfigure */ + qt2025c_verify, /* epo_verify */ + qt2025c_uplink_check, /* epo_uplink_check */ + qt2025c_downlink_check, /* epo_downlink_check */ + qt2025c_oui_get, /* epo_oui_get */ +#if EFSYS_OPT_PHY_STATS + qt2025c_stats_update, /* epo_stats_update */ +#endif /* EFSYS_OPT_PHY_STATS */ +#if EFSYS_OPT_PHY_PROPS +#if EFSYS_OPT_NAMES + qt2025c_prop_name, /* epo_prop_name */ +#endif + qt2025c_prop_get, /* epo_prop_get */ + qt2025c_prop_set, /* epo_prop_set */ +#endif /* EFSYS_OPT_PHY_PROPS */ +#if EFSYS_OPT_PHY_BIST + NULL, /* epo_bist_start */ + NULL, /* epo_bist_poll */ + NULL, /* epo_bist_stop */ +#endif /* EFSYS_OPT_PHY_BIST */ +}; +#endif /* EFSYS_OPT_PHY_QT2025C */ + +#if EFSYS_OPT_SIENA +static efx_phy_ops_t __cs __efx_phy_siena_ops = { + siena_phy_power, /* epo_power */ + NULL, /* epo_reset */ + siena_phy_reconfigure, /* epo_reconfigure */ + siena_phy_verify, /* epo_verify */ + NULL, /* epo_uplink_check */ + NULL, /* epo_downlink_check */ + siena_phy_oui_get, /* epo_oui_get */ +#if EFSYS_OPT_PHY_STATS + siena_phy_stats_update, /* epo_stats_update */ +#endif /* EFSYS_OPT_PHY_STATS */ +#if EFSYS_OPT_PHY_PROPS +#if EFSYS_OPT_NAMES + siena_phy_prop_name, /* epo_prop_name */ +#endif + siena_phy_prop_get, /* epo_prop_get */ + siena_phy_prop_set, /* epo_prop_set */ +#endif /* EFSYS_OPT_PHY_PROPS */ +#if EFSYS_OPT_PHY_BIST + siena_phy_bist_start, /* epo_bist_start */ + siena_phy_bist_poll, /* epo_bist_poll */ + siena_phy_bist_stop, /* epo_bist_stop */ +#endif /* EFSYS_OPT_PHY_BIST */ +}; +#endif /* EFSYS_OPT_SIENA */ + + __checkReturn int +efx_phy_probe( + __in efx_nic_t *enp) +{ + efx_port_t *epp = &(enp->en_port); + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + efx_phy_ops_t *epop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + + epp->ep_port = encp->enc_port; + epp->ep_phy_type = encp->enc_phy_type; + + /* Hook in operations structure */ + switch (enp->en_family) { +#if EFSYS_OPT_FALCON + case EFX_FAMILY_FALCON: + switch (epp->ep_phy_type) { +#if EFSYS_OPT_PHY_NULL + case PHY_TYPE_NONE_DECODE: + epop = (efx_phy_ops_t *)&__efx_phy_null_ops; + break; +#endif +#if EFSYS_OPT_PHY_QT2022C2 + case PHY_TYPE_QT2022C2_DECODE: + epop = (efx_phy_ops_t *)&__efx_phy_qt2022c2_ops; + break; +#endif +#if EFSYS_OPT_PHY_SFX7101 + case PHY_TYPE_SFX7101_DECODE: + epop = (efx_phy_ops_t *)&__efx_phy_sfx7101_ops; + break; +#endif +#if EFSYS_OPT_PHY_TXC43128 + case PHY_TYPE_TXC43128_DECODE: + epop = (efx_phy_ops_t *)&__efx_phy_txc43128_ops; + break; +#endif +#if EFSYS_OPT_PHY_SFT9001 + case PHY_TYPE_SFT9001A_DECODE: + case PHY_TYPE_SFT9001B_DECODE: + epop = (efx_phy_ops_t *)&__efx_phy_sft9001_ops; + break; +#endif +#if EFSYS_OPT_PHY_QT2025C + case EFX_PHY_QT2025C: + epop = (efx_phy_ops_t *)&__efx_phy_qt2025c_ops; + break; +#endif + default: + rc = ENOTSUP; + goto fail1; + } + break; +#endif /* EFSYS_OPT_FALCON */ +#if EFSYS_OPT_SIENA + case EFX_FAMILY_SIENA: + epop = (efx_phy_ops_t *)&__efx_phy_siena_ops; + break; +#endif /* EFSYS_OPT_SIENA */ + default: + rc = ENOTSUP; + goto fail1; + } + + epp->ep_epop = epop; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + epp->ep_port = 0; + epp->ep_phy_type = 0; + + return (rc); +} + + __checkReturn int +efx_phy_verify( + __in efx_nic_t *enp) +{ + efx_port_t *epp = &(enp->en_port); + efx_phy_ops_t *epop = epp->ep_epop; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + return (epop->epo_verify(enp)); +} + +#if EFSYS_OPT_PHY_LED_CONTROL + + __checkReturn int +efx_phy_led_set( + __in efx_nic_t *enp, + __in efx_phy_led_mode_t mode) +{ + efx_nic_cfg_t *encp = (&enp->en_nic_cfg); + efx_port_t *epp = &(enp->en_port); + efx_phy_ops_t *epop = epp->ep_epop; + uint32_t mask; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + if (epp->ep_phy_led_mode == mode) + goto done; + + mask = (1 << EFX_PHY_LED_DEFAULT); + mask |= encp->enc_led_mask; + + if (!((1 << mode) & mask)) { + rc = ENOTSUP; + goto fail1; + } + + EFSYS_ASSERT3U(mode, <, EFX_PHY_LED_NMODES); + epp->ep_phy_led_mode = mode; + + if ((rc = epop->epo_reconfigure(enp)) != 0) + goto fail2; + +done: + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} +#endif /* EFSYS_OPT_PHY_LED_CONTROL */ + + void +efx_phy_adv_cap_get( + __in efx_nic_t *enp, + __in uint32_t flag, + __out uint32_t *maskp) +{ + efx_port_t *epp = &(enp->en_port); + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + + switch (flag) { + case EFX_PHY_CAP_CURRENT: + *maskp = epp->ep_adv_cap_mask; + break; + case EFX_PHY_CAP_DEFAULT: + *maskp = epp->ep_default_adv_cap_mask; + break; + case EFX_PHY_CAP_PERM: + *maskp = epp->ep_phy_cap_mask; + break; + default: + EFSYS_ASSERT(B_FALSE); + break; + } +} + + __checkReturn int +efx_phy_adv_cap_set( + __in efx_nic_t *enp, + __in uint32_t mask) +{ + efx_port_t *epp = &(enp->en_port); + efx_phy_ops_t *epop = epp->ep_epop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + if ((mask & ~epp->ep_phy_cap_mask) != 0) { + rc = ENOTSUP; + goto fail1; + } + + if (epp->ep_adv_cap_mask == mask) + goto done; + + epp->ep_adv_cap_mask = mask; + + if ((rc = epop->epo_reconfigure(enp)) != 0) + goto fail2; + +done: + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + void +efx_phy_lp_cap_get( + __in efx_nic_t *enp, + __out uint32_t *maskp) +{ + efx_port_t *epp = &(enp->en_port); + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + *maskp = epp->ep_lp_cap_mask; +} + + __checkReturn int +efx_phy_oui_get( + __in efx_nic_t *enp, + __out uint32_t *ouip) +{ + efx_port_t *epp = &(enp->en_port); + efx_phy_ops_t *epop = epp->ep_epop; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + return (epop->epo_oui_get(enp, ouip)); +} + + void +efx_phy_media_type_get( + __in efx_nic_t *enp, + __out efx_phy_media_type_t *typep) +{ + efx_port_t *epp = &(enp->en_port); + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + if (epp->ep_module_type != EFX_PHY_MEDIA_INVALID) + *typep = epp->ep_module_type; + else + *typep = epp->ep_fixed_port_type; +} + +#if EFSYS_OPT_PHY_STATS + +#if EFSYS_OPT_NAMES + +/* START MKCONFIG GENERATED PhyStatNamesBlock 271268f3da0e804f */ +static const char __cs * __cs __efx_phy_stat_name[] = { + "oui", + "pma_pmd_link_up", + "pma_pmd_rx_fault", + "pma_pmd_tx_fault", + "pma_pmd_rev_a", + "pma_pmd_rev_b", + "pma_pmd_rev_c", + "pma_pmd_rev_d", + "pcs_link_up", + "pcs_rx_fault", + "pcs_tx_fault", + "pcs_ber", + "pcs_block_errors", + "phy_xs_link_up", + "phy_xs_rx_fault", + "phy_xs_tx_fault", + "phy_xs_align", + "phy_xs_sync_a", + "phy_xs_sync_b", + "phy_xs_sync_c", + "phy_xs_sync_d", + "an_link_up", + "an_master", + "an_local_rx_ok", + "an_remote_rx_ok", + "cl22ext_link_up", + "snr_a", + "snr_b", + "snr_c", + "snr_d", + "pma_pmd_signal_a", + "pma_pmd_signal_b", + "pma_pmd_signal_c", + "pma_pmd_signal_d", + "an_complete", + "pma_pmd_rev_major", + "pma_pmd_rev_minor", + "pma_pmd_rev_micro", + "pcs_fw_version_0", + "pcs_fw_version_1", + "pcs_fw_version_2", + "pcs_fw_version_3", + "pcs_fw_build_yy", + "pcs_fw_build_mm", + "pcs_fw_build_dd", + "pcs_op_mode", +}; + +/* END MKCONFIG GENERATED PhyStatNamesBlock */ + + const char __cs * +efx_phy_stat_name( + __in efx_nic_t *enp, + __in efx_phy_stat_t type) +{ + _NOTE(ARGUNUSED(enp)) + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(type, <, EFX_PHY_NSTATS); + + return (__efx_phy_stat_name[type]); +} + +#endif /* EFSYS_OPT_NAMES */ + + __checkReturn int +efx_phy_stats_update( + __in efx_nic_t *enp, + __in efsys_mem_t *esmp, + __out_ecount(EFX_PHY_NSTATS) uint32_t *stat) +{ + efx_port_t *epp = &(enp->en_port); + efx_phy_ops_t *epop = epp->ep_epop; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + return (epop->epo_stats_update(enp, esmp, stat)); +} + +#endif /* EFSYS_OPT_PHY_STATS */ + +#if EFSYS_OPT_PHY_PROPS + +#if EFSYS_OPT_NAMES + const char __cs * +efx_phy_prop_name( + __in efx_nic_t *enp, + __in unsigned int id) +{ + efx_port_t *epp = &(enp->en_port); + efx_phy_ops_t *epop = epp->ep_epop; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + + return (epop->epo_prop_name(enp, id)); +} +#endif /* EFSYS_OPT_NAMES */ + + __checkReturn int +efx_phy_prop_get( + __in efx_nic_t *enp, + __in unsigned int id, + __in uint32_t flags, + __out uint32_t *valp) +{ + efx_port_t *epp = &(enp->en_port); + efx_phy_ops_t *epop = epp->ep_epop; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + return (epop->epo_prop_get(enp, id, flags, valp)); +} + + __checkReturn int +efx_phy_prop_set( + __in efx_nic_t *enp, + __in unsigned int id, + __in uint32_t val) +{ + efx_port_t *epp = &(enp->en_port); + efx_phy_ops_t *epop = epp->ep_epop; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + return (epop->epo_prop_set(enp, id, val)); +} +#endif /* EFSYS_OPT_PHY_STATS */ + +#if EFSYS_OPT_PHY_BIST + + __checkReturn int +efx_phy_bist_start( + __in efx_nic_t *enp, + __in efx_phy_bist_type_t type) +{ + efx_port_t *epp = &(enp->en_port); + efx_phy_ops_t *epop = epp->ep_epop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN); + EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES); + EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_PHY_BIST_TYPE_UNKNOWN); + + if (epop->epo_bist_start == NULL) { + rc = ENOTSUP; + goto fail1; + } + + if ((rc = epop->epo_bist_start(enp, type)) != 0) + goto fail2; + + epp->ep_current_bist = type; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_phy_bist_poll( + __in efx_nic_t *enp, + __in efx_phy_bist_type_t type, + __out efx_phy_bist_result_t *resultp, + __out_opt uint32_t *value_maskp, + __out_ecount_opt(count) unsigned long *valuesp, + __in size_t count) +{ + efx_port_t *epp = &(enp->en_port); + efx_phy_ops_t *epop = epp->ep_epop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN); + EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES); + EFSYS_ASSERT3U(epp->ep_current_bist, ==, type); + + EFSYS_ASSERT(epop->epo_bist_poll != NULL); + if (epop->epo_bist_poll == NULL) { + rc = ENOTSUP; + goto fail1; + } + + if ((rc = epop->epo_bist_poll(enp, type, resultp, value_maskp, + valuesp, count)) != 0) + goto fail2; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + void +efx_phy_bist_stop( + __in efx_nic_t *enp, + __in efx_phy_bist_type_t type) +{ + efx_port_t *epp = &(enp->en_port); + efx_phy_ops_t *epop = epp->ep_epop; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN); + EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES); + EFSYS_ASSERT3U(epp->ep_current_bist, ==, type); + + EFSYS_ASSERT(epop->epo_bist_stop != NULL); + + if (epop->epo_bist_stop != NULL) + epop->epo_bist_stop(enp, type); + + epp->ep_current_bist = EFX_PHY_BIST_TYPE_UNKNOWN; +} + +#endif /* EFSYS_OPT_PHY_BIST */ + void +efx_phy_unprobe( + __in efx_nic_t *enp) +{ + efx_port_t *epp = &(enp->en_port); + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + + epp->ep_epop = NULL; + + epp->ep_adv_cap_mask = 0; + + epp->ep_port = 0; + epp->ep_phy_type = 0; +} diff --git a/sys/dev/sfxge/common/efx_port.c b/sys/dev/sfxge/common/efx_port.c new file mode 100644 index 000000000000..cbb0b3bf3d96 --- /dev/null +++ b/sys/dev/sfxge/common/efx_port.c @@ -0,0 +1,226 @@ +/*- + * Copyright 2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "efsys.h" +#include "efx.h" +#include "efx_types.h" +#include "efx_impl.h" + + __checkReturn int +efx_port_init( + __in efx_nic_t *enp) +{ + efx_port_t *epp = &(enp->en_port); + efx_phy_ops_t *epop = epp->ep_epop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); + + if (enp->en_mod_flags & EFX_MOD_PORT) { + rc = EINVAL; + goto fail1; + } + + enp->en_mod_flags |= EFX_MOD_PORT; + + epp->ep_mac_type = EFX_MAC_INVALID; + epp->ep_link_mode = EFX_LINK_UNKNOWN; + epp->ep_mac_poll_needed = B_TRUE; + epp->ep_mac_drain = B_TRUE; + + /* Configure the MAC */ + if ((rc = efx_mac_select(enp)) != 0) + goto fail1; + + epp->ep_emop->emo_reconfigure(enp); + + /* + * Turn on the PHY if available, otherwise reset it, and + * reconfigure it with the current configuration. + */ + if (epop->epo_power != NULL) { + if ((rc = epop->epo_power(enp, B_TRUE)) != 0) + goto fail2; + } else { + if ((rc = epop->epo_reset(enp)) != 0) + goto fail2; + } + + EFSYS_ASSERT(enp->en_reset_flags & EFX_RESET_PHY); + enp->en_reset_flags &= ~EFX_RESET_PHY; + + if ((rc = epop->epo_reconfigure(enp)) != 0) + goto fail3; + + return (0); + +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + enp->en_mod_flags &= ~EFX_MOD_PORT; + + return (rc); +} + + __checkReturn int +efx_port_poll( + __in efx_nic_t *enp, + __out efx_link_mode_t *link_modep) +{ + efx_port_t *epp = &(enp->en_port); + efx_mac_ops_t *emop = epp->ep_emop; + efx_link_mode_t ignore_link_mode; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + EFSYS_ASSERT(emop != NULL); + EFSYS_ASSERT(!epp->ep_mac_stats_pending); + + if (link_modep == NULL) + link_modep = &ignore_link_mode; + + if ((rc = emop->emo_poll(enp, link_modep)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#if EFSYS_OPT_LOOPBACK + + __checkReturn int +efx_port_loopback_set( + __in efx_nic_t *enp, + __in efx_link_mode_t link_mode, + __in efx_loopback_type_t loopback_type) +{ + efx_port_t *epp = &(enp->en_port); + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + efx_mac_ops_t *emop = epp->ep_emop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + EFSYS_ASSERT(emop != NULL); + + EFSYS_ASSERT(link_mode < EFX_LINK_NMODES); + if ((1 << loopback_type) & ~encp->enc_loopback_types[link_mode]) { + rc = ENOTSUP; + goto fail1; + } + + if (epp->ep_loopback_type == loopback_type && + epp->ep_loopback_link_mode == link_mode) + return (0); + + if ((rc = emop->emo_loopback_set(enp, link_mode, loopback_type)) != 0) + goto fail2; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#if EFSYS_OPT_NAMES + +static const char __cs * __cs __efx_loopback_type_name[] = { + "OFF", + "DATA", + "GMAC", + "XGMII", + "XGXS", + "XAUI", + "GMII", + "SGMII", + "XGBR", + "XFI", + "XAUI_FAR", + "GMII_FAR", + "SGMII_FAR", + "XFI_FAR", + "GPHY", + "PHY_XS", + "PCS", + "PMA_PMD", +}; + + __checkReturn const char __cs * +efx_loopback_type_name( + __in efx_nic_t *enp, + __in efx_loopback_type_t type) +{ + _NOTE(ARGUNUSED(enp)) + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(type, <, EFX_LOOPBACK_NTYPES); + + return (__efx_loopback_type_name[type]); +} + +#endif /* EFSYS_OPT_NAMES */ + +#endif /* EFSYS_OPT_LOOPBACK */ + + void +efx_port_fini( + __in efx_nic_t *enp) +{ + efx_port_t *epp = &(enp->en_port); + efx_phy_ops_t *epop = epp->ep_epop; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); + + EFSYS_ASSERT(epp->ep_mac_drain); + + epp->ep_emop = NULL; + epp->ep_mac_type = EFX_MAC_INVALID; + epp->ep_mac_drain = B_FALSE; + epp->ep_mac_poll_needed = B_FALSE; + + /* Turn off the PHY */ + if (epop->epo_power != NULL) + (void) epop->epo_power(enp, B_FALSE); + + enp->en_mod_flags &= ~EFX_MOD_PORT; +} diff --git a/sys/dev/sfxge/common/efx_regs.h b/sys/dev/sfxge/common/efx_regs.h new file mode 100644 index 000000000000..c31c33e626c0 --- /dev/null +++ b/sys/dev/sfxge/common/efx_regs.h @@ -0,0 +1,3846 @@ +/*- + * Copyright 2007-2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SYS_EFX_REGS_H +#define _SYS_EFX_REGS_H + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * FR_AB_EE_VPD_CFG0_REG_SF(128bit): + * SPI/VPD configuration register 0 + */ +#define FR_AB_EE_VPD_CFG0_REG_SF_OFST 0x00000300 +/* falcona0,falconb0=eeprom_flash */ +/* + * FR_AB_EE_VPD_CFG0_REG(128bit): + * SPI/VPD configuration register 0 + */ +#define FR_AB_EE_VPD_CFG0_REG_OFST 0x00000140 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_EE_SF_FASTRD_EN_LBN 127 +#define FRF_AB_EE_SF_FASTRD_EN_WIDTH 1 +#define FRF_AB_EE_SF_CLOCK_DIV_LBN 120 +#define FRF_AB_EE_SF_CLOCK_DIV_WIDTH 7 +#define FRF_AB_EE_VPD_WIP_POLL_LBN 119 +#define FRF_AB_EE_VPD_WIP_POLL_WIDTH 1 +#define FRF_AB_EE_EE_CLOCK_DIV_LBN 112 +#define FRF_AB_EE_EE_CLOCK_DIV_WIDTH 7 +#define FRF_AB_EE_EE_WR_TMR_VALUE_LBN 96 +#define FRF_AB_EE_EE_WR_TMR_VALUE_WIDTH 16 +#define FRF_AB_EE_VPDW_LENGTH_LBN 80 +#define FRF_AB_EE_VPDW_LENGTH_WIDTH 15 +#define FRF_AB_EE_VPDW_BASE_LBN 64 +#define FRF_AB_EE_VPDW_BASE_WIDTH 15 +#define FRF_AB_EE_VPD_WR_CMD_EN_LBN 56 +#define FRF_AB_EE_VPD_WR_CMD_EN_WIDTH 8 +#define FRF_AB_EE_VPD_BASE_LBN 32 +#define FRF_AB_EE_VPD_BASE_WIDTH 24 +#define FRF_AB_EE_VPD_LENGTH_LBN 16 +#define FRF_AB_EE_VPD_LENGTH_WIDTH 15 +#define FRF_AB_EE_VPD_AD_SIZE_LBN 8 +#define FRF_AB_EE_VPD_AD_SIZE_WIDTH 5 +#define FRF_AB_EE_VPD_ACCESS_ON_LBN 5 +#define FRF_AB_EE_VPD_ACCESS_ON_WIDTH 1 +#define FRF_AB_EE_VPD_ACCESS_BLOCK_LBN 4 +#define FRF_AB_EE_VPD_ACCESS_BLOCK_WIDTH 1 +#define FRF_AB_EE_VPD_DEV_SF_SEL_LBN 2 +#define FRF_AB_EE_VPD_DEV_SF_SEL_WIDTH 1 +#define FRF_AB_EE_VPD_EN_AD9_MODE_LBN 1 +#define FRF_AB_EE_VPD_EN_AD9_MODE_WIDTH 1 +#define FRF_AB_EE_VPD_EN_LBN 0 +#define FRF_AB_EE_VPD_EN_WIDTH 1 + + +/* + * FR_AB_PCIE_SD_CTL0123_REG_SF(128bit): + * PCIE SerDes control register 0 to 3 + */ +#define FR_AB_PCIE_SD_CTL0123_REG_SF_OFST 0x00000320 +/* falcona0,falconb0=eeprom_flash */ +/* + * FR_AB_PCIE_SD_CTL0123_REG(128bit): + * PCIE SerDes control register 0 to 3 + */ +#define FR_AB_PCIE_SD_CTL0123_REG_OFST 0x00000320 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_PCIE_TESTSIG_H_LBN 96 +#define FRF_AB_PCIE_TESTSIG_H_WIDTH 19 +#define FRF_AB_PCIE_TESTSIG_L_LBN 64 +#define FRF_AB_PCIE_TESTSIG_L_WIDTH 19 +#define FRF_AB_PCIE_OFFSET_LBN 56 +#define FRF_AB_PCIE_OFFSET_WIDTH 8 +#define FRF_AB_PCIE_OFFSETEN_H_LBN 55 +#define FRF_AB_PCIE_OFFSETEN_H_WIDTH 1 +#define FRF_AB_PCIE_OFFSETEN_L_LBN 54 +#define FRF_AB_PCIE_OFFSETEN_L_WIDTH 1 +#define FRF_AB_PCIE_HIVMODE_H_LBN 53 +#define FRF_AB_PCIE_HIVMODE_H_WIDTH 1 +#define FRF_AB_PCIE_HIVMODE_L_LBN 52 +#define FRF_AB_PCIE_HIVMODE_L_WIDTH 1 +#define FRF_AB_PCIE_PARRESET_H_LBN 51 +#define FRF_AB_PCIE_PARRESET_H_WIDTH 1 +#define FRF_AB_PCIE_PARRESET_L_LBN 50 +#define FRF_AB_PCIE_PARRESET_L_WIDTH 1 +#define FRF_AB_PCIE_LPBKWDRV_H_LBN 49 +#define FRF_AB_PCIE_LPBKWDRV_H_WIDTH 1 +#define FRF_AB_PCIE_LPBKWDRV_L_LBN 48 +#define FRF_AB_PCIE_LPBKWDRV_L_WIDTH 1 +#define FRF_AB_PCIE_LPBK_LBN 40 +#define FRF_AB_PCIE_LPBK_WIDTH 8 +#define FRF_AB_PCIE_PARLPBK_LBN 32 +#define FRF_AB_PCIE_PARLPBK_WIDTH 8 +#define FRF_AB_PCIE_RXTERMADJ_H_LBN 30 +#define FRF_AB_PCIE_RXTERMADJ_H_WIDTH 2 +#define FRF_AB_PCIE_RXTERMADJ_L_LBN 28 +#define FRF_AB_PCIE_RXTERMADJ_L_WIDTH 2 +#define FFE_AB_PCIE_RXTERMADJ_MIN15PCNT 3 +#define FFE_AB_PCIE_RXTERMADJ_PL10PCNT 2 +#define FFE_AB_PCIE_RXTERMADJ_MIN17PCNT 1 +#define FFE_AB_PCIE_RXTERMADJ_NOMNL 0 +#define FRF_AB_PCIE_TXTERMADJ_H_LBN 26 +#define FRF_AB_PCIE_TXTERMADJ_H_WIDTH 2 +#define FRF_AB_PCIE_TXTERMADJ_L_LBN 24 +#define FRF_AB_PCIE_TXTERMADJ_L_WIDTH 2 +#define FFE_AB_PCIE_TXTERMADJ_MIN15PCNT 3 +#define FFE_AB_PCIE_TXTERMADJ_PL10PCNT 2 +#define FFE_AB_PCIE_TXTERMADJ_MIN17PCNT 1 +#define FFE_AB_PCIE_TXTERMADJ_NOMNL 0 +#define FRF_AB_PCIE_RXEQCTL_H_LBN 18 +#define FRF_AB_PCIE_RXEQCTL_H_WIDTH 2 +#define FRF_AB_PCIE_RXEQCTL_L_LBN 16 +#define FRF_AB_PCIE_RXEQCTL_L_WIDTH 2 +#define FFE_AB_PCIE_RXEQCTL_OFF_ALT 3 +#define FFE_AB_PCIE_RXEQCTL_OFF 2 +#define FFE_AB_PCIE_RXEQCTL_MIN 1 +#define FFE_AB_PCIE_RXEQCTL_MAX 0 +#define FRF_AB_PCIE_HIDRV_LBN 8 +#define FRF_AB_PCIE_HIDRV_WIDTH 8 +#define FRF_AB_PCIE_LODRV_LBN 0 +#define FRF_AB_PCIE_LODRV_WIDTH 8 + + +/* + * FR_AB_PCIE_SD_CTL45_REG_SF(128bit): + * PCIE SerDes control register 4 and 5 + */ +#define FR_AB_PCIE_SD_CTL45_REG_SF_OFST 0x00000330 +/* falcona0,falconb0=eeprom_flash */ +/* + * FR_AB_PCIE_SD_CTL45_REG(128bit): + * PCIE SerDes control register 4 and 5 + */ +#define FR_AB_PCIE_SD_CTL45_REG_OFST 0x00000330 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_PCIE_DTX7_LBN 60 +#define FRF_AB_PCIE_DTX7_WIDTH 4 +#define FRF_AB_PCIE_DTX6_LBN 56 +#define FRF_AB_PCIE_DTX6_WIDTH 4 +#define FRF_AB_PCIE_DTX5_LBN 52 +#define FRF_AB_PCIE_DTX5_WIDTH 4 +#define FRF_AB_PCIE_DTX4_LBN 48 +#define FRF_AB_PCIE_DTX4_WIDTH 4 +#define FRF_AB_PCIE_DTX3_LBN 44 +#define FRF_AB_PCIE_DTX3_WIDTH 4 +#define FRF_AB_PCIE_DTX2_LBN 40 +#define FRF_AB_PCIE_DTX2_WIDTH 4 +#define FRF_AB_PCIE_DTX1_LBN 36 +#define FRF_AB_PCIE_DTX1_WIDTH 4 +#define FRF_AB_PCIE_DTX0_LBN 32 +#define FRF_AB_PCIE_DTX0_WIDTH 4 +#define FRF_AB_PCIE_DEQ7_LBN 28 +#define FRF_AB_PCIE_DEQ7_WIDTH 4 +#define FRF_AB_PCIE_DEQ6_LBN 24 +#define FRF_AB_PCIE_DEQ6_WIDTH 4 +#define FRF_AB_PCIE_DEQ5_LBN 20 +#define FRF_AB_PCIE_DEQ5_WIDTH 4 +#define FRF_AB_PCIE_DEQ4_LBN 16 +#define FRF_AB_PCIE_DEQ4_WIDTH 4 +#define FRF_AB_PCIE_DEQ3_LBN 12 +#define FRF_AB_PCIE_DEQ3_WIDTH 4 +#define FRF_AB_PCIE_DEQ2_LBN 8 +#define FRF_AB_PCIE_DEQ2_WIDTH 4 +#define FRF_AB_PCIE_DEQ1_LBN 4 +#define FRF_AB_PCIE_DEQ1_WIDTH 4 +#define FRF_AB_PCIE_DEQ0_LBN 0 +#define FRF_AB_PCIE_DEQ0_WIDTH 4 + + +/* + * FR_AB_PCIE_PCS_CTL_STAT_REG_SF(128bit): + * PCIE PCS control and status register + */ +#define FR_AB_PCIE_PCS_CTL_STAT_REG_SF_OFST 0x00000340 +/* falcona0,falconb0=eeprom_flash */ +/* + * FR_AB_PCIE_PCS_CTL_STAT_REG(128bit): + * PCIE PCS control and status register + */ +#define FR_AB_PCIE_PCS_CTL_STAT_REG_OFST 0x00000340 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_PCIE_PRBSERRCOUNT0_H_LBN 52 +#define FRF_AB_PCIE_PRBSERRCOUNT0_H_WIDTH 4 +#define FRF_AB_PCIE_PRBSERRCOUNT0_L_LBN 48 +#define FRF_AB_PCIE_PRBSERRCOUNT0_L_WIDTH 4 +#define FRF_AB_PCIE_PRBSERR_LBN 40 +#define FRF_AB_PCIE_PRBSERR_WIDTH 8 +#define FRF_AB_PCIE_PRBSERRH0_LBN 32 +#define FRF_AB_PCIE_PRBSERRH0_WIDTH 8 +#define FRF_AB_PCIE_FASTINIT_H_LBN 15 +#define FRF_AB_PCIE_FASTINIT_H_WIDTH 1 +#define FRF_AB_PCIE_FASTINIT_L_LBN 14 +#define FRF_AB_PCIE_FASTINIT_L_WIDTH 1 +#define FRF_AB_PCIE_CTCDISABLE_H_LBN 13 +#define FRF_AB_PCIE_CTCDISABLE_H_WIDTH 1 +#define FRF_AB_PCIE_CTCDISABLE_L_LBN 12 +#define FRF_AB_PCIE_CTCDISABLE_L_WIDTH 1 +#define FRF_AB_PCIE_PRBSSYNC_H_LBN 11 +#define FRF_AB_PCIE_PRBSSYNC_H_WIDTH 1 +#define FRF_AB_PCIE_PRBSSYNC_L_LBN 10 +#define FRF_AB_PCIE_PRBSSYNC_L_WIDTH 1 +#define FRF_AB_PCIE_PRBSERRACK_H_LBN 9 +#define FRF_AB_PCIE_PRBSERRACK_H_WIDTH 1 +#define FRF_AB_PCIE_PRBSERRACK_L_LBN 8 +#define FRF_AB_PCIE_PRBSERRACK_L_WIDTH 1 +#define FRF_AB_PCIE_PRBSSEL_LBN 0 +#define FRF_AB_PCIE_PRBSSEL_WIDTH 8 + + +/* + * FR_AB_HW_INIT_REG_SF(128bit): + * Hardware initialization register + */ +#define FR_AB_HW_INIT_REG_SF_OFST 0x00000350 +/* falcona0,falconb0=eeprom_flash */ +/* + * FR_AZ_HW_INIT_REG(128bit): + * Hardware initialization register + */ +#define FR_AZ_HW_INIT_REG_OFST 0x000000c0 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_BB_BDMRD_CPLF_FULL_LBN 124 +#define FRF_BB_BDMRD_CPLF_FULL_WIDTH 1 +#define FRF_BB_PCIE_CPL_TIMEOUT_CTRL_LBN 121 +#define FRF_BB_PCIE_CPL_TIMEOUT_CTRL_WIDTH 3 +#define FRF_CZ_TX_MRG_TAGS_LBN 120 +#define FRF_CZ_TX_MRG_TAGS_WIDTH 1 +#define FRF_AZ_TRGT_MASK_ALL_LBN 100 +#define FRF_AZ_TRGT_MASK_ALL_WIDTH 1 +#define FRF_AZ_DOORBELL_DROP_LBN 92 +#define FRF_AZ_DOORBELL_DROP_WIDTH 8 +#define FRF_AB_TX_RREQ_MASK_EN_LBN 76 +#define FRF_AB_TX_RREQ_MASK_EN_WIDTH 1 +#define FRF_AB_PE_EIDLE_DIS_LBN 75 +#define FRF_AB_PE_EIDLE_DIS_WIDTH 1 +#define FRF_AZ_FC_BLOCKING_EN_LBN 45 +#define FRF_AZ_FC_BLOCKING_EN_WIDTH 1 +#define FRF_AZ_B2B_REQ_EN_LBN 44 +#define FRF_AZ_B2B_REQ_EN_WIDTH 1 +#define FRF_AZ_POST_WR_MASK_LBN 40 +#define FRF_AZ_POST_WR_MASK_WIDTH 4 +#define FRF_AZ_TLP_TC_LBN 34 +#define FRF_AZ_TLP_TC_WIDTH 3 +#define FRF_AZ_TLP_ATTR_LBN 32 +#define FRF_AZ_TLP_ATTR_WIDTH 2 +#define FRF_AB_INTB_VEC_LBN 24 +#define FRF_AB_INTB_VEC_WIDTH 5 +#define FRF_AB_INTA_VEC_LBN 16 +#define FRF_AB_INTA_VEC_WIDTH 5 +#define FRF_AZ_WD_TIMER_LBN 8 +#define FRF_AZ_WD_TIMER_WIDTH 8 +#define FRF_AZ_US_DISABLE_LBN 5 +#define FRF_AZ_US_DISABLE_WIDTH 1 +#define FRF_AZ_TLP_EP_LBN 4 +#define FRF_AZ_TLP_EP_WIDTH 1 +#define FRF_AZ_ATTR_SEL_LBN 3 +#define FRF_AZ_ATTR_SEL_WIDTH 1 +#define FRF_AZ_TD_SEL_LBN 1 +#define FRF_AZ_TD_SEL_WIDTH 1 +#define FRF_AZ_TLP_TD_LBN 0 +#define FRF_AZ_TLP_TD_WIDTH 1 + + +/* + * FR_AB_NIC_STAT_REG_SF(128bit): + * NIC status register + */ +#define FR_AB_NIC_STAT_REG_SF_OFST 0x00000360 +/* falcona0,falconb0=eeprom_flash */ +/* + * FR_AB_NIC_STAT_REG(128bit): + * NIC status register + */ +#define FR_AB_NIC_STAT_REG_OFST 0x00000200 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_BB_AER_DIS_LBN 34 +#define FRF_BB_AER_DIS_WIDTH 1 +#define FRF_BB_EE_STRAP_EN_LBN 31 +#define FRF_BB_EE_STRAP_EN_WIDTH 1 +#define FRF_BB_EE_STRAP_LBN 24 +#define FRF_BB_EE_STRAP_WIDTH 4 +#define FRF_BB_REVISION_ID_LBN 17 +#define FRF_BB_REVISION_ID_WIDTH 7 +#define FRF_AB_ONCHIP_SRAM_LBN 16 +#define FRF_AB_ONCHIP_SRAM_WIDTH 1 +#define FRF_AB_SF_PRST_LBN 9 +#define FRF_AB_SF_PRST_WIDTH 1 +#define FRF_AB_EE_PRST_LBN 8 +#define FRF_AB_EE_PRST_WIDTH 1 +#define FRF_AB_ATE_MODE_LBN 3 +#define FRF_AB_ATE_MODE_WIDTH 1 +#define FRF_AB_STRAP_PINS_LBN 0 +#define FRF_AB_STRAP_PINS_WIDTH 3 + + +/* + * FR_AB_GLB_CTL_REG_SF(128bit): + * Global control register + */ +#define FR_AB_GLB_CTL_REG_SF_OFST 0x00000370 +/* falcona0,falconb0=eeprom_flash */ +/* + * FR_AB_GLB_CTL_REG(128bit): + * Global control register + */ +#define FR_AB_GLB_CTL_REG_OFST 0x00000220 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_EXT_PHY_RST_CTL_LBN 63 +#define FRF_AB_EXT_PHY_RST_CTL_WIDTH 1 +#define FRF_AB_XAUI_SD_RST_CTL_LBN 62 +#define FRF_AB_XAUI_SD_RST_CTL_WIDTH 1 +#define FRF_AB_PCIE_SD_RST_CTL_LBN 61 +#define FRF_AB_PCIE_SD_RST_CTL_WIDTH 1 +#define FRF_AA_PCIX_RST_CTL_LBN 60 +#define FRF_AA_PCIX_RST_CTL_WIDTH 1 +#define FRF_BB_BIU_RST_CTL_LBN 60 +#define FRF_BB_BIU_RST_CTL_WIDTH 1 +#define FRF_AB_PCIE_STKY_RST_CTL_LBN 59 +#define FRF_AB_PCIE_STKY_RST_CTL_WIDTH 1 +#define FRF_AB_PCIE_NSTKY_RST_CTL_LBN 58 +#define FRF_AB_PCIE_NSTKY_RST_CTL_WIDTH 1 +#define FRF_AB_PCIE_CORE_RST_CTL_LBN 57 +#define FRF_AB_PCIE_CORE_RST_CTL_WIDTH 1 +#define FRF_AB_XGRX_RST_CTL_LBN 56 +#define FRF_AB_XGRX_RST_CTL_WIDTH 1 +#define FRF_AB_XGTX_RST_CTL_LBN 55 +#define FRF_AB_XGTX_RST_CTL_WIDTH 1 +#define FRF_AB_EM_RST_CTL_LBN 54 +#define FRF_AB_EM_RST_CTL_WIDTH 1 +#define FRF_AB_EV_RST_CTL_LBN 53 +#define FRF_AB_EV_RST_CTL_WIDTH 1 +#define FRF_AB_SR_RST_CTL_LBN 52 +#define FRF_AB_SR_RST_CTL_WIDTH 1 +#define FRF_AB_RX_RST_CTL_LBN 51 +#define FRF_AB_RX_RST_CTL_WIDTH 1 +#define FRF_AB_TX_RST_CTL_LBN 50 +#define FRF_AB_TX_RST_CTL_WIDTH 1 +#define FRF_AB_EE_RST_CTL_LBN 49 +#define FRF_AB_EE_RST_CTL_WIDTH 1 +#define FRF_AB_CS_RST_CTL_LBN 48 +#define FRF_AB_CS_RST_CTL_WIDTH 1 +#define FRF_AB_HOT_RST_CTL_LBN 40 +#define FRF_AB_HOT_RST_CTL_WIDTH 2 +#define FRF_AB_RST_EXT_PHY_LBN 31 +#define FRF_AB_RST_EXT_PHY_WIDTH 1 +#define FRF_AB_RST_XAUI_SD_LBN 30 +#define FRF_AB_RST_XAUI_SD_WIDTH 1 +#define FRF_AB_RST_PCIE_SD_LBN 29 +#define FRF_AB_RST_PCIE_SD_WIDTH 1 +#define FRF_AA_RST_PCIX_LBN 28 +#define FRF_AA_RST_PCIX_WIDTH 1 +#define FRF_BB_RST_BIU_LBN 28 +#define FRF_BB_RST_BIU_WIDTH 1 +#define FRF_AB_RST_PCIE_STKY_LBN 27 +#define FRF_AB_RST_PCIE_STKY_WIDTH 1 +#define FRF_AB_RST_PCIE_NSTKY_LBN 26 +#define FRF_AB_RST_PCIE_NSTKY_WIDTH 1 +#define FRF_AB_RST_PCIE_CORE_LBN 25 +#define FRF_AB_RST_PCIE_CORE_WIDTH 1 +#define FRF_AB_RST_XGRX_LBN 24 +#define FRF_AB_RST_XGRX_WIDTH 1 +#define FRF_AB_RST_XGTX_LBN 23 +#define FRF_AB_RST_XGTX_WIDTH 1 +#define FRF_AB_RST_EM_LBN 22 +#define FRF_AB_RST_EM_WIDTH 1 +#define FRF_AB_RST_EV_LBN 21 +#define FRF_AB_RST_EV_WIDTH 1 +#define FRF_AB_RST_SR_LBN 20 +#define FRF_AB_RST_SR_WIDTH 1 +#define FRF_AB_RST_RX_LBN 19 +#define FRF_AB_RST_RX_WIDTH 1 +#define FRF_AB_RST_TX_LBN 18 +#define FRF_AB_RST_TX_WIDTH 1 +#define FRF_AB_RST_SF_LBN 17 +#define FRF_AB_RST_SF_WIDTH 1 +#define FRF_AB_RST_CS_LBN 16 +#define FRF_AB_RST_CS_WIDTH 1 +#define FRF_AB_INT_RST_DUR_LBN 4 +#define FRF_AB_INT_RST_DUR_WIDTH 3 +#define FRF_AB_EXT_PHY_RST_DUR_LBN 1 +#define FRF_AB_EXT_PHY_RST_DUR_WIDTH 3 +#define FFE_AB_EXT_PHY_RST_DUR_10240US 7 +#define FFE_AB_EXT_PHY_RST_DUR_5120US 6 +#define FFE_AB_EXT_PHY_RST_DUR_2560US 5 +#define FFE_AB_EXT_PHY_RST_DUR_1280US 4 +#define FFE_AB_EXT_PHY_RST_DUR_640US 3 +#define FFE_AB_EXT_PHY_RST_DUR_320US 2 +#define FFE_AB_EXT_PHY_RST_DUR_160US 1 +#define FFE_AB_EXT_PHY_RST_DUR_80US 0 +#define FRF_AB_SWRST_LBN 0 +#define FRF_AB_SWRST_WIDTH 1 + + +/* + * FR_AZ_IOM_IND_ADR_REG(32bit): + * IO-mapped indirect access address register + */ +#define FR_AZ_IOM_IND_ADR_REG_OFST 0x00000000 +/* falcona0,falconb0,sienaa0=net_func_bar0 */ + +#define FRF_AZ_IOM_AUTO_ADR_INC_EN_LBN 24 +#define FRF_AZ_IOM_AUTO_ADR_INC_EN_WIDTH 1 +#define FRF_AZ_IOM_IND_ADR_LBN 0 +#define FRF_AZ_IOM_IND_ADR_WIDTH 24 + + +/* + * FR_AZ_IOM_IND_DAT_REG(32bit): + * IO-mapped indirect access data register + */ +#define FR_AZ_IOM_IND_DAT_REG_OFST 0x00000004 +/* falcona0,falconb0,sienaa0=net_func_bar0 */ + +#define FRF_AZ_IOM_IND_DAT_LBN 0 +#define FRF_AZ_IOM_IND_DAT_WIDTH 32 + + +/* + * FR_AZ_ADR_REGION_REG(128bit): + * Address region register + */ +#define FR_AZ_ADR_REGION_REG_OFST 0x00000000 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_ADR_REGION3_LBN 96 +#define FRF_AZ_ADR_REGION3_WIDTH 18 +#define FRF_AZ_ADR_REGION2_LBN 64 +#define FRF_AZ_ADR_REGION2_WIDTH 18 +#define FRF_AZ_ADR_REGION1_LBN 32 +#define FRF_AZ_ADR_REGION1_WIDTH 18 +#define FRF_AZ_ADR_REGION0_LBN 0 +#define FRF_AZ_ADR_REGION0_WIDTH 18 + + +/* + * FR_AZ_INT_EN_REG_KER(128bit): + * Kernel driver Interrupt enable register + */ +#define FR_AZ_INT_EN_REG_KER_OFST 0x00000010 +/* falcona0,falconb0,sienaa0=net_func_bar2 */ + +#define FRF_AZ_KER_INT_LEVE_SEL_LBN 8 +#define FRF_AZ_KER_INT_LEVE_SEL_WIDTH 6 +#define FRF_AZ_KER_INT_CHAR_LBN 4 +#define FRF_AZ_KER_INT_CHAR_WIDTH 1 +#define FRF_AZ_KER_INT_KER_LBN 3 +#define FRF_AZ_KER_INT_KER_WIDTH 1 +#define FRF_AZ_DRV_INT_EN_KER_LBN 0 +#define FRF_AZ_DRV_INT_EN_KER_WIDTH 1 + + +/* + * FR_AZ_INT_EN_REG_CHAR(128bit): + * Char Driver interrupt enable register + */ +#define FR_AZ_INT_EN_REG_CHAR_OFST 0x00000020 +/* falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_CHAR_INT_LEVE_SEL_LBN 8 +#define FRF_AZ_CHAR_INT_LEVE_SEL_WIDTH 6 +#define FRF_AZ_CHAR_INT_CHAR_LBN 4 +#define FRF_AZ_CHAR_INT_CHAR_WIDTH 1 +#define FRF_AZ_CHAR_INT_KER_LBN 3 +#define FRF_AZ_CHAR_INT_KER_WIDTH 1 +#define FRF_AZ_DRV_INT_EN_CHAR_LBN 0 +#define FRF_AZ_DRV_INT_EN_CHAR_WIDTH 1 + + +/* + * FR_AZ_INT_ADR_REG_KER(128bit): + * Interrupt host address for Kernel driver + */ +#define FR_AZ_INT_ADR_REG_KER_OFST 0x00000030 +/* falcona0,falconb0,sienaa0=net_func_bar2 */ + +#define FRF_AZ_NORM_INT_VEC_DIS_KER_LBN 64 +#define FRF_AZ_NORM_INT_VEC_DIS_KER_WIDTH 1 +#define FRF_AZ_INT_ADR_KER_LBN 0 +#define FRF_AZ_INT_ADR_KER_WIDTH 64 +#define FRF_AZ_INT_ADR_KER_DW0_LBN 0 +#define FRF_AZ_INT_ADR_KER_DW0_WIDTH 32 +#define FRF_AZ_INT_ADR_KER_DW1_LBN 32 +#define FRF_AZ_INT_ADR_KER_DW1_WIDTH 32 + + +/* + * FR_AZ_INT_ADR_REG_CHAR(128bit): + * Interrupt host address for Char driver + */ +#define FR_AZ_INT_ADR_REG_CHAR_OFST 0x00000040 +/* falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_NORM_INT_VEC_DIS_CHAR_LBN 64 +#define FRF_AZ_NORM_INT_VEC_DIS_CHAR_WIDTH 1 +#define FRF_AZ_INT_ADR_CHAR_LBN 0 +#define FRF_AZ_INT_ADR_CHAR_WIDTH 64 +#define FRF_AZ_INT_ADR_CHAR_DW0_LBN 0 +#define FRF_AZ_INT_ADR_CHAR_DW0_WIDTH 32 +#define FRF_AZ_INT_ADR_CHAR_DW1_LBN 32 +#define FRF_AZ_INT_ADR_CHAR_DW1_WIDTH 32 + + +/* + * FR_AA_INT_ACK_KER(32bit): + * Kernel interrupt acknowledge register + */ +#define FR_AA_INT_ACK_KER_OFST 0x00000050 +/* falcona0=net_func_bar2 */ + +#define FRF_AA_INT_ACK_KER_FIELD_LBN 0 +#define FRF_AA_INT_ACK_KER_FIELD_WIDTH 32 + + +/* + * FR_BZ_INT_ISR0_REG(128bit): + * Function 0 Interrupt Acknowlege Status register + */ +#define FR_BZ_INT_ISR0_REG_OFST 0x00000090 +/* falconb0,sienaa0=net_func_bar2 */ + +#define FRF_BZ_INT_ISR_REG_LBN 0 +#define FRF_BZ_INT_ISR_REG_WIDTH 64 +#define FRF_BZ_INT_ISR_REG_DW0_LBN 0 +#define FRF_BZ_INT_ISR_REG_DW0_WIDTH 32 +#define FRF_BZ_INT_ISR_REG_DW1_LBN 32 +#define FRF_BZ_INT_ISR_REG_DW1_WIDTH 32 + + +/* + * FR_AB_EE_SPI_HCMD_REG(128bit): + * SPI host command register + */ +#define FR_AB_EE_SPI_HCMD_REG_OFST 0x00000100 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_EE_SPI_HCMD_CMD_EN_LBN 31 +#define FRF_AB_EE_SPI_HCMD_CMD_EN_WIDTH 1 +#define FRF_AB_EE_WR_TIMER_ACTIVE_LBN 28 +#define FRF_AB_EE_WR_TIMER_ACTIVE_WIDTH 1 +#define FRF_AB_EE_SPI_HCMD_SF_SEL_LBN 24 +#define FRF_AB_EE_SPI_HCMD_SF_SEL_WIDTH 1 +#define FRF_AB_EE_SPI_HCMD_DABCNT_LBN 16 +#define FRF_AB_EE_SPI_HCMD_DABCNT_WIDTH 5 +#define FRF_AB_EE_SPI_HCMD_READ_LBN 15 +#define FRF_AB_EE_SPI_HCMD_READ_WIDTH 1 +#define FRF_AB_EE_SPI_HCMD_DUBCNT_LBN 12 +#define FRF_AB_EE_SPI_HCMD_DUBCNT_WIDTH 2 +#define FRF_AB_EE_SPI_HCMD_ADBCNT_LBN 8 +#define FRF_AB_EE_SPI_HCMD_ADBCNT_WIDTH 2 +#define FRF_AB_EE_SPI_HCMD_ENC_LBN 0 +#define FRF_AB_EE_SPI_HCMD_ENC_WIDTH 8 + + +/* + * FR_CZ_USR_EV_CFG(32bit): + * User Level Event Configuration register + */ +#define FR_CZ_USR_EV_CFG_OFST 0x00000100 +/* sienaa0=net_func_bar2 */ + +#define FRF_CZ_USREV_DIS_LBN 16 +#define FRF_CZ_USREV_DIS_WIDTH 1 +#define FRF_CZ_DFLT_EVQ_LBN 0 +#define FRF_CZ_DFLT_EVQ_WIDTH 10 + + +/* + * FR_AB_EE_SPI_HADR_REG(128bit): + * SPI host address register + */ +#define FR_AB_EE_SPI_HADR_REG_OFST 0x00000110 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_EE_SPI_HADR_DUBYTE_LBN 24 +#define FRF_AB_EE_SPI_HADR_DUBYTE_WIDTH 8 +#define FRF_AB_EE_SPI_HADR_ADR_LBN 0 +#define FRF_AB_EE_SPI_HADR_ADR_WIDTH 24 + + +/* + * FR_AB_EE_SPI_HDATA_REG(128bit): + * SPI host data register + */ +#define FR_AB_EE_SPI_HDATA_REG_OFST 0x00000120 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_EE_SPI_HDATA3_LBN 96 +#define FRF_AB_EE_SPI_HDATA3_WIDTH 32 +#define FRF_AB_EE_SPI_HDATA2_LBN 64 +#define FRF_AB_EE_SPI_HDATA2_WIDTH 32 +#define FRF_AB_EE_SPI_HDATA1_LBN 32 +#define FRF_AB_EE_SPI_HDATA1_WIDTH 32 +#define FRF_AB_EE_SPI_HDATA0_LBN 0 +#define FRF_AB_EE_SPI_HDATA0_WIDTH 32 + + +/* + * FR_AB_EE_BASE_PAGE_REG(128bit): + * Expansion ROM base mirror register + */ +#define FR_AB_EE_BASE_PAGE_REG_OFST 0x00000130 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_EE_EXPROM_MASK_LBN 16 +#define FRF_AB_EE_EXPROM_MASK_WIDTH 13 +#define FRF_AB_EE_EXP_ROM_WINDOW_BASE_LBN 0 +#define FRF_AB_EE_EXP_ROM_WINDOW_BASE_WIDTH 13 + + +/* + * FR_AB_EE_VPD_SW_CNTL_REG(128bit): + * VPD access SW control register + */ +#define FR_AB_EE_VPD_SW_CNTL_REG_OFST 0x00000150 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_EE_VPD_CYCLE_PENDING_LBN 31 +#define FRF_AB_EE_VPD_CYCLE_PENDING_WIDTH 1 +#define FRF_AB_EE_VPD_CYC_WRITE_LBN 28 +#define FRF_AB_EE_VPD_CYC_WRITE_WIDTH 1 +#define FRF_AB_EE_VPD_CYC_ADR_LBN 0 +#define FRF_AB_EE_VPD_CYC_ADR_WIDTH 15 + + +/* + * FR_AB_EE_VPD_SW_DATA_REG(128bit): + * VPD access SW data register + */ +#define FR_AB_EE_VPD_SW_DATA_REG_OFST 0x00000160 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_EE_VPD_CYC_DAT_LBN 0 +#define FRF_AB_EE_VPD_CYC_DAT_WIDTH 32 + + +/* + * FR_BB_PCIE_CORE_INDIRECT_REG(64bit): + * Indirect Access to PCIE Core registers + */ +#define FR_BB_PCIE_CORE_INDIRECT_REG_OFST 0x000001f0 +/* falconb0=net_func_bar2 */ + +#define FRF_BB_PCIE_CORE_TARGET_DATA_LBN 32 +#define FRF_BB_PCIE_CORE_TARGET_DATA_WIDTH 32 +#define FRF_BB_PCIE_CORE_INDIRECT_ACCESS_DIR_LBN 15 +#define FRF_BB_PCIE_CORE_INDIRECT_ACCESS_DIR_WIDTH 1 +#define FRF_BB_PCIE_CORE_TARGET_REG_ADRS_LBN 0 +#define FRF_BB_PCIE_CORE_TARGET_REG_ADRS_WIDTH 12 + + +/* + * FR_AB_GPIO_CTL_REG(128bit): + * GPIO control register + */ +#define FR_AB_GPIO_CTL_REG_OFST 0x00000210 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_GPIO15_OEN_LBN 63 +#define FRF_AB_GPIO15_OEN_WIDTH 1 +#define FRF_AB_GPIO14_OEN_LBN 62 +#define FRF_AB_GPIO14_OEN_WIDTH 1 +#define FRF_AB_GPIO13_OEN_LBN 61 +#define FRF_AB_GPIO13_OEN_WIDTH 1 +#define FRF_AB_GPIO12_OEN_LBN 60 +#define FRF_AB_GPIO12_OEN_WIDTH 1 +#define FRF_AB_GPIO11_OEN_LBN 59 +#define FRF_AB_GPIO11_OEN_WIDTH 1 +#define FRF_AB_GPIO10_OEN_LBN 58 +#define FRF_AB_GPIO10_OEN_WIDTH 1 +#define FRF_AB_GPIO9_OEN_LBN 57 +#define FRF_AB_GPIO9_OEN_WIDTH 1 +#define FRF_AB_GPIO8_OEN_LBN 56 +#define FRF_AB_GPIO8_OEN_WIDTH 1 +#define FRF_AB_GPIO15_OUT_LBN 55 +#define FRF_AB_GPIO15_OUT_WIDTH 1 +#define FRF_AB_GPIO14_OUT_LBN 54 +#define FRF_AB_GPIO14_OUT_WIDTH 1 +#define FRF_AB_GPIO13_OUT_LBN 53 +#define FRF_AB_GPIO13_OUT_WIDTH 1 +#define FRF_AB_GPIO12_OUT_LBN 52 +#define FRF_AB_GPIO12_OUT_WIDTH 1 +#define FRF_AB_GPIO11_OUT_LBN 51 +#define FRF_AB_GPIO11_OUT_WIDTH 1 +#define FRF_AB_GPIO10_OUT_LBN 50 +#define FRF_AB_GPIO10_OUT_WIDTH 1 +#define FRF_AB_GPIO9_OUT_LBN 49 +#define FRF_AB_GPIO9_OUT_WIDTH 1 +#define FRF_AB_GPIO8_OUT_LBN 48 +#define FRF_AB_GPIO8_OUT_WIDTH 1 +#define FRF_AB_GPIO15_IN_LBN 47 +#define FRF_AB_GPIO15_IN_WIDTH 1 +#define FRF_AB_GPIO14_IN_LBN 46 +#define FRF_AB_GPIO14_IN_WIDTH 1 +#define FRF_AB_GPIO13_IN_LBN 45 +#define FRF_AB_GPIO13_IN_WIDTH 1 +#define FRF_AB_GPIO12_IN_LBN 44 +#define FRF_AB_GPIO12_IN_WIDTH 1 +#define FRF_AB_GPIO11_IN_LBN 43 +#define FRF_AB_GPIO11_IN_WIDTH 1 +#define FRF_AB_GPIO10_IN_LBN 42 +#define FRF_AB_GPIO10_IN_WIDTH 1 +#define FRF_AB_GPIO9_IN_LBN 41 +#define FRF_AB_GPIO9_IN_WIDTH 1 +#define FRF_AB_GPIO8_IN_LBN 40 +#define FRF_AB_GPIO8_IN_WIDTH 1 +#define FRF_AB_GPIO15_PWRUP_VALUE_LBN 39 +#define FRF_AB_GPIO15_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO14_PWRUP_VALUE_LBN 38 +#define FRF_AB_GPIO14_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO13_PWRUP_VALUE_LBN 37 +#define FRF_AB_GPIO13_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO12_PWRUP_VALUE_LBN 36 +#define FRF_AB_GPIO12_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO11_PWRUP_VALUE_LBN 35 +#define FRF_AB_GPIO11_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO10_PWRUP_VALUE_LBN 34 +#define FRF_AB_GPIO10_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO9_PWRUP_VALUE_LBN 33 +#define FRF_AB_GPIO9_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO8_PWRUP_VALUE_LBN 32 +#define FRF_AB_GPIO8_PWRUP_VALUE_WIDTH 1 +#define FRF_BB_CLK156_OUT_EN_LBN 31 +#define FRF_BB_CLK156_OUT_EN_WIDTH 1 +#define FRF_BB_USE_NIC_CLK_LBN 30 +#define FRF_BB_USE_NIC_CLK_WIDTH 1 +#define FRF_AB_GPIO5_OEN_LBN 29 +#define FRF_AB_GPIO5_OEN_WIDTH 1 +#define FRF_AB_GPIO4_OEN_LBN 28 +#define FRF_AB_GPIO4_OEN_WIDTH 1 +#define FRF_AB_GPIO3_OEN_LBN 27 +#define FRF_AB_GPIO3_OEN_WIDTH 1 +#define FRF_AB_GPIO2_OEN_LBN 26 +#define FRF_AB_GPIO2_OEN_WIDTH 1 +#define FRF_AB_GPIO1_OEN_LBN 25 +#define FRF_AB_GPIO1_OEN_WIDTH 1 +#define FRF_AB_GPIO0_OEN_LBN 24 +#define FRF_AB_GPIO0_OEN_WIDTH 1 +#define FRF_AB_GPIO5_OUT_LBN 21 +#define FRF_AB_GPIO5_OUT_WIDTH 1 +#define FRF_AB_GPIO4_OUT_LBN 20 +#define FRF_AB_GPIO4_OUT_WIDTH 1 +#define FRF_AB_GPIO3_OUT_LBN 19 +#define FRF_AB_GPIO3_OUT_WIDTH 1 +#define FRF_AB_GPIO2_OUT_LBN 18 +#define FRF_AB_GPIO2_OUT_WIDTH 1 +#define FRF_AB_GPIO1_OUT_LBN 17 +#define FRF_AB_GPIO1_OUT_WIDTH 1 +#define FRF_AB_GPIO0_OUT_LBN 16 +#define FRF_AB_GPIO0_OUT_WIDTH 1 +#define FRF_AB_GPIO5_IN_LBN 13 +#define FRF_AB_GPIO5_IN_WIDTH 1 +#define FRF_AB_GPIO4_IN_LBN 12 +#define FRF_AB_GPIO4_IN_WIDTH 1 +#define FRF_AB_GPIO3_IN_LBN 11 +#define FRF_AB_GPIO3_IN_WIDTH 1 +#define FRF_AB_GPIO2_IN_LBN 10 +#define FRF_AB_GPIO2_IN_WIDTH 1 +#define FRF_AB_GPIO1_IN_LBN 9 +#define FRF_AB_GPIO1_IN_WIDTH 1 +#define FRF_AB_GPIO0_IN_LBN 8 +#define FRF_AB_GPIO0_IN_WIDTH 1 +#define FRF_AB_GPIO5_PWRUP_VALUE_LBN 5 +#define FRF_AB_GPIO5_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO4_PWRUP_VALUE_LBN 4 +#define FRF_AB_GPIO4_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO3_PWRUP_VALUE_LBN 3 +#define FRF_AB_GPIO3_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO2_PWRUP_VALUE_LBN 2 +#define FRF_AB_GPIO2_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO1_PWRUP_VALUE_LBN 1 +#define FRF_AB_GPIO1_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO0_PWRUP_VALUE_LBN 0 +#define FRF_AB_GPIO0_PWRUP_VALUE_WIDTH 1 + + +/* + * FR_AZ_FATAL_INTR_REG_KER(128bit): + * Fatal interrupt register for Kernel + */ +#define FR_AZ_FATAL_INTR_REG_KER_OFST 0x00000230 +/* falcona0,falconb0,sienaa0=net_func_bar2 */ + +#define FRF_CZ_SRAM_PERR_INT_P_KER_EN_LBN 44 +#define FRF_CZ_SRAM_PERR_INT_P_KER_EN_WIDTH 1 +#define FRF_AB_PCI_BUSERR_INT_KER_EN_LBN 43 +#define FRF_AB_PCI_BUSERR_INT_KER_EN_WIDTH 1 +#define FRF_CZ_MBU_PERR_INT_KER_EN_LBN 43 +#define FRF_CZ_MBU_PERR_INT_KER_EN_WIDTH 1 +#define FRF_AZ_SRAM_OOB_INT_KER_EN_LBN 42 +#define FRF_AZ_SRAM_OOB_INT_KER_EN_WIDTH 1 +#define FRF_AZ_BUFID_OOB_INT_KER_EN_LBN 41 +#define FRF_AZ_BUFID_OOB_INT_KER_EN_WIDTH 1 +#define FRF_AZ_MEM_PERR_INT_KER_EN_LBN 40 +#define FRF_AZ_MEM_PERR_INT_KER_EN_WIDTH 1 +#define FRF_AZ_RBUF_OWN_INT_KER_EN_LBN 39 +#define FRF_AZ_RBUF_OWN_INT_KER_EN_WIDTH 1 +#define FRF_AZ_TBUF_OWN_INT_KER_EN_LBN 38 +#define FRF_AZ_TBUF_OWN_INT_KER_EN_WIDTH 1 +#define FRF_AZ_RDESCQ_OWN_INT_KER_EN_LBN 37 +#define FRF_AZ_RDESCQ_OWN_INT_KER_EN_WIDTH 1 +#define FRF_AZ_TDESCQ_OWN_INT_KER_EN_LBN 36 +#define FRF_AZ_TDESCQ_OWN_INT_KER_EN_WIDTH 1 +#define FRF_AZ_EVQ_OWN_INT_KER_EN_LBN 35 +#define FRF_AZ_EVQ_OWN_INT_KER_EN_WIDTH 1 +#define FRF_AZ_EVF_OFLO_INT_KER_EN_LBN 34 +#define FRF_AZ_EVF_OFLO_INT_KER_EN_WIDTH 1 +#define FRF_AZ_ILL_ADR_INT_KER_EN_LBN 33 +#define FRF_AZ_ILL_ADR_INT_KER_EN_WIDTH 1 +#define FRF_AZ_SRM_PERR_INT_KER_EN_LBN 32 +#define FRF_AZ_SRM_PERR_INT_KER_EN_WIDTH 1 +#define FRF_CZ_SRAM_PERR_INT_P_KER_LBN 12 +#define FRF_CZ_SRAM_PERR_INT_P_KER_WIDTH 1 +#define FRF_AB_PCI_BUSERR_INT_KER_LBN 11 +#define FRF_AB_PCI_BUSERR_INT_KER_WIDTH 1 +#define FRF_CZ_MBU_PERR_INT_KER_LBN 11 +#define FRF_CZ_MBU_PERR_INT_KER_WIDTH 1 +#define FRF_AZ_SRAM_OOB_INT_KER_LBN 10 +#define FRF_AZ_SRAM_OOB_INT_KER_WIDTH 1 +#define FRF_AZ_BUFID_DC_OOB_INT_KER_LBN 9 +#define FRF_AZ_BUFID_DC_OOB_INT_KER_WIDTH 1 +#define FRF_AZ_MEM_PERR_INT_KER_LBN 8 +#define FRF_AZ_MEM_PERR_INT_KER_WIDTH 1 +#define FRF_AZ_RBUF_OWN_INT_KER_LBN 7 +#define FRF_AZ_RBUF_OWN_INT_KER_WIDTH 1 +#define FRF_AZ_TBUF_OWN_INT_KER_LBN 6 +#define FRF_AZ_TBUF_OWN_INT_KER_WIDTH 1 +#define FRF_AZ_RDESCQ_OWN_INT_KER_LBN 5 +#define FRF_AZ_RDESCQ_OWN_INT_KER_WIDTH 1 +#define FRF_AZ_TDESCQ_OWN_INT_KER_LBN 4 +#define FRF_AZ_TDESCQ_OWN_INT_KER_WIDTH 1 +#define FRF_AZ_EVQ_OWN_INT_KER_LBN 3 +#define FRF_AZ_EVQ_OWN_INT_KER_WIDTH 1 +#define FRF_AZ_EVF_OFLO_INT_KER_LBN 2 +#define FRF_AZ_EVF_OFLO_INT_KER_WIDTH 1 +#define FRF_AZ_ILL_ADR_INT_KER_LBN 1 +#define FRF_AZ_ILL_ADR_INT_KER_WIDTH 1 +#define FRF_AZ_SRM_PERR_INT_KER_LBN 0 +#define FRF_AZ_SRM_PERR_INT_KER_WIDTH 1 + + +/* + * FR_AZ_FATAL_INTR_REG_CHAR(128bit): + * Fatal interrupt register for Char + */ +#define FR_AZ_FATAL_INTR_REG_CHAR_OFST 0x00000240 +/* falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_CZ_SRAM_PERR_INT_P_CHAR_EN_LBN 44 +#define FRF_CZ_SRAM_PERR_INT_P_CHAR_EN_WIDTH 1 +#define FRF_AB_PCI_BUSERR_INT_CHAR_EN_LBN 43 +#define FRF_AB_PCI_BUSERR_INT_CHAR_EN_WIDTH 1 +#define FRF_CZ_MBU_PERR_INT_CHAR_EN_LBN 43 +#define FRF_CZ_MBU_PERR_INT_CHAR_EN_WIDTH 1 +#define FRF_AZ_SRAM_OOB_INT_CHAR_EN_LBN 42 +#define FRF_AZ_SRAM_OOB_INT_CHAR_EN_WIDTH 1 +#define FRF_AZ_BUFID_OOB_INT_CHAR_EN_LBN 41 +#define FRF_AZ_BUFID_OOB_INT_CHAR_EN_WIDTH 1 +#define FRF_AZ_MEM_PERR_INT_CHAR_EN_LBN 40 +#define FRF_AZ_MEM_PERR_INT_CHAR_EN_WIDTH 1 +#define FRF_AZ_RBUF_OWN_INT_CHAR_EN_LBN 39 +#define FRF_AZ_RBUF_OWN_INT_CHAR_EN_WIDTH 1 +#define FRF_AZ_TBUF_OWN_INT_CHAR_EN_LBN 38 +#define FRF_AZ_TBUF_OWN_INT_CHAR_EN_WIDTH 1 +#define FRF_AZ_RDESCQ_OWN_INT_CHAR_EN_LBN 37 +#define FRF_AZ_RDESCQ_OWN_INT_CHAR_EN_WIDTH 1 +#define FRF_AZ_TDESCQ_OWN_INT_CHAR_EN_LBN 36 +#define FRF_AZ_TDESCQ_OWN_INT_CHAR_EN_WIDTH 1 +#define FRF_AZ_EVQ_OWN_INT_CHAR_EN_LBN 35 +#define FRF_AZ_EVQ_OWN_INT_CHAR_EN_WIDTH 1 +#define FRF_AZ_EVF_OFLO_INT_CHAR_EN_LBN 34 +#define FRF_AZ_EVF_OFLO_INT_CHAR_EN_WIDTH 1 +#define FRF_AZ_ILL_ADR_INT_CHAR_EN_LBN 33 +#define FRF_AZ_ILL_ADR_INT_CHAR_EN_WIDTH 1 +#define FRF_AZ_SRM_PERR_INT_CHAR_EN_LBN 32 +#define FRF_AZ_SRM_PERR_INT_CHAR_EN_WIDTH 1 +#define FRF_CZ_SRAM_PERR_INT_P_CHAR_LBN 12 +#define FRF_CZ_SRAM_PERR_INT_P_CHAR_WIDTH 1 +#define FRF_AB_PCI_BUSERR_INT_CHAR_LBN 11 +#define FRF_AB_PCI_BUSERR_INT_CHAR_WIDTH 1 +#define FRF_CZ_MBU_PERR_INT_CHAR_LBN 11 +#define FRF_CZ_MBU_PERR_INT_CHAR_WIDTH 1 +#define FRF_AZ_SRAM_OOB_INT_CHAR_LBN 10 +#define FRF_AZ_SRAM_OOB_INT_CHAR_WIDTH 1 +#define FRF_AZ_BUFID_DC_OOB_INT_CHAR_LBN 9 +#define FRF_AZ_BUFID_DC_OOB_INT_CHAR_WIDTH 1 +#define FRF_AZ_MEM_PERR_INT_CHAR_LBN 8 +#define FRF_AZ_MEM_PERR_INT_CHAR_WIDTH 1 +#define FRF_AZ_RBUF_OWN_INT_CHAR_LBN 7 +#define FRF_AZ_RBUF_OWN_INT_CHAR_WIDTH 1 +#define FRF_AZ_TBUF_OWN_INT_CHAR_LBN 6 +#define FRF_AZ_TBUF_OWN_INT_CHAR_WIDTH 1 +#define FRF_AZ_RDESCQ_OWN_INT_CHAR_LBN 5 +#define FRF_AZ_RDESCQ_OWN_INT_CHAR_WIDTH 1 +#define FRF_AZ_TDESCQ_OWN_INT_CHAR_LBN 4 +#define FRF_AZ_TDESCQ_OWN_INT_CHAR_WIDTH 1 +#define FRF_AZ_EVQ_OWN_INT_CHAR_LBN 3 +#define FRF_AZ_EVQ_OWN_INT_CHAR_WIDTH 1 +#define FRF_AZ_EVF_OFLO_INT_CHAR_LBN 2 +#define FRF_AZ_EVF_OFLO_INT_CHAR_WIDTH 1 +#define FRF_AZ_ILL_ADR_INT_CHAR_LBN 1 +#define FRF_AZ_ILL_ADR_INT_CHAR_WIDTH 1 +#define FRF_AZ_SRM_PERR_INT_CHAR_LBN 0 +#define FRF_AZ_SRM_PERR_INT_CHAR_WIDTH 1 + + +/* + * FR_AZ_DP_CTRL_REG(128bit): + * Datapath control register + */ +#define FR_AZ_DP_CTRL_REG_OFST 0x00000250 +/* falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_FLS_EVQ_ID_LBN 0 +#define FRF_AZ_FLS_EVQ_ID_WIDTH 12 + + +/* + * FR_AZ_MEM_STAT_REG(128bit): + * Memory status register + */ +#define FR_AZ_MEM_STAT_REG_OFST 0x00000260 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_MEM_PERR_VEC_LBN 53 +#define FRF_AB_MEM_PERR_VEC_WIDTH 40 +#define FRF_AB_MEM_PERR_VEC_DW0_LBN 53 +#define FRF_AB_MEM_PERR_VEC_DW0_WIDTH 32 +#define FRF_AB_MEM_PERR_VEC_DW1_LBN 85 +#define FRF_AB_MEM_PERR_VEC_DW1_WIDTH 6 +#define FRF_AB_MBIST_CORR_LBN 38 +#define FRF_AB_MBIST_CORR_WIDTH 15 +#define FRF_AB_MBIST_ERR_LBN 0 +#define FRF_AB_MBIST_ERR_WIDTH 40 +#define FRF_AB_MBIST_ERR_DW0_LBN 0 +#define FRF_AB_MBIST_ERR_DW0_WIDTH 32 +#define FRF_AB_MBIST_ERR_DW1_LBN 32 +#define FRF_AB_MBIST_ERR_DW1_WIDTH 6 +#define FRF_CZ_MEM_PERR_VEC_LBN 0 +#define FRF_CZ_MEM_PERR_VEC_WIDTH 35 +#define FRF_CZ_MEM_PERR_VEC_DW0_LBN 0 +#define FRF_CZ_MEM_PERR_VEC_DW0_WIDTH 32 +#define FRF_CZ_MEM_PERR_VEC_DW1_LBN 32 +#define FRF_CZ_MEM_PERR_VEC_DW1_WIDTH 3 + + +/* + * FR_PORT0_CS_DEBUG_REG(128bit): + * Debug register + */ + +#define FR_AZ_CS_DEBUG_REG_OFST 0x00000270 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_GLB_DEBUG2_SEL_LBN 50 +#define FRF_AB_GLB_DEBUG2_SEL_WIDTH 3 +#define FRF_AB_DEBUG_BLK_SEL2_LBN 47 +#define FRF_AB_DEBUG_BLK_SEL2_WIDTH 3 +#define FRF_AB_DEBUG_BLK_SEL1_LBN 44 +#define FRF_AB_DEBUG_BLK_SEL1_WIDTH 3 +#define FRF_AB_DEBUG_BLK_SEL0_LBN 41 +#define FRF_AB_DEBUG_BLK_SEL0_WIDTH 3 +#define FRF_CZ_CS_PORT_NUM_LBN 40 +#define FRF_CZ_CS_PORT_NUM_WIDTH 2 +#define FRF_AB_MISC_DEBUG_ADDR_LBN 36 +#define FRF_AB_MISC_DEBUG_ADDR_WIDTH 5 +#define FRF_CZ_CS_RESERVED_LBN 36 +#define FRF_CZ_CS_RESERVED_WIDTH 4 +#define FRF_AB_SERDES_DEBUG_ADDR_LBN 31 +#define FRF_AB_SERDES_DEBUG_ADDR_WIDTH 5 +#define FRF_CZ_CS_PORT_FPE_DW0_LBN 1 +#define FRF_CZ_CS_PORT_FPE_DW0_WIDTH 32 +#define FRF_CZ_CS_PORT_FPE_DW1_LBN 33 +#define FRF_CZ_CS_PORT_FPE_DW1_WIDTH 3 +#define FRF_CZ_CS_PORT_FPE_LBN 1 +#define FRF_CZ_CS_PORT_FPE_WIDTH 35 +#define FRF_AB_EM_DEBUG_ADDR_LBN 26 +#define FRF_AB_EM_DEBUG_ADDR_WIDTH 5 +#define FRF_AB_SR_DEBUG_ADDR_LBN 21 +#define FRF_AB_SR_DEBUG_ADDR_WIDTH 5 +#define FRF_AB_EV_DEBUG_ADDR_LBN 16 +#define FRF_AB_EV_DEBUG_ADDR_WIDTH 5 +#define FRF_AB_RX_DEBUG_ADDR_LBN 11 +#define FRF_AB_RX_DEBUG_ADDR_WIDTH 5 +#define FRF_AB_TX_DEBUG_ADDR_LBN 6 +#define FRF_AB_TX_DEBUG_ADDR_WIDTH 5 +#define FRF_AB_CS_BIU_DEBUG_ADDR_LBN 1 +#define FRF_AB_CS_BIU_DEBUG_ADDR_WIDTH 5 +#define FRF_AZ_CS_DEBUG_EN_LBN 0 +#define FRF_AZ_CS_DEBUG_EN_WIDTH 1 + + +/* + * FR_AZ_DRIVER_REG(128bit): + * Driver scratch register [0-7] + */ +#define FR_AZ_DRIVER_REG_OFST 0x00000280 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ +#define FR_AZ_DRIVER_REG_STEP 16 +#define FR_AZ_DRIVER_REG_ROWS 8 + +#define FRF_AZ_DRIVER_DW0_LBN 0 +#define FRF_AZ_DRIVER_DW0_WIDTH 32 + + +/* + * FR_AZ_ALTERA_BUILD_REG(128bit): + * Altera build register + */ +#define FR_AZ_ALTERA_BUILD_REG_OFST 0x00000300 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_ALTERA_BUILD_VER_LBN 0 +#define FRF_AZ_ALTERA_BUILD_VER_WIDTH 32 + + +/* + * FR_AZ_CSR_SPARE_REG(128bit): + * Spare register + */ +#define FR_AZ_CSR_SPARE_REG_OFST 0x00000310 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_MEM_PERR_EN_TX_DATA_LBN 72 +#define FRF_AZ_MEM_PERR_EN_TX_DATA_WIDTH 2 +#define FRF_AZ_MEM_PERR_EN_LBN 64 +#define FRF_AZ_MEM_PERR_EN_WIDTH 38 +#define FRF_AZ_MEM_PERR_EN_DW0_LBN 64 +#define FRF_AZ_MEM_PERR_EN_DW0_WIDTH 32 +#define FRF_AZ_MEM_PERR_EN_DW1_LBN 96 +#define FRF_AZ_MEM_PERR_EN_DW1_WIDTH 6 +#define FRF_AZ_CSR_SPARE_BITS_LBN 0 +#define FRF_AZ_CSR_SPARE_BITS_WIDTH 32 + + +/* + * FR_BZ_DEBUG_DATA_OUT_REG(128bit): + * Live Debug and Debug 2 out ports + */ +#define FR_BZ_DEBUG_DATA_OUT_REG_OFST 0x00000350 +/* falconb0,sienaa0=net_func_bar2 */ + +#define FRF_BZ_DEBUG2_PORT_LBN 25 +#define FRF_BZ_DEBUG2_PORT_WIDTH 15 +#define FRF_BZ_DEBUG1_PORT_LBN 0 +#define FRF_BZ_DEBUG1_PORT_WIDTH 25 + + +/* + * FR_BZ_EVQ_RPTR_REGP0(32bit): + * Event queue read pointer register + */ +#define FR_BZ_EVQ_RPTR_REGP0_OFST 0x00000400 +/* falconb0,sienaa0=net_func_bar2 */ +#define FR_BZ_EVQ_RPTR_REGP0_STEP 8192 +#define FR_BZ_EVQ_RPTR_REGP0_ROWS 1024 +/* + * FR_AA_EVQ_RPTR_REG_KER(32bit): + * Event queue read pointer register + */ +#define FR_AA_EVQ_RPTR_REG_KER_OFST 0x00011b00 +/* falcona0=net_func_bar2 */ +#define FR_AA_EVQ_RPTR_REG_KER_STEP 4 +#define FR_AA_EVQ_RPTR_REG_KER_ROWS 4 +/* + * FR_AZ_EVQ_RPTR_REG(32bit): + * Event queue read pointer register + */ +#define FR_AZ_EVQ_RPTR_REG_OFST 0x00fa0000 +/* falconb0=net_func_bar2,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ +#define FR_AZ_EVQ_RPTR_REG_STEP 16 +#define FR_AB_EVQ_RPTR_REG_ROWS 4096 +#define FR_CZ_EVQ_RPTR_REG_ROWS 1024 +/* + * FR_BB_EVQ_RPTR_REGP123(32bit): + * Event queue read pointer register + */ +#define FR_BB_EVQ_RPTR_REGP123_OFST 0x01000400 +/* falconb0=net_func_bar2 */ +#define FR_BB_EVQ_RPTR_REGP123_STEP 8192 +#define FR_BB_EVQ_RPTR_REGP123_ROWS 3072 + +#define FRF_AZ_EVQ_RPTR_VLD_LBN 15 +#define FRF_AZ_EVQ_RPTR_VLD_WIDTH 1 +#define FRF_AZ_EVQ_RPTR_LBN 0 +#define FRF_AZ_EVQ_RPTR_WIDTH 15 + + +/* + * FR_BZ_TIMER_COMMAND_REGP0(128bit): + * Timer Command Registers + */ +#define FR_BZ_TIMER_COMMAND_REGP0_OFST 0x00000420 +/* falconb0,sienaa0=net_func_bar2 */ +#define FR_BZ_TIMER_COMMAND_REGP0_STEP 8192 +#define FR_BZ_TIMER_COMMAND_REGP0_ROWS 1024 +/* + * FR_AA_TIMER_COMMAND_REG_KER(128bit): + * Timer Command Registers + */ +#define FR_AA_TIMER_COMMAND_REG_KER_OFST 0x00000420 +/* falcona0=net_func_bar2 */ +#define FR_AA_TIMER_COMMAND_REG_KER_STEP 8192 +#define FR_AA_TIMER_COMMAND_REG_KER_ROWS 4 +/* + * FR_AB_TIMER_COMMAND_REGP123(128bit): + * Timer Command Registers + */ +#define FR_AB_TIMER_COMMAND_REGP123_OFST 0x01000420 +/* falconb0=net_func_bar2,falcona0=char_func_bar0 */ +#define FR_AB_TIMER_COMMAND_REGP123_STEP 8192 +#define FR_AB_TIMER_COMMAND_REGP123_ROWS 3072 +/* + * FR_AA_TIMER_COMMAND_REGP0(128bit): + * Timer Command Registers + */ +#define FR_AA_TIMER_COMMAND_REGP0_OFST 0x00008420 +/* falcona0=char_func_bar0 */ +#define FR_AA_TIMER_COMMAND_REGP0_STEP 8192 +#define FR_AA_TIMER_COMMAND_REGP0_ROWS 1020 + +#define FRF_CZ_TC_TIMER_MODE_LBN 14 +#define FRF_CZ_TC_TIMER_MODE_WIDTH 2 +#define FRF_AB_TC_TIMER_MODE_LBN 12 +#define FRF_AB_TC_TIMER_MODE_WIDTH 2 +#define FRF_CZ_TC_TIMER_VAL_LBN 0 +#define FRF_CZ_TC_TIMER_VAL_WIDTH 14 +#define FRF_AB_TC_TIMER_VAL_LBN 0 +#define FRF_AB_TC_TIMER_VAL_WIDTH 12 + + +/* + * FR_AZ_DRV_EV_REG(128bit): + * Driver generated event register + */ +#define FR_AZ_DRV_EV_REG_OFST 0x00000440 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_DRV_EV_QID_LBN 64 +#define FRF_AZ_DRV_EV_QID_WIDTH 12 +#define FRF_AZ_DRV_EV_DATA_LBN 0 +#define FRF_AZ_DRV_EV_DATA_WIDTH 64 +#define FRF_AZ_DRV_EV_DATA_DW0_LBN 0 +#define FRF_AZ_DRV_EV_DATA_DW0_WIDTH 32 +#define FRF_AZ_DRV_EV_DATA_DW1_LBN 32 +#define FRF_AZ_DRV_EV_DATA_DW1_WIDTH 32 + + +/* + * FR_AZ_EVQ_CTL_REG(128bit): + * Event queue control register + */ +#define FR_AZ_EVQ_CTL_REG_OFST 0x00000450 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_CZ_RX_EVQ_WAKEUP_MASK_LBN 15 +#define FRF_CZ_RX_EVQ_WAKEUP_MASK_WIDTH 10 +#define FRF_BB_RX_EVQ_WAKEUP_MASK_LBN 15 +#define FRF_BB_RX_EVQ_WAKEUP_MASK_WIDTH 6 +#define FRF_AZ_EVQ_OWNERR_CTL_LBN 14 +#define FRF_AZ_EVQ_OWNERR_CTL_WIDTH 1 +#define FRF_AZ_EVQ_FIFO_AF_TH_LBN 7 +#define FRF_AZ_EVQ_FIFO_AF_TH_WIDTH 7 +#define FRF_AZ_EVQ_FIFO_NOTAF_TH_LBN 0 +#define FRF_AZ_EVQ_FIFO_NOTAF_TH_WIDTH 7 + + +/* + * FR_AZ_EVQ_CNT1_REG(128bit): + * Event counter 1 register + */ +#define FR_AZ_EVQ_CNT1_REG_OFST 0x00000460 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_EVQ_CNT_PRE_FIFO_LBN 120 +#define FRF_AZ_EVQ_CNT_PRE_FIFO_WIDTH 7 +#define FRF_AZ_EVQ_CNT_TOBIU_LBN 100 +#define FRF_AZ_EVQ_CNT_TOBIU_WIDTH 20 +#define FRF_AZ_EVQ_TX_REQ_CNT_LBN 80 +#define FRF_AZ_EVQ_TX_REQ_CNT_WIDTH 20 +#define FRF_AZ_EVQ_RX_REQ_CNT_LBN 60 +#define FRF_AZ_EVQ_RX_REQ_CNT_WIDTH 20 +#define FRF_AZ_EVQ_EM_REQ_CNT_LBN 40 +#define FRF_AZ_EVQ_EM_REQ_CNT_WIDTH 20 +#define FRF_AZ_EVQ_CSR_REQ_CNT_LBN 20 +#define FRF_AZ_EVQ_CSR_REQ_CNT_WIDTH 20 +#define FRF_AZ_EVQ_ERR_REQ_CNT_LBN 0 +#define FRF_AZ_EVQ_ERR_REQ_CNT_WIDTH 20 + + +/* + * FR_AZ_EVQ_CNT2_REG(128bit): + * Event counter 2 register + */ +#define FR_AZ_EVQ_CNT2_REG_OFST 0x00000470 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_EVQ_UPD_REQ_CNT_LBN 104 +#define FRF_AZ_EVQ_UPD_REQ_CNT_WIDTH 20 +#define FRF_AZ_EVQ_CLR_REQ_CNT_LBN 84 +#define FRF_AZ_EVQ_CLR_REQ_CNT_WIDTH 20 +#define FRF_AZ_EVQ_RDY_CNT_LBN 80 +#define FRF_AZ_EVQ_RDY_CNT_WIDTH 4 +#define FRF_AZ_EVQ_WU_REQ_CNT_LBN 60 +#define FRF_AZ_EVQ_WU_REQ_CNT_WIDTH 20 +#define FRF_AZ_EVQ_WET_REQ_CNT_LBN 40 +#define FRF_AZ_EVQ_WET_REQ_CNT_WIDTH 20 +#define FRF_AZ_EVQ_INIT_REQ_CNT_LBN 20 +#define FRF_AZ_EVQ_INIT_REQ_CNT_WIDTH 20 +#define FRF_AZ_EVQ_TM_REQ_CNT_LBN 0 +#define FRF_AZ_EVQ_TM_REQ_CNT_WIDTH 20 + + +/* + * FR_CZ_USR_EV_REG(32bit): + * Event mailbox register + */ +#define FR_CZ_USR_EV_REG_OFST 0x00000540 +/* sienaa0=net_func_bar2 */ +#define FR_CZ_USR_EV_REG_STEP 8192 +#define FR_CZ_USR_EV_REG_ROWS 1024 + +#define FRF_CZ_USR_EV_DATA_LBN 0 +#define FRF_CZ_USR_EV_DATA_WIDTH 32 + + +/* + * FR_AZ_BUF_TBL_CFG_REG(128bit): + * Buffer table configuration register + */ +#define FR_AZ_BUF_TBL_CFG_REG_OFST 0x00000600 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_BUF_TBL_MODE_LBN 3 +#define FRF_AZ_BUF_TBL_MODE_WIDTH 1 + + +/* + * FR_AZ_SRM_RX_DC_CFG_REG(128bit): + * SRAM receive descriptor cache configuration register + */ +#define FR_AZ_SRM_RX_DC_CFG_REG_OFST 0x00000610 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_SRM_CLK_TMP_EN_LBN 21 +#define FRF_AZ_SRM_CLK_TMP_EN_WIDTH 1 +#define FRF_AZ_SRM_RX_DC_BASE_ADR_LBN 0 +#define FRF_AZ_SRM_RX_DC_BASE_ADR_WIDTH 21 + + +/* + * FR_AZ_SRM_TX_DC_CFG_REG(128bit): + * SRAM transmit descriptor cache configuration register + */ +#define FR_AZ_SRM_TX_DC_CFG_REG_OFST 0x00000620 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_SRM_TX_DC_BASE_ADR_LBN 0 +#define FRF_AZ_SRM_TX_DC_BASE_ADR_WIDTH 21 + + +/* + * FR_AZ_SRM_CFG_REG(128bit): + * SRAM configuration register + */ +#define FR_AZ_SRM_CFG_REG_SF_OFST 0x00000380 +/* falcona0,falconb0=eeprom_flash */ +/* + * FR_AZ_SRM_CFG_REG(128bit): + * SRAM configuration register + */ +#define FR_AZ_SRM_CFG_REG_OFST 0x00000630 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_SRM_OOB_ADR_INTEN_LBN 5 +#define FRF_AZ_SRM_OOB_ADR_INTEN_WIDTH 1 +#define FRF_AZ_SRM_OOB_BUF_INTEN_LBN 4 +#define FRF_AZ_SRM_OOB_BUF_INTEN_WIDTH 1 +#define FRF_AZ_SRM_INIT_EN_LBN 3 +#define FRF_AZ_SRM_INIT_EN_WIDTH 1 +#define FRF_AZ_SRM_NUM_BANK_LBN 2 +#define FRF_AZ_SRM_NUM_BANK_WIDTH 1 +#define FRF_AZ_SRM_BANK_SIZE_LBN 0 +#define FRF_AZ_SRM_BANK_SIZE_WIDTH 2 + + +/* + * FR_AZ_BUF_TBL_UPD_REG(128bit): + * Buffer table update register + */ +#define FR_AZ_BUF_TBL_UPD_REG_OFST 0x00000650 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_BUF_UPD_CMD_LBN 63 +#define FRF_AZ_BUF_UPD_CMD_WIDTH 1 +#define FRF_AZ_BUF_CLR_CMD_LBN 62 +#define FRF_AZ_BUF_CLR_CMD_WIDTH 1 +#define FRF_AZ_BUF_CLR_END_ID_LBN 32 +#define FRF_AZ_BUF_CLR_END_ID_WIDTH 20 +#define FRF_AZ_BUF_CLR_START_ID_LBN 0 +#define FRF_AZ_BUF_CLR_START_ID_WIDTH 20 + + +/* + * FR_AZ_SRM_UPD_EVQ_REG(128bit): + * Buffer table update register + */ +#define FR_AZ_SRM_UPD_EVQ_REG_OFST 0x00000660 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_SRM_UPD_EVQ_ID_LBN 0 +#define FRF_AZ_SRM_UPD_EVQ_ID_WIDTH 12 + + +/* + * FR_AZ_SRAM_PARITY_REG(128bit): + * SRAM parity register. + */ +#define FR_AZ_SRAM_PARITY_REG_OFST 0x00000670 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_CZ_BYPASS_ECC_LBN 3 +#define FRF_CZ_BYPASS_ECC_WIDTH 1 +#define FRF_CZ_SEC_INT_LBN 2 +#define FRF_CZ_SEC_INT_WIDTH 1 +#define FRF_CZ_FORCE_SRAM_DOUBLE_ERR_LBN 1 +#define FRF_CZ_FORCE_SRAM_DOUBLE_ERR_WIDTH 1 +#define FRF_CZ_FORCE_SRAM_SINGLE_ERR_LBN 0 +#define FRF_CZ_FORCE_SRAM_SINGLE_ERR_WIDTH 1 +#define FRF_AB_FORCE_SRAM_PERR_LBN 0 +#define FRF_AB_FORCE_SRAM_PERR_WIDTH 1 + + +/* + * FR_AZ_RX_CFG_REG(128bit): + * Receive configuration register + */ +#define FR_AZ_RX_CFG_REG_OFST 0x00000800 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_CZ_RX_HDR_SPLIT_EN_LBN 71 +#define FRF_CZ_RX_HDR_SPLIT_EN_WIDTH 1 +#define FRF_CZ_RX_HDR_SPLIT_PLD_BUF_SIZE_LBN 62 +#define FRF_CZ_RX_HDR_SPLIT_PLD_BUF_SIZE_WIDTH 9 +#define FRF_CZ_RX_HDR_SPLIT_HDR_BUF_SIZE_LBN 53 +#define FRF_CZ_RX_HDR_SPLIT_HDR_BUF_SIZE_WIDTH 9 +#define FRF_CZ_RX_PRE_RFF_IPG_LBN 49 +#define FRF_CZ_RX_PRE_RFF_IPG_WIDTH 4 +#define FRF_BZ_RX_TCP_SUP_LBN 48 +#define FRF_BZ_RX_TCP_SUP_WIDTH 1 +#define FRF_BZ_RX_INGR_EN_LBN 47 +#define FRF_BZ_RX_INGR_EN_WIDTH 1 +#define FRF_BZ_RX_IP_HASH_LBN 46 +#define FRF_BZ_RX_IP_HASH_WIDTH 1 +#define FRF_BZ_RX_HASH_ALG_LBN 45 +#define FRF_BZ_RX_HASH_ALG_WIDTH 1 +#define FRF_BZ_RX_HASH_INSRT_HDR_LBN 44 +#define FRF_BZ_RX_HASH_INSRT_HDR_WIDTH 1 +#define FRF_BZ_RX_DESC_PUSH_EN_LBN 43 +#define FRF_BZ_RX_DESC_PUSH_EN_WIDTH 1 +#define FRF_BZ_RX_RDW_PATCH_EN_LBN 42 +#define FRF_BZ_RX_RDW_PATCH_EN_WIDTH 1 +#define FRF_BB_RX_PCI_BURST_SIZE_LBN 39 +#define FRF_BB_RX_PCI_BURST_SIZE_WIDTH 3 +#define FRF_BZ_RX_OWNERR_CTL_LBN 38 +#define FRF_BZ_RX_OWNERR_CTL_WIDTH 1 +#define FRF_BZ_RX_XON_TX_TH_LBN 33 +#define FRF_BZ_RX_XON_TX_TH_WIDTH 5 +#define FRF_AA_RX_DESC_PUSH_EN_LBN 35 +#define FRF_AA_RX_DESC_PUSH_EN_WIDTH 1 +#define FRF_AA_RX_RDW_PATCH_EN_LBN 34 +#define FRF_AA_RX_RDW_PATCH_EN_WIDTH 1 +#define FRF_AA_RX_PCI_BURST_SIZE_LBN 31 +#define FRF_AA_RX_PCI_BURST_SIZE_WIDTH 3 +#define FRF_BZ_RX_XOFF_TX_TH_LBN 28 +#define FRF_BZ_RX_XOFF_TX_TH_WIDTH 5 +#define FRF_AA_RX_OWNERR_CTL_LBN 30 +#define FRF_AA_RX_OWNERR_CTL_WIDTH 1 +#define FRF_AA_RX_XON_TX_TH_LBN 25 +#define FRF_AA_RX_XON_TX_TH_WIDTH 5 +#define FRF_BZ_RX_USR_BUF_SIZE_LBN 19 +#define FRF_BZ_RX_USR_BUF_SIZE_WIDTH 9 +#define FRF_AA_RX_XOFF_TX_TH_LBN 20 +#define FRF_AA_RX_XOFF_TX_TH_WIDTH 5 +#define FRF_AA_RX_USR_BUF_SIZE_LBN 11 +#define FRF_AA_RX_USR_BUF_SIZE_WIDTH 9 +#define FRF_BZ_RX_XON_MAC_TH_LBN 10 +#define FRF_BZ_RX_XON_MAC_TH_WIDTH 9 +#define FRF_AA_RX_XON_MAC_TH_LBN 6 +#define FRF_AA_RX_XON_MAC_TH_WIDTH 5 +#define FRF_BZ_RX_XOFF_MAC_TH_LBN 1 +#define FRF_BZ_RX_XOFF_MAC_TH_WIDTH 9 +#define FRF_AA_RX_XOFF_MAC_TH_LBN 1 +#define FRF_AA_RX_XOFF_MAC_TH_WIDTH 5 +#define FRF_AZ_RX_XOFF_MAC_EN_LBN 0 +#define FRF_AZ_RX_XOFF_MAC_EN_WIDTH 1 + + +/* + * FR_AZ_RX_FILTER_CTL_REG(128bit): + * Receive filter control registers + */ +#define FR_AZ_RX_FILTER_CTL_REG_OFST 0x00000810 +/* falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT_LBN 94 +#define FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT_WIDTH 8 +#define FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT_LBN 86 +#define FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT_WIDTH 8 +#define FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES_LBN 85 +#define FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES_WIDTH 1 +#define FRF_CZ_RX_VLAN_MATCH_ETHERTYPE_LBN 69 +#define FRF_CZ_RX_VLAN_MATCH_ETHERTYPE_WIDTH 16 +#define FRF_CZ_MULTICAST_NOMATCH_Q_ID_LBN 57 +#define FRF_CZ_MULTICAST_NOMATCH_Q_ID_WIDTH 12 +#define FRF_CZ_MULTICAST_NOMATCH_RSS_ENABLED_LBN 56 +#define FRF_CZ_MULTICAST_NOMATCH_RSS_ENABLED_WIDTH 1 +#define FRF_CZ_MULTICAST_NOMATCH_IP_OVERRIDE_LBN 55 +#define FRF_CZ_MULTICAST_NOMATCH_IP_OVERRIDE_WIDTH 1 +#define FRF_CZ_UNICAST_NOMATCH_Q_ID_LBN 43 +#define FRF_CZ_UNICAST_NOMATCH_Q_ID_WIDTH 12 +#define FRF_CZ_UNICAST_NOMATCH_RSS_ENABLED_LBN 42 +#define FRF_CZ_UNICAST_NOMATCH_RSS_ENABLED_WIDTH 1 +#define FRF_CZ_UNICAST_NOMATCH_IP_OVERRIDE_LBN 41 +#define FRF_CZ_UNICAST_NOMATCH_IP_OVERRIDE_WIDTH 1 +#define FRF_BZ_SCATTER_ENBL_NO_MATCH_Q_LBN 40 +#define FRF_BZ_SCATTER_ENBL_NO_MATCH_Q_WIDTH 1 +#define FRF_AZ_UDP_FULL_SRCH_LIMIT_LBN 32 +#define FRF_AZ_UDP_FULL_SRCH_LIMIT_WIDTH 8 +#define FRF_AZ_NUM_KER_LBN 24 +#define FRF_AZ_NUM_KER_WIDTH 2 +#define FRF_AZ_UDP_WILD_SRCH_LIMIT_LBN 16 +#define FRF_AZ_UDP_WILD_SRCH_LIMIT_WIDTH 8 +#define FRF_AZ_TCP_WILD_SRCH_LIMIT_LBN 8 +#define FRF_AZ_TCP_WILD_SRCH_LIMIT_WIDTH 8 +#define FRF_AZ_TCP_FULL_SRCH_LIMIT_LBN 0 +#define FRF_AZ_TCP_FULL_SRCH_LIMIT_WIDTH 8 + + +/* + * FR_AZ_RX_FLUSH_DESCQ_REG(128bit): + * Receive flush descriptor queue register + */ +#define FR_AZ_RX_FLUSH_DESCQ_REG_OFST 0x00000820 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_RX_FLUSH_DESCQ_CMD_LBN 24 +#define FRF_AZ_RX_FLUSH_DESCQ_CMD_WIDTH 1 +#define FRF_AZ_RX_FLUSH_DESCQ_LBN 0 +#define FRF_AZ_RX_FLUSH_DESCQ_WIDTH 12 + + +/* + * FR_BZ_RX_DESC_UPD_REGP0(128bit): + * Receive descriptor update register. + */ +#define FR_BZ_RX_DESC_UPD_REGP0_OFST 0x00000830 +/* falconb0,sienaa0=net_func_bar2 */ +#define FR_BZ_RX_DESC_UPD_REGP0_STEP 8192 +#define FR_BZ_RX_DESC_UPD_REGP0_ROWS 1024 +/* + * FR_AA_RX_DESC_UPD_REG_KER(128bit): + * Receive descriptor update register. + */ +#define FR_AA_RX_DESC_UPD_REG_KER_OFST 0x00000830 +/* falcona0=net_func_bar2 */ +#define FR_AA_RX_DESC_UPD_REG_KER_STEP 8192 +#define FR_AA_RX_DESC_UPD_REG_KER_ROWS 4 +/* + * FR_AB_RX_DESC_UPD_REGP123(128bit): + * Receive descriptor update register. + */ +#define FR_AB_RX_DESC_UPD_REGP123_OFST 0x01000830 +/* falconb0=net_func_bar2,falcona0=char_func_bar0 */ +#define FR_AB_RX_DESC_UPD_REGP123_STEP 8192 +#define FR_AB_RX_DESC_UPD_REGP123_ROWS 3072 +/* + * FR_AA_RX_DESC_UPD_REGP0(128bit): + * Receive descriptor update register. + */ +#define FR_AA_RX_DESC_UPD_REGP0_OFST 0x00008830 +/* falcona0=char_func_bar0 */ +#define FR_AA_RX_DESC_UPD_REGP0_STEP 8192 +#define FR_AA_RX_DESC_UPD_REGP0_ROWS 1020 + +#define FRF_AZ_RX_DESC_WPTR_LBN 96 +#define FRF_AZ_RX_DESC_WPTR_WIDTH 12 +#define FRF_AZ_RX_DESC_PUSH_CMD_LBN 95 +#define FRF_AZ_RX_DESC_PUSH_CMD_WIDTH 1 +#define FRF_AZ_RX_DESC_LBN 0 +#define FRF_AZ_RX_DESC_WIDTH 64 +#define FRF_AZ_RX_DESC_DW0_LBN 0 +#define FRF_AZ_RX_DESC_DW0_WIDTH 32 +#define FRF_AZ_RX_DESC_DW1_LBN 32 +#define FRF_AZ_RX_DESC_DW1_WIDTH 32 + + +/* + * FR_AZ_RX_DC_CFG_REG(128bit): + * Receive descriptor cache configuration register + */ +#define FR_AZ_RX_DC_CFG_REG_OFST 0x00000840 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_RX_MAX_PF_LBN 2 +#define FRF_AZ_RX_MAX_PF_WIDTH 2 +#define FRF_AZ_RX_DC_SIZE_LBN 0 +#define FRF_AZ_RX_DC_SIZE_WIDTH 2 +#define FFE_AZ_RX_DC_SIZE_64 3 +#define FFE_AZ_RX_DC_SIZE_32 2 +#define FFE_AZ_RX_DC_SIZE_16 1 +#define FFE_AZ_RX_DC_SIZE_8 0 + + +/* + * FR_AZ_RX_DC_PF_WM_REG(128bit): + * Receive descriptor cache pre-fetch watermark register + */ +#define FR_AZ_RX_DC_PF_WM_REG_OFST 0x00000850 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_RX_DC_PF_HWM_LBN 6 +#define FRF_AZ_RX_DC_PF_HWM_WIDTH 6 +#define FRF_AZ_RX_DC_PF_LWM_LBN 0 +#define FRF_AZ_RX_DC_PF_LWM_WIDTH 6 + + +/* + * FR_BZ_RX_RSS_TKEY_REG(128bit): + * RSS Toeplitz hash key + */ +#define FR_BZ_RX_RSS_TKEY_REG_OFST 0x00000860 +/* falconb0,sienaa0=net_func_bar2 */ + +#define FRF_BZ_RX_RSS_TKEY_LBN 96 +#define FRF_BZ_RX_RSS_TKEY_WIDTH 32 +#define FRF_BZ_RX_RSS_TKEY_DW3_LBN 96 +#define FRF_BZ_RX_RSS_TKEY_DW3_WIDTH 32 +#define FRF_BZ_RX_RSS_TKEY_DW2_LBN 64 +#define FRF_BZ_RX_RSS_TKEY_DW2_WIDTH 32 +#define FRF_BZ_RX_RSS_TKEY_DW1_LBN 32 +#define FRF_BZ_RX_RSS_TKEY_DW1_WIDTH 32 +#define FRF_BZ_RX_RSS_TKEY_DW0_LBN 0 +#define FRF_BZ_RX_RSS_TKEY_DW0_WIDTH 32 + + +/* + * FR_AZ_RX_NODESC_DROP_REG(128bit): + * Receive dropped packet counter register + */ +#define FR_AZ_RX_NODESC_DROP_REG_OFST 0x00000880 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_RX_NODESC_DROP_CNT_LBN 0 +#define FRF_AZ_RX_NODESC_DROP_CNT_WIDTH 16 + + +/* + * FR_AZ_RX_SELF_RST_REG(128bit): + * Receive self reset register + */ +#define FR_AZ_RX_SELF_RST_REG_OFST 0x00000890 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_RX_ISCSI_DIS_LBN 17 +#define FRF_AZ_RX_ISCSI_DIS_WIDTH 1 +#define FRF_AB_RX_SW_RST_REG_LBN 16 +#define FRF_AB_RX_SW_RST_REG_WIDTH 1 +#define FRF_AB_RX_SELF_RST_EN_LBN 8 +#define FRF_AB_RX_SELF_RST_EN_WIDTH 1 +#define FRF_AZ_RX_MAX_PF_LAT_LBN 4 +#define FRF_AZ_RX_MAX_PF_LAT_WIDTH 4 +#define FRF_AZ_RX_MAX_LU_LAT_LBN 0 +#define FRF_AZ_RX_MAX_LU_LAT_WIDTH 4 + + +/* + * FR_AZ_RX_DEBUG_REG(128bit): + * undocumented register + */ +#define FR_AZ_RX_DEBUG_REG_OFST 0x000008a0 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_RX_DEBUG_LBN 0 +#define FRF_AZ_RX_DEBUG_WIDTH 64 +#define FRF_AZ_RX_DEBUG_DW0_LBN 0 +#define FRF_AZ_RX_DEBUG_DW0_WIDTH 32 +#define FRF_AZ_RX_DEBUG_DW1_LBN 32 +#define FRF_AZ_RX_DEBUG_DW1_WIDTH 32 + + +/* + * FR_AZ_RX_PUSH_DROP_REG(128bit): + * Receive descriptor push dropped counter register + */ +#define FR_AZ_RX_PUSH_DROP_REG_OFST 0x000008b0 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_RX_PUSH_DROP_CNT_LBN 0 +#define FRF_AZ_RX_PUSH_DROP_CNT_WIDTH 32 + + +/* + * FR_CZ_RX_RSS_IPV6_REG1(128bit): + * IPv6 RSS Toeplitz hash key low bytes + */ +#define FR_CZ_RX_RSS_IPV6_REG1_OFST 0x000008d0 +/* sienaa0=net_func_bar2 */ + +#define FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN 0 +#define FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH 128 +#define FRF_CZ_RX_RSS_IPV6_TKEY_LO_DW0_LBN 0 +#define FRF_CZ_RX_RSS_IPV6_TKEY_LO_DW0_WIDTH 32 +#define FRF_CZ_RX_RSS_IPV6_TKEY_LO_DW1_LBN 32 +#define FRF_CZ_RX_RSS_IPV6_TKEY_LO_DW1_WIDTH 32 +#define FRF_CZ_RX_RSS_IPV6_TKEY_LO_DW2_LBN 64 +#define FRF_CZ_RX_RSS_IPV6_TKEY_LO_DW2_WIDTH 32 +#define FRF_CZ_RX_RSS_IPV6_TKEY_LO_DW3_LBN 96 +#define FRF_CZ_RX_RSS_IPV6_TKEY_LO_DW3_WIDTH 32 + + +/* + * FR_CZ_RX_RSS_IPV6_REG2(128bit): + * IPv6 RSS Toeplitz hash key middle bytes + */ +#define FR_CZ_RX_RSS_IPV6_REG2_OFST 0x000008e0 +/* sienaa0=net_func_bar2 */ + +#define FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN 0 +#define FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH 128 +#define FRF_CZ_RX_RSS_IPV6_TKEY_MID_DW0_LBN 0 +#define FRF_CZ_RX_RSS_IPV6_TKEY_MID_DW0_WIDTH 32 +#define FRF_CZ_RX_RSS_IPV6_TKEY_MID_DW1_LBN 32 +#define FRF_CZ_RX_RSS_IPV6_TKEY_MID_DW1_WIDTH 32 +#define FRF_CZ_RX_RSS_IPV6_TKEY_MID_DW2_LBN 64 +#define FRF_CZ_RX_RSS_IPV6_TKEY_MID_DW2_WIDTH 32 +#define FRF_CZ_RX_RSS_IPV6_TKEY_MID_DW3_LBN 96 +#define FRF_CZ_RX_RSS_IPV6_TKEY_MID_DW3_WIDTH 32 + + +/* + * FR_CZ_RX_RSS_IPV6_REG3(128bit): + * IPv6 RSS Toeplitz hash key upper bytes and IPv6 RSS settings + */ +#define FR_CZ_RX_RSS_IPV6_REG3_OFST 0x000008f0 +/* sienaa0=net_func_bar2 */ + +#define FRF_CZ_RX_RSS_IPV6_THASH_ENABLE_LBN 66 +#define FRF_CZ_RX_RSS_IPV6_THASH_ENABLE_WIDTH 1 +#define FRF_CZ_RX_RSS_IPV6_IP_THASH_ENABLE_LBN 65 +#define FRF_CZ_RX_RSS_IPV6_IP_THASH_ENABLE_WIDTH 1 +#define FRF_CZ_RX_RSS_IPV6_TCP_SUPPRESS_LBN 64 +#define FRF_CZ_RX_RSS_IPV6_TCP_SUPPRESS_WIDTH 1 +#define FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN 0 +#define FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH 64 +#define FRF_CZ_RX_RSS_IPV6_TKEY_HI_DW0_LBN 0 +#define FRF_CZ_RX_RSS_IPV6_TKEY_HI_DW0_WIDTH 32 +#define FRF_CZ_RX_RSS_IPV6_TKEY_HI_DW1_LBN 32 +#define FRF_CZ_RX_RSS_IPV6_TKEY_HI_DW1_WIDTH 32 + + +/* + * FR_AZ_TX_FLUSH_DESCQ_REG(128bit): + * Transmit flush descriptor queue register + */ +#define FR_AZ_TX_FLUSH_DESCQ_REG_OFST 0x00000a00 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_TX_FLUSH_DESCQ_CMD_LBN 12 +#define FRF_AZ_TX_FLUSH_DESCQ_CMD_WIDTH 1 +#define FRF_AZ_TX_FLUSH_DESCQ_LBN 0 +#define FRF_AZ_TX_FLUSH_DESCQ_WIDTH 12 + + +/* + * FR_BZ_TX_DESC_UPD_REGP0(128bit): + * Transmit descriptor update register. + */ +#define FR_BZ_TX_DESC_UPD_REGP0_OFST 0x00000a10 +/* falconb0,sienaa0=net_func_bar2 */ +#define FR_BZ_TX_DESC_UPD_REGP0_STEP 8192 +#define FR_BZ_TX_DESC_UPD_REGP0_ROWS 1024 +/* + * FR_AA_TX_DESC_UPD_REG_KER(128bit): + * Transmit descriptor update register. + */ +#define FR_AA_TX_DESC_UPD_REG_KER_OFST 0x00000a10 +/* falcona0=net_func_bar2 */ +#define FR_AA_TX_DESC_UPD_REG_KER_STEP 8192 +#define FR_AA_TX_DESC_UPD_REG_KER_ROWS 8 +/* + * FR_AB_TX_DESC_UPD_REGP123(128bit): + * Transmit descriptor update register. + */ +#define FR_AB_TX_DESC_UPD_REGP123_OFST 0x01000a10 +/* falconb0=net_func_bar2,falcona0=char_func_bar0 */ +#define FR_AB_TX_DESC_UPD_REGP123_STEP 8192 +#define FR_AB_TX_DESC_UPD_REGP123_ROWS 3072 +/* + * FR_AA_TX_DESC_UPD_REGP0(128bit): + * Transmit descriptor update register. + */ +#define FR_AA_TX_DESC_UPD_REGP0_OFST 0x00008a10 +/* falcona0=char_func_bar0 */ +#define FR_AA_TX_DESC_UPD_REGP0_STEP 8192 +#define FR_AA_TX_DESC_UPD_REGP0_ROWS 1020 + +#define FRF_AZ_TX_DESC_WPTR_LBN 96 +#define FRF_AZ_TX_DESC_WPTR_WIDTH 12 +#define FRF_AZ_TX_DESC_PUSH_CMD_LBN 95 +#define FRF_AZ_TX_DESC_PUSH_CMD_WIDTH 1 +#define FRF_AZ_TX_DESC_LBN 0 +#define FRF_AZ_TX_DESC_WIDTH 95 +#define FRF_AZ_TX_DESC_DW0_LBN 0 +#define FRF_AZ_TX_DESC_DW0_WIDTH 32 +#define FRF_AZ_TX_DESC_DW1_LBN 32 +#define FRF_AZ_TX_DESC_DW1_WIDTH 32 +#define FRF_AZ_TX_DESC_DW2_LBN 64 +#define FRF_AZ_TX_DESC_DW2_WIDTH 31 + + +/* + * FR_AZ_TX_DC_CFG_REG(128bit): + * Transmit descriptor cache configuration register + */ +#define FR_AZ_TX_DC_CFG_REG_OFST 0x00000a20 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_TX_DC_SIZE_LBN 0 +#define FRF_AZ_TX_DC_SIZE_WIDTH 2 +#define FFE_AZ_TX_DC_SIZE_32 2 +#define FFE_AZ_TX_DC_SIZE_16 1 +#define FFE_AZ_TX_DC_SIZE_8 0 + + +/* + * FR_AA_TX_CHKSM_CFG_REG(128bit): + * Transmit checksum configuration register + */ +#define FR_AA_TX_CHKSM_CFG_REG_OFST 0x00000a30 +/* falcona0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AA_TX_Q_CHKSM_DIS_96_127_LBN 96 +#define FRF_AA_TX_Q_CHKSM_DIS_96_127_WIDTH 32 +#define FRF_AA_TX_Q_CHKSM_DIS_64_95_LBN 64 +#define FRF_AA_TX_Q_CHKSM_DIS_64_95_WIDTH 32 +#define FRF_AA_TX_Q_CHKSM_DIS_32_63_LBN 32 +#define FRF_AA_TX_Q_CHKSM_DIS_32_63_WIDTH 32 +#define FRF_AA_TX_Q_CHKSM_DIS_0_31_LBN 0 +#define FRF_AA_TX_Q_CHKSM_DIS_0_31_WIDTH 32 + + +/* + * FR_AZ_TX_CFG_REG(128bit): + * Transmit configuration register + */ +#define FR_AZ_TX_CFG_REG_OFST 0x00000a50 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_CZ_TX_CONT_LOOKUP_THRESH_RANGE_LBN 114 +#define FRF_CZ_TX_CONT_LOOKUP_THRESH_RANGE_WIDTH 8 +#define FRF_CZ_TX_FILTER_TEST_MODE_BIT_LBN 113 +#define FRF_CZ_TX_FILTER_TEST_MODE_BIT_WIDTH 1 +#define FRF_CZ_TX_ETH_FILTER_WILD_SEARCH_RANGE_LBN 105 +#define FRF_CZ_TX_ETH_FILTER_WILD_SEARCH_RANGE_WIDTH 8 +#define FRF_CZ_TX_ETH_FILTER_FULL_SEARCH_RANGE_LBN 97 +#define FRF_CZ_TX_ETH_FILTER_FULL_SEARCH_RANGE_WIDTH 8 +#define FRF_CZ_TX_UDPIP_FILTER_WILD_SEARCH_RANGE_LBN 89 +#define FRF_CZ_TX_UDPIP_FILTER_WILD_SEARCH_RANGE_WIDTH 8 +#define FRF_CZ_TX_UDPIP_FILTER_FULL_SEARCH_RANGE_LBN 81 +#define FRF_CZ_TX_UDPIP_FILTER_FULL_SEARCH_RANGE_WIDTH 8 +#define FRF_CZ_TX_TCPIP_FILTER_WILD_SEARCH_RANGE_LBN 73 +#define FRF_CZ_TX_TCPIP_FILTER_WILD_SEARCH_RANGE_WIDTH 8 +#define FRF_CZ_TX_TCPIP_FILTER_FULL_SEARCH_RANGE_LBN 65 +#define FRF_CZ_TX_TCPIP_FILTER_FULL_SEARCH_RANGE_WIDTH 8 +#define FRF_CZ_TX_FILTER_ALL_VLAN_ETHERTYPES_BIT_LBN 64 +#define FRF_CZ_TX_FILTER_ALL_VLAN_ETHERTYPES_BIT_WIDTH 1 +#define FRF_CZ_TX_VLAN_MATCH_ETHERTYPE_RANGE_LBN 48 +#define FRF_CZ_TX_VLAN_MATCH_ETHERTYPE_RANGE_WIDTH 16 +#define FRF_CZ_TX_FILTER_EN_BIT_LBN 47 +#define FRF_CZ_TX_FILTER_EN_BIT_WIDTH 1 +#define FRF_AZ_TX_IP_ID_P0_OFS_LBN 16 +#define FRF_AZ_TX_IP_ID_P0_OFS_WIDTH 15 +#define FRF_AZ_TX_NO_EOP_DISC_EN_LBN 5 +#define FRF_AZ_TX_NO_EOP_DISC_EN_WIDTH 1 +#define FRF_AZ_TX_P1_PRI_EN_LBN 4 +#define FRF_AZ_TX_P1_PRI_EN_WIDTH 1 +#define FRF_AZ_TX_OWNERR_CTL_LBN 2 +#define FRF_AZ_TX_OWNERR_CTL_WIDTH 1 +#define FRF_AA_TX_NON_IP_DROP_DIS_LBN 1 +#define FRF_AA_TX_NON_IP_DROP_DIS_WIDTH 1 +#define FRF_AZ_TX_IP_ID_REP_EN_LBN 0 +#define FRF_AZ_TX_IP_ID_REP_EN_WIDTH 1 + + +/* + * FR_AZ_TX_PUSH_DROP_REG(128bit): + * Transmit push dropped register + */ +#define FR_AZ_TX_PUSH_DROP_REG_OFST 0x00000a60 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_TX_PUSH_DROP_CNT_LBN 0 +#define FRF_AZ_TX_PUSH_DROP_CNT_WIDTH 32 + + +/* + * FR_AZ_TX_RESERVED_REG(128bit): + * Transmit configuration register + */ +#define FR_AZ_TX_RESERVED_REG_OFST 0x00000a80 +/* falcona0,falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_TX_EVT_CNT_LBN 121 +#define FRF_AZ_TX_EVT_CNT_WIDTH 7 +#define FRF_AZ_TX_PREF_AGE_CNT_LBN 119 +#define FRF_AZ_TX_PREF_AGE_CNT_WIDTH 2 +#define FRF_AZ_TX_RD_COMP_TMR_LBN 96 +#define FRF_AZ_TX_RD_COMP_TMR_WIDTH 23 +#define FRF_AZ_TX_PUSH_EN_LBN 89 +#define FRF_AZ_TX_PUSH_EN_WIDTH 1 +#define FRF_AZ_TX_PUSH_CHK_DIS_LBN 88 +#define FRF_AZ_TX_PUSH_CHK_DIS_WIDTH 1 +#define FRF_AZ_TX_D_FF_FULL_P0_LBN 85 +#define FRF_AZ_TX_D_FF_FULL_P0_WIDTH 1 +#define FRF_AZ_TX_DMAR_ST_P0_LBN 81 +#define FRF_AZ_TX_DMAR_ST_P0_WIDTH 1 +#define FRF_AZ_TX_DMAQ_ST_LBN 78 +#define FRF_AZ_TX_DMAQ_ST_WIDTH 1 +#define FRF_AZ_TX_RX_SPACER_LBN 64 +#define FRF_AZ_TX_RX_SPACER_WIDTH 8 +#define FRF_AZ_TX_DROP_ABORT_EN_LBN 60 +#define FRF_AZ_TX_DROP_ABORT_EN_WIDTH 1 +#define FRF_AZ_TX_SOFT_EVT_EN_LBN 59 +#define FRF_AZ_TX_SOFT_EVT_EN_WIDTH 1 +#define FRF_AZ_TX_PS_EVT_DIS_LBN 58 +#define FRF_AZ_TX_PS_EVT_DIS_WIDTH 1 +#define FRF_AZ_TX_RX_SPACER_EN_LBN 57 +#define FRF_AZ_TX_RX_SPACER_EN_WIDTH 1 +#define FRF_AZ_TX_XP_TIMER_LBN 52 +#define FRF_AZ_TX_XP_TIMER_WIDTH 5 +#define FRF_AZ_TX_PREF_SPACER_LBN 44 +#define FRF_AZ_TX_PREF_SPACER_WIDTH 8 +#define FRF_AZ_TX_PREF_WD_TMR_LBN 22 +#define FRF_AZ_TX_PREF_WD_TMR_WIDTH 22 +#define FRF_AZ_TX_ONLY1TAG_LBN 21 +#define FRF_AZ_TX_ONLY1TAG_WIDTH 1 +#define FRF_AZ_TX_PREF_THRESHOLD_LBN 19 +#define FRF_AZ_TX_PREF_THRESHOLD_WIDTH 2 +#define FRF_AZ_TX_ONE_PKT_PER_Q_LBN 18 +#define FRF_AZ_TX_ONE_PKT_PER_Q_WIDTH 1 +#define FRF_AZ_TX_DIS_NON_IP_EV_LBN 17 +#define FRF_AZ_TX_DIS_NON_IP_EV_WIDTH 1 +#define FRF_AA_TX_DMA_FF_THR_LBN 16 +#define FRF_AA_TX_DMA_FF_THR_WIDTH 1 +#define FRF_AZ_TX_DMA_SPACER_LBN 8 +#define FRF_AZ_TX_DMA_SPACER_WIDTH 8 +#define FRF_AA_TX_TCP_DIS_LBN 7 +#define FRF_AA_TX_TCP_DIS_WIDTH 1 +#define FRF_BZ_TX_FLUSH_MIN_LEN_EN_LBN 7 +#define FRF_BZ_TX_FLUSH_MIN_LEN_EN_WIDTH 1 +#define FRF_AA_TX_IP_DIS_LBN 6 +#define FRF_AA_TX_IP_DIS_WIDTH 1 +#define FRF_AZ_TX_MAX_CPL_LBN 2 +#define FRF_AZ_TX_MAX_CPL_WIDTH 2 +#define FFE_AZ_TX_MAX_CPL_16 3 +#define FFE_AZ_TX_MAX_CPL_8 2 +#define FFE_AZ_TX_MAX_CPL_4 1 +#define FFE_AZ_TX_MAX_CPL_NOLIMIT 0 +#define FRF_AZ_TX_MAX_PREF_LBN 0 +#define FRF_AZ_TX_MAX_PREF_WIDTH 2 +#define FFE_AZ_TX_MAX_PREF_32 3 +#define FFE_AZ_TX_MAX_PREF_16 2 +#define FFE_AZ_TX_MAX_PREF_8 1 +#define FFE_AZ_TX_MAX_PREF_OFF 0 + + +/* + * FR_BZ_TX_PACE_REG(128bit): + * Transmit pace control register + */ +#define FR_BZ_TX_PACE_REG_OFST 0x00000a90 +/* falconb0,sienaa0=net_func_bar2 */ +/* + * FR_AA_TX_PACE_REG(128bit): + * Transmit pace control register + */ +#define FR_AA_TX_PACE_REG_OFST 0x00f80000 +/* falcona0=char_func_bar0 */ + +#define FRF_AZ_TX_PACE_SB_NOT_AF_LBN 19 +#define FRF_AZ_TX_PACE_SB_NOT_AF_WIDTH 10 +#define FRF_AZ_TX_PACE_SB_AF_LBN 9 +#define FRF_AZ_TX_PACE_SB_AF_WIDTH 10 +#define FRF_AZ_TX_PACE_FB_BASE_LBN 5 +#define FRF_AZ_TX_PACE_FB_BASE_WIDTH 4 +#define FRF_AZ_TX_PACE_BIN_TH_LBN 0 +#define FRF_AZ_TX_PACE_BIN_TH_WIDTH 5 + + +/* + * FR_AZ_TX_PACE_DROP_QID_REG(128bit): + * PACE Drop QID Counter + */ +#define FR_AZ_TX_PACE_DROP_QID_REG_OFST 0x00000aa0 +/* falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_TX_PACE_QID_DRP_CNT_LBN 0 +#define FRF_AZ_TX_PACE_QID_DRP_CNT_WIDTH 16 + + +/* + * FR_AB_TX_VLAN_REG(128bit): + * Transmit VLAN tag register + */ +#define FR_AB_TX_VLAN_REG_OFST 0x00000ae0 +/* falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_TX_VLAN_EN_LBN 127 +#define FRF_AB_TX_VLAN_EN_WIDTH 1 +#define FRF_AB_TX_VLAN7_PORT1_EN_LBN 125 +#define FRF_AB_TX_VLAN7_PORT1_EN_WIDTH 1 +#define FRF_AB_TX_VLAN7_PORT0_EN_LBN 124 +#define FRF_AB_TX_VLAN7_PORT0_EN_WIDTH 1 +#define FRF_AB_TX_VLAN7_LBN 112 +#define FRF_AB_TX_VLAN7_WIDTH 12 +#define FRF_AB_TX_VLAN6_PORT1_EN_LBN 109 +#define FRF_AB_TX_VLAN6_PORT1_EN_WIDTH 1 +#define FRF_AB_TX_VLAN6_PORT0_EN_LBN 108 +#define FRF_AB_TX_VLAN6_PORT0_EN_WIDTH 1 +#define FRF_AB_TX_VLAN6_LBN 96 +#define FRF_AB_TX_VLAN6_WIDTH 12 +#define FRF_AB_TX_VLAN5_PORT1_EN_LBN 93 +#define FRF_AB_TX_VLAN5_PORT1_EN_WIDTH 1 +#define FRF_AB_TX_VLAN5_PORT0_EN_LBN 92 +#define FRF_AB_TX_VLAN5_PORT0_EN_WIDTH 1 +#define FRF_AB_TX_VLAN5_LBN 80 +#define FRF_AB_TX_VLAN5_WIDTH 12 +#define FRF_AB_TX_VLAN4_PORT1_EN_LBN 77 +#define FRF_AB_TX_VLAN4_PORT1_EN_WIDTH 1 +#define FRF_AB_TX_VLAN4_PORT0_EN_LBN 76 +#define FRF_AB_TX_VLAN4_PORT0_EN_WIDTH 1 +#define FRF_AB_TX_VLAN4_LBN 64 +#define FRF_AB_TX_VLAN4_WIDTH 12 +#define FRF_AB_TX_VLAN3_PORT1_EN_LBN 61 +#define FRF_AB_TX_VLAN3_PORT1_EN_WIDTH 1 +#define FRF_AB_TX_VLAN3_PORT0_EN_LBN 60 +#define FRF_AB_TX_VLAN3_PORT0_EN_WIDTH 1 +#define FRF_AB_TX_VLAN3_LBN 48 +#define FRF_AB_TX_VLAN3_WIDTH 12 +#define FRF_AB_TX_VLAN2_PORT1_EN_LBN 45 +#define FRF_AB_TX_VLAN2_PORT1_EN_WIDTH 1 +#define FRF_AB_TX_VLAN2_PORT0_EN_LBN 44 +#define FRF_AB_TX_VLAN2_PORT0_EN_WIDTH 1 +#define FRF_AB_TX_VLAN2_LBN 32 +#define FRF_AB_TX_VLAN2_WIDTH 12 +#define FRF_AB_TX_VLAN1_PORT1_EN_LBN 29 +#define FRF_AB_TX_VLAN1_PORT1_EN_WIDTH 1 +#define FRF_AB_TX_VLAN1_PORT0_EN_LBN 28 +#define FRF_AB_TX_VLAN1_PORT0_EN_WIDTH 1 +#define FRF_AB_TX_VLAN1_LBN 16 +#define FRF_AB_TX_VLAN1_WIDTH 12 +#define FRF_AB_TX_VLAN0_PORT1_EN_LBN 13 +#define FRF_AB_TX_VLAN0_PORT1_EN_WIDTH 1 +#define FRF_AB_TX_VLAN0_PORT0_EN_LBN 12 +#define FRF_AB_TX_VLAN0_PORT0_EN_WIDTH 1 +#define FRF_AB_TX_VLAN0_LBN 0 +#define FRF_AB_TX_VLAN0_WIDTH 12 + + +/* + * FR_AZ_TX_IPFIL_PORTEN_REG(128bit): + * Transmit filter control register + */ +#define FR_AZ_TX_IPFIL_PORTEN_REG_OFST 0x00000af0 +/* falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AZ_TX_MADR0_FIL_EN_LBN 64 +#define FRF_AZ_TX_MADR0_FIL_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL31_PORT_EN_LBN 62 +#define FRF_AB_TX_IPFIL31_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL30_PORT_EN_LBN 60 +#define FRF_AB_TX_IPFIL30_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL29_PORT_EN_LBN 58 +#define FRF_AB_TX_IPFIL29_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL28_PORT_EN_LBN 56 +#define FRF_AB_TX_IPFIL28_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL27_PORT_EN_LBN 54 +#define FRF_AB_TX_IPFIL27_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL26_PORT_EN_LBN 52 +#define FRF_AB_TX_IPFIL26_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL25_PORT_EN_LBN 50 +#define FRF_AB_TX_IPFIL25_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL24_PORT_EN_LBN 48 +#define FRF_AB_TX_IPFIL24_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL23_PORT_EN_LBN 46 +#define FRF_AB_TX_IPFIL23_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL22_PORT_EN_LBN 44 +#define FRF_AB_TX_IPFIL22_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL21_PORT_EN_LBN 42 +#define FRF_AB_TX_IPFIL21_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL20_PORT_EN_LBN 40 +#define FRF_AB_TX_IPFIL20_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL19_PORT_EN_LBN 38 +#define FRF_AB_TX_IPFIL19_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL18_PORT_EN_LBN 36 +#define FRF_AB_TX_IPFIL18_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL17_PORT_EN_LBN 34 +#define FRF_AB_TX_IPFIL17_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL16_PORT_EN_LBN 32 +#define FRF_AB_TX_IPFIL16_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL15_PORT_EN_LBN 30 +#define FRF_AB_TX_IPFIL15_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL14_PORT_EN_LBN 28 +#define FRF_AB_TX_IPFIL14_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL13_PORT_EN_LBN 26 +#define FRF_AB_TX_IPFIL13_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL12_PORT_EN_LBN 24 +#define FRF_AB_TX_IPFIL12_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL11_PORT_EN_LBN 22 +#define FRF_AB_TX_IPFIL11_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL10_PORT_EN_LBN 20 +#define FRF_AB_TX_IPFIL10_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL9_PORT_EN_LBN 18 +#define FRF_AB_TX_IPFIL9_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL8_PORT_EN_LBN 16 +#define FRF_AB_TX_IPFIL8_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL7_PORT_EN_LBN 14 +#define FRF_AB_TX_IPFIL7_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL6_PORT_EN_LBN 12 +#define FRF_AB_TX_IPFIL6_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL5_PORT_EN_LBN 10 +#define FRF_AB_TX_IPFIL5_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL4_PORT_EN_LBN 8 +#define FRF_AB_TX_IPFIL4_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL3_PORT_EN_LBN 6 +#define FRF_AB_TX_IPFIL3_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL2_PORT_EN_LBN 4 +#define FRF_AB_TX_IPFIL2_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL1_PORT_EN_LBN 2 +#define FRF_AB_TX_IPFIL1_PORT_EN_WIDTH 1 +#define FRF_AB_TX_IPFIL0_PORT_EN_LBN 0 +#define FRF_AB_TX_IPFIL0_PORT_EN_WIDTH 1 + + +/* + * FR_AB_TX_IPFIL_TBL(128bit): + * Transmit IP source address filter table + */ +#define FR_AB_TX_IPFIL_TBL_OFST 0x00000b00 +/* falconb0=net_func_bar2,falcona0=char_func_bar0 */ +#define FR_AB_TX_IPFIL_TBL_STEP 16 +#define FR_AB_TX_IPFIL_TBL_ROWS 16 + +#define FRF_AB_TX_IPFIL_MASK_1_LBN 96 +#define FRF_AB_TX_IPFIL_MASK_1_WIDTH 32 +#define FRF_AB_TX_IP_SRC_ADR_1_LBN 64 +#define FRF_AB_TX_IP_SRC_ADR_1_WIDTH 32 +#define FRF_AB_TX_IPFIL_MASK_0_LBN 32 +#define FRF_AB_TX_IPFIL_MASK_0_WIDTH 32 +#define FRF_AB_TX_IP_SRC_ADR_0_LBN 0 +#define FRF_AB_TX_IP_SRC_ADR_0_WIDTH 32 + + +/* + * FR_AB_MD_TXD_REG(128bit): + * PHY management transmit data register + */ +#define FR_AB_MD_TXD_REG_OFST 0x00000c00 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_MD_TXD_LBN 0 +#define FRF_AB_MD_TXD_WIDTH 16 + + +/* + * FR_AB_MD_RXD_REG(128bit): + * PHY management receive data register + */ +#define FR_AB_MD_RXD_REG_OFST 0x00000c10 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_MD_RXD_LBN 0 +#define FRF_AB_MD_RXD_WIDTH 16 + + +/* + * FR_AB_MD_CS_REG(128bit): + * PHY management configuration & status register + */ +#define FR_AB_MD_CS_REG_OFST 0x00000c20 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_MD_RD_EN_LBN 15 +#define FRF_AB_MD_RD_EN_WIDTH 1 +#define FRF_AB_MD_WR_EN_LBN 14 +#define FRF_AB_MD_WR_EN_WIDTH 1 +#define FRF_AB_MD_ADDR_CMD_LBN 13 +#define FRF_AB_MD_ADDR_CMD_WIDTH 1 +#define FRF_AB_MD_PT_LBN 7 +#define FRF_AB_MD_PT_WIDTH 3 +#define FRF_AB_MD_PL_LBN 6 +#define FRF_AB_MD_PL_WIDTH 1 +#define FRF_AB_MD_INT_CLR_LBN 5 +#define FRF_AB_MD_INT_CLR_WIDTH 1 +#define FRF_AB_MD_GC_LBN 4 +#define FRF_AB_MD_GC_WIDTH 1 +#define FRF_AB_MD_PRSP_LBN 3 +#define FRF_AB_MD_PRSP_WIDTH 1 +#define FRF_AB_MD_RIC_LBN 2 +#define FRF_AB_MD_RIC_WIDTH 1 +#define FRF_AB_MD_RDC_LBN 1 +#define FRF_AB_MD_RDC_WIDTH 1 +#define FRF_AB_MD_WRC_LBN 0 +#define FRF_AB_MD_WRC_WIDTH 1 + + +/* + * FR_AB_MD_PHY_ADR_REG(128bit): + * PHY management PHY address register + */ +#define FR_AB_MD_PHY_ADR_REG_OFST 0x00000c30 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_MD_PHY_ADR_LBN 0 +#define FRF_AB_MD_PHY_ADR_WIDTH 16 + + +/* + * FR_AB_MD_ID_REG(128bit): + * PHY management ID register + */ +#define FR_AB_MD_ID_REG_OFST 0x00000c40 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_MD_PRT_ADR_LBN 11 +#define FRF_AB_MD_PRT_ADR_WIDTH 5 +#define FRF_AB_MD_DEV_ADR_LBN 6 +#define FRF_AB_MD_DEV_ADR_WIDTH 5 + + +/* + * FR_AB_MD_STAT_REG(128bit): + * PHY management status & mask register + */ +#define FR_AB_MD_STAT_REG_OFST 0x00000c50 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_MD_PINT_LBN 4 +#define FRF_AB_MD_PINT_WIDTH 1 +#define FRF_AB_MD_DONE_LBN 3 +#define FRF_AB_MD_DONE_WIDTH 1 +#define FRF_AB_MD_BSERR_LBN 2 +#define FRF_AB_MD_BSERR_WIDTH 1 +#define FRF_AB_MD_LNFL_LBN 1 +#define FRF_AB_MD_LNFL_WIDTH 1 +#define FRF_AB_MD_BSY_LBN 0 +#define FRF_AB_MD_BSY_WIDTH 1 + + +/* + * FR_AB_MAC_STAT_DMA_REG(128bit): + * Port MAC statistical counter DMA register + */ +#define FR_AB_MAC_STAT_DMA_REG_OFST 0x00000c60 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_MAC_STAT_DMA_CMD_LBN 48 +#define FRF_AB_MAC_STAT_DMA_CMD_WIDTH 1 +#define FRF_AB_MAC_STAT_DMA_ADR_LBN 0 +#define FRF_AB_MAC_STAT_DMA_ADR_WIDTH 48 +#define FRF_AB_MAC_STAT_DMA_ADR_DW0_LBN 0 +#define FRF_AB_MAC_STAT_DMA_ADR_DW0_WIDTH 32 +#define FRF_AB_MAC_STAT_DMA_ADR_DW1_LBN 32 +#define FRF_AB_MAC_STAT_DMA_ADR_DW1_WIDTH 16 + + +/* + * FR_AB_MAC_CTRL_REG(128bit): + * Port MAC control register + */ +#define FR_AB_MAC_CTRL_REG_OFST 0x00000c80 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_MAC_XOFF_VAL_LBN 16 +#define FRF_AB_MAC_XOFF_VAL_WIDTH 16 +#define FRF_BB_TXFIFO_DRAIN_EN_LBN 7 +#define FRF_BB_TXFIFO_DRAIN_EN_WIDTH 1 +#define FRF_AB_MAC_XG_DISTXCRC_LBN 5 +#define FRF_AB_MAC_XG_DISTXCRC_WIDTH 1 +#define FRF_AB_MAC_BCAD_ACPT_LBN 4 +#define FRF_AB_MAC_BCAD_ACPT_WIDTH 1 +#define FRF_AB_MAC_UC_PROM_LBN 3 +#define FRF_AB_MAC_UC_PROM_WIDTH 1 +#define FRF_AB_MAC_LINK_STATUS_LBN 2 +#define FRF_AB_MAC_LINK_STATUS_WIDTH 1 +#define FRF_AB_MAC_SPEED_LBN 0 +#define FRF_AB_MAC_SPEED_WIDTH 2 +#define FRF_AB_MAC_SPEED_10M 0 +#define FRF_AB_MAC_SPEED_100M 1 +#define FRF_AB_MAC_SPEED_1G 2 +#define FRF_AB_MAC_SPEED_10G 3 + +/* + * FR_BB_GEN_MODE_REG(128bit): + * General Purpose mode register (external interrupt mask) + */ +#define FR_BB_GEN_MODE_REG_OFST 0x00000c90 +/* falconb0=net_func_bar2 */ + +#define FRF_BB_XFP_PHY_INT_POL_SEL_LBN 3 +#define FRF_BB_XFP_PHY_INT_POL_SEL_WIDTH 1 +#define FRF_BB_XG_PHY_INT_POL_SEL_LBN 2 +#define FRF_BB_XG_PHY_INT_POL_SEL_WIDTH 1 +#define FRF_BB_XFP_PHY_INT_MASK_LBN 1 +#define FRF_BB_XFP_PHY_INT_MASK_WIDTH 1 +#define FRF_BB_XG_PHY_INT_MASK_LBN 0 +#define FRF_BB_XG_PHY_INT_MASK_WIDTH 1 + + +/* + * FR_AB_MAC_MC_HASH_REG0(128bit): + * Multicast address hash table + */ +#define FR_AB_MAC_MC_HASH0_REG_OFST 0x00000ca0 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_MAC_MCAST_HASH0_LBN 0 +#define FRF_AB_MAC_MCAST_HASH0_WIDTH 128 +#define FRF_AB_MAC_MCAST_HASH0_DW0_LBN 0 +#define FRF_AB_MAC_MCAST_HASH0_DW0_WIDTH 32 +#define FRF_AB_MAC_MCAST_HASH0_DW1_LBN 32 +#define FRF_AB_MAC_MCAST_HASH0_DW1_WIDTH 32 +#define FRF_AB_MAC_MCAST_HASH0_DW2_LBN 64 +#define FRF_AB_MAC_MCAST_HASH0_DW2_WIDTH 32 +#define FRF_AB_MAC_MCAST_HASH0_DW3_LBN 96 +#define FRF_AB_MAC_MCAST_HASH0_DW3_WIDTH 32 + + +/* + * FR_AB_MAC_MC_HASH_REG1(128bit): + * Multicast address hash table + */ +#define FR_AB_MAC_MC_HASH1_REG_OFST 0x00000cb0 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_MAC_MCAST_HASH1_LBN 0 +#define FRF_AB_MAC_MCAST_HASH1_WIDTH 128 +#define FRF_AB_MAC_MCAST_HASH1_DW0_LBN 0 +#define FRF_AB_MAC_MCAST_HASH1_DW0_WIDTH 32 +#define FRF_AB_MAC_MCAST_HASH1_DW1_LBN 32 +#define FRF_AB_MAC_MCAST_HASH1_DW1_WIDTH 32 +#define FRF_AB_MAC_MCAST_HASH1_DW2_LBN 64 +#define FRF_AB_MAC_MCAST_HASH1_DW2_WIDTH 32 +#define FRF_AB_MAC_MCAST_HASH1_DW3_LBN 96 +#define FRF_AB_MAC_MCAST_HASH1_DW3_WIDTH 32 + + +/* + * FR_AB_GM_CFG1_REG(32bit): + * GMAC configuration register 1 + */ +#define FR_AB_GM_CFG1_REG_OFST 0x00000e00 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_GM_SW_RST_LBN 31 +#define FRF_AB_GM_SW_RST_WIDTH 1 +#define FRF_AB_GM_SIM_RST_LBN 30 +#define FRF_AB_GM_SIM_RST_WIDTH 1 +#define FRF_AB_GM_RST_RX_MAC_CTL_LBN 19 +#define FRF_AB_GM_RST_RX_MAC_CTL_WIDTH 1 +#define FRF_AB_GM_RST_TX_MAC_CTL_LBN 18 +#define FRF_AB_GM_RST_TX_MAC_CTL_WIDTH 1 +#define FRF_AB_GM_RST_RX_FUNC_LBN 17 +#define FRF_AB_GM_RST_RX_FUNC_WIDTH 1 +#define FRF_AB_GM_RST_TX_FUNC_LBN 16 +#define FRF_AB_GM_RST_TX_FUNC_WIDTH 1 +#define FRF_AB_GM_LOOP_LBN 8 +#define FRF_AB_GM_LOOP_WIDTH 1 +#define FRF_AB_GM_RX_FC_EN_LBN 5 +#define FRF_AB_GM_RX_FC_EN_WIDTH 1 +#define FRF_AB_GM_TX_FC_EN_LBN 4 +#define FRF_AB_GM_TX_FC_EN_WIDTH 1 +#define FRF_AB_GM_SYNC_RXEN_LBN 3 +#define FRF_AB_GM_SYNC_RXEN_WIDTH 1 +#define FRF_AB_GM_RX_EN_LBN 2 +#define FRF_AB_GM_RX_EN_WIDTH 1 +#define FRF_AB_GM_SYNC_TXEN_LBN 1 +#define FRF_AB_GM_SYNC_TXEN_WIDTH 1 +#define FRF_AB_GM_TX_EN_LBN 0 +#define FRF_AB_GM_TX_EN_WIDTH 1 + + +/* + * FR_AB_GM_CFG2_REG(32bit): + * GMAC configuration register 2 + */ +#define FR_AB_GM_CFG2_REG_OFST 0x00000e10 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_GM_PAMBL_LEN_LBN 12 +#define FRF_AB_GM_PAMBL_LEN_WIDTH 4 +#define FRF_AB_GM_IF_MODE_LBN 8 +#define FRF_AB_GM_IF_MODE_WIDTH 2 +#define FRF_AB_GM_IF_MODE_BYTE_MODE 2 +#define FRF_AB_GM_IF_MODE_NIBBLE_MODE 1 +#define FRF_AB_GM_HUGE_FRM_EN_LBN 5 +#define FRF_AB_GM_HUGE_FRM_EN_WIDTH 1 +#define FRF_AB_GM_LEN_CHK_LBN 4 +#define FRF_AB_GM_LEN_CHK_WIDTH 1 +#define FRF_AB_GM_PAD_CRC_EN_LBN 2 +#define FRF_AB_GM_PAD_CRC_EN_WIDTH 1 +#define FRF_AB_GM_CRC_EN_LBN 1 +#define FRF_AB_GM_CRC_EN_WIDTH 1 +#define FRF_AB_GM_FD_LBN 0 +#define FRF_AB_GM_FD_WIDTH 1 + + +/* + * FR_AB_GM_IPG_REG(32bit): + * GMAC IPG register + */ +#define FR_AB_GM_IPG_REG_OFST 0x00000e20 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_GM_NONB2B_IPG1_LBN 24 +#define FRF_AB_GM_NONB2B_IPG1_WIDTH 7 +#define FRF_AB_GM_NONB2B_IPG2_LBN 16 +#define FRF_AB_GM_NONB2B_IPG2_WIDTH 7 +#define FRF_AB_GM_MIN_IPG_ENF_LBN 8 +#define FRF_AB_GM_MIN_IPG_ENF_WIDTH 8 +#define FRF_AB_GM_B2B_IPG_LBN 0 +#define FRF_AB_GM_B2B_IPG_WIDTH 7 + + +/* + * FR_AB_GM_HD_REG(32bit): + * GMAC half duplex register + */ +#define FR_AB_GM_HD_REG_OFST 0x00000e30 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_GM_ALT_BOFF_VAL_LBN 20 +#define FRF_AB_GM_ALT_BOFF_VAL_WIDTH 4 +#define FRF_AB_GM_ALT_BOFF_EN_LBN 19 +#define FRF_AB_GM_ALT_BOFF_EN_WIDTH 1 +#define FRF_AB_GM_BP_NO_BOFF_LBN 18 +#define FRF_AB_GM_BP_NO_BOFF_WIDTH 1 +#define FRF_AB_GM_DIS_BOFF_LBN 17 +#define FRF_AB_GM_DIS_BOFF_WIDTH 1 +#define FRF_AB_GM_EXDEF_TX_EN_LBN 16 +#define FRF_AB_GM_EXDEF_TX_EN_WIDTH 1 +#define FRF_AB_GM_RTRY_LIMIT_LBN 12 +#define FRF_AB_GM_RTRY_LIMIT_WIDTH 4 +#define FRF_AB_GM_COL_WIN_LBN 0 +#define FRF_AB_GM_COL_WIN_WIDTH 10 + + +/* + * FR_AB_GM_MAX_FLEN_REG(32bit): + * GMAC maximum frame length register + */ +#define FR_AB_GM_MAX_FLEN_REG_OFST 0x00000e40 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_GM_MAX_FLEN_LBN 0 +#define FRF_AB_GM_MAX_FLEN_WIDTH 16 + + +/* + * FR_AB_GM_TEST_REG(32bit): + * GMAC test register + */ +#define FR_AB_GM_TEST_REG_OFST 0x00000e70 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_GM_MAX_BOFF_LBN 3 +#define FRF_AB_GM_MAX_BOFF_WIDTH 1 +#define FRF_AB_GM_REG_TX_FLOW_EN_LBN 2 +#define FRF_AB_GM_REG_TX_FLOW_EN_WIDTH 1 +#define FRF_AB_GM_TEST_PAUSE_LBN 1 +#define FRF_AB_GM_TEST_PAUSE_WIDTH 1 +#define FRF_AB_GM_SHORT_SLOT_LBN 0 +#define FRF_AB_GM_SHORT_SLOT_WIDTH 1 + + +/* + * FR_AB_GM_ADR1_REG(32bit): + * GMAC station address register 1 + */ +#define FR_AB_GM_ADR1_REG_OFST 0x00000f00 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_GM_ADR_B0_LBN 24 +#define FRF_AB_GM_ADR_B0_WIDTH 8 +#define FRF_AB_GM_ADR_B1_LBN 16 +#define FRF_AB_GM_ADR_B1_WIDTH 8 +#define FRF_AB_GM_ADR_B2_LBN 8 +#define FRF_AB_GM_ADR_B2_WIDTH 8 +#define FRF_AB_GM_ADR_B3_LBN 0 +#define FRF_AB_GM_ADR_B3_WIDTH 8 + + +/* + * FR_AB_GM_ADR2_REG(32bit): + * GMAC station address register 2 + */ +#define FR_AB_GM_ADR2_REG_OFST 0x00000f10 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_GM_ADR_B4_LBN 24 +#define FRF_AB_GM_ADR_B4_WIDTH 8 +#define FRF_AB_GM_ADR_B5_LBN 16 +#define FRF_AB_GM_ADR_B5_WIDTH 8 + + +/* + * FR_AB_GMF_CFG0_REG(32bit): + * GMAC FIFO configuration register 0 + */ +#define FR_AB_GMF_CFG0_REG_OFST 0x00000f20 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_GMF_FTFENRPLY_LBN 20 +#define FRF_AB_GMF_FTFENRPLY_WIDTH 1 +#define FRF_AB_GMF_STFENRPLY_LBN 19 +#define FRF_AB_GMF_STFENRPLY_WIDTH 1 +#define FRF_AB_GMF_FRFENRPLY_LBN 18 +#define FRF_AB_GMF_FRFENRPLY_WIDTH 1 +#define FRF_AB_GMF_SRFENRPLY_LBN 17 +#define FRF_AB_GMF_SRFENRPLY_WIDTH 1 +#define FRF_AB_GMF_WTMENRPLY_LBN 16 +#define FRF_AB_GMF_WTMENRPLY_WIDTH 1 +#define FRF_AB_GMF_FTFENREQ_LBN 12 +#define FRF_AB_GMF_FTFENREQ_WIDTH 1 +#define FRF_AB_GMF_STFENREQ_LBN 11 +#define FRF_AB_GMF_STFENREQ_WIDTH 1 +#define FRF_AB_GMF_FRFENREQ_LBN 10 +#define FRF_AB_GMF_FRFENREQ_WIDTH 1 +#define FRF_AB_GMF_SRFENREQ_LBN 9 +#define FRF_AB_GMF_SRFENREQ_WIDTH 1 +#define FRF_AB_GMF_WTMENREQ_LBN 8 +#define FRF_AB_GMF_WTMENREQ_WIDTH 1 +#define FRF_AB_GMF_HSTRSTFT_LBN 4 +#define FRF_AB_GMF_HSTRSTFT_WIDTH 1 +#define FRF_AB_GMF_HSTRSTST_LBN 3 +#define FRF_AB_GMF_HSTRSTST_WIDTH 1 +#define FRF_AB_GMF_HSTRSTFR_LBN 2 +#define FRF_AB_GMF_HSTRSTFR_WIDTH 1 +#define FRF_AB_GMF_HSTRSTSR_LBN 1 +#define FRF_AB_GMF_HSTRSTSR_WIDTH 1 +#define FRF_AB_GMF_HSTRSTWT_LBN 0 +#define FRF_AB_GMF_HSTRSTWT_WIDTH 1 + + +/* + * FR_AB_GMF_CFG1_REG(32bit): + * GMAC FIFO configuration register 1 + */ +#define FR_AB_GMF_CFG1_REG_OFST 0x00000f30 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_GMF_CFGFRTH_LBN 16 +#define FRF_AB_GMF_CFGFRTH_WIDTH 5 +#define FRF_AB_GMF_CFGXOFFRTX_LBN 0 +#define FRF_AB_GMF_CFGXOFFRTX_WIDTH 16 + + +/* + * FR_AB_GMF_CFG2_REG(32bit): + * GMAC FIFO configuration register 2 + */ +#define FR_AB_GMF_CFG2_REG_OFST 0x00000f40 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_GMF_CFGHWM_LBN 16 +#define FRF_AB_GMF_CFGHWM_WIDTH 6 +#define FRF_AB_GMF_CFGLWM_LBN 0 +#define FRF_AB_GMF_CFGLWM_WIDTH 6 + + +/* + * FR_AB_GMF_CFG3_REG(32bit): + * GMAC FIFO configuration register 3 + */ +#define FR_AB_GMF_CFG3_REG_OFST 0x00000f50 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_GMF_CFGHWMFT_LBN 16 +#define FRF_AB_GMF_CFGHWMFT_WIDTH 6 +#define FRF_AB_GMF_CFGFTTH_LBN 0 +#define FRF_AB_GMF_CFGFTTH_WIDTH 6 + + +/* + * FR_AB_GMF_CFG4_REG(32bit): + * GMAC FIFO configuration register 4 + */ +#define FR_AB_GMF_CFG4_REG_OFST 0x00000f60 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_GMF_HSTFLTRFRM_LBN 0 +#define FRF_AB_GMF_HSTFLTRFRM_WIDTH 18 + + +/* + * FR_AB_GMF_CFG5_REG(32bit): + * GMAC FIFO configuration register 5 + */ +#define FR_AB_GMF_CFG5_REG_OFST 0x00000f70 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_GMF_CFGHDPLX_LBN 22 +#define FRF_AB_GMF_CFGHDPLX_WIDTH 1 +#define FRF_AB_GMF_SRFULL_LBN 21 +#define FRF_AB_GMF_SRFULL_WIDTH 1 +#define FRF_AB_GMF_HSTSRFULLCLR_LBN 20 +#define FRF_AB_GMF_HSTSRFULLCLR_WIDTH 1 +#define FRF_AB_GMF_CFGBYTMODE_LBN 19 +#define FRF_AB_GMF_CFGBYTMODE_WIDTH 1 +#define FRF_AB_GMF_HSTDRPLT64_LBN 18 +#define FRF_AB_GMF_HSTDRPLT64_WIDTH 1 +#define FRF_AB_GMF_HSTFLTRFRMDC_LBN 0 +#define FRF_AB_GMF_HSTFLTRFRMDC_WIDTH 18 + + +/* + * FR_BB_TX_SRC_MAC_TBL(128bit): + * Transmit IP source address filter table + */ +#define FR_BB_TX_SRC_MAC_TBL_OFST 0x00001000 +/* falconb0=net_func_bar2 */ +#define FR_BB_TX_SRC_MAC_TBL_STEP 16 +#define FR_BB_TX_SRC_MAC_TBL_ROWS 16 + +#define FRF_BB_TX_SRC_MAC_ADR_1_LBN 64 +#define FRF_BB_TX_SRC_MAC_ADR_1_WIDTH 48 +#define FRF_BB_TX_SRC_MAC_ADR_1_DW0_LBN 64 +#define FRF_BB_TX_SRC_MAC_ADR_1_DW0_WIDTH 32 +#define FRF_BB_TX_SRC_MAC_ADR_1_DW1_LBN 96 +#define FRF_BB_TX_SRC_MAC_ADR_1_DW1_WIDTH 16 +#define FRF_BB_TX_SRC_MAC_ADR_0_LBN 0 +#define FRF_BB_TX_SRC_MAC_ADR_0_WIDTH 48 +#define FRF_BB_TX_SRC_MAC_ADR_0_DW0_LBN 0 +#define FRF_BB_TX_SRC_MAC_ADR_0_DW0_WIDTH 32 +#define FRF_BB_TX_SRC_MAC_ADR_0_DW1_LBN 32 +#define FRF_BB_TX_SRC_MAC_ADR_0_DW1_WIDTH 16 + + +/* + * FR_BB_TX_SRC_MAC_CTL_REG(128bit): + * Transmit MAC source address filter control + */ +#define FR_BB_TX_SRC_MAC_CTL_REG_OFST 0x00001100 +/* falconb0=net_func_bar2 */ + +#define FRF_BB_TX_SRC_DROP_CTR_LBN 16 +#define FRF_BB_TX_SRC_DROP_CTR_WIDTH 16 +#define FRF_BB_TX_SRC_FLTR_EN_LBN 15 +#define FRF_BB_TX_SRC_FLTR_EN_WIDTH 1 +#define FRF_BB_TX_DROP_CTR_CLR_LBN 12 +#define FRF_BB_TX_DROP_CTR_CLR_WIDTH 1 +#define FRF_BB_TX_MAC_QID_SEL_LBN 0 +#define FRF_BB_TX_MAC_QID_SEL_WIDTH 3 + + +/* + * FR_AB_XM_ADR_LO_REG(128bit): + * XGMAC address register low + */ +#define FR_AB_XM_ADR_LO_REG_OFST 0x00001200 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_XM_ADR_LO_LBN 0 +#define FRF_AB_XM_ADR_LO_WIDTH 32 + + +/* + * FR_AB_XM_ADR_HI_REG(128bit): + * XGMAC address register high + */ +#define FR_AB_XM_ADR_HI_REG_OFST 0x00001210 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_XM_ADR_HI_LBN 0 +#define FRF_AB_XM_ADR_HI_WIDTH 16 + + +/* + * FR_AB_XM_GLB_CFG_REG(128bit): + * XGMAC global configuration + */ +#define FR_AB_XM_GLB_CFG_REG_OFST 0x00001220 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_XM_RMTFLT_GEN_LBN 17 +#define FRF_AB_XM_RMTFLT_GEN_WIDTH 1 +#define FRF_AB_XM_DEBUG_MODE_LBN 16 +#define FRF_AB_XM_DEBUG_MODE_WIDTH 1 +#define FRF_AB_XM_RX_STAT_EN_LBN 11 +#define FRF_AB_XM_RX_STAT_EN_WIDTH 1 +#define FRF_AB_XM_TX_STAT_EN_LBN 10 +#define FRF_AB_XM_TX_STAT_EN_WIDTH 1 +#define FRF_AB_XM_RX_JUMBO_MODE_LBN 6 +#define FRF_AB_XM_RX_JUMBO_MODE_WIDTH 1 +#define FRF_AB_XM_WAN_MODE_LBN 5 +#define FRF_AB_XM_WAN_MODE_WIDTH 1 +#define FRF_AB_XM_INTCLR_MODE_LBN 3 +#define FRF_AB_XM_INTCLR_MODE_WIDTH 1 +#define FRF_AB_XM_CORE_RST_LBN 0 +#define FRF_AB_XM_CORE_RST_WIDTH 1 + + +/* + * FR_AB_XM_TX_CFG_REG(128bit): + * XGMAC transmit configuration + */ +#define FR_AB_XM_TX_CFG_REG_OFST 0x00001230 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_XM_TX_PROG_LBN 24 +#define FRF_AB_XM_TX_PROG_WIDTH 1 +#define FRF_AB_XM_IPG_LBN 16 +#define FRF_AB_XM_IPG_WIDTH 4 +#define FRF_AB_XM_FCNTL_LBN 10 +#define FRF_AB_XM_FCNTL_WIDTH 1 +#define FRF_AB_XM_TXCRC_LBN 8 +#define FRF_AB_XM_TXCRC_WIDTH 1 +#define FRF_AB_XM_EDRC_LBN 6 +#define FRF_AB_XM_EDRC_WIDTH 1 +#define FRF_AB_XM_AUTO_PAD_LBN 5 +#define FRF_AB_XM_AUTO_PAD_WIDTH 1 +#define FRF_AB_XM_TX_PRMBL_LBN 2 +#define FRF_AB_XM_TX_PRMBL_WIDTH 1 +#define FRF_AB_XM_TXEN_LBN 1 +#define FRF_AB_XM_TXEN_WIDTH 1 +#define FRF_AB_XM_TX_RST_LBN 0 +#define FRF_AB_XM_TX_RST_WIDTH 1 + + +/* + * FR_AB_XM_RX_CFG_REG(128bit): + * XGMAC receive configuration + */ +#define FR_AB_XM_RX_CFG_REG_OFST 0x00001240 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_XM_PASS_LENERR_LBN 26 +#define FRF_AB_XM_PASS_LENERR_WIDTH 1 +#define FRF_AB_XM_PASS_CRC_ERR_LBN 25 +#define FRF_AB_XM_PASS_CRC_ERR_WIDTH 1 +#define FRF_AB_XM_PASS_PRMBLE_ERR_LBN 24 +#define FRF_AB_XM_PASS_PRMBLE_ERR_WIDTH 1 +#define FRF_AB_XM_REJ_BCAST_LBN 20 +#define FRF_AB_XM_REJ_BCAST_WIDTH 1 +#define FRF_AB_XM_ACPT_ALL_MCAST_LBN 11 +#define FRF_AB_XM_ACPT_ALL_MCAST_WIDTH 1 +#define FRF_AB_XM_ACPT_ALL_UCAST_LBN 9 +#define FRF_AB_XM_ACPT_ALL_UCAST_WIDTH 1 +#define FRF_AB_XM_AUTO_DEPAD_LBN 8 +#define FRF_AB_XM_AUTO_DEPAD_WIDTH 1 +#define FRF_AB_XM_RXCRC_LBN 3 +#define FRF_AB_XM_RXCRC_WIDTH 1 +#define FRF_AB_XM_RX_PRMBL_LBN 2 +#define FRF_AB_XM_RX_PRMBL_WIDTH 1 +#define FRF_AB_XM_RXEN_LBN 1 +#define FRF_AB_XM_RXEN_WIDTH 1 +#define FRF_AB_XM_RX_RST_LBN 0 +#define FRF_AB_XM_RX_RST_WIDTH 1 + + +/* + * FR_AB_XM_MGT_INT_MASK(128bit): + * documentation to be written for sum_XM_MGT_INT_MASK + */ +#define FR_AB_XM_MGT_INT_MASK_OFST 0x00001250 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_XM_MSK_STA_INTR_LBN 16 +#define FRF_AB_XM_MSK_STA_INTR_WIDTH 1 +#define FRF_AB_XM_MSK_STAT_CNTR_HF_LBN 9 +#define FRF_AB_XM_MSK_STAT_CNTR_HF_WIDTH 1 +#define FRF_AB_XM_MSK_STAT_CNTR_OF_LBN 8 +#define FRF_AB_XM_MSK_STAT_CNTR_OF_WIDTH 1 +#define FRF_AB_XM_MSK_PRMBLE_ERR_LBN 2 +#define FRF_AB_XM_MSK_PRMBLE_ERR_WIDTH 1 +#define FRF_AB_XM_MSK_RMTFLT_LBN 1 +#define FRF_AB_XM_MSK_RMTFLT_WIDTH 1 +#define FRF_AB_XM_MSK_LCLFLT_LBN 0 +#define FRF_AB_XM_MSK_LCLFLT_WIDTH 1 + + +/* + * FR_AB_XM_FC_REG(128bit): + * XGMAC flow control register + */ +#define FR_AB_XM_FC_REG_OFST 0x00001270 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_XM_PAUSE_TIME_LBN 16 +#define FRF_AB_XM_PAUSE_TIME_WIDTH 16 +#define FRF_AB_XM_RX_MAC_STAT_LBN 11 +#define FRF_AB_XM_RX_MAC_STAT_WIDTH 1 +#define FRF_AB_XM_TX_MAC_STAT_LBN 10 +#define FRF_AB_XM_TX_MAC_STAT_WIDTH 1 +#define FRF_AB_XM_MCNTL_PASS_LBN 8 +#define FRF_AB_XM_MCNTL_PASS_WIDTH 2 +#define FRF_AB_XM_REJ_CNTL_UCAST_LBN 6 +#define FRF_AB_XM_REJ_CNTL_UCAST_WIDTH 1 +#define FRF_AB_XM_REJ_CNTL_MCAST_LBN 5 +#define FRF_AB_XM_REJ_CNTL_MCAST_WIDTH 1 +#define FRF_AB_XM_ZPAUSE_LBN 2 +#define FRF_AB_XM_ZPAUSE_WIDTH 1 +#define FRF_AB_XM_XMIT_PAUSE_LBN 1 +#define FRF_AB_XM_XMIT_PAUSE_WIDTH 1 +#define FRF_AB_XM_DIS_FCNTL_LBN 0 +#define FRF_AB_XM_DIS_FCNTL_WIDTH 1 + + +/* + * FR_AB_XM_PAUSE_TIME_REG(128bit): + * XGMAC pause time register + */ +#define FR_AB_XM_PAUSE_TIME_REG_OFST 0x00001290 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_XM_TX_PAUSE_CNT_LBN 16 +#define FRF_AB_XM_TX_PAUSE_CNT_WIDTH 16 +#define FRF_AB_XM_RX_PAUSE_CNT_LBN 0 +#define FRF_AB_XM_RX_PAUSE_CNT_WIDTH 16 + + +/* + * FR_AB_XM_TX_PARAM_REG(128bit): + * XGMAC transmit parameter register + */ +#define FR_AB_XM_TX_PARAM_REG_OFST 0x000012d0 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_XM_TX_JUMBO_MODE_LBN 31 +#define FRF_AB_XM_TX_JUMBO_MODE_WIDTH 1 +#define FRF_AB_XM_MAX_TX_FRM_SIZE_HI_LBN 19 +#define FRF_AB_XM_MAX_TX_FRM_SIZE_HI_WIDTH 11 +#define FRF_AB_XM_MAX_TX_FRM_SIZE_LO_LBN 16 +#define FRF_AB_XM_MAX_TX_FRM_SIZE_LO_WIDTH 3 +#define FRF_AB_XM_PAD_CHAR_LBN 0 +#define FRF_AB_XM_PAD_CHAR_WIDTH 8 + + +/* + * FR_AB_XM_RX_PARAM_REG(128bit): + * XGMAC receive parameter register + */ +#define FR_AB_XM_RX_PARAM_REG_OFST 0x000012e0 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_XM_MAX_RX_FRM_SIZE_HI_LBN 3 +#define FRF_AB_XM_MAX_RX_FRM_SIZE_HI_WIDTH 11 +#define FRF_AB_XM_MAX_RX_FRM_SIZE_LO_LBN 0 +#define FRF_AB_XM_MAX_RX_FRM_SIZE_LO_WIDTH 3 + + +/* + * FR_AB_XM_MGT_INT_MSK_REG(128bit): + * XGMAC management interrupt mask register + */ +#define FR_AB_XM_MGT_INT_REG_OFST 0x000012f0 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_XM_STAT_CNTR_OF_LBN 9 +#define FRF_AB_XM_STAT_CNTR_OF_WIDTH 1 +#define FRF_AB_XM_STAT_CNTR_HF_LBN 8 +#define FRF_AB_XM_STAT_CNTR_HF_WIDTH 1 +#define FRF_AB_XM_PRMBLE_ERR_LBN 2 +#define FRF_AB_XM_PRMBLE_ERR_WIDTH 1 +#define FRF_AB_XM_RMTFLT_LBN 1 +#define FRF_AB_XM_RMTFLT_WIDTH 1 +#define FRF_AB_XM_LCLFLT_LBN 0 +#define FRF_AB_XM_LCLFLT_WIDTH 1 + + +/* + * FR_AB_XX_PWR_RST_REG(128bit): + * XGXS/XAUI powerdown/reset register + */ +#define FR_AB_XX_PWR_RST_REG_OFST 0x00001300 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_XX_PWRDND_SIG_LBN 31 +#define FRF_AB_XX_PWRDND_SIG_WIDTH 1 +#define FRF_AB_XX_PWRDNC_SIG_LBN 30 +#define FRF_AB_XX_PWRDNC_SIG_WIDTH 1 +#define FRF_AB_XX_PWRDNB_SIG_LBN 29 +#define FRF_AB_XX_PWRDNB_SIG_WIDTH 1 +#define FRF_AB_XX_PWRDNA_SIG_LBN 28 +#define FRF_AB_XX_PWRDNA_SIG_WIDTH 1 +#define FRF_AB_XX_SIM_MODE_LBN 27 +#define FRF_AB_XX_SIM_MODE_WIDTH 1 +#define FRF_AB_XX_RSTPLLCD_SIG_LBN 25 +#define FRF_AB_XX_RSTPLLCD_SIG_WIDTH 1 +#define FRF_AB_XX_RSTPLLAB_SIG_LBN 24 +#define FRF_AB_XX_RSTPLLAB_SIG_WIDTH 1 +#define FRF_AB_XX_RESETD_SIG_LBN 23 +#define FRF_AB_XX_RESETD_SIG_WIDTH 1 +#define FRF_AB_XX_RESETC_SIG_LBN 22 +#define FRF_AB_XX_RESETC_SIG_WIDTH 1 +#define FRF_AB_XX_RESETB_SIG_LBN 21 +#define FRF_AB_XX_RESETB_SIG_WIDTH 1 +#define FRF_AB_XX_RESETA_SIG_LBN 20 +#define FRF_AB_XX_RESETA_SIG_WIDTH 1 +#define FRF_AB_XX_RSTXGXSRX_SIG_LBN 18 +#define FRF_AB_XX_RSTXGXSRX_SIG_WIDTH 1 +#define FRF_AB_XX_RSTXGXSTX_SIG_LBN 17 +#define FRF_AB_XX_RSTXGXSTX_SIG_WIDTH 1 +#define FRF_AB_XX_SD_RST_ACT_LBN 16 +#define FRF_AB_XX_SD_RST_ACT_WIDTH 1 +#define FRF_AB_XX_PWRDND_EN_LBN 15 +#define FRF_AB_XX_PWRDND_EN_WIDTH 1 +#define FRF_AB_XX_PWRDNC_EN_LBN 14 +#define FRF_AB_XX_PWRDNC_EN_WIDTH 1 +#define FRF_AB_XX_PWRDNB_EN_LBN 13 +#define FRF_AB_XX_PWRDNB_EN_WIDTH 1 +#define FRF_AB_XX_PWRDNA_EN_LBN 12 +#define FRF_AB_XX_PWRDNA_EN_WIDTH 1 +#define FRF_AB_XX_RSTPLLCD_EN_LBN 9 +#define FRF_AB_XX_RSTPLLCD_EN_WIDTH 1 +#define FRF_AB_XX_RSTPLLAB_EN_LBN 8 +#define FRF_AB_XX_RSTPLLAB_EN_WIDTH 1 +#define FRF_AB_XX_RESETD_EN_LBN 7 +#define FRF_AB_XX_RESETD_EN_WIDTH 1 +#define FRF_AB_XX_RESETC_EN_LBN 6 +#define FRF_AB_XX_RESETC_EN_WIDTH 1 +#define FRF_AB_XX_RESETB_EN_LBN 5 +#define FRF_AB_XX_RESETB_EN_WIDTH 1 +#define FRF_AB_XX_RESETA_EN_LBN 4 +#define FRF_AB_XX_RESETA_EN_WIDTH 1 +#define FRF_AB_XX_RSTXGXSRX_EN_LBN 2 +#define FRF_AB_XX_RSTXGXSRX_EN_WIDTH 1 +#define FRF_AB_XX_RSTXGXSTX_EN_LBN 1 +#define FRF_AB_XX_RSTXGXSTX_EN_WIDTH 1 +#define FRF_AB_XX_RST_XX_EN_LBN 0 +#define FRF_AB_XX_RST_XX_EN_WIDTH 1 + + +/* + * FR_AB_XX_SD_CTL_REG(128bit): + * XGXS/XAUI powerdown/reset control register + */ +#define FR_AB_XX_SD_CTL_REG_OFST 0x00001310 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_XX_TERMADJ1_LBN 17 +#define FRF_AB_XX_TERMADJ1_WIDTH 1 +#define FRF_AB_XX_TERMADJ0_LBN 16 +#define FRF_AB_XX_TERMADJ0_WIDTH 1 +#define FRF_AB_XX_HIDRVD_LBN 15 +#define FRF_AB_XX_HIDRVD_WIDTH 1 +#define FRF_AB_XX_LODRVD_LBN 14 +#define FRF_AB_XX_LODRVD_WIDTH 1 +#define FRF_AB_XX_HIDRVC_LBN 13 +#define FRF_AB_XX_HIDRVC_WIDTH 1 +#define FRF_AB_XX_LODRVC_LBN 12 +#define FRF_AB_XX_LODRVC_WIDTH 1 +#define FRF_AB_XX_HIDRVB_LBN 11 +#define FRF_AB_XX_HIDRVB_WIDTH 1 +#define FRF_AB_XX_LODRVB_LBN 10 +#define FRF_AB_XX_LODRVB_WIDTH 1 +#define FRF_AB_XX_HIDRVA_LBN 9 +#define FRF_AB_XX_HIDRVA_WIDTH 1 +#define FRF_AB_XX_LODRVA_LBN 8 +#define FRF_AB_XX_LODRVA_WIDTH 1 +#define FRF_AB_XX_LPBKD_LBN 3 +#define FRF_AB_XX_LPBKD_WIDTH 1 +#define FRF_AB_XX_LPBKC_LBN 2 +#define FRF_AB_XX_LPBKC_WIDTH 1 +#define FRF_AB_XX_LPBKB_LBN 1 +#define FRF_AB_XX_LPBKB_WIDTH 1 +#define FRF_AB_XX_LPBKA_LBN 0 +#define FRF_AB_XX_LPBKA_WIDTH 1 + + +/* + * FR_AB_XX_TXDRV_CTL_REG(128bit): + * XAUI SerDes transmit drive control register + */ +#define FR_AB_XX_TXDRV_CTL_REG_OFST 0x00001320 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_XX_DEQD_LBN 28 +#define FRF_AB_XX_DEQD_WIDTH 4 +#define FRF_AB_XX_DEQC_LBN 24 +#define FRF_AB_XX_DEQC_WIDTH 4 +#define FRF_AB_XX_DEQB_LBN 20 +#define FRF_AB_XX_DEQB_WIDTH 4 +#define FRF_AB_XX_DEQA_LBN 16 +#define FRF_AB_XX_DEQA_WIDTH 4 +#define FRF_AB_XX_DTXD_LBN 12 +#define FRF_AB_XX_DTXD_WIDTH 4 +#define FRF_AB_XX_DTXC_LBN 8 +#define FRF_AB_XX_DTXC_WIDTH 4 +#define FRF_AB_XX_DTXB_LBN 4 +#define FRF_AB_XX_DTXB_WIDTH 4 +#define FRF_AB_XX_DTXA_LBN 0 +#define FRF_AB_XX_DTXA_WIDTH 4 + + +/* + * FR_AB_XX_PRBS_CTL_REG(128bit): + * documentation to be written for sum_XX_PRBS_CTL_REG + */ +#define FR_AB_XX_PRBS_CTL_REG_OFST 0x00001330 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_XX_CH3_RX_PRBS_SEL_LBN 30 +#define FRF_AB_XX_CH3_RX_PRBS_SEL_WIDTH 2 +#define FRF_AB_XX_CH3_RX_PRBS_INV_LBN 29 +#define FRF_AB_XX_CH3_RX_PRBS_INV_WIDTH 1 +#define FRF_AB_XX_CH3_RX_PRBS_CHKEN_LBN 28 +#define FRF_AB_XX_CH3_RX_PRBS_CHKEN_WIDTH 1 +#define FRF_AB_XX_CH2_RX_PRBS_SEL_LBN 26 +#define FRF_AB_XX_CH2_RX_PRBS_SEL_WIDTH 2 +#define FRF_AB_XX_CH2_RX_PRBS_INV_LBN 25 +#define FRF_AB_XX_CH2_RX_PRBS_INV_WIDTH 1 +#define FRF_AB_XX_CH2_RX_PRBS_CHKEN_LBN 24 +#define FRF_AB_XX_CH2_RX_PRBS_CHKEN_WIDTH 1 +#define FRF_AB_XX_CH1_RX_PRBS_SEL_LBN 22 +#define FRF_AB_XX_CH1_RX_PRBS_SEL_WIDTH 2 +#define FRF_AB_XX_CH1_RX_PRBS_INV_LBN 21 +#define FRF_AB_XX_CH1_RX_PRBS_INV_WIDTH 1 +#define FRF_AB_XX_CH1_RX_PRBS_CHKEN_LBN 20 +#define FRF_AB_XX_CH1_RX_PRBS_CHKEN_WIDTH 1 +#define FRF_AB_XX_CH0_RX_PRBS_SEL_LBN 18 +#define FRF_AB_XX_CH0_RX_PRBS_SEL_WIDTH 2 +#define FRF_AB_XX_CH0_RX_PRBS_INV_LBN 17 +#define FRF_AB_XX_CH0_RX_PRBS_INV_WIDTH 1 +#define FRF_AB_XX_CH0_RX_PRBS_CHKEN_LBN 16 +#define FRF_AB_XX_CH0_RX_PRBS_CHKEN_WIDTH 1 +#define FRF_AB_XX_CH3_TX_PRBS_SEL_LBN 14 +#define FRF_AB_XX_CH3_TX_PRBS_SEL_WIDTH 2 +#define FRF_AB_XX_CH3_TX_PRBS_INV_LBN 13 +#define FRF_AB_XX_CH3_TX_PRBS_INV_WIDTH 1 +#define FRF_AB_XX_CH3_TX_PRBS_CHKEN_LBN 12 +#define FRF_AB_XX_CH3_TX_PRBS_CHKEN_WIDTH 1 +#define FRF_AB_XX_CH2_TX_PRBS_SEL_LBN 10 +#define FRF_AB_XX_CH2_TX_PRBS_SEL_WIDTH 2 +#define FRF_AB_XX_CH2_TX_PRBS_INV_LBN 9 +#define FRF_AB_XX_CH2_TX_PRBS_INV_WIDTH 1 +#define FRF_AB_XX_CH2_TX_PRBS_CHKEN_LBN 8 +#define FRF_AB_XX_CH2_TX_PRBS_CHKEN_WIDTH 1 +#define FRF_AB_XX_CH1_TX_PRBS_SEL_LBN 6 +#define FRF_AB_XX_CH1_TX_PRBS_SEL_WIDTH 2 +#define FRF_AB_XX_CH1_TX_PRBS_INV_LBN 5 +#define FRF_AB_XX_CH1_TX_PRBS_INV_WIDTH 1 +#define FRF_AB_XX_CH1_TX_PRBS_CHKEN_LBN 4 +#define FRF_AB_XX_CH1_TX_PRBS_CHKEN_WIDTH 1 +#define FRF_AB_XX_CH0_TX_PRBS_SEL_LBN 2 +#define FRF_AB_XX_CH0_TX_PRBS_SEL_WIDTH 2 +#define FRF_AB_XX_CH0_TX_PRBS_INV_LBN 1 +#define FRF_AB_XX_CH0_TX_PRBS_INV_WIDTH 1 +#define FRF_AB_XX_CH0_TX_PRBS_CHKEN_LBN 0 +#define FRF_AB_XX_CH0_TX_PRBS_CHKEN_WIDTH 1 + + +/* + * FR_AB_XX_PRBS_CHK_REG(128bit): + * documentation to be written for sum_XX_PRBS_CHK_REG + */ +#define FR_AB_XX_PRBS_CHK_REG_OFST 0x00001340 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_XX_REV_LB_EN_LBN 16 +#define FRF_AB_XX_REV_LB_EN_WIDTH 1 +#define FRF_AB_XX_CH3_DEG_DET_LBN 15 +#define FRF_AB_XX_CH3_DEG_DET_WIDTH 1 +#define FRF_AB_XX_CH3_LFSR_LOCK_IND_LBN 14 +#define FRF_AB_XX_CH3_LFSR_LOCK_IND_WIDTH 1 +#define FRF_AB_XX_CH3_PRBS_FRUN_LBN 13 +#define FRF_AB_XX_CH3_PRBS_FRUN_WIDTH 1 +#define FRF_AB_XX_CH3_ERR_CHK_LBN 12 +#define FRF_AB_XX_CH3_ERR_CHK_WIDTH 1 +#define FRF_AB_XX_CH2_DEG_DET_LBN 11 +#define FRF_AB_XX_CH2_DEG_DET_WIDTH 1 +#define FRF_AB_XX_CH2_LFSR_LOCK_IND_LBN 10 +#define FRF_AB_XX_CH2_LFSR_LOCK_IND_WIDTH 1 +#define FRF_AB_XX_CH2_PRBS_FRUN_LBN 9 +#define FRF_AB_XX_CH2_PRBS_FRUN_WIDTH 1 +#define FRF_AB_XX_CH2_ERR_CHK_LBN 8 +#define FRF_AB_XX_CH2_ERR_CHK_WIDTH 1 +#define FRF_AB_XX_CH1_DEG_DET_LBN 7 +#define FRF_AB_XX_CH1_DEG_DET_WIDTH 1 +#define FRF_AB_XX_CH1_LFSR_LOCK_IND_LBN 6 +#define FRF_AB_XX_CH1_LFSR_LOCK_IND_WIDTH 1 +#define FRF_AB_XX_CH1_PRBS_FRUN_LBN 5 +#define FRF_AB_XX_CH1_PRBS_FRUN_WIDTH 1 +#define FRF_AB_XX_CH1_ERR_CHK_LBN 4 +#define FRF_AB_XX_CH1_ERR_CHK_WIDTH 1 +#define FRF_AB_XX_CH0_DEG_DET_LBN 3 +#define FRF_AB_XX_CH0_DEG_DET_WIDTH 1 +#define FRF_AB_XX_CH0_LFSR_LOCK_IND_LBN 2 +#define FRF_AB_XX_CH0_LFSR_LOCK_IND_WIDTH 1 +#define FRF_AB_XX_CH0_PRBS_FRUN_LBN 1 +#define FRF_AB_XX_CH0_PRBS_FRUN_WIDTH 1 +#define FRF_AB_XX_CH0_ERR_CHK_LBN 0 +#define FRF_AB_XX_CH0_ERR_CHK_WIDTH 1 + + +/* + * FR_AB_XX_PRBS_ERR_REG(128bit): + * documentation to be written for sum_XX_PRBS_ERR_REG + */ +#define FR_AB_XX_PRBS_ERR_REG_OFST 0x00001350 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_XX_CH3_PRBS_ERR_CNT_LBN 24 +#define FRF_AB_XX_CH3_PRBS_ERR_CNT_WIDTH 8 +#define FRF_AB_XX_CH2_PRBS_ERR_CNT_LBN 16 +#define FRF_AB_XX_CH2_PRBS_ERR_CNT_WIDTH 8 +#define FRF_AB_XX_CH1_PRBS_ERR_CNT_LBN 8 +#define FRF_AB_XX_CH1_PRBS_ERR_CNT_WIDTH 8 +#define FRF_AB_XX_CH0_PRBS_ERR_CNT_LBN 0 +#define FRF_AB_XX_CH0_PRBS_ERR_CNT_WIDTH 8 + + +/* + * FR_AB_XX_CORE_STAT_REG(128bit): + * XAUI XGXS core status register + */ +#define FR_AB_XX_CORE_STAT_REG_OFST 0x00001360 +/* falcona0,falconb0=net_func_bar2,falcona0=char_func_bar0 */ + +#define FRF_AB_XX_FORCE_SIG3_LBN 31 +#define FRF_AB_XX_FORCE_SIG3_WIDTH 1 +#define FRF_AB_XX_FORCE_SIG3_VAL_LBN 30 +#define FRF_AB_XX_FORCE_SIG3_VAL_WIDTH 1 +#define FRF_AB_XX_FORCE_SIG2_LBN 29 +#define FRF_AB_XX_FORCE_SIG2_WIDTH 1 +#define FRF_AB_XX_FORCE_SIG2_VAL_LBN 28 +#define FRF_AB_XX_FORCE_SIG2_VAL_WIDTH 1 +#define FRF_AB_XX_FORCE_SIG1_LBN 27 +#define FRF_AB_XX_FORCE_SIG1_WIDTH 1 +#define FRF_AB_XX_FORCE_SIG1_VAL_LBN 26 +#define FRF_AB_XX_FORCE_SIG1_VAL_WIDTH 1 +#define FRF_AB_XX_FORCE_SIG0_LBN 25 +#define FRF_AB_XX_FORCE_SIG0_WIDTH 1 +#define FRF_AB_XX_FORCE_SIG0_VAL_LBN 24 +#define FRF_AB_XX_FORCE_SIG0_VAL_WIDTH 1 +#define FRF_AB_XX_XGXS_LB_EN_LBN 23 +#define FRF_AB_XX_XGXS_LB_EN_WIDTH 1 +#define FRF_AB_XX_XGMII_LB_EN_LBN 22 +#define FRF_AB_XX_XGMII_LB_EN_WIDTH 1 +#define FRF_AB_XX_MATCH_FAULT_LBN 21 +#define FRF_AB_XX_MATCH_FAULT_WIDTH 1 +#define FRF_AB_XX_ALIGN_DONE_LBN 20 +#define FRF_AB_XX_ALIGN_DONE_WIDTH 1 +#define FRF_AB_XX_SYNC_STAT3_LBN 19 +#define FRF_AB_XX_SYNC_STAT3_WIDTH 1 +#define FRF_AB_XX_SYNC_STAT2_LBN 18 +#define FRF_AB_XX_SYNC_STAT2_WIDTH 1 +#define FRF_AB_XX_SYNC_STAT1_LBN 17 +#define FRF_AB_XX_SYNC_STAT1_WIDTH 1 +#define FRF_AB_XX_SYNC_STAT0_LBN 16 +#define FRF_AB_XX_SYNC_STAT0_WIDTH 1 +#define FRF_AB_XX_COMMA_DET_CH3_LBN 15 +#define FRF_AB_XX_COMMA_DET_CH3_WIDTH 1 +#define FRF_AB_XX_COMMA_DET_CH2_LBN 14 +#define FRF_AB_XX_COMMA_DET_CH2_WIDTH 1 +#define FRF_AB_XX_COMMA_DET_CH1_LBN 13 +#define FRF_AB_XX_COMMA_DET_CH1_WIDTH 1 +#define FRF_AB_XX_COMMA_DET_CH0_LBN 12 +#define FRF_AB_XX_COMMA_DET_CH0_WIDTH 1 +#define FRF_AB_XX_CGRP_ALIGN_CH3_LBN 11 +#define FRF_AB_XX_CGRP_ALIGN_CH3_WIDTH 1 +#define FRF_AB_XX_CGRP_ALIGN_CH2_LBN 10 +#define FRF_AB_XX_CGRP_ALIGN_CH2_WIDTH 1 +#define FRF_AB_XX_CGRP_ALIGN_CH1_LBN 9 +#define FRF_AB_XX_CGRP_ALIGN_CH1_WIDTH 1 +#define FRF_AB_XX_CGRP_ALIGN_CH0_LBN 8 +#define FRF_AB_XX_CGRP_ALIGN_CH0_WIDTH 1 +#define FRF_AB_XX_CHAR_ERR_CH3_LBN 7 +#define FRF_AB_XX_CHAR_ERR_CH3_WIDTH 1 +#define FRF_AB_XX_CHAR_ERR_CH2_LBN 6 +#define FRF_AB_XX_CHAR_ERR_CH2_WIDTH 1 +#define FRF_AB_XX_CHAR_ERR_CH1_LBN 5 +#define FRF_AB_XX_CHAR_ERR_CH1_WIDTH 1 +#define FRF_AB_XX_CHAR_ERR_CH0_LBN 4 +#define FRF_AB_XX_CHAR_ERR_CH0_WIDTH 1 +#define FRF_AB_XX_DISPERR_CH3_LBN 3 +#define FRF_AB_XX_DISPERR_CH3_WIDTH 1 +#define FRF_AB_XX_DISPERR_CH2_LBN 2 +#define FRF_AB_XX_DISPERR_CH2_WIDTH 1 +#define FRF_AB_XX_DISPERR_CH1_LBN 1 +#define FRF_AB_XX_DISPERR_CH1_WIDTH 1 +#define FRF_AB_XX_DISPERR_CH0_LBN 0 +#define FRF_AB_XX_DISPERR_CH0_WIDTH 1 + + +/* + * FR_AA_RX_DESC_PTR_TBL_KER(128bit): + * Receive descriptor pointer table + */ +#define FR_AA_RX_DESC_PTR_TBL_KER_OFST 0x00011800 +/* falcona0=net_func_bar2 */ +#define FR_AA_RX_DESC_PTR_TBL_KER_STEP 16 +#define FR_AA_RX_DESC_PTR_TBL_KER_ROWS 4 +/* + * FR_AZ_RX_DESC_PTR_TBL(128bit): + * Receive descriptor pointer table + */ +#define FR_AZ_RX_DESC_PTR_TBL_OFST 0x00f40000 +/* sienaa0=net_func_bar2,falconb0=net_func_bar2,falcona0=char_func_bar0 */ +#define FR_AZ_RX_DESC_PTR_TBL_STEP 16 +#define FR_CZ_RX_DESC_PTR_TBL_ROWS 1024 +#define FR_AB_RX_DESC_PTR_TBL_ROWS 4096 + +#define FRF_CZ_RX_HDR_SPLIT_LBN 90 +#define FRF_CZ_RX_HDR_SPLIT_WIDTH 1 +#define FRF_AZ_RX_RESET_LBN 89 +#define FRF_AZ_RX_RESET_WIDTH 1 +#define FRF_AZ_RX_ISCSI_DDIG_EN_LBN 88 +#define FRF_AZ_RX_ISCSI_DDIG_EN_WIDTH 1 +#define FRF_AZ_RX_ISCSI_HDIG_EN_LBN 87 +#define FRF_AZ_RX_ISCSI_HDIG_EN_WIDTH 1 +#define FRF_AZ_RX_DESC_PREF_ACT_LBN 86 +#define FRF_AZ_RX_DESC_PREF_ACT_WIDTH 1 +#define FRF_AZ_RX_DC_HW_RPTR_LBN 80 +#define FRF_AZ_RX_DC_HW_RPTR_WIDTH 6 +#define FRF_AZ_RX_DESCQ_HW_RPTR_LBN 68 +#define FRF_AZ_RX_DESCQ_HW_RPTR_WIDTH 12 +#define FRF_AZ_RX_DESCQ_SW_WPTR_LBN 56 +#define FRF_AZ_RX_DESCQ_SW_WPTR_WIDTH 12 +#define FRF_AZ_RX_DESCQ_BUF_BASE_ID_LBN 36 +#define FRF_AZ_RX_DESCQ_BUF_BASE_ID_WIDTH 20 +#define FRF_AZ_RX_DESCQ_EVQ_ID_LBN 24 +#define FRF_AZ_RX_DESCQ_EVQ_ID_WIDTH 12 +#define FRF_AZ_RX_DESCQ_OWNER_ID_LBN 10 +#define FRF_AZ_RX_DESCQ_OWNER_ID_WIDTH 14 +#define FRF_AZ_RX_DESCQ_LABEL_LBN 5 +#define FRF_AZ_RX_DESCQ_LABEL_WIDTH 5 +#define FRF_AZ_RX_DESCQ_SIZE_LBN 3 +#define FRF_AZ_RX_DESCQ_SIZE_WIDTH 2 +#define FFE_AZ_RX_DESCQ_SIZE_4K 3 +#define FFE_AZ_RX_DESCQ_SIZE_2K 2 +#define FFE_AZ_RX_DESCQ_SIZE_1K 1 +#define FFE_AZ_RX_DESCQ_SIZE_512 0 +#define FRF_AZ_RX_DESCQ_TYPE_LBN 2 +#define FRF_AZ_RX_DESCQ_TYPE_WIDTH 1 +#define FRF_AZ_RX_DESCQ_JUMBO_LBN 1 +#define FRF_AZ_RX_DESCQ_JUMBO_WIDTH 1 +#define FRF_AZ_RX_DESCQ_EN_LBN 0 +#define FRF_AZ_RX_DESCQ_EN_WIDTH 1 + + +/* + * FR_AA_TX_DESC_PTR_TBL_KER(128bit): + * Transmit descriptor pointer + */ +#define FR_AA_TX_DESC_PTR_TBL_KER_OFST 0x00011900 +/* falcona0=net_func_bar2 */ +#define FR_AA_TX_DESC_PTR_TBL_KER_STEP 16 +#define FR_AA_TX_DESC_PTR_TBL_KER_ROWS 8 +/* + * FR_AZ_TX_DESC_PTR_TBL(128bit): + * Transmit descriptor pointer + */ +#define FR_AZ_TX_DESC_PTR_TBL_OFST 0x00f50000 +/* falconb0=net_func_bar2,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ +#define FR_AZ_TX_DESC_PTR_TBL_STEP 16 +#define FR_AB_TX_DESC_PTR_TBL_ROWS 4096 +#define FR_CZ_TX_DESC_PTR_TBL_ROWS 1024 + +#define FRF_CZ_TX_DPT_Q_MASK_WIDTH_LBN 94 +#define FRF_CZ_TX_DPT_Q_MASK_WIDTH_WIDTH 2 +#define FRF_CZ_TX_DPT_ETH_FILT_EN_LBN 93 +#define FRF_CZ_TX_DPT_ETH_FILT_EN_WIDTH 1 +#define FRF_CZ_TX_DPT_IP_FILT_EN_LBN 92 +#define FRF_CZ_TX_DPT_IP_FILT_EN_WIDTH 1 +#define FRF_BZ_TX_NON_IP_DROP_DIS_LBN 91 +#define FRF_BZ_TX_NON_IP_DROP_DIS_WIDTH 1 +#define FRF_BZ_TX_IP_CHKSM_DIS_LBN 90 +#define FRF_BZ_TX_IP_CHKSM_DIS_WIDTH 1 +#define FRF_BZ_TX_TCP_CHKSM_DIS_LBN 89 +#define FRF_BZ_TX_TCP_CHKSM_DIS_WIDTH 1 +#define FRF_AZ_TX_DESCQ_EN_LBN 88 +#define FRF_AZ_TX_DESCQ_EN_WIDTH 1 +#define FRF_AZ_TX_ISCSI_DDIG_EN_LBN 87 +#define FRF_AZ_TX_ISCSI_DDIG_EN_WIDTH 1 +#define FRF_AZ_TX_ISCSI_HDIG_EN_LBN 86 +#define FRF_AZ_TX_ISCSI_HDIG_EN_WIDTH 1 +#define FRF_AZ_TX_DC_HW_RPTR_LBN 80 +#define FRF_AZ_TX_DC_HW_RPTR_WIDTH 6 +#define FRF_AZ_TX_DESCQ_HW_RPTR_LBN 68 +#define FRF_AZ_TX_DESCQ_HW_RPTR_WIDTH 12 +#define FRF_AZ_TX_DESCQ_SW_WPTR_LBN 56 +#define FRF_AZ_TX_DESCQ_SW_WPTR_WIDTH 12 +#define FRF_AZ_TX_DESCQ_BUF_BASE_ID_LBN 36 +#define FRF_AZ_TX_DESCQ_BUF_BASE_ID_WIDTH 20 +#define FRF_AZ_TX_DESCQ_EVQ_ID_LBN 24 +#define FRF_AZ_TX_DESCQ_EVQ_ID_WIDTH 12 +#define FRF_AZ_TX_DESCQ_OWNER_ID_LBN 10 +#define FRF_AZ_TX_DESCQ_OWNER_ID_WIDTH 14 +#define FRF_AZ_TX_DESCQ_LABEL_LBN 5 +#define FRF_AZ_TX_DESCQ_LABEL_WIDTH 5 +#define FRF_AZ_TX_DESCQ_SIZE_LBN 3 +#define FRF_AZ_TX_DESCQ_SIZE_WIDTH 2 +#define FFE_AZ_TX_DESCQ_SIZE_4K 3 +#define FFE_AZ_TX_DESCQ_SIZE_2K 2 +#define FFE_AZ_TX_DESCQ_SIZE_1K 1 +#define FFE_AZ_TX_DESCQ_SIZE_512 0 +#define FRF_AZ_TX_DESCQ_TYPE_LBN 1 +#define FRF_AZ_TX_DESCQ_TYPE_WIDTH 2 +#define FRF_AZ_TX_DESCQ_FLUSH_LBN 0 +#define FRF_AZ_TX_DESCQ_FLUSH_WIDTH 1 + + +/* + * FR_AA_EVQ_PTR_TBL_KER(128bit): + * Event queue pointer table + */ +#define FR_AA_EVQ_PTR_TBL_KER_OFST 0x00011a00 +/* falcona0=net_func_bar2 */ +#define FR_AA_EVQ_PTR_TBL_KER_STEP 16 +#define FR_AA_EVQ_PTR_TBL_KER_ROWS 4 +/* + * FR_AZ_EVQ_PTR_TBL(128bit): + * Event queue pointer table + */ +#define FR_AZ_EVQ_PTR_TBL_OFST 0x00f60000 +/* sienaa0=net_func_bar2,falconb0=net_func_bar2,falcona0=char_func_bar0 */ +#define FR_AZ_EVQ_PTR_TBL_STEP 16 +#define FR_CZ_EVQ_PTR_TBL_ROWS 1024 +#define FR_AB_EVQ_PTR_TBL_ROWS 4096 + +#define FRF_BZ_EVQ_RPTR_IGN_LBN 40 +#define FRF_BZ_EVQ_RPTR_IGN_WIDTH 1 +#define FRF_AZ_EVQ_WKUP_OR_INT_EN_LBN 39 +#define FRF_AZ_EVQ_WKUP_OR_INT_EN_WIDTH 1 +#define FRF_AZ_EVQ_NXT_WPTR_LBN 24 +#define FRF_AZ_EVQ_NXT_WPTR_WIDTH 15 +#define FRF_AZ_EVQ_EN_LBN 23 +#define FRF_AZ_EVQ_EN_WIDTH 1 +#define FRF_AZ_EVQ_SIZE_LBN 20 +#define FRF_AZ_EVQ_SIZE_WIDTH 3 +#define FFE_AZ_EVQ_SIZE_32K 6 +#define FFE_AZ_EVQ_SIZE_16K 5 +#define FFE_AZ_EVQ_SIZE_8K 4 +#define FFE_AZ_EVQ_SIZE_4K 3 +#define FFE_AZ_EVQ_SIZE_2K 2 +#define FFE_AZ_EVQ_SIZE_1K 1 +#define FFE_AZ_EVQ_SIZE_512 0 +#define FRF_AZ_EVQ_BUF_BASE_ID_LBN 0 +#define FRF_AZ_EVQ_BUF_BASE_ID_WIDTH 20 + + +/* + * FR_AA_BUF_HALF_TBL_KER(64bit): + * Buffer table in half buffer table mode direct access by driver + */ +#define FR_AA_BUF_HALF_TBL_KER_OFST 0x00018000 +/* falcona0=net_func_bar2 */ +#define FR_AA_BUF_HALF_TBL_KER_STEP 8 +#define FR_AA_BUF_HALF_TBL_KER_ROWS 4096 +/* + * FR_AZ_BUF_HALF_TBL(64bit): + * Buffer table in half buffer table mode direct access by driver + */ +#define FR_AZ_BUF_HALF_TBL_OFST 0x00800000 +/* sienaa0=net_func_bar2,falconb0=net_func_bar2,falcona0=char_func_bar0 */ +#define FR_AZ_BUF_HALF_TBL_STEP 8 +#define FR_CZ_BUF_HALF_TBL_ROWS 147456 +#define FR_AB_BUF_HALF_TBL_ROWS 524288 + +#define FRF_AZ_BUF_ADR_HBUF_ODD_LBN 44 +#define FRF_AZ_BUF_ADR_HBUF_ODD_WIDTH 20 +#define FRF_AZ_BUF_OWNER_ID_HBUF_ODD_LBN 32 +#define FRF_AZ_BUF_OWNER_ID_HBUF_ODD_WIDTH 12 +#define FRF_AZ_BUF_ADR_HBUF_EVEN_LBN 12 +#define FRF_AZ_BUF_ADR_HBUF_EVEN_WIDTH 20 +#define FRF_AZ_BUF_OWNER_ID_HBUF_EVEN_LBN 0 +#define FRF_AZ_BUF_OWNER_ID_HBUF_EVEN_WIDTH 12 + + +/* + * FR_AA_BUF_FULL_TBL_KER(64bit): + * Buffer table in full buffer table mode direct access by driver + */ +#define FR_AA_BUF_FULL_TBL_KER_OFST 0x00018000 +/* falcona0=net_func_bar2 */ +#define FR_AA_BUF_FULL_TBL_KER_STEP 8 +#define FR_AA_BUF_FULL_TBL_KER_ROWS 4096 +/* + * FR_AZ_BUF_FULL_TBL(64bit): + * Buffer table in full buffer table mode direct access by driver + */ +#define FR_AZ_BUF_FULL_TBL_OFST 0x00800000 +/* sienaa0=net_func_bar2,falconb0=net_func_bar2,falcona0=char_func_bar0 */ +#define FR_AZ_BUF_FULL_TBL_STEP 8 + +#define FR_CZ_BUF_FULL_TBL_ROWS 147456 +#define FR_AB_BUF_FULL_TBL_ROWS 917504 + +#define FRF_AZ_BUF_FULL_UNUSED_LBN 51 +#define FRF_AZ_BUF_FULL_UNUSED_WIDTH 13 +#define FRF_AZ_IP_DAT_BUF_SIZE_LBN 50 +#define FRF_AZ_IP_DAT_BUF_SIZE_WIDTH 1 +#define FRF_AZ_BUF_ADR_REGION_LBN 48 +#define FRF_AZ_BUF_ADR_REGION_WIDTH 2 +#define FFE_AZ_BUF_ADR_REGN3 3 +#define FFE_AZ_BUF_ADR_REGN2 2 +#define FFE_AZ_BUF_ADR_REGN1 1 +#define FFE_AZ_BUF_ADR_REGN0 0 +#define FRF_AZ_BUF_ADR_FBUF_LBN 14 +#define FRF_AZ_BUF_ADR_FBUF_WIDTH 34 +#define FRF_AZ_BUF_ADR_FBUF_DW0_LBN 14 +#define FRF_AZ_BUF_ADR_FBUF_DW0_WIDTH 32 +#define FRF_AZ_BUF_ADR_FBUF_DW1_LBN 46 +#define FRF_AZ_BUF_ADR_FBUF_DW1_WIDTH 2 +#define FRF_AZ_BUF_OWNER_ID_FBUF_LBN 0 +#define FRF_AZ_BUF_OWNER_ID_FBUF_WIDTH 14 + + +/* + * FR_AZ_RX_FILTER_TBL0(128bit): + * TCP/IPv4 Receive filter table + */ +#define FR_AZ_RX_FILTER_TBL0_OFST 0x00f00000 +/* falconb0,sienaa0=net_func_bar2,falcona0=char_func_bar0 */ +#define FR_AZ_RX_FILTER_TBL0_STEP 32 +#define FR_AZ_RX_FILTER_TBL0_ROWS 8192 +/* + * FR_AB_RX_FILTER_TBL1(128bit): + * TCP/IPv4 Receive filter table + */ +#define FR_AB_RX_FILTER_TBL1_OFST 0x00f00010 +/* falconb0=net_func_bar2,falcona0=char_func_bar0 */ +#define FR_AB_RX_FILTER_TBL1_STEP 32 +#define FR_AB_RX_FILTER_TBL1_ROWS 8192 + +#define FRF_BZ_RSS_EN_LBN 110 +#define FRF_BZ_RSS_EN_WIDTH 1 +#define FRF_BZ_SCATTER_EN_LBN 109 +#define FRF_BZ_SCATTER_EN_WIDTH 1 +#define FRF_AZ_TCP_UDP_LBN 108 +#define FRF_AZ_TCP_UDP_WIDTH 1 +#define FRF_AZ_RXQ_ID_LBN 96 +#define FRF_AZ_RXQ_ID_WIDTH 12 +#define FRF_AZ_DEST_IP_LBN 64 +#define FRF_AZ_DEST_IP_WIDTH 32 +#define FRF_AZ_DEST_PORT_TCP_LBN 48 +#define FRF_AZ_DEST_PORT_TCP_WIDTH 16 +#define FRF_AZ_SRC_IP_LBN 16 +#define FRF_AZ_SRC_IP_WIDTH 32 +#define FRF_AZ_SRC_TCP_DEST_UDP_LBN 0 +#define FRF_AZ_SRC_TCP_DEST_UDP_WIDTH 16 + + +/* + * FR_CZ_RX_MAC_FILTER_TBL0(128bit): + * Receive Ethernet filter table + */ +#define FR_CZ_RX_MAC_FILTER_TBL0_OFST 0x00f00010 +/* sienaa0=net_func_bar2 */ +#define FR_CZ_RX_MAC_FILTER_TBL0_STEP 32 +#define FR_CZ_RX_MAC_FILTER_TBL0_ROWS 512 + +#define FRF_CZ_RMFT_RSS_EN_LBN 75 +#define FRF_CZ_RMFT_RSS_EN_WIDTH 1 +#define FRF_CZ_RMFT_SCATTER_EN_LBN 74 +#define FRF_CZ_RMFT_SCATTER_EN_WIDTH 1 +#define FRF_CZ_RMFT_IP_OVERRIDE_LBN 73 +#define FRF_CZ_RMFT_IP_OVERRIDE_WIDTH 1 +#define FRF_CZ_RMFT_RXQ_ID_LBN 61 +#define FRF_CZ_RMFT_RXQ_ID_WIDTH 12 +#define FRF_CZ_RMFT_WILDCARD_MATCH_LBN 60 +#define FRF_CZ_RMFT_WILDCARD_MATCH_WIDTH 1 +#define FRF_CZ_RMFT_DEST_MAC_LBN 12 +#define FRF_CZ_RMFT_DEST_MAC_WIDTH 48 +#define FRF_CZ_RMFT_DEST_MAC_DW0_LBN 12 +#define FRF_CZ_RMFT_DEST_MAC_DW0_WIDTH 32 +#define FRF_CZ_RMFT_DEST_MAC_DW1_LBN 44 +#define FRF_CZ_RMFT_DEST_MAC_DW1_WIDTH 16 +#define FRF_CZ_RMFT_VLAN_ID_LBN 0 +#define FRF_CZ_RMFT_VLAN_ID_WIDTH 12 + + +/* + * FR_AZ_TIMER_TBL(128bit): + * Timer table + */ +#define FR_AZ_TIMER_TBL_OFST 0x00f70000 +/* sienaa0=net_func_bar2,falconb0=net_func_bar2,falcona0=char_func_bar0 */ +#define FR_AZ_TIMER_TBL_STEP 16 +#define FR_CZ_TIMER_TBL_ROWS 1024 +#define FR_AB_TIMER_TBL_ROWS 4096 + +#define FRF_CZ_TIMER_Q_EN_LBN 33 +#define FRF_CZ_TIMER_Q_EN_WIDTH 1 +#define FRF_CZ_INT_ARMD_LBN 32 +#define FRF_CZ_INT_ARMD_WIDTH 1 +#define FRF_CZ_INT_PEND_LBN 31 +#define FRF_CZ_INT_PEND_WIDTH 1 +#define FRF_CZ_HOST_NOTIFY_MODE_LBN 30 +#define FRF_CZ_HOST_NOTIFY_MODE_WIDTH 1 +#define FRF_CZ_RELOAD_TIMER_VAL_LBN 16 +#define FRF_CZ_RELOAD_TIMER_VAL_WIDTH 14 +#define FRF_CZ_TIMER_MODE_LBN 14 +#define FRF_CZ_TIMER_MODE_WIDTH 2 +#define FFE_CZ_TIMER_MODE_INT_HLDOFF 3 +#define FFE_CZ_TIMER_MODE_TRIG_START 2 +#define FFE_CZ_TIMER_MODE_IMMED_START 1 +#define FFE_CZ_TIMER_MODE_DIS 0 +#define FRF_AB_TIMER_MODE_LBN 12 +#define FRF_AB_TIMER_MODE_WIDTH 2 +#define FFE_AB_TIMER_MODE_INT_HLDOFF 2 +#define FFE_AB_TIMER_MODE_TRIG_START 2 +#define FFE_AB_TIMER_MODE_IMMED_START 1 +#define FFE_AB_TIMER_MODE_DIS 0 +#define FRF_CZ_TIMER_VAL_LBN 0 +#define FRF_CZ_TIMER_VAL_WIDTH 14 +#define FRF_AB_TIMER_VAL_LBN 0 +#define FRF_AB_TIMER_VAL_WIDTH 12 + + +/* + * FR_BZ_TX_PACE_TBL(128bit): + * Transmit pacing table + */ +#define FR_BZ_TX_PACE_TBL_OFST 0x00f80000 +/* sienaa0=net_func_bar2,falconb0=net_func_bar2 */ +#define FR_AZ_TX_PACE_TBL_STEP 16 +#define FR_CZ_TX_PACE_TBL_ROWS 1024 +#define FR_BB_TX_PACE_TBL_ROWS 4096 +/* + * FR_AA_TX_PACE_TBL(128bit): + * Transmit pacing table + */ +#define FR_AA_TX_PACE_TBL_OFST 0x00f80040 +/* falcona0=char_func_bar0 */ +/* FR_AZ_TX_PACE_TBL_STEP 16 */ +#define FR_AA_TX_PACE_TBL_ROWS 4092 + +#define FRF_AZ_TX_PACE_LBN 0 +#define FRF_AZ_TX_PACE_WIDTH 5 + + +/* + * FR_BZ_RX_INDIRECTION_TBL(7bit): + * RX Indirection Table + */ +#define FR_BZ_RX_INDIRECTION_TBL_OFST 0x00fb0000 +/* falconb0,sienaa0=net_func_bar2 */ +#define FR_BZ_RX_INDIRECTION_TBL_STEP 16 +#define FR_BZ_RX_INDIRECTION_TBL_ROWS 128 + +#define FRF_BZ_IT_QUEUE_LBN 0 +#define FRF_BZ_IT_QUEUE_WIDTH 6 + + +/* + * FR_CZ_TX_FILTER_TBL0(128bit): + * TCP/IPv4 Transmit filter table + */ +#define FR_CZ_TX_FILTER_TBL0_OFST 0x00fc0000 +/* sienaa0=net_func_bar2 */ +#define FR_CZ_TX_FILTER_TBL0_STEP 16 +#define FR_CZ_TX_FILTER_TBL0_ROWS 8192 + +#define FRF_CZ_TIFT_TCP_UDP_LBN 108 +#define FRF_CZ_TIFT_TCP_UDP_WIDTH 1 +#define FRF_CZ_TIFT_TXQ_ID_LBN 96 +#define FRF_CZ_TIFT_TXQ_ID_WIDTH 12 +#define FRF_CZ_TIFT_DEST_IP_LBN 64 +#define FRF_CZ_TIFT_DEST_IP_WIDTH 32 +#define FRF_CZ_TIFT_DEST_PORT_TCP_LBN 48 +#define FRF_CZ_TIFT_DEST_PORT_TCP_WIDTH 16 +#define FRF_CZ_TIFT_SRC_IP_LBN 16 +#define FRF_CZ_TIFT_SRC_IP_WIDTH 32 +#define FRF_CZ_TIFT_SRC_TCP_DEST_UDP_LBN 0 +#define FRF_CZ_TIFT_SRC_TCP_DEST_UDP_WIDTH 16 + + +/* + * FR_CZ_TX_MAC_FILTER_TBL0(128bit): + * Transmit Ethernet filter table + */ +#define FR_CZ_TX_MAC_FILTER_TBL0_OFST 0x00fe0000 +/* sienaa0=net_func_bar2 */ +#define FR_CZ_TX_MAC_FILTER_TBL0_STEP 16 +#define FR_CZ_TX_MAC_FILTER_TBL0_ROWS 512 + +#define FRF_CZ_TMFT_TXQ_ID_LBN 61 +#define FRF_CZ_TMFT_TXQ_ID_WIDTH 12 +#define FRF_CZ_TMFT_WILDCARD_MATCH_LBN 60 +#define FRF_CZ_TMFT_WILDCARD_MATCH_WIDTH 1 +#define FRF_CZ_TMFT_SRC_MAC_LBN 12 +#define FRF_CZ_TMFT_SRC_MAC_WIDTH 48 +#define FRF_CZ_TMFT_SRC_MAC_DW0_LBN 12 +#define FRF_CZ_TMFT_SRC_MAC_DW0_WIDTH 32 +#define FRF_CZ_TMFT_SRC_MAC_DW1_LBN 44 +#define FRF_CZ_TMFT_SRC_MAC_DW1_WIDTH 16 +#define FRF_CZ_TMFT_VLAN_ID_LBN 0 +#define FRF_CZ_TMFT_VLAN_ID_WIDTH 12 + + +/* + * FR_CZ_MC_TREG_SMEM(32bit): + * MC Shared Memory + */ +#define FR_CZ_MC_TREG_SMEM_OFST 0x00ff0000 +/* sienaa0=net_func_bar2 */ +#define FR_CZ_MC_TREG_SMEM_STEP 4 +#define FR_CZ_MC_TREG_SMEM_ROWS 512 + +#define FRF_CZ_MC_TREG_SMEM_ROW_LBN 0 +#define FRF_CZ_MC_TREG_SMEM_ROW_WIDTH 32 + + +/* + * FR_BB_MSIX_VECTOR_TABLE(128bit): + * MSIX Vector Table + */ +#define FR_BB_MSIX_VECTOR_TABLE_OFST 0x00ff0000 +/* falconb0=net_func_bar2 */ +#define FR_BZ_MSIX_VECTOR_TABLE_STEP 16 +#define FR_BB_MSIX_VECTOR_TABLE_ROWS 64 +/* + * FR_CZ_MSIX_VECTOR_TABLE(128bit): + * MSIX Vector Table + */ +#define FR_CZ_MSIX_VECTOR_TABLE_OFST 0x00000000 +/* sienaa0=pci_f0_bar4 */ +/* FR_BZ_MSIX_VECTOR_TABLE_STEP 16 */ +#define FR_CZ_MSIX_VECTOR_TABLE_ROWS 1024 + +#define FRF_BZ_MSIX_VECTOR_RESERVED_LBN 97 +#define FRF_BZ_MSIX_VECTOR_RESERVED_WIDTH 31 +#define FRF_BZ_MSIX_VECTOR_MASK_LBN 96 +#define FRF_BZ_MSIX_VECTOR_MASK_WIDTH 1 +#define FRF_BZ_MSIX_MESSAGE_DATA_LBN 64 +#define FRF_BZ_MSIX_MESSAGE_DATA_WIDTH 32 +#define FRF_BZ_MSIX_MESSAGE_ADDRESS_HI_LBN 32 +#define FRF_BZ_MSIX_MESSAGE_ADDRESS_HI_WIDTH 32 +#define FRF_BZ_MSIX_MESSAGE_ADDRESS_LO_LBN 0 +#define FRF_BZ_MSIX_MESSAGE_ADDRESS_LO_WIDTH 32 + + +/* + * FR_BB_MSIX_PBA_TABLE(32bit): + * MSIX Pending Bit Array + */ +#define FR_BB_MSIX_PBA_TABLE_OFST 0x00ff2000 +/* falconb0=net_func_bar2 */ +#define FR_BZ_MSIX_PBA_TABLE_STEP 4 +#define FR_BB_MSIX_PBA_TABLE_ROWS 2 +/* + * FR_CZ_MSIX_PBA_TABLE(32bit): + * MSIX Pending Bit Array + */ +#define FR_CZ_MSIX_PBA_TABLE_OFST 0x00008000 +/* sienaa0=pci_f0_bar4 */ +/* FR_BZ_MSIX_PBA_TABLE_STEP 4 */ +#define FR_CZ_MSIX_PBA_TABLE_ROWS 32 + +#define FRF_BZ_MSIX_PBA_PEND_DWORD_LBN 0 +#define FRF_BZ_MSIX_PBA_PEND_DWORD_WIDTH 32 + + +/* + * FR_AZ_SRM_DBG_REG(64bit): + * SRAM debug access + */ +#define FR_AZ_SRM_DBG_REG_OFST 0x03000000 +/* sienaa0=net_func_bar2,falconb0=net_func_bar2,falcona0=char_func_bar0 */ +#define FR_AZ_SRM_DBG_REG_STEP 8 + +#define FR_CZ_SRM_DBG_REG_ROWS 262144 +#define FR_AB_SRM_DBG_REG_ROWS 2097152 + +#define FRF_AZ_SRM_DBG_LBN 0 +#define FRF_AZ_SRM_DBG_WIDTH 64 +#define FRF_AZ_SRM_DBG_DW0_LBN 0 +#define FRF_AZ_SRM_DBG_DW0_WIDTH 32 +#define FRF_AZ_SRM_DBG_DW1_LBN 32 +#define FRF_AZ_SRM_DBG_DW1_WIDTH 32 + + +/* + * FR_AA_INT_ACK_CHAR(32bit): + * CHAR interrupt acknowledge register + */ +#define FR_AA_INT_ACK_CHAR_OFST 0x00000060 +/* falcona0=char_func_bar0 */ + +#define FRF_AA_INT_ACK_CHAR_FIELD_LBN 0 +#define FRF_AA_INT_ACK_CHAR_FIELD_WIDTH 32 + + +/* FS_DRIVER_EV */ +#define FSF_AZ_DRIVER_EV_SUBCODE_LBN 56 +#define FSF_AZ_DRIVER_EV_SUBCODE_WIDTH 4 +#define FSE_AZ_TX_DSC_ERROR_EV 15 +#define FSE_AZ_RX_DSC_ERROR_EV 14 +#define FSE_AZ_RX_RECOVER_EV 11 +#define FSE_AZ_TIMER_EV 10 +#define FSE_AZ_TX_PKT_NON_TCP_UDP 9 +#define FSE_AZ_WAKE_UP_EV 6 +#define FSE_AZ_SRM_UPD_DONE_EV 5 +#define FSE_AZ_EVQ_NOT_EN_EV 3 +#define FSE_AZ_EVQ_INIT_DONE_EV 2 +#define FSE_AZ_RX_DESCQ_FLS_DONE_EV 1 +#define FSE_AZ_TX_DESCQ_FLS_DONE_EV 0 +#define FSF_AZ_DRIVER_EV_SUBDATA_LBN 0 +#define FSF_AZ_DRIVER_EV_SUBDATA_WIDTH 14 + + +/* FS_EVENT_ENTRY */ +#define FSF_AZ_EV_CODE_LBN 60 +#define FSF_AZ_EV_CODE_WIDTH 4 +#define FSE_AZ_EV_CODE_USER_EV 8 +#define FSE_AZ_EV_CODE_DRV_GEN_EV 7 +#define FSE_AZ_EV_CODE_GLOBAL_EV 6 +#define FSE_AZ_EV_CODE_DRIVER_EV 5 +#define FSE_AZ_EV_CODE_TX_EV 2 +#define FSE_AZ_EV_CODE_RX_EV 0 +#define FSF_AZ_EV_DATA_LBN 0 +#define FSF_AZ_EV_DATA_WIDTH 60 +#define FSF_AZ_EV_DATA_DW0_LBN 0 +#define FSF_AZ_EV_DATA_DW0_WIDTH 32 +#define FSF_AZ_EV_DATA_DW1_LBN 32 +#define FSF_AZ_EV_DATA_DW1_WIDTH 28 + + +/* FS_GLOBAL_EV */ +#define FSF_AA_GLB_EV_RX_RECOVERY_LBN 12 +#define FSF_AA_GLB_EV_RX_RECOVERY_WIDTH 1 +#define FSF_BZ_GLB_EV_XG_MNT_INTR_LBN 11 +#define FSF_BZ_GLB_EV_XG_MNT_INTR_WIDTH 1 +#define FSF_AZ_GLB_EV_XFP_PHY0_INTR_LBN 10 +#define FSF_AZ_GLB_EV_XFP_PHY0_INTR_WIDTH 1 +#define FSF_AZ_GLB_EV_XG_PHY0_INTR_LBN 9 +#define FSF_AZ_GLB_EV_XG_PHY0_INTR_WIDTH 1 +#define FSF_AZ_GLB_EV_G_PHY0_INTR_LBN 7 +#define FSF_AZ_GLB_EV_G_PHY0_INTR_WIDTH 1 + + +/* FS_RX_EV */ +#define FSF_CZ_RX_EV_PKT_NOT_PARSED_LBN 58 +#define FSF_CZ_RX_EV_PKT_NOT_PARSED_WIDTH 1 +#define FSF_CZ_RX_EV_IPV6_PKT_LBN 57 +#define FSF_CZ_RX_EV_IPV6_PKT_WIDTH 1 +#define FSF_AZ_RX_EV_PKT_OK_LBN 56 +#define FSF_AZ_RX_EV_PKT_OK_WIDTH 1 +#define FSF_AZ_RX_EV_PAUSE_FRM_ERR_LBN 55 +#define FSF_AZ_RX_EV_PAUSE_FRM_ERR_WIDTH 1 +#define FSF_AZ_RX_EV_BUF_OWNER_ID_ERR_LBN 54 +#define FSF_AZ_RX_EV_BUF_OWNER_ID_ERR_WIDTH 1 +#define FSF_AZ_RX_EV_IP_FRAG_ERR_LBN 53 +#define FSF_AZ_RX_EV_IP_FRAG_ERR_WIDTH 1 +#define FSF_AZ_RX_EV_IP_HDR_CHKSUM_ERR_LBN 52 +#define FSF_AZ_RX_EV_IP_HDR_CHKSUM_ERR_WIDTH 1 +#define FSF_AZ_RX_EV_TCP_UDP_CHKSUM_ERR_LBN 51 +#define FSF_AZ_RX_EV_TCP_UDP_CHKSUM_ERR_WIDTH 1 +#define FSF_AZ_RX_EV_ETH_CRC_ERR_LBN 50 +#define FSF_AZ_RX_EV_ETH_CRC_ERR_WIDTH 1 +#define FSF_AZ_RX_EV_FRM_TRUNC_LBN 49 +#define FSF_AZ_RX_EV_FRM_TRUNC_WIDTH 1 +#define FSF_AZ_RX_EV_TOBE_DISC_LBN 47 +#define FSF_AZ_RX_EV_TOBE_DISC_WIDTH 1 +#define FSF_AZ_RX_EV_PKT_TYPE_LBN 44 +#define FSF_AZ_RX_EV_PKT_TYPE_WIDTH 3 +#define FSE_AZ_RX_EV_PKT_TYPE_VLAN_JUMBO 5 +#define FSE_AZ_RX_EV_PKT_TYPE_VLAN_LLC 4 +#define FSE_AZ_RX_EV_PKT_TYPE_VLAN 3 +#define FSE_AZ_RX_EV_PKT_TYPE_JUMBO 2 +#define FSE_AZ_RX_EV_PKT_TYPE_LLC 1 +#define FSE_AZ_RX_EV_PKT_TYPE_ETH 0 +#define FSF_AZ_RX_EV_HDR_TYPE_LBN 42 +#define FSF_AZ_RX_EV_HDR_TYPE_WIDTH 2 +#define FSE_AZ_RX_EV_HDR_TYPE_OTHER 3 +#define FSE_AZ_RX_EV_HDR_TYPE_IPV4_OTHER 2 +#define FSE_AZ_RX_EV_HDR_TYPE_IPV4V6_OTHER 2 +#define FSE_AZ_RX_EV_HDR_TYPE_IPV4_UDP 1 +#define FSE_AZ_RX_EV_HDR_TYPE_IPV4V6_UDP 1 +#define FSE_AZ_RX_EV_HDR_TYPE_IPV4_TCP 0 +#define FSE_AZ_RX_EV_HDR_TYPE_IPV4V6_TCP 0 +#define FSF_AZ_RX_EV_DESC_Q_EMPTY_LBN 41 +#define FSF_AZ_RX_EV_DESC_Q_EMPTY_WIDTH 1 +#define FSF_AZ_RX_EV_MCAST_HASH_MATCH_LBN 40 +#define FSF_AZ_RX_EV_MCAST_HASH_MATCH_WIDTH 1 +#define FSF_AZ_RX_EV_MCAST_PKT_LBN 39 +#define FSF_AZ_RX_EV_MCAST_PKT_WIDTH 1 +#define FSF_AA_RX_EV_RECOVERY_FLAG_LBN 37 +#define FSF_AA_RX_EV_RECOVERY_FLAG_WIDTH 1 +#define FSF_AZ_RX_EV_Q_LABEL_LBN 32 +#define FSF_AZ_RX_EV_Q_LABEL_WIDTH 5 +#define FSF_AZ_RX_EV_JUMBO_CONT_LBN 31 +#define FSF_AZ_RX_EV_JUMBO_CONT_WIDTH 1 +#define FSF_AZ_RX_EV_PORT_LBN 30 +#define FSF_AZ_RX_EV_PORT_WIDTH 1 +#define FSF_AZ_RX_EV_BYTE_CNT_LBN 16 +#define FSF_AZ_RX_EV_BYTE_CNT_WIDTH 14 +#define FSF_AZ_RX_EV_SOP_LBN 15 +#define FSF_AZ_RX_EV_SOP_WIDTH 1 +#define FSF_AZ_RX_EV_ISCSI_PKT_OK_LBN 14 +#define FSF_AZ_RX_EV_ISCSI_PKT_OK_WIDTH 1 +#define FSF_AZ_RX_EV_ISCSI_DDIG_ERR_LBN 13 +#define FSF_AZ_RX_EV_ISCSI_DDIG_ERR_WIDTH 1 +#define FSF_AZ_RX_EV_ISCSI_HDIG_ERR_LBN 12 +#define FSF_AZ_RX_EV_ISCSI_HDIG_ERR_WIDTH 1 +#define FSF_AZ_RX_EV_DESC_PTR_LBN 0 +#define FSF_AZ_RX_EV_DESC_PTR_WIDTH 12 + + +/* FS_RX_KER_DESC */ +#define FSF_AZ_RX_KER_BUF_SIZE_LBN 48 +#define FSF_AZ_RX_KER_BUF_SIZE_WIDTH 14 +#define FSF_AZ_RX_KER_BUF_REGION_LBN 46 +#define FSF_AZ_RX_KER_BUF_REGION_WIDTH 2 +#define FSF_AZ_RX_KER_BUF_ADDR_LBN 0 +#define FSF_AZ_RX_KER_BUF_ADDR_WIDTH 46 +#define FSF_AZ_RX_KER_BUF_ADDR_DW0_LBN 0 +#define FSF_AZ_RX_KER_BUF_ADDR_DW0_WIDTH 32 +#define FSF_AZ_RX_KER_BUF_ADDR_DW1_LBN 32 +#define FSF_AZ_RX_KER_BUF_ADDR_DW1_WIDTH 14 + + +/* FS_RX_USER_DESC */ +#define FSF_AZ_RX_USER_2BYTE_OFFSET_LBN 20 +#define FSF_AZ_RX_USER_2BYTE_OFFSET_WIDTH 12 +#define FSF_AZ_RX_USER_BUF_ID_LBN 0 +#define FSF_AZ_RX_USER_BUF_ID_WIDTH 20 + + +/* FS_TX_EV */ +#define FSF_AZ_TX_EV_PKT_ERR_LBN 38 +#define FSF_AZ_TX_EV_PKT_ERR_WIDTH 1 +#define FSF_AZ_TX_EV_PKT_TOO_BIG_LBN 37 +#define FSF_AZ_TX_EV_PKT_TOO_BIG_WIDTH 1 +#define FSF_AZ_TX_EV_Q_LABEL_LBN 32 +#define FSF_AZ_TX_EV_Q_LABEL_WIDTH 5 +#define FSF_AZ_TX_EV_PORT_LBN 16 +#define FSF_AZ_TX_EV_PORT_WIDTH 1 +#define FSF_AZ_TX_EV_WQ_FF_FULL_LBN 15 +#define FSF_AZ_TX_EV_WQ_FF_FULL_WIDTH 1 +#define FSF_AZ_TX_EV_BUF_OWNER_ID_ERR_LBN 14 +#define FSF_AZ_TX_EV_BUF_OWNER_ID_ERR_WIDTH 1 +#define FSF_AZ_TX_EV_COMP_LBN 12 +#define FSF_AZ_TX_EV_COMP_WIDTH 1 +#define FSF_AZ_TX_EV_DESC_PTR_LBN 0 +#define FSF_AZ_TX_EV_DESC_PTR_WIDTH 12 + + +/* FS_TX_KER_DESC */ +#define FSF_AZ_TX_KER_CONT_LBN 62 +#define FSF_AZ_TX_KER_CONT_WIDTH 1 +#define FSF_AZ_TX_KER_BYTE_COUNT_LBN 48 +#define FSF_AZ_TX_KER_BYTE_COUNT_WIDTH 14 +#define FSF_AZ_TX_KER_BUF_REGION_LBN 46 +#define FSF_AZ_TX_KER_BUF_REGION_WIDTH 2 +#define FSF_AZ_TX_KER_BUF_ADDR_LBN 0 +#define FSF_AZ_TX_KER_BUF_ADDR_WIDTH 46 +#define FSF_AZ_TX_KER_BUF_ADDR_DW0_LBN 0 +#define FSF_AZ_TX_KER_BUF_ADDR_DW0_WIDTH 32 +#define FSF_AZ_TX_KER_BUF_ADDR_DW1_LBN 32 +#define FSF_AZ_TX_KER_BUF_ADDR_DW1_WIDTH 14 + + +/* FS_TX_USER_DESC */ +#define FSF_AZ_TX_USER_SW_EV_EN_LBN 48 +#define FSF_AZ_TX_USER_SW_EV_EN_WIDTH 1 +#define FSF_AZ_TX_USER_CONT_LBN 46 +#define FSF_AZ_TX_USER_CONT_WIDTH 1 +#define FSF_AZ_TX_USER_BYTE_CNT_LBN 33 +#define FSF_AZ_TX_USER_BYTE_CNT_WIDTH 13 +#define FSF_AZ_TX_USER_BUF_ID_LBN 13 +#define FSF_AZ_TX_USER_BUF_ID_WIDTH 20 +#define FSF_AZ_TX_USER_BYTE_OFS_LBN 0 +#define FSF_AZ_TX_USER_BYTE_OFS_WIDTH 13 + + +/* FS_USER_EV */ +#define FSF_CZ_USER_QID_LBN 32 +#define FSF_CZ_USER_QID_WIDTH 10 +#define FSF_CZ_USER_EV_REG_VALUE_LBN 0 +#define FSF_CZ_USER_EV_REG_VALUE_WIDTH 32 + + +/* FS_NET_IVEC */ +#define FSF_AZ_NET_IVEC_FATAL_INT_LBN 64 +#define FSF_AZ_NET_IVEC_FATAL_INT_WIDTH 1 +#define FSF_AZ_NET_IVEC_INT_Q_LBN 40 +#define FSF_AZ_NET_IVEC_INT_Q_WIDTH 4 +#define FSF_AZ_NET_IVEC_INT_FLAG_LBN 32 +#define FSF_AZ_NET_IVEC_INT_FLAG_WIDTH 1 +#define FSF_AZ_NET_IVEC_EVQ_FIFO_HF_LBN 1 +#define FSF_AZ_NET_IVEC_EVQ_FIFO_HF_WIDTH 1 +#define FSF_AZ_NET_IVEC_EVQ_FIFO_AF_LBN 0 +#define FSF_AZ_NET_IVEC_EVQ_FIFO_AF_WIDTH 1 + + +/* DRIVER_EV */ +/* Sub-fields of an RX flush completion event */ +#define FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL_LBN 12 +#define FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL_WIDTH 1 +#define FSF_AZ_DRIVER_EV_RX_DESCQ_ID_LBN 0 +#define FSF_AZ_DRIVER_EV_RX_DESCQ_ID_WIDTH 12 + + +#ifdef __cplusplus +} +#endif + + + + +#endif /* _SYS_EFX_REGS_H */ diff --git a/sys/dev/sfxge/common/efx_regs_ef10.h b/sys/dev/sfxge/common/efx_regs_ef10.h new file mode 100644 index 000000000000..62c03721d004 --- /dev/null +++ b/sys/dev/sfxge/common/efx_regs_ef10.h @@ -0,0 +1,2682 @@ +/*- + * Copyright 2007-2010 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SYS_EFX_EF10_REGS_H +#define _SYS_EFX_EF10_REGS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * BIU_HW_REV_ID_REG(32bit): + * + */ + +#define ER_DZ_BIU_HW_REV_ID_REG 0x00000000 +/* hunta0=pcie_pf_bar2 */ + +#define ERF_DZ_HW_REV_ID_LBN 0 +#define ERF_DZ_HW_REV_ID_WIDTH 32 + + +/* + * BIU_MC_SFT_STATUS_REG(32bit): + * + */ + +#define ER_DZ_BIU_MC_SFT_STATUS_REG 0x00000010 +/* hunta0=pcie_pf_bar2 */ +#define ER_DZ_BIU_MC_SFT_STATUS_REG_STEP 4 +#define ER_DZ_BIU_MC_SFT_STATUS_REG_ROWS 8 + +#define ERF_DZ_MC_SFT_STATUS_LBN 0 +#define ERF_DZ_MC_SFT_STATUS_WIDTH 32 + + +/* + * BIU_INT_ISR_REG(32bit): + * + */ + +#define ER_DZ_BIU_INT_ISR_REG 0x00000090 +/* hunta0=pcie_pf_bar2 */ + +#define ERF_DZ_ISR_REG_LBN 0 +#define ERF_DZ_ISR_REG_WIDTH 32 + + +/* + * MC_DB_LWRD_REG(32bit): + * + */ + +#define ER_DZ_MC_DB_LWRD_REG 0x00000200 +/* hunta0=pcie_pf_bar2 */ + +#define ERF_DZ_MC_DOORBELL_L_LBN 0 +#define ERF_DZ_MC_DOORBELL_L_WIDTH 32 + + +/* + * MC_DB_HWRD_REG(32bit): + * + */ + +#define ER_DZ_MC_DB_HWRD_REG 0x00000204 +/* hunta0=pcie_pf_bar2 */ + +#define ERF_DZ_MC_DOORBELL_H_LBN 0 +#define ERF_DZ_MC_DOORBELL_H_WIDTH 32 + + +/* + * EVQ_RPTR_REG(32bit): + * + */ + +#define ER_DZ_EVQ_RPTR_REG 0x00000400 +/* hunta0=pcie_pf_bar2 */ +#define ER_DZ_EVQ_RPTR_REG_STEP 4096 +#define ER_DZ_EVQ_RPTR_REG_ROWS 2048 + +#define ERF_DZ_EVQ_RPTR_VLD_LBN 15 +#define ERF_DZ_EVQ_RPTR_VLD_WIDTH 1 +#define ERF_DZ_EVQ_RPTR_LBN 0 +#define ERF_DZ_EVQ_RPTR_WIDTH 15 + + +/* + * EVQ_TMR_REG(32bit): + * + */ + +#define ER_DZ_EVQ_TMR_REG 0x00000420 +/* hunta0=pcie_pf_bar2 */ +#define ER_DZ_EVQ_TMR_REG_STEP 4096 +#define ER_DZ_EVQ_TMR_REG_ROWS 2048 + +#define ERF_DZ_TC_TIMER_MODE_LBN 14 +#define ERF_DZ_TC_TIMER_MODE_WIDTH 2 +#define ERF_DZ_TC_TIMER_VAL_LBN 0 +#define ERF_DZ_TC_TIMER_VAL_WIDTH 14 + + +/* + * RX_DESC_UPD_REG(32bit): + * + */ + +#define ER_DZ_RX_DESC_UPD_REG 0x00000830 +/* hunta0=pcie_pf_bar2 */ +#define ER_DZ_RX_DESC_UPD_REG_STEP 4096 +#define ER_DZ_RX_DESC_UPD_REG_ROWS 2048 + +#define ERF_DZ_RX_DESC_WPTR_LBN 0 +#define ERF_DZ_RX_DESC_WPTR_WIDTH 12 + + +/* + * TX_DESC_UPD_REG(76bit): + * + */ + +#define ER_DZ_TX_DESC_UPD_REG 0x00000a10 +/* hunta0=pcie_pf_bar2 */ +#define ER_DZ_TX_DESC_UPD_REG_STEP 4096 +#define ER_DZ_TX_DESC_UPD_REG_ROWS 2048 + +#define ERF_DZ_TX_DESC_WPTR_LBN 64 +#define ERF_DZ_TX_DESC_WPTR_WIDTH 12 +#define ERF_DZ_TX_DESC_HWORD_LBN 32 +#define ERF_DZ_TX_DESC_HWORD_WIDTH 32 +#define ERF_DZ_TX_DESC_LWORD_LBN 0 +#define ERF_DZ_TX_DESC_LWORD_WIDTH 32 + + +/* ES_DRIVER_EV */ +#define ESF_DZ_DRV_CODE_LBN 60 +#define ESF_DZ_DRV_CODE_WIDTH 4 +#define ESF_DZ_DRV_SUB_CODE_LBN 56 +#define ESF_DZ_DRV_SUB_CODE_WIDTH 4 +#define ESE_DZ_DRV_TIMER_EV 10 +#define ESE_DZ_DRV_WAKE_UP_EV 6 +#define ESF_DZ_DRV_SUB_DATA_DW0_LBN 0 +#define ESF_DZ_DRV_SUB_DATA_DW0_WIDTH 32 +#define ESF_DZ_DRV_SUB_DATA_DW1_LBN 32 +#define ESF_DZ_DRV_SUB_DATA_DW1_WIDTH 24 +#define ESF_DZ_DRV_SUB_DATA_LBN 0 +#define ESF_DZ_DRV_SUB_DATA_WIDTH 56 +#define ESF_DZ_DRV_EVQ_ID_LBN 0 +#define ESF_DZ_DRV_EVQ_ID_WIDTH 14 +#define ESF_DZ_DRV_TMR_ID_LBN 0 +#define ESF_DZ_DRV_TMR_ID_WIDTH 14 + + +/* ES_EVENT_ENTRY */ +#define ESF_DZ_EV_CODE_LBN 60 +#define ESF_DZ_EV_CODE_WIDTH 4 +#define ESE_DZ_EV_CODE_MCDI_EV 12 +#define ESE_DZ_EV_CODE_DRIVER_EV 5 +#define ESE_DZ_EV_CODE_TX_EV 2 +#define ESE_DZ_EV_CODE_RX_EV 0 +#define ESE_DZ_OTHER other +#define ESF_DZ_EV_DATA_DW0_LBN 0 +#define ESF_DZ_EV_DATA_DW0_WIDTH 32 +#define ESF_DZ_EV_DATA_DW1_LBN 32 +#define ESF_DZ_EV_DATA_DW1_WIDTH 28 +#define ESF_DZ_EV_DATA_LBN 0 +#define ESF_DZ_EV_DATA_WIDTH 60 + + +/* ES_FF_UMSG_CPU2DL_DESC_FETCH */ +#define ESF_DZ_C2DDF_DSCR_CACHE_RPTR_LBN 112 +#define ESF_DZ_C2DDF_DSCR_CACHE_RPTR_WIDTH 6 +#define ESF_DZ_C2DDF_QID_LBN 96 +#define ESF_DZ_C2DDF_QID_WIDTH 11 +#define ESF_DZ_C2DDF_DSCR_BASE_PAGE_ID_LBN 64 +#define ESF_DZ_C2DDF_DSCR_BASE_PAGE_ID_WIDTH 18 +#define ESF_DZ_C2DDF_DSCR_HW_RPTR_LBN 48 +#define ESF_DZ_C2DDF_DSCR_HW_RPTR_WIDTH 12 +#define ESF_DZ_C2DDF_DSCR_HW_WPTR_LBN 32 +#define ESF_DZ_C2DDF_DSCR_HW_WPTR_WIDTH 12 +#define ESF_DZ_C2DDF_OID_LBN 16 +#define ESF_DZ_C2DDF_OID_WIDTH 12 +#define ESF_DZ_C2DDF_DSCR_SIZE_LBN 13 +#define ESF_DZ_C2DDF_DSCR_SIZE_WIDTH 3 +#define ESE_DZ_C2DDF_DSCR_SIZE_512 7 +#define ESE_DZ_C2DDF_DSCR_SIZE_1K 6 +#define ESE_DZ_C2DDF_DSCR_SIZE_2K 5 +#define ESE_DZ_C2DDF_DSCR_SIZE_4K 4 +#define ESF_DZ_C2DDF_BIU_ARGS_LBN 0 +#define ESF_DZ_C2DDF_BIU_ARGS_WIDTH 13 + + +/* ES_FF_UMSG_CPU2DL_DESC_PUSH */ +#define ESF_DZ_C2DDP_DESC_DW0_LBN 128 +#define ESF_DZ_C2DDP_DESC_DW0_WIDTH 32 +#define ESF_DZ_C2DDP_DESC_DW1_LBN 160 +#define ESF_DZ_C2DDP_DESC_DW1_WIDTH 32 +#define ESF_DZ_C2DDP_DESC_LBN 128 +#define ESF_DZ_C2DDP_DESC_WIDTH 64 +#define ESF_DZ_C2DDP_QID_LBN 96 +#define ESF_DZ_C2DDP_QID_WIDTH 11 +#define ESF_DZ_C2DDP_DSCR_HW_RPTR_LBN 48 +#define ESF_DZ_C2DDP_DSCR_HW_RPTR_WIDTH 12 +#define ESF_DZ_C2DDP_DSCR_HW_WPTR_LBN 32 +#define ESF_DZ_C2DDP_DSCR_HW_WPTR_WIDTH 12 +#define ESF_DZ_C2DDP_OID_LBN 16 +#define ESF_DZ_C2DDP_OID_WIDTH 12 +#define ESF_DZ_C2DDP_DSCR_SIZE_LBN 0 +#define ESF_DZ_C2DDP_DSCR_SIZE_WIDTH 3 +#define ESE_DZ_C2DDF_DSCR_SIZE_512 7 +#define ESE_DZ_C2DDF_DSCR_SIZE_1K 6 +#define ESE_DZ_C2DDF_DSCR_SIZE_2K 5 +#define ESE_DZ_C2DDF_DSCR_SIZE_4K 4 + + +/* ES_FF_UMSG_CPU2DL_GPRD */ +#define ESF_DZ_C2DG_ENCODED_HOST_ADDR_DW0_LBN 64 +#define ESF_DZ_C2DG_ENCODED_HOST_ADDR_DW0_WIDTH 32 +#define ESF_DZ_C2DG_ENCODED_HOST_ADDR_DW1_LBN 96 +#define ESF_DZ_C2DG_ENCODED_HOST_ADDR_DW1_WIDTH 16 +#define ESF_DZ_C2DG_ENCODED_HOST_ADDR_LBN 64 +#define ESF_DZ_C2DG_ENCODED_HOST_ADDR_WIDTH 48 +#define ESF_DZ_C2DG_SMC_ADDR_LBN 16 +#define ESF_DZ_C2DG_SMC_ADDR_WIDTH 16 +#define ESF_DZ_C2DG_BIU_ARGS_LBN 0 +#define ESF_DZ_C2DG_BIU_ARGS_WIDTH 14 + + +/* ES_FF_UMSG_CPU2EV_SOFT */ +#define ESF_DZ_C2ES_TBD_LBN 0 +#define ESF_DZ_C2ES_TBD_WIDTH 1 + + +/* ES_FF_UMSG_CPU2EV_TXCMPLT */ +#define ESF_DZ_C2ET_EV_SOFT0_LBN 32 +#define ESF_DZ_C2ET_EV_SOFT0_WIDTH 16 +#define ESF_DZ_C2ET_DSCR_IDX_LBN 16 +#define ESF_DZ_C2ET_DSCR_IDX_WIDTH 16 +#define ESF_DZ_C2ET_EV_QID_LBN 5 +#define ESF_DZ_C2ET_EV_QID_WIDTH 11 +#define ESF_DZ_C2ET_EV_QLABEL_LBN 0 +#define ESF_DZ_C2ET_EV_QLABEL_WIDTH 5 + + +/* ES_FF_UMSG_CPU2RXDP_INGR_BUFOP */ +#define ESF_DZ_C2RIB_EV_DISABLE_LBN 191 +#define ESF_DZ_C2RIB_EV_DISABLE_WIDTH 1 +#define ESF_DZ_C2RIB_EV_SOFT_LBN 188 +#define ESF_DZ_C2RIB_EV_SOFT_WIDTH 3 +#define ESF_DZ_C2RIB_EV_DESC_PTR_LBN 176 +#define ESF_DZ_C2RIB_EV_DESC_PTR_WIDTH 12 +#define ESF_DZ_C2RIB_EV_ARG1_LBN 160 +#define ESF_DZ_C2RIB_EV_ARG1_WIDTH 16 +#define ESF_DZ_C2RIB_ENCODED_HOST_ADDR_DW0_LBN 64 +#define ESF_DZ_C2RIB_ENCODED_HOST_ADDR_DW0_WIDTH 32 +#define ESF_DZ_C2RIB_ENCODED_HOST_ADDR_DW1_LBN 96 +#define ESF_DZ_C2RIB_ENCODED_HOST_ADDR_DW1_WIDTH 16 +#define ESF_DZ_C2RIB_ENCODED_HOST_ADDR_LBN 64 +#define ESF_DZ_C2RIB_ENCODED_HOST_ADDR_WIDTH 48 +#define ESF_DZ_C2RIB_BIU_ARGS_LBN 16 +#define ESF_DZ_C2RIB_BIU_ARGS_WIDTH 13 +#define ESF_DZ_C2RIB_EV_QID_LBN 5 +#define ESF_DZ_C2RIB_EV_QID_WIDTH 11 +#define ESF_DZ_C2RIB_EV_QLABEL_LBN 0 +#define ESF_DZ_C2RIB_EV_QLABEL_WIDTH 5 + + +/* ES_FF_UMSG_CPU2RXDP_INGR_PDISP */ +#define ESF_DZ_C2RIP_BUF_LEN_LBN 240 +#define ESF_DZ_C2RIP_BUF_LEN_WIDTH 16 +#define ESF_DZ_C2RIP_ENCODED_HOST_ADDR_DW0_LBN 192 +#define ESF_DZ_C2RIP_ENCODED_HOST_ADDR_DW0_WIDTH 32 +#define ESF_DZ_C2RIP_ENCODED_HOST_ADDR_DW1_LBN 224 +#define ESF_DZ_C2RIP_ENCODED_HOST_ADDR_DW1_WIDTH 16 +#define ESF_DZ_C2RIP_ENCODED_HOST_ADDR_LBN 192 +#define ESF_DZ_C2RIP_ENCODED_HOST_ADDR_WIDTH 48 +#define ESF_DZ_C2RIP_EV_DISABLE_LBN 191 +#define ESF_DZ_C2RIP_EV_DISABLE_WIDTH 1 +#define ESF_DZ_C2RIP_EV_SOFT_LBN 188 +#define ESF_DZ_C2RIP_EV_SOFT_WIDTH 3 +#define ESF_DZ_C2RIP_EV_DESC_PTR_LBN 176 +#define ESF_DZ_C2RIP_EV_DESC_PTR_WIDTH 12 +#define ESF_DZ_C2RIP_EV_ARG1_LBN 160 +#define ESF_DZ_C2RIP_EV_ARG1_WIDTH 16 +#define ESF_DZ_C2RIP_UPD_CRC_MODE_LBN 157 +#define ESF_DZ_C2RIP_UPD_CRC_MODE_WIDTH 3 +#define ESE_DZ_C2RIP_FCOIP_MPA 5 +#define ESE_DZ_C2RIP_FCOIP_FCOE 4 +#define ESE_DZ_C2RIP_ISCSI_HDR_AND_PYLD 3 +#define ESE_DZ_C2RIP_ISCSI_HDR 2 +#define ESE_DZ_C2RIP_FCOE 1 +#define ESE_DZ_C2RIP_OFF 0 +#define ESF_DZ_C2RIP_BIU_ARGS_LBN 144 +#define ESF_DZ_C2RIP_BIU_ARGS_WIDTH 13 +#define ESF_DZ_C2RIP_EV_QID_LBN 133 +#define ESF_DZ_C2RIP_EV_QID_WIDTH 11 +#define ESF_DZ_C2RIP_EV_QLABEL_LBN 128 +#define ESF_DZ_C2RIP_EV_QLABEL_WIDTH 5 +#define ESF_DZ_C2RIP_PEDIT_DELTA_LBN 104 +#define ESF_DZ_C2RIP_PEDIT_DELTA_WIDTH 8 +#define ESF_DZ_C2RIP_PYLOAD_OFST_LBN 96 +#define ESF_DZ_C2RIP_PYLOAD_OFST_WIDTH 8 +#define ESF_DZ_C2RIP_L4_HDR_OFST_LBN 88 +#define ESF_DZ_C2RIP_L4_HDR_OFST_WIDTH 8 +#define ESF_DZ_C2RIP_L3_HDR_OFST_LBN 80 +#define ESF_DZ_C2RIP_L3_HDR_OFST_WIDTH 8 +#define ESF_DZ_C2RIP_IS_UDP_LBN 69 +#define ESF_DZ_C2RIP_IS_UDP_WIDTH 1 +#define ESF_DZ_C2RIP_IS_TCP_LBN 68 +#define ESF_DZ_C2RIP_IS_TCP_WIDTH 1 +#define ESF_DZ_C2RIP_IS_IPV6_LBN 67 +#define ESF_DZ_C2RIP_IS_IPV6_WIDTH 1 +#define ESF_DZ_C2RIP_IS_IPV4_LBN 66 +#define ESF_DZ_C2RIP_IS_IPV4_WIDTH 1 +#define ESF_DZ_C2RIP_IS_FCOE_LBN 65 +#define ESF_DZ_C2RIP_IS_FCOE_WIDTH 1 +#define ESF_DZ_C2RIP_PARSE_INCOMP_LBN 64 +#define ESF_DZ_C2RIP_PARSE_INCOMP_WIDTH 1 +#define ESF_DZ_C2RIP_FINFO_WRD3_LBN 48 +#define ESF_DZ_C2RIP_FINFO_WRD3_WIDTH 16 +#define ESF_DZ_C2RIP_FINFO_WRD2_LBN 32 +#define ESF_DZ_C2RIP_FINFO_WRD2_WIDTH 16 +#define ESF_DZ_C2RIP_FINFO_WRD1_LBN 16 +#define ESF_DZ_C2RIP_FINFO_WRD1_WIDTH 16 +#define ESF_DZ_C2RIP_FINFO_SRCDST_LBN 0 +#define ESF_DZ_C2RIP_FINFO_SRCDST_WIDTH 16 + + +/* ES_FF_UMSG_CPU2RXDP_INGR_SOFT */ +#define ESF_DZ_C2RIS_SOFT3_LBN 48 +#define ESF_DZ_C2RIS_SOFT3_WIDTH 16 +#define ESF_DZ_C2RIS_SOFT2_LBN 32 +#define ESF_DZ_C2RIS_SOFT2_WIDTH 16 +#define ESF_DZ_C2RIS_SOFT1_LBN 16 +#define ESF_DZ_C2RIS_SOFT1_WIDTH 16 +#define ESF_DZ_C2RIS_SOFT0_LBN 0 +#define ESF_DZ_C2RIS_SOFT0_WIDTH 16 + + +/* ES_FF_UMSG_CPU2SMC_BUFLKUP */ +#define ESF_DZ_C2SB_PAGE_ID_LBN 16 +#define ESF_DZ_C2SB_PAGE_ID_WIDTH 18 +#define ESF_DZ_C2SB_EXP_PAGE_ID_LBN 0 +#define ESF_DZ_C2SB_EXP_PAGE_ID_WIDTH 12 + + +/* ES_FF_UMSG_CPU2SMC_DESCOP */ +#define ESF_DZ_C2SD_LEN_LBN 112 +#define ESF_DZ_C2SD_LEN_WIDTH 14 +#define ESF_DZ_C2SD_ENCODED_HOST_ADDR_DW0_LBN 64 +#define ESF_DZ_C2SD_ENCODED_HOST_ADDR_DW0_WIDTH 32 +#define ESF_DZ_C2SD_ENCODED_HOST_ADDR_DW1_LBN 96 +#define ESF_DZ_C2SD_ENCODED_HOST_ADDR_DW1_WIDTH 16 +#define ESF_DZ_C2SD_ENCODED_HOST_ADDR_LBN 64 +#define ESF_DZ_C2SD_ENCODED_HOST_ADDR_WIDTH 48 +#define ESF_DZ_C2SD_OFFSET_LBN 48 +#define ESF_DZ_C2SD_OFFSET_WIDTH 8 +#define ESF_DZ_C2SD_QID_LBN 32 +#define ESF_DZ_C2SD_QID_WIDTH 11 +#define ESF_DZ_C2SD_CONT_LBN 16 +#define ESF_DZ_C2SD_CONT_WIDTH 1 +#define ESF_DZ_C2SD_TYPE_LBN 0 +#define ESF_DZ_C2SD_TYPE_WIDTH 1 + + +/* ES_FF_UMSG_CPU2SMC_GPOP */ +#define ESF_DZ_C2SG_DATA_DW0_LBN 64 +#define ESF_DZ_C2SG_DATA_DW0_WIDTH 32 +#define ESF_DZ_C2SG_DATA_DW1_LBN 96 +#define ESF_DZ_C2SG_DATA_DW1_WIDTH 32 +#define ESF_DZ_C2SG_DATA_LBN 64 +#define ESF_DZ_C2SG_DATA_WIDTH 64 +#define ESF_DZ_C2SG_SOFT_LBN 48 +#define ESF_DZ_C2SG_SOFT_WIDTH 4 +#define ESF_DZ_C2SG_REFLECT_LBN 32 +#define ESF_DZ_C2SG_REFLECT_WIDTH 1 +#define ESF_DZ_C2SG_ADDR_LBN 0 +#define ESF_DZ_C2SG_ADDR_WIDTH 16 + + +/* ES_FF_UMSG_CPU2TXDP_DMA_BUFREQ */ +#define ESF_DZ_C2TDB_BUF_LEN_LBN 176 +#define ESF_DZ_C2TDB_BUF_LEN_WIDTH 16 +#define ESF_DZ_C2TDB_ENCODED_HOST_ADDR_DW0_LBN 128 +#define ESF_DZ_C2TDB_ENCODED_HOST_ADDR_DW0_WIDTH 32 +#define ESF_DZ_C2TDB_ENCODED_HOST_ADDR_DW1_LBN 160 +#define ESF_DZ_C2TDB_ENCODED_HOST_ADDR_DW1_WIDTH 16 +#define ESF_DZ_C2TDB_ENCODED_HOST_ADDR_LBN 128 +#define ESF_DZ_C2TDB_ENCODED_HOST_ADDR_WIDTH 48 +#define ESF_DZ_C2TDB_SOFT_LBN 112 +#define ESF_DZ_C2TDB_SOFT_WIDTH 14 +#define ESF_DZ_C2TDB_DESC_IDX_LBN 96 +#define ESF_DZ_C2TDB_DESC_IDX_WIDTH 16 +#define ESF_DZ_C2TDB_UPD_CRC_MODE_LBN 93 +#define ESF_DZ_C2TDB_UPD_CRC_MODE_WIDTH 3 +#define ESE_DZ_C2RIP_FCOIP_MPA 5 +#define ESE_DZ_C2RIP_FCOIP_FCOE 4 +#define ESE_DZ_C2RIP_ISCSI_HDR_AND_PYLD 3 +#define ESE_DZ_C2RIP_ISCSI_HDR 2 +#define ESE_DZ_C2RIP_FCOE 1 +#define ESE_DZ_C2RIP_OFF 0 +#define ESF_DZ_C2TDB_BIU_ARGS_LBN 80 +#define ESF_DZ_C2TDB_BIU_ARGS_WIDTH 13 +#define ESF_DZ_C2TDB_CONT_LBN 64 +#define ESF_DZ_C2TDB_CONT_WIDTH 1 +#define ESF_DZ_C2TDB_FINFO_WRD3_LBN 48 +#define ESF_DZ_C2TDB_FINFO_WRD3_WIDTH 16 +#define ESF_DZ_C2TDB_FINFO_WRD2_LBN 32 +#define ESF_DZ_C2TDB_FINFO_WRD2_WIDTH 16 +#define ESF_DZ_C2TDB_FINFO_WRD1_LBN 16 +#define ESF_DZ_C2TDB_FINFO_WRD1_WIDTH 16 +#define ESF_DZ_C2TDB_FINFO_SRCDST_LBN 0 +#define ESF_DZ_C2TDB_FINFO_SRCDST_WIDTH 16 + + +/* ES_FF_UMSG_CPU2TXDP_DMA_PKTABORT */ +#define ESF_DZ_C2TDP_SOFT_LBN 48 +#define ESF_DZ_C2TDP_SOFT_WIDTH 14 +#define ESF_DZ_C2TDP_DESC_IDX_LBN 32 +#define ESF_DZ_C2TDP_DESC_IDX_WIDTH 16 +#define ESF_DZ_C2TDP_BIU_ARGS_LBN 16 +#define ESF_DZ_C2TDP_BIU_ARGS_WIDTH 14 + + +/* ES_FF_UMSG_CPU2TXDP_DMA_SOFT */ +#define ESF_DZ_C2TDS_SOFT3_LBN 48 +#define ESF_DZ_C2TDS_SOFT3_WIDTH 16 +#define ESF_DZ_C2TDS_SOFT2_LBN 32 +#define ESF_DZ_C2TDS_SOFT2_WIDTH 16 +#define ESF_DZ_C2TDS_SOFT1_LBN 16 +#define ESF_DZ_C2TDS_SOFT1_WIDTH 16 +#define ESF_DZ_C2TDS_SOFT0_LBN 0 +#define ESF_DZ_C2TDS_SOFT0_WIDTH 16 + + +/* ES_FF_UMSG_CPU2TXDP_EGR */ +#define ESF_DZ_C2TE_PEDIT_DELTA_LBN 168 +#define ESF_DZ_C2TE_PEDIT_DELTA_WIDTH 8 +#define ESF_DZ_C2TE_PYLOAD_OFST_LBN 160 +#define ESF_DZ_C2TE_PYLOAD_OFST_WIDTH 8 +#define ESF_DZ_C2TE_L4_HDR_OFST_LBN 152 +#define ESF_DZ_C2TE_L4_HDR_OFST_WIDTH 8 +#define ESF_DZ_C2TE_L3_HDR_OFST_LBN 144 +#define ESF_DZ_C2TE_L3_HDR_OFST_WIDTH 8 +#define ESF_DZ_C2TE_IS_UDP_LBN 133 +#define ESF_DZ_C2TE_IS_UDP_WIDTH 1 +#define ESF_DZ_C2TE_IS_TCP_LBN 132 +#define ESF_DZ_C2TE_IS_TCP_WIDTH 1 +#define ESF_DZ_C2TE_IS_IPV6_LBN 131 +#define ESF_DZ_C2TE_IS_IPV6_WIDTH 1 +#define ESF_DZ_C2TE_IS_IPV4_LBN 130 +#define ESF_DZ_C2TE_IS_IPV4_WIDTH 1 +#define ESF_DZ_C2TE_IS_FCOE_LBN 129 +#define ESF_DZ_C2TE_IS_FCOE_WIDTH 1 +#define ESF_DZ_C2TE_PARSE_INCOMP_LBN 128 +#define ESF_DZ_C2TE_PARSE_INCOMP_WIDTH 1 +#define ESF_DZ_C2TE_PKT_LEN_LBN 112 +#define ESF_DZ_C2TE_PKT_LEN_WIDTH 16 +#define ESF_DZ_C2TE_UPD_TCPUDPCSUM_MODE_LBN 97 +#define ESF_DZ_C2TE_UPD_TCPUDPCSUM_MODE_WIDTH 1 +#define ESF_DZ_C2TE_UPD_IPCSUM_MODE_LBN 96 +#define ESF_DZ_C2TE_UPD_IPCSUM_MODE_WIDTH 1 +#define ESF_DZ_C2TE_UPD_CRC_MODE_LBN 93 +#define ESF_DZ_C2TE_UPD_CRC_MODE_WIDTH 3 +#define ESE_DZ_C2RIP_FCOIP_MPA 5 +#define ESE_DZ_C2RIP_FCOIP_FCOE 4 +#define ESE_DZ_C2RIP_ISCSI_HDR_AND_PYLD 3 +#define ESE_DZ_C2RIP_ISCSI_HDR 2 +#define ESE_DZ_C2RIP_FCOE 1 +#define ESE_DZ_C2RIP_OFF 0 +#define ESF_DZ_C2TE_FINFO_WRD3_LBN 48 +#define ESF_DZ_C2TE_FINFO_WRD3_WIDTH 16 +#define ESF_DZ_C2TE_FINFO_WRD2_LBN 32 +#define ESF_DZ_C2TE_FINFO_WRD2_WIDTH 16 +#define ESF_DZ_C2TE_FINFO_WRD1_LBN 16 +#define ESF_DZ_C2TE_FINFO_WRD1_WIDTH 16 +#define ESF_DZ_C2TE_FINFO_SRCDST_LBN 0 +#define ESF_DZ_C2TE_FINFO_SRCDST_WIDTH 16 + + +/* ES_FF_UMSG_CPU2TXDP_EGR_SOFT */ +#define ESF_DZ_C2TES_SOFT3_LBN 48 +#define ESF_DZ_C2TES_SOFT3_WIDTH 16 +#define ESF_DZ_C2TES_SOFT2_LBN 32 +#define ESF_DZ_C2TES_SOFT2_WIDTH 16 +#define ESF_DZ_C2TES_SOFT1_LBN 16 +#define ESF_DZ_C2TES_SOFT1_WIDTH 16 +#define ESF_DZ_C2TES_SOFT0_LBN 0 +#define ESF_DZ_C2TES_SOFT0_WIDTH 16 + + +/* ES_FF_UMSG_DL2CPU_DESC_FETCH */ +#define ESF_DZ_D2CDF_REFL_DSCR_HW_WPTR_LBN 64 +#define ESF_DZ_D2CDF_REFL_DSCR_HW_WPTR_WIDTH 12 +#define ESF_DZ_D2CDF_FAIL_LBN 48 +#define ESF_DZ_D2CDF_FAIL_WIDTH 1 +#define ESF_DZ_D2CDF_QID_LBN 32 +#define ESF_DZ_D2CDF_QID_WIDTH 11 +#define ESF_DZ_D2CDF_NUM_DESC_LBN 16 +#define ESF_DZ_D2CDF_NUM_DESC_WIDTH 7 +#define ESF_DZ_D2CDF_NEW_DSCR_HW_RPTR_LBN 0 +#define ESF_DZ_D2CDF_NEW_DSCR_HW_RPTR_WIDTH 12 + + +/* ES_FF_UMSG_DL2CPU_GPRD */ +#define ESF_DZ_D2CG_BIU_ARGS_LBN 0 +#define ESF_DZ_D2CG_BIU_ARGS_WIDTH 14 + + +/* ES_FF_UMSG_DPCPU_PACER_TXQ_D_R_I_REQ */ +#define ESF_DZ_FRM_LEN_LBN 16 +#define ESF_DZ_FRM_LEN_WIDTH 15 +#define ESF_DZ_TXQ_ID_LBN 0 +#define ESF_DZ_TXQ_ID_WIDTH 10 + + +/* ES_FF_UMSG_PACER_BKT_TBL_RD_REQ */ +#define ESF_DZ_BKT_ID_LBN 0 +#define ESF_DZ_BKT_ID_WIDTH 9 + + +/* ES_FF_UMSG_PACER_BKT_TBL_RD_RSP */ +#define ESF_DZ_DUE_TIME_LBN 80 +#define ESF_DZ_DUE_TIME_WIDTH 16 +#define ESF_DZ_LAST_FILL_TIME_LBN 64 +#define ESF_DZ_LAST_FILL_TIME_WIDTH 16 +#define ESF_DZ_RATE_REC_LBN 48 +#define ESF_DZ_RATE_REC_WIDTH 16 +#define ESF_DZ_RATE_LBN 32 +#define ESF_DZ_RATE_WIDTH 16 +#define ESF_DZ_FILL_LEVEL_LBN 16 +#define ESF_DZ_FILL_LEVEL_WIDTH 16 +#define ESF_DZ_IDLE_LBN 15 +#define ESF_DZ_IDLE_WIDTH 1 +#define ESF_DZ_USED_LBN 14 +#define ESF_DZ_USED_WIDTH 1 +#define ESF_DZ_MAX_FILL_REG_LBN 12 +#define ESF_DZ_MAX_FILL_REG_WIDTH 2 +#define ESF_DZ_BKT_ID_LBN 0 +#define ESF_DZ_BKT_ID_WIDTH 9 + + +/* ES_FF_UMSG_PACER_BKT_TBL_WR_REQ */ +#define ESF_DZ_RATE_REC_LBN 48 +#define ESF_DZ_RATE_REC_WIDTH 16 +#define ESF_DZ_RATE_LBN 32 +#define ESF_DZ_RATE_WIDTH 16 +#define ESF_DZ_FILL_LEVEL_LBN 16 +#define ESF_DZ_FILL_LEVEL_WIDTH 16 +#define ESF_DZ_IDLE_LBN 15 +#define ESF_DZ_IDLE_WIDTH 1 +#define ESF_DZ_USED_LBN 14 +#define ESF_DZ_USED_WIDTH 1 +#define ESF_DZ_MAX_FILL_REG_LBN 12 +#define ESF_DZ_MAX_FILL_REG_WIDTH 2 +#define ESF_DZ_BKT_ID_LBN 0 +#define ESF_DZ_BKT_ID_WIDTH 9 + + +/* ES_FF_UMSG_PACER_TXQ_TBL_RD_REQ */ +#define ESF_DZ_TXQ_ID_LBN 0 +#define ESF_DZ_TXQ_ID_WIDTH 10 + + +/* ES_FF_UMSG_PACER_TXQ_TBL_RD_RSP */ +#define ESF_DZ_MAX_BKT2_LBN 112 +#define ESF_DZ_MAX_BKT2_WIDTH 9 +#define ESF_DZ_MAX_BKT1_LBN 96 +#define ESF_DZ_MAX_BKT1_WIDTH 9 +#define ESF_DZ_MAX_BKT0_LBN 80 +#define ESF_DZ_MAX_BKT0_WIDTH 9 +#define ESF_DZ_MIN_BKT_LBN 64 +#define ESF_DZ_MIN_BKT_WIDTH 9 +#define ESF_DZ_LABEL_LBN 48 +#define ESF_DZ_LABEL_WIDTH 4 +#define ESF_DZ_PQ_FLAGS_LBN 32 +#define ESF_DZ_PQ_FLAGS_WIDTH 3 +#define ESF_DZ_DSBL_LBN 16 +#define ESF_DZ_DSBL_WIDTH 1 +#define ESF_DZ_TXQ_ID_LBN 0 +#define ESF_DZ_TXQ_ID_WIDTH 10 + + +/* ES_FF_UMSG_PACER_TXQ_TBL_WR_REQ */ +#define ESF_DZ_MAX_BKT2_LBN 112 +#define ESF_DZ_MAX_BKT2_WIDTH 9 +#define ESF_DZ_MAX_BKT1_LBN 96 +#define ESF_DZ_MAX_BKT1_WIDTH 9 +#define ESF_DZ_MAX_BKT0_LBN 80 +#define ESF_DZ_MAX_BKT0_WIDTH 9 +#define ESF_DZ_MIN_BKT_LBN 64 +#define ESF_DZ_MIN_BKT_WIDTH 9 +#define ESF_DZ_LABEL_LBN 48 +#define ESF_DZ_LABEL_WIDTH 4 +#define ESF_DZ_PQ_FLAGS_LBN 32 +#define ESF_DZ_PQ_FLAGS_WIDTH 3 +#define ESF_DZ_DSBL_LBN 16 +#define ESF_DZ_DSBL_WIDTH 1 +#define ESF_DZ_TXQ_ID_LBN 0 +#define ESF_DZ_TXQ_ID_WIDTH 10 + + +/* ES_FF_UMSG_PE */ +#define ESF_DZ_PE_PKT_OFST_LBN 47 +#define ESF_DZ_PE_PKT_OFST_WIDTH 17 +#define ESF_DZ_PE_PEDIT_DELTA_LBN 40 +#define ESF_DZ_PE_PEDIT_DELTA_WIDTH 8 +#define ESF_DZ_PE_PYLOAD_OFST_LBN 32 +#define ESF_DZ_PE_PYLOAD_OFST_WIDTH 8 +#define ESF_DZ_PE_L4_HDR_OFST_LBN 24 +#define ESF_DZ_PE_L4_HDR_OFST_WIDTH 8 +#define ESF_DZ_PE_L3_HDR_OFST_LBN 16 +#define ESF_DZ_PE_L3_HDR_OFST_WIDTH 8 +#define ESF_DZ_PE_HAVE_UDP_HDR_LBN 5 +#define ESF_DZ_PE_HAVE_UDP_HDR_WIDTH 1 +#define ESF_DZ_PE_HAVE_TCP_HDR_LBN 4 +#define ESF_DZ_PE_HAVE_TCP_HDR_WIDTH 1 +#define ESF_DZ_PE_HAVE_IPV6_HDR_LBN 3 +#define ESF_DZ_PE_HAVE_IPV6_HDR_WIDTH 1 +#define ESF_DZ_PE_HAVE_IPV4_HDR_LBN 2 +#define ESF_DZ_PE_HAVE_IPV4_HDR_WIDTH 1 +#define ESF_DZ_PE_HAVE_FCOE_LBN 1 +#define ESF_DZ_PE_HAVE_FCOE_WIDTH 1 +#define ESF_DZ_PE_PARSE_INCOMP_LBN 0 +#define ESF_DZ_PE_PARSE_INCOMP_WIDTH 1 + + +/* ES_FF_UMSG_RXDP_EGR2CPU_SOFT */ +#define ESF_DZ_RE2CS_SOFT3_LBN 48 +#define ESF_DZ_RE2CS_SOFT3_WIDTH 16 +#define ESF_DZ_RE2CS_SOFT2_LBN 32 +#define ESF_DZ_RE2CS_SOFT2_WIDTH 16 +#define ESF_DZ_RE2CS_SOFT1_LBN 16 +#define ESF_DZ_RE2CS_SOFT1_WIDTH 16 +#define ESF_DZ_RE2CS_SOFT0_LBN 0 +#define ESF_DZ_RE2CS_SOFT0_WIDTH 16 + + +/* ES_FF_UMSG_RXDP_INGR2CPU */ +#define ESF_DZ_RI2C_LEN_LBN 208 +#define ESF_DZ_RI2C_LEN_WIDTH 16 +#define ESF_DZ_RI2C_L4_CLASS_LBN 202 +#define ESF_DZ_RI2C_L4_CLASS_WIDTH 3 +#define ESF_DZ_RI2C_L3_CLASS_LBN 199 +#define ESF_DZ_RI2C_L3_CLASS_WIDTH 3 +#define ESF_DZ_RI2C_ETHTAG_CLASS_LBN 196 +#define ESF_DZ_RI2C_ETHTAG_CLASS_WIDTH 3 +#define ESF_DZ_RI2C_ETHBASE_CLASS_LBN 193 +#define ESF_DZ_RI2C_ETHBASE_CLASS_WIDTH 3 +#define ESF_DZ_RI2C_MAC_CLASS_LBN 192 +#define ESF_DZ_RI2C_MAC_CLASS_WIDTH 1 +#define ESF_DZ_RI2C_PKT_OFST_LBN 176 +#define ESF_DZ_RI2C_PKT_OFST_WIDTH 16 +#define ESF_DZ_RI2C_PEDIT_DELTA_LBN 168 +#define ESF_DZ_RI2C_PEDIT_DELTA_WIDTH 8 +#define ESF_DZ_RI2C_PYLOAD_OFST_LBN 160 +#define ESF_DZ_RI2C_PYLOAD_OFST_WIDTH 8 +#define ESF_DZ_RI2C_L4_HDR_OFST_LBN 152 +#define ESF_DZ_RI2C_L4_HDR_OFST_WIDTH 8 +#define ESF_DZ_RI2C_L3_HDR_OFST_LBN 144 +#define ESF_DZ_RI2C_L3_HDR_OFST_WIDTH 8 +#define ESF_DZ_RI2C_HAVE_UDP_HDR_LBN 133 +#define ESF_DZ_RI2C_HAVE_UDP_HDR_WIDTH 1 +#define ESF_DZ_RI2C_HAVE_TCP_HDR_LBN 132 +#define ESF_DZ_RI2C_HAVE_TCP_HDR_WIDTH 1 +#define ESF_DZ_RI2C_HAVE_IPV6_HDR_LBN 131 +#define ESF_DZ_RI2C_HAVE_IPV6_HDR_WIDTH 1 +#define ESF_DZ_RI2C_HAVE_IPV4_HDR_LBN 130 +#define ESF_DZ_RI2C_HAVE_IPV4_HDR_WIDTH 1 +#define ESF_DZ_RI2C_HAVE_FCOE_LBN 129 +#define ESF_DZ_RI2C_HAVE_FCOE_WIDTH 1 +#define ESF_DZ_RI2C_PARSE_INCOMP_LBN 128 +#define ESF_DZ_RI2C_PARSE_INCOMP_WIDTH 1 +#define ESF_DZ_RI2C_EFINFO_WRD3_LBN 112 +#define ESF_DZ_RI2C_EFINFO_WRD3_WIDTH 16 +#define ESF_DZ_RI2C_EFINFO_WRD2_LBN 96 +#define ESF_DZ_RI2C_EFINFO_WRD2_WIDTH 16 +#define ESF_DZ_RI2C_EFINFO_WRD1_LBN 80 +#define ESF_DZ_RI2C_EFINFO_WRD1_WIDTH 16 +#define ESF_DZ_RI2C_EFINFO_WRD0_LBN 64 +#define ESF_DZ_RI2C_EFINFO_WRD0_WIDTH 16 +#define ESF_DZ_RI2C_FINFO_WRD3_LBN 48 +#define ESF_DZ_RI2C_FINFO_WRD3_WIDTH 16 +#define ESF_DZ_RI2C_FINFO_WRD2_LBN 32 +#define ESF_DZ_RI2C_FINFO_WRD2_WIDTH 16 +#define ESF_DZ_RI2C_FINFO_WRD1_LBN 16 +#define ESF_DZ_RI2C_FINFO_WRD1_WIDTH 16 +#define ESF_DZ_RI2C_FINFO_SRCDST_LBN 0 +#define ESF_DZ_RI2C_FINFO_SRCDST_WIDTH 16 + + +/* ES_FF_UMSG_SMC2CPU_BUFLKUP */ +#define ESF_DZ_S2CB_ENCODED_PAGE_ADDR_DW0_LBN 0 +#define ESF_DZ_S2CB_ENCODED_PAGE_ADDR_DW0_WIDTH 32 +#define ESF_DZ_S2CB_ENCODED_PAGE_ADDR_DW1_LBN 32 +#define ESF_DZ_S2CB_ENCODED_PAGE_ADDR_DW1_WIDTH 16 +#define ESF_DZ_S2CB_ENCODED_PAGE_ADDR_LBN 0 +#define ESF_DZ_S2CB_ENCODED_PAGE_ADDR_WIDTH 48 +#define ESF_DZ_S2CB_FAIL_LBN 32 +#define ESF_DZ_S2CB_FAIL_WIDTH 1 + + +/* ES_FF_UMSG_SMC2CPU_DESCRD */ +#define ESF_DZ_S2CD_BUF_LEN_LBN 112 +#define ESF_DZ_S2CD_BUF_LEN_WIDTH 14 +#define ESF_DZ_S2CD_ENCODED_HOST_ADDR_DW0_LBN 64 +#define ESF_DZ_S2CD_ENCODED_HOST_ADDR_DW0_WIDTH 32 +#define ESF_DZ_S2CD_ENCODED_HOST_ADDR_DW1_LBN 96 +#define ESF_DZ_S2CD_ENCODED_HOST_ADDR_DW1_WIDTH 16 +#define ESF_DZ_S2CD_ENCODED_HOST_ADDR_LBN 64 +#define ESF_DZ_S2CD_ENCODED_HOST_ADDR_WIDTH 48 +#define ESF_DZ_S2CD_CONT_LBN 16 +#define ESF_DZ_S2CD_CONT_WIDTH 1 +#define ESF_DZ_S2CD_TYPE_LBN 0 +#define ESF_DZ_S2CD_TYPE_WIDTH 1 + + +/* ES_FF_UMSG_SMC2CPU_GPRD */ +#define ESF_DZ_S2CG_DATA_DW0_LBN 64 +#define ESF_DZ_S2CG_DATA_DW0_WIDTH 32 +#define ESF_DZ_S2CG_DATA_DW1_LBN 96 +#define ESF_DZ_S2CG_DATA_DW1_WIDTH 32 +#define ESF_DZ_S2CG_DATA_LBN 64 +#define ESF_DZ_S2CG_DATA_WIDTH 64 +#define ESF_DZ_S2CG_SOFT_LBN 48 +#define ESF_DZ_S2CG_SOFT_WIDTH 4 +#define ESF_DZ_S2CG_FAIL_LBN 32 +#define ESF_DZ_S2CG_FAIL_WIDTH 1 + + +/* ES_FF_UMSG_TXDP_DMA2CPU_PKTRDY */ +#define ESF_DZ_TD2CP_L4_CLASS_LBN 250 +#define ESF_DZ_TD2CP_L4_CLASS_WIDTH 3 +#define ESF_DZ_TD2CP_L3_CLASS_LBN 247 +#define ESF_DZ_TD2CP_L3_CLASS_WIDTH 3 +#define ESF_DZ_TD2CP_ETHTAG_CLASS_LBN 244 +#define ESF_DZ_TD2CP_ETHTAG_CLASS_WIDTH 3 +#define ESF_DZ_TD2CP_ETHBASE_CLASS_LBN 241 +#define ESF_DZ_TD2CP_ETHBASE_CLASS_WIDTH 3 +#define ESF_DZ_TD2CP_MAC_CLASS_LBN 240 +#define ESF_DZ_TD2CP_MAC_CLASS_WIDTH 1 +#define ESF_DZ_TD2CP_SOFT_LBN 226 +#define ESF_DZ_TD2CP_SOFT_WIDTH 14 +#define ESF_DZ_TD2CP_PKT_ABORT_LBN 225 +#define ESF_DZ_TD2CP_PKT_ABORT_WIDTH 1 +#define ESF_DZ_TD2CP_PCIE_ERR_LBN 224 +#define ESF_DZ_TD2CP_PCIE_ERR_WIDTH 1 +#define ESF_DZ_TD2CP_DESC_IDX_LBN 208 +#define ESF_DZ_TD2CP_DESC_IDX_WIDTH 16 +#define ESF_DZ_TD2CP_PKT_LEN_LBN 192 +#define ESF_DZ_TD2CP_PKT_LEN_WIDTH 16 +#define ESF_DZ_TD2CP_PKT_OFFST_OR_FIRST_DESC_IDX_LBN 176 +#define ESF_DZ_TD2CP_PKT_OFFST_OR_FIRST_DESC_IDX_WIDTH 7 +#define ESF_DZ_TD2CP_PEDIT_DELTA_LBN 168 +#define ESF_DZ_TD2CP_PEDIT_DELTA_WIDTH 8 +#define ESF_DZ_TD2CP_PYLOAD_OFST_LBN 160 +#define ESF_DZ_TD2CP_PYLOAD_OFST_WIDTH 8 +#define ESF_DZ_TD2CP_L4_HDR_OFST_LBN 152 +#define ESF_DZ_TD2CP_L4_HDR_OFST_WIDTH 8 +#define ESF_DZ_TD2CP_L3_HDR_OFST_LBN 144 +#define ESF_DZ_TD2CP_L3_HDR_OFST_WIDTH 8 +#define ESF_DZ_TD2CP_IS_UDP_LBN 133 +#define ESF_DZ_TD2CP_IS_UDP_WIDTH 1 +#define ESF_DZ_TD2CP_IS_TCP_LBN 132 +#define ESF_DZ_TD2CP_IS_TCP_WIDTH 1 +#define ESF_DZ_TD2CP_IS_IPV6_LBN 131 +#define ESF_DZ_TD2CP_IS_IPV6_WIDTH 1 +#define ESF_DZ_TD2CP_IS_IPV4_LBN 130 +#define ESF_DZ_TD2CP_IS_IPV4_WIDTH 1 +#define ESF_DZ_TD2CP_IS_FCOE_LBN 129 +#define ESF_DZ_TD2CP_IS_FCOE_WIDTH 1 +#define ESF_DZ_TD2CP_PARSE_INCOMP_LBN 128 +#define ESF_DZ_TD2CP_PARSE_INCOMP_WIDTH 1 +#define ESF_DZ_TD2CP_EFINFO_WRD3_LBN 112 +#define ESF_DZ_TD2CP_EFINFO_WRD3_WIDTH 16 +#define ESF_DZ_TD2CP_EFINFO_WRD2_LBN 96 +#define ESF_DZ_TD2CP_EFINFO_WRD2_WIDTH 16 +#define ESF_DZ_TD2CP_EFINFO_WRD1_LBN 80 +#define ESF_DZ_TD2CP_EFINFO_WRD1_WIDTH 16 +#define ESF_DZ_TD2CP_EFINFO_WRD0_LBN 64 +#define ESF_DZ_TD2CP_EFINFO_WRD0_WIDTH 16 +#define ESF_DZ_TD2CP_FINFO_WRD3_LBN 48 +#define ESF_DZ_TD2CP_FINFO_WRD3_WIDTH 16 +#define ESF_DZ_TD2CP_FINFO_WRD2_LBN 32 +#define ESF_DZ_TD2CP_FINFO_WRD2_WIDTH 16 +#define ESF_DZ_TD2CP_FINFO_WRD1_LBN 16 +#define ESF_DZ_TD2CP_FINFO_WRD1_WIDTH 16 +#define ESF_DZ_TD2CP_FINFO_SRCDST_LBN 0 +#define ESF_DZ_TD2CP_FINFO_SRCDST_WIDTH 16 + + +/* ES_FF_UMSG_TXDP_DMA2CPU_SOFT */ +#define ESF_DZ_TD2CS_SOFT3_LBN 48 +#define ESF_DZ_TD2CS_SOFT3_WIDTH 16 +#define ESF_DZ_TD2CS_SOFT2_LBN 32 +#define ESF_DZ_TD2CS_SOFT2_WIDTH 16 +#define ESF_DZ_TD2CS_SOFT1_LBN 16 +#define ESF_DZ_TD2CS_SOFT1_WIDTH 16 +#define ESF_DZ_TD2CS_SOFT0_LBN 0 +#define ESF_DZ_TD2CS_SOFT0_WIDTH 16 + + +/* ES_FF_UMSG_TXDP_EGR2CPU_SOFT */ +#define ESF_DZ_TE2CS_SOFT3_LBN 48 +#define ESF_DZ_TE2CS_SOFT3_WIDTH 16 +#define ESF_DZ_TE2CS_SOFT2_LBN 32 +#define ESF_DZ_TE2CS_SOFT2_WIDTH 16 +#define ESF_DZ_TE2CS_SOFT1_LBN 16 +#define ESF_DZ_TE2CS_SOFT1_WIDTH 16 +#define ESF_DZ_TE2CS_SOFT0_LBN 0 +#define ESF_DZ_TE2CS_SOFT0_WIDTH 16 + + +/* ES_FF_UMSG_VICTL2CPU */ +#define ESF_DZ_V2C_DESC_WORD3_LBN 112 +#define ESF_DZ_V2C_DESC_WORD3_WIDTH 17 +#define ESF_DZ_V2C_DESC_WORD2_LBN 96 +#define ESF_DZ_V2C_DESC_WORD2_WIDTH 16 +#define ESF_DZ_V2C_DESC_WORD1_LBN 80 +#define ESF_DZ_V2C_DESC_WORD1_WIDTH 16 +#define ESF_DZ_V2C_DESC_WORD0_LBN 64 +#define ESF_DZ_V2C_DESC_WORD0_WIDTH 16 +#define ESF_DZ_V2C_NEW_DSCR_WPTR_LBN 32 +#define ESF_DZ_V2C_NEW_DSCR_WPTR_WIDTH 12 +#define ESF_DZ_V2C_DESC_PUSH_LBN 16 +#define ESF_DZ_V2C_DESC_PUSH_WIDTH 1 + + +/* ES_LUE_DB_MATCH_ENTRY */ +#define ESF_DZ_LUE_DSCRMNTR_LBN 140 +#define ESF_DZ_LUE_DSCRMNTR_WIDTH 4 +#define ESF_DZ_LUE_MATCH_VAL_DW0_LBN 44 +#define ESF_DZ_LUE_MATCH_VAL_DW0_WIDTH 32 +#define ESF_DZ_LUE_MATCH_VAL_DW1_LBN 76 +#define ESF_DZ_LUE_MATCH_VAL_DW1_WIDTH 32 +#define ESF_DZ_LUE_MATCH_VAL_DW2_LBN 108 +#define ESF_DZ_LUE_MATCH_VAL_DW2_WIDTH 32 +#define ESF_DZ_LUE_MATCH_VAL_LBN 44 +#define ESF_DZ_LUE_MATCH_VAL_WIDTH 96 +#define ESF_DZ_LUE_ME_SOFT_LBN 35 +#define ESF_DZ_LUE_ME_SOFT_WIDTH 9 +#define ESF_DZ_LUE_TX_MCAST_LBN 33 +#define ESF_DZ_LUE_TX_MCAST_WIDTH 2 +#define ESF_DZ_LUE_TX_DOMAIN_LBN 25 +#define ESF_DZ_LUE_TX_DOMAIN_WIDTH 8 +#define ESF_DZ_LUE_RX_MCAST_LBN 24 +#define ESF_DZ_LUE_RX_MCAST_WIDTH 1 +#define ESE_DZ_LUE_MULTI 1 +#define ESE_DZ_LUE_SINGLE 0 +#define ESF_DZ_LUE_RCPNTR_LBN 0 +#define ESF_DZ_LUE_RCPNTR_WIDTH 24 +#define ESF_DZ_LUE_RCPNTR_ME_PTR_LBN 0 +#define ESF_DZ_LUE_RCPNTR_ME_PTR_WIDTH 14 + + +/* ES_LUE_DB_NONMATCH_ENTRY */ +#define ESF_DZ_LUE_DSCRMNTR_LBN 140 +#define ESF_DZ_LUE_DSCRMNTR_WIDTH 4 +#define ESF_DZ_LUE_TERMINAL_LBN 139 +#define ESF_DZ_LUE_TERMINAL_WIDTH 1 +#define ESF_DZ_LUE_LAST_LBN 138 +#define ESF_DZ_LUE_LAST_WIDTH 1 +#define ESF_DZ_LUE_NE_SOFT_LBN 137 +#define ESF_DZ_LUE_NE_SOFT_WIDTH 1 +#define ESF_DZ_LUE_RCPNTR_NUM_LBN 134 +#define ESF_DZ_LUE_RCPNTR_NUM_WIDTH 3 +#define ESF_DZ_LUE_RCPNTR0_LBN 110 +#define ESF_DZ_LUE_RCPNTR0_WIDTH 24 +#define ESF_DZ_LUE_RCPNTR1_LBN 86 +#define ESF_DZ_LUE_RCPNTR1_WIDTH 24 +#define ESF_DZ_LUE_RCPNTR2_LBN 62 +#define ESF_DZ_LUE_RCPNTR2_WIDTH 24 +#define ESF_DZ_LUE_RCPNTR3_LBN 38 +#define ESF_DZ_LUE_RCPNTR3_WIDTH 24 +#define ESF_DZ_LUE_RCPNTR4_LBN 14 +#define ESF_DZ_LUE_RCPNTR4_WIDTH 24 +#define ESF_DZ_LUE_RCPNTR_NE_PTR_LBN 0 +#define ESF_DZ_LUE_RCPNTR_NE_PTR_WIDTH 14 + + +/* ES_LUE_MC_DIRECT_REQUEST_MSG */ +#define ESF_DZ_MC2L_DR_PAD_DW0_LBN 22 +#define ESF_DZ_MC2L_DR_PAD_DW0_WIDTH 32 +#define ESF_DZ_MC2L_DR_PAD_DW1_LBN 54 +#define ESF_DZ_MC2L_DR_PAD_DW1_WIDTH 32 +#define ESF_DZ_MC2L_DR_PAD_DW2_LBN 86 +#define ESF_DZ_MC2L_DR_PAD_DW2_WIDTH 32 +#define ESF_DZ_MC2L_DR_PAD_DW3_LBN 118 +#define ESF_DZ_MC2L_DR_PAD_DW3_WIDTH 32 +#define ESF_DZ_MC2L_DR_PAD_DW4_LBN 150 +#define ESF_DZ_MC2L_DR_PAD_DW4_WIDTH 16 +#define ESF_DZ_MC2L_DR_PAD_LBN 22 +#define ESF_DZ_MC2L_DR_PAD_WIDTH 144 +#define ESF_DZ_MC2L_DR_ADDR_LBN 8 +#define ESF_DZ_MC2L_DR_ADDR_WIDTH 14 +#define ESF_DZ_MC2L_DR_THREAD_ID_LBN 5 +#define ESF_DZ_MC2L_DR_THREAD_ID_WIDTH 3 +#define ESF_DZ_MC2L_DR_CLIENT_ID_LBN 2 +#define ESF_DZ_MC2L_DR_CLIENT_ID_WIDTH 3 +#define ESF_DZ_MC2L_DR_OP_LBN 0 +#define ESF_DZ_MC2L_DR_OP_WIDTH 2 +#define ESE_DZ_LUE_GP_WR 3 +#define ESE_DZ_LUE_GP_RD 2 +#define ESE_DZ_LUE_DIR_REQ 1 +#define ESE_DZ_LUE_MATCH_REQ 0 + + +/* ES_LUE_MC_DIRECT_RESPONSE_MSG */ +#define ESF_DZ_L2MC_DR_PAD_LBN 146 +#define ESF_DZ_L2MC_DR_PAD_WIDTH 6 +#define ESF_DZ_L2MC_DR_RCPNT_PTR_LBN 132 +#define ESF_DZ_L2MC_DR_RCPNT_PTR_WIDTH 14 +#define ESF_DZ_L2MC_DR_RCPNT4_LBN 108 +#define ESF_DZ_L2MC_DR_RCPNT4_WIDTH 24 +#define ESF_DZ_L2MC_DR_RCPNT3_LBN 84 +#define ESF_DZ_L2MC_DR_RCPNT3_WIDTH 24 +#define ESF_DZ_L2MC_DR_RCPNT2_LBN 60 +#define ESF_DZ_L2MC_DR_RCPNT2_WIDTH 24 +#define ESF_DZ_L2MC_DR_RCPNT1_LBN 36 +#define ESF_DZ_L2MC_DR_RCPNT1_WIDTH 24 +#define ESF_DZ_L2MC_DR_RCPNT0_LBN 12 +#define ESF_DZ_L2MC_DR_RCPNT0_WIDTH 24 +#define ESF_DZ_L2MC_DR_RCPNT_NUM_LBN 9 +#define ESF_DZ_L2MC_DR_RCPNT_NUM_WIDTH 3 +#define ESF_DZ_L2MC_DR_LAST_LBN 8 +#define ESF_DZ_L2MC_DR_LAST_WIDTH 1 +#define ESF_DZ_L2MC_DR_THREAD_ID_LBN 5 +#define ESF_DZ_L2MC_DR_THREAD_ID_WIDTH 3 +#define ESF_DZ_L2MC_DR_CLIENT_ID_LBN 2 +#define ESF_DZ_L2MC_DR_CLIENT_ID_WIDTH 3 +#define ESF_DZ_L2MC_DR_OP_LBN 0 +#define ESF_DZ_L2MC_DR_OP_WIDTH 2 +#define ESE_DZ_LUE_GP_WR 3 +#define ESE_DZ_LUE_GP_RD 2 +#define ESE_DZ_LUE_DIR_REQ 1 +#define ESE_DZ_LUE_MATCH_REQ 0 + + +/* ES_LUE_MC_GP_RD_REQUEST_MSG */ +#define ESF_DZ_MC2L_GPR_PAD_DW0_LBN 22 +#define ESF_DZ_MC2L_GPR_PAD_DW0_WIDTH 32 +#define ESF_DZ_MC2L_GPR_PAD_DW1_LBN 54 +#define ESF_DZ_MC2L_GPR_PAD_DW1_WIDTH 32 +#define ESF_DZ_MC2L_GPR_PAD_DW2_LBN 86 +#define ESF_DZ_MC2L_GPR_PAD_DW2_WIDTH 32 +#define ESF_DZ_MC2L_GPR_PAD_DW3_LBN 118 +#define ESF_DZ_MC2L_GPR_PAD_DW3_WIDTH 32 +#define ESF_DZ_MC2L_GPR_PAD_DW4_LBN 150 +#define ESF_DZ_MC2L_GPR_PAD_DW4_WIDTH 16 +#define ESF_DZ_MC2L_GPR_PAD_LBN 22 +#define ESF_DZ_MC2L_GPR_PAD_WIDTH 144 +#define ESF_DZ_MC2L_GPR_ADDR_LBN 8 +#define ESF_DZ_MC2L_GPR_ADDR_WIDTH 14 +#define ESF_DZ_MC2L_GPR_THREAD_ID_LBN 5 +#define ESF_DZ_MC2L_GPR_THREAD_ID_WIDTH 3 +#define ESF_DZ_MC2L_GPR_CLIENT_ID_LBN 2 +#define ESF_DZ_MC2L_GPR_CLIENT_ID_WIDTH 3 +#define ESF_DZ_MC2L_GPR_OP_LBN 0 +#define ESF_DZ_MC2L_GPR_OP_WIDTH 2 +#define ESE_DZ_LUE_GP_WR 3 +#define ESE_DZ_LUE_GP_RD 2 +#define ESE_DZ_LUE_DIR_REQ 1 +#define ESE_DZ_LUE_MATCH_REQ 0 + + +/* ES_LUE_MC_GP_RD_RESPONSE_MSG */ +#define ESF_DZ_L2MC_GPR_DATA_DW0_LBN 8 +#define ESF_DZ_L2MC_GPR_DATA_DW0_WIDTH 32 +#define ESF_DZ_L2MC_GPR_DATA_DW1_LBN 40 +#define ESF_DZ_L2MC_GPR_DATA_DW1_WIDTH 32 +#define ESF_DZ_L2MC_GPR_DATA_DW2_LBN 72 +#define ESF_DZ_L2MC_GPR_DATA_DW2_WIDTH 32 +#define ESF_DZ_L2MC_GPR_DATA_DW3_LBN 104 +#define ESF_DZ_L2MC_GPR_DATA_DW3_WIDTH 32 +#define ESF_DZ_L2MC_GPR_DATA_DW4_LBN 136 +#define ESF_DZ_L2MC_GPR_DATA_DW4_WIDTH 16 +#define ESF_DZ_L2MC_GPR_DATA_LBN 8 +#define ESF_DZ_L2MC_GPR_DATA_WIDTH 144 +#define ESF_DZ_L2MC_GPR_THREAD_ID_LBN 5 +#define ESF_DZ_L2MC_GPR_THREAD_ID_WIDTH 3 +#define ESF_DZ_L2MC_GPR_CLIENT_ID_LBN 2 +#define ESF_DZ_L2MC_GPR_CLIENT_ID_WIDTH 3 +#define ESF_DZ_L2MC_GPR_OP_LBN 0 +#define ESF_DZ_L2MC_GPR_OP_WIDTH 2 +#define ESE_DZ_LUE_GP_WR 3 +#define ESE_DZ_LUE_GP_RD 2 +#define ESE_DZ_LUE_DIR_REQ 1 +#define ESE_DZ_LUE_MATCH_REQ 0 + + +/* ES_LUE_MC_GP_WR_REQUEST_MSG */ +#define ESF_DZ_MC2L_GPW_DATA_DW0_LBN 22 +#define ESF_DZ_MC2L_GPW_DATA_DW0_WIDTH 32 +#define ESF_DZ_MC2L_GPW_DATA_DW1_LBN 54 +#define ESF_DZ_MC2L_GPW_DATA_DW1_WIDTH 32 +#define ESF_DZ_MC2L_GPW_DATA_DW2_LBN 86 +#define ESF_DZ_MC2L_GPW_DATA_DW2_WIDTH 32 +#define ESF_DZ_MC2L_GPW_DATA_DW3_LBN 118 +#define ESF_DZ_MC2L_GPW_DATA_DW3_WIDTH 32 +#define ESF_DZ_MC2L_GPW_DATA_DW4_LBN 150 +#define ESF_DZ_MC2L_GPW_DATA_DW4_WIDTH 16 +#define ESF_DZ_MC2L_GPW_DATA_LBN 22 +#define ESF_DZ_MC2L_GPW_DATA_WIDTH 144 +#define ESF_DZ_MC2L_GPW_ADDR_LBN 8 +#define ESF_DZ_MC2L_GPW_ADDR_WIDTH 14 +#define ESF_DZ_MC2L_GPW_THREAD_ID_LBN 5 +#define ESF_DZ_MC2L_GPW_THREAD_ID_WIDTH 3 +#define ESF_DZ_MC2L_GPW_CLIENT_ID_LBN 2 +#define ESF_DZ_MC2L_GPW_CLIENT_ID_WIDTH 3 +#define ESF_DZ_MC2L_GPW_OP_LBN 0 +#define ESF_DZ_MC2L_GPW_OP_WIDTH 2 +#define ESE_DZ_LUE_GP_WR 3 +#define ESE_DZ_LUE_GP_RD 2 +#define ESE_DZ_LUE_DIR_REQ 1 +#define ESE_DZ_LUE_MATCH_REQ 0 + + +/* ES_LUE_MC_MATCH_REQUEST_MSG */ +#define ESF_DZ_MC2L_MR_PAD_LBN 135 +#define ESF_DZ_MC2L_MR_PAD_WIDTH 31 +#define ESF_DZ_MC2L_MR_HASH2_LBN 122 +#define ESF_DZ_MC2L_MR_HASH2_WIDTH 13 +#define ESF_DZ_MC2L_MR_HASH1_LBN 108 +#define ESF_DZ_MC2L_MR_HASH1_WIDTH 14 +#define ESF_DZ_MC2L_MR_MATCH_BITS_DW0_LBN 12 +#define ESF_DZ_MC2L_MR_MATCH_BITS_DW0_WIDTH 32 +#define ESF_DZ_MC2L_MR_MATCH_BITS_DW1_LBN 44 +#define ESF_DZ_MC2L_MR_MATCH_BITS_DW1_WIDTH 32 +#define ESF_DZ_MC2L_MR_MATCH_BITS_DW2_LBN 76 +#define ESF_DZ_MC2L_MR_MATCH_BITS_DW2_WIDTH 32 +#define ESF_DZ_MC2L_MR_MATCH_BITS_LBN 12 +#define ESF_DZ_MC2L_MR_MATCH_BITS_WIDTH 96 +#define ESF_DZ_MC2L_MR_DSCRMNTR_LBN 8 +#define ESF_DZ_MC2L_MR_DSCRMNTR_WIDTH 4 +#define ESF_DZ_MC2L_MR_THREAD_ID_LBN 5 +#define ESF_DZ_MC2L_MR_THREAD_ID_WIDTH 3 +#define ESF_DZ_MC2L_MR_CLIENT_ID_LBN 2 +#define ESF_DZ_MC2L_MR_CLIENT_ID_WIDTH 3 +#define ESF_DZ_MC2L_MR_OP_LBN 0 +#define ESF_DZ_MC2L_MR_OP_WIDTH 2 +#define ESE_DZ_LUE_GP_WR 3 +#define ESE_DZ_LUE_GP_RD 2 +#define ESE_DZ_LUE_DIR_REQ 1 +#define ESE_DZ_LUE_MATCH_REQ 0 + + +/* ES_LUE_MC_MATCH_RESPONSE_MSG */ +#define ESF_DZ_L2MC_MR_PAD_DW0_LBN 53 +#define ESF_DZ_L2MC_MR_PAD_DW0_WIDTH 32 +#define ESF_DZ_L2MC_MR_PAD_DW1_LBN 85 +#define ESF_DZ_L2MC_MR_PAD_DW1_WIDTH 32 +#define ESF_DZ_L2MC_MR_PAD_DW2_LBN 117 +#define ESF_DZ_L2MC_MR_PAD_DW2_WIDTH 32 +#define ESF_DZ_L2MC_MR_PAD_DW3_LBN 149 +#define ESF_DZ_L2MC_MR_PAD_DW3_WIDTH 3 +#define ESF_DZ_L2MC_MR_PAD_LBN 53 +#define ESF_DZ_L2MC_MR_PAD_WIDTH 99 +#define ESF_DZ_L2MC_MR_LUE_RCPNT_LBN 29 +#define ESF_DZ_L2MC_MR_LUE_RCPNT_WIDTH 24 +#define ESF_DZ_L2MC_MR_RX_MCAST_LBN 28 +#define ESF_DZ_L2MC_MR_RX_MCAST_WIDTH 1 +#define ESF_DZ_L2MC_MR_TX_DOMAIN_LBN 20 +#define ESF_DZ_L2MC_MR_TX_DOMAIN_WIDTH 8 +#define ESF_DZ_L2MC_MR_TX_MCAST_LBN 18 +#define ESF_DZ_L2MC_MR_TX_MCAST_WIDTH 2 +#define ESF_DZ_L2MC_MR_SOFT_LBN 9 +#define ESF_DZ_L2MC_MR_SOFT_WIDTH 9 +#define ESF_DZ_L2MC_MR_MATCH_LBN 8 +#define ESF_DZ_L2MC_MR_MATCH_WIDTH 1 +#define ESF_DZ_L2MC_MR_THREAD_ID_LBN 5 +#define ESF_DZ_L2MC_MR_THREAD_ID_WIDTH 3 +#define ESF_DZ_L2MC_MR_CLIENT_ID_LBN 2 +#define ESF_DZ_L2MC_MR_CLIENT_ID_WIDTH 3 +#define ESF_DZ_L2MC_MR_OP_LBN 0 +#define ESF_DZ_L2MC_MR_OP_WIDTH 2 +#define ESE_DZ_LUE_GP_WR 3 +#define ESE_DZ_LUE_GP_RD 2 +#define ESE_DZ_LUE_DIR_REQ 1 +#define ESE_DZ_LUE_MATCH_REQ 0 + + +/* ES_LUE_MSG_BASE_REQ */ +#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_DW0_LBN 8 +#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_DW0_WIDTH 32 +#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_DW1_LBN 40 +#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_DW1_WIDTH 32 +#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_DW2_LBN 72 +#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_DW2_WIDTH 32 +#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_DW3_LBN 104 +#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_DW3_WIDTH 32 +#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_DW4_LBN 136 +#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_DW4_WIDTH 30 +#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_LBN 8 +#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_WIDTH 158 +#define ESF_DZ_LUE_HW_REQ_BASE_THREAD_ID_LBN 5 +#define ESF_DZ_LUE_HW_REQ_BASE_THREAD_ID_WIDTH 3 +#define ESF_DZ_LUE_HW_REQ_BASE_CLIENT_ID_LBN 2 +#define ESF_DZ_LUE_HW_REQ_BASE_CLIENT_ID_WIDTH 3 +#define ESE_DZ_LUE_MC_ID 7 +#define ESE_DZ_LUE_MATCH_REQ_FIFO_ID 3 +#define ESE_DZ_LUE_TX_DICPU_ID 1 +#define ESE_DZ_LUE_RX_DICPU_ID 0 +#define ESF_DZ_LUE_HW_REQ_BASE_OP_LBN 0 +#define ESF_DZ_LUE_HW_REQ_BASE_OP_WIDTH 2 +#define ESE_DZ_LUE_GP_WR 3 +#define ESE_DZ_LUE_GP_RD 2 +#define ESE_DZ_LUE_DIR_REQ 1 +#define ESE_DZ_LUE_MATCH_REQ 0 + + +/* ES_LUE_MSG_BASE_RESP */ +#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_DW0_LBN 8 +#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_DW0_WIDTH 32 +#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_DW1_LBN 40 +#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_DW1_WIDTH 32 +#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_DW2_LBN 72 +#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_DW2_WIDTH 32 +#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_DW3_LBN 104 +#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_DW3_WIDTH 32 +#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_DW4_LBN 136 +#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_DW4_WIDTH 16 +#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_LBN 8 +#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_WIDTH 144 +#define ESF_DZ_LUE_HW_RSP_BASE_THREAD_ID_LBN 5 +#define ESF_DZ_LUE_HW_RSP_BASE_THREAD_ID_WIDTH 3 +#define ESF_DZ_LUE_HW_RSP_BASE_CLIENT_ID_LBN 2 +#define ESF_DZ_LUE_HW_RSP_BASE_CLIENT_ID_WIDTH 3 +#define ESE_DZ_LUE_MC_ID 7 +#define ESE_DZ_LUE_MATCH_REQ_FIFO_ID 3 +#define ESE_DZ_LUE_TX_DICPU_ID 1 +#define ESE_DZ_LUE_RX_DICPU_ID 0 +#define ESF_DZ_LUE_HW_RSP_BASE_OP_LBN 0 +#define ESF_DZ_LUE_HW_RSP_BASE_OP_WIDTH 2 +#define ESE_DZ_LUE_GP_WR 3 +#define ESE_DZ_LUE_GP_RD 2 +#define ESE_DZ_LUE_DIR_REQ 1 +#define ESE_DZ_LUE_MATCH_REQ 0 + + +/* ES_LUE_MSG_DIRECT_REQ */ +#define ESF_DZ_LUE_HW_REQ_DIR_ADDR_LBN 8 +#define ESF_DZ_LUE_HW_REQ_DIR_ADDR_WIDTH 14 +#define ESF_DZ_LUE_HW_REQ_DIR_THREAD_ID_LBN 5 +#define ESF_DZ_LUE_HW_REQ_DIR_THREAD_ID_WIDTH 3 +#define ESF_DZ_LUE_HW_REQ_DIR_CLIENT_ID_LBN 2 +#define ESF_DZ_LUE_HW_REQ_DIR_CLIENT_ID_WIDTH 3 +#define ESE_DZ_LUE_MC_ID 7 +#define ESE_DZ_LUE_MATCH_REQ_FIFO_ID 3 +#define ESE_DZ_LUE_TX_DICPU_ID 1 +#define ESE_DZ_LUE_RX_DICPU_ID 0 +#define ESF_DZ_LUE_HW_REQ_DIR_OP_LBN 0 +#define ESF_DZ_LUE_HW_REQ_DIR_OP_WIDTH 2 +#define ESE_DZ_LUE_GP_WR 3 +#define ESE_DZ_LUE_GP_RD 2 +#define ESE_DZ_LUE_DIR_REQ 1 +#define ESE_DZ_LUE_MATCH_REQ 0 + + +/* ES_LUE_MSG_DIRECT_RESP */ +#define ESF_DZ_LUE_HW_RSP_DIR_RCPNT_PTR_LBN 132 +#define ESF_DZ_LUE_HW_RSP_DIR_RCPNT_PTR_WIDTH 14 +#define ESF_DZ_LUE_HW_RSP_DIR_RCPNT4_LBN 108 +#define ESF_DZ_LUE_HW_RSP_DIR_RCPNT4_WIDTH 24 +#define ESF_DZ_LUE_HW_RSP_DIR_RCPNT3_LBN 84 +#define ESF_DZ_LUE_HW_RSP_DIR_RCPNT3_WIDTH 24 +#define ESF_DZ_LUE_HW_RSP_DIR_RCPNT2_LBN 60 +#define ESF_DZ_LUE_HW_RSP_DIR_RCPNT2_WIDTH 24 +#define ESF_DZ_LUE_HW_RSP_DIR_RCPNT1_LBN 36 +#define ESF_DZ_LUE_HW_RSP_DIR_RCPNT1_WIDTH 24 +#define ESF_DZ_LUE_HW_RSP_DIR_RCPNT0_LBN 12 +#define ESF_DZ_LUE_HW_RSP_DIR_RCPNT0_WIDTH 24 +#define ESF_DZ_LUE_HW_RSP_DIR_RCPNT_NUM_LBN 9 +#define ESF_DZ_LUE_HW_RSP_DIR_RCPNT_NUM_WIDTH 3 +#define ESF_DZ_LUE_HW_RSP_DIR_LAST_LBN 8 +#define ESF_DZ_LUE_HW_RSP_DIR_LAST_WIDTH 1 +#define ESF_DZ_LUE_HW_RSP_DIR_THREAD_ID_LBN 5 +#define ESF_DZ_LUE_HW_RSP_DIR_THREAD_ID_WIDTH 3 +#define ESF_DZ_LUE_HW_RSP_DIR_CLIENT_ID_LBN 2 +#define ESF_DZ_LUE_HW_RSP_DIR_CLIENT_ID_WIDTH 3 +#define ESE_DZ_LUE_MC_ID 7 +#define ESE_DZ_LUE_MATCH_REQ_FIFO_ID 3 +#define ESE_DZ_LUE_TX_DICPU_ID 1 +#define ESE_DZ_LUE_RX_DICPU_ID 0 +#define ESF_DZ_LUE_HW_RSP_DIR_OP_LBN 0 +#define ESF_DZ_LUE_HW_RSP_DIR_OP_WIDTH 2 +#define ESE_DZ_LUE_GP_WR 3 +#define ESE_DZ_LUE_GP_RD 2 +#define ESE_DZ_LUE_DIR_REQ 1 +#define ESE_DZ_LUE_MATCH_REQ 0 + + +/* ES_LUE_MSG_GP_RD_REQ */ +#define ESF_DZ_LUE_HW_REQ_GPRD_ADDR_LBN 8 +#define ESF_DZ_LUE_HW_REQ_GPRD_ADDR_WIDTH 14 +#define ESF_DZ_LUE_HW_REQ_GPRD_THREAD_ID_LBN 5 +#define ESF_DZ_LUE_HW_REQ_GPRD_THREAD_ID_WIDTH 3 +#define ESF_DZ_LUE_HW_REQ_GPRD_CLIENT_ID_LBN 2 +#define ESF_DZ_LUE_HW_REQ_GPRD_CLIENT_ID_WIDTH 3 +#define ESE_DZ_LUE_MC_ID 7 +#define ESE_DZ_LUE_MATCH_REQ_FIFO_ID 3 +#define ESE_DZ_LUE_TX_DICPU_ID 1 +#define ESE_DZ_LUE_RX_DICPU_ID 0 +#define ESF_DZ_LUE_HW_REQ_GPRD_OP_LBN 0 +#define ESF_DZ_LUE_HW_REQ_GPRD_OP_WIDTH 2 +#define ESE_DZ_LUE_GP_WR 3 +#define ESE_DZ_LUE_GP_RD 2 +#define ESE_DZ_LUE_DIR_REQ 1 +#define ESE_DZ_LUE_MATCH_REQ 0 + + +/* ES_LUE_MSG_GP_RD_RESP */ +#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_DW0_LBN 8 +#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_DW0_WIDTH 32 +#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_DW1_LBN 40 +#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_DW1_WIDTH 32 +#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_DW2_LBN 72 +#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_DW2_WIDTH 32 +#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_DW3_LBN 104 +#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_DW3_WIDTH 32 +#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_DW4_LBN 136 +#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_DW4_WIDTH 16 +#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_LBN 8 +#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_WIDTH 144 +#define ESF_DZ_LUE_HW_RSP_GPRD_THREAD_ID_LBN 5 +#define ESF_DZ_LUE_HW_RSP_GPRD_THREAD_ID_WIDTH 3 +#define ESF_DZ_LUE_HW_RSP_GPRD_CLIENT_ID_LBN 2 +#define ESF_DZ_LUE_HW_RSP_GPRD_CLIENT_ID_WIDTH 3 +#define ESE_DZ_LUE_MC_ID 7 +#define ESE_DZ_LUE_MATCH_REQ_FIFO_ID 3 +#define ESE_DZ_LUE_TX_DICPU_ID 1 +#define ESE_DZ_LUE_RX_DICPU_ID 0 +#define ESF_DZ_LUE_HW_RSP_GPRD_OP_LBN 0 +#define ESF_DZ_LUE_HW_RSP_GPRD_OP_WIDTH 2 +#define ESE_DZ_LUE_GP_WR 3 +#define ESE_DZ_LUE_GP_RD 2 +#define ESE_DZ_LUE_DIR_REQ 1 +#define ESE_DZ_LUE_MATCH_REQ 0 + + +/* ES_LUE_MSG_GP_WR_REQ */ +#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_DW0_LBN 22 +#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_DW0_WIDTH 32 +#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_DW1_LBN 54 +#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_DW1_WIDTH 32 +#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_DW2_LBN 86 +#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_DW2_WIDTH 32 +#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_DW3_LBN 118 +#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_DW3_WIDTH 32 +#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_DW4_LBN 150 +#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_DW4_WIDTH 16 +#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_LBN 22 +#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_WIDTH 144 +#define ESF_DZ_LUE_HW_REQ_GPWR_ADDR_LBN 8 +#define ESF_DZ_LUE_HW_REQ_GPWR_ADDR_WIDTH 14 +#define ESF_DZ_LUE_HW_REQ_GPWR_THREAD_ID_LBN 5 +#define ESF_DZ_LUE_HW_REQ_GPWR_THREAD_ID_WIDTH 3 +#define ESF_DZ_LUE_HW_REQ_GPWR_CLIENT_ID_LBN 2 +#define ESF_DZ_LUE_HW_REQ_GPWR_CLIENT_ID_WIDTH 3 +#define ESE_DZ_LUE_MC_ID 7 +#define ESE_DZ_LUE_MATCH_REQ_FIFO_ID 3 +#define ESE_DZ_LUE_TX_DICPU_ID 1 +#define ESE_DZ_LUE_RX_DICPU_ID 0 +#define ESF_DZ_LUE_HW_REQ_GPWR_OP_LBN 0 +#define ESF_DZ_LUE_HW_REQ_GPWR_OP_WIDTH 2 +#define ESE_DZ_LUE_GP_WR 3 +#define ESE_DZ_LUE_GP_RD 2 +#define ESE_DZ_LUE_DIR_REQ 1 +#define ESE_DZ_LUE_MATCH_REQ 0 + + +/* ES_LUE_MSG_MATCH_REQ */ +#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_REQ_COUNT_LBN 135 +#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_REQ_COUNT_WIDTH 6 +#define ESF_DZ_LUE_HW_REQ_MATCH_HASH2_LBN 122 +#define ESF_DZ_LUE_HW_REQ_MATCH_HASH2_WIDTH 13 +#define ESF_DZ_LUE_HW_REQ_MATCH_HASH1_LBN 108 +#define ESF_DZ_LUE_HW_REQ_MATCH_HASH1_WIDTH 14 +#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW0_LBN 12 +#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW0_WIDTH 32 +#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW1_LBN 44 +#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW1_WIDTH 32 +#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW2_LBN 76 +#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW2_WIDTH 32 +#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_LBN 12 +#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_WIDTH 96 +#define ESF_DZ_LUE_HW_REQ_MATCH_DSCRMNTR_LBN 8 +#define ESF_DZ_LUE_HW_REQ_MATCH_DSCRMNTR_WIDTH 4 +#define ESF_DZ_LUE_HW_REQ_MATCH_THREAD_ID_LBN 5 +#define ESF_DZ_LUE_HW_REQ_MATCH_THREAD_ID_WIDTH 3 +#define ESF_DZ_LUE_HW_REQ_MATCH_CLIENT_ID_LBN 2 +#define ESF_DZ_LUE_HW_REQ_MATCH_CLIENT_ID_WIDTH 3 +#define ESE_DZ_LUE_MC_ID 7 +#define ESE_DZ_LUE_MATCH_REQ_FIFO_ID 3 +#define ESE_DZ_LUE_TX_DICPU_ID 1 +#define ESE_DZ_LUE_RX_DICPU_ID 0 +#define ESF_DZ_LUE_HW_REQ_MATCH_OP_LBN 0 +#define ESF_DZ_LUE_HW_REQ_MATCH_OP_WIDTH 2 +#define ESE_DZ_LUE_GP_WR 3 +#define ESE_DZ_LUE_GP_RD 2 +#define ESE_DZ_LUE_DIR_REQ 1 +#define ESE_DZ_LUE_MATCH_REQ 0 + + +/* ES_LUE_MSG_MATCH_RESP */ +#define ESF_DZ_LUE_HW_RSP_MATCH_LUE_RCPNT_LBN 29 +#define ESF_DZ_LUE_HW_RSP_MATCH_LUE_RCPNT_WIDTH 24 +#define ESF_DZ_LUE_HW_RSP_MATCH_RX_MCAST_LBN 28 +#define ESF_DZ_LUE_HW_RSP_MATCH_RX_MCAST_WIDTH 1 +#define ESF_DZ_LUE_HW_RSP_MATCH_TX_DOMAIN_LBN 20 +#define ESF_DZ_LUE_HW_RSP_MATCH_TX_DOMAIN_WIDTH 8 +#define ESF_DZ_LUE_HW_RSP_MATCH_TX_MCAST_LBN 18 +#define ESF_DZ_LUE_HW_RSP_MATCH_TX_MCAST_WIDTH 2 +#define ESF_DZ_LUE_HW_RSP_MATCH_SOFT_LBN 9 +#define ESF_DZ_LUE_HW_RSP_MATCH_SOFT_WIDTH 9 +#define ESF_DZ_LUE_HW_RSP_MATCH_MATCH_LBN 8 +#define ESF_DZ_LUE_HW_RSP_MATCH_MATCH_WIDTH 1 +#define ESF_DZ_LUE_HW_RSP_MATCH_THREAD_ID_LBN 5 +#define ESF_DZ_LUE_HW_RSP_MATCH_THREAD_ID_WIDTH 3 +#define ESF_DZ_LUE_HW_RSP_MATCH_CLIENT_ID_LBN 2 +#define ESF_DZ_LUE_HW_RSP_MATCH_CLIENT_ID_WIDTH 3 +#define ESE_DZ_LUE_MC_ID 7 +#define ESE_DZ_LUE_MATCH_REQ_FIFO_ID 3 +#define ESE_DZ_LUE_TX_DICPU_ID 1 +#define ESE_DZ_LUE_RX_DICPU_ID 0 +#define ESF_DZ_LUE_HW_RSP_MATCH_OP_LBN 0 +#define ESF_DZ_LUE_HW_RSP_MATCH_OP_WIDTH 2 +#define ESE_DZ_LUE_GP_WR 3 +#define ESE_DZ_LUE_GP_RD 2 +#define ESE_DZ_LUE_DIR_REQ 1 +#define ESE_DZ_LUE_MATCH_REQ 0 + + +/* ES_LUE_RCPNTR_TYPE */ +#define ESF_DZ_LUE_RXQ_LBN 14 +#define ESF_DZ_LUE_RXQ_WIDTH 10 +#define ESF_DZ_LUE_RSS_INFO_LBN 8 +#define ESF_DZ_LUE_RSS_INFO_WIDTH 6 +#define ESF_DZ_LUE_DEST_LBN 5 +#define ESF_DZ_LUE_DEST_WIDTH 3 +#define ESF_DZ_LUE_SOFT_LBN 0 +#define ESF_DZ_LUE_SOFT_WIDTH 5 + + +/* ES_LUE_UMSG_LU2DI_HASH_RESP */ +#define ESF_DZ_L2DHR_LASTREC_ENTRY_STATUS_LBN 50 +#define ESF_DZ_L2DHR_LASTREC_ENTRY_STATUS_WIDTH 1 +#define ESF_DZ_L2DHR_MULTITYPE_STATUS_LBN 50 +#define ESF_DZ_L2DHR_MULTITYPE_STATUS_WIDTH 1 +#define ESF_DZ_L2DHR_LASTREC_STATUS_LBN 49 +#define ESF_DZ_L2DHR_LASTREC_STATUS_WIDTH 1 +#define ESF_DZ_L2DHR_MATCH_STATUS_LBN 48 +#define ESF_DZ_L2DHR_MATCH_STATUS_WIDTH 1 +#define ESF_DZ_L2DHR_HASH_LBN 0 +#define ESF_DZ_L2DHR_HASH_WIDTH 32 + + +/* ES_LUE_UMSG_LU2DI_RXLU_MULTI_MATCH_RESP */ +#define ESF_DZ_L2DRMMR_SOFT_LBN 112 +#define ESF_DZ_L2DRMMR_SOFT_WIDTH 9 +#define ESF_DZ_L2DRMMR_RCPNTR_PTR_LBN 96 +#define ESF_DZ_L2DRMMR_RCPNTR_PTR_WIDTH 14 +#define ESF_DZ_L2DRMMR_TX_MCAST_LBN 80 +#define ESF_DZ_L2DRMMR_TX_MCAST_WIDTH 2 +#define ESF_DZ_L2DRMMR_MULTITYPE_STATUS_LBN 67 +#define ESF_DZ_L2DRMMR_MULTITYPE_STATUS_WIDTH 1 +#define ESF_DZ_L2DRMMR_LASTREC_ENTRY_STATUS_LBN 66 +#define ESF_DZ_L2DRMMR_LASTREC_ENTRY_STATUS_WIDTH 1 +#define ESF_DZ_L2DRMMR_LASTREC_STATUS_LBN 65 +#define ESF_DZ_L2DRMMR_LASTREC_STATUS_WIDTH 1 +#define ESF_DZ_L2DRMMR_MATCH_STATUS_LBN 64 +#define ESF_DZ_L2DRMMR_MATCH_STATUS_WIDTH 1 + + +/* ES_LUE_UMSG_LU2DI_RXLU_MULTI_RECORD_RESP */ +#define ESF_DZ_L2DRMRR_SOFT_LBN 112 +#define ESF_DZ_L2DRMRR_SOFT_WIDTH 9 +#define ESF_DZ_L2DRMRR_RCPNTR_PTR_LBN 96 +#define ESF_DZ_L2DRMRR_RCPNTR_PTR_WIDTH 14 +#define ESF_DZ_L2DRMRR_RCPNTR_NUM_LBN 80 +#define ESF_DZ_L2DRMRR_RCPNTR_NUM_WIDTH 3 +#define ESF_DZ_L2DRMRR_MULTITYPE_STATUS_LBN 67 +#define ESF_DZ_L2DRMRR_MULTITYPE_STATUS_WIDTH 1 +#define ESF_DZ_L2DRMRR_LASTREC_ENTRY_STATUS_LBN 66 +#define ESF_DZ_L2DRMRR_LASTREC_ENTRY_STATUS_WIDTH 1 +#define ESF_DZ_L2DRMRR_LASTREC_STATUS_LBN 65 +#define ESF_DZ_L2DRMRR_LASTREC_STATUS_WIDTH 1 +#define ESF_DZ_L2DRMRR_MATCH_STATUS_LBN 64 +#define ESF_DZ_L2DRMRR_MATCH_STATUS_WIDTH 1 +#define ESF_DZ_L2DRMRR_RCPNTR_SOFT_LBN 48 +#define ESF_DZ_L2DRMRR_RCPNTR_SOFT_WIDTH 6 +#define ESF_DZ_L2DRMRR_RCPNTR_RSS_INFO_LBN 32 +#define ESF_DZ_L2DRMRR_RCPNTR_RSS_INFO_WIDTH 5 +#define ESF_DZ_L2DRMRR_RCPNTR_RXQ_LBN 16 +#define ESF_DZ_L2DRMRR_RCPNTR_RXQ_WIDTH 10 +#define ESF_DZ_L2DRMRR_HOST_LBN 7 +#define ESF_DZ_L2DRMRR_HOST_WIDTH 1 +#define ESF_DZ_L2DRMRR_MC_LBN 6 +#define ESF_DZ_L2DRMRR_MC_WIDTH 1 +#define ESF_DZ_L2DRMRR_PORT0_MAC_LBN 5 +#define ESF_DZ_L2DRMRR_PORT0_MAC_WIDTH 1 +#define ESF_DZ_L2DRMRR_PORT1_MAC_LBN 4 +#define ESF_DZ_L2DRMRR_PORT1_MAC_WIDTH 1 + + +/* ES_LUE_UMSG_LU2DI_RXLU_SINGLE_MATCH_RESP */ +#define ESF_DZ_L2DRSMR_MULTITYPE_STATUS_LBN 67 +#define ESF_DZ_L2DRSMR_MULTITYPE_STATUS_WIDTH 1 +#define ESF_DZ_L2DRSMR_LASTREC_ENTRY_STATUS_LBN 66 +#define ESF_DZ_L2DRSMR_LASTREC_ENTRY_STATUS_WIDTH 1 +#define ESF_DZ_L2DRSMR_LASTREC_STATUS_LBN 65 +#define ESF_DZ_L2DRSMR_LASTREC_STATUS_WIDTH 1 +#define ESF_DZ_L2DRSMR_MATCH_STATUS_LBN 64 +#define ESF_DZ_L2DRSMR_MATCH_STATUS_WIDTH 1 +#define ESF_DZ_L2DRSMR_RCPNTR_SOFT_LBN 48 +#define ESF_DZ_L2DRSMR_RCPNTR_SOFT_WIDTH 6 +#define ESF_DZ_L2DRSMR_RCPNTR_RSS_INFO_LBN 32 +#define ESF_DZ_L2DRSMR_RCPNTR_RSS_INFO_WIDTH 5 +#define ESF_DZ_L2DRSMR_RCPNTR_RXQ_LBN 16 +#define ESF_DZ_L2DRSMR_RCPNTR_RXQ_WIDTH 10 +#define ESF_DZ_L2DRSMR_HOST_LBN 7 +#define ESF_DZ_L2DRSMR_HOST_WIDTH 1 +#define ESF_DZ_L2DRSMR_MC_LBN 6 +#define ESF_DZ_L2DRSMR_MC_WIDTH 1 +#define ESF_DZ_L2DRSMR_PORT0_MAC_LBN 5 +#define ESF_DZ_L2DRSMR_PORT0_MAC_WIDTH 1 +#define ESF_DZ_L2DRSMR_PORT1_MAC_LBN 4 +#define ESF_DZ_L2DRSMR_PORT1_MAC_WIDTH 1 + + +/* ES_LUE_UMSG_LU2DI_TXLU_MATCH_RESP */ +#define ESF_DZ_L2DTMR_RCPNTR_SOFT_LBN 112 +#define ESF_DZ_L2DTMR_RCPNTR_SOFT_WIDTH 6 +#define ESF_DZ_L2DTMR_RCPNTR_RSS_INFO_LBN 96 +#define ESF_DZ_L2DTMR_RCPNTR_RSS_INFO_WIDTH 5 +#define ESF_DZ_L2DTMR_RCPNTR__RXQ_LBN 80 +#define ESF_DZ_L2DTMR_RCPNTR__RXQ_WIDTH 10 +#define ESF_DZ_L2DTMR_MULTITYPE_STATUS_LBN 67 +#define ESF_DZ_L2DTMR_MULTITYPE_STATUS_WIDTH 1 +#define ESF_DZ_L2DTMR_LASTREC_ENTRY_STATUS_LBN 66 +#define ESF_DZ_L2DTMR_LASTREC_ENTRY_STATUS_WIDTH 1 +#define ESF_DZ_L2DTMR_LASTREC_STATUS_LBN 65 +#define ESF_DZ_L2DTMR_LASTREC_STATUS_WIDTH 1 +#define ESF_DZ_L2DTMR_MATCH_STATUS_LBN 64 +#define ESF_DZ_L2DTMR_MATCH_STATUS_WIDTH 1 +#define ESF_DZ_L2DTMR_ME_SOFT_LBN 48 +#define ESF_DZ_L2DTMR_ME_SOFT_WIDTH 9 +#define ESF_DZ_L2DTMR_TX_MCAST_LBN 32 +#define ESF_DZ_L2DTMR_TX_MCAST_WIDTH 2 +#define ESF_DZ_L2DTMR_TX_DOMAIN_LBN 16 +#define ESF_DZ_L2DTMR_TX_DOMAIN_WIDTH 8 +#define ESF_DZ_L2DTMR_PORT1_MAC_LBN 6 +#define ESF_DZ_L2DTMR_PORT1_MAC_WIDTH 1 +#define ESF_DZ_L2DTMR_PMEM_LBN 6 +#define ESF_DZ_L2DTMR_PMEM_WIDTH 1 +#define ESF_DZ_L2DTMR_PORT0_MAC_LBN 5 +#define ESF_DZ_L2DTMR_PORT0_MAC_WIDTH 1 + + +/* ES_MC_EVENT */ +#define ESF_DZ_MC_CODE_LBN 60 +#define ESF_DZ_MC_CODE_WIDTH 4 +#define ESF_DZ_MC_OVERRIDE_HOLDOFF_LBN 59 +#define ESF_DZ_MC_OVERRIDE_HOLDOFF_WIDTH 1 +#define ESF_DZ_MC_DROP_EVENT_LBN 58 +#define ESF_DZ_MC_DROP_EVENT_WIDTH 1 +#define ESF_DZ_MC_SOFT_DW0_LBN 0 +#define ESF_DZ_MC_SOFT_DW0_WIDTH 32 +#define ESF_DZ_MC_SOFT_DW1_LBN 32 +#define ESF_DZ_MC_SOFT_DW1_WIDTH 26 +#define ESF_DZ_MC_SOFT_LBN 0 +#define ESF_DZ_MC_SOFT_WIDTH 58 + + +/* ES_MC_XGMAC_FLTR_RULE_DEF */ +#define ESF_DZ_MC_XFRC_MODE_LBN 416 +#define ESF_DZ_MC_XFRC_MODE_WIDTH 1 +#define ESE_DZ_MC_XFRC_MODE_LAYERED 1 +#define ESE_DZ_MC_XFRC_MODE_SIMPLE 0 +#define ESF_DZ_MC_XFRC_HASH_LBN 384 +#define ESF_DZ_MC_XFRC_HASH_WIDTH 32 +#define ESF_DZ_MC_XFRC_LAYER4_BYTE_MASK_DW0_LBN 256 +#define ESF_DZ_MC_XFRC_LAYER4_BYTE_MASK_DW0_WIDTH 32 +#define ESF_DZ_MC_XFRC_LAYER4_BYTE_MASK_DW1_LBN 288 +#define ESF_DZ_MC_XFRC_LAYER4_BYTE_MASK_DW1_WIDTH 32 +#define ESF_DZ_MC_XFRC_LAYER4_BYTE_MASK_DW2_LBN 320 +#define ESF_DZ_MC_XFRC_LAYER4_BYTE_MASK_DW2_WIDTH 32 +#define ESF_DZ_MC_XFRC_LAYER4_BYTE_MASK_DW3_LBN 352 +#define ESF_DZ_MC_XFRC_LAYER4_BYTE_MASK_DW3_WIDTH 32 +#define ESF_DZ_MC_XFRC_LAYER4_BYTE_MASK_LBN 256 +#define ESF_DZ_MC_XFRC_LAYER4_BYTE_MASK_WIDTH 128 +#define ESF_DZ_MC_XFRC_LAYER3_BYTE_MASK_DW0_LBN 128 +#define ESF_DZ_MC_XFRC_LAYER3_BYTE_MASK_DW0_WIDTH 32 +#define ESF_DZ_MC_XFRC_LAYER3_BYTE_MASK_DW1_LBN 160 +#define ESF_DZ_MC_XFRC_LAYER3_BYTE_MASK_DW1_WIDTH 32 +#define ESF_DZ_MC_XFRC_LAYER3_BYTE_MASK_DW2_LBN 192 +#define ESF_DZ_MC_XFRC_LAYER3_BYTE_MASK_DW2_WIDTH 32 +#define ESF_DZ_MC_XFRC_LAYER3_BYTE_MASK_DW3_LBN 224 +#define ESF_DZ_MC_XFRC_LAYER3_BYTE_MASK_DW3_WIDTH 32 +#define ESF_DZ_MC_XFRC_LAYER3_BYTE_MASK_LBN 128 +#define ESF_DZ_MC_XFRC_LAYER3_BYTE_MASK_WIDTH 128 +#define ESF_DZ_MC_XFRC_LAYER2_OR_SIMPLE_BYTE_MASK_DW0_LBN 0 +#define ESF_DZ_MC_XFRC_LAYER2_OR_SIMPLE_BYTE_MASK_DW0_WIDTH 32 +#define ESF_DZ_MC_XFRC_LAYER2_OR_SIMPLE_BYTE_MASK_DW1_LBN 32 +#define ESF_DZ_MC_XFRC_LAYER2_OR_SIMPLE_BYTE_MASK_DW1_WIDTH 32 +#define ESF_DZ_MC_XFRC_LAYER2_OR_SIMPLE_BYTE_MASK_DW2_LBN 64 +#define ESF_DZ_MC_XFRC_LAYER2_OR_SIMPLE_BYTE_MASK_DW2_WIDTH 32 +#define ESF_DZ_MC_XFRC_LAYER2_OR_SIMPLE_BYTE_MASK_DW3_LBN 96 +#define ESF_DZ_MC_XFRC_LAYER2_OR_SIMPLE_BYTE_MASK_DW3_WIDTH 32 +#define ESF_DZ_MC_XFRC_LAYER2_OR_SIMPLE_BYTE_MASK_LBN 0 +#define ESF_DZ_MC_XFRC_LAYER2_OR_SIMPLE_BYTE_MASK_WIDTH 128 + + +/* ES_RX_EVENT */ +#define ESF_DZ_RX_CODE_LBN 60 +#define ESF_DZ_RX_CODE_WIDTH 4 +#define ESF_DZ_RX_OVERRIDE_HOLDOFF_LBN 59 +#define ESF_DZ_RX_OVERRIDE_HOLDOFF_WIDTH 1 +#define ESF_DZ_RX_DROP_EVENT_LBN 58 +#define ESF_DZ_RX_DROP_EVENT_WIDTH 1 +#define ESF_DZ_RX_EV_RSVD2_LBN 55 +#define ESF_DZ_RX_EV_RSVD2_WIDTH 3 +#define ESF_DZ_RX_EV_SOFT2_LBN 52 +#define ESF_DZ_RX_EV_SOFT2_WIDTH 3 +#define ESF_DZ_RX_DSC_PTR_LBITS_LBN 48 +#define ESF_DZ_RX_DSC_PTR_LBITS_WIDTH 4 +#define ESF_DZ_RX_L4_CLASS_LBN 45 +#define ESF_DZ_RX_L4_CLASS_WIDTH 3 +#define ESE_DZ_L4_CLASS_RSVD7 7 +#define ESE_DZ_L4_CLASS_RSVD6 6 +#define ESE_DZ_L4_CLASS_RSVD5 5 +#define ESE_DZ_L4_CLASS_RSVD4 4 +#define ESE_DZ_L4_CLASS_RSVD3 3 +#define ESE_DZ_L4_CLASS_UDP 2 +#define ESE_DZ_L4_CLASS_TCP 1 +#define ESE_DZ_L4_CLASS_UNKNOWN 0 +#define ESF_DZ_RX_L3_CLASS_LBN 42 +#define ESF_DZ_RX_L3_CLASS_WIDTH 3 +#define ESE_DZ_L3_CLASS_RSVD7 7 +#define ESE_DZ_L3_CLASS_IP6_FRAG 6 +#define ESE_DZ_L3_CLASS_ARP 5 +#define ESE_DZ_L3_CLASS_IP4_FRAG 4 +#define ESE_DZ_L3_CLASS_FCOE 3 +#define ESE_DZ_L3_CLASS_IP6 2 +#define ESE_DZ_L3_CLASS_IP4 1 +#define ESE_DZ_L3_CLASS_UNKNOWN 0 +#define ESF_DZ_RX_ETH_TAG_CLASS_LBN 39 +#define ESF_DZ_RX_ETH_TAG_CLASS_WIDTH 3 +#define ESE_DZ_ETH_TAG_CLASS_RSVD7 7 +#define ESE_DZ_ETH_TAG_CLASS_RSVD6 6 +#define ESE_DZ_ETH_TAG_CLASS_RSVD5 5 +#define ESE_DZ_ETH_TAG_CLASS_RSVD4 4 +#define ESE_DZ_ETH_TAG_CLASS_RSVD3 3 +#define ESE_DZ_ETH_TAG_CLASS_VLAN2 2 +#define ESE_DZ_ETH_TAG_CLASS_VLAN1 1 +#define ESE_DZ_ETH_TAG_CLASS_NONE 0 +#define ESF_DZ_RX_ETH_BASE_CLASS_LBN 36 +#define ESF_DZ_RX_ETH_BASE_CLASS_WIDTH 3 +#define ESE_DZ_ETH_BASE_CLASS_LLC_SNAP 2 +#define ESE_DZ_ETH_BASE_CLASS_LLC 1 +#define ESE_DZ_ETH_BASE_CLASS_ETH2 0 +#define ESF_DZ_RX_MAC_CLASS_LBN 35 +#define ESF_DZ_RX_MAC_CLASS_WIDTH 1 +#define ESE_DZ_MAC_CLASS_MCAST 1 +#define ESE_DZ_MAC_CLASS_UCAST 0 +#define ESF_DZ_RX_EV_SOFT1_LBN 32 +#define ESF_DZ_RX_EV_SOFT1_WIDTH 3 +#define ESF_DZ_RX_EV_RSVD1_LBN 30 +#define ESF_DZ_RX_EV_RSVD1_WIDTH 2 +#define ESF_DZ_RX_ECC_ERR_LBN 29 +#define ESF_DZ_RX_ECC_ERR_WIDTH 1 +#define ESF_DZ_RX_CRC1_ERR_LBN 28 +#define ESF_DZ_RX_CRC1_ERR_WIDTH 1 +#define ESF_DZ_RX_CRC0_ERR_LBN 27 +#define ESF_DZ_RX_CRC0_ERR_WIDTH 1 +#define ESF_DZ_RX_TCPUDP_CKSUM_ERR_LBN 26 +#define ESF_DZ_RX_TCPUDP_CKSUM_ERR_WIDTH 1 +#define ESF_DZ_RX_IPCKSUM_ERR_LBN 25 +#define ESF_DZ_RX_IPCKSUM_ERR_WIDTH 1 +#define ESF_DZ_RX_ECRC_ERR_LBN 24 +#define ESF_DZ_RX_ECRC_ERR_WIDTH 1 +#define ESF_DZ_RX_QLABEL_LBN 16 +#define ESF_DZ_RX_QLABEL_WIDTH 8 +#define ESF_DZ_RX_PARSE_INCOMPLETE_LBN 15 +#define ESF_DZ_RX_PARSE_INCOMPLETE_WIDTH 1 +#define ESF_DZ_RX_CONT_LBN 14 +#define ESF_DZ_RX_CONT_WIDTH 1 +#define ESF_DZ_RX_BYTES_LBN 0 +#define ESF_DZ_RX_BYTES_WIDTH 14 + + +/* ES_RX_KER_DESC */ +#define ESF_DZ_RX_KER_RESERVED_LBN 62 +#define ESF_DZ_RX_KER_RESERVED_WIDTH 2 +#define ESF_DZ_RX_KER_BYTE_CNT_LBN 48 +#define ESF_DZ_RX_KER_BYTE_CNT_WIDTH 14 +#define ESF_DZ_RX_KER_BUF_ADDR_DW0_LBN 0 +#define ESF_DZ_RX_KER_BUF_ADDR_DW0_WIDTH 32 +#define ESF_DZ_RX_KER_BUF_ADDR_DW1_LBN 32 +#define ESF_DZ_RX_KER_BUF_ADDR_DW1_WIDTH 16 +#define ESF_DZ_RX_KER_BUF_ADDR_LBN 0 +#define ESF_DZ_RX_KER_BUF_ADDR_WIDTH 48 + + +/* ES_RX_USER_DESC */ +#define ESF_DZ_RX_USR_RESERVED_LBN 62 +#define ESF_DZ_RX_USR_RESERVED_WIDTH 2 +#define ESF_DZ_RX_USR_BYTE_CNT_LBN 48 +#define ESF_DZ_RX_USR_BYTE_CNT_WIDTH 14 +#define ESF_DZ_RX_USR_BUF_PAGE_SIZE_LBN 44 +#define ESF_DZ_RX_USR_BUF_PAGE_SIZE_WIDTH 4 +#define ESE_DZ_USR_BUF_PAGE_SZ_4MB 10 +#define ESE_DZ_USR_BUF_PAGE_SZ_1MB 8 +#define ESE_DZ_USR_BUF_PAGE_SZ_64KB 4 +#define ESE_DZ_USR_BUF_PAGE_SZ_4KB 0 +#define ESF_DZ_RX_USR_BUF_ID_OFFSET_DW0_LBN 0 +#define ESF_DZ_RX_USR_BUF_ID_OFFSET_DW0_WIDTH 32 +#define ESF_DZ_RX_USR_BUF_ID_OFFSET_DW1_LBN 32 +#define ESF_DZ_RX_USR_BUF_ID_OFFSET_DW1_WIDTH 12 +#define ESF_DZ_RX_USR_BUF_ID_OFFSET_LBN 0 +#define ESF_DZ_RX_USR_BUF_ID_OFFSET_WIDTH 44 +#define ESF_DZ_RX_USR_4KBPS_BUF_ID_LBN 12 +#define ESF_DZ_RX_USR_4KBPS_BUF_ID_WIDTH 32 +#define ESF_DZ_RX_USR_64KBPS_BUF_ID_LBN 16 +#define ESF_DZ_RX_USR_64KBPS_BUF_ID_WIDTH 28 +#define ESF_DZ_RX_USR_1MBPS_BUF_ID_LBN 20 +#define ESF_DZ_RX_USR_1MBPS_BUF_ID_WIDTH 24 +#define ESF_DZ_RX_USR_4MBPS_BUF_ID_LBN 22 +#define ESF_DZ_RX_USR_4MBPS_BUF_ID_WIDTH 22 +#define ESF_DZ_RX_USR_4MBPS_BYTE_OFFSET_LBN 0 +#define ESF_DZ_RX_USR_4MBPS_BYTE_OFFSET_WIDTH 22 +#define ESF_DZ_RX_USR_1MBPS_BYTE_OFFSET_LBN 0 +#define ESF_DZ_RX_USR_1MBPS_BYTE_OFFSET_WIDTH 20 +#define ESF_DZ_RX_USR_64KBPS_BYTE_OFFSET_LBN 0 +#define ESF_DZ_RX_USR_64KBPS_BYTE_OFFSET_WIDTH 16 +#define ESF_DZ_RX_USR_4KBPS_BYTE_OFFSET_LBN 0 +#define ESF_DZ_RX_USR_4KBPS_BYTE_OFFSET_WIDTH 12 + + +/* ES_RX_U_QSTATE_TBL0_ENTRY */ +#define ESF_DZ_RX_U_DC_FILL_LBN 112 +#define ESF_DZ_RX_U_DC_FILL_WIDTH 7 +#define ESF_DZ_RX_U_SOFT7_B1R1_0_LBN 112 +#define ESF_DZ_RX_U_SOFT7_B1R1_0_WIDTH 7 +#define ESF_DZ_RX_U_DSCR_HW_RPTR_LBN 96 +#define ESF_DZ_RX_U_DSCR_HW_RPTR_WIDTH 12 +#define ESF_DZ_RX_U_SOFT12_B1R2_0_LBN 96 +#define ESF_DZ_RX_U_SOFT12_B1R2_0_WIDTH 12 +#define ESF_DZ_RX_U_DC_RPTR_LBN 80 +#define ESF_DZ_RX_U_DC_RPTR_WIDTH 6 +#define ESF_DZ_RX_U_SOFT6_B1R1_0_LBN 80 +#define ESF_DZ_RX_U_SOFT6_B1R1_0_WIDTH 6 +#define ESF_DZ_RX_U_NOTIFY_PENDING_LBN 70 +#define ESF_DZ_RX_U_NOTIFY_PENDING_WIDTH 1 +#define ESF_DZ_RX_U_SOFT1_B1R0_6_LBN 70 +#define ESF_DZ_RX_U_SOFT1_B1R0_6_WIDTH 1 +#define ESF_DZ_RX_U_DATA_ACTIVE_LBN 69 +#define ESF_DZ_RX_U_DATA_ACTIVE_WIDTH 1 +#define ESF_DZ_RX_U_SOFT1_B1R0_5_LBN 69 +#define ESF_DZ_RX_U_SOFT1_B1R0_5_WIDTH 1 +#define ESF_DZ_RX_U_FAST_PATH_LBN 68 +#define ESF_DZ_RX_U_FAST_PATH_WIDTH 1 +#define ESF_DZ_RX_U_SOFT1_B1R0_4_LBN 68 +#define ESF_DZ_RX_U_SOFT1_B1R0_4_WIDTH 1 +#define ESF_DZ_RX_U_NO_FLUSH_LBN 67 +#define ESF_DZ_RX_U_NO_FLUSH_WIDTH 1 +#define ESF_DZ_RX_U_SOFT1_B1R0_3_LBN 67 +#define ESF_DZ_RX_U_SOFT1_B1R0_3_WIDTH 1 +#define ESF_DZ_RX_U_DESC_ACTIVE_LBN 66 +#define ESF_DZ_RX_U_DESC_ACTIVE_WIDTH 1 +#define ESF_DZ_RX_U_SOFT1_B1R0_2_LBN 66 +#define ESF_DZ_RX_U_SOFT1_B1R0_2_WIDTH 1 +#define ESF_DZ_RX_U_HDR_SPLIT_LBN 65 +#define ESF_DZ_RX_U_HDR_SPLIT_WIDTH 1 +#define ESF_DZ_RX_U_SOFT1_B1R0_1_LBN 65 +#define ESF_DZ_RX_U_SOFT1_B1R0_1_WIDTH 1 +#define ESF_DZ_RX_U_Q_ENABLE_LBN 64 +#define ESF_DZ_RX_U_Q_ENABLE_WIDTH 1 +#define ESF_DZ_RX_U_SOFT1_B1R0_0_LBN 64 +#define ESF_DZ_RX_U_SOFT1_B1R0_0_WIDTH 1 +#define ESF_DZ_RX_U_UPD_CRC_MODE_LBN 29 +#define ESF_DZ_RX_U_UPD_CRC_MODE_WIDTH 3 +#define ESE_DZ_C2RIP_FCOIP_MPA 5 +#define ESE_DZ_C2RIP_FCOIP_FCOE 4 +#define ESE_DZ_C2RIP_ISCSI_HDR_AND_PYLD 3 +#define ESE_DZ_C2RIP_ISCSI_HDR 2 +#define ESE_DZ_C2RIP_FCOE 1 +#define ESE_DZ_C2RIP_OFF 0 +#define ESF_DZ_RX_U_SOFT16_B0R1_LBN 16 +#define ESF_DZ_RX_U_SOFT16_B0R1_WIDTH 16 +#define ESF_DZ_RX_U_BIU_ARGS_LBN 16 +#define ESF_DZ_RX_U_BIU_ARGS_WIDTH 13 +#define ESF_DZ_RX_U_EV_QID_LBN 5 +#define ESF_DZ_RX_U_EV_QID_WIDTH 11 +#define ESF_DZ_RX_U_SOFT16_B0R0_LBN 0 +#define ESF_DZ_RX_U_SOFT16_B0R0_WIDTH 16 +#define ESF_DZ_RX_U_EV_QLABEL_LBN 0 +#define ESF_DZ_RX_U_EV_QLABEL_WIDTH 5 + + +/* ES_RX_U_QSTATE_TBL1_ENTRY */ +#define ESF_DZ_RX_U_DSCR_BASE_PAGE_ID_LBN 64 +#define ESF_DZ_RX_U_DSCR_BASE_PAGE_ID_WIDTH 18 +#define ESF_DZ_RX_U_SOFT18_B1R0_0_LBN 64 +#define ESF_DZ_RX_U_SOFT18_B1R0_0_WIDTH 18 +#define ESF_DZ_RX_U_QST1_SPARE_LBN 52 +#define ESF_DZ_RX_U_QST1_SPARE_WIDTH 12 +#define ESF_DZ_RX_U_SOFT16_B0R3_0_LBN 48 +#define ESF_DZ_RX_U_SOFT16_B0R3_0_WIDTH 16 +#define ESF_DZ_RX_U_PKT_EDIT_LBN 51 +#define ESF_DZ_RX_U_PKT_EDIT_WIDTH 1 +#define ESF_DZ_RX_U_DOORBELL_ENABLED_LBN 50 +#define ESF_DZ_RX_U_DOORBELL_ENABLED_WIDTH 1 +#define ESF_DZ_RX_U_WORK_PENDING_LBN 49 +#define ESF_DZ_RX_U_WORK_PENDING_WIDTH 1 +#define ESF_DZ_RX_U_ERROR_LBN 48 +#define ESF_DZ_RX_U_ERROR_WIDTH 1 +#define ESF_DZ_RX_U_DSCR_SW_WPTR_LBN 32 +#define ESF_DZ_RX_U_DSCR_SW_WPTR_WIDTH 12 +#define ESF_DZ_RX_U_SOFT12_B0R2_0_LBN 32 +#define ESF_DZ_RX_U_SOFT12_B0R2_0_WIDTH 12 +#define ESF_DZ_RX_U_OWNER_ID_LBN 16 +#define ESF_DZ_RX_U_OWNER_ID_WIDTH 12 +#define ESF_DZ_RX_U_SOFT12_B0R1_0_LBN 16 +#define ESF_DZ_RX_U_SOFT12_B0R1_0_WIDTH 12 +#define ESF_DZ_RX_U_DSCR_SIZE_LBN 0 +#define ESF_DZ_RX_U_DSCR_SIZE_WIDTH 3 +#define ESE_DZ_RX_DSCR_SIZE_512 7 +#define ESE_DZ_RX_DSCR_SIZE_1K 6 +#define ESE_DZ_RX_DSCR_SIZE_2K 5 +#define ESE_DZ_RX_DSCR_SIZE_4K 4 +#define ESF_DZ_RX_U_SOFT3_B0R0_0_LBN 0 +#define ESF_DZ_RX_U_SOFT3_B0R0_0_WIDTH 3 + + +/* ES_SMC_BUFTBL_CNTRL_ENTRY */ +#define ESF_DZ_SMC_SW_CNTXT_DW0_LBN 16 +#define ESF_DZ_SMC_SW_CNTXT_DW0_WIDTH 32 +#define ESF_DZ_SMC_SW_CNTXT_DW1_LBN 48 +#define ESF_DZ_SMC_SW_CNTXT_DW1_WIDTH 24 +#define ESF_DZ_SMC_SW_CNTXT_LBN 16 +#define ESF_DZ_SMC_SW_CNTXT_WIDTH 56 +#define ESF_DZ_SMC_PAGE_SIZE_LBN 12 +#define ESF_DZ_SMC_PAGE_SIZE_WIDTH 4 +#define ESF_DZ_SMC_OWNER_ID_LBN 0 +#define ESF_DZ_SMC_OWNER_ID_WIDTH 12 + + +/* ES_SMC_BUFTBL_TRANSL_ENTRY */ +#define ESF_DZ_SMC_PAGE_INDEX0_DW0_LBN 36 +#define ESF_DZ_SMC_PAGE_INDEX0_DW0_WIDTH 32 +#define ESF_DZ_SMC_PAGE_INDEX0_DW1_LBN 68 +#define ESF_DZ_SMC_PAGE_INDEX0_DW1_WIDTH 4 +#define ESF_DZ_SMC_PAGE_INDEX0_LBN 36 +#define ESF_DZ_SMC_PAGE_INDEX0_WIDTH 36 +#define ESF_DZ_SMC_PAGE_INDEX1_DW0_LBN 0 +#define ESF_DZ_SMC_PAGE_INDEX1_DW0_WIDTH 32 +#define ESF_DZ_SMC_PAGE_INDEX1_DW1_LBN 32 +#define ESF_DZ_SMC_PAGE_INDEX1_DW1_WIDTH 4 +#define ESF_DZ_SMC_PAGE_INDEX1_LBN 0 +#define ESF_DZ_SMC_PAGE_INDEX1_WIDTH 36 + + +/* ES_SMC_DSCR_CACHE_ENTRY */ +#define ESF_DZ_SMC_BTE_PAD_LBN 64 +#define ESF_DZ_SMC_BTE_PAD_WIDTH 8 +#define ESF_DZ_SMC_DSCR_DW0_LBN 0 +#define ESF_DZ_SMC_DSCR_DW0_WIDTH 32 +#define ESF_DZ_SMC_DSCR_DW1_LBN 32 +#define ESF_DZ_SMC_DSCR_DW1_WIDTH 32 +#define ESF_DZ_SMC_DSCR_LBN 0 +#define ESF_DZ_SMC_DSCR_WIDTH 64 + + +/* ES_SMC_GEN_STORAGE_ENTRY */ +#define ESF_DZ_SMC_DATA_DW0_LBN 0 +#define ESF_DZ_SMC_DATA_DW0_WIDTH 32 +#define ESF_DZ_SMC_DATA_DW1_LBN 32 +#define ESF_DZ_SMC_DATA_DW1_WIDTH 32 +#define ESF_DZ_SMC_DATA_DW2_LBN 64 +#define ESF_DZ_SMC_DATA_DW2_WIDTH 8 +#define ESF_DZ_SMC_DATA_LBN 0 +#define ESF_DZ_SMC_DATA_WIDTH 72 + + +/* ES_SMC_MSG_BASE_REQ */ +#define ESF_DZ_MC2S_BASE_REQ_MSG_DATA_DW0_LBN 11 +#define ESF_DZ_MC2S_BASE_REQ_MSG_DATA_DW0_WIDTH 32 +#define ESF_DZ_MC2S_BASE_REQ_MSG_DATA_DW1_LBN 43 +#define ESF_DZ_MC2S_BASE_REQ_MSG_DATA_DW1_WIDTH 32 +#define ESF_DZ_MC2S_BASE_REQ_MSG_DATA_DW2_LBN 75 +#define ESF_DZ_MC2S_BASE_REQ_MSG_DATA_DW2_WIDTH 26 +#define ESF_DZ_MC2S_BASE_REQ_MSG_DATA_LBN 11 +#define ESF_DZ_MC2S_BASE_REQ_MSG_DATA_WIDTH 90 +#define ESF_DZ_MC2S_BASE_SOFT_LBN 7 +#define ESF_DZ_MC2S_BASE_SOFT_WIDTH 4 +#define ESF_DZ_MC2S_BASE_CLIENT_ID_LBN 3 +#define ESF_DZ_MC2S_BASE_CLIENT_ID_WIDTH 4 +#define ESE_DZ_SMC_MACRO_ENGINE_ID 15 +#define ESE_DZ_SMC_TX_DICPU_ID 14 +#define ESE_DZ_SMC_RX_DICPU_ID 13 +#define ESE_DZ_SMC_MC_ID 12 +#define ESE_DZ_SMC_DL_ID 10 +#define ESE_DZ_SMC_EV_ID 8 +#define ESE_DZ_SMC_TX_DPCPU1_ID 5 +#define ESE_DZ_SMC_TX_DPCPU0_ID 4 +#define ESE_DZ_SMC_RX_DPCPU_ID 0 +#define ESF_DZ_MC2S_BASE_OP_LBN 0 +#define ESF_DZ_MC2S_BASE_OP_WIDTH 3 +#define ESE_DZ_SMC_REQ_WR 4 +#define ESE_DZ_SMC_RESP_WR 4 +#define ESE_DZ_SMC_REQ_RD 3 +#define ESE_DZ_SMC_RESP_RD 3 +#define ESE_DZ_SMC_REQ_DSCR_WRITE 2 +#define ESE_DZ_SMC_RESP_DSCR_WRITE 2 +#define ESE_DZ_SMC_REQ_DSCR_READ 1 +#define ESE_DZ_SMC_RESP_DSCR_READ 1 +#define ESE_DZ_SMC_REQ_BUFTBL_LOOKUP 0 +#define ESE_DZ_SMC_RESP_BUFTBL_LOOKUP 0 + + +/* ES_SMC_MSG_BUFTBL_LOOKUP_REQ */ +#define ESF_DZ_MC2S_BL_BUF_ID_LBN 28 +#define ESF_DZ_MC2S_BL_BUF_ID_WIDTH 18 +#define ESF_DZ_MC2S_BL_EXP_PAGE_SIZE_LBN 24 +#define ESF_DZ_MC2S_BL_EXP_PAGE_SIZE_WIDTH 4 +#define ESE_DZ_SMC_PAGE_SIZE_4M 10 +#define ESE_DZ_SMC_PAGE_SIZE_1M 8 +#define ESE_DZ_SMC_PAGE_SIZE_64K 4 +#define ESE_DZ_SMC_PAGE_SIZE_4K 0 +#define ESF_DZ_MC2S_BL_EXP_OWNER_ID_LBN 12 +#define ESF_DZ_MC2S_BL_EXP_OWNER_ID_WIDTH 12 +#define ESF_DZ_MC2S_BL_REFLECT_LBN 11 +#define ESF_DZ_MC2S_BL_REFLECT_WIDTH 1 +#define ESF_DZ_MC2S_BL_SOFT_LBN 7 +#define ESF_DZ_MC2S_BL_SOFT_WIDTH 4 +#define ESF_DZ_MC2S_BL_CLIENT_ID_LBN 3 +#define ESF_DZ_MC2S_BL_CLIENT_ID_WIDTH 4 +#define ESE_DZ_SMC_MACRO_ENGINE_ID 15 +#define ESE_DZ_SMC_TX_DICPU_ID 14 +#define ESE_DZ_SMC_RX_DICPU_ID 13 +#define ESE_DZ_SMC_MC_ID 12 +#define ESE_DZ_SMC_DL_ID 10 +#define ESE_DZ_SMC_EV_ID 8 +#define ESE_DZ_SMC_TX_DPCPU1_ID 5 +#define ESE_DZ_SMC_TX_DPCPU0_ID 4 +#define ESE_DZ_SMC_RX_DPCPU_ID 0 +#define ESF_DZ_MC2S_BL_OP_LBN 0 +#define ESF_DZ_MC2S_BL_OP_WIDTH 3 +#define ESE_DZ_SMC_REQ_WR 4 +#define ESE_DZ_SMC_REQ_RD 3 +#define ESE_DZ_SMC_REQ_DSCR_WRITE 2 +#define ESE_DZ_SMC_REQ_DSCR_READ 1 +#define ESE_DZ_SMC_REQ_BUFTBL_LOOKUP 0 + + +/* ES_SMC_MSG_BUFTBL_LOOKUP_RESP */ +#define ESF_DZ_S2MC_BL_BUFTBL_ENTRY_DW0_LBN 12 +#define ESF_DZ_S2MC_BL_BUFTBL_ENTRY_DW0_WIDTH 32 +#define ESF_DZ_S2MC_BL_BUFTBL_ENTRY_DW1_LBN 44 +#define ESF_DZ_S2MC_BL_BUFTBL_ENTRY_DW1_WIDTH 4 +#define ESF_DZ_S2MC_BL_BUFTBL_ENTRY_LBN 12 +#define ESF_DZ_S2MC_BL_BUFTBL_ENTRY_WIDTH 36 +#define ESF_DZ_S2MC_BL_FAIL_LBN 11 +#define ESF_DZ_S2MC_BL_FAIL_WIDTH 1 +#define ESF_DZ_S2MC_BL_SOFT_LBN 7 +#define ESF_DZ_S2MC_BL_SOFT_WIDTH 4 +#define ESF_DZ_S2MC_BL_CLIENT_ID_LBN 3 +#define ESF_DZ_S2MC_BL_CLIENT_ID_WIDTH 4 +#define ESE_DZ_SMC_MACRO_ENGINE_ID 15 +#define ESE_DZ_SMC_TX_DICPU_ID 14 +#define ESE_DZ_SMC_RX_DICPU_ID 13 +#define ESE_DZ_SMC_MC_ID 12 +#define ESE_DZ_SMC_DL_ID 10 +#define ESE_DZ_SMC_EV_ID 8 +#define ESE_DZ_SMC_TX_DPCPU1_ID 5 +#define ESE_DZ_SMC_TX_DPCPU0_ID 4 +#define ESE_DZ_SMC_RX_DPCPU_ID 0 +#define ESF_DZ_S2MC_BL_OP_LBN 0 +#define ESF_DZ_S2MC_BL_OP_WIDTH 3 +#define ESE_DZ_SMC_REQ_WR 4 +#define ESE_DZ_SMC_REQ_RD 3 +#define ESE_DZ_SMC_REQ_DSCR_WRITE 2 +#define ESE_DZ_SMC_REQ_DSCR_READ 1 +#define ESE_DZ_SMC_REQ_BUFTBL_LOOKUP 0 + + +/* ES_SMC_MSG_DSCR_RD_REQ */ +#define ESF_DZ_MC2S_DR_DSCR_OFST_LBN 24 +#define ESF_DZ_MC2S_DR_DSCR_OFST_WIDTH 6 +#define ESF_DZ_MC2S_DR_QID_LBN 13 +#define ESF_DZ_MC2S_DR_QID_WIDTH 11 +#define ESF_DZ_MC2S_DR_IS_TX_LBN 12 +#define ESF_DZ_MC2S_DR_IS_TX_WIDTH 1 +#define ESF_DZ_MC2S_DR_REFLECT_LBN 11 +#define ESF_DZ_MC2S_DR_REFLECT_WIDTH 1 +#define ESF_DZ_MC2S_DR_SOFT_LBN 7 +#define ESF_DZ_MC2S_DR_SOFT_WIDTH 4 +#define ESF_DZ_MC2S_DR_CLIENT_ID_LBN 3 +#define ESF_DZ_MC2S_DR_CLIENT_ID_WIDTH 4 +#define ESE_DZ_SMC_MACRO_ENGINE_ID 15 +#define ESE_DZ_SMC_TX_DICPU_ID 14 +#define ESE_DZ_SMC_RX_DICPU_ID 13 +#define ESE_DZ_SMC_MC_ID 12 +#define ESE_DZ_SMC_DL_ID 10 +#define ESE_DZ_SMC_EV_ID 8 +#define ESE_DZ_SMC_TX_DPCPU1_ID 5 +#define ESE_DZ_SMC_TX_DPCPU0_ID 4 +#define ESE_DZ_SMC_RX_DPCPU_ID 0 +#define ESF_DZ_MC2S_DR_OP_LBN 0 +#define ESF_DZ_MC2S_DR_OP_WIDTH 3 +#define ESE_DZ_SMC_REQ_WR 4 +#define ESE_DZ_SMC_REQ_RD 3 +#define ESE_DZ_SMC_REQ_DSCR_WRITE 2 +#define ESE_DZ_SMC_REQ_DSCR_READ 1 +#define ESE_DZ_SMC_REQ_BUFTBL_LOOKUP 0 + + +/* ES_SMC_MSG_DSCR_RD_RESP */ +#define ESF_DZ_S2MC_DR_DSCR_DW0_LBN 12 +#define ESF_DZ_S2MC_DR_DSCR_DW0_WIDTH 32 +#define ESF_DZ_S2MC_DR_DSCR_DW1_LBN 44 +#define ESF_DZ_S2MC_DR_DSCR_DW1_WIDTH 32 +#define ESF_DZ_S2MC_DR_DSCR_LBN 12 +#define ESF_DZ_S2MC_DR_DSCR_WIDTH 64 +#define ESF_DZ_S2MC_DR_FAIL_LBN 11 +#define ESF_DZ_S2MC_DR_FAIL_WIDTH 1 +#define ESF_DZ_S2MC_DR_SOFT_LBN 7 +#define ESF_DZ_S2MC_DR_SOFT_WIDTH 4 +#define ESF_DZ_S2MC_DR_CLIENT_ID_LBN 3 +#define ESF_DZ_S2MC_DR_CLIENT_ID_WIDTH 4 +#define ESE_DZ_SMC_MACRO_ENGINE_ID 15 +#define ESE_DZ_SMC_TX_DICPU_ID 14 +#define ESE_DZ_SMC_RX_DICPU_ID 13 +#define ESE_DZ_SMC_MC_ID 12 +#define ESE_DZ_SMC_DL_ID 10 +#define ESE_DZ_SMC_EV_ID 8 +#define ESE_DZ_SMC_TX_DPCPU1_ID 5 +#define ESE_DZ_SMC_TX_DPCPU0_ID 4 +#define ESE_DZ_SMC_RX_DPCPU_ID 0 +#define ESF_DZ_S2MC_DR_OP_LBN 0 +#define ESF_DZ_S2MC_DR_OP_WIDTH 3 +#define ESE_DZ_SMC_REQ_WR 4 +#define ESE_DZ_SMC_REQ_RD 3 +#define ESE_DZ_SMC_REQ_DSCR_WRITE 2 +#define ESE_DZ_SMC_REQ_DSCR_READ 1 +#define ESE_DZ_SMC_REQ_BUFTBL_LOOKUP 0 + + +/* ES_SMC_MSG_DSCR_WR_REQ */ +#define ESF_DZ_MC2S_DW_DSCR_DW0_LBN 30 +#define ESF_DZ_MC2S_DW_DSCR_DW0_WIDTH 32 +#define ESF_DZ_MC2S_DW_DSCR_DW1_LBN 62 +#define ESF_DZ_MC2S_DW_DSCR_DW1_WIDTH 32 +#define ESF_DZ_MC2S_DW_DSCR_LBN 30 +#define ESF_DZ_MC2S_DW_DSCR_WIDTH 64 +#define ESF_DZ_MC2S_DW_DSCR_OFST_LBN 24 +#define ESF_DZ_MC2S_DW_DSCR_OFST_WIDTH 6 +#define ESF_DZ_MC2S_DW_QID_LBN 13 +#define ESF_DZ_MC2S_DW_QID_WIDTH 11 +#define ESF_DZ_MC2S_DW_IS_TX_LBN 12 +#define ESF_DZ_MC2S_DW_IS_TX_WIDTH 1 +#define ESF_DZ_MC2S_DW_REFLECT_LBN 11 +#define ESF_DZ_MC2S_DW_REFLECT_WIDTH 1 +#define ESF_DZ_MC2S_DW_SOFT_LBN 7 +#define ESF_DZ_MC2S_DW_SOFT_WIDTH 4 +#define ESF_DZ_MC2S_DW_CLIENT_ID_LBN 3 +#define ESF_DZ_MC2S_DW_CLIENT_ID_WIDTH 4 +#define ESE_DZ_SMC_MACRO_ENGINE_ID 15 +#define ESE_DZ_SMC_TX_DICPU_ID 14 +#define ESE_DZ_SMC_RX_DICPU_ID 13 +#define ESE_DZ_SMC_MC_ID 12 +#define ESE_DZ_SMC_DL_ID 10 +#define ESE_DZ_SMC_EV_ID 8 +#define ESE_DZ_SMC_TX_DPCPU1_ID 5 +#define ESE_DZ_SMC_TX_DPCPU0_ID 4 +#define ESE_DZ_SMC_RX_DPCPU_ID 0 +#define ESF_DZ_MC2S_DW_OP_LBN 0 +#define ESF_DZ_MC2S_DW_OP_WIDTH 3 +#define ESE_DZ_SMC_REQ_WR 4 +#define ESE_DZ_SMC_REQ_RD 3 +#define ESE_DZ_SMC_REQ_DSCR_WRITE 2 +#define ESE_DZ_SMC_REQ_DSCR_READ 1 +#define ESE_DZ_SMC_REQ_BUFTBL_LOOKUP 0 + + +/* ES_SMC_MSG_DSCR_WR_RESP */ +#define ESF_DZ_S2MC_DW_FAIL_LBN 11 +#define ESF_DZ_S2MC_DW_FAIL_WIDTH 1 +#define ESF_DZ_S2MC_DW_SOFT_LBN 7 +#define ESF_DZ_S2MC_DW_SOFT_WIDTH 4 +#define ESF_DZ_S2MC_DW_CLIENT_ID_LBN 3 +#define ESF_DZ_S2MC_DW_CLIENT_ID_WIDTH 4 +#define ESE_DZ_SMC_MACRO_ENGINE_ID 15 +#define ESE_DZ_SMC_TX_DICPU_ID 14 +#define ESE_DZ_SMC_RX_DICPU_ID 13 +#define ESE_DZ_SMC_MC_ID 12 +#define ESE_DZ_SMC_DL_ID 10 +#define ESE_DZ_SMC_EV_ID 8 +#define ESE_DZ_SMC_TX_DPCPU1_ID 5 +#define ESE_DZ_SMC_TX_DPCPU0_ID 4 +#define ESE_DZ_SMC_RX_DPCPU_ID 0 +#define ESF_DZ_S2MC_DW_OP_LBN 0 +#define ESF_DZ_S2MC_DW_OP_WIDTH 3 +#define ESE_DZ_SMC_REQ_WR 4 +#define ESE_DZ_SMC_REQ_RD 3 +#define ESE_DZ_SMC_REQ_DSCR_WRITE 2 +#define ESE_DZ_SMC_REQ_DSCR_READ 1 +#define ESE_DZ_SMC_REQ_BUFTBL_LOOKUP 0 + + +/* ES_SMC_MSG_RD_REQ */ +#define ESF_DZ_MC2S_RD_ADDR_LBN 12 +#define ESF_DZ_MC2S_RD_ADDR_WIDTH 17 +#define ESF_DZ_MC2S_RD_REFLECT_LBN 11 +#define ESF_DZ_MC2S_RD_REFLECT_WIDTH 1 +#define ESF_DZ_MC2S_RD_SOFT_LBN 7 +#define ESF_DZ_MC2S_RD_SOFT_WIDTH 4 +#define ESF_DZ_MC2S_RD_CLIENT_ID_LBN 3 +#define ESF_DZ_MC2S_RD_CLIENT_ID_WIDTH 4 +#define ESE_DZ_SMC_MACRO_ENGINE_ID 15 +#define ESE_DZ_SMC_TX_DICPU_ID 14 +#define ESE_DZ_SMC_RX_DICPU_ID 13 +#define ESE_DZ_SMC_MC_ID 12 +#define ESE_DZ_SMC_DL_ID 10 +#define ESE_DZ_SMC_EV_ID 8 +#define ESE_DZ_SMC_TX_DPCPU1_ID 5 +#define ESE_DZ_SMC_TX_DPCPU0_ID 4 +#define ESE_DZ_SMC_RX_DPCPU_ID 0 +#define ESF_DZ_MC2S_RD_OP_LBN 0 +#define ESF_DZ_MC2S_RD_OP_WIDTH 3 +#define ESE_DZ_SMC_REQ_WR 4 +#define ESE_DZ_SMC_REQ_RD 3 +#define ESE_DZ_SMC_REQ_DSCR_WRITE 2 +#define ESE_DZ_SMC_REQ_DSCR_READ 1 +#define ESE_DZ_SMC_REQ_BUFTBL_LOOKUP 0 + + +/* ES_SMC_MSG_RD_RESP */ +#define ESF_DZ_S2MC_RD_DATA_DW0_LBN 12 +#define ESF_DZ_S2MC_RD_DATA_DW0_WIDTH 32 +#define ESF_DZ_S2MC_RD_DATA_DW1_LBN 44 +#define ESF_DZ_S2MC_RD_DATA_DW1_WIDTH 32 +#define ESF_DZ_S2MC_RD_DATA_DW2_LBN 76 +#define ESF_DZ_S2MC_RD_DATA_DW2_WIDTH 8 +#define ESF_DZ_S2MC_RD_DATA_LBN 12 +#define ESF_DZ_S2MC_RD_DATA_WIDTH 72 +#define ESF_DZ_S2MC_RD_FAIL_LBN 11 +#define ESF_DZ_S2MC_RD_FAIL_WIDTH 1 +#define ESF_DZ_S2MC_RD_SOFT_LBN 7 +#define ESF_DZ_S2MC_RD_SOFT_WIDTH 4 +#define ESF_DZ_S2MC_RD_CLIENT_ID_LBN 3 +#define ESF_DZ_S2MC_RD_CLIENT_ID_WIDTH 4 +#define ESE_DZ_SMC_MACRO_ENGINE_ID 15 +#define ESE_DZ_SMC_TX_DICPU_ID 14 +#define ESE_DZ_SMC_RX_DICPU_ID 13 +#define ESE_DZ_SMC_MC_ID 12 +#define ESE_DZ_SMC_DL_ID 10 +#define ESE_DZ_SMC_EV_ID 8 +#define ESE_DZ_SMC_TX_DPCPU1_ID 5 +#define ESE_DZ_SMC_TX_DPCPU0_ID 4 +#define ESE_DZ_SMC_RX_DPCPU_ID 0 +#define ESF_DZ_S2MC_RD_OP_LBN 0 +#define ESF_DZ_S2MC_RD_OP_WIDTH 3 +#define ESE_DZ_SMC_REQ_WR 4 +#define ESE_DZ_SMC_REQ_RD 3 +#define ESE_DZ_SMC_REQ_DSCR_WRITE 2 +#define ESE_DZ_SMC_REQ_DSCR_READ 1 +#define ESE_DZ_SMC_REQ_BUFTBL_LOOKUP 0 + + +/* ES_SMC_MSG_RESP */ +#define ESF_DZ_S2MC_BASE_RSP_DATA_DW0_LBN 12 +#define ESF_DZ_S2MC_BASE_RSP_DATA_DW0_WIDTH 32 +#define ESF_DZ_S2MC_BASE_RSP_DATA_DW1_LBN 44 +#define ESF_DZ_S2MC_BASE_RSP_DATA_DW1_WIDTH 32 +#define ESF_DZ_S2MC_BASE_RSP_DATA_DW2_LBN 76 +#define ESF_DZ_S2MC_BASE_RSP_DATA_DW2_WIDTH 8 +#define ESF_DZ_S2MC_BASE_RSP_DATA_LBN 12 +#define ESF_DZ_S2MC_BASE_RSP_DATA_WIDTH 72 +#define ESF_DZ_S2MC_BASE_FAIL_LBN 11 +#define ESF_DZ_S2MC_BASE_FAIL_WIDTH 1 +#define ESF_DZ_S2MC_BASE_SOFT_LBN 7 +#define ESF_DZ_S2MC_BASE_SOFT_WIDTH 4 +#define ESF_DZ_S2MC_BASE_CLIENT_ID_LBN 3 +#define ESF_DZ_S2MC_BASE_CLIENT_ID_WIDTH 4 +#define ESE_DZ_SMC_MACRO_ENGINE_ID 15 +#define ESE_DZ_SMC_TX_DICPU_ID 14 +#define ESE_DZ_SMC_RX_DICPU_ID 13 +#define ESE_DZ_SMC_MC_ID 12 +#define ESE_DZ_SMC_DL_ID 10 +#define ESE_DZ_SMC_EV_ID 8 +#define ESE_DZ_SMC_TX_DPCPU1_ID 5 +#define ESE_DZ_SMC_TX_DPCPU0_ID 4 +#define ESE_DZ_SMC_RX_DPCPU_ID 0 +#define ESF_DZ_S2MC_BASE_OP_LBN 0 +#define ESF_DZ_S2MC_BASE_OP_WIDTH 3 +#define ESE_DZ_SMC_REQ_WR 4 +#define ESE_DZ_SMC_REQ_RD 3 +#define ESE_DZ_SMC_REQ_DSCR_WRITE 2 +#define ESE_DZ_SMC_REQ_DSCR_READ 1 +#define ESE_DZ_SMC_REQ_BUFTBL_LOOKUP 0 + + +/* ES_SMC_MSG_WR_REQ */ +#define ESF_DZ_MC2S_WR_DATA_DW0_LBN 29 +#define ESF_DZ_MC2S_WR_DATA_DW0_WIDTH 32 +#define ESF_DZ_MC2S_WR_DATA_DW1_LBN 61 +#define ESF_DZ_MC2S_WR_DATA_DW1_WIDTH 32 +#define ESF_DZ_MC2S_WR_DATA_DW2_LBN 93 +#define ESF_DZ_MC2S_WR_DATA_DW2_WIDTH 8 +#define ESF_DZ_MC2S_WR_DATA_LBN 29 +#define ESF_DZ_MC2S_WR_DATA_WIDTH 72 +#define ESF_DZ_MC2S_WR_ADDR_LBN 12 +#define ESF_DZ_MC2S_WR_ADDR_WIDTH 17 +#define ESF_DZ_MC2S_WR_REFLECT_LBN 11 +#define ESF_DZ_MC2S_WR_REFLECT_WIDTH 1 +#define ESF_DZ_MC2S_WR_SOFT_LBN 7 +#define ESF_DZ_MC2S_WR_SOFT_WIDTH 4 +#define ESF_DZ_MC2S_WR_CLIENT_ID_LBN 3 +#define ESF_DZ_MC2S_WR_CLIENT_ID_WIDTH 4 +#define ESE_DZ_SMC_MACRO_ENGINE_ID 15 +#define ESE_DZ_SMC_TX_DICPU_ID 14 +#define ESE_DZ_SMC_RX_DICPU_ID 13 +#define ESE_DZ_SMC_MC_ID 12 +#define ESE_DZ_SMC_DL_ID 10 +#define ESE_DZ_SMC_EV_ID 8 +#define ESE_DZ_SMC_TX_DPCPU1_ID 5 +#define ESE_DZ_SMC_TX_DPCPU0_ID 4 +#define ESE_DZ_SMC_RX_DPCPU_ID 0 +#define ESF_DZ_MC2S_WR_OP_LBN 0 +#define ESF_DZ_MC2S_WR_OP_WIDTH 3 +#define ESE_DZ_SMC_REQ_WR 4 +#define ESE_DZ_SMC_REQ_RD 3 +#define ESE_DZ_SMC_REQ_DSCR_WRITE 2 +#define ESE_DZ_SMC_REQ_DSCR_READ 1 +#define ESE_DZ_SMC_REQ_BUFTBL_LOOKUP 0 + + +/* ES_SMC_MSG_WR_RESP */ +#define ESF_DZ_S2MC_WR_FAIL_LBN 11 +#define ESF_DZ_S2MC_WR_FAIL_WIDTH 1 +#define ESF_DZ_S2MC_WR_SOFT_LBN 7 +#define ESF_DZ_S2MC_WR_SOFT_WIDTH 4 +#define ESF_DZ_S2MC_WR_CLIENT_ID_LBN 3 +#define ESF_DZ_S2MC_WR_CLIENT_ID_WIDTH 4 +#define ESE_DZ_SMC_MACRO_ENGINE_ID 15 +#define ESE_DZ_SMC_TX_DICPU_ID 14 +#define ESE_DZ_SMC_RX_DICPU_ID 13 +#define ESE_DZ_SMC_MC_ID 12 +#define ESE_DZ_SMC_DL_ID 10 +#define ESE_DZ_SMC_EV_ID 8 +#define ESE_DZ_SMC_TX_DPCPU1_ID 5 +#define ESE_DZ_SMC_TX_DPCPU0_ID 4 +#define ESE_DZ_SMC_RX_DPCPU_ID 0 +#define ESF_DZ_S2MC_WR_OP_LBN 0 +#define ESF_DZ_S2MC_WR_OP_WIDTH 3 +#define ESE_DZ_SMC_REQ_WR 4 +#define ESE_DZ_SMC_REQ_RD 3 +#define ESE_DZ_SMC_REQ_DSCR_WRITE 2 +#define ESE_DZ_SMC_REQ_DSCR_READ 1 +#define ESE_DZ_SMC_REQ_BUFTBL_LOOKUP 0 + + +/* ES_TX_EVENT */ +#define ESF_DZ_TX_CODE_LBN 60 +#define ESF_DZ_TX_CODE_WIDTH 4 +#define ESF_DZ_TX_OVERRIDE_HOLDOFF_LBN 59 +#define ESF_DZ_TX_OVERRIDE_HOLDOFF_WIDTH 1 +#define ESF_DZ_TX_DROP_EVENT_LBN 58 +#define ESF_DZ_TX_DROP_EVENT_WIDTH 1 +#define ESF_DZ_TX_EV_RSVD_LBN 48 +#define ESF_DZ_TX_EV_RSVD_WIDTH 10 +#define ESF_DZ_TX_SOFT2_LBN 32 +#define ESF_DZ_TX_SOFT2_WIDTH 16 +#define ESF_DZ_TX_SOFT1_LBN 24 +#define ESF_DZ_TX_SOFT1_WIDTH 8 +#define ESF_DZ_TX_QLABEL_LBN 16 +#define ESF_DZ_TX_QLABEL_WIDTH 8 +#define ESF_DZ_TX_DESCR_INDX_LBN 0 +#define ESF_DZ_TX_DESCR_INDX_WIDTH 16 + + +/* ES_TX_KER_DESC */ +#define ESF_DZ_TX_KER_TYPE_LBN 63 +#define ESF_DZ_TX_KER_TYPE_WIDTH 1 +#define ESF_DZ_TX_KER_CONT_LBN 62 +#define ESF_DZ_TX_KER_CONT_WIDTH 1 +#define ESF_DZ_TX_KER_BYTE_CNT_LBN 48 +#define ESF_DZ_TX_KER_BYTE_CNT_WIDTH 14 +#define ESF_DZ_TX_KER_BUF_ADDR_DW0_LBN 0 +#define ESF_DZ_TX_KER_BUF_ADDR_DW0_WIDTH 32 +#define ESF_DZ_TX_KER_BUF_ADDR_DW1_LBN 32 +#define ESF_DZ_TX_KER_BUF_ADDR_DW1_WIDTH 16 +#define ESF_DZ_TX_KER_BUF_ADDR_LBN 0 +#define ESF_DZ_TX_KER_BUF_ADDR_WIDTH 48 + + +/* ES_TX_OPTION_DESC */ +#define ESF_DZ_TX_DESC_IS_OPT_LBN 63 +#define ESF_DZ_TX_DESC_IS_OPT_WIDTH 1 +#define ESF_DZ_TX_OPTION_TYPE_LBN 60 +#define ESF_DZ_TX_OPTION_TYPE_WIDTH 3 +#define ESE_DZ_TX_OPTION_DESC_TSO 4 +#define ESE_DZ_TX_OPTION_DESC_CRC_CSUM 0 +#define ESF_DZ_TX_TSO_TCP_FLAGS_LBN 48 +#define ESF_DZ_TX_TSO_TCP_FLAGS_WIDTH 8 +#define ESF_DZ_TX_TSO_TCP_MSS_LBN 32 +#define ESF_DZ_TX_TSO_TCP_MSS_WIDTH 16 +#define ESF_DZ_TX_TSO_TCP_SEQNO_LBN 0 +#define ESF_DZ_TX_TSO_TCP_SEQNO_WIDTH 32 +#define ESF_DZ_TX_OPTION_CRC_MODE_LBN 2 +#define ESF_DZ_TX_OPTION_CRC_MODE_WIDTH 3 +#define ESE_DZ_TX_OPTION_CRC_FCOIP_MPA 5 +#define ESE_DZ_TX_OPTION_CRC_FCOIP_FCOE 4 +#define ESE_DZ_TX_OPTION_CRC_ISCSI_HDR_AND_PYLD 3 +#define ESE_DZ_TX_OPTION_CRC_ISCSI_HDR 2 +#define ESE_DZ_TX_OPTION_CRC_FCOE 1 +#define ESE_DZ_TX_OPTION_CRC_OFF 0 +#define ESF_DZ_TX_OPTION_UDP_TCP_CSUM_LBN 1 +#define ESF_DZ_TX_OPTION_UDP_TCP_CSUM_WIDTH 1 +#define ESF_DZ_TX_OPTION_IP_CSUM_LBN 0 +#define ESF_DZ_TX_OPTION_IP_CSUM_WIDTH 1 + + +/* ES_TX_PACER_BASE_MSG */ +#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_DW0_LBN 11 +#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_DW0_WIDTH 32 +#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_DW1_LBN 43 +#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_DW1_WIDTH 32 +#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_DW2_LBN 75 +#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_DW2_WIDTH 23 +#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_LBN 11 +#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_WIDTH 87 +#define ESF_DZ_TXP_BASE_OP_LBN 2 +#define ESF_DZ_TXP_BASE_OP_WIDTH 3 +#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7 +#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6 +#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5 +#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4 +#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3 +#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2 +#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1 +#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0 +#define ESF_DZ_TXP_BASE_CLIENT_ID_LBN 0 +#define ESF_DZ_TXP_BASE_CLIENT_ID_WIDTH 2 +#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2 +#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1 +#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0 + + +/* ES_TX_PACER_BKT_D_R_REQ */ +#define ESF_DZ_TXP_BKT_D_R_REQ_FRM_LEN_LBN 45 +#define ESF_DZ_TXP_BKT_D_R_REQ_FRM_LEN_WIDTH 14 +#define ESF_DZ_TXP_BKT_D_R_REQ_MAX_BKT2_LBN 35 +#define ESF_DZ_TXP_BKT_D_R_REQ_MAX_BKT2_WIDTH 10 +#define ESF_DZ_TXP_BKT_D_R_REQ_MAX_BKT1_LBN 25 +#define ESF_DZ_TXP_BKT_D_R_REQ_MAX_BKT1_WIDTH 10 +#define ESF_DZ_TXP_BKT_D_R_REQ_MAX_BKT0_LBN 15 +#define ESF_DZ_TXP_BKT_D_R_REQ_MAX_BKT0_WIDTH 10 +#define ESF_DZ_TXP_BKT_D_R_REQ_MIN_BKT_LBN 5 +#define ESF_DZ_TXP_BKT_D_R_REQ_MIN_BKT_WIDTH 10 +#define ESF_DZ_TXP_BKT_D_R_REQ_OP_LBN 2 +#define ESF_DZ_TXP_BKT_D_R_REQ_OP_WIDTH 3 +#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7 +#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6 +#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5 +#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4 +#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3 +#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2 +#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1 +#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0 +#define ESF_DZ_TXP_BKT_D_R_REQ_CLIENT_ID_LBN 0 +#define ESF_DZ_TXP_BKT_D_R_REQ_CLIENT_ID_WIDTH 2 +#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2 +#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1 +#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0 + + +/* ES_TX_PACER_BKT_TBL_D_R_RSP */ +#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_DUE_TIME_WITH_MIN_BKT_LBN 21 +#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_DUE_TIME_WITH_MIN_BKT_WIDTH 26 +#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_DUE_TIME_LBN 5 +#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_DUE_TIME_WIDTH 16 +#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_OP_LBN 2 +#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_OP_WIDTH 3 +#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7 +#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6 +#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5 +#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4 +#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3 +#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2 +#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1 +#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0 +#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_CLIENT_ID_LBN 0 +#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_CLIENT_ID_WIDTH 2 +#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2 +#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1 +#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0 + + +/* ES_TX_PACER_BKT_TBL_RD_REQ */ +#define ESF_DZ_TXP_BKT_TBL_RD_REQ_BKT_ID_LBN 5 +#define ESF_DZ_TXP_BKT_TBL_RD_REQ_BKT_ID_WIDTH 10 +#define ESF_DZ_TXP_BKT_TBL_RD_REQ_OP_LBN 2 +#define ESF_DZ_TXP_BKT_TBL_RD_REQ_OP_WIDTH 3 +#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7 +#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6 +#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5 +#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4 +#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3 +#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2 +#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1 +#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0 +#define ESF_DZ_TXP_BKT_TBL_RD_REQ_CLIENT_ID_LBN 0 +#define ESF_DZ_TXP_BKT_TBL_RD_REQ_CLIENT_ID_WIDTH 2 +#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2 +#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1 +#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0 + + +/* ES_TX_PACER_BKT_TBL_RD_RSP */ +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_IDLE_LBN 97 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_IDLE_WIDTH 1 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_USED_LBN 96 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_USED_WIDTH 1 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_MAX_FILL_REG_LBN 94 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_MAX_FILL_REG_WIDTH 2 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_RATE_REC_LBN 78 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_RATE_REC_WIDTH 16 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_RATE_LBN 62 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_RATE_WIDTH 16 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_FILL_LEVEL_LBN 47 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_FILL_LEVEL_WIDTH 15 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_DUE_TIME_LBN 31 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_DUE_TIME_WIDTH 16 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_LAST_FILL_TIME_LBN 15 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_LAST_FILL_TIME_WIDTH 16 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_BKT_ID_LBN 5 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_BKT_ID_WIDTH 10 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_OP_LBN 2 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_OP_WIDTH 3 +#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7 +#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6 +#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5 +#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4 +#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3 +#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2 +#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1 +#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_CLIENT_ID_LBN 0 +#define ESF_DZ_TXP_BKT_TBL_RD_RSP_CLIENT_ID_WIDTH 2 +#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2 +#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1 +#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0 + + +/* ES_TX_PACER_BKT_TBL_WR_REQ */ +#define ESF_DZ_TXP_BKT_TBL_WR_REQ_IDLE_LBN 65 +#define ESF_DZ_TXP_BKT_TBL_WR_REQ_IDLE_WIDTH 1 +#define ESF_DZ_TXP_BKT_TBL_WR_REQ_USED_LBN 64 +#define ESF_DZ_TXP_BKT_TBL_WR_REQ_USED_WIDTH 1 +#define ESF_DZ_TXP_BKT_TBL_WR_REQ_MAX_FILL_REG_LBN 62 +#define ESF_DZ_TXP_BKT_TBL_WR_REQ_MAX_FILL_REG_WIDTH 2 +#define ESF_DZ_TXP_BKT_TBL_WR_REQ_RATE_REC_LBN 46 +#define ESF_DZ_TXP_BKT_TBL_WR_REQ_RATE_REC_WIDTH 16 +#define ESF_DZ_TXP_BKT_TBL_WR_REQ_RATE_LBN 30 +#define ESF_DZ_TXP_BKT_TBL_WR_REQ_RATE_WIDTH 16 +#define ESF_DZ_TXP_BKT_TBL_WR_REQ_FILL_LEVEL_LBN 15 +#define ESF_DZ_TXP_BKT_TBL_WR_REQ_FILL_LEVEL_WIDTH 15 +#define ESF_DZ_TXP_BKT_TBL_WR_REQ_BKT_ID_LBN 5 +#define ESF_DZ_TXP_BKT_TBL_WR_REQ_BKT_ID_WIDTH 10 +#define ESF_DZ_TXP_BKT_TBL_WR_REQ_OP_LBN 2 +#define ESF_DZ_TXP_BKT_TBL_WR_REQ_OP_WIDTH 3 +#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7 +#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6 +#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5 +#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4 +#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3 +#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2 +#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1 +#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0 +#define ESF_DZ_TXP_BKT_TBL_WR_REQ_CLIENT_ID_LBN 0 +#define ESF_DZ_TXP_BKT_TBL_WR_REQ_CLIENT_ID_WIDTH 2 +#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2 +#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1 +#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0 + + +/* ES_TX_PACER_TXQ_D_R_I_REQ */ +#define ESF_DZ_TXP_TXQ_D_R_I_REQ_FRM_LEN_LBN 15 +#define ESF_DZ_TXP_TXQ_D_R_I_REQ_FRM_LEN_WIDTH 14 +#define ESF_DZ_TXP_TXQ_D_R_I_REQ_TXQ_ID_LBN 5 +#define ESF_DZ_TXP_TXQ_D_R_I_REQ_TXQ_ID_WIDTH 10 +#define ESF_DZ_TXP_TXQ_D_R_I_REQ_OP_LBN 2 +#define ESF_DZ_TXP_TXQ_D_R_I_REQ_OP_WIDTH 3 +#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7 +#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6 +#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5 +#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4 +#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3 +#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2 +#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1 +#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0 +#define ESF_DZ_TXP_TXQ_D_R_I_REQ_CLIENT_ID_LBN 0 +#define ESF_DZ_TXP_TXQ_D_R_I_REQ_CLIENT_ID_WIDTH 2 +#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2 +#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1 +#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0 + + +/* ES_TX_PACER_TXQ_TBL_RD_REQ */ +#define ESF_DZ_TXP_TXQ_TBL_RD_REQ_TXQ_ID_LBN 5 +#define ESF_DZ_TXP_TXQ_TBL_RD_REQ_TXQ_ID_WIDTH 10 +#define ESF_DZ_TXP_TXQ_TBL_RD_REQ_OP_LBN 2 +#define ESF_DZ_TXP_TXQ_TBL_RD_REQ_OP_WIDTH 3 +#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7 +#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6 +#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5 +#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4 +#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3 +#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2 +#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1 +#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0 +#define ESF_DZ_TXP_TXQ_TBL_RD_REQ_CLIENT_ID_LBN 0 +#define ESF_DZ_TXP_TXQ_TBL_RD_REQ_CLIENT_ID_WIDTH 2 +#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2 +#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1 +#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0 + + +/* ES_TX_PACER_TXQ_TBL_RD_RSP */ +#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MAX_BKT2_LBN 53 +#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MAX_BKT2_WIDTH 10 +#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MAX_BKT1_LBN 43 +#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MAX_BKT1_WIDTH 10 +#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MAX_BKT0_LBN 33 +#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MAX_BKT0_WIDTH 10 +#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MIN_BKT_LBN 23 +#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MIN_BKT_WIDTH 10 +#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_LABEL_LBN 19 +#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_LABEL_WIDTH 4 +#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_PQ_FLAGS_LBN 16 +#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_PQ_FLAGS_WIDTH 3 +#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_DSBL_LBN 15 +#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_DSBL_WIDTH 1 +#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_TXQ_ID_LBN 5 +#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_TXQ_ID_WIDTH 10 +#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_OP_LBN 2 +#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_OP_WIDTH 3 +#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7 +#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6 +#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5 +#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4 +#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3 +#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2 +#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1 +#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0 +#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_CLIENT_ID_LBN 0 +#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_CLIENT_ID_WIDTH 2 +#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2 +#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1 +#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0 + + +/* ES_TX_PACER_TXQ_TBL_WR_REQ */ +#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MAX_BKT2_LBN 53 +#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MAX_BKT2_WIDTH 10 +#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MAX_BKT1_LBN 43 +#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MAX_BKT1_WIDTH 10 +#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MAX_BKT0_LBN 33 +#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MAX_BKT0_WIDTH 10 +#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MIN_BKT_LBN 23 +#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MIN_BKT_WIDTH 10 +#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_LABEL_LBN 19 +#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_LABEL_WIDTH 4 +#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_PQ_FLAGS_LBN 16 +#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_PQ_FLAGS_WIDTH 3 +#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_DSBL_LBN 15 +#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_DSBL_WIDTH 1 +#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_TXQ_ID_LBN 5 +#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_TXQ_ID_WIDTH 10 +#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_OP_LBN 2 +#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_OP_WIDTH 3 +#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7 +#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6 +#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5 +#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4 +#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3 +#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2 +#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1 +#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0 +#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_CLIENT_ID_LBN 0 +#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_CLIENT_ID_WIDTH 2 +#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2 +#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1 +#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0 + + +/* ES_TX_USER_DESC */ +#define ESF_DZ_TX_USR_TYPE_LBN 63 +#define ESF_DZ_TX_USR_TYPE_WIDTH 1 +#define ESF_DZ_TX_USR_CONT_LBN 62 +#define ESF_DZ_TX_USR_CONT_WIDTH 1 +#define ESF_DZ_TX_USR_BYTE_CNT_LBN 48 +#define ESF_DZ_TX_USR_BYTE_CNT_WIDTH 14 +#define ESF_DZ_TX_USR_BUF_PAGE_SIZE_LBN 44 +#define ESF_DZ_TX_USR_BUF_PAGE_SIZE_WIDTH 4 +#define ESE_DZ_USR_BUF_PAGE_SZ_4MB 10 +#define ESE_DZ_USR_BUF_PAGE_SZ_1MB 8 +#define ESE_DZ_USR_BUF_PAGE_SZ_64KB 4 +#define ESE_DZ_USR_BUF_PAGE_SZ_4KB 0 +#define ESF_DZ_TX_USR_BUF_ID_OFFSET_DW0_LBN 0 +#define ESF_DZ_TX_USR_BUF_ID_OFFSET_DW0_WIDTH 32 +#define ESF_DZ_TX_USR_BUF_ID_OFFSET_DW1_LBN 32 +#define ESF_DZ_TX_USR_BUF_ID_OFFSET_DW1_WIDTH 12 +#define ESF_DZ_TX_USR_BUF_ID_OFFSET_LBN 0 +#define ESF_DZ_TX_USR_BUF_ID_OFFSET_WIDTH 44 +#define ESF_DZ_TX_USR_4KBPS_BUF_ID_LBN 12 +#define ESF_DZ_TX_USR_4KBPS_BUF_ID_WIDTH 32 +#define ESF_DZ_TX_USR_64KBPS_BUF_ID_LBN 16 +#define ESF_DZ_TX_USR_64KBPS_BUF_ID_WIDTH 28 +#define ESF_DZ_TX_USR_1MBPS_BUF_ID_LBN 20 +#define ESF_DZ_TX_USR_1MBPS_BUF_ID_WIDTH 24 +#define ESF_DZ_TX_USR_4MBPS_BUF_ID_LBN 22 +#define ESF_DZ_TX_USR_4MBPS_BUF_ID_WIDTH 22 +#define ESF_DZ_TX_USR_4MBPS_BYTE_OFFSET_LBN 0 +#define ESF_DZ_TX_USR_4MBPS_BYTE_OFFSET_WIDTH 22 +#define ESF_DZ_TX_USR_1MBPS_BYTE_OFFSET_LBN 0 +#define ESF_DZ_TX_USR_1MBPS_BYTE_OFFSET_WIDTH 20 +#define ESF_DZ_TX_USR_64KBPS_BYTE_OFFSET_LBN 0 +#define ESF_DZ_TX_USR_64KBPS_BYTE_OFFSET_WIDTH 16 +#define ESF_DZ_TX_USR_4KBPS_BYTE_OFFSET_LBN 0 +#define ESF_DZ_TX_USR_4KBPS_BYTE_OFFSET_WIDTH 12 + + +/* ES_TX_U_QSTATE_TBL0_ENTRY */ +#define ESF_DZ_TX_U_DC_FILL_LBN 112 +#define ESF_DZ_TX_U_DC_FILL_WIDTH 7 +#define ESF_DZ_TX_U_SOFT7_B1R3_LBN 112 +#define ESF_DZ_TX_U_SOFT7_B1R3_WIDTH 7 +#define ESF_DZ_TX_U_DSCR_HW_RPTR_LBN 96 +#define ESF_DZ_TX_U_DSCR_HW_RPTR_WIDTH 12 +#define ESF_DZ_TX_U_SOFT12_B1R2_LBN 96 +#define ESF_DZ_TX_U_SOFT12_B1R2_WIDTH 12 +#define ESF_DZ_TX_U_DC_RPTR_LBN 80 +#define ESF_DZ_TX_U_DC_RPTR_WIDTH 6 +#define ESF_DZ_TX_U_SOFT6_B1R1_LBN 80 +#define ESF_DZ_TX_U_SOFT6_B1R1_WIDTH 6 +#define ESF_DZ_TX_U_SOFT5_B1R0_LBN 64 +#define ESF_DZ_TX_U_SOFT5_B1R0_WIDTH 5 +#define ESF_DZ_TX_U_PREFETCH_ACTIVE_LBN 66 +#define ESF_DZ_TX_U_PREFETCH_ACTIVE_WIDTH 1 +#define ESF_DZ_TX_U_PREFETCH_PENDING_LBN 65 +#define ESF_DZ_TX_U_PREFETCH_PENDING_WIDTH 1 +#define ESF_DZ_TX_U_DOORBELL_ENABLED_LBN 64 +#define ESF_DZ_TX_U_DOORBELL_ENABLED_WIDTH 1 +#define ESF_DZ_TX_U_UPD_UDPTCP_CSUM_MODE_LBN 33 +#define ESF_DZ_TX_U_UPD_UDPTCP_CSUM_MODE_WIDTH 1 +#define ESF_DZ_TX_U_SOFT2_B0R2_LBN 32 +#define ESF_DZ_TX_U_SOFT2_B0R2_WIDTH 2 +#define ESF_DZ_TX_U_UPD_IP_CSUM_MODE_LBN 32 +#define ESF_DZ_TX_U_UPD_IP_CSUM_MODE_WIDTH 1 +#define ESF_DZ_TX_U_UPD_CRC_MODE_LBN 29 +#define ESF_DZ_TX_U_UPD_CRC_MODE_WIDTH 3 +#define ESE_DZ_C2RIP_FCOIP_MPA 5 +#define ESE_DZ_C2RIP_FCOIP_FCOE 4 +#define ESE_DZ_C2RIP_ISCSI_HDR_AND_PYLD 3 +#define ESE_DZ_C2RIP_ISCSI_HDR 2 +#define ESE_DZ_C2RIP_FCOE 1 +#define ESE_DZ_C2RIP_OFF 0 +#define ESF_DZ_TX_U_SOFT16_B0R1_LBN 16 +#define ESF_DZ_TX_U_SOFT16_B0R1_WIDTH 16 +#define ESF_DZ_TX_U_BIU_ARGS_LBN 16 +#define ESF_DZ_TX_U_BIU_ARGS_WIDTH 13 +#define ESF_DZ_TX_U_EV_QID_LBN 5 +#define ESF_DZ_TX_U_EV_QID_WIDTH 11 +#define ESF_DZ_TX_U_SOFT16_B0R0_LBN 0 +#define ESF_DZ_TX_U_SOFT16_B0R0_WIDTH 16 +#define ESF_DZ_TX_U_EV_QLABEL_LBN 0 +#define ESF_DZ_TX_U_EV_QLABEL_WIDTH 5 + + +/* ES_TX_U_QSTATE_TBL1_ENTRY */ +#define ESF_DZ_TX_U_DSCR_BASE_PAGE_ID_LBN 64 +#define ESF_DZ_TX_U_DSCR_BASE_PAGE_ID_WIDTH 18 +#define ESF_DZ_TX_U_SOFT18_B1R0_LBN 64 +#define ESF_DZ_TX_U_SOFT18_B1R0_WIDTH 18 +#define ESF_DZ_TX_U_SOFT16_B0R3_LBN 48 +#define ESF_DZ_TX_U_SOFT16_B0R3_WIDTH 16 +#define ESF_DZ_TX_U_QUEUE_ENABLED_LBN 49 +#define ESF_DZ_TX_U_QUEUE_ENABLED_WIDTH 1 +#define ESF_DZ_TX_U_FLUSH_PENDING_LBN 48 +#define ESF_DZ_TX_U_FLUSH_PENDING_WIDTH 1 +#define ESF_DZ_TX_U_DSCR_HW_WPTR_LBN 32 +#define ESF_DZ_TX_U_DSCR_HW_WPTR_WIDTH 12 +#define ESF_DZ_TX_U_SOFT12_B0R2_LBN 32 +#define ESF_DZ_TX_U_SOFT12_B0R2_WIDTH 12 +#define ESF_DZ_TX_U_OWNER_ID_LBN 16 +#define ESF_DZ_TX_U_OWNER_ID_WIDTH 12 +#define ESF_DZ_TX_U_SOFT12_B0R1_LBN 16 +#define ESF_DZ_TX_U_SOFT12_B0R1_WIDTH 12 +#define ESF_DZ_TX_U_DSCR_SIZE_LBN 0 +#define ESF_DZ_TX_U_DSCR_SIZE_WIDTH 3 +#define ESF_DZ_TX_U_SOFT3_B0R0_LBN 0 +#define ESF_DZ_TX_U_SOFT3_B0R0_WIDTH 3 + + +/* ES_TX_U_QSTATE_TBL2_ENTRY */ +#define ESF_DZ_TX_FINFO_WRD3_LBN 48 +#define ESF_DZ_TX_FINFO_WRD3_WIDTH 16 +#define ESF_DZ_TX_FINFO_WRD2_LBN 32 +#define ESF_DZ_TX_FINFO_WRD2_WIDTH 16 +#define ESF_DZ_TX_FINFO_WRD1_LBN 16 +#define ESF_DZ_TX_FINFO_WRD1_WIDTH 16 +#define ESF_DZ_TX_FINFO_SRCDST_LBN 0 +#define ESF_DZ_TX_FINFO_SRCDST_WIDTH 16 + + +/* ES_b2t_cpl_rsp */ +#define ESF_DZ_B2T_CPL_RSP_CPL_ECC_LBN 268 +#define ESF_DZ_B2T_CPL_RSP_CPL_ECC_WIDTH 32 +#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW0_LBN 27 +#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW0_WIDTH 32 +#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW1_LBN 59 +#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW1_WIDTH 32 +#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW2_LBN 91 +#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW2_WIDTH 32 +#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW3_LBN 123 +#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW3_WIDTH 32 +#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW4_LBN 155 +#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW4_WIDTH 32 +#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW5_LBN 187 +#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW5_WIDTH 32 +#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW6_LBN 219 +#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW6_WIDTH 32 +#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW7_LBN 251 +#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW7_WIDTH 32 +#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_LBN 27 +#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_WIDTH 256 +#define ESF_DZ_B2T_CPL_RSP_CPL_EOT_LBN 283 +#define ESF_DZ_B2T_CPL_RSP_CPL_EOT_WIDTH -15 +#define ESF_DZ_B2T_CPL_RSP_CPL_ERROR_LBN 26 +#define ESF_DZ_B2T_CPL_RSP_CPL_ERROR_WIDTH 1 +#define ESF_DZ_B2T_CPL_RSP_CPL_LAST_LBN 25 +#define ESF_DZ_B2T_CPL_RSP_CPL_LAST_WIDTH 1 +#define ESF_DZ_B2T_CPL_RSP_CPL_TAG_LBN 19 +#define ESF_DZ_B2T_CPL_RSP_CPL_TAG_WIDTH 6 +#define ESF_DZ_B2T_CPL_RSP_CPL_LEN_LBN 7 +#define ESF_DZ_B2T_CPL_RSP_CPL_LEN_WIDTH 12 +#define ESF_DZ_B2T_CPL_RSP_CPL_ADRS_LBN 0 +#define ESF_DZ_B2T_CPL_RSP_CPL_ADRS_WIDTH 7 + + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_EFX_EF10_REGS_H */ diff --git a/sys/dev/sfxge/common/efx_regs_mcdi.h b/sys/dev/sfxge/common/efx_regs_mcdi.h new file mode 100644 index 000000000000..720770cbee1f --- /dev/null +++ b/sys/dev/sfxge/common/efx_regs_mcdi.h @@ -0,0 +1,2786 @@ +/*- + * Copyright 2008-2011 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*! \cidoxg_firmware_mc_cmd */ + +#ifndef _SIENA_MC_DRIVER_PCOL_H +#define _SIENA_MC_DRIVER_PCOL_H + + +/* Values to be written into FMCR_CZ_RESET_STATE_REG to control boot. */ +/* Power-on reset state */ +#define MC_FW_STATE_POR (1) +/* If this is set in MC_RESET_STATE_REG then it should be + * possible to jump into IMEM without loading code from flash. */ +#define MC_FW_WARM_BOOT_OK (2) +/* The MC main image has started to boot. */ +#define MC_FW_STATE_BOOTING (4) +/* The Scheduler has started. */ +#define MC_FW_STATE_SCHED (8) + +/* Values to be written to the per-port status dword in shared + * memory on reboot and assert */ +#define MC_STATUS_DWORD_REBOOT (0xb007b007) +#define MC_STATUS_DWORD_ASSERT (0xdeaddead) + +/* The current version of the MCDI protocol. + * + * Note that the ROM burnt into the card only talks V0, so at the very + * least every driver must support version 0 and MCDI_PCOL_VERSION + */ +#ifdef WITH_MCDI_V2 +#define MCDI_PCOL_VERSION 2 +#else +#define MCDI_PCOL_VERSION 1 +#endif + +/* Unused commands: 0x23, 0x27, 0x30, 0x31 */ + +/* Unused commands: 0x23, 0x27, 0x30, 0x31 */ + +/** + * MCDI version 1 + * + * Each MCDI request starts with an MCDI_HEADER, which is a 32byte + * structure, filled in by the client. + * + * 0 7 8 16 20 22 23 24 31 + * | CODE | R | LEN | SEQ | Rsvd | E | R | XFLAGS | + * | | | + * | | \--- Response + * | \------- Error + * \------------------------------ Resync (always set) + * + * The client writes it's request into MC shared memory, and rings the + * doorbell. Each request is completed by either by the MC writting + * back into shared memory, or by writting out an event. + * + * All MCDI commands support completion by shared memory response. Each + * request may also contain additional data (accounted for by HEADER.LEN), + * and some response's may also contain additional data (again, accounted + * for by HEADER.LEN). + * + * Some MCDI commands support completion by event, in which any associated + * response data is included in the event. + * + * The protocol requires one response to be delivered for every request, a + * request should not be sent unless the response for the previous request + * has been received (either by polling shared memory, or by receiving + * an event). + */ + +/** Request/Response structure */ +#define MCDI_HEADER_OFST 0 +#define MCDI_HEADER_CODE_LBN 0 +#define MCDI_HEADER_CODE_WIDTH 7 +#define MCDI_HEADER_RESYNC_LBN 7 +#define MCDI_HEADER_RESYNC_WIDTH 1 +#define MCDI_HEADER_DATALEN_LBN 8 +#define MCDI_HEADER_DATALEN_WIDTH 8 +#define MCDI_HEADER_SEQ_LBN 16 +#define MCDI_HEADER_RSVD_LBN 20 +#define MCDI_HEADER_RSVD_WIDTH 2 +#define MCDI_HEADER_SEQ_WIDTH 4 +#define MCDI_HEADER_ERROR_LBN 22 +#define MCDI_HEADER_ERROR_WIDTH 1 +#define MCDI_HEADER_RESPONSE_LBN 23 +#define MCDI_HEADER_RESPONSE_WIDTH 1 +#define MCDI_HEADER_XFLAGS_LBN 24 +#define MCDI_HEADER_XFLAGS_WIDTH 8 +/* Request response using event */ +#define MCDI_HEADER_XFLAGS_EVREQ 0x01 + +/* Maximum number of payload bytes */ +#if MCDI_PCOL_VERSION == 1 +#define MCDI_CTL_SDU_LEN_MAX 0xfc +#elif MCDI_PCOL_VERSION == 2 +#define MCDI_CTL_SDU_LEN_MAX 0x400 +#endif + +/* The MC can generate events for two reasons: + * - To complete a shared memory request if XFLAGS_EVREQ was set + * - As a notification (link state, i2c event), controlled + * via MC_CMD_LOG_CTRL + * + * Both events share a common structure: + * + * 0 32 33 36 44 52 60 + * | Data | Cont | Level | Src | Code | Rsvd | + * | + * \ There is another event pending in this notification + * + * If Code==CMDDONE, then the fields are further interpreted as: + * + * - LEVEL==INFO Command succeded + * - LEVEL==ERR Command failed + * + * 0 8 16 24 32 + * | Seq | Datalen | Errno | Rsvd | + * + * These fields are taken directly out of the standard MCDI header, i.e., + * LEVEL==ERR, Datalen == 0 => Reboot + * + * Events can be squirted out of the UART (using LOG_CTRL) without a + * MCDI header. An event can be distinguished from a MCDI response by + * examining the first byte which is 0xc0. This corresponds to the + * non-existent MCDI command MC_CMD_DEBUG_LOG. + * + * 0 7 8 + * | command | Resync | = 0xc0 + * + * Since the event is written in big-endian byte order, this works + * providing bits 56-63 of the event are 0xc0. + * + * 56 60 63 + * | Rsvd | Code | = 0xc0 + * + * Which means for convenience the event code is 0xc for all MC + * generated events. + */ +#define FSE_AZ_EV_CODE_MCDI_EVRESPONSE 0xc + + +/* Non-existent command target */ +#define MC_CMD_ERR_ENOENT 2 +/* assert() has killed the MC */ +#define MC_CMD_ERR_EINTR 4 +/* Caller does not hold required locks */ +#define MC_CMD_ERR_EACCES 13 +/* Resource is currently unavailable (e.g. lock contention) */ +#define MC_CMD_ERR_EBUSY 16 +/* Invalid argument to target */ +#define MC_CMD_ERR_EINVAL 22 +/* Non-recursive resource is already acquired */ +#define MC_CMD_ERR_EDEADLK 35 +/* Operation not implemented */ +#define MC_CMD_ERR_ENOSYS 38 +/* Operation timed out */ +#define MC_CMD_ERR_ETIME 62 + +#define MC_CMD_ERR_CODE_OFST 0 + +/* We define 8 "escape" commands to allow + for command number space extension */ + +#define MC_CMD_CMD_SPACE_ESCAPE_0 0x78 +#define MC_CMD_CMD_SPACE_ESCAPE_1 0x79 +#define MC_CMD_CMD_SPACE_ESCAPE_2 0x7A +#define MC_CMD_CMD_SPACE_ESCAPE_3 0x7B +#define MC_CMD_CMD_SPACE_ESCAPE_4 0x7C +#define MC_CMD_CMD_SPACE_ESCAPE_5 0x7D +#define MC_CMD_CMD_SPACE_ESCAPE_6 0x7E +#define MC_CMD_CMD_SPACE_ESCAPE_7 0x7F + +/* Vectors in the boot ROM */ +/* Point to the copycode entry point. */ +#define MC_BOOTROM_COPYCODE_VEC (0x7f4) +/* Points to the recovery mode entry point. */ +#define MC_BOOTROM_NOFLASH_VEC (0x7f8) + +/* The command set exported by the boot ROM (MCDI v0) */ +#define MC_CMD_GET_VERSION_V0_SUPPORTED_FUNCS { \ + (1 << MC_CMD_READ32) | \ + (1 << MC_CMD_WRITE32) | \ + (1 << MC_CMD_COPYCODE) | \ + (1 << MC_CMD_GET_VERSION), \ + 0, 0, 0 } + +#define MC_CMD_SENSOR_INFO_OUT_OFFSET_OFST(_x) \ + (MC_CMD_SENSOR_ENTRY_OFST + (_x)) + +#define MC_CMD_DBI_WRITE_IN_ADDRESS_OFST(n) ( \ + (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST+ \ + MC_CMD_DBIWROP_TYPEDEF_ADDRESS_OFST)+ \ + ((n)*MC_CMD_DBIWROP_TYPEDEF_LEN)) + +#define MC_CMD_DBI_WRITE_IN_BYTE_MASK_OFST(n) ( \ + (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST+ \ + MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_OFST)+ \ + ((n)*MC_CMD_DBIWROP_TYPEDEF_LEN)) + +#define MC_CMD_DBI_WRITE_IN_VALUE_OFST(n) ( \ + (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST+ \ + MC_CMD_DBIWROP_TYPEDEF_VALUE_OFST)+ \ + ((n)*MC_CMD_DBIWROP_TYPEDEF_LEN)) + + +#ifdef WITH_MCDI_V2 + +/* Version 2 adds an optional argument to error returns: the errno value + * may be followed by the (0-based) number of the first argument that + * could not be processed. + */ +#define MC_CMD_ERR_ARG_OFST 4 + +/* Try again */ +#define MC_CMD_ERR_EAGAIN 11 +/* No space */ +#define MC_CMD_ERR_ENOSPC 28 + +#endif + +/* MCDI_EVENT structuredef */ +#define MCDI_EVENT_LEN 8 +#define MCDI_EVENT_CONT_LBN 32 +#define MCDI_EVENT_CONT_WIDTH 1 +#define MCDI_EVENT_LEVEL_LBN 33 +#define MCDI_EVENT_LEVEL_WIDTH 3 +#define MCDI_EVENT_LEVEL_INFO 0x0 /* enum */ +#define MCDI_EVENT_LEVEL_WARN 0x1 /* enum */ +#define MCDI_EVENT_LEVEL_ERR 0x2 /* enum */ +#define MCDI_EVENT_LEVEL_FATAL 0x3 /* enum */ +#define MCDI_EVENT_DATA_OFST 0 +#define MCDI_EVENT_CMDDONE_SEQ_LBN 0 +#define MCDI_EVENT_CMDDONE_SEQ_WIDTH 8 +#define MCDI_EVENT_CMDDONE_DATALEN_LBN 8 +#define MCDI_EVENT_CMDDONE_DATALEN_WIDTH 8 +#define MCDI_EVENT_CMDDONE_ERRNO_LBN 16 +#define MCDI_EVENT_CMDDONE_ERRNO_WIDTH 8 +#define MCDI_EVENT_LINKCHANGE_LP_CAP_LBN 0 +#define MCDI_EVENT_LINKCHANGE_LP_CAP_WIDTH 16 +#define MCDI_EVENT_LINKCHANGE_SPEED_LBN 16 +#define MCDI_EVENT_LINKCHANGE_SPEED_WIDTH 4 +#define MCDI_EVENT_LINKCHANGE_SPEED_100M 0x1 /* enum */ +#define MCDI_EVENT_LINKCHANGE_SPEED_1G 0x2 /* enum */ +#define MCDI_EVENT_LINKCHANGE_SPEED_10G 0x3 /* enum */ +#define MCDI_EVENT_LINKCHANGE_FCNTL_LBN 20 +#define MCDI_EVENT_LINKCHANGE_FCNTL_WIDTH 4 +#define MCDI_EVENT_LINKCHANGE_LINK_FLAGS_LBN 24 +#define MCDI_EVENT_LINKCHANGE_LINK_FLAGS_WIDTH 8 +#define MCDI_EVENT_SENSOREVT_MONITOR_LBN 0 +#define MCDI_EVENT_SENSOREVT_MONITOR_WIDTH 8 +#define MCDI_EVENT_SENSOREVT_STATE_LBN 8 +#define MCDI_EVENT_SENSOREVT_STATE_WIDTH 8 +#define MCDI_EVENT_SENSOREVT_VALUE_LBN 16 +#define MCDI_EVENT_SENSOREVT_VALUE_WIDTH 16 +#define MCDI_EVENT_FWALERT_DATA_LBN 8 +#define MCDI_EVENT_FWALERT_DATA_WIDTH 24 +#define MCDI_EVENT_FWALERT_REASON_LBN 0 +#define MCDI_EVENT_FWALERT_REASON_WIDTH 8 +#define MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS 0x1 /* enum */ +#define MCDI_EVENT_FLR_VF_LBN 0 +#define MCDI_EVENT_FLR_VF_WIDTH 8 +#define MCDI_EVENT_TX_ERR_TXQ_LBN 0 +#define MCDI_EVENT_TX_ERR_TXQ_WIDTH 12 +#define MCDI_EVENT_TX_ERR_TYPE_LBN 12 +#define MCDI_EVENT_TX_ERR_TYPE_WIDTH 4 +#define MCDI_EVENT_TX_ERR_DL_FAIL 0x1 /* enum */ +#define MCDI_EVENT_TX_ERR_NO_EOP 0x2 /* enum */ +#define MCDI_EVENT_TX_ERR_2BIG 0x3 /* enum */ +#define MCDI_EVENT_TX_ERR_INFO_LBN 16 +#define MCDI_EVENT_TX_ERR_INFO_WIDTH 16 +#define MCDI_EVENT_TX_FLUSH_TXQ_LBN 0 +#define MCDI_EVENT_TX_FLUSH_TXQ_WIDTH 12 +#define MCDI_EVENT_DATA_LBN 0 +#define MCDI_EVENT_DATA_WIDTH 32 +#define MCDI_EVENT_SRC_LBN 36 +#define MCDI_EVENT_SRC_WIDTH 8 +#define MCDI_EVENT_EV_CODE_LBN 60 +#define MCDI_EVENT_EV_CODE_WIDTH 4 +#define MCDI_EVENT_CODE_LBN 44 +#define MCDI_EVENT_CODE_WIDTH 8 +#define MCDI_EVENT_CODE_BADSSERT 0x1 /* enum */ +#define MCDI_EVENT_CODE_PMNOTICE 0x2 /* enum */ +#define MCDI_EVENT_CODE_CMDDONE 0x3 /* enum */ +#define MCDI_EVENT_CODE_LINKCHANGE 0x4 /* enum */ +#define MCDI_EVENT_CODE_SENSOREVT 0x5 /* enum */ +#define MCDI_EVENT_CODE_SCHEDERR 0x6 /* enum */ +#define MCDI_EVENT_CODE_REBOOT 0x7 /* enum */ +#define MCDI_EVENT_CODE_MAC_STATS_DMA 0x8 /* enum */ +#define MCDI_EVENT_CODE_FWALERT 0x9 /* enum */ +#define MCDI_EVENT_CODE_FLR 0xa /* enum */ +#define MCDI_EVENT_CODE_TX_ERR 0xb /* enum */ +#define MCDI_EVENT_CODE_TX_FLUSH 0xc /* enum */ +#define MCDI_EVENT_CMDDONE_DATA_OFST 0 +#define MCDI_EVENT_CMDDONE_DATA_LBN 0 +#define MCDI_EVENT_CMDDONE_DATA_WIDTH 32 +#define MCDI_EVENT_LINKCHANGE_DATA_OFST 0 +#define MCDI_EVENT_LINKCHANGE_DATA_LBN 0 +#define MCDI_EVENT_LINKCHANGE_DATA_WIDTH 32 +#define MCDI_EVENT_SENSOREVT_DATA_OFST 0 +#define MCDI_EVENT_SENSOREVT_DATA_LBN 0 +#define MCDI_EVENT_SENSOREVT_DATA_WIDTH 32 +#define MCDI_EVENT_MAC_STATS_DMA_GENERATION_OFST 0 +#define MCDI_EVENT_MAC_STATS_DMA_GENERATION_LBN 0 +#define MCDI_EVENT_MAC_STATS_DMA_GENERATION_WIDTH 32 +#define MCDI_EVENT_TX_ERR_DATA_OFST 0 +#define MCDI_EVENT_TX_ERR_DATA_LBN 0 +#define MCDI_EVENT_TX_ERR_DATA_WIDTH 32 + + +/***********************************/ +/* MC_CMD_READ32 + * Read multiple 32byte words from MC memory. + */ +#define MC_CMD_READ32 0x1 + +/* MC_CMD_READ32_IN msgrequest */ +#define MC_CMD_READ32_IN_LEN 8 +#define MC_CMD_READ32_IN_ADDR_OFST 0 +#define MC_CMD_READ32_IN_NUMWORDS_OFST 4 + +/* MC_CMD_READ32_OUT msgresponse */ +#define MC_CMD_READ32_OUT_LENMIN 4 +#define MC_CMD_READ32_OUT_LENMAX 252 +#define MC_CMD_READ32_OUT_LEN(num) (0+4*(num)) +#define MC_CMD_READ32_OUT_BUFFER_OFST 0 +#define MC_CMD_READ32_OUT_BUFFER_LEN 4 +#define MC_CMD_READ32_OUT_BUFFER_MINNUM 1 +#define MC_CMD_READ32_OUT_BUFFER_MAXNUM 63 + + +/***********************************/ +/* MC_CMD_WRITE32 + * Write multiple 32byte words to MC memory. + */ +#define MC_CMD_WRITE32 0x2 + +/* MC_CMD_WRITE32_IN msgrequest */ +#define MC_CMD_WRITE32_IN_LENMIN 8 +#define MC_CMD_WRITE32_IN_LENMAX 252 +#define MC_CMD_WRITE32_IN_LEN(num) (4+4*(num)) +#define MC_CMD_WRITE32_IN_ADDR_OFST 0 +#define MC_CMD_WRITE32_IN_BUFFER_OFST 4 +#define MC_CMD_WRITE32_IN_BUFFER_LEN 4 +#define MC_CMD_WRITE32_IN_BUFFER_MINNUM 1 +#define MC_CMD_WRITE32_IN_BUFFER_MAXNUM 62 + +/* MC_CMD_WRITE32_OUT msgresponse */ +#define MC_CMD_WRITE32_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_COPYCODE + * Copy MC code between two locations and jump. + */ +#define MC_CMD_COPYCODE 0x3 + +/* MC_CMD_COPYCODE_IN msgrequest */ +#define MC_CMD_COPYCODE_IN_LEN 16 +#define MC_CMD_COPYCODE_IN_SRC_ADDR_OFST 0 +#define MC_CMD_COPYCODE_IN_DEST_ADDR_OFST 4 +#define MC_CMD_COPYCODE_IN_NUMWORDS_OFST 8 +#define MC_CMD_COPYCODE_IN_JUMP_OFST 12 +#define MC_CMD_COPYCODE_JUMP_NONE 0x1 /* enum */ + +/* MC_CMD_COPYCODE_OUT msgresponse */ +#define MC_CMD_COPYCODE_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_SET_FUNC + */ +#define MC_CMD_SET_FUNC 0x4 + +/* MC_CMD_SET_FUNC_IN msgrequest */ +#define MC_CMD_SET_FUNC_IN_LEN 4 +#define MC_CMD_SET_FUNC_IN_FUNC_OFST 0 + +/* MC_CMD_SET_FUNC_OUT msgresponse */ +#define MC_CMD_SET_FUNC_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_BOOT_STATUS + */ +#define MC_CMD_GET_BOOT_STATUS 0x5 + +/* MC_CMD_GET_BOOT_STATUS_IN msgrequest */ +#define MC_CMD_GET_BOOT_STATUS_IN_LEN 0 + +/* MC_CMD_GET_BOOT_STATUS_OUT msgresponse */ +#define MC_CMD_GET_BOOT_STATUS_OUT_LEN 8 +#define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_OFST 0 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_OFST 4 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_WATCHDOG_LBN 0 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_WATCHDOG_WIDTH 1 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_PRIMARY_LBN 1 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_PRIMARY_WIDTH 1 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_BACKUP_LBN 2 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_BACKUP_WIDTH 1 + + +/***********************************/ +/* MC_CMD_GET_ASSERTS + * Get and clear any assertion status. + */ +#define MC_CMD_GET_ASSERTS 0x6 + +/* MC_CMD_GET_ASSERTS_IN msgrequest */ +#define MC_CMD_GET_ASSERTS_IN_LEN 4 +#define MC_CMD_GET_ASSERTS_IN_CLEAR_OFST 0 + +/* MC_CMD_GET_ASSERTS_OUT msgresponse */ +#define MC_CMD_GET_ASSERTS_OUT_LEN 140 +#define MC_CMD_GET_ASSERTS_OUT_GLOBAL_FLAGS_OFST 0 +#define MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS 0x1 /* enum */ +#define MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL 0x2 /* enum */ +#define MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL 0x3 /* enum */ +#define MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED 0x4 /* enum */ +#define MC_CMD_GET_ASSERTS_OUT_SAVED_PC_OFFS_OFST 4 +#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST 8 +#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_LEN 4 +#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_NUM 31 +#define MC_CMD_GET_ASSERTS_OUT_THREAD_OFFS_OFST 132 +#define MC_CMD_GET_ASSERTS_OUT_RESERVED_OFST 136 + + +/***********************************/ +/* MC_CMD_LOG_CTRL + * Configure the output stream for various events and messages. + */ +#define MC_CMD_LOG_CTRL 0x7 + +/* MC_CMD_LOG_CTRL_IN msgrequest */ +#define MC_CMD_LOG_CTRL_IN_LEN 8 +#define MC_CMD_LOG_CTRL_IN_LOG_DEST_OFST 0 +#define MC_CMD_LOG_CTRL_IN_LOG_DEST_UART 0x1 /* enum */ +#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ 0x2 /* enum */ +#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ_OFST 4 + +/* MC_CMD_LOG_CTRL_OUT msgresponse */ +#define MC_CMD_LOG_CTRL_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_VERSION + * Get version information about the MC firmware. + */ +#define MC_CMD_GET_VERSION 0x8 + +/* MC_CMD_GET_VERSION_IN msgrequest */ +#define MC_CMD_GET_VERSION_IN_LEN 0 + +/* MC_CMD_GET_VERSION_V0_OUT msgresponse */ +#define MC_CMD_GET_VERSION_V0_OUT_LEN 4 +#define MC_CMD_GET_VERSION_OUT_FIRMWARE_OFST 0 +#define MC_CMD_GET_VERSION_OUT_FIRMWARE_ANY 0xffffffff /* enum */ +#define MC_CMD_GET_VERSION_OUT_FIRMWARE_BOOTROM 0xb0070000 /* enum */ + +/* MC_CMD_GET_VERSION_OUT msgresponse */ +#define MC_CMD_GET_VERSION_OUT_LEN 32 +/* MC_CMD_GET_VERSION_OUT_FIRMWARE_OFST 0 */ +/* Enum values, see field(s): */ +/* MC_CMD_GET_VERSION_V0_OUT/MC_CMD_GET_VERSION_OUT_FIRMWARE */ +#define MC_CMD_GET_VERSION_OUT_PCOL_OFST 4 +#define MC_CMD_GET_VERSION_OUT_SUPPORTED_FUNCS_OFST 8 +#define MC_CMD_GET_VERSION_OUT_SUPPORTED_FUNCS_LEN 16 +#define MC_CMD_GET_VERSION_OUT_VERSION_OFST 24 +#define MC_CMD_GET_VERSION_OUT_VERSION_LEN 8 +#define MC_CMD_GET_VERSION_OUT_VERSION_LO_OFST 24 +#define MC_CMD_GET_VERSION_OUT_VERSION_HI_OFST 28 + + +/***********************************/ +/* MC_CMD_CSR_READ32 + * Read 32bit words from the indirect memory map. + */ +#define MC_CMD_CSR_READ32 0xc + +/* MC_CMD_CSR_READ32_IN msgrequest */ +#define MC_CMD_CSR_READ32_IN_LEN 12 +#define MC_CMD_CSR_READ32_IN_ADDR_OFST 0 +#define MC_CMD_CSR_READ32_IN_STEP_OFST 4 +#define MC_CMD_CSR_READ32_IN_NUMWORDS_OFST 8 + +/* MC_CMD_CSR_READ32_OUT msgresponse */ +#define MC_CMD_CSR_READ32_OUT_LENMIN 4 +#define MC_CMD_CSR_READ32_OUT_LENMAX 252 +#define MC_CMD_CSR_READ32_OUT_LEN(num) (0+4*(num)) +#define MC_CMD_CSR_READ32_OUT_BUFFER_OFST 0 +#define MC_CMD_CSR_READ32_OUT_BUFFER_LEN 4 +#define MC_CMD_CSR_READ32_OUT_BUFFER_MINNUM 1 +#define MC_CMD_CSR_READ32_OUT_BUFFER_MAXNUM 63 + + +/***********************************/ +/* MC_CMD_CSR_WRITE32 + * Write 32bit dwords to the indirect memory map. + */ +#define MC_CMD_CSR_WRITE32 0xd + +/* MC_CMD_CSR_WRITE32_IN msgrequest */ +#define MC_CMD_CSR_WRITE32_IN_LENMIN 12 +#define MC_CMD_CSR_WRITE32_IN_LENMAX 252 +#define MC_CMD_CSR_WRITE32_IN_LEN(num) (8+4*(num)) +#define MC_CMD_CSR_WRITE32_IN_ADDR_OFST 0 +#define MC_CMD_CSR_WRITE32_IN_STEP_OFST 4 +#define MC_CMD_CSR_WRITE32_IN_BUFFER_OFST 8 +#define MC_CMD_CSR_WRITE32_IN_BUFFER_LEN 4 +#define MC_CMD_CSR_WRITE32_IN_BUFFER_MINNUM 1 +#define MC_CMD_CSR_WRITE32_IN_BUFFER_MAXNUM 61 + +/* MC_CMD_CSR_WRITE32_OUT msgresponse */ +#define MC_CMD_CSR_WRITE32_OUT_LEN 4 +#define MC_CMD_CSR_WRITE32_OUT_STATUS_OFST 0 + + +/***********************************/ +/* MC_CMD_STACKINFO + * Get stack information. + */ +#define MC_CMD_STACKINFO 0xf + +/* MC_CMD_STACKINFO_IN msgrequest */ +#define MC_CMD_STACKINFO_IN_LEN 0 + +/* MC_CMD_STACKINFO_OUT msgresponse */ +#define MC_CMD_STACKINFO_OUT_LENMIN 12 +#define MC_CMD_STACKINFO_OUT_LENMAX 252 +#define MC_CMD_STACKINFO_OUT_LEN(num) (0+12*(num)) +#define MC_CMD_STACKINFO_OUT_THREAD_INFO_OFST 0 +#define MC_CMD_STACKINFO_OUT_THREAD_INFO_LEN 12 +#define MC_CMD_STACKINFO_OUT_THREAD_INFO_MINNUM 1 +#define MC_CMD_STACKINFO_OUT_THREAD_INFO_MAXNUM 21 + + +/***********************************/ +/* MC_CMD_MDIO_READ + * MDIO register read. + */ +#define MC_CMD_MDIO_READ 0x10 + +/* MC_CMD_MDIO_READ_IN msgrequest */ +#define MC_CMD_MDIO_READ_IN_LEN 16 +#define MC_CMD_MDIO_READ_IN_BUS_OFST 0 +#define MC_CMD_MDIO_BUS_INTERNAL 0x0 /* enum */ +#define MC_CMD_MDIO_BUS_EXTERNAL 0x1 /* enum */ +#define MC_CMD_MDIO_READ_IN_PRTAD_OFST 4 +#define MC_CMD_MDIO_READ_IN_DEVAD_OFST 8 +#define MC_CMD_MDIO_CLAUSE22 0x20 /* enum */ +#define MC_CMD_MDIO_READ_IN_ADDR_OFST 12 + +/* MC_CMD_MDIO_READ_OUT msgresponse */ +#define MC_CMD_MDIO_READ_OUT_LEN 8 +#define MC_CMD_MDIO_READ_OUT_VALUE_OFST 0 +#define MC_CMD_MDIO_READ_OUT_STATUS_OFST 4 +#define MC_CMD_MDIO_STATUS_GOOD 0x8 /* enum */ + + +/***********************************/ +/* MC_CMD_MDIO_WRITE + * MDIO register write. + */ +#define MC_CMD_MDIO_WRITE 0x11 + +/* MC_CMD_MDIO_WRITE_IN msgrequest */ +#define MC_CMD_MDIO_WRITE_IN_LEN 20 +#define MC_CMD_MDIO_WRITE_IN_BUS_OFST 0 +/* MC_CMD_MDIO_BUS_INTERNAL 0x0 */ +/* MC_CMD_MDIO_BUS_EXTERNAL 0x1 */ +#define MC_CMD_MDIO_WRITE_IN_PRTAD_OFST 4 +#define MC_CMD_MDIO_WRITE_IN_DEVAD_OFST 8 +/* MC_CMD_MDIO_CLAUSE22 0x20 */ +#define MC_CMD_MDIO_WRITE_IN_ADDR_OFST 12 +#define MC_CMD_MDIO_WRITE_IN_VALUE_OFST 16 + +/* MC_CMD_MDIO_WRITE_OUT msgresponse */ +#define MC_CMD_MDIO_WRITE_OUT_LEN 4 +#define MC_CMD_MDIO_WRITE_OUT_STATUS_OFST 0 +/* MC_CMD_MDIO_STATUS_GOOD 0x8 */ + + +/***********************************/ +/* MC_CMD_DBI_WRITE + * Write DBI register(s). + */ +#define MC_CMD_DBI_WRITE 0x12 + +/* MC_CMD_DBI_WRITE_IN msgrequest */ +#define MC_CMD_DBI_WRITE_IN_LENMIN 12 +#define MC_CMD_DBI_WRITE_IN_LENMAX 252 +#define MC_CMD_DBI_WRITE_IN_LEN(num) (0+12*(num)) +#define MC_CMD_DBI_WRITE_IN_DBIWROP_OFST 0 +#define MC_CMD_DBI_WRITE_IN_DBIWROP_LEN 12 +#define MC_CMD_DBI_WRITE_IN_DBIWROP_MINNUM 1 +#define MC_CMD_DBI_WRITE_IN_DBIWROP_MAXNUM 21 + +/* MC_CMD_DBI_WRITE_OUT msgresponse */ +#define MC_CMD_DBI_WRITE_OUT_LEN 0 + +/* MC_CMD_DBIWROP_TYPEDEF structuredef */ +#define MC_CMD_DBIWROP_TYPEDEF_LEN 12 +#define MC_CMD_DBIWROP_TYPEDEF_ADDRESS_OFST 0 +#define MC_CMD_DBIWROP_TYPEDEF_ADDRESS_LBN 0 +#define MC_CMD_DBIWROP_TYPEDEF_ADDRESS_WIDTH 32 +#define MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_OFST 4 +#define MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_LBN 32 +#define MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_WIDTH 32 +#define MC_CMD_DBIWROP_TYPEDEF_VALUE_OFST 8 +#define MC_CMD_DBIWROP_TYPEDEF_VALUE_LBN 64 +#define MC_CMD_DBIWROP_TYPEDEF_VALUE_WIDTH 32 + + +/***********************************/ +/* MC_CMD_PORT_READ32 + * Read a 32-bit register from the indirect port register map. + */ +#define MC_CMD_PORT_READ32 0x14 + +/* MC_CMD_PORT_READ32_IN msgrequest */ +#define MC_CMD_PORT_READ32_IN_LEN 4 +#define MC_CMD_PORT_READ32_IN_ADDR_OFST 0 + +/* MC_CMD_PORT_READ32_OUT msgresponse */ +#define MC_CMD_PORT_READ32_OUT_LEN 8 +#define MC_CMD_PORT_READ32_OUT_VALUE_OFST 0 +#define MC_CMD_PORT_READ32_OUT_STATUS_OFST 4 + + +/***********************************/ +/* MC_CMD_PORT_WRITE32 + * Write a 32-bit register to the indirect port register map. + */ +#define MC_CMD_PORT_WRITE32 0x15 + +/* MC_CMD_PORT_WRITE32_IN msgrequest */ +#define MC_CMD_PORT_WRITE32_IN_LEN 8 +#define MC_CMD_PORT_WRITE32_IN_ADDR_OFST 0 +#define MC_CMD_PORT_WRITE32_IN_VALUE_OFST 4 + +/* MC_CMD_PORT_WRITE32_OUT msgresponse */ +#define MC_CMD_PORT_WRITE32_OUT_LEN 4 +#define MC_CMD_PORT_WRITE32_OUT_STATUS_OFST 0 + + +/***********************************/ +/* MC_CMD_PORT_READ128 + * Read a 128-bit register from the indirect port register map. + */ +#define MC_CMD_PORT_READ128 0x16 + +/* MC_CMD_PORT_READ128_IN msgrequest */ +#define MC_CMD_PORT_READ128_IN_LEN 4 +#define MC_CMD_PORT_READ128_IN_ADDR_OFST 0 + +/* MC_CMD_PORT_READ128_OUT msgresponse */ +#define MC_CMD_PORT_READ128_OUT_LEN 20 +#define MC_CMD_PORT_READ128_OUT_VALUE_OFST 0 +#define MC_CMD_PORT_READ128_OUT_VALUE_LEN 16 +#define MC_CMD_PORT_READ128_OUT_STATUS_OFST 16 + + +/***********************************/ +/* MC_CMD_PORT_WRITE128 + * Write a 128-bit register to the indirect port register map. + */ +#define MC_CMD_PORT_WRITE128 0x17 + +/* MC_CMD_PORT_WRITE128_IN msgrequest */ +#define MC_CMD_PORT_WRITE128_IN_LEN 20 +#define MC_CMD_PORT_WRITE128_IN_ADDR_OFST 0 +#define MC_CMD_PORT_WRITE128_IN_VALUE_OFST 4 +#define MC_CMD_PORT_WRITE128_IN_VALUE_LEN 16 + +/* MC_CMD_PORT_WRITE128_OUT msgresponse */ +#define MC_CMD_PORT_WRITE128_OUT_LEN 4 +#define MC_CMD_PORT_WRITE128_OUT_STATUS_OFST 0 + + +/***********************************/ +/* MC_CMD_GET_BOARD_CFG + * Returns the MC firmware configuration structure. + */ +#define MC_CMD_GET_BOARD_CFG 0x18 + +/* MC_CMD_GET_BOARD_CFG_IN msgrequest */ +#define MC_CMD_GET_BOARD_CFG_IN_LEN 0 + +/* MC_CMD_GET_BOARD_CFG_OUT msgresponse */ +#define MC_CMD_GET_BOARD_CFG_OUT_LEN 96 +#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_TYPE_OFST 0 +#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_OFST 4 +#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_LEN 32 +#define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT0_OFST 36 +#define MC_CMD_CAPABILITIES_SMALL_BUF_TBL_LBN 0x0 /* enum */ +#define MC_CMD_CAPABILITIES_SMALL_BUF_TBL_WIDTH 0x1 /* enum */ +#define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT1_OFST 40 +/* Enum values, see field(s): */ +/* CAPABILITIES_PORT0 */ +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_OFST 44 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_LEN 6 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_OFST 50 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_LEN 6 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT0_OFST 56 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT1_OFST 60 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT0_OFST 64 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT1_OFST 68 +#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST 72 +#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN 2 +#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_NUM 12 + + +/***********************************/ +/* MC_CMD_DBI_READX + * Read DBI register(s). + */ +#define MC_CMD_DBI_READX 0x19 + +/* MC_CMD_DBI_READX_IN msgrequest */ +#define MC_CMD_DBI_READX_IN_LENMIN 8 +#define MC_CMD_DBI_READX_IN_LENMAX 248 +#define MC_CMD_DBI_READX_IN_LEN(num) (0+8*(num)) +#define MC_CMD_DBI_READX_IN_DBIRDOP_OFST 0 +#define MC_CMD_DBI_READX_IN_DBIRDOP_LEN 8 +#define MC_CMD_DBI_READX_IN_DBIRDOP_LO_OFST 0 +#define MC_CMD_DBI_READX_IN_DBIRDOP_HI_OFST 4 +#define MC_CMD_DBI_READX_IN_DBIRDOP_MINNUM 1 +#define MC_CMD_DBI_READX_IN_DBIRDOP_MAXNUM 31 + +/* MC_CMD_DBI_READX_OUT msgresponse */ +#define MC_CMD_DBI_READX_OUT_LENMIN 4 +#define MC_CMD_DBI_READX_OUT_LENMAX 252 +#define MC_CMD_DBI_READX_OUT_LEN(num) (0+4*(num)) +#define MC_CMD_DBI_READX_OUT_VALUE_OFST 0 +#define MC_CMD_DBI_READX_OUT_VALUE_LEN 4 +#define MC_CMD_DBI_READX_OUT_VALUE_MINNUM 1 +#define MC_CMD_DBI_READX_OUT_VALUE_MAXNUM 63 + + +/***********************************/ +/* MC_CMD_SET_RAND_SEED + * Set the 16byte seed for the MC psuedo-random generator. + */ +#define MC_CMD_SET_RAND_SEED 0x1a + +/* MC_CMD_SET_RAND_SEED_IN msgrequest */ +#define MC_CMD_SET_RAND_SEED_IN_LEN 16 +#define MC_CMD_SET_RAND_SEED_IN_SEED_OFST 0 +#define MC_CMD_SET_RAND_SEED_IN_SEED_LEN 16 + +/* MC_CMD_SET_RAND_SEED_OUT msgresponse */ +#define MC_CMD_SET_RAND_SEED_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_LTSSM_HIST + * Retrieve the history of the PCIE LTSSM. + */ +#define MC_CMD_LTSSM_HIST 0x1b + +/* MC_CMD_LTSSM_HIST_IN msgrequest */ +#define MC_CMD_LTSSM_HIST_IN_LEN 0 + +/* MC_CMD_LTSSM_HIST_OUT msgresponse */ +#define MC_CMD_LTSSM_HIST_OUT_LENMIN 0 +#define MC_CMD_LTSSM_HIST_OUT_LENMAX 252 +#define MC_CMD_LTSSM_HIST_OUT_LEN(num) (0+4*(num)) +#define MC_CMD_LTSSM_HIST_OUT_DATA_OFST 0 +#define MC_CMD_LTSSM_HIST_OUT_DATA_LEN 4 +#define MC_CMD_LTSSM_HIST_OUT_DATA_MINNUM 0 +#define MC_CMD_LTSSM_HIST_OUT_DATA_MAXNUM 63 + + +/***********************************/ +/* MC_CMD_DRV_ATTACH + * Inform MCPU that this port is managed on the host. + */ +#define MC_CMD_DRV_ATTACH 0x1c + +/* MC_CMD_DRV_ATTACH_IN msgrequest */ +#define MC_CMD_DRV_ATTACH_IN_LEN 8 +#define MC_CMD_DRV_ATTACH_IN_NEW_STATE_OFST 0 +#define MC_CMD_DRV_ATTACH_IN_UPDATE_OFST 4 + +/* MC_CMD_DRV_ATTACH_OUT msgresponse */ +#define MC_CMD_DRV_ATTACH_OUT_LEN 4 +#define MC_CMD_DRV_ATTACH_OUT_OLD_STATE_OFST 0 + + +/***********************************/ +/* MC_CMD_NCSI_PROD + * Trigger an NC-SI event. + */ +#define MC_CMD_NCSI_PROD 0x1d + +/* MC_CMD_NCSI_PROD_IN msgrequest */ +#define MC_CMD_NCSI_PROD_IN_LEN 4 +#define MC_CMD_NCSI_PROD_IN_EVENTS_OFST 0 +#define MC_CMD_NCSI_PROD_LINKCHANGE 0x0 /* enum */ +#define MC_CMD_NCSI_PROD_RESET 0x1 /* enum */ +#define MC_CMD_NCSI_PROD_DRVATTACH 0x2 /* enum */ +#define MC_CMD_NCSI_PROD_IN_LINKCHANGE_LBN 0 +#define MC_CMD_NCSI_PROD_IN_LINKCHANGE_WIDTH 1 +#define MC_CMD_NCSI_PROD_IN_RESET_LBN 1 +#define MC_CMD_NCSI_PROD_IN_RESET_WIDTH 1 +#define MC_CMD_NCSI_PROD_IN_DRVATTACH_LBN 2 +#define MC_CMD_NCSI_PROD_IN_DRVATTACH_WIDTH 1 + +/* MC_CMD_NCSI_PROD_OUT msgresponse */ +#define MC_CMD_NCSI_PROD_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_SHMUART + * Route UART output to circular buffer in shared memory instead. + */ +#define MC_CMD_SHMUART 0x1f + +/* MC_CMD_SHMUART_IN msgrequest */ +#define MC_CMD_SHMUART_IN_LEN 4 +#define MC_CMD_SHMUART_IN_FLAG_OFST 0 + +/* MC_CMD_SHMUART_OUT msgresponse */ +#define MC_CMD_SHMUART_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_PORT_RESET + * Generic per-port reset. + */ +#define MC_CMD_PORT_RESET 0x20 + +/* MC_CMD_PORT_RESET_IN msgrequest */ +#define MC_CMD_PORT_RESET_IN_LEN 0 + +/* MC_CMD_PORT_RESET_OUT msgresponse */ +#define MC_CMD_PORT_RESET_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_PCIE_CREDITS + * Read instantaneous and minimum flow control thresholds. + */ +#define MC_CMD_PCIE_CREDITS 0x21 + +/* MC_CMD_PCIE_CREDITS_IN msgrequest */ +#define MC_CMD_PCIE_CREDITS_IN_LEN 8 +#define MC_CMD_PCIE_CREDITS_IN_POLL_PERIOD_OFST 0 +#define MC_CMD_PCIE_CREDITS_IN_WIPE_OFST 4 + +/* MC_CMD_PCIE_CREDITS_OUT msgresponse */ +#define MC_CMD_PCIE_CREDITS_OUT_LEN 16 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_P_HDR_OFST 0 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_P_HDR_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_P_DATA_OFST 2 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_P_DATA_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_NP_HDR_OFST 4 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_NP_HDR_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_NP_DATA_OFST 6 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_NP_DATA_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_P_HDR_OFST 8 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_P_HDR_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_P_DATA_OFST 10 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_P_DATA_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_NP_HDR_OFST 12 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_NP_HDR_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_NP_DATA_OFST 14 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_NP_DATA_LEN 2 + + +/***********************************/ +/* MC_CMD_RXD_MONITOR + * Get histogram of RX queue fill level. + */ +#define MC_CMD_RXD_MONITOR 0x22 + +/* MC_CMD_RXD_MONITOR_IN msgrequest */ +#define MC_CMD_RXD_MONITOR_IN_LEN 12 +#define MC_CMD_RXD_MONITOR_IN_QID_OFST 0 +#define MC_CMD_RXD_MONITOR_IN_POLL_PERIOD_OFST 4 +#define MC_CMD_RXD_MONITOR_IN_WIPE_OFST 8 + +/* MC_CMD_RXD_MONITOR_OUT msgresponse */ +#define MC_CMD_RXD_MONITOR_OUT_LEN 80 +#define MC_CMD_RXD_MONITOR_OUT_QID_OFST 0 +#define MC_CMD_RXD_MONITOR_OUT_RING_FILL_OFST 4 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_FILL_OFST 8 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_1_OFST 12 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_2_OFST 16 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_4_OFST 20 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_8_OFST 24 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_16_OFST 28 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_32_OFST 32 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_64_OFST 36 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_128_OFST 40 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_256_OFST 44 +#define MC_CMD_RXD_MONITOR_OUT_RING_GE_256_OFST 48 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_1_OFST 52 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_2_OFST 56 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_4_OFST 60 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_8_OFST 64 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_16_OFST 68 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_32_OFST 72 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_GE_32_OFST 76 + + +/***********************************/ +/* MC_CMD_PUTS + * puts(3) implementation over MCDI + */ +#define MC_CMD_PUTS 0x23 + +/* MC_CMD_PUTS_IN msgrequest */ +#define MC_CMD_PUTS_IN_LENMIN 13 +#define MC_CMD_PUTS_IN_LENMAX 255 +#define MC_CMD_PUTS_IN_LEN(num) (12+1*(num)) +#define MC_CMD_PUTS_IN_DEST_OFST 0 +#define MC_CMD_PUTS_IN_UART_LBN 0 +#define MC_CMD_PUTS_IN_UART_WIDTH 1 +#define MC_CMD_PUTS_IN_PORT_LBN 1 +#define MC_CMD_PUTS_IN_PORT_WIDTH 1 +#define MC_CMD_PUTS_IN_DHOST_OFST 4 +#define MC_CMD_PUTS_IN_DHOST_LEN 6 +#define MC_CMD_PUTS_IN_STRING_OFST 12 +#define MC_CMD_PUTS_IN_STRING_LEN 1 +#define MC_CMD_PUTS_IN_STRING_MINNUM 1 +#define MC_CMD_PUTS_IN_STRING_MAXNUM 243 + +/* MC_CMD_PUTS_OUT msgresponse */ +#define MC_CMD_PUTS_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_PHY_CFG + * Report PHY configuration. + */ +#define MC_CMD_GET_PHY_CFG 0x24 + +/* MC_CMD_GET_PHY_CFG_IN msgrequest */ +#define MC_CMD_GET_PHY_CFG_IN_LEN 0 + +/* MC_CMD_GET_PHY_CFG_OUT msgresponse */ +#define MC_CMD_GET_PHY_CFG_OUT_LEN 72 +#define MC_CMD_GET_PHY_CFG_OUT_FLAGS_OFST 0 +#define MC_CMD_GET_PHY_CFG_OUT_PRESENT_LBN 0 +#define MC_CMD_GET_PHY_CFG_OUT_PRESENT_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN 1 +#define MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN 2 +#define MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_LBN 3 +#define MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_POWEROFF_LBN 4 +#define MC_CMD_GET_PHY_CFG_OUT_POWEROFF_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_TXDIS_LBN 5 +#define MC_CMD_GET_PHY_CFG_OUT_TXDIS_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_BIST_LBN 6 +#define MC_CMD_GET_PHY_CFG_OUT_BIST_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_TYPE_OFST 4 +#define MC_CMD_GET_PHY_CFG_OUT_SUPPORTED_CAP_OFST 8 +#define MC_CMD_PHY_CAP_10HDX_LBN 1 +#define MC_CMD_PHY_CAP_10HDX_WIDTH 1 +#define MC_CMD_PHY_CAP_10FDX_LBN 2 +#define MC_CMD_PHY_CAP_10FDX_WIDTH 1 +#define MC_CMD_PHY_CAP_100HDX_LBN 3 +#define MC_CMD_PHY_CAP_100HDX_WIDTH 1 +#define MC_CMD_PHY_CAP_100FDX_LBN 4 +#define MC_CMD_PHY_CAP_100FDX_WIDTH 1 +#define MC_CMD_PHY_CAP_1000HDX_LBN 5 +#define MC_CMD_PHY_CAP_1000HDX_WIDTH 1 +#define MC_CMD_PHY_CAP_1000FDX_LBN 6 +#define MC_CMD_PHY_CAP_1000FDX_WIDTH 1 +#define MC_CMD_PHY_CAP_10000FDX_LBN 7 +#define MC_CMD_PHY_CAP_10000FDX_WIDTH 1 +#define MC_CMD_PHY_CAP_PAUSE_LBN 8 +#define MC_CMD_PHY_CAP_PAUSE_WIDTH 1 +#define MC_CMD_PHY_CAP_ASYM_LBN 9 +#define MC_CMD_PHY_CAP_ASYM_WIDTH 1 +#define MC_CMD_PHY_CAP_AN_LBN 10 +#define MC_CMD_PHY_CAP_AN_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_CHANNEL_OFST 12 +#define MC_CMD_GET_PHY_CFG_OUT_PRT_OFST 16 +#define MC_CMD_GET_PHY_CFG_OUT_STATS_MASK_OFST 20 +#define MC_CMD_GET_PHY_CFG_OUT_NAME_OFST 24 +#define MC_CMD_GET_PHY_CFG_OUT_NAME_LEN 20 +#define MC_CMD_GET_PHY_CFG_OUT_MEDIA_TYPE_OFST 44 +#define MC_CMD_MEDIA_XAUI 0x1 /* enum */ +#define MC_CMD_MEDIA_CX4 0x2 /* enum */ +#define MC_CMD_MEDIA_KX4 0x3 /* enum */ +#define MC_CMD_MEDIA_XFP 0x4 /* enum */ +#define MC_CMD_MEDIA_SFP_PLUS 0x5 /* enum */ +#define MC_CMD_MEDIA_BASE_T 0x6 /* enum */ +#define MC_CMD_GET_PHY_CFG_OUT_MMD_MASK_OFST 48 +#define MC_CMD_MMD_CLAUSE22 0x0 /* enum */ +#define MC_CMD_MMD_CLAUSE45_PMAPMD 0x1 /* enum */ +#define MC_CMD_MMD_CLAUSE45_WIS 0x2 /* enum */ +#define MC_CMD_MMD_CLAUSE45_PCS 0x3 /* enum */ +#define MC_CMD_MMD_CLAUSE45_PHYXS 0x4 /* enum */ +#define MC_CMD_MMD_CLAUSE45_DTEXS 0x5 /* enum */ +#define MC_CMD_MMD_CLAUSE45_TC 0x6 /* enum */ +#define MC_CMD_MMD_CLAUSE45_AN 0x7 /* enum */ +#define MC_CMD_MMD_CLAUSE45_C22EXT 0x1d /* enum */ +#define MC_CMD_MMD_CLAUSE45_VEND1 0x1e /* enum */ +#define MC_CMD_MMD_CLAUSE45_VEND2 0x1f /* enum */ +#define MC_CMD_GET_PHY_CFG_OUT_REVISION_OFST 52 +#define MC_CMD_GET_PHY_CFG_OUT_REVISION_LEN 20 + + +/***********************************/ +/* MC_CMD_START_BIST + * Start a BIST test on the PHY. + */ +#define MC_CMD_START_BIST 0x25 + +/* MC_CMD_START_BIST_IN msgrequest */ +#define MC_CMD_START_BIST_IN_LEN 4 +#define MC_CMD_START_BIST_IN_TYPE_OFST 0 +#define MC_CMD_PHY_BIST_CABLE_SHORT 0x1 /* enum */ +#define MC_CMD_PHY_BIST_CABLE_LONG 0x2 /* enum */ +#define MC_CMD_BPX_SERDES_BIST 0x3 /* enum */ +#define MC_CMD_MC_LOOPBACK_BIST 0x4 /* enum */ +#define MC_CMD_PHY_BIST 0x5 /* enum */ + +/* MC_CMD_START_BIST_OUT msgresponse */ +#define MC_CMD_START_BIST_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_POLL_BIST + * Poll for BIST completion. + */ +#define MC_CMD_POLL_BIST 0x26 + +/* MC_CMD_POLL_BIST_IN msgrequest */ +#define MC_CMD_POLL_BIST_IN_LEN 0 + +/* MC_CMD_POLL_BIST_OUT msgresponse */ +#define MC_CMD_POLL_BIST_OUT_LEN 8 +#define MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 +#define MC_CMD_POLL_BIST_RUNNING 0x1 /* enum */ +#define MC_CMD_POLL_BIST_PASSED 0x2 /* enum */ +#define MC_CMD_POLL_BIST_FAILED 0x3 /* enum */ +#define MC_CMD_POLL_BIST_TIMEOUT 0x4 /* enum */ +#define MC_CMD_POLL_BIST_OUT_PRIVATE_OFST 4 + +/* MC_CMD_POLL_BIST_OUT_SFT9001 msgresponse */ +#define MC_CMD_POLL_BIST_OUT_SFT9001_LEN 36 +/* MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 */ +/* Enum values, see field(s): */ +/* MC_CMD_POLL_BIST_OUT/MC_CMD_POLL_BIST_OUT_RESULT */ +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A_OFST 4 +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_B_OFST 8 +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_C_OFST 12 +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_D_OFST 16 +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_A_OFST 20 +#define MC_CMD_POLL_BIST_SFT9001_PAIR_OK 0x1 /* enum */ +#define MC_CMD_POLL_BIST_SFT9001_PAIR_OPEN 0x2 /* enum */ +#define MC_CMD_POLL_BIST_SFT9001_INTRA_PAIR_SHORT 0x3 /* enum */ +#define MC_CMD_POLL_BIST_SFT9001_INTER_PAIR_SHORT 0x4 /* enum */ +#define MC_CMD_POLL_BIST_SFT9001_PAIR_BUSY 0x9 /* enum */ +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_B_OFST 24 +/* Enum values, see field(s): */ +/* CABLE_STATUS_A */ +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_C_OFST 28 +/* Enum values, see field(s): */ +/* CABLE_STATUS_A */ +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_D_OFST 32 +/* Enum values, see field(s): */ +/* CABLE_STATUS_A */ + +/* MC_CMD_POLL_BIST_OUT_MRSFP msgresponse */ +#define MC_CMD_POLL_BIST_OUT_MRSFP_LEN 8 +/* MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 */ +/* Enum values, see field(s): */ +/* MC_CMD_POLL_BIST_OUT/MC_CMD_POLL_BIST_OUT_RESULT */ +#define MC_CMD_POLL_BIST_OUT_MRSFP_TEST_OFST 4 +#define MC_CMD_POLL_BIST_MRSFP_TEST_COMPLETE 0x0 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_WRITE 0x1 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_IO_EXP 0x2 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_MODULE 0x3 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_IO_EXP_I2C_CONFIGURE 0x4 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_I2C_NO_CROSSTALK 0x5 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_PRESENCE 0x6 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_I2C_ACCESS 0x7 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_SANE_VALUE 0x8 /* enum */ + + +/***********************************/ +/* MC_CMD_FLUSH_RX_QUEUES + * Flush receive queue(s). + */ +#define MC_CMD_FLUSH_RX_QUEUES 0x27 + +/* MC_CMD_FLUSH_RX_QUEUES_IN msgrequest */ +#define MC_CMD_FLUSH_RX_QUEUES_IN_LENMIN 4 +#define MC_CMD_FLUSH_RX_QUEUES_IN_LENMAX 252 +#define MC_CMD_FLUSH_RX_QUEUES_IN_LEN(num) (0+4*(num)) +#define MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_OFST 0 +#define MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_LEN 4 +#define MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MINNUM 1 +#define MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MAXNUM 63 + +/* MC_CMD_FLUSH_RX_QUEUES_OUT msgresponse */ +#define MC_CMD_FLUSH_RX_QUEUES_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_LOOPBACK_MODES + * Get port's loopback modes. + */ +#define MC_CMD_GET_LOOPBACK_MODES 0x28 + +/* MC_CMD_GET_LOOPBACK_MODES_IN msgrequest */ +#define MC_CMD_GET_LOOPBACK_MODES_IN_LEN 0 + +/* MC_CMD_GET_LOOPBACK_MODES_OUT msgresponse */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_LEN 32 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_OFST 0 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_LEN 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_LO_OFST 0 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_HI_OFST 4 +#define MC_CMD_LOOPBACK_NONE 0x0 /* enum */ +#define MC_CMD_LOOPBACK_DATA 0x1 /* enum */ +#define MC_CMD_LOOPBACK_GMAC 0x2 /* enum */ +#define MC_CMD_LOOPBACK_XGMII 0x3 /* enum */ +#define MC_CMD_LOOPBACK_XGXS 0x4 /* enum */ +#define MC_CMD_LOOPBACK_XAUI 0x5 /* enum */ +#define MC_CMD_LOOPBACK_GMII 0x6 /* enum */ +#define MC_CMD_LOOPBACK_SGMII 0x7 /* enum */ +#define MC_CMD_LOOPBACK_XGBR 0x8 /* enum */ +#define MC_CMD_LOOPBACK_XFI 0x9 /* enum */ +#define MC_CMD_LOOPBACK_XAUI_FAR 0xa /* enum */ +#define MC_CMD_LOOPBACK_GMII_FAR 0xb /* enum */ +#define MC_CMD_LOOPBACK_SGMII_FAR 0xc /* enum */ +#define MC_CMD_LOOPBACK_XFI_FAR 0xd /* enum */ +#define MC_CMD_LOOPBACK_GPHY 0xe /* enum */ +#define MC_CMD_LOOPBACK_PHYXS 0xf /* enum */ +#define MC_CMD_LOOPBACK_PCS 0x10 /* enum */ +#define MC_CMD_LOOPBACK_PMAPMD 0x11 /* enum */ +#define MC_CMD_LOOPBACK_XPORT 0x12 /* enum */ +#define MC_CMD_LOOPBACK_XGMII_WS 0x13 /* enum */ +#define MC_CMD_LOOPBACK_XAUI_WS 0x14 /* enum */ +#define MC_CMD_LOOPBACK_XAUI_WS_FAR 0x15 /* enum */ +#define MC_CMD_LOOPBACK_XAUI_WS_NEAR 0x16 /* enum */ +#define MC_CMD_LOOPBACK_GMII_WS 0x17 /* enum */ +#define MC_CMD_LOOPBACK_XFI_WS 0x18 /* enum */ +#define MC_CMD_LOOPBACK_XFI_WS_FAR 0x19 /* enum */ +#define MC_CMD_LOOPBACK_PHYXS_WS 0x1a /* enum */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_OFST 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_LEN 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_LO_OFST 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_HI_OFST 12 +/* Enum values, see field(s): */ +/* 100M */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_10G_OFST 16 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_10G_LEN 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_10G_LO_OFST 16 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_10G_HI_OFST 20 +/* Enum values, see field(s): */ +/* 100M */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST 24 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LO_OFST 24 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_HI_OFST 28 +/* Enum values, see field(s): */ +/* 100M */ + + +/***********************************/ +/* MC_CMD_GET_LINK + * Read the unified MAC/PHY link state. + */ +#define MC_CMD_GET_LINK 0x29 + +/* MC_CMD_GET_LINK_IN msgrequest */ +#define MC_CMD_GET_LINK_IN_LEN 0 + +/* MC_CMD_GET_LINK_OUT msgresponse */ +#define MC_CMD_GET_LINK_OUT_LEN 28 +#define MC_CMD_GET_LINK_OUT_CAP_OFST 0 +#define MC_CMD_GET_LINK_OUT_LP_CAP_OFST 4 +#define MC_CMD_GET_LINK_OUT_LINK_SPEED_OFST 8 +#define MC_CMD_GET_LINK_OUT_LOOPBACK_MODE_OFST 12 +/* Enum values, see field(s): */ +/* MC_CMD_GET_LOOPBACK_MODES/MC_CMD_GET_LOOPBACK_MODES_OUT/100M */ +#define MC_CMD_GET_LINK_OUT_FLAGS_OFST 16 +#define MC_CMD_GET_LINK_OUT_LINK_UP_LBN 0 +#define MC_CMD_GET_LINK_OUT_LINK_UP_WIDTH 1 +#define MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN 1 +#define MC_CMD_GET_LINK_OUT_FULL_DUPLEX_WIDTH 1 +#define MC_CMD_GET_LINK_OUT_BPX_LINK_LBN 2 +#define MC_CMD_GET_LINK_OUT_BPX_LINK_WIDTH 1 +#define MC_CMD_GET_LINK_OUT_PHY_LINK_LBN 3 +#define MC_CMD_GET_LINK_OUT_PHY_LINK_WIDTH 1 +#define MC_CMD_GET_LINK_OUT_FCNTL_OFST 20 +#define MC_CMD_FCNTL_OFF 0x0 /* enum */ +#define MC_CMD_FCNTL_RESPOND 0x1 /* enum */ +#define MC_CMD_FCNTL_BIDIR 0x2 /* enum */ +#define MC_CMD_GET_LINK_OUT_MAC_FAULT_OFST 24 +#define MC_CMD_MAC_FAULT_XGMII_LOCAL_LBN 0 +#define MC_CMD_MAC_FAULT_XGMII_LOCAL_WIDTH 1 +#define MC_CMD_MAC_FAULT_XGMII_REMOTE_LBN 1 +#define MC_CMD_MAC_FAULT_XGMII_REMOTE_WIDTH 1 +#define MC_CMD_MAC_FAULT_SGMII_REMOTE_LBN 2 +#define MC_CMD_MAC_FAULT_SGMII_REMOTE_WIDTH 1 +#define MC_CMD_MAC_FAULT_PENDING_RECONFIG_LBN 3 +#define MC_CMD_MAC_FAULT_PENDING_RECONFIG_WIDTH 1 + + +/***********************************/ +/* MC_CMD_SET_LINK + * Write the unified MAC/PHY link configuration. + */ +#define MC_CMD_SET_LINK 0x2a + +/* MC_CMD_SET_LINK_IN msgrequest */ +#define MC_CMD_SET_LINK_IN_LEN 16 +#define MC_CMD_SET_LINK_IN_CAP_OFST 0 +#define MC_CMD_SET_LINK_IN_FLAGS_OFST 4 +#define MC_CMD_SET_LINK_IN_LOWPOWER_LBN 0 +#define MC_CMD_SET_LINK_IN_LOWPOWER_WIDTH 1 +#define MC_CMD_SET_LINK_IN_POWEROFF_LBN 1 +#define MC_CMD_SET_LINK_IN_POWEROFF_WIDTH 1 +#define MC_CMD_SET_LINK_IN_TXDIS_LBN 2 +#define MC_CMD_SET_LINK_IN_TXDIS_WIDTH 1 +#define MC_CMD_SET_LINK_IN_LOOPBACK_MODE_OFST 8 +/* Enum values, see field(s): */ +/* MC_CMD_GET_LOOPBACK_MODES/MC_CMD_GET_LOOPBACK_MODES_OUT/100M */ +#define MC_CMD_SET_LINK_IN_LOOPBACK_SPEED_OFST 12 + +/* MC_CMD_SET_LINK_OUT msgresponse */ +#define MC_CMD_SET_LINK_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_SET_ID_LED + * Set indentification LED state. + */ +#define MC_CMD_SET_ID_LED 0x2b + +/* MC_CMD_SET_ID_LED_IN msgrequest */ +#define MC_CMD_SET_ID_LED_IN_LEN 4 +#define MC_CMD_SET_ID_LED_IN_STATE_OFST 0 +#define MC_CMD_LED_OFF 0x0 /* enum */ +#define MC_CMD_LED_ON 0x1 /* enum */ +#define MC_CMD_LED_DEFAULT 0x2 /* enum */ + +/* MC_CMD_SET_ID_LED_OUT msgresponse */ +#define MC_CMD_SET_ID_LED_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_SET_MAC + * Set MAC configuration. + */ +#define MC_CMD_SET_MAC 0x2c + +/* MC_CMD_SET_MAC_IN msgrequest */ +#define MC_CMD_SET_MAC_IN_LEN 24 +#define MC_CMD_SET_MAC_IN_MTU_OFST 0 +#define MC_CMD_SET_MAC_IN_DRAIN_OFST 4 +#define MC_CMD_SET_MAC_IN_ADDR_OFST 8 +#define MC_CMD_SET_MAC_IN_ADDR_LEN 8 +#define MC_CMD_SET_MAC_IN_ADDR_LO_OFST 8 +#define MC_CMD_SET_MAC_IN_ADDR_HI_OFST 12 +#define MC_CMD_SET_MAC_IN_REJECT_OFST 16 +#define MC_CMD_SET_MAC_IN_REJECT_UNCST_LBN 0 +#define MC_CMD_SET_MAC_IN_REJECT_UNCST_WIDTH 1 +#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_LBN 1 +#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_WIDTH 1 +#define MC_CMD_SET_MAC_IN_FCNTL_OFST 20 +/* MC_CMD_FCNTL_OFF 0x0 */ +/* MC_CMD_FCNTL_RESPOND 0x1 */ +/* MC_CMD_FCNTL_BIDIR 0x2 */ +#define MC_CMD_FCNTL_AUTO 0x3 /* enum */ + +/* MC_CMD_SET_MAC_OUT msgresponse */ +#define MC_CMD_SET_MAC_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_PHY_STATS + * Get generic PHY statistics. + */ +#define MC_CMD_PHY_STATS 0x2d + +/* MC_CMD_PHY_STATS_IN msgrequest */ +#define MC_CMD_PHY_STATS_IN_LEN 8 +#define MC_CMD_PHY_STATS_IN_DMA_ADDR_OFST 0 +#define MC_CMD_PHY_STATS_IN_DMA_ADDR_LEN 8 +#define MC_CMD_PHY_STATS_IN_DMA_ADDR_LO_OFST 0 +#define MC_CMD_PHY_STATS_IN_DMA_ADDR_HI_OFST 4 + +/* MC_CMD_PHY_STATS_OUT_DMA msgresponse */ +#define MC_CMD_PHY_STATS_OUT_DMA_LEN 0 + +/* MC_CMD_PHY_STATS_OUT_NO_DMA msgresponse */ +#define MC_CMD_PHY_STATS_OUT_NO_DMA_LEN (((MC_CMD_PHY_NSTATS*32))>>3) +#define MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_OFST 0 +#define MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_LEN 4 +#define MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_NUM MC_CMD_PHY_NSTATS +#define MC_CMD_OUI 0x0 /* enum */ +#define MC_CMD_PMA_PMD_LINK_UP 0x1 /* enum */ +#define MC_CMD_PMA_PMD_RX_FAULT 0x2 /* enum */ +#define MC_CMD_PMA_PMD_TX_FAULT 0x3 /* enum */ +#define MC_CMD_PMA_PMD_SIGNAL 0x4 /* enum */ +#define MC_CMD_PMA_PMD_SNR_A 0x5 /* enum */ +#define MC_CMD_PMA_PMD_SNR_B 0x6 /* enum */ +#define MC_CMD_PMA_PMD_SNR_C 0x7 /* enum */ +#define MC_CMD_PMA_PMD_SNR_D 0x8 /* enum */ +#define MC_CMD_PCS_LINK_UP 0x9 /* enum */ +#define MC_CMD_PCS_RX_FAULT 0xa /* enum */ +#define MC_CMD_PCS_TX_FAULT 0xb /* enum */ +#define MC_CMD_PCS_BER 0xc /* enum */ +#define MC_CMD_PCS_BLOCK_ERRORS 0xd /* enum */ +#define MC_CMD_PHYXS_LINK_UP 0xe /* enum */ +#define MC_CMD_PHYXS_RX_FAULT 0xf /* enum */ +#define MC_CMD_PHYXS_TX_FAULT 0x10 /* enum */ +#define MC_CMD_PHYXS_ALIGN 0x11 /* enum */ +#define MC_CMD_PHYXS_SYNC 0x12 /* enum */ +#define MC_CMD_AN_LINK_UP 0x13 /* enum */ +#define MC_CMD_AN_COMPLETE 0x14 /* enum */ +#define MC_CMD_AN_10GBT_STATUS 0x15 /* enum */ +#define MC_CMD_CL22_LINK_UP 0x16 /* enum */ +#define MC_CMD_PHY_NSTATS 0x17 /* enum */ + + +/***********************************/ +/* MC_CMD_MAC_STATS + * Get generic MAC statistics. + */ +#define MC_CMD_MAC_STATS 0x2e + +/* MC_CMD_MAC_STATS_IN msgrequest */ +#define MC_CMD_MAC_STATS_IN_LEN 16 +#define MC_CMD_MAC_STATS_IN_DMA_ADDR_OFST 0 +#define MC_CMD_MAC_STATS_IN_DMA_ADDR_LEN 8 +#define MC_CMD_MAC_STATS_IN_DMA_ADDR_LO_OFST 0 +#define MC_CMD_MAC_STATS_IN_DMA_ADDR_HI_OFST 4 +#define MC_CMD_MAC_STATS_IN_CMD_OFST 8 +#define MC_CMD_MAC_STATS_IN_DMA_LBN 0 +#define MC_CMD_MAC_STATS_IN_DMA_WIDTH 1 +#define MC_CMD_MAC_STATS_IN_CLEAR_LBN 1 +#define MC_CMD_MAC_STATS_IN_CLEAR_WIDTH 1 +#define MC_CMD_MAC_STATS_IN_PERIODIC_CHANGE_LBN 2 +#define MC_CMD_MAC_STATS_IN_PERIODIC_CHANGE_WIDTH 1 +#define MC_CMD_MAC_STATS_IN_PERIODIC_ENABLE_LBN 3 +#define MC_CMD_MAC_STATS_IN_PERIODIC_ENABLE_WIDTH 1 +#define MC_CMD_MAC_STATS_IN_PERIODIC_CLEAR_LBN 4 +#define MC_CMD_MAC_STATS_IN_PERIODIC_CLEAR_WIDTH 1 +#define MC_CMD_MAC_STATS_IN_PERIODIC_NOEVENT_LBN 5 +#define MC_CMD_MAC_STATS_IN_PERIODIC_NOEVENT_WIDTH 1 +#define MC_CMD_MAC_STATS_IN_PERIOD_MS_LBN 16 +#define MC_CMD_MAC_STATS_IN_PERIOD_MS_WIDTH 16 +#define MC_CMD_MAC_STATS_IN_DMA_LEN_OFST 12 + +/* MC_CMD_MAC_STATS_OUT_DMA msgresponse */ +#define MC_CMD_MAC_STATS_OUT_DMA_LEN 0 + +/* MC_CMD_MAC_STATS_OUT_NO_DMA msgresponse */ +#define MC_CMD_MAC_STATS_OUT_NO_DMA_LEN (((MC_CMD_MAC_NSTATS*64))>>3) +#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_OFST 0 +#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_LEN 8 +#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_LO_OFST 0 +#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_HI_OFST 4 +#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_NUM MC_CMD_MAC_NSTATS +#define MC_CMD_MAC_GENERATION_START 0x0 /* enum */ +#define MC_CMD_MAC_TX_PKTS 0x1 /* enum */ +#define MC_CMD_MAC_TX_PAUSE_PKTS 0x2 /* enum */ +#define MC_CMD_MAC_TX_CONTROL_PKTS 0x3 /* enum */ +#define MC_CMD_MAC_TX_UNICAST_PKTS 0x4 /* enum */ +#define MC_CMD_MAC_TX_MULTICAST_PKTS 0x5 /* enum */ +#define MC_CMD_MAC_TX_BROADCAST_PKTS 0x6 /* enum */ +#define MC_CMD_MAC_TX_BYTES 0x7 /* enum */ +#define MC_CMD_MAC_TX_BAD_BYTES 0x8 /* enum */ +#define MC_CMD_MAC_TX_LT64_PKTS 0x9 /* enum */ +#define MC_CMD_MAC_TX_64_PKTS 0xa /* enum */ +#define MC_CMD_MAC_TX_65_TO_127_PKTS 0xb /* enum */ +#define MC_CMD_MAC_TX_128_TO_255_PKTS 0xc /* enum */ +#define MC_CMD_MAC_TX_256_TO_511_PKTS 0xd /* enum */ +#define MC_CMD_MAC_TX_512_TO_1023_PKTS 0xe /* enum */ +#define MC_CMD_MAC_TX_1024_TO_15XX_PKTS 0xf /* enum */ +#define MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS 0x10 /* enum */ +#define MC_CMD_MAC_TX_GTJUMBO_PKTS 0x11 /* enum */ +#define MC_CMD_MAC_TX_BAD_FCS_PKTS 0x12 /* enum */ +#define MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS 0x13 /* enum */ +#define MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS 0x14 /* enum */ +#define MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS 0x15 /* enum */ +#define MC_CMD_MAC_TX_LATE_COLLISION_PKTS 0x16 /* enum */ +#define MC_CMD_MAC_TX_DEFERRED_PKTS 0x17 /* enum */ +#define MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS 0x18 /* enum */ +#define MC_CMD_MAC_TX_NON_TCPUDP_PKTS 0x19 /* enum */ +#define MC_CMD_MAC_TX_MAC_SRC_ERR_PKTS 0x1a /* enum */ +#define MC_CMD_MAC_TX_IP_SRC_ERR_PKTS 0x1b /* enum */ +#define MC_CMD_MAC_RX_PKTS 0x1c /* enum */ +#define MC_CMD_MAC_RX_PAUSE_PKTS 0x1d /* enum */ +#define MC_CMD_MAC_RX_GOOD_PKTS 0x1e /* enum */ +#define MC_CMD_MAC_RX_CONTROL_PKTS 0x1f /* enum */ +#define MC_CMD_MAC_RX_UNICAST_PKTS 0x20 /* enum */ +#define MC_CMD_MAC_RX_MULTICAST_PKTS 0x21 /* enum */ +#define MC_CMD_MAC_RX_BROADCAST_PKTS 0x22 /* enum */ +#define MC_CMD_MAC_RX_BYTES 0x23 /* enum */ +#define MC_CMD_MAC_RX_BAD_BYTES 0x24 /* enum */ +#define MC_CMD_MAC_RX_64_PKTS 0x25 /* enum */ +#define MC_CMD_MAC_RX_65_TO_127_PKTS 0x26 /* enum */ +#define MC_CMD_MAC_RX_128_TO_255_PKTS 0x27 /* enum */ +#define MC_CMD_MAC_RX_256_TO_511_PKTS 0x28 /* enum */ +#define MC_CMD_MAC_RX_512_TO_1023_PKTS 0x29 /* enum */ +#define MC_CMD_MAC_RX_1024_TO_15XX_PKTS 0x2a /* enum */ +#define MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS 0x2b /* enum */ +#define MC_CMD_MAC_RX_GTJUMBO_PKTS 0x2c /* enum */ +#define MC_CMD_MAC_RX_UNDERSIZE_PKTS 0x2d /* enum */ +#define MC_CMD_MAC_RX_BAD_FCS_PKTS 0x2e /* enum */ +#define MC_CMD_MAC_RX_OVERFLOW_PKTS 0x2f /* enum */ +#define MC_CMD_MAC_RX_FALSE_CARRIER_PKTS 0x30 /* enum */ +#define MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS 0x31 /* enum */ +#define MC_CMD_MAC_RX_ALIGN_ERROR_PKTS 0x32 /* enum */ +#define MC_CMD_MAC_RX_LENGTH_ERROR_PKTS 0x33 /* enum */ +#define MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS 0x34 /* enum */ +#define MC_CMD_MAC_RX_JABBER_PKTS 0x35 /* enum */ +#define MC_CMD_MAC_RX_NODESC_DROPS 0x36 /* enum */ +#define MC_CMD_MAC_RX_LANES01_CHAR_ERR 0x37 /* enum */ +#define MC_CMD_MAC_RX_LANES23_CHAR_ERR 0x38 /* enum */ +#define MC_CMD_MAC_RX_LANES01_DISP_ERR 0x39 /* enum */ +#define MC_CMD_MAC_RX_LANES23_DISP_ERR 0x3a /* enum */ +#define MC_CMD_MAC_RX_MATCH_FAULT 0x3b /* enum */ +#define MC_CMD_GMAC_DMABUF_START 0x40 /* enum */ +#define MC_CMD_GMAC_DMABUF_END 0x5f /* enum */ +#define MC_CMD_MAC_GENERATION_END 0x60 /* enum */ +#define MC_CMD_MAC_NSTATS 0x61 /* enum */ + + +/***********************************/ +/* MC_CMD_SRIOV + * to be documented + */ +#define MC_CMD_SRIOV 0x30 + +/* MC_CMD_SRIOV_IN msgrequest */ +#define MC_CMD_SRIOV_IN_LEN 12 +#define MC_CMD_SRIOV_IN_ENABLE_OFST 0 +#define MC_CMD_SRIOV_IN_VI_BASE_OFST 4 +#define MC_CMD_SRIOV_IN_VF_COUNT_OFST 8 + +/* MC_CMD_SRIOV_OUT msgresponse */ +#define MC_CMD_SRIOV_OUT_LEN 8 +#define MC_CMD_SRIOV_OUT_VI_SCALE_OFST 0 +#define MC_CMD_SRIOV_OUT_VF_TOTAL_OFST 4 + +/* MC_CMD_MEMCPY_RECORD_TYPEDEF structuredef */ +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_LEN 32 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_OFST 0 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_LBN 0 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_WIDTH 32 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_RID_OFST 4 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_RID_LBN 32 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_RID_WIDTH 32 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_OFST 8 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_LEN 8 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_LO_OFST 8 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_HI_OFST 12 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_LBN 64 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_WIDTH 64 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_RID_OFST 16 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_RID_INLINE 0x100 /* enum */ +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_RID_LBN 128 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_RID_WIDTH 32 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_OFST 20 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_LEN 8 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_LO_OFST 20 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_HI_OFST 24 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_LBN 160 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_WIDTH 64 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_LENGTH_OFST 28 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_LENGTH_LBN 224 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_LENGTH_WIDTH 32 + + +/***********************************/ +/* MC_CMD_MEMCPY + * Perform memory copy operation. + */ +#define MC_CMD_MEMCPY 0x31 + +/* MC_CMD_MEMCPY_IN msgrequest */ +#define MC_CMD_MEMCPY_IN_LENMIN 32 +#define MC_CMD_MEMCPY_IN_LENMAX 224 +#define MC_CMD_MEMCPY_IN_LEN(num) (0+32*(num)) +#define MC_CMD_MEMCPY_IN_RECORD_OFST 0 +#define MC_CMD_MEMCPY_IN_RECORD_LEN 32 +#define MC_CMD_MEMCPY_IN_RECORD_MINNUM 1 +#define MC_CMD_MEMCPY_IN_RECORD_MAXNUM 7 + +/* MC_CMD_MEMCPY_OUT msgresponse */ +#define MC_CMD_MEMCPY_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_WOL_FILTER_SET + * Set a WoL filter. + */ +#define MC_CMD_WOL_FILTER_SET 0x32 + +/* MC_CMD_WOL_FILTER_SET_IN msgrequest */ +#define MC_CMD_WOL_FILTER_SET_IN_LEN 192 +#define MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 +#define MC_CMD_FILTER_MODE_SIMPLE 0x0 /* enum */ +#define MC_CMD_FILTER_MODE_STRUCTURED 0xffffffff /* enum */ +#define MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 +#define MC_CMD_WOL_TYPE_MAGIC 0x0 /* enum */ +#define MC_CMD_WOL_TYPE_WIN_MAGIC 0x2 /* enum */ +#define MC_CMD_WOL_TYPE_IPV4_SYN 0x3 /* enum */ +#define MC_CMD_WOL_TYPE_IPV6_SYN 0x4 /* enum */ +#define MC_CMD_WOL_TYPE_BITMAP 0x5 /* enum */ +#define MC_CMD_WOL_TYPE_LINK 0x6 /* enum */ +#define MC_CMD_WOL_TYPE_MAX 0x7 /* enum */ +#define MC_CMD_WOL_FILTER_SET_IN_DATA_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_DATA_LEN 4 +#define MC_CMD_WOL_FILTER_SET_IN_DATA_NUM 46 + +/* MC_CMD_WOL_FILTER_SET_IN_MAGIC msgrequest */ +#define MC_CMD_WOL_FILTER_SET_IN_MAGIC_LEN 16 +/* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */ +/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */ +#define MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_LEN 8 +#define MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_LO_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_HI_OFST 12 + +/* MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN msgrequest */ +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_LEN 20 +/* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */ +/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */ +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_IP_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_IP_OFST 12 +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_PORT_OFST 16 +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_PORT_LEN 2 +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_PORT_OFST 18 +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_PORT_LEN 2 + +/* MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN msgrequest */ +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_LEN 44 +/* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */ +/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */ +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_IP_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_IP_LEN 16 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_IP_OFST 24 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_IP_LEN 16 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_PORT_OFST 40 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_PORT_LEN 2 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_PORT_OFST 42 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_PORT_LEN 2 + +/* MC_CMD_WOL_FILTER_SET_IN_BITMAP msgrequest */ +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LEN 187 +/* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */ +/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */ +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_MASK_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_MASK_LEN 48 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_BITMAP_OFST 56 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_BITMAP_LEN 128 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LEN_OFST 184 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LEN_LEN 1 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER3_OFST 185 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER3_LEN 1 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER4_OFST 186 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER4_LEN 1 + +/* MC_CMD_WOL_FILTER_SET_IN_LINK msgrequest */ +#define MC_CMD_WOL_FILTER_SET_IN_LINK_LEN 12 +/* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */ +/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */ +#define MC_CMD_WOL_FILTER_SET_IN_LINK_MASK_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_LINK_UP_LBN 0 +#define MC_CMD_WOL_FILTER_SET_IN_LINK_UP_WIDTH 1 +#define MC_CMD_WOL_FILTER_SET_IN_LINK_DOWN_LBN 1 +#define MC_CMD_WOL_FILTER_SET_IN_LINK_DOWN_WIDTH 1 + +/* MC_CMD_WOL_FILTER_SET_OUT msgresponse */ +#define MC_CMD_WOL_FILTER_SET_OUT_LEN 4 +#define MC_CMD_WOL_FILTER_SET_OUT_FILTER_ID_OFST 0 + + +/***********************************/ +/* MC_CMD_WOL_FILTER_REMOVE + * Remove a WoL filter. + */ +#define MC_CMD_WOL_FILTER_REMOVE 0x33 + +/* MC_CMD_WOL_FILTER_REMOVE_IN msgrequest */ +#define MC_CMD_WOL_FILTER_REMOVE_IN_LEN 4 +#define MC_CMD_WOL_FILTER_REMOVE_IN_FILTER_ID_OFST 0 + +/* MC_CMD_WOL_FILTER_REMOVE_OUT msgresponse */ +#define MC_CMD_WOL_FILTER_REMOVE_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_WOL_FILTER_RESET + * Reset (i.e. remove all) WoL filters. + */ +#define MC_CMD_WOL_FILTER_RESET 0x34 + +/* MC_CMD_WOL_FILTER_RESET_IN msgrequest */ +#define MC_CMD_WOL_FILTER_RESET_IN_LEN 4 +#define MC_CMD_WOL_FILTER_RESET_IN_MASK_OFST 0 +#define MC_CMD_WOL_FILTER_RESET_IN_WAKE_FILTERS 0x1 /* enum */ +#define MC_CMD_WOL_FILTER_RESET_IN_LIGHTSOUT_OFFLOADS 0x2 /* enum */ + +/* MC_CMD_WOL_FILTER_RESET_OUT msgresponse */ +#define MC_CMD_WOL_FILTER_RESET_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_SET_MCAST_HASH + * Set the MCASH hash value. + */ +#define MC_CMD_SET_MCAST_HASH 0x35 + +/* MC_CMD_SET_MCAST_HASH_IN msgrequest */ +#define MC_CMD_SET_MCAST_HASH_IN_LEN 32 +#define MC_CMD_SET_MCAST_HASH_IN_HASH0_OFST 0 +#define MC_CMD_SET_MCAST_HASH_IN_HASH0_LEN 16 +#define MC_CMD_SET_MCAST_HASH_IN_HASH1_OFST 16 +#define MC_CMD_SET_MCAST_HASH_IN_HASH1_LEN 16 + +/* MC_CMD_SET_MCAST_HASH_OUT msgresponse */ +#define MC_CMD_SET_MCAST_HASH_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_NVRAM_TYPES + * Get virtual NVRAM partitions information. + */ +#define MC_CMD_NVRAM_TYPES 0x36 + +/* MC_CMD_NVRAM_TYPES_IN msgrequest */ +#define MC_CMD_NVRAM_TYPES_IN_LEN 0 + +/* MC_CMD_NVRAM_TYPES_OUT msgresponse */ +#define MC_CMD_NVRAM_TYPES_OUT_LEN 4 +#define MC_CMD_NVRAM_TYPES_OUT_TYPES_OFST 0 +#define MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO 0x0 /* enum */ +#define MC_CMD_NVRAM_TYPE_MC_FW 0x1 /* enum */ +#define MC_CMD_NVRAM_TYPE_MC_FW_BACKUP 0x2 /* enum */ +#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0 0x3 /* enum */ +#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1 0x4 /* enum */ +#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0 0x5 /* enum */ +#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1 0x6 /* enum */ +#define MC_CMD_NVRAM_TYPE_EXP_ROM 0x7 /* enum */ +#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT0 0x8 /* enum */ +#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1 0x9 /* enum */ +#define MC_CMD_NVRAM_TYPE_PHY_PORT0 0xa /* enum */ +#define MC_CMD_NVRAM_TYPE_PHY_PORT1 0xb /* enum */ +#define MC_CMD_NVRAM_TYPE_LOG 0xc /* enum */ + + +/***********************************/ +/* MC_CMD_NVRAM_INFO + * Read info about a virtual NVRAM partition. + */ +#define MC_CMD_NVRAM_INFO 0x37 + +/* MC_CMD_NVRAM_INFO_IN msgrequest */ +#define MC_CMD_NVRAM_INFO_IN_LEN 4 +#define MC_CMD_NVRAM_INFO_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ + +/* MC_CMD_NVRAM_INFO_OUT msgresponse */ +#define MC_CMD_NVRAM_INFO_OUT_LEN 24 +#define MC_CMD_NVRAM_INFO_OUT_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ +#define MC_CMD_NVRAM_INFO_OUT_SIZE_OFST 4 +#define MC_CMD_NVRAM_INFO_OUT_ERASESIZE_OFST 8 +#define MC_CMD_NVRAM_INFO_OUT_FLAGS_OFST 12 +#define MC_CMD_NVRAM_INFO_OUT_PROTECTED_LBN 0 +#define MC_CMD_NVRAM_INFO_OUT_PROTECTED_WIDTH 1 +#define MC_CMD_NVRAM_INFO_OUT_PHYSDEV_OFST 16 +#define MC_CMD_NVRAM_INFO_OUT_PHYSADDR_OFST 20 + + +/***********************************/ +/* MC_CMD_NVRAM_UPDATE_START + * Start a group of update operations on a virtual NVRAM partition. + */ +#define MC_CMD_NVRAM_UPDATE_START 0x38 + +/* MC_CMD_NVRAM_UPDATE_START_IN msgrequest */ +#define MC_CMD_NVRAM_UPDATE_START_IN_LEN 4 +#define MC_CMD_NVRAM_UPDATE_START_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ + +/* MC_CMD_NVRAM_UPDATE_START_OUT msgresponse */ +#define MC_CMD_NVRAM_UPDATE_START_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_NVRAM_READ + * Read data from a virtual NVRAM partition. + */ +#define MC_CMD_NVRAM_READ 0x39 + +/* MC_CMD_NVRAM_READ_IN msgrequest */ +#define MC_CMD_NVRAM_READ_IN_LEN 12 +#define MC_CMD_NVRAM_READ_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ +#define MC_CMD_NVRAM_READ_IN_OFFSET_OFST 4 +#define MC_CMD_NVRAM_READ_IN_LENGTH_OFST 8 + +/* MC_CMD_NVRAM_READ_OUT msgresponse */ +#define MC_CMD_NVRAM_READ_OUT_LENMIN 1 +#define MC_CMD_NVRAM_READ_OUT_LENMAX 255 +#define MC_CMD_NVRAM_READ_OUT_LEN(num) (0+1*(num)) +#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_OFST 0 +#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_LEN 1 +#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_MINNUM 1 +#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_MAXNUM 255 + + +/***********************************/ +/* MC_CMD_NVRAM_WRITE + * Write data to a virtual NVRAM partition. + */ +#define MC_CMD_NVRAM_WRITE 0x3a + +/* MC_CMD_NVRAM_WRITE_IN msgrequest */ +#define MC_CMD_NVRAM_WRITE_IN_LENMIN 13 +#define MC_CMD_NVRAM_WRITE_IN_LENMAX 255 +#define MC_CMD_NVRAM_WRITE_IN_LEN(num) (12+1*(num)) +#define MC_CMD_NVRAM_WRITE_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ +#define MC_CMD_NVRAM_WRITE_IN_OFFSET_OFST 4 +#define MC_CMD_NVRAM_WRITE_IN_LENGTH_OFST 8 +#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_OFST 12 +#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_LEN 1 +#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_MINNUM 1 +#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_MAXNUM 243 + +/* MC_CMD_NVRAM_WRITE_OUT msgresponse */ +#define MC_CMD_NVRAM_WRITE_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_NVRAM_ERASE + * Erase sector(s) from a virtual NVRAM partition. + */ +#define MC_CMD_NVRAM_ERASE 0x3b + +/* MC_CMD_NVRAM_ERASE_IN msgrequest */ +#define MC_CMD_NVRAM_ERASE_IN_LEN 12 +#define MC_CMD_NVRAM_ERASE_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ +#define MC_CMD_NVRAM_ERASE_IN_OFFSET_OFST 4 +#define MC_CMD_NVRAM_ERASE_IN_LENGTH_OFST 8 + +/* MC_CMD_NVRAM_ERASE_OUT msgresponse */ +#define MC_CMD_NVRAM_ERASE_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_NVRAM_UPDATE_FINISH + * Finish a group of update operations on a virtual NVRAM partition. + */ +#define MC_CMD_NVRAM_UPDATE_FINISH 0x3c + +/* MC_CMD_NVRAM_UPDATE_FINISH_IN msgrequest */ +#define MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN 8 +#define MC_CMD_NVRAM_UPDATE_FINISH_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ +#define MC_CMD_NVRAM_UPDATE_FINISH_IN_REBOOT_OFST 4 + +/* MC_CMD_NVRAM_UPDATE_FINISH_OUT msgresponse */ +#define MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_REBOOT + * Reboot the MC. + */ +#define MC_CMD_REBOOT 0x3d + +/* MC_CMD_REBOOT_IN msgrequest */ +#define MC_CMD_REBOOT_IN_LEN 4 +#define MC_CMD_REBOOT_IN_FLAGS_OFST 0 +#define MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION 0x1 /* enum */ + +/* MC_CMD_REBOOT_OUT msgresponse */ +#define MC_CMD_REBOOT_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_SCHEDINFO + * Request scheduler info. + */ +#define MC_CMD_SCHEDINFO 0x3e + +/* MC_CMD_SCHEDINFO_IN msgrequest */ +#define MC_CMD_SCHEDINFO_IN_LEN 0 + +/* MC_CMD_SCHEDINFO_OUT msgresponse */ +#define MC_CMD_SCHEDINFO_OUT_LENMIN 4 +#define MC_CMD_SCHEDINFO_OUT_LENMAX 252 +#define MC_CMD_SCHEDINFO_OUT_LEN(num) (0+4*(num)) +#define MC_CMD_SCHEDINFO_OUT_DATA_OFST 0 +#define MC_CMD_SCHEDINFO_OUT_DATA_LEN 4 +#define MC_CMD_SCHEDINFO_OUT_DATA_MINNUM 1 +#define MC_CMD_SCHEDINFO_OUT_DATA_MAXNUM 63 + + +/***********************************/ +/* MC_CMD_REBOOT_MODE + */ +#define MC_CMD_REBOOT_MODE 0x3f + +/* MC_CMD_REBOOT_MODE_IN msgrequest */ +#define MC_CMD_REBOOT_MODE_IN_LEN 4 +#define MC_CMD_REBOOT_MODE_IN_VALUE_OFST 0 +#define MC_CMD_REBOOT_MODE_NORMAL 0x0 /* enum */ +#define MC_CMD_REBOOT_MODE_SNAPPER 0x3 /* enum */ + +/* MC_CMD_REBOOT_MODE_OUT msgresponse */ +#define MC_CMD_REBOOT_MODE_OUT_LEN 4 +#define MC_CMD_REBOOT_MODE_OUT_VALUE_OFST 0 + + +/***********************************/ +/* MC_CMD_SENSOR_INFO + * Returns information about every available sensor. + */ +#define MC_CMD_SENSOR_INFO 0x41 + +/* MC_CMD_SENSOR_INFO_IN msgrequest */ +#define MC_CMD_SENSOR_INFO_IN_LEN 0 + +/* MC_CMD_SENSOR_INFO_OUT msgresponse */ +#define MC_CMD_SENSOR_INFO_OUT_LENMIN 12 +#define MC_CMD_SENSOR_INFO_OUT_LENMAX 252 +#define MC_CMD_SENSOR_INFO_OUT_LEN(num) (4+8*(num)) +#define MC_CMD_SENSOR_INFO_OUT_MASK_OFST 0 +#define MC_CMD_SENSOR_CONTROLLER_TEMP 0x0 /* enum */ +#define MC_CMD_SENSOR_PHY_COMMON_TEMP 0x1 /* enum */ +#define MC_CMD_SENSOR_CONTROLLER_COOLING 0x2 /* enum */ +#define MC_CMD_SENSOR_PHY0_TEMP 0x3 /* enum */ +#define MC_CMD_SENSOR_PHY0_COOLING 0x4 /* enum */ +#define MC_CMD_SENSOR_PHY1_TEMP 0x5 /* enum */ +#define MC_CMD_SENSOR_PHY1_COOLING 0x6 /* enum */ +#define MC_CMD_SENSOR_IN_1V0 0x7 /* enum */ +#define MC_CMD_SENSOR_IN_1V2 0x8 /* enum */ +#define MC_CMD_SENSOR_IN_1V8 0x9 /* enum */ +#define MC_CMD_SENSOR_IN_2V5 0xa /* enum */ +#define MC_CMD_SENSOR_IN_3V3 0xb /* enum */ +#define MC_CMD_SENSOR_IN_12V0 0xc /* enum */ +#define MC_CMD_SENSOR_ENTRY_OFST 4 +#define MC_CMD_SENSOR_ENTRY_LEN 8 +#define MC_CMD_SENSOR_ENTRY_LO_OFST 4 +#define MC_CMD_SENSOR_ENTRY_HI_OFST 8 +#define MC_CMD_SENSOR_ENTRY_MINNUM 1 +#define MC_CMD_SENSOR_ENTRY_MAXNUM 31 + +/* MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF structuredef */ +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_LEN 8 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1_OFST 0 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1_LEN 2 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1_LBN 0 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1_WIDTH 16 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX1_OFST 2 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX1_LEN 2 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX1_LBN 16 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX1_WIDTH 16 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN2_OFST 4 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN2_LEN 2 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN2_LBN 32 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN2_WIDTH 16 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX2_OFST 6 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX2_LEN 2 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX2_LBN 48 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX2_WIDTH 16 + + +/***********************************/ +/* MC_CMD_READ_SENSORS + * Returns the current reading from each sensor. + */ +#define MC_CMD_READ_SENSORS 0x42 + +/* MC_CMD_READ_SENSORS_IN msgrequest */ +#define MC_CMD_READ_SENSORS_IN_LEN 8 +#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_OFST 0 +#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_LEN 8 +#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_LO_OFST 0 +#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_HI_OFST 4 + +/* MC_CMD_READ_SENSORS_OUT msgresponse */ +#define MC_CMD_READ_SENSORS_OUT_LEN 0 + +/* MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF structuredef */ +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_LEN 3 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_OFST 0 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_LEN 2 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_LBN 0 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_WIDTH 16 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_OFST 2 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_LEN 1 +#define MC_CMD_SENSOR_STATE_OK 0x0 /* enum */ +#define MC_CMD_SENSOR_STATE_WARNING 0x1 /* enum */ +#define MC_CMD_SENSOR_STATE_FATAL 0x2 /* enum */ +#define MC_CMD_SENSOR_STATE_BROKEN 0x3 /* enum */ +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_LBN 16 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_WIDTH 8 + + +/***********************************/ +/* MC_CMD_GET_PHY_STATE + * Report current state of PHY. + */ +#define MC_CMD_GET_PHY_STATE 0x43 + +/* MC_CMD_GET_PHY_STATE_IN msgrequest */ +#define MC_CMD_GET_PHY_STATE_IN_LEN 0 + +/* MC_CMD_GET_PHY_STATE_OUT msgresponse */ +#define MC_CMD_GET_PHY_STATE_OUT_LEN 4 +#define MC_CMD_GET_PHY_STATE_OUT_STATE_OFST 0 +#define MC_CMD_PHY_STATE_OK 0x1 /* enum */ +#define MC_CMD_PHY_STATE_ZOMBIE 0x2 /* enum */ + + +/***********************************/ +/* MC_CMD_SETUP_8021QBB + * 802.1Qbb control. + */ +#define MC_CMD_SETUP_8021QBB 0x44 + +/* MC_CMD_SETUP_8021QBB_IN msgrequest */ +#define MC_CMD_SETUP_8021QBB_IN_LEN 32 +#define MC_CMD_SETUP_8021QBB_IN_TXQS_OFST 0 +#define MC_CMD_SETUP_8021QBB_IN_TXQS_LEN 32 + +/* MC_CMD_SETUP_8021QBB_OUT msgresponse */ +#define MC_CMD_SETUP_8021QBB_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_WOL_FILTER_GET + * Retrieve ID of any WoL filters. + */ +#define MC_CMD_WOL_FILTER_GET 0x45 + +/* MC_CMD_WOL_FILTER_GET_IN msgrequest */ +#define MC_CMD_WOL_FILTER_GET_IN_LEN 0 + +/* MC_CMD_WOL_FILTER_GET_OUT msgresponse */ +#define MC_CMD_WOL_FILTER_GET_OUT_LEN 4 +#define MC_CMD_WOL_FILTER_GET_OUT_FILTER_ID_OFST 0 + + +/***********************************/ +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD + * Add a protocol offload to NIC for lights-out state. + */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD 0x46 + +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN msgrequest */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LENMIN 8 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LENMAX 252 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LEN(num) (4+4*(num)) +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 +#define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP 0x1 /* enum */ +#define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS 0x2 /* enum */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_OFST 4 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_LEN 4 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_MINNUM 1 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_MAXNUM 62 + +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP msgrequest */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_LEN 14 +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_MAC_OFST 4 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_MAC_LEN 6 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_IP_OFST 10 + +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS msgrequest */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_LEN 42 +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_MAC_OFST 4 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_MAC_LEN 6 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_SNIPV6_OFST 10 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_SNIPV6_LEN 16 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_IPV6_OFST 26 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_IPV6_LEN 16 + +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT msgresponse */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN 4 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_FILTER_ID_OFST 0 + + +/***********************************/ +/* MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD + * Remove a protocol offload from NIC for lights-out state. + */ +#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD 0x47 + +/* MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN msgrequest */ +#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN 8 +#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 +#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_FILTER_ID_OFST 4 + +/* MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT msgresponse */ +#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_MAC_RESET_RESTORE + * Restore MAC after block reset. + */ +#define MC_CMD_MAC_RESET_RESTORE 0x48 + +/* MC_CMD_MAC_RESET_RESTORE_IN msgrequest */ +#define MC_CMD_MAC_RESET_RESTORE_IN_LEN 0 + +/* MC_CMD_MAC_RESET_RESTORE_OUT msgresponse */ +#define MC_CMD_MAC_RESET_RESTORE_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_TESTASSERT + */ +#define MC_CMD_TESTASSERT 0x49 + +/* MC_CMD_TESTASSERT_IN msgrequest */ +#define MC_CMD_TESTASSERT_IN_LEN 0 + +/* MC_CMD_TESTASSERT_OUT msgresponse */ +#define MC_CMD_TESTASSERT_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_WORKAROUND + * Enable/Disable a given workaround. + */ +#define MC_CMD_WORKAROUND 0x4a + +/* MC_CMD_WORKAROUND_IN msgrequest */ +#define MC_CMD_WORKAROUND_IN_LEN 8 +#define MC_CMD_WORKAROUND_IN_TYPE_OFST 0 +#define MC_CMD_WORKAROUND_BUG17230 0x1 /* enum */ +#define MC_CMD_WORKAROUND_IN_ENABLED_OFST 4 + +/* MC_CMD_WORKAROUND_OUT msgresponse */ +#define MC_CMD_WORKAROUND_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_PHY_MEDIA_INFO + * Read media-specific data from PHY. + */ +#define MC_CMD_GET_PHY_MEDIA_INFO 0x4b + +/* MC_CMD_GET_PHY_MEDIA_INFO_IN msgrequest */ +#define MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN 4 +#define MC_CMD_GET_PHY_MEDIA_INFO_IN_PAGE_OFST 0 + +/* MC_CMD_GET_PHY_MEDIA_INFO_OUT msgresponse */ +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMIN 5 +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMAX 255 +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN(num) (4+1*(num)) +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATALEN_OFST 0 +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST 4 +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_LEN 1 +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_MINNUM 1 +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_MAXNUM 251 + + +/***********************************/ +/* MC_CMD_NVRAM_TEST + * Test a particular NVRAM partition. + */ +#define MC_CMD_NVRAM_TEST 0x4c + +/* MC_CMD_NVRAM_TEST_IN msgrequest */ +#define MC_CMD_NVRAM_TEST_IN_LEN 4 +#define MC_CMD_NVRAM_TEST_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ + +/* MC_CMD_NVRAM_TEST_OUT msgresponse */ +#define MC_CMD_NVRAM_TEST_OUT_LEN 4 +#define MC_CMD_NVRAM_TEST_OUT_RESULT_OFST 0 +#define MC_CMD_NVRAM_TEST_PASS 0x0 /* enum */ +#define MC_CMD_NVRAM_TEST_FAIL 0x1 /* enum */ +#define MC_CMD_NVRAM_TEST_NOTSUPP 0x2 /* enum */ + + +/***********************************/ +/* MC_CMD_MRSFP_TWEAK + * Read status and/or set parameters for the 'mrsfp' driver. + */ +#define MC_CMD_MRSFP_TWEAK 0x4d + +/* MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG msgrequest */ +#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_LEN 16 +#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_TXEQ_LEVEL_OFST 0 +#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_TXEQ_DT_CFG_OFST 4 +#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_RXEQ_BOOST_OFST 8 +#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_RXEQ_DT_CFG_OFST 12 + +/* MC_CMD_MRSFP_TWEAK_IN_READ_ONLY msgrequest */ +#define MC_CMD_MRSFP_TWEAK_IN_READ_ONLY_LEN 0 + +/* MC_CMD_MRSFP_TWEAK_OUT msgresponse */ +#define MC_CMD_MRSFP_TWEAK_OUT_LEN 12 +#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_INPUTS_OFST 0 +#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_OUTPUTS_OFST 4 +#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_OFST 8 +#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_OUT 0x0 /* enum */ +#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_IN 0x1 /* enum */ + + +/***********************************/ +/* MC_CMD_SENSOR_SET_LIMS + * Adjusts the sensor limits. + */ +#define MC_CMD_SENSOR_SET_LIMS 0x4e + +/* MC_CMD_SENSOR_SET_LIMS_IN msgrequest */ +#define MC_CMD_SENSOR_SET_LIMS_IN_LEN 20 +#define MC_CMD_SENSOR_SET_LIMS_IN_SENSOR_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_SENSOR_INFO/MC_CMD_SENSOR_INFO_OUT/MASK */ +#define MC_CMD_SENSOR_SET_LIMS_IN_LOW0_OFST 4 +#define MC_CMD_SENSOR_SET_LIMS_IN_HI0_OFST 8 +#define MC_CMD_SENSOR_SET_LIMS_IN_LOW1_OFST 12 +#define MC_CMD_SENSOR_SET_LIMS_IN_HI1_OFST 16 + +/* MC_CMD_SENSOR_SET_LIMS_OUT msgresponse */ +#define MC_CMD_SENSOR_SET_LIMS_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_RESOURCE_LIMITS + */ +#define MC_CMD_GET_RESOURCE_LIMITS 0x4f + +/* MC_CMD_GET_RESOURCE_LIMITS_IN msgrequest */ +#define MC_CMD_GET_RESOURCE_LIMITS_IN_LEN 0 + +/* MC_CMD_GET_RESOURCE_LIMITS_OUT msgresponse */ +#define MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN 16 +#define MC_CMD_GET_RESOURCE_LIMITS_OUT_BUFTBL_OFST 0 +#define MC_CMD_GET_RESOURCE_LIMITS_OUT_EVQ_OFST 4 +#define MC_CMD_GET_RESOURCE_LIMITS_OUT_RXQ_OFST 8 +#define MC_CMD_GET_RESOURCE_LIMITS_OUT_TXQ_OFST 12 + +/* MC_CMD_RESOURCE_SPECIFIER enum */ +#define MC_CMD_RESOURCE_INSTANCE_ANY 0xffffffff /* enum */ +#define MC_CMD_RESOURCE_INSTANCE_NONE 0xfffffffe /* enum */ + + +/***********************************/ +/* MC_CMD_INIT_EVQ + */ +#define MC_CMD_INIT_EVQ 0x50 + +/* MC_CMD_INIT_EVQ_IN msgrequest */ +#define MC_CMD_INIT_EVQ_IN_LENMIN 36 +#define MC_CMD_INIT_EVQ_IN_LENMAX 540 +#define MC_CMD_INIT_EVQ_IN_LEN(num) (28+8*(num)) +#define MC_CMD_INIT_EVQ_IN_SIZE_OFST 0 +#define MC_CMD_INIT_EVQ_IN_INSTANCE_OFST 4 +#define MC_CMD_INIT_EVQ_IN_TMR_LOAD_OFST 8 +#define MC_CMD_INIT_EVQ_IN_TMR_RELOAD_OFST 12 +#define MC_CMD_INIT_EVQ_IN_FLAGS_OFST 16 +#define MC_CMD_INIT_EVQ_IN_FLAG_INTERRUPTING_LBN 0 +#define MC_CMD_INIT_EVQ_IN_FLAG_INTERRUPTING_WIDTH 1 +#define MC_CMD_INIT_EVQ_IN_FLAG_RPTR_DOS_LBN 1 +#define MC_CMD_INIT_EVQ_IN_FLAG_RPTR_DOS_WIDTH 1 +#define MC_CMD_INIT_EVQ_IN_TMR_MODE_OFST 20 +#define MC_CMD_INIT_EVQ_IN_TMR_MODE_DIS 0x0 /* enum */ +#define MC_CMD_INIT_EVQ_IN_TMR_IMMED_START 0x1 /* enum */ +#define MC_CMD_INIT_EVQ_IN_TMR_TRIG_START 0x2 /* enum */ +#define MC_CMD_INIT_EVQ_IN_TMR_INT_HLDOFF 0x3 /* enum */ +#define MC_CMD_INIT_EVQ_IN_TARGET_EVQ_OFST 24 +#define MC_CMD_INIT_EVQ_IN_IRQ_NUM_OFST 24 +#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_OFST 28 +#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_LEN 8 +#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_LO_OFST 28 +#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_HI_OFST 32 +#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_MINNUM 1 +#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_MAXNUM 64 + +/* MC_CMD_INIT_EVQ_OUT msgresponse */ +#define MC_CMD_INIT_EVQ_OUT_LEN 4 +#define MC_CMD_INIT_EVQ_OUT_IRQ_OFST 0 + +/* QUEUE_CRC_MODE structuredef */ +#define QUEUE_CRC_MODE_LEN 1 +#define QUEUE_CRC_MODE_MODE_LBN 0 +#define QUEUE_CRC_MODE_MODE_WIDTH 4 +#define QUEUE_CRC_MODE_NONE 0x0 /* enum */ +#define QUEUE_CRC_MODE_FCOE 0x1 /* enum */ +#define QUEUE_CRC_MODE_ISCSI_HDR 0x2 /* enum */ +#define QUEUE_CRC_MODE_ISCSI 0x3 /* enum */ +#define QUEUE_CRC_MODE_FCOIPOE 0x4 /* enum */ +#define QUEUE_CRC_MODE_MPA 0x5 /* enum */ +#define QUEUE_CRC_MODE_SPARE_LBN 4 +#define QUEUE_CRC_MODE_SPARE_WIDTH 4 + + +/***********************************/ +/* MC_CMD_INIT_RXQ + */ +#define MC_CMD_INIT_RXQ 0x51 + +/* MC_CMD_INIT_RXQ_IN msgrequest */ +#define MC_CMD_INIT_RXQ_IN_LENMIN 32 +#define MC_CMD_INIT_RXQ_IN_LENMAX 248 +#define MC_CMD_INIT_RXQ_IN_LEN(num) (24+8*(num)) +#define MC_CMD_INIT_RXQ_IN_SIZE_OFST 0 +#define MC_CMD_INIT_RXQ_IN_TARGET_EVQ_OFST 4 +#define MC_CMD_INIT_RXQ_IN_LABEL_OFST 8 +#define MC_CMD_INIT_RXQ_IN_INSTANCE_OFST 12 +#define MC_CMD_INIT_RXQ_IN_FLAGS_OFST 16 +#define MC_CMD_INIT_RXQ_IN_FLAG_BUFF_MODE_LBN 0 +#define MC_CMD_INIT_RXQ_IN_FLAG_BUFF_MODE_WIDTH 1 +#define MC_CMD_INIT_RXQ_IN_FLAG_HDR_SPLIT_LBN 1 +#define MC_CMD_INIT_RXQ_IN_FLAG_HDR_SPLIT_WIDTH 1 +#define MC_CMD_INIT_RXQ_IN_FLAG_PKT_EDIT_LBN 2 +#define MC_CMD_INIT_RXQ_IN_FLAG_PKT_EDIT_WIDTH 1 +#define MC_CMD_INIT_RXQ_IN_CRC_MODE_LBN 3 +#define MC_CMD_INIT_RXQ_IN_CRC_MODE_WIDTH 4 +#define MC_CMD_INIT_RXQ_IN_OWNER_ID_OFST 20 +#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_OFST 24 +#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_LEN 8 +#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_LO_OFST 24 +#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_HI_OFST 28 +#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_MINNUM 1 +#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_MAXNUM 28 + +/* MC_CMD_INIT_RXQ_OUT msgresponse */ +#define MC_CMD_INIT_RXQ_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_INIT_TXQ + */ +#define MC_CMD_INIT_TXQ 0x52 + +/* MC_CMD_INIT_TXQ_IN msgrequest */ +#define MC_CMD_INIT_TXQ_IN_LENMIN 32 +#define MC_CMD_INIT_TXQ_IN_LENMAX 248 +#define MC_CMD_INIT_TXQ_IN_LEN(num) (24+8*(num)) +#define MC_CMD_INIT_TXQ_IN_SIZE_OFST 0 +#define MC_CMD_INIT_TXQ_IN_TARGET_EVQ_OFST 4 +#define MC_CMD_INIT_TXQ_IN_LABEL_OFST 8 +#define MC_CMD_INIT_TXQ_IN_INSTANCE_OFST 12 +#define MC_CMD_INIT_TXQ_IN_FLAGS_OFST 16 +#define MC_CMD_INIT_TXQ_IN_FLAG_BUFF_MODE_LBN 0 +#define MC_CMD_INIT_TXQ_IN_FLAG_BUFF_MODE_WIDTH 1 +#define MC_CMD_INIT_TXQ_IN_FLAG_IP_CSUM_DIS_LBN 1 +#define MC_CMD_INIT_TXQ_IN_FLAG_IP_CSUM_DIS_WIDTH 1 +#define MC_CMD_INIT_TXQ_IN_FLAG_TCP_CSUM_DIS_LBN 2 +#define MC_CMD_INIT_TXQ_IN_FLAG_TCP_CSUM_DIS_WIDTH 1 +#define MC_CMD_INIT_TXQ_IN_CRC_MODE_LBN 4 +#define MC_CMD_INIT_TXQ_IN_CRC_MODE_WIDTH 4 +#define MC_CMD_INIT_TXQ_IN_OWNER_ID_OFST 20 +#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_OFST 24 +#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_LEN 8 +#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_LO_OFST 24 +#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_HI_OFST 28 +#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_MINNUM 1 +#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_MAXNUM 28 + +/* MC_CMD_INIT_TXQ_OUT msgresponse */ +#define MC_CMD_INIT_TXQ_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_FINI_EVQ + */ +#define MC_CMD_FINI_EVQ 0x55 + +/* MC_CMD_FINI_EVQ_IN msgrequest */ +#define MC_CMD_FINI_EVQ_IN_LEN 4 +#define MC_CMD_FINI_EVQ_IN_INSTANCE_OFST 0 + +/* MC_CMD_FINI_EVQ_OUT msgresponse */ +#define MC_CMD_FINI_EVQ_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_FINI_RXQ + */ +#define MC_CMD_FINI_RXQ 0x56 + +/* MC_CMD_FINI_RXQ_IN msgrequest */ +#define MC_CMD_FINI_RXQ_IN_LEN 4 +#define MC_CMD_FINI_RXQ_IN_INSTANCE_OFST 0 + +/* MC_CMD_FINI_RXQ_OUT msgresponse */ +#define MC_CMD_FINI_RXQ_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_FINI_TXQ + */ +#define MC_CMD_FINI_TXQ 0x57 + +/* MC_CMD_FINI_TXQ_IN msgrequest */ +#define MC_CMD_FINI_TXQ_IN_LEN 4 +#define MC_CMD_FINI_TXQ_IN_INSTANCE_OFST 0 + +/* MC_CMD_FINI_TXQ_OUT msgresponse */ +#define MC_CMD_FINI_TXQ_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_DRIVER_EVENT + */ +#define MC_CMD_DRIVER_EVENT 0x5a + +/* MC_CMD_DRIVER_EVENT_IN msgrequest */ +#define MC_CMD_DRIVER_EVENT_IN_LEN 12 +#define MC_CMD_DRIVER_EVENT_IN_EVQ_OFST 0 +#define MC_CMD_DRIVER_EVENT_IN_DATA_OFST 4 +#define MC_CMD_DRIVER_EVENT_IN_DATA_LEN 8 +#define MC_CMD_DRIVER_EVENT_IN_DATA_LO_OFST 4 +#define MC_CMD_DRIVER_EVENT_IN_DATA_HI_OFST 8 + + +/***********************************/ +/* MC_CMD_PROXY_CMD + */ +#define MC_CMD_PROXY_CMD 0x5b + +/* MC_CMD_PROXY_CMD_IN msgrequest */ +#define MC_CMD_PROXY_CMD_IN_LEN 4 +#define MC_CMD_PROXY_CMD_IN_TARGET_OFST 0 + + +/***********************************/ +/* MC_CMD_ALLOC_OWNER_IDS + */ +#define MC_CMD_ALLOC_OWNER_IDS 0x54 + +/* MC_CMD_ALLOC_OWNER_IDS_IN msgrequest */ +#define MC_CMD_ALLOC_OWNER_IDS_IN_LEN 4 +#define MC_CMD_ALLOC_OWNER_IDS_IN_NIDS_OFST 0 + +/* MC_CMD_ALLOC_OWNER_IDS_OUT msgresponse */ +#define MC_CMD_ALLOC_OWNER_IDS_OUT_LEN 12 +#define MC_CMD_ALLOC_OWNER_IDS_OUT_HANDLE_OFST 0 +#define MC_CMD_ALLOC_OWNER_IDS_OUT_NIDS_OFST 4 +#define MC_CMD_ALLOC_OWNER_IDS_OUT_BASE_OFST 8 + + +/***********************************/ +/* MC_CMD_FREE_OWNER_IDS + */ +#define MC_CMD_FREE_OWNER_IDS 0x59 + +/* MC_CMD_FREE_OWNER_IDS_IN msgrequest */ +#define MC_CMD_FREE_OWNER_IDS_IN_LEN 4 +#define MC_CMD_FREE_OWNER_IDS_IN_HANDLE_OFST 0 + +/* MC_CMD_FREE_OWNER_IDS_OUT msgresponse */ +#define MC_CMD_FREE_OWNER_IDS_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_ALLOC_BUFTBL_CHUNK + */ +#define MC_CMD_ALLOC_BUFTBL_CHUNK 0x5c + +/* MC_CMD_ALLOC_BUFTBL_CHUNK_IN msgrequest */ +#define MC_CMD_ALLOC_BUFTBL_CHUNK_IN_LEN 8 +#define MC_CMD_ALLOC_BUFTBL_CHUNK_IN_OWNER_OFST 0 +#define MC_CMD_ALLOC_BUFTBL_CHUNK_IN_PAGE_SIZE_OFST 4 + +/* MC_CMD_ALLOC_BUFTBL_CHUNK_OUT msgresponse */ +#define MC_CMD_ALLOC_BUFTBL_CHUNK_OUT_LEN 12 +#define MC_CMD_ALLOC_BUFTBL_CHUNK_OUT_HANDLE_OFST 0 +#define MC_CMD_ALLOC_BUFTBL_CHUNK_OUT_NUMENTRIES_OFST 4 +#define MC_CMD_ALLOC_BUFTBL_CHUNK_OUT_ID_OFST 8 + + +/***********************************/ +/* MC_CMD_PROGRAM_BUFTBL_ENTRIES + */ +#define MC_CMD_PROGRAM_BUFTBL_ENTRIES 0x5d + +/* MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN msgrequest */ +#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LENMIN 20 +#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LENMAX 252 +#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LEN(num) (12+8*(num)) +#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_HANDLE_OFST 0 +#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_FIRSTID_OFST 4 +#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_NUMENTRIES_OFST 8 +#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_OFST 12 +#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_LEN 8 +#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_LO_OFST 12 +#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_HI_OFST 16 +#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_MINNUM 1 +#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_MAXNUM 30 + +/* MC_CMD_PROGRAM_BUFTBL_ENTRIES_OUT msgresponse */ +#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_FREE_BUFTBL_CHUNK + */ +#define MC_CMD_FREE_BUFTBL_CHUNK 0x5e + +/* MC_CMD_FREE_BUFTBL_CHUNK_IN msgrequest */ +#define MC_CMD_FREE_BUFTBL_CHUNK_IN_LEN 4 +#define MC_CMD_FREE_BUFTBL_CHUNK_IN_HANDLE_OFST 0 + +/* MC_CMD_FREE_BUFTBL_CHUNK_OUT msgresponse */ +#define MC_CMD_FREE_BUFTBL_CHUNK_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_PF_COUNT + */ +#define MC_CMD_GET_PF_COUNT 0x60 + +/* MC_CMD_GET_PF_COUNT_IN msgrequest */ +#define MC_CMD_GET_PF_COUNT_IN_LEN 0 + +/* MC_CMD_GET_PF_COUNT_OUT msgresponse */ +#define MC_CMD_GET_PF_COUNT_OUT_LEN 1 +#define MC_CMD_GET_PF_COUNT_OUT_PF_COUNT_OFST 0 +#define MC_CMD_GET_PF_COUNT_OUT_PF_COUNT_LEN 1 + + +/***********************************/ +/* MC_CMD_FILTER_OP + */ +#define MC_CMD_FILTER_OP 0x61 + +/* MC_CMD_FILTER_OP_IN msgrequest */ +#define MC_CMD_FILTER_OP_IN_LEN 100 +#define MC_CMD_FILTER_OP_IN_OP_OFST 0 +#define MC_CMD_FILTER_OP_IN_OP_INSERT 0x0 /* enum */ +#define MC_CMD_FILTER_OP_IN_OP_REMOVE 0x1 /* enum */ +#define MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE 0x2 /* enum */ +#define MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE 0x3 /* enum */ +#define MC_CMD_FILTER_OP_IN_HANDLE_OFST 4 +#define MC_CMD_FILTER_OP_IN_MATCH_FIELDS_OFST 8 +#define MC_CMD_FILTER_OP_IN_MATCH_SRC_IP_LBN 0 +#define MC_CMD_FILTER_OP_IN_MATCH_SRC_IP_WIDTH 1 +#define MC_CMD_FILTER_OP_IN_MATCH_DST_IP_LBN 1 +#define MC_CMD_FILTER_OP_IN_MATCH_DST_IP_WIDTH 1 +#define MC_CMD_FILTER_OP_IN_MATCH_SRC_MAC_LBN 2 +#define MC_CMD_FILTER_OP_IN_MATCH_SRC_MAC_WIDTH 1 +#define MC_CMD_FILTER_OP_IN_MATCH_SRC_PORT_LBN 3 +#define MC_CMD_FILTER_OP_IN_MATCH_SRC_PORT_WIDTH 1 +#define MC_CMD_FILTER_OP_IN_MATCH_DST_MAC_LBN 4 +#define MC_CMD_FILTER_OP_IN_MATCH_DST_MAC_WIDTH 1 +#define MC_CMD_FILTER_OP_IN_MATCH_DST_PORT_LBN 5 +#define MC_CMD_FILTER_OP_IN_MATCH_DST_PORT_WIDTH 1 +#define MC_CMD_FILTER_OP_IN_MATCH_ETHER_TYPE_LBN 6 +#define MC_CMD_FILTER_OP_IN_MATCH_ETHER_TYPE_WIDTH 1 +#define MC_CMD_FILTER_OP_IN_MATCH_INNER_VLAN_LBN 7 +#define MC_CMD_FILTER_OP_IN_MATCH_INNER_VLAN_WIDTH 1 +#define MC_CMD_FILTER_OP_IN_MATCH_OUTER_VLAN_LBN 8 +#define MC_CMD_FILTER_OP_IN_MATCH_OUTER_VLAN_WIDTH 1 +#define MC_CMD_FILTER_OP_IN_MATCH_IP_PROTO_LBN 9 +#define MC_CMD_FILTER_OP_IN_MATCH_IP_PROTO_WIDTH 1 +#define MC_CMD_FILTER_OP_IN_MATCH_FWDEF0_LBN 10 +#define MC_CMD_FILTER_OP_IN_MATCH_FWDEF0_WIDTH 1 +#define MC_CMD_FILTER_OP_IN_MATCH_FWDEF1_LBN 11 +#define MC_CMD_FILTER_OP_IN_MATCH_FWDEF1_WIDTH 1 +#define MC_CMD_FILTER_OP_IN_RX_DEST_OFST 12 +#define MC_CMD_FILTER_OP_IN_RX_DEST_DROP 0x0 /* enum */ +#define MC_CMD_FILTER_OP_IN_RX_DEST_HOST 0x1 /* enum */ +#define MC_CMD_FILTER_OP_IN_RX_DEST_MC 0x2 /* enum */ +#define MC_CMD_FILTER_OP_IN_RX_DEST_TX0 0x3 /* enum */ +#define MC_CMD_FILTER_OP_IN_RX_DEST_TX1 0x4 /* enum */ +#define MC_CMD_FILTER_OP_IN_RX_QUEUE_OFST 16 +#define MC_CMD_FILTER_OP_IN_RX_FLAGS_OFST 20 +#define MC_CMD_FILTER_OP_IN_RX_FLAG_RSS_LBN 0 +#define MC_CMD_FILTER_OP_IN_RX_FLAG_RSS_WIDTH 1 +#define MC_CMD_FILTER_OP_IN_RSS_CONTEXT_OFST 24 +#define MC_CMD_FILTER_OP_IN_TX_DOMAIN_OFST 28 +#define MC_CMD_FILTER_OP_IN_TX_DEST_OFST 32 +#define MC_CMD_FILTER_OP_IN_TX_DEST_MAC_LBN 0 +#define MC_CMD_FILTER_OP_IN_TX_DEST_MAC_WIDTH 1 +#define MC_CMD_FILTER_OP_IN_TX_DEST_PM_LBN 1 +#define MC_CMD_FILTER_OP_IN_TX_DEST_PM_WIDTH 1 +#define MC_CMD_FILTER_OP_IN_SRC_MAC_OFST 36 +#define MC_CMD_FILTER_OP_IN_SRC_MAC_LEN 6 +#define MC_CMD_FILTER_OP_IN_SRC_PORT_OFST 42 +#define MC_CMD_FILTER_OP_IN_SRC_PORT_LEN 2 +#define MC_CMD_FILTER_OP_IN_DST_MAC_OFST 44 +#define MC_CMD_FILTER_OP_IN_DST_MAC_LEN 6 +#define MC_CMD_FILTER_OP_IN_DST_PORT_OFST 50 +#define MC_CMD_FILTER_OP_IN_DST_PORT_LEN 2 +#define MC_CMD_FILTER_OP_IN_ETHER_TYPE_OFST 52 +#define MC_CMD_FILTER_OP_IN_ETHER_TYPE_LEN 2 +#define MC_CMD_FILTER_OP_IN_INNER_VLAN_OFST 54 +#define MC_CMD_FILTER_OP_IN_INNER_VLAN_LEN 2 +#define MC_CMD_FILTER_OP_IN_OUTER_VLAN_OFST 56 +#define MC_CMD_FILTER_OP_IN_OUTER_VLAN_LEN 2 +#define MC_CMD_FILTER_OP_IN_IP_PROTO_OFST 58 +#define MC_CMD_FILTER_OP_IN_IP_PROTO_LEN 2 +#define MC_CMD_FILTER_OP_IN_FWDEF0_OFST 60 +#define MC_CMD_FILTER_OP_IN_FWDEF1_OFST 64 +#define MC_CMD_FILTER_OP_IN_SRC_IP_OFST 68 +#define MC_CMD_FILTER_OP_IN_SRC_IP_LEN 16 +#define MC_CMD_FILTER_OP_IN_DST_IP_OFST 84 +#define MC_CMD_FILTER_OP_IN_DST_IP_LEN 16 + +/* MC_CMD_FILTER_OP_OUT msgresponse */ +#define MC_CMD_FILTER_OP_OUT_LEN 8 +#define MC_CMD_FILTER_OP_OUT_OP_OFST 0 +#define MC_CMD_FILTER_OP_OUT_OP_INSERT 0x0 /* enum */ +#define MC_CMD_FILTER_OP_OUT_OP_REMOVE 0x1 /* enum */ +#define MC_CMD_FILTER_OP_OUT_OP_SUBSCRIBE 0x2 /* enum */ +#define MC_CMD_FILTER_OP_OUT_OP_UNSUBSCRIBE 0x3 /* enum */ +#define MC_CMD_FILTER_OP_OUT_HANDLE_OFST 4 + + +/***********************************/ +/* MC_CMD_SET_PF_COUNT + */ +#define MC_CMD_SET_PF_COUNT 0x62 + +/* MC_CMD_SET_PF_COUNT_IN msgrequest */ +#define MC_CMD_SET_PF_COUNT_IN_LEN 4 +#define MC_CMD_SET_PF_COUNT_IN_PF_COUNT_OFST 0 + +/* MC_CMD_SET_PF_COUNT_OUT msgresponse */ +#define MC_CMD_SET_PF_COUNT_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_PORT_ASSIGNMENT + */ +#define MC_CMD_GET_PORT_ASSIGNMENT 0x63 + +/* MC_CMD_GET_PORT_ASSIGNMENT_IN msgrequest */ +#define MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN 0 + +/* MC_CMD_GET_PORT_ASSIGNMENT_OUT msgresponse */ +#define MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN 4 +#define MC_CMD_GET_PORT_ASSIGNMENT_OUT_PORT_OFST 0 + + +/***********************************/ +/* MC_CMD_SET_PORT_ASSIGNMENT + */ +#define MC_CMD_SET_PORT_ASSIGNMENT 0x64 + +/* MC_CMD_SET_PORT_ASSIGNMENT_IN msgrequest */ +#define MC_CMD_SET_PORT_ASSIGNMENT_IN_LEN 4 +#define MC_CMD_SET_PORT_ASSIGNMENT_IN_PORT_OFST 0 + +/* MC_CMD_SET_PORT_ASSIGNMENT_OUT msgresponse */ +#define MC_CMD_SET_PORT_ASSIGNMENT_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_ALLOC_VIS + */ +#define MC_CMD_ALLOC_VIS 0x65 + +/* MC_CMD_ALLOC_VIS_IN msgrequest */ +#define MC_CMD_ALLOC_VIS_IN_LEN 4 +#define MC_CMD_ALLOC_VIS_IN_VI_COUNT_OFST 0 + +/* MC_CMD_ALLOC_VIS_OUT msgresponse */ +#define MC_CMD_ALLOC_VIS_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_FREE_VIS + */ +#define MC_CMD_FREE_VIS 0x66 + +/* MC_CMD_FREE_VIS_IN msgrequest */ +#define MC_CMD_FREE_VIS_IN_LEN 0 + +/* MC_CMD_FREE_VIS_OUT msgresponse */ +#define MC_CMD_FREE_VIS_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_SRIOV_CFG + */ +#define MC_CMD_GET_SRIOV_CFG 0x67 + +/* MC_CMD_GET_SRIOV_CFG_IN msgrequest */ +#define MC_CMD_GET_SRIOV_CFG_IN_LEN 0 + +/* MC_CMD_GET_SRIOV_CFG_OUT msgresponse */ +#define MC_CMD_GET_SRIOV_CFG_OUT_LEN 20 +#define MC_CMD_GET_SRIOV_CFG_OUT_VF_CURRENT_OFST 0 +#define MC_CMD_GET_SRIOV_CFG_OUT_VF_MAX_OFST 4 +#define MC_CMD_GET_SRIOV_CFG_OUT_FLAGS_OFST 8 +#define MC_CMD_GET_SRIOV_CFG_OUT_VF_ENABLED_LBN 0 +#define MC_CMD_GET_SRIOV_CFG_OUT_VF_ENABLED_WIDTH 1 +#define MC_CMD_GET_SRIOV_CFG_OUT_VF_OFFSET_OFST 12 +#define MC_CMD_GET_SRIOV_CFG_OUT_VF_STRIDE_OFST 16 + + +/***********************************/ +/* MC_CMD_SET_SRIOV_CFG + */ +#define MC_CMD_SET_SRIOV_CFG 0x68 + +/* MC_CMD_SET_SRIOV_CFG_IN msgrequest */ +#define MC_CMD_SET_SRIOV_CFG_IN_LEN 20 +#define MC_CMD_SET_SRIOV_CFG_IN_VF_CURRENT_OFST 0 +#define MC_CMD_SET_SRIOV_CFG_IN_VF_MAX_OFST 4 +#define MC_CMD_SET_SRIOV_CFG_IN_FLAGS_OFST 8 +#define MC_CMD_SET_SRIOV_CFG_IN_VF_ENABLED_LBN 0 +#define MC_CMD_SET_SRIOV_CFG_IN_VF_ENABLED_WIDTH 1 +#define MC_CMD_SET_SRIOV_CFG_IN_VF_OFFSET_OFST 12 +#define MC_CMD_SET_SRIOV_CFG_IN_VF_STRIDE_OFST 16 + +/* MC_CMD_SET_SRIOV_CFG_OUT msgresponse */ +#define MC_CMD_SET_SRIOV_CFG_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_VI_COUNT + */ +#define MC_CMD_GET_VI_COUNT 0x69 + +/* MC_CMD_GET_VI_COUNT_IN msgrequest */ +#define MC_CMD_GET_VI_COUNT_IN_LEN 0 + +/* MC_CMD_GET_VI_COUNT_OUT msgresponse */ +#define MC_CMD_GET_VI_COUNT_OUT_LEN 4 +#define MC_CMD_GET_VI_COUNT_OUT_VI_COUNT_OFST 0 + + +/***********************************/ +/* MC_CMD_GET_VECTOR_CFG + */ +#define MC_CMD_GET_VECTOR_CFG 0x70 + +/* MC_CMD_GET_VECTOR_CFG_IN msgrequest */ +#define MC_CMD_GET_VECTOR_CFG_IN_LEN 0 + +/* MC_CMD_GET_VECTOR_CFG_OUT msgresponse */ +#define MC_CMD_GET_VECTOR_CFG_OUT_LEN 12 +#define MC_CMD_GET_VECTOR_CFG_OUT_VEC_BASE_OFST 0 +#define MC_CMD_GET_VECTOR_CFG_OUT_VECS_PER_PF_OFST 4 +#define MC_CMD_GET_VECTOR_CFG_OUT_VECS_PER_VF_OFST 8 + + +/***********************************/ +/* MC_CMD_SET_VECTOR_CFG + */ +#define MC_CMD_SET_VECTOR_CFG 0x71 + +/* MC_CMD_SET_VECTOR_CFG_IN msgrequest */ +#define MC_CMD_SET_VECTOR_CFG_IN_LEN 12 +#define MC_CMD_SET_VECTOR_CFG_IN_VEC_BASE_OFST 0 +#define MC_CMD_SET_VECTOR_CFG_IN_VECS_PER_PF_OFST 4 +#define MC_CMD_SET_VECTOR_CFG_IN_VECS_PER_VF_OFST 8 + +/* MC_CMD_SET_VECTOR_CFG_OUT msgresponse */ +#define MC_CMD_SET_VECTOR_CFG_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_ALLOC_PIOBUF + */ +#define MC_CMD_ALLOC_PIOBUF 0x72 + +/* MC_CMD_ALLOC_PIOBUF_IN msgrequest */ +#define MC_CMD_ALLOC_PIOBUF_IN_LEN 0 + +/* MC_CMD_ALLOC_PIOBUF_OUT msgresponse */ +#define MC_CMD_ALLOC_PIOBUF_OUT_LEN 4 +#define MC_CMD_ALLOC_PIOBUF_OUT_PIOBUF_HANDLE_OFST 0 + + +/***********************************/ +/* MC_CMD_FREE_PIOBUF + */ +#define MC_CMD_FREE_PIOBUF 0x73 + +/* MC_CMD_FREE_PIOBUF_IN msgrequest */ +#define MC_CMD_FREE_PIOBUF_IN_LEN 4 +#define MC_CMD_FREE_PIOBUF_IN_PIOBUF_HANDLE_OFST 0 + +/* MC_CMD_FREE_PIOBUF_OUT msgresponse */ +#define MC_CMD_FREE_PIOBUF_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_V2_EXTN + */ +#define MC_CMD_V2_EXTN 0x7f + +/* MC_CMD_V2_EXTN_IN msgrequest */ +#define MC_CMD_V2_EXTN_IN_LEN 4 +#define MC_CMD_V2_EXTN_IN_EXTENDED_CMD_LBN 0 +#define MC_CMD_V2_EXTN_IN_EXTENDED_CMD_WIDTH 15 +#define MC_CMD_V2_EXTN_IN_UNUSED_LBN 15 +#define MC_CMD_V2_EXTN_IN_UNUSED_WIDTH 1 +#define MC_CMD_V2_EXTN_IN_ACTUAL_LEN_LBN 16 +#define MC_CMD_V2_EXTN_IN_ACTUAL_LEN_WIDTH 10 +#define MC_CMD_V2_EXTN_IN_UNUSED2_LBN 26 +#define MC_CMD_V2_EXTN_IN_UNUSED2_WIDTH 6 + + +/***********************************/ +/* MC_CMD_TCM_BUCKET_ALLOC + */ +#define MC_CMD_TCM_BUCKET_ALLOC 0x80 + +/* MC_CMD_TCM_BUCKET_ALLOC_IN msgrequest */ +#define MC_CMD_TCM_BUCKET_ALLOC_IN_LEN 0 + +/* MC_CMD_TCM_BUCKET_ALLOC_OUT msgresponse */ +#define MC_CMD_TCM_BUCKET_ALLOC_OUT_LEN 4 +#define MC_CMD_TCM_BUCKET_ALLOC_OUT_BUCKET_OFST 0 + + +/***********************************/ +/* MC_CMD_TCM_BUCKET_FREE + */ +#define MC_CMD_TCM_BUCKET_FREE 0x81 + +/* MC_CMD_TCM_BUCKET_FREE_IN msgrequest */ +#define MC_CMD_TCM_BUCKET_FREE_IN_LEN 4 +#define MC_CMD_TCM_BUCKET_FREE_IN_BUCKET_OFST 0 + +/* MC_CMD_TCM_BUCKET_FREE_OUT msgresponse */ +#define MC_CMD_TCM_BUCKET_FREE_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_TCM_TXQ_INIT + */ +#define MC_CMD_TCM_TXQ_INIT 0x82 + +/* MC_CMD_TCM_TXQ_INIT_IN msgrequest */ +#define MC_CMD_TCM_TXQ_INIT_IN_LEN 28 +#define MC_CMD_TCM_TXQ_INIT_IN_QID_OFST 0 +#define MC_CMD_TCM_TXQ_INIT_IN_LABEL_OFST 4 +#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAGS_OFST 8 +#define MC_CMD_TCM_TXQ_INIT_IN_RP_BKT_OFST 12 +#define MC_CMD_TCM_TXQ_INIT_IN_MAX_BKT1_OFST 16 +#define MC_CMD_TCM_TXQ_INIT_IN_MAX_BKT2_OFST 20 +#define MC_CMD_TCM_TXQ_INIT_IN_MIN_BKT_OFST 24 + +/* MC_CMD_TCM_TXQ_INIT_OUT msgresponse */ +#define MC_CMD_TCM_TXQ_INIT_OUT_LEN 0 + +#endif /* _SIENA_MC_DRIVER_PCOL_H */ +/*! \cidoxg_end */ diff --git a/sys/dev/sfxge/common/efx_regs_pci.h b/sys/dev/sfxge/common/efx_regs_pci.h new file mode 100644 index 000000000000..cb5efab71590 --- /dev/null +++ b/sys/dev/sfxge/common/efx_regs_pci.h @@ -0,0 +1,2376 @@ +/*- + * Copyright 2007-2010 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SYS_EFX_REGS_PCI_H +#define _SYS_EFX_REGS_PCI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * PC_VEND_ID_REG(16bit): + * Vendor ID register + */ + +#define PCR_AZ_VEND_ID_REG 0x00000000 +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_VEND_ID_LBN 0 +#define PCRF_AZ_VEND_ID_WIDTH 16 + + +/* + * PC_DEV_ID_REG(16bit): + * Device ID register + */ + +#define PCR_AZ_DEV_ID_REG 0x00000002 +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_DEV_ID_LBN 0 +#define PCRF_AZ_DEV_ID_WIDTH 16 + + +/* + * PC_CMD_REG(16bit): + * Command register + */ + +#define PCR_AZ_CMD_REG 0x00000004 +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_INTX_DIS_LBN 10 +#define PCRF_AZ_INTX_DIS_WIDTH 1 +#define PCRF_AZ_FB2B_EN_LBN 9 +#define PCRF_AZ_FB2B_EN_WIDTH 1 +#define PCRF_AZ_SERR_EN_LBN 8 +#define PCRF_AZ_SERR_EN_WIDTH 1 +#define PCRF_AZ_IDSEL_CTL_LBN 7 +#define PCRF_AZ_IDSEL_CTL_WIDTH 1 +#define PCRF_AZ_PERR_EN_LBN 6 +#define PCRF_AZ_PERR_EN_WIDTH 1 +#define PCRF_AZ_VGA_PAL_SNP_LBN 5 +#define PCRF_AZ_VGA_PAL_SNP_WIDTH 1 +#define PCRF_AZ_MWI_EN_LBN 4 +#define PCRF_AZ_MWI_EN_WIDTH 1 +#define PCRF_AZ_SPEC_CYC_LBN 3 +#define PCRF_AZ_SPEC_CYC_WIDTH 1 +#define PCRF_AZ_MST_EN_LBN 2 +#define PCRF_AZ_MST_EN_WIDTH 1 +#define PCRF_AZ_MEM_EN_LBN 1 +#define PCRF_AZ_MEM_EN_WIDTH 1 +#define PCRF_AZ_IO_EN_LBN 0 +#define PCRF_AZ_IO_EN_WIDTH 1 + + +/* + * PC_STAT_REG(16bit): + * Status register + */ + +#define PCR_AZ_STAT_REG 0x00000006 +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_DET_PERR_LBN 15 +#define PCRF_AZ_DET_PERR_WIDTH 1 +#define PCRF_AZ_SIG_SERR_LBN 14 +#define PCRF_AZ_SIG_SERR_WIDTH 1 +#define PCRF_AZ_GOT_MABRT_LBN 13 +#define PCRF_AZ_GOT_MABRT_WIDTH 1 +#define PCRF_AZ_GOT_TABRT_LBN 12 +#define PCRF_AZ_GOT_TABRT_WIDTH 1 +#define PCRF_AZ_SIG_TABRT_LBN 11 +#define PCRF_AZ_SIG_TABRT_WIDTH 1 +#define PCRF_AZ_DEVSEL_TIM_LBN 9 +#define PCRF_AZ_DEVSEL_TIM_WIDTH 2 +#define PCRF_AZ_MDAT_PERR_LBN 8 +#define PCRF_AZ_MDAT_PERR_WIDTH 1 +#define PCRF_AZ_FB2B_CAP_LBN 7 +#define PCRF_AZ_FB2B_CAP_WIDTH 1 +#define PCRF_AZ_66MHZ_CAP_LBN 5 +#define PCRF_AZ_66MHZ_CAP_WIDTH 1 +#define PCRF_AZ_CAP_LIST_LBN 4 +#define PCRF_AZ_CAP_LIST_WIDTH 1 +#define PCRF_AZ_INTX_STAT_LBN 3 +#define PCRF_AZ_INTX_STAT_WIDTH 1 + + +/* + * PC_REV_ID_REG(8bit): + * Class code & revision ID register + */ + +#define PCR_AZ_REV_ID_REG 0x00000008 +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_REV_ID_LBN 0 +#define PCRF_AZ_REV_ID_WIDTH 8 + + +/* + * PC_CC_REG(24bit): + * Class code register + */ + +#define PCR_AZ_CC_REG 0x00000009 +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_BASE_CC_LBN 16 +#define PCRF_AZ_BASE_CC_WIDTH 8 +#define PCRF_AZ_SUB_CC_LBN 8 +#define PCRF_AZ_SUB_CC_WIDTH 8 +#define PCRF_AZ_PROG_IF_LBN 0 +#define PCRF_AZ_PROG_IF_WIDTH 8 + + +/* + * PC_CACHE_LSIZE_REG(8bit): + * Cache line size + */ + +#define PCR_AZ_CACHE_LSIZE_REG 0x0000000c +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_CACHE_LSIZE_LBN 0 +#define PCRF_AZ_CACHE_LSIZE_WIDTH 8 + + +/* + * PC_MST_LAT_REG(8bit): + * Master latency timer register + */ + +#define PCR_AZ_MST_LAT_REG 0x0000000d +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_MST_LAT_LBN 0 +#define PCRF_AZ_MST_LAT_WIDTH 8 + + +/* + * PC_HDR_TYPE_REG(8bit): + * Header type register + */ + +#define PCR_AZ_HDR_TYPE_REG 0x0000000e +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_MULT_FUNC_LBN 7 +#define PCRF_AZ_MULT_FUNC_WIDTH 1 +#define PCRF_AZ_TYPE_LBN 0 +#define PCRF_AZ_TYPE_WIDTH 7 + + +/* + * PC_BIST_REG(8bit): + * BIST register + */ + +#define PCR_AZ_BIST_REG 0x0000000f +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_BIST_LBN 0 +#define PCRF_AZ_BIST_WIDTH 8 + + +/* + * PC_BAR0_REG(32bit): + * Primary function base address register 0 + */ + +#define PCR_AZ_BAR0_REG 0x00000010 +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_BAR0_LBN 4 +#define PCRF_AZ_BAR0_WIDTH 28 +#define PCRF_AZ_BAR0_PREF_LBN 3 +#define PCRF_AZ_BAR0_PREF_WIDTH 1 +#define PCRF_AZ_BAR0_TYPE_LBN 1 +#define PCRF_AZ_BAR0_TYPE_WIDTH 2 +#define PCRF_AZ_BAR0_IOM_LBN 0 +#define PCRF_AZ_BAR0_IOM_WIDTH 1 + + +/* + * PC_BAR1_REG(32bit): + * Primary function base address register 1, BAR1 is not implemented so read only. + */ + +#define PCR_DZ_BAR1_REG 0x00000014 +/* hunta0=pci_f0_config */ + +#define PCRF_DZ_BAR1_LBN 0 +#define PCRF_DZ_BAR1_WIDTH 32 + + +/* + * PC_BAR2_LO_REG(32bit): + * Primary function base address register 2 low bits + */ + +#define PCR_AZ_BAR2_LO_REG 0x00000018 +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_BAR2_LO_LBN 4 +#define PCRF_AZ_BAR2_LO_WIDTH 28 +#define PCRF_AZ_BAR2_PREF_LBN 3 +#define PCRF_AZ_BAR2_PREF_WIDTH 1 +#define PCRF_AZ_BAR2_TYPE_LBN 1 +#define PCRF_AZ_BAR2_TYPE_WIDTH 2 +#define PCRF_AZ_BAR2_IOM_LBN 0 +#define PCRF_AZ_BAR2_IOM_WIDTH 1 + + +/* + * PC_BAR2_HI_REG(32bit): + * Primary function base address register 2 high bits + */ + +#define PCR_AZ_BAR2_HI_REG 0x0000001c +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_BAR2_HI_LBN 0 +#define PCRF_AZ_BAR2_HI_WIDTH 32 + + +/* + * PC_BAR4_LO_REG(32bit): + * Primary function base address register 2 low bits + */ + +#define PCR_CZ_BAR4_LO_REG 0x00000020 +/* sienaa0,hunta0=pci_f0_config */ + +#define PCRF_CZ_BAR4_LO_LBN 4 +#define PCRF_CZ_BAR4_LO_WIDTH 28 +#define PCRF_CZ_BAR4_PREF_LBN 3 +#define PCRF_CZ_BAR4_PREF_WIDTH 1 +#define PCRF_CZ_BAR4_TYPE_LBN 1 +#define PCRF_CZ_BAR4_TYPE_WIDTH 2 +#define PCRF_CZ_BAR4_IOM_LBN 0 +#define PCRF_CZ_BAR4_IOM_WIDTH 1 + + +/* + * PC_BAR4_HI_REG(32bit): + * Primary function base address register 2 high bits + */ + +#define PCR_CZ_BAR4_HI_REG 0x00000024 +/* sienaa0,hunta0=pci_f0_config */ + +#define PCRF_CZ_BAR4_HI_LBN 0 +#define PCRF_CZ_BAR4_HI_WIDTH 32 + + +/* + * PC_SS_VEND_ID_REG(16bit): + * Sub-system vendor ID register + */ + +#define PCR_AZ_SS_VEND_ID_REG 0x0000002c +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_SS_VEND_ID_LBN 0 +#define PCRF_AZ_SS_VEND_ID_WIDTH 16 + + +/* + * PC_SS_ID_REG(16bit): + * Sub-system ID register + */ + +#define PCR_AZ_SS_ID_REG 0x0000002e +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_SS_ID_LBN 0 +#define PCRF_AZ_SS_ID_WIDTH 16 + + +/* + * PC_EXPROM_BAR_REG(32bit): + * Expansion ROM base address register + */ + +#define PCR_AZ_EXPROM_BAR_REG 0x00000030 +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_EXPROM_BAR_LBN 11 +#define PCRF_AZ_EXPROM_BAR_WIDTH 21 +#define PCRF_AB_EXPROM_MIN_SIZE_LBN 2 +#define PCRF_AB_EXPROM_MIN_SIZE_WIDTH 9 +#define PCRF_CZ_EXPROM_MIN_SIZE_LBN 1 +#define PCRF_CZ_EXPROM_MIN_SIZE_WIDTH 10 +#define PCRF_AB_EXPROM_FEATURE_ENABLE_LBN 1 +#define PCRF_AB_EXPROM_FEATURE_ENABLE_WIDTH 1 +#define PCRF_AZ_EXPROM_EN_LBN 0 +#define PCRF_AZ_EXPROM_EN_WIDTH 1 + + +/* + * PC_CAP_PTR_REG(8bit): + * Capability pointer register + */ + +#define PCR_AZ_CAP_PTR_REG 0x00000034 +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_CAP_PTR_LBN 0 +#define PCRF_AZ_CAP_PTR_WIDTH 8 + + +/* + * PC_INT_LINE_REG(8bit): + * Interrupt line register + */ + +#define PCR_AZ_INT_LINE_REG 0x0000003c +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_INT_LINE_LBN 0 +#define PCRF_AZ_INT_LINE_WIDTH 8 + + +/* + * PC_INT_PIN_REG(8bit): + * Interrupt pin register + */ + +#define PCR_AZ_INT_PIN_REG 0x0000003d +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_INT_PIN_LBN 0 +#define PCRF_AZ_INT_PIN_WIDTH 8 + + +/* + * PC_PM_CAP_ID_REG(8bit): + * Power management capability ID + */ + +#define PCR_AC_PM_CAP_ID_REG 0x00000040 +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCR_DZ_PM_CAP_ID_REG 0x00000080 +/* hunta0=pci_f0_config */ + +#define PCRF_AZ_PM_CAP_ID_LBN 0 +#define PCRF_AZ_PM_CAP_ID_WIDTH 8 + + +/* + * PC_PM_NXT_PTR_REG(8bit): + * Power management next item pointer + */ + +#define PCR_AC_PM_NXT_PTR_REG 0x00000041 +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCR_DZ_PM_NXT_PTR_REG 0x00000081 +/* hunta0=pci_f0_config */ + +#define PCRF_AZ_PM_NXT_PTR_LBN 0 +#define PCRF_AZ_PM_NXT_PTR_WIDTH 8 + + +/* + * PC_PM_CAP_REG(16bit): + * Power management capabilities register + */ + +#define PCR_AC_PM_CAP_REG 0x00000042 +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCR_DZ_PM_CAP_REG 0x00000082 +/* hunta0=pci_f0_config */ + +#define PCRF_AZ_PM_PME_SUPT_LBN 11 +#define PCRF_AZ_PM_PME_SUPT_WIDTH 5 +#define PCRF_AZ_PM_D2_SUPT_LBN 10 +#define PCRF_AZ_PM_D2_SUPT_WIDTH 1 +#define PCRF_AZ_PM_D1_SUPT_LBN 9 +#define PCRF_AZ_PM_D1_SUPT_WIDTH 1 +#define PCRF_AZ_PM_AUX_CURR_LBN 6 +#define PCRF_AZ_PM_AUX_CURR_WIDTH 3 +#define PCRF_AZ_PM_DSI_LBN 5 +#define PCRF_AZ_PM_DSI_WIDTH 1 +#define PCRF_AZ_PM_PME_CLK_LBN 3 +#define PCRF_AZ_PM_PME_CLK_WIDTH 1 +#define PCRF_AZ_PM_PME_VER_LBN 0 +#define PCRF_AZ_PM_PME_VER_WIDTH 3 + + +/* + * PC_PM_CS_REG(16bit): + * Power management control & status register + */ + +#define PCR_AC_PM_CS_REG 0x00000044 +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCR_DZ_PM_CS_REG 0x00000084 +/* hunta0=pci_f0_config */ + +#define PCRF_AZ_PM_PME_STAT_LBN 15 +#define PCRF_AZ_PM_PME_STAT_WIDTH 1 +#define PCRF_AZ_PM_DAT_SCALE_LBN 13 +#define PCRF_AZ_PM_DAT_SCALE_WIDTH 2 +#define PCRF_AZ_PM_DAT_SEL_LBN 9 +#define PCRF_AZ_PM_DAT_SEL_WIDTH 4 +#define PCRF_AZ_PM_PME_EN_LBN 8 +#define PCRF_AZ_PM_PME_EN_WIDTH 1 +#define PCRF_CZ_NO_SOFT_RESET_LBN 3 +#define PCRF_CZ_NO_SOFT_RESET_WIDTH 1 +#define PCRF_AZ_PM_PWR_ST_LBN 0 +#define PCRF_AZ_PM_PWR_ST_WIDTH 2 + + +/* + * PC_MSI_CAP_ID_REG(8bit): + * MSI capability ID + */ + +#define PCR_AC_MSI_CAP_ID_REG 0x00000050 +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCR_DZ_MSI_CAP_ID_REG 0x00000090 +/* hunta0=pci_f0_config */ + +#define PCRF_AZ_MSI_CAP_ID_LBN 0 +#define PCRF_AZ_MSI_CAP_ID_WIDTH 8 + + +/* + * PC_MSI_NXT_PTR_REG(8bit): + * MSI next item pointer + */ + +#define PCR_AC_MSI_NXT_PTR_REG 0x00000051 +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCR_DZ_MSI_NXT_PTR_REG 0x00000091 +/* hunta0=pci_f0_config */ + +#define PCRF_AZ_MSI_NXT_PTR_LBN 0 +#define PCRF_AZ_MSI_NXT_PTR_WIDTH 8 + + +/* + * PC_MSI_CTL_REG(16bit): + * MSI control register + */ + +#define PCR_AC_MSI_CTL_REG 0x00000052 +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCR_DZ_MSI_CTL_REG 0x00000092 +/* hunta0=pci_f0_config */ + +#define PCRF_AZ_MSI_64_EN_LBN 7 +#define PCRF_AZ_MSI_64_EN_WIDTH 1 +#define PCRF_AZ_MSI_MULT_MSG_EN_LBN 4 +#define PCRF_AZ_MSI_MULT_MSG_EN_WIDTH 3 +#define PCRF_AZ_MSI_MULT_MSG_CAP_LBN 1 +#define PCRF_AZ_MSI_MULT_MSG_CAP_WIDTH 3 +#define PCRF_AZ_MSI_EN_LBN 0 +#define PCRF_AZ_MSI_EN_WIDTH 1 + + +/* + * PC_MSI_ADR_LO_REG(32bit): + * MSI low 32 bits address register + */ + +#define PCR_AC_MSI_ADR_LO_REG 0x00000054 +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCR_DZ_MSI_ADR_LO_REG 0x00000094 +/* hunta0=pci_f0_config */ + +#define PCRF_AZ_MSI_ADR_LO_LBN 2 +#define PCRF_AZ_MSI_ADR_LO_WIDTH 30 + + +/* + * PC_VPD_CAP_CTL_REG(8bit): + * VPD control and capabilities register + */ + +#define PCR_DZ_VPD_CAP_CTL_REG 0x00000054 +/* hunta0=pci_f0_config */ + +#define PCR_CC_VPD_CAP_CTL_REG 0x000000d0 +/* sienaa0=pci_f0_config */ + +#define PCRF_CZ_VPD_FLAG_LBN 31 +#define PCRF_CZ_VPD_FLAG_WIDTH 1 +#define PCRF_CZ_VPD_ADDR_LBN 16 +#define PCRF_CZ_VPD_ADDR_WIDTH 15 +#define PCRF_CZ_VPD_NXT_PTR_LBN 8 +#define PCRF_CZ_VPD_NXT_PTR_WIDTH 8 +#define PCRF_CZ_VPD_CAP_ID_LBN 0 +#define PCRF_CZ_VPD_CAP_ID_WIDTH 8 + + +/* + * PC_VPD_CAP_DATA_REG(32bit): + * documentation to be written for sum_PC_VPD_CAP_DATA_REG + */ + +#define PCR_DZ_VPD_CAP_DATA_REG 0x00000058 +/* hunta0=pci_f0_config */ + +#define PCR_AB_VPD_CAP_DATA_REG 0x000000b4 +/* falcona0,falconb0=pci_f0_config */ + +#define PCR_CC_VPD_CAP_DATA_REG 0x000000d4 +/* sienaa0=pci_f0_config */ + +#define PCRF_AZ_VPD_DATA_LBN 0 +#define PCRF_AZ_VPD_DATA_WIDTH 32 + + +/* + * PC_MSI_ADR_HI_REG(32bit): + * MSI high 32 bits address register + */ + +#define PCR_AC_MSI_ADR_HI_REG 0x00000058 +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCR_DZ_MSI_ADR_HI_REG 0x00000098 +/* hunta0=pci_f0_config */ + +#define PCRF_AZ_MSI_ADR_HI_LBN 0 +#define PCRF_AZ_MSI_ADR_HI_WIDTH 32 + + +/* + * PC_MSI_DAT_REG(16bit): + * MSI data register + */ + +#define PCR_AC_MSI_DAT_REG 0x0000005c +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCR_DZ_MSI_DAT_REG 0x0000009c +/* hunta0=pci_f0_config */ + +#define PCRF_AZ_MSI_DAT_LBN 0 +#define PCRF_AZ_MSI_DAT_WIDTH 16 + + +/* + * PC_PCIE_CAP_LIST_REG(16bit): + * PCIe capability list register + */ + +#define PCR_AB_PCIE_CAP_LIST_REG 0x00000060 +/* falcona0,falconb0=pci_f0_config */ + +#define PCR_CC_PCIE_CAP_LIST_REG 0x00000070 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_PCIE_CAP_LIST_REG 0x000000c0 +/* hunta0=pci_f0_config */ + +#define PCRF_AZ_PCIE_NXT_PTR_LBN 8 +#define PCRF_AZ_PCIE_NXT_PTR_WIDTH 8 +#define PCRF_AZ_PCIE_CAP_ID_LBN 0 +#define PCRF_AZ_PCIE_CAP_ID_WIDTH 8 + + +/* + * PC_PCIE_CAP_REG(16bit): + * PCIe capability register + */ + +#define PCR_AB_PCIE_CAP_REG 0x00000062 +/* falcona0,falconb0=pci_f0_config */ + +#define PCR_CC_PCIE_CAP_REG 0x00000072 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_PCIE_CAP_REG 0x000000c2 +/* hunta0=pci_f0_config */ + +#define PCRF_AZ_PCIE_INT_MSG_NUM_LBN 9 +#define PCRF_AZ_PCIE_INT_MSG_NUM_WIDTH 5 +#define PCRF_AZ_PCIE_SLOT_IMP_LBN 8 +#define PCRF_AZ_PCIE_SLOT_IMP_WIDTH 1 +#define PCRF_AZ_PCIE_DEV_PORT_TYPE_LBN 4 +#define PCRF_AZ_PCIE_DEV_PORT_TYPE_WIDTH 4 +#define PCRF_AZ_PCIE_CAP_VER_LBN 0 +#define PCRF_AZ_PCIE_CAP_VER_WIDTH 4 + + +/* + * PC_DEV_CAP_REG(32bit): + * PCIe device capabilities register + */ + +#define PCR_AB_DEV_CAP_REG 0x00000064 +/* falcona0,falconb0=pci_f0_config */ + +#define PCR_CC_DEV_CAP_REG 0x00000074 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_DEV_CAP_REG 0x000000c4 +/* hunta0=pci_f0_config */ + +#define PCRF_CZ_CAP_FN_LEVEL_RESET_LBN 28 +#define PCRF_CZ_CAP_FN_LEVEL_RESET_WIDTH 1 +#define PCRF_AZ_CAP_SLOT_PWR_SCL_LBN 26 +#define PCRF_AZ_CAP_SLOT_PWR_SCL_WIDTH 2 +#define PCRF_AZ_CAP_SLOT_PWR_VAL_LBN 18 +#define PCRF_AZ_CAP_SLOT_PWR_VAL_WIDTH 8 +#define PCRF_CZ_ROLE_BASE_ERR_REPORTING_LBN 15 +#define PCRF_CZ_ROLE_BASE_ERR_REPORTING_WIDTH 1 +#define PCRF_AB_PWR_IND_LBN 14 +#define PCRF_AB_PWR_IND_WIDTH 1 +#define PCRF_AB_ATTN_IND_LBN 13 +#define PCRF_AB_ATTN_IND_WIDTH 1 +#define PCRF_AB_ATTN_BUTTON_LBN 12 +#define PCRF_AB_ATTN_BUTTON_WIDTH 1 +#define PCRF_AZ_ENDPT_L1_LAT_LBN 9 +#define PCRF_AZ_ENDPT_L1_LAT_WIDTH 3 +#define PCRF_AZ_ENDPT_L0_LAT_LBN 6 +#define PCRF_AZ_ENDPT_L0_LAT_WIDTH 3 +#define PCRF_AZ_TAG_FIELD_LBN 5 +#define PCRF_AZ_TAG_FIELD_WIDTH 1 +#define PCRF_AZ_PHAN_FUNC_LBN 3 +#define PCRF_AZ_PHAN_FUNC_WIDTH 2 +#define PCRF_AZ_MAX_PAYL_SIZE_SUPT_LBN 0 +#define PCRF_AZ_MAX_PAYL_SIZE_SUPT_WIDTH 3 + + +/* + * PC_DEV_CTL_REG(16bit): + * PCIe device control register + */ + +#define PCR_AB_DEV_CTL_REG 0x00000068 +/* falcona0,falconb0=pci_f0_config */ + +#define PCR_CC_DEV_CTL_REG 0x00000078 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_DEV_CTL_REG 0x000000c8 +/* hunta0=pci_f0_config */ + +#define PCRF_CZ_FN_LEVEL_RESET_LBN 15 +#define PCRF_CZ_FN_LEVEL_RESET_WIDTH 1 +#define PCRF_AZ_MAX_RD_REQ_SIZE_LBN 12 +#define PCRF_AZ_MAX_RD_REQ_SIZE_WIDTH 3 +#define PCFE_AZ_MAX_RD_REQ_SIZE_4096 5 +#define PCFE_AZ_MAX_RD_REQ_SIZE_2048 4 +#define PCFE_AZ_MAX_RD_REQ_SIZE_1024 3 +#define PCFE_AZ_MAX_RD_REQ_SIZE_512 2 +#define PCFE_AZ_MAX_RD_REQ_SIZE_256 1 +#define PCFE_AZ_MAX_RD_REQ_SIZE_128 0 +#define PCFE_DZ_OTHER other +#define PCRF_AZ_EN_NO_SNOOP_LBN 11 +#define PCRF_AZ_EN_NO_SNOOP_WIDTH 1 +#define PCRF_AZ_AUX_PWR_PM_EN_LBN 10 +#define PCRF_AZ_AUX_PWR_PM_EN_WIDTH 1 +#define PCRF_AZ_PHAN_FUNC_EN_LBN 9 +#define PCRF_AZ_PHAN_FUNC_EN_WIDTH 1 +#define PCRF_AB_DEV_CAP_REG_RSVD0_LBN 8 +#define PCRF_AB_DEV_CAP_REG_RSVD0_WIDTH 1 +#define PCRF_CZ_EXTENDED_TAG_EN_LBN 8 +#define PCRF_CZ_EXTENDED_TAG_EN_WIDTH 1 +#define PCRF_AZ_MAX_PAYL_SIZE_LBN 5 +#define PCRF_AZ_MAX_PAYL_SIZE_WIDTH 3 +#define PCFE_AZ_MAX_PAYL_SIZE_4096 5 +#define PCFE_AZ_MAX_PAYL_SIZE_2048 4 +#define PCFE_AZ_MAX_PAYL_SIZE_1024 3 +#define PCFE_AZ_MAX_PAYL_SIZE_512 2 +#define PCFE_AZ_MAX_PAYL_SIZE_256 1 +#define PCFE_AZ_MAX_PAYL_SIZE_128 0 +#define PCFE_DZ_OTHER other +#define PCRF_AZ_EN_RELAX_ORDER_LBN 4 +#define PCRF_AZ_EN_RELAX_ORDER_WIDTH 1 +#define PCRF_AZ_UNSUP_REQ_RPT_EN_LBN 3 +#define PCRF_AZ_UNSUP_REQ_RPT_EN_WIDTH 1 +#define PCRF_AZ_FATAL_ERR_RPT_EN_LBN 2 +#define PCRF_AZ_FATAL_ERR_RPT_EN_WIDTH 1 +#define PCRF_AZ_NONFATAL_ERR_RPT_EN_LBN 1 +#define PCRF_AZ_NONFATAL_ERR_RPT_EN_WIDTH 1 +#define PCRF_AZ_CORR_ERR_RPT_EN_LBN 0 +#define PCRF_AZ_CORR_ERR_RPT_EN_WIDTH 1 + + +/* + * PC_DEV_STAT_REG(16bit): + * PCIe device status register + */ + +#define PCR_AB_DEV_STAT_REG 0x0000006a +/* falcona0,falconb0=pci_f0_config */ + +#define PCR_CC_DEV_STAT_REG 0x0000007a +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_DEV_STAT_REG 0x000000ca +/* hunta0=pci_f0_config */ + +#define PCRF_AZ_TRNS_PEND_LBN 5 +#define PCRF_AZ_TRNS_PEND_WIDTH 1 +#define PCRF_AZ_AUX_PWR_DET_LBN 4 +#define PCRF_AZ_AUX_PWR_DET_WIDTH 1 +#define PCRF_AZ_UNSUP_REQ_DET_LBN 3 +#define PCRF_AZ_UNSUP_REQ_DET_WIDTH 1 +#define PCRF_AZ_FATAL_ERR_DET_LBN 2 +#define PCRF_AZ_FATAL_ERR_DET_WIDTH 1 +#define PCRF_AZ_NONFATAL_ERR_DET_LBN 1 +#define PCRF_AZ_NONFATAL_ERR_DET_WIDTH 1 +#define PCRF_AZ_CORR_ERR_DET_LBN 0 +#define PCRF_AZ_CORR_ERR_DET_WIDTH 1 + + +/* + * PC_LNK_CAP_REG(32bit): + * PCIe link capabilities register + */ + +#define PCR_AB_LNK_CAP_REG 0x0000006c +/* falcona0,falconb0=pci_f0_config */ + +#define PCR_CC_LNK_CAP_REG 0x0000007c +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_LNK_CAP_REG 0x000000cc +/* hunta0=pci_f0_config */ + +#define PCRF_AZ_PORT_NUM_LBN 24 +#define PCRF_AZ_PORT_NUM_WIDTH 8 +#define PCRF_CZ_LINK_BWDITH_NOTIF_CAP_LBN 21 +#define PCRF_CZ_LINK_BWDITH_NOTIF_CAP_WIDTH 1 +#define PCRF_CZ_DATA_LINK_ACTIVE_RPT_CAP_LBN 20 +#define PCRF_CZ_DATA_LINK_ACTIVE_RPT_CAP_WIDTH 1 +#define PCRF_CZ_SURPISE_DOWN_RPT_CAP_LBN 19 +#define PCRF_CZ_SURPISE_DOWN_RPT_CAP_WIDTH 1 +#define PCRF_CZ_CLOCK_PWR_MNGMNT_CAP_LBN 18 +#define PCRF_CZ_CLOCK_PWR_MNGMNT_CAP_WIDTH 1 +#define PCRF_AZ_DEF_L1_EXIT_LAT_LBN 15 +#define PCRF_AZ_DEF_L1_EXIT_LAT_WIDTH 3 +#define PCRF_AZ_DEF_L0_EXIT_LATPORT_NUM_LBN 12 +#define PCRF_AZ_DEF_L0_EXIT_LATPORT_NUM_WIDTH 3 +#define PCRF_AZ_AS_LNK_PM_SUPT_LBN 10 +#define PCRF_AZ_AS_LNK_PM_SUPT_WIDTH 2 +#define PCRF_AZ_MAX_LNK_WIDTH_LBN 4 +#define PCRF_AZ_MAX_LNK_WIDTH_WIDTH 6 +#define PCRF_AZ_MAX_LNK_SP_LBN 0 +#define PCRF_AZ_MAX_LNK_SP_WIDTH 4 + + +/* + * PC_LNK_CTL_REG(16bit): + * PCIe link control register + */ + +#define PCR_AB_LNK_CTL_REG 0x00000070 +/* falcona0,falconb0=pci_f0_config */ + +#define PCR_CC_LNK_CTL_REG 0x00000080 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_LNK_CTL_REG 0x000000d0 +/* hunta0=pci_f0_config */ + +#define PCRF_AZ_EXT_SYNC_LBN 7 +#define PCRF_AZ_EXT_SYNC_WIDTH 1 +#define PCRF_AZ_COMM_CLK_CFG_LBN 6 +#define PCRF_AZ_COMM_CLK_CFG_WIDTH 1 +#define PCRF_AB_LNK_CTL_REG_RSVD0_LBN 5 +#define PCRF_AB_LNK_CTL_REG_RSVD0_WIDTH 1 +#define PCRF_CZ_LNK_RETRAIN_LBN 5 +#define PCRF_CZ_LNK_RETRAIN_WIDTH 1 +#define PCRF_AZ_LNK_DIS_LBN 4 +#define PCRF_AZ_LNK_DIS_WIDTH 1 +#define PCRF_AZ_RD_COM_BDRY_LBN 3 +#define PCRF_AZ_RD_COM_BDRY_WIDTH 1 +#define PCRF_AZ_ACT_ST_LNK_PM_CTL_LBN 0 +#define PCRF_AZ_ACT_ST_LNK_PM_CTL_WIDTH 2 + + +/* + * PC_LNK_STAT_REG(16bit): + * PCIe link status register + */ + +#define PCR_AB_LNK_STAT_REG 0x00000072 +/* falcona0,falconb0=pci_f0_config */ + +#define PCR_CC_LNK_STAT_REG 0x00000082 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_LNK_STAT_REG 0x000000d2 +/* hunta0=pci_f0_config */ + +#define PCRF_AZ_SLOT_CLK_CFG_LBN 12 +#define PCRF_AZ_SLOT_CLK_CFG_WIDTH 1 +#define PCRF_AZ_LNK_TRAIN_LBN 11 +#define PCRF_AZ_LNK_TRAIN_WIDTH 1 +#define PCRF_AB_TRAIN_ERR_LBN 10 +#define PCRF_AB_TRAIN_ERR_WIDTH 1 +#define PCRF_AZ_LNK_WIDTH_LBN 4 +#define PCRF_AZ_LNK_WIDTH_WIDTH 6 +#define PCRF_AZ_LNK_SP_LBN 0 +#define PCRF_AZ_LNK_SP_WIDTH 4 + + +/* + * PC_SLOT_CAP_REG(32bit): + * PCIe slot capabilities register + */ + +#define PCR_AB_SLOT_CAP_REG 0x00000074 +/* falcona0,falconb0=pci_f0_config */ + +#define PCRF_AB_SLOT_NUM_LBN 19 +#define PCRF_AB_SLOT_NUM_WIDTH 13 +#define PCRF_AB_SLOT_PWR_LIM_SCL_LBN 15 +#define PCRF_AB_SLOT_PWR_LIM_SCL_WIDTH 2 +#define PCRF_AB_SLOT_PWR_LIM_VAL_LBN 7 +#define PCRF_AB_SLOT_PWR_LIM_VAL_WIDTH 8 +#define PCRF_AB_SLOT_HP_CAP_LBN 6 +#define PCRF_AB_SLOT_HP_CAP_WIDTH 1 +#define PCRF_AB_SLOT_HP_SURP_LBN 5 +#define PCRF_AB_SLOT_HP_SURP_WIDTH 1 +#define PCRF_AB_SLOT_PWR_IND_PRST_LBN 4 +#define PCRF_AB_SLOT_PWR_IND_PRST_WIDTH 1 +#define PCRF_AB_SLOT_ATTN_IND_PRST_LBN 3 +#define PCRF_AB_SLOT_ATTN_IND_PRST_WIDTH 1 +#define PCRF_AB_SLOT_MRL_SENS_PRST_LBN 2 +#define PCRF_AB_SLOT_MRL_SENS_PRST_WIDTH 1 +#define PCRF_AB_SLOT_PWR_CTL_PRST_LBN 1 +#define PCRF_AB_SLOT_PWR_CTL_PRST_WIDTH 1 +#define PCRF_AB_SLOT_ATTN_BUT_PRST_LBN 0 +#define PCRF_AB_SLOT_ATTN_BUT_PRST_WIDTH 1 + + +/* + * PC_SLOT_CTL_REG(16bit): + * PCIe slot control register + */ + +#define PCR_AB_SLOT_CTL_REG 0x00000078 +/* falcona0,falconb0=pci_f0_config */ + +#define PCRF_AB_SLOT_PWR_CTLR_CTL_LBN 10 +#define PCRF_AB_SLOT_PWR_CTLR_CTL_WIDTH 1 +#define PCRF_AB_SLOT_PWR_IND_CTL_LBN 8 +#define PCRF_AB_SLOT_PWR_IND_CTL_WIDTH 2 +#define PCRF_AB_SLOT_ATT_IND_CTL_LBN 6 +#define PCRF_AB_SLOT_ATT_IND_CTL_WIDTH 2 +#define PCRF_AB_SLOT_HP_INT_EN_LBN 5 +#define PCRF_AB_SLOT_HP_INT_EN_WIDTH 1 +#define PCRF_AB_SLOT_CMD_COMP_INT_EN_LBN 4 +#define PCRF_AB_SLOT_CMD_COMP_INT_EN_WIDTH 1 +#define PCRF_AB_SLOT_PRES_DET_CHG_EN_LBN 3 +#define PCRF_AB_SLOT_PRES_DET_CHG_EN_WIDTH 1 +#define PCRF_AB_SLOT_MRL_SENS_CHG_EN_LBN 2 +#define PCRF_AB_SLOT_MRL_SENS_CHG_EN_WIDTH 1 +#define PCRF_AB_SLOT_PWR_FLTDET_EN_LBN 1 +#define PCRF_AB_SLOT_PWR_FLTDET_EN_WIDTH 1 +#define PCRF_AB_SLOT_ATTN_BUT_EN_LBN 0 +#define PCRF_AB_SLOT_ATTN_BUT_EN_WIDTH 1 + + +/* + * PC_SLOT_STAT_REG(16bit): + * PCIe slot status register + */ + +#define PCR_AB_SLOT_STAT_REG 0x0000007a +/* falcona0,falconb0=pci_f0_config */ + +#define PCRF_AB_PRES_DET_ST_LBN 6 +#define PCRF_AB_PRES_DET_ST_WIDTH 1 +#define PCRF_AB_MRL_SENS_ST_LBN 5 +#define PCRF_AB_MRL_SENS_ST_WIDTH 1 +#define PCRF_AB_SLOT_PWR_IND_LBN 4 +#define PCRF_AB_SLOT_PWR_IND_WIDTH 1 +#define PCRF_AB_SLOT_ATTN_IND_LBN 3 +#define PCRF_AB_SLOT_ATTN_IND_WIDTH 1 +#define PCRF_AB_SLOT_MRL_SENS_LBN 2 +#define PCRF_AB_SLOT_MRL_SENS_WIDTH 1 +#define PCRF_AB_PWR_FLTDET_LBN 1 +#define PCRF_AB_PWR_FLTDET_WIDTH 1 +#define PCRF_AB_ATTN_BUTDET_LBN 0 +#define PCRF_AB_ATTN_BUTDET_WIDTH 1 + + +/* + * PC_MSIX_CAP_ID_REG(8bit): + * MSIX Capability ID + */ + +#define PCR_BB_MSIX_CAP_ID_REG 0x00000090 +/* falconb0=pci_f0_config */ + +#define PCR_CZ_MSIX_CAP_ID_REG 0x000000b0 +/* sienaa0,hunta0=pci_f0_config */ + +#define PCRF_BZ_MSIX_CAP_ID_LBN 0 +#define PCRF_BZ_MSIX_CAP_ID_WIDTH 8 + + +/* + * PC_MSIX_NXT_PTR_REG(8bit): + * MSIX Capability Next Capability Ptr + */ + +#define PCR_BB_MSIX_NXT_PTR_REG 0x00000091 +/* falconb0=pci_f0_config */ + +#define PCR_CZ_MSIX_NXT_PTR_REG 0x000000b1 +/* sienaa0,hunta0=pci_f0_config */ + +#define PCRF_BZ_MSIX_NXT_PTR_LBN 0 +#define PCRF_BZ_MSIX_NXT_PTR_WIDTH 8 + + +/* + * PC_MSIX_CTL_REG(16bit): + * MSIX control register + */ + +#define PCR_BB_MSIX_CTL_REG 0x00000092 +/* falconb0=pci_f0_config */ + +#define PCR_CZ_MSIX_CTL_REG 0x000000b2 +/* sienaa0,hunta0=pci_f0_config */ + +#define PCRF_BZ_MSIX_EN_LBN 15 +#define PCRF_BZ_MSIX_EN_WIDTH 1 +#define PCRF_BZ_MSIX_FUNC_MASK_LBN 14 +#define PCRF_BZ_MSIX_FUNC_MASK_WIDTH 1 +#define PCRF_BZ_MSIX_TBL_SIZE_LBN 0 +#define PCRF_BZ_MSIX_TBL_SIZE_WIDTH 11 + + +/* + * PC_DEV_CAP2_REG(16bit): + * PCIe Device Capabilities 2 + */ + +#define PCR_CC_DEV_CAP2_REG 0x00000094 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_DEV_CAP2_REG 0x000000e4 +/* hunta0=pci_f0_config */ + +#define PCRF_CZ_CMPL_TIMEOUT_DIS_LBN 4 +#define PCRF_CZ_CMPL_TIMEOUT_DIS_WIDTH 1 +#define PCRF_CZ_CMPL_TIMEOUT_LBN 0 +#define PCRF_CZ_CMPL_TIMEOUT_WIDTH 4 +#define PCFE_CZ_CMPL_TIMEOUT_17000_TO_6400MS 14 +#define PCFE_CZ_CMPL_TIMEOUT_4000_TO_1300MS 13 +#define PCFE_CZ_CMPL_TIMEOUT_1000_TO_3500MS 10 +#define PCFE_CZ_CMPL_TIMEOUT_260_TO_900MS 9 +#define PCFE_CZ_CMPL_TIMEOUT_65_TO_210MS 6 +#define PCFE_CZ_CMPL_TIMEOUT_16_TO_55MS 5 +#define PCFE_CZ_CMPL_TIMEOUT_1_TO_10MS 2 +#define PCFE_CZ_CMPL_TIMEOUT_50_TO_100US 1 +#define PCFE_CZ_CMPL_TIMEOUT_DEFAULT 0 + + +/* + * PC_MSIX_TBL_BASE_REG(32bit): + * MSIX Capability Vector Table Base + */ + +#define PCR_BB_MSIX_TBL_BASE_REG 0x00000094 +/* falconb0=pci_f0_config */ + +#define PCR_CZ_MSIX_TBL_BASE_REG 0x000000b4 +/* sienaa0,hunta0=pci_f0_config */ + +#define PCRF_BZ_MSIX_TBL_OFF_LBN 3 +#define PCRF_BZ_MSIX_TBL_OFF_WIDTH 29 +#define PCRF_BZ_MSIX_TBL_BIR_LBN 0 +#define PCRF_BZ_MSIX_TBL_BIR_WIDTH 3 + + +/* + * PC_DEV_CTL2_REG(16bit): + * PCIe Device Control 2 + */ + +#define PCR_CC_DEV_CTL2_REG 0x00000098 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_DEV_CTL2_REG 0x000000e8 +/* hunta0=pci_f0_config */ + +#define PCRF_CZ_CMPL_TIMEOUT_DIS_CTL_LBN 4 +#define PCRF_CZ_CMPL_TIMEOUT_DIS_CTL_WIDTH 1 +#define PCRF_CZ_CMPL_TIMEOUT_CTL_LBN 0 +#define PCRF_CZ_CMPL_TIMEOUT_CTL_WIDTH 4 + + +/* + * PC_MSIX_PBA_BASE_REG(32bit): + * MSIX Capability PBA Base + */ + +#define PCR_BB_MSIX_PBA_BASE_REG 0x00000098 +/* falconb0=pci_f0_config */ + +#define PCR_CZ_MSIX_PBA_BASE_REG 0x000000b8 +/* sienaa0,hunta0=pci_f0_config */ + +#define PCRF_BZ_MSIX_PBA_OFF_LBN 3 +#define PCRF_BZ_MSIX_PBA_OFF_WIDTH 29 +#define PCRF_BZ_MSIX_PBA_BIR_LBN 0 +#define PCRF_BZ_MSIX_PBA_BIR_WIDTH 3 + + +/* + * PC_LNK_CTL2_REG(16bit): + * PCIe Link Control 2 + */ + +#define PCR_CC_LNK_CTL2_REG 0x000000a0 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_LNK_CTL2_REG 0x000000f0 +/* hunta0=pci_f0_config */ + +#define PCRF_CZ_POLLING_DEEMPH_LVL_LBN 12 +#define PCRF_CZ_POLLING_DEEMPH_LVL_WIDTH 1 +#define PCRF_CZ_COMPLIANCE_SOS_CTL_LBN 11 +#define PCRF_CZ_COMPLIANCE_SOS_CTL_WIDTH 1 +#define PCRF_CZ_ENTER_MODIFIED_COMPLIANCE_CTL_LBN 10 +#define PCRF_CZ_ENTER_MODIFIED_COMPLIANCE_CTL_WIDTH 1 +#define PCRF_CZ_TRANSMIT_MARGIN_LBN 7 +#define PCRF_CZ_TRANSMIT_MARGIN_WIDTH 3 +#define PCRF_CZ_SELECT_DEEMPH_LBN 6 +#define PCRF_CZ_SELECT_DEEMPH_WIDTH 1 +#define PCRF_CZ_HW_AUTONOMOUS_SPEED_DIS_LBN 5 +#define PCRF_CZ_HW_AUTONOMOUS_SPEED_DIS_WIDTH 1 +#define PCRF_CZ_ENTER_COMPLIANCE_CTL_LBN 4 +#define PCRF_CZ_ENTER_COMPLIANCE_CTL_WIDTH 1 +#define PCRF_CZ_TGT_LNK_SPEED_CTL_LBN 0 +#define PCRF_CZ_TGT_LNK_SPEED_CTL_WIDTH 4 + + +/* + * PC_LNK_STAT2_REG(16bit): + * PCIe Link Status 2 + */ + +#define PCR_CC_LNK_STAT2_REG 0x000000a2 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_LNK_STAT2_REG 0x000000f2 +/* hunta0=pci_f0_config */ + +#define PCRF_CZ_CURRENT_DEEMPH_LBN 0 +#define PCRF_CZ_CURRENT_DEEMPH_WIDTH 1 + + +/* + * PC_VPD_CAP_ID_REG(8bit): + * VPD data register + */ + +#define PCR_AB_VPD_CAP_ID_REG 0x000000b0 +/* falcona0,falconb0=pci_f0_config */ + +#define PCRF_AB_VPD_CAP_ID_LBN 0 +#define PCRF_AB_VPD_CAP_ID_WIDTH 8 + + +/* + * PC_VPD_NXT_PTR_REG(8bit): + * VPD next item pointer + */ + +#define PCR_AB_VPD_NXT_PTR_REG 0x000000b1 +/* falcona0,falconb0=pci_f0_config */ + +#define PCRF_AB_VPD_NXT_PTR_LBN 0 +#define PCRF_AB_VPD_NXT_PTR_WIDTH 8 + + +/* + * PC_VPD_ADDR_REG(16bit): + * VPD address register + */ + +#define PCR_AB_VPD_ADDR_REG 0x000000b2 +/* falcona0,falconb0=pci_f0_config */ + +#define PCRF_AB_VPD_FLAG_LBN 15 +#define PCRF_AB_VPD_FLAG_WIDTH 1 +#define PCRF_AB_VPD_ADDR_LBN 0 +#define PCRF_AB_VPD_ADDR_WIDTH 15 + + +/* + * PC_AER_CAP_HDR_REG(32bit): + * AER capability header register + */ + +#define PCR_AZ_AER_CAP_HDR_REG 0x00000100 +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_AERCAPHDR_NXT_PTR_LBN 20 +#define PCRF_AZ_AERCAPHDR_NXT_PTR_WIDTH 12 +#define PCRF_AZ_AERCAPHDR_VER_LBN 16 +#define PCRF_AZ_AERCAPHDR_VER_WIDTH 4 +#define PCRF_AZ_AERCAPHDR_ID_LBN 0 +#define PCRF_AZ_AERCAPHDR_ID_WIDTH 16 + + +/* + * PC_AER_UNCORR_ERR_STAT_REG(32bit): + * AER Uncorrectable error status register + */ + +#define PCR_AZ_AER_UNCORR_ERR_STAT_REG 0x00000104 +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_UNSUPT_REQ_ERR_STAT_LBN 20 +#define PCRF_AZ_UNSUPT_REQ_ERR_STAT_WIDTH 1 +#define PCRF_AZ_ECRC_ERR_STAT_LBN 19 +#define PCRF_AZ_ECRC_ERR_STAT_WIDTH 1 +#define PCRF_AZ_MALF_TLP_STAT_LBN 18 +#define PCRF_AZ_MALF_TLP_STAT_WIDTH 1 +#define PCRF_AZ_RX_OVF_STAT_LBN 17 +#define PCRF_AZ_RX_OVF_STAT_WIDTH 1 +#define PCRF_AZ_UNEXP_COMP_STAT_LBN 16 +#define PCRF_AZ_UNEXP_COMP_STAT_WIDTH 1 +#define PCRF_AZ_COMP_ABRT_STAT_LBN 15 +#define PCRF_AZ_COMP_ABRT_STAT_WIDTH 1 +#define PCRF_AZ_COMP_TIMEOUT_STAT_LBN 14 +#define PCRF_AZ_COMP_TIMEOUT_STAT_WIDTH 1 +#define PCRF_AZ_FC_PROTO_ERR_STAT_LBN 13 +#define PCRF_AZ_FC_PROTO_ERR_STAT_WIDTH 1 +#define PCRF_AZ_PSON_TLP_STAT_LBN 12 +#define PCRF_AZ_PSON_TLP_STAT_WIDTH 1 +#define PCRF_AZ_DL_PROTO_ERR_STAT_LBN 4 +#define PCRF_AZ_DL_PROTO_ERR_STAT_WIDTH 1 +#define PCRF_AB_TRAIN_ERR_STAT_LBN 0 +#define PCRF_AB_TRAIN_ERR_STAT_WIDTH 1 + + +/* + * PC_AER_UNCORR_ERR_MASK_REG(32bit): + * AER Uncorrectable error mask register + */ + +#define PCR_AZ_AER_UNCORR_ERR_MASK_REG 0x00000108 +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_UNSUPT_REQ_ERR_MASK_LBN 20 +#define PCRF_AZ_UNSUPT_REQ_ERR_MASK_WIDTH 1 +#define PCRF_AZ_ECRC_ERR_MASK_LBN 19 +#define PCRF_AZ_ECRC_ERR_MASK_WIDTH 1 +#define PCRF_AZ_MALF_TLP_MASK_LBN 18 +#define PCRF_AZ_MALF_TLP_MASK_WIDTH 1 +#define PCRF_AZ_RX_OVF_MASK_LBN 17 +#define PCRF_AZ_RX_OVF_MASK_WIDTH 1 +#define PCRF_AZ_UNEXP_COMP_MASK_LBN 16 +#define PCRF_AZ_UNEXP_COMP_MASK_WIDTH 1 +#define PCRF_AZ_COMP_ABRT_MASK_LBN 15 +#define PCRF_AZ_COMP_ABRT_MASK_WIDTH 1 +#define PCRF_AZ_COMP_TIMEOUT_MASK_LBN 14 +#define PCRF_AZ_COMP_TIMEOUT_MASK_WIDTH 1 +#define PCRF_AZ_FC_PROTO_ERR_MASK_LBN 13 +#define PCRF_AZ_FC_PROTO_ERR_MASK_WIDTH 1 +#define PCRF_AZ_PSON_TLP_MASK_LBN 12 +#define PCRF_AZ_PSON_TLP_MASK_WIDTH 1 +#define PCRF_AZ_DL_PROTO_ERR_MASK_LBN 4 +#define PCRF_AZ_DL_PROTO_ERR_MASK_WIDTH 1 +#define PCRF_AB_TRAIN_ERR_MASK_LBN 0 +#define PCRF_AB_TRAIN_ERR_MASK_WIDTH 1 + + +/* + * PC_AER_UNCORR_ERR_SEV_REG(32bit): + * AER Uncorrectable error severity register + */ + +#define PCR_AZ_AER_UNCORR_ERR_SEV_REG 0x0000010c +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_UNSUPT_REQ_ERR_SEV_LBN 20 +#define PCRF_AZ_UNSUPT_REQ_ERR_SEV_WIDTH 1 +#define PCRF_AZ_ECRC_ERR_SEV_LBN 19 +#define PCRF_AZ_ECRC_ERR_SEV_WIDTH 1 +#define PCRF_AZ_MALF_TLP_SEV_LBN 18 +#define PCRF_AZ_MALF_TLP_SEV_WIDTH 1 +#define PCRF_AZ_RX_OVF_SEV_LBN 17 +#define PCRF_AZ_RX_OVF_SEV_WIDTH 1 +#define PCRF_AZ_UNEXP_COMP_SEV_LBN 16 +#define PCRF_AZ_UNEXP_COMP_SEV_WIDTH 1 +#define PCRF_AZ_COMP_ABRT_SEV_LBN 15 +#define PCRF_AZ_COMP_ABRT_SEV_WIDTH 1 +#define PCRF_AZ_COMP_TIMEOUT_SEV_LBN 14 +#define PCRF_AZ_COMP_TIMEOUT_SEV_WIDTH 1 +#define PCRF_AZ_FC_PROTO_ERR_SEV_LBN 13 +#define PCRF_AZ_FC_PROTO_ERR_SEV_WIDTH 1 +#define PCRF_AZ_PSON_TLP_SEV_LBN 12 +#define PCRF_AZ_PSON_TLP_SEV_WIDTH 1 +#define PCRF_AZ_DL_PROTO_ERR_SEV_LBN 4 +#define PCRF_AZ_DL_PROTO_ERR_SEV_WIDTH 1 +#define PCRF_AB_TRAIN_ERR_SEV_LBN 0 +#define PCRF_AB_TRAIN_ERR_SEV_WIDTH 1 + + +/* + * PC_AER_CORR_ERR_STAT_REG(32bit): + * AER Correctable error status register + */ + +#define PCR_AZ_AER_CORR_ERR_STAT_REG 0x00000110 +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_CZ_ADVSY_NON_FATAL_STAT_LBN 13 +#define PCRF_CZ_ADVSY_NON_FATAL_STAT_WIDTH 1 +#define PCRF_AZ_RPLY_TMR_TOUT_STAT_LBN 12 +#define PCRF_AZ_RPLY_TMR_TOUT_STAT_WIDTH 1 +#define PCRF_AZ_RPLAY_NUM_RO_STAT_LBN 8 +#define PCRF_AZ_RPLAY_NUM_RO_STAT_WIDTH 1 +#define PCRF_AZ_BAD_DLLP_STAT_LBN 7 +#define PCRF_AZ_BAD_DLLP_STAT_WIDTH 1 +#define PCRF_AZ_BAD_TLP_STAT_LBN 6 +#define PCRF_AZ_BAD_TLP_STAT_WIDTH 1 +#define PCRF_AZ_RX_ERR_STAT_LBN 0 +#define PCRF_AZ_RX_ERR_STAT_WIDTH 1 + + +/* + * PC_AER_CORR_ERR_MASK_REG(32bit): + * AER Correctable error status register + */ + +#define PCR_AZ_AER_CORR_ERR_MASK_REG 0x00000114 +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_CZ_ADVSY_NON_FATAL_MASK_LBN 13 +#define PCRF_CZ_ADVSY_NON_FATAL_MASK_WIDTH 1 +#define PCRF_AZ_RPLY_TMR_TOUT_MASK_LBN 12 +#define PCRF_AZ_RPLY_TMR_TOUT_MASK_WIDTH 1 +#define PCRF_AZ_RPLAY_NUM_RO_MASK_LBN 8 +#define PCRF_AZ_RPLAY_NUM_RO_MASK_WIDTH 1 +#define PCRF_AZ_BAD_DLLP_MASK_LBN 7 +#define PCRF_AZ_BAD_DLLP_MASK_WIDTH 1 +#define PCRF_AZ_BAD_TLP_MASK_LBN 6 +#define PCRF_AZ_BAD_TLP_MASK_WIDTH 1 +#define PCRF_AZ_RX_ERR_MASK_LBN 0 +#define PCRF_AZ_RX_ERR_MASK_WIDTH 1 + + +/* + * PC_AER_CAP_CTL_REG(32bit): + * AER capability and control register + */ + +#define PCR_AZ_AER_CAP_CTL_REG 0x00000118 +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_ECRC_CHK_EN_LBN 8 +#define PCRF_AZ_ECRC_CHK_EN_WIDTH 1 +#define PCRF_AZ_ECRC_CHK_CAP_LBN 7 +#define PCRF_AZ_ECRC_CHK_CAP_WIDTH 1 +#define PCRF_AZ_ECRC_GEN_EN_LBN 6 +#define PCRF_AZ_ECRC_GEN_EN_WIDTH 1 +#define PCRF_AZ_ECRC_GEN_CAP_LBN 5 +#define PCRF_AZ_ECRC_GEN_CAP_WIDTH 1 +#define PCRF_AZ_1ST_ERR_PTR_LBN 0 +#define PCRF_AZ_1ST_ERR_PTR_WIDTH 5 + + +/* + * PC_AER_HDR_LOG_REG(128bit): + * AER Header log register + */ + +#define PCR_AZ_AER_HDR_LOG_REG 0x0000011c +/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */ + +#define PCRF_AZ_HDR_LOG_LBN 0 +#define PCRF_AZ_HDR_LOG_WIDTH 128 + + +/* + * PC_DEVSN_CAP_HDR_REG(32bit): + * Device serial number capability header register + */ + +#define PCR_DZ_DEVSN_CAP_HDR_REG 0x00000130 +/* hunta0=pci_f0_config */ + +#define PCR_CC_DEVSN_CAP_HDR_REG 0x00000140 +/* sienaa0=pci_f0_config */ + +#define PCRF_CZ_DEVSNCAPHDR_NXT_PTR_LBN 20 +#define PCRF_CZ_DEVSNCAPHDR_NXT_PTR_WIDTH 12 +#define PCRF_CZ_DEVSNCAPHDR_VER_LBN 16 +#define PCRF_CZ_DEVSNCAPHDR_VER_WIDTH 4 +#define PCRF_CZ_DEVSNCAPHDR_ID_LBN 0 +#define PCRF_CZ_DEVSNCAPHDR_ID_WIDTH 16 + + +/* + * PC_DEVSN_DWORD0_REG(32bit): + * Device serial number DWORD0 + */ + +#define PCR_DZ_DEVSN_DWORD0_REG 0x00000134 +/* hunta0=pci_f0_config */ + +#define PCR_CC_DEVSN_DWORD0_REG 0x00000144 +/* sienaa0=pci_f0_config */ + +#define PCRF_CZ_DEVSN_DWORD0_LBN 0 +#define PCRF_CZ_DEVSN_DWORD0_WIDTH 32 + + +/* + * PC_DEVSN_DWORD1_REG(32bit): + * Device serial number DWORD0 + */ + +#define PCR_DZ_DEVSN_DWORD1_REG 0x00000138 +/* hunta0=pci_f0_config */ + +#define PCR_CC_DEVSN_DWORD1_REG 0x00000148 +/* sienaa0=pci_f0_config */ + +#define PCRF_CZ_DEVSN_DWORD1_LBN 0 +#define PCRF_CZ_DEVSN_DWORD1_WIDTH 32 + + +/* + * PC_ARI_CAP_HDR_REG(32bit): + * ARI capability header register + */ + +#define PCR_DZ_ARI_CAP_HDR_REG 0x00000140 +/* hunta0=pci_f0_config */ + +#define PCR_CC_ARI_CAP_HDR_REG 0x00000150 +/* sienaa0=pci_f0_config */ + +#define PCRF_CZ_ARICAPHDR_NXT_PTR_LBN 20 +#define PCRF_CZ_ARICAPHDR_NXT_PTR_WIDTH 12 +#define PCRF_CZ_ARICAPHDR_VER_LBN 16 +#define PCRF_CZ_ARICAPHDR_VER_WIDTH 4 +#define PCRF_CZ_ARICAPHDR_ID_LBN 0 +#define PCRF_CZ_ARICAPHDR_ID_WIDTH 16 + + +/* + * PC_ARI_CAP_REG(16bit): + * ARI Capabilities + */ + +#define PCR_DZ_ARI_CAP_REG 0x00000144 +/* hunta0=pci_f0_config */ + +#define PCR_CC_ARI_CAP_REG 0x00000154 +/* sienaa0=pci_f0_config */ + +#define PCRF_CZ_ARI_NXT_FN_NUM_LBN 8 +#define PCRF_CZ_ARI_NXT_FN_NUM_WIDTH 8 +#define PCRF_CZ_ARI_ACS_FNGRP_CAP_LBN 1 +#define PCRF_CZ_ARI_ACS_FNGRP_CAP_WIDTH 1 +#define PCRF_CZ_ARI_MFVC_FNGRP_CAP_LBN 0 +#define PCRF_CZ_ARI_MFVC_FNGRP_CAP_WIDTH 1 + + +/* + * PC_ARI_CTL_REG(16bit): + * ARI Control + */ + +#define PCR_DZ_ARI_CTL_REG 0x00000146 +/* hunta0=pci_f0_config */ + +#define PCR_CC_ARI_CTL_REG 0x00000156 +/* sienaa0=pci_f0_config */ + +#define PCRF_CZ_ARI_FN_GRP_LBN 4 +#define PCRF_CZ_ARI_FN_GRP_WIDTH 3 +#define PCRF_CZ_ARI_ACS_FNGRP_EN_LBN 1 +#define PCRF_CZ_ARI_ACS_FNGRP_EN_WIDTH 1 +#define PCRF_CZ_ARI_MFVC_FNGRP_EN_LBN 0 +#define PCRF_CZ_ARI_MFVC_FNGRP_EN_WIDTH 1 + + +/* + * PC_SRIOV_CAP_HDR_REG(32bit): + * SRIOV capability header register + */ + +#define PCR_CC_SRIOV_CAP_HDR_REG 0x00000160 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_SRIOV_CAP_HDR_REG 0x00000200 +/* hunta0=pci_f0_config */ + +#define PCRF_CZ_SRIOVCAPHDR_NXT_PTR_LBN 20 +#define PCRF_CZ_SRIOVCAPHDR_NXT_PTR_WIDTH 12 +#define PCRF_CZ_SRIOVCAPHDR_VER_LBN 16 +#define PCRF_CZ_SRIOVCAPHDR_VER_WIDTH 4 +#define PCRF_CZ_SRIOVCAPHDR_ID_LBN 0 +#define PCRF_CZ_SRIOVCAPHDR_ID_WIDTH 16 + + +/* + * PC_SRIOV_CAP_REG(32bit): + * SRIOV Capabilities + */ + +#define PCR_CC_SRIOV_CAP_REG 0x00000164 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_SRIOV_CAP_REG 0x00000204 +/* hunta0=pci_f0_config */ + +#define PCRF_CZ_VF_MIGR_INT_MSG_NUM_LBN 21 +#define PCRF_CZ_VF_MIGR_INT_MSG_NUM_WIDTH 11 +#define PCRF_CZ_VF_MIGR_CAP_LBN 0 +#define PCRF_CZ_VF_MIGR_CAP_WIDTH 1 + + +/* + * PC_SRIOV_CTL_REG(16bit): + * SRIOV Control + */ + +#define PCR_CC_SRIOV_CTL_REG 0x00000168 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_SRIOV_CTL_REG 0x00000208 +/* hunta0=pci_f0_config */ + +#define PCRF_CZ_VF_ARI_CAP_HRCHY_LBN 4 +#define PCRF_CZ_VF_ARI_CAP_HRCHY_WIDTH 1 +#define PCRF_CZ_VF_MSE_LBN 3 +#define PCRF_CZ_VF_MSE_WIDTH 1 +#define PCRF_CZ_VF_MIGR_INT_EN_LBN 2 +#define PCRF_CZ_VF_MIGR_INT_EN_WIDTH 1 +#define PCRF_CZ_VF_MIGR_EN_LBN 1 +#define PCRF_CZ_VF_MIGR_EN_WIDTH 1 +#define PCRF_CZ_VF_EN_LBN 0 +#define PCRF_CZ_VF_EN_WIDTH 1 + + +/* + * PC_SRIOV_STAT_REG(16bit): + * SRIOV Status + */ + +#define PCR_CC_SRIOV_STAT_REG 0x0000016a +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_SRIOV_STAT_REG 0x0000020a +/* hunta0=pci_f0_config */ + +#define PCRF_CZ_VF_MIGR_STAT_LBN 0 +#define PCRF_CZ_VF_MIGR_STAT_WIDTH 1 + + +/* + * PC_SRIOV_INITIALVFS_REG(16bit): + * SRIOV Initial VFs + */ + +#define PCR_CC_SRIOV_INITIALVFS_REG 0x0000016c +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_SRIOV_INITIALVFS_REG 0x0000020c +/* hunta0=pci_f0_config */ + +#define PCRF_CZ_VF_INITIALVFS_LBN 0 +#define PCRF_CZ_VF_INITIALVFS_WIDTH 16 + + +/* + * PC_SRIOV_TOTALVFS_REG(10bit): + * SRIOV Total VFs + */ + +#define PCR_CC_SRIOV_TOTALVFS_REG 0x0000016e +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_SRIOV_TOTALVFS_REG 0x0000020e +/* hunta0=pci_f0_config */ + +#define PCRF_CZ_VF_TOTALVFS_LBN 0 +#define PCRF_CZ_VF_TOTALVFS_WIDTH 16 + + +/* + * PC_SRIOV_NUMVFS_REG(16bit): + * SRIOV Number of VFs + */ + +#define PCR_CC_SRIOV_NUMVFS_REG 0x00000170 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_SRIOV_NUMVFS_REG 0x00000210 +/* hunta0=pci_f0_config */ + +#define PCRF_CZ_VF_NUMVFS_LBN 0 +#define PCRF_CZ_VF_NUMVFS_WIDTH 16 + + +/* + * PC_SRIOV_FN_DPND_LNK_REG(16bit): + * SRIOV Function dependency link + */ + +#define PCR_CC_SRIOV_FN_DPND_LNK_REG 0x00000172 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_SRIOV_FN_DPND_LNK_REG 0x00000212 +/* hunta0=pci_f0_config */ + +#define PCRF_CZ_SRIOV_FN_DPND_LNK_LBN 0 +#define PCRF_CZ_SRIOV_FN_DPND_LNK_WIDTH 8 + + +/* + * PC_SRIOV_1STVF_OFFSET_REG(16bit): + * SRIOV First VF Offset + */ + +#define PCR_CC_SRIOV_1STVF_OFFSET_REG 0x00000174 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_SRIOV_1STVF_OFFSET_REG 0x00000214 +/* hunta0=pci_f0_config */ + +#define PCRF_CZ_VF_1STVF_OFFSET_LBN 0 +#define PCRF_CZ_VF_1STVF_OFFSET_WIDTH 16 + + +/* + * PC_SRIOV_VFSTRIDE_REG(16bit): + * SRIOV VF Stride + */ + +#define PCR_CC_SRIOV_VFSTRIDE_REG 0x00000176 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_SRIOV_VFSTRIDE_REG 0x00000216 +/* hunta0=pci_f0_config */ + +#define PCRF_CZ_VF_VFSTRIDE_LBN 0 +#define PCRF_CZ_VF_VFSTRIDE_WIDTH 16 + + +/* + * PC_SRIOV_DEVID_REG(16bit): + * SRIOV VF Device ID + */ + +#define PCR_CC_SRIOV_DEVID_REG 0x0000017a +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_SRIOV_DEVID_REG 0x0000021a +/* hunta0=pci_f0_config */ + +#define PCRF_CZ_VF_DEVID_LBN 0 +#define PCRF_CZ_VF_DEVID_WIDTH 16 + + +/* + * PC_SRIOV_SUP_PAGESZ_REG(16bit): + * SRIOV Supported Page Sizes + */ + +#define PCR_CC_SRIOV_SUP_PAGESZ_REG 0x0000017c +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_SRIOV_SUP_PAGESZ_REG 0x0000021c +/* hunta0=pci_f0_config */ + +#define PCRF_CZ_VF_SUP_PAGESZ_LBN 0 +#define PCRF_CZ_VF_SUP_PAGESZ_WIDTH 16 + + +/* + * PC_SRIOV_SYS_PAGESZ_REG(32bit): + * SRIOV System Page Size + */ + +#define PCR_CC_SRIOV_SYS_PAGESZ_REG 0x00000180 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_SRIOV_SYS_PAGESZ_REG 0x00000220 +/* hunta0=pci_f0_config */ + +#define PCRF_CZ_VF_SYS_PAGESZ_LBN 0 +#define PCRF_CZ_VF_SYS_PAGESZ_WIDTH 16 + + +/* + * PC_SRIOV_BAR0_REG(32bit): + * SRIOV VF Bar0 + */ + +#define PCR_CC_SRIOV_BAR0_REG 0x00000184 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_SRIOV_BAR0_REG 0x00000224 +/* hunta0=pci_f0_config */ + +#define PCRF_CC_VF_BAR_ADDRESS_LBN 0 +#define PCRF_CC_VF_BAR_ADDRESS_WIDTH 32 +#define PCRF_DZ_VF_BAR0_ADDRESS_LBN 0 +#define PCRF_DZ_VF_BAR0_ADDRESS_WIDTH 32 + + +/* + * PC_SRIOV_BAR1_REG(32bit): + * SRIOV Bar1 + */ + +#define PCR_CC_SRIOV_BAR1_REG 0x00000188 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_SRIOV_BAR1_REG 0x00000228 +/* hunta0=pci_f0_config */ + +/* defined as PCRF_CC_VF_BAR_ADDRESS_LBN 0; */ +/* defined as PCRF_CC_VF_BAR_ADDRESS_WIDTH 32 */ +#define PCRF_DZ_VF_BAR1_ADDRESS_LBN 0 +#define PCRF_DZ_VF_BAR1_ADDRESS_WIDTH 32 + + +/* + * PC_SRIOV_BAR2_REG(32bit): + * SRIOV Bar2 + */ + +#define PCR_CC_SRIOV_BAR2_REG 0x0000018c +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_SRIOV_BAR2_REG 0x0000022c +/* hunta0=pci_f0_config */ + +/* defined as PCRF_CC_VF_BAR_ADDRESS_LBN 0; */ +/* defined as PCRF_CC_VF_BAR_ADDRESS_WIDTH 32 */ +#define PCRF_DZ_VF_BAR2_ADDRESS_LBN 0 +#define PCRF_DZ_VF_BAR2_ADDRESS_WIDTH 32 + + +/* + * PC_SRIOV_BAR3_REG(32bit): + * SRIOV Bar3 + */ + +#define PCR_CC_SRIOV_BAR3_REG 0x00000190 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_SRIOV_BAR3_REG 0x00000230 +/* hunta0=pci_f0_config */ + +/* defined as PCRF_CC_VF_BAR_ADDRESS_LBN 0; */ +/* defined as PCRF_CC_VF_BAR_ADDRESS_WIDTH 32 */ +#define PCRF_DZ_VF_BAR3_ADDRESS_LBN 0 +#define PCRF_DZ_VF_BAR3_ADDRESS_WIDTH 32 + + +/* + * PC_SRIOV_BAR4_REG(32bit): + * SRIOV Bar4 + */ + +#define PCR_CC_SRIOV_BAR4_REG 0x00000194 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_SRIOV_BAR4_REG 0x00000234 +/* hunta0=pci_f0_config */ + +/* defined as PCRF_CC_VF_BAR_ADDRESS_LBN 0; */ +/* defined as PCRF_CC_VF_BAR_ADDRESS_WIDTH 32 */ +#define PCRF_DZ_VF_BAR4_ADDRESS_LBN 0 +#define PCRF_DZ_VF_BAR4_ADDRESS_WIDTH 32 + + +/* + * PC_SRIOV_BAR5_REG(32bit): + * SRIOV Bar5 + */ + +#define PCR_CC_SRIOV_BAR5_REG 0x00000198 +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_SRIOV_BAR5_REG 0x00000238 +/* hunta0=pci_f0_config */ + +/* defined as PCRF_CC_VF_BAR_ADDRESS_LBN 0; */ +/* defined as PCRF_CC_VF_BAR_ADDRESS_WIDTH 32 */ +#define PCRF_DZ_VF_BAR5_ADDRESS_LBN 0 +#define PCRF_DZ_VF_BAR5_ADDRESS_WIDTH 32 + + +/* + * PC_SRIOV_MIBR_SARRAY_OFFSET_REG(32bit): + * SRIOV VF Migration State Array Offset + */ + +#define PCR_CC_SRIOV_MIBR_SARRAY_OFFSET_REG 0x0000019c +/* sienaa0=pci_f0_config */ + +#define PCR_DZ_SRIOV_MIBR_SARRAY_OFFSET_REG 0x0000023c +/* hunta0=pci_f0_config */ + +#define PCRF_CZ_VF_MIGR_OFFSET_LBN 3 +#define PCRF_CZ_VF_MIGR_OFFSET_WIDTH 29 +#define PCRF_CZ_VF_MIGR_BIR_LBN 0 +#define PCRF_CZ_VF_MIGR_BIR_WIDTH 3 + + +/* + * PC_LTR_CAP_HDR_REG(32bit): + * Latency Tolerance Reporting Cap Header Reg + */ + +#define PCR_DZ_LTR_CAP_HDR_REG 0x00000240 +/* hunta0=pci_f0_config */ + +#define PCRF_DZ_LTR_NXT_PTR_LBN 20 +#define PCRF_DZ_LTR_NXT_PTR_WIDTH 12 +#define PCRF_DZ_LTR_VERSION_LBN 16 +#define PCRF_DZ_LTR_VERSION_WIDTH 4 +#define PCRF_DZ_LTR_EXT_CAP_ID_LBN 0 +#define PCRF_DZ_LTR_EXT_CAP_ID_WIDTH 16 + + +/* + * PC_LTR_MAX_SNOOP_REG(32bit): + * LTR Maximum Snoop/No Snoop Register + */ + +#define PCR_DZ_LTR_MAX_SNOOP_REG 0x00000244 +/* hunta0=pci_f0_config */ + +#define PCRF_DZ_LTR_MAX_NOSNOOP_SCALE_LBN 26 +#define PCRF_DZ_LTR_MAX_NOSNOOP_SCALE_WIDTH 3 +#define PCRF_DZ_LTR_MAX_NOSNOOP_LAT_LBN 16 +#define PCRF_DZ_LTR_MAX_NOSNOOP_LAT_WIDTH 10 +#define PCRF_DZ_LTR_MAX_SNOOP_SCALE_LBN 10 +#define PCRF_DZ_LTR_MAX_SNOOP_SCALE_WIDTH 3 +#define PCRF_DZ_LTR_MAX_SNOOP_LAT_LBN 0 +#define PCRF_DZ_LTR_MAX_SNOOP_LAT_WIDTH 10 + + +/* + * PC_TPH_CAP_HDR_REG(32bit): + * TPH Capability Header Register + */ + +#define PCR_DZ_TPH_CAP_HDR_REG 0x00000274 +/* hunta0=pci_f0_config */ + +#define PCRF_DZ_TPH_NXT_PTR_LBN 20 +#define PCRF_DZ_TPH_NXT_PTR_WIDTH 12 +#define PCRF_DZ_TPH_VERSION_LBN 16 +#define PCRF_DZ_TPH_VERSION_WIDTH 4 +#define PCRF_DZ_TPH_EXT_CAP_ID_LBN 0 +#define PCRF_DZ_TPH_EXT_CAP_ID_WIDTH 16 + + +/* + * PC_TPH_REQ_CAP_REG(32bit): + * TPH Requester Capability Register + */ + +#define PCR_DZ_TPH_REQ_CAP_REG 0x00000278 +/* hunta0=pci_f0_config */ + +#define PCRF_DZ_ST_TBLE_SIZE_LBN 16 +#define PCRF_DZ_ST_TBLE_SIZE_WIDTH 11 +#define PCRF_DZ_ST_TBLE_LOC_LBN 9 +#define PCRF_DZ_ST_TBLE_LOC_WIDTH 2 +#define PCRF_DZ_EXT_TPH_MODE_SUP_LBN 8 +#define PCRF_DZ_EXT_TPH_MODE_SUP_WIDTH 1 +#define PCRF_DZ_TPH_DEV_MODE_SUP_LBN 2 +#define PCRF_DZ_TPH_DEV_MODE_SUP_WIDTH 1 +#define PCRF_DZ_TPH_INT_MODE_SUP_LBN 1 +#define PCRF_DZ_TPH_INT_MODE_SUP_WIDTH 1 +#define PCRF_DZ_TPH_NOST_MODE_SUP_LBN 0 +#define PCRF_DZ_TPH_NOST_MODE_SUP_WIDTH 1 + + +/* + * PC_TPH_REQ_CTL_REG(32bit): + * TPH Requester Control Register + */ + +#define PCR_DZ_TPH_REQ_CTL_REG 0x0000027c +/* hunta0=pci_f0_config */ + +#define PCRF_DZ_TPH_REQ_ENABLE_LBN 8 +#define PCRF_DZ_TPH_REQ_ENABLE_WIDTH 2 +#define PCRF_DZ_TPH_ST_MODE_LBN 0 +#define PCRF_DZ_TPH_ST_MODE_WIDTH 3 + + +/* + * PC_SEC_PCIE_CAP_REG(32bit): + * Secondary PCIE Capability Register + */ + +#define PCR_DZ_SEC_PCIE_CAP_REG 0x00000300 +/* hunta0=pci_f0_config */ + +#define PCRF_DZ_SEC_NXT_PTR_LBN 20 +#define PCRF_DZ_SEC_NXT_PTR_WIDTH 12 +#define PCRF_DZ_SEC_VERSION_LBN 16 +#define PCRF_DZ_SEC_VERSION_WIDTH 4 +#define PCRF_DZ_SEC_EXT_CAP_ID_LBN 0 +#define PCRF_DZ_SEC_EXT_CAP_ID_WIDTH 16 + + +/* + * PC_LINK_CONTROL3_REG(32bit): + * Link Control 3. + */ + +#define PCR_DZ_LINK_CONTROL3_REG 0x00000304 +/* hunta0=pci_f0_config */ + +#define PCRF_DZ_LINK_EQ_INT_EN_LBN 1 +#define PCRF_DZ_LINK_EQ_INT_EN_WIDTH 1 +#define PCRF_DZ_PERFORM_EQL_LBN 0 +#define PCRF_DZ_PERFORM_EQL_WIDTH 1 + + +/* + * PC_LANE_ERROR_STAT_REG(32bit): + * Lane Error Status Register. + */ + +#define PCR_DZ_LANE_ERROR_STAT_REG 0x00000308 +/* hunta0=pci_f0_config */ + +#define PCRF_DZ_LANE_STATUS_LBN 0 +#define PCRF_DZ_LANE_STATUS_WIDTH 8 + + +/* + * PC_LANE01_EQU_CONTROL_REG(32bit): + * Lanes 0,1 Equalization Control Register. + */ + +#define PCR_DZ_LANE01_EQU_CONTROL_REG 0x0000030c +/* hunta0=pci_f0_config */ + +#define PCRF_DZ_LANE1_EQ_CTRL_LBN 16 +#define PCRF_DZ_LANE1_EQ_CTRL_WIDTH 16 +#define PCRF_DZ_LANE0_EQ_CTRL_LBN 0 +#define PCRF_DZ_LANE0_EQ_CTRL_WIDTH 16 + + +/* + * PC_LANE23_EQU_CONTROL_REG(32bit): + * Lanes 2,3 Equalization Control Register. + */ + +#define PCR_DZ_LANE23_EQU_CONTROL_REG 0x00000310 +/* hunta0=pci_f0_config */ + +#define PCRF_DZ_LANE3_EQ_CTRL_LBN 16 +#define PCRF_DZ_LANE3_EQ_CTRL_WIDTH 16 +#define PCRF_DZ_LANE2_EQ_CTRL_LBN 0 +#define PCRF_DZ_LANE2_EQ_CTRL_WIDTH 16 + + +/* + * PC_LANE45_EQU_CONTROL_REG(32bit): + * Lanes 4,5 Equalization Control Register. + */ + +#define PCR_DZ_LANE45_EQU_CONTROL_REG 0x00000314 +/* hunta0=pci_f0_config */ + +#define PCRF_DZ_LANE5_EQ_CTRL_LBN 16 +#define PCRF_DZ_LANE5_EQ_CTRL_WIDTH 16 +#define PCRF_DZ_LANE4_EQ_CTRL_LBN 0 +#define PCRF_DZ_LANE4_EQ_CTRL_WIDTH 16 + + +/* + * PC_LANE67_EQU_CONTROL_REG(32bit): + * Lanes 6,7 Equalization Control Register. + */ + +#define PCR_DZ_LANE67_EQU_CONTROL_REG 0x00000318 +/* hunta0=pci_f0_config */ + +#define PCRF_DZ_LANE7_EQ_CTRL_LBN 16 +#define PCRF_DZ_LANE7_EQ_CTRL_WIDTH 16 +#define PCRF_DZ_LANE6_EQ_CTRL_LBN 0 +#define PCRF_DZ_LANE6_EQ_CTRL_WIDTH 16 + + +/* + * PC_ACK_LAT_TMR_REG(32bit): + * ACK latency timer & replay timer register + */ + +#define PCR_AC_ACK_LAT_TMR_REG 0x00000700 +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCRF_AC_RT_LBN 16 +#define PCRF_AC_RT_WIDTH 16 +#define PCRF_AC_ALT_LBN 0 +#define PCRF_AC_ALT_WIDTH 16 + + +/* + * PC_OTHER_MSG_REG(32bit): + * Other message register + */ + +#define PCR_AC_OTHER_MSG_REG 0x00000704 +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCRF_AC_OM_CRPT3_LBN 24 +#define PCRF_AC_OM_CRPT3_WIDTH 8 +#define PCRF_AC_OM_CRPT2_LBN 16 +#define PCRF_AC_OM_CRPT2_WIDTH 8 +#define PCRF_AC_OM_CRPT1_LBN 8 +#define PCRF_AC_OM_CRPT1_WIDTH 8 +#define PCRF_AC_OM_CRPT0_LBN 0 +#define PCRF_AC_OM_CRPT0_WIDTH 8 + + +/* + * PC_FORCE_LNK_REG(24bit): + * Port force link register + */ + +#define PCR_AC_FORCE_LNK_REG 0x00000708 +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCRF_AC_LFS_LBN 16 +#define PCRF_AC_LFS_WIDTH 6 +#define PCRF_AC_FL_LBN 15 +#define PCRF_AC_FL_WIDTH 1 +#define PCRF_AC_LN_LBN 0 +#define PCRF_AC_LN_WIDTH 8 + + +/* + * PC_ACK_FREQ_REG(32bit): + * ACK frequency register + */ + +#define PCR_AC_ACK_FREQ_REG 0x0000070c +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCRF_CC_ALLOW_L1_WITHOUT_L0S_LBN 30 +#define PCRF_CC_ALLOW_L1_WITHOUT_L0S_WIDTH 1 +#define PCRF_AC_L1_ENTR_LAT_LBN 27 +#define PCRF_AC_L1_ENTR_LAT_WIDTH 3 +#define PCRF_AC_L0_ENTR_LAT_LBN 24 +#define PCRF_AC_L0_ENTR_LAT_WIDTH 3 +#define PCRF_CC_COMM_NFTS_LBN 16 +#define PCRF_CC_COMM_NFTS_WIDTH 8 +#define PCRF_AB_ACK_FREQ_REG_RSVD0_LBN 16 +#define PCRF_AB_ACK_FREQ_REG_RSVD0_WIDTH 3 +#define PCRF_AC_MAX_FTS_LBN 8 +#define PCRF_AC_MAX_FTS_WIDTH 8 +#define PCRF_AC_ACK_FREQ_LBN 0 +#define PCRF_AC_ACK_FREQ_WIDTH 8 + + +/* + * PC_PORT_LNK_CTL_REG(32bit): + * Port link control register + */ + +#define PCR_AC_PORT_LNK_CTL_REG 0x00000710 +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCRF_AB_LRE_LBN 27 +#define PCRF_AB_LRE_WIDTH 1 +#define PCRF_AB_ESYNC_LBN 26 +#define PCRF_AB_ESYNC_WIDTH 1 +#define PCRF_AB_CRPT_LBN 25 +#define PCRF_AB_CRPT_WIDTH 1 +#define PCRF_AB_XB_LBN 24 +#define PCRF_AB_XB_WIDTH 1 +#define PCRF_AC_LC_LBN 16 +#define PCRF_AC_LC_WIDTH 6 +#define PCRF_AC_LDR_LBN 8 +#define PCRF_AC_LDR_WIDTH 4 +#define PCRF_AC_FLM_LBN 7 +#define PCRF_AC_FLM_WIDTH 1 +#define PCRF_AC_LKD_LBN 6 +#define PCRF_AC_LKD_WIDTH 1 +#define PCRF_AC_DLE_LBN 5 +#define PCRF_AC_DLE_WIDTH 1 +#define PCRF_AB_PORT_LNK_CTL_REG_RSVD0_LBN 4 +#define PCRF_AB_PORT_LNK_CTL_REG_RSVD0_WIDTH 1 +#define PCRF_AC_RA_LBN 3 +#define PCRF_AC_RA_WIDTH 1 +#define PCRF_AC_LE_LBN 2 +#define PCRF_AC_LE_WIDTH 1 +#define PCRF_AC_SD_LBN 1 +#define PCRF_AC_SD_WIDTH 1 +#define PCRF_AC_OMR_LBN 0 +#define PCRF_AC_OMR_WIDTH 1 + + +/* + * PC_LN_SKEW_REG(32bit): + * Lane skew register + */ + +#define PCR_AC_LN_SKEW_REG 0x00000714 +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCRF_AC_DIS_LBN 31 +#define PCRF_AC_DIS_WIDTH 1 +#define PCRF_AB_RST_LBN 30 +#define PCRF_AB_RST_WIDTH 1 +#define PCRF_AC_AD_LBN 25 +#define PCRF_AC_AD_WIDTH 1 +#define PCRF_AC_FCD_LBN 24 +#define PCRF_AC_FCD_WIDTH 1 +#define PCRF_AC_LS2_LBN 16 +#define PCRF_AC_LS2_WIDTH 8 +#define PCRF_AC_LS1_LBN 8 +#define PCRF_AC_LS1_WIDTH 8 +#define PCRF_AC_LS0_LBN 0 +#define PCRF_AC_LS0_WIDTH 8 + + +/* + * PC_SYM_NUM_REG(16bit): + * Symbol number register + */ + +#define PCR_AC_SYM_NUM_REG 0x00000718 +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCRF_CC_MAX_FUNCTIONS_LBN 29 +#define PCRF_CC_MAX_FUNCTIONS_WIDTH 3 +#define PCRF_CC_FC_WATCHDOG_TMR_LBN 24 +#define PCRF_CC_FC_WATCHDOG_TMR_WIDTH 5 +#define PCRF_CC_ACK_NAK_TMR_MOD_LBN 19 +#define PCRF_CC_ACK_NAK_TMR_MOD_WIDTH 5 +#define PCRF_CC_REPLAY_TMR_MOD_LBN 14 +#define PCRF_CC_REPLAY_TMR_MOD_WIDTH 5 +#define PCRF_AB_ES_LBN 12 +#define PCRF_AB_ES_WIDTH 3 +#define PCRF_AB_SYM_NUM_REG_RSVD0_LBN 11 +#define PCRF_AB_SYM_NUM_REG_RSVD0_WIDTH 1 +#define PCRF_CC_NUM_SKP_SYMS_LBN 8 +#define PCRF_CC_NUM_SKP_SYMS_WIDTH 3 +#define PCRF_AB_TS2_LBN 4 +#define PCRF_AB_TS2_WIDTH 4 +#define PCRF_AC_TS1_LBN 0 +#define PCRF_AC_TS1_WIDTH 4 + + +/* + * PC_SYM_TMR_FLT_MSK_REG(16bit): + * Symbol timer and Filter Mask Register + */ + +#define PCR_CC_SYM_TMR_FLT_MSK_REG 0x0000071c +/* sienaa0=pci_f0_config */ + +#define PCRF_CC_DEFAULT_FLT_MSK1_LBN 16 +#define PCRF_CC_DEFAULT_FLT_MSK1_WIDTH 16 +#define PCRF_CC_FC_WDOG_TMR_DIS_LBN 15 +#define PCRF_CC_FC_WDOG_TMR_DIS_WIDTH 1 +#define PCRF_CC_SI1_LBN 8 +#define PCRF_CC_SI1_WIDTH 3 +#define PCRF_CC_SKIP_INT_VAL_LBN 0 +#define PCRF_CC_SKIP_INT_VAL_WIDTH 11 +#define PCRF_CC_SI0_LBN 0 +#define PCRF_CC_SI0_WIDTH 8 + + +/* + * PC_SYM_TMR_REG(16bit): + * Symbol timer register + */ + +#define PCR_AB_SYM_TMR_REG 0x0000071c +/* falcona0,falconb0=pci_f0_config */ + +#define PCRF_AB_ET_LBN 11 +#define PCRF_AB_ET_WIDTH 4 +#define PCRF_AB_SI1_LBN 8 +#define PCRF_AB_SI1_WIDTH 3 +#define PCRF_AB_SI0_LBN 0 +#define PCRF_AB_SI0_WIDTH 8 + + +/* + * PC_PHY_STAT_REG(32bit): + * PHY status register + */ + +#define PCR_AB_PHY_STAT_REG 0x00000720 +/* falcona0,falconb0=pci_f0_config */ + +#define PCR_CC_PHY_STAT_REG 0x00000810 +/* sienaa0=pci_f0_config */ + +#define PCRF_AC_SSL_LBN 3 +#define PCRF_AC_SSL_WIDTH 1 +#define PCRF_AC_SSR_LBN 2 +#define PCRF_AC_SSR_WIDTH 1 +#define PCRF_AC_SSCL_LBN 1 +#define PCRF_AC_SSCL_WIDTH 1 +#define PCRF_AC_SSCD_LBN 0 +#define PCRF_AC_SSCD_WIDTH 1 + + +/* + * PC_FLT_MSK_REG(32bit): + * Filter Mask Register 2 + */ + +#define PCR_CC_FLT_MSK_REG 0x00000720 +/* sienaa0=pci_f0_config */ + +#define PCRF_CC_DEFAULT_FLT_MSK2_LBN 0 +#define PCRF_CC_DEFAULT_FLT_MSK2_WIDTH 32 + + +/* + * PC_PHY_CTL_REG(32bit): + * PHY control register + */ + +#define PCR_AB_PHY_CTL_REG 0x00000724 +/* falcona0,falconb0=pci_f0_config */ + +#define PCR_CC_PHY_CTL_REG 0x00000814 +/* sienaa0=pci_f0_config */ + +#define PCRF_AC_BD_LBN 31 +#define PCRF_AC_BD_WIDTH 1 +#define PCRF_AC_CDS_LBN 30 +#define PCRF_AC_CDS_WIDTH 1 +#define PCRF_AC_DWRAP_LB_LBN 29 +#define PCRF_AC_DWRAP_LB_WIDTH 1 +#define PCRF_AC_EBD_LBN 28 +#define PCRF_AC_EBD_WIDTH 1 +#define PCRF_AC_SNR_LBN 27 +#define PCRF_AC_SNR_WIDTH 1 +#define PCRF_AC_RX_NOT_DET_LBN 2 +#define PCRF_AC_RX_NOT_DET_WIDTH 1 +#define PCRF_AC_FORCE_LOS_VAL_LBN 1 +#define PCRF_AC_FORCE_LOS_VAL_WIDTH 1 +#define PCRF_AC_FORCE_LOS_EN_LBN 0 +#define PCRF_AC_FORCE_LOS_EN_WIDTH 1 + + +/* + * PC_DEBUG0_REG(32bit): + * Debug register 0 + */ + +#define PCR_AC_DEBUG0_REG 0x00000728 +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCRF_AC_CDI03_LBN 24 +#define PCRF_AC_CDI03_WIDTH 8 +#define PCRF_AC_CDI0_LBN 0 +#define PCRF_AC_CDI0_WIDTH 32 +#define PCRF_AC_CDI02_LBN 16 +#define PCRF_AC_CDI02_WIDTH 8 +#define PCRF_AC_CDI01_LBN 8 +#define PCRF_AC_CDI01_WIDTH 8 +#define PCRF_AC_CDI00_LBN 0 +#define PCRF_AC_CDI00_WIDTH 8 + + +/* + * PC_DEBUG1_REG(32bit): + * Debug register 1 + */ + +#define PCR_AC_DEBUG1_REG 0x0000072c +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCRF_AC_CDI13_LBN 24 +#define PCRF_AC_CDI13_WIDTH 8 +#define PCRF_AC_CDI1_LBN 0 +#define PCRF_AC_CDI1_WIDTH 32 +#define PCRF_AC_CDI12_LBN 16 +#define PCRF_AC_CDI12_WIDTH 8 +#define PCRF_AC_CDI11_LBN 8 +#define PCRF_AC_CDI11_WIDTH 8 +#define PCRF_AC_CDI10_LBN 0 +#define PCRF_AC_CDI10_WIDTH 8 + + +/* + * PC_XPFCC_STAT_REG(24bit): + * documentation to be written for sum_PC_XPFCC_STAT_REG + */ + +#define PCR_AC_XPFCC_STAT_REG 0x00000730 +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCRF_AC_XPDC_LBN 12 +#define PCRF_AC_XPDC_WIDTH 8 +#define PCRF_AC_XPHC_LBN 0 +#define PCRF_AC_XPHC_WIDTH 12 + + +/* + * PC_XNPFCC_STAT_REG(24bit): + * documentation to be written for sum_PC_XNPFCC_STAT_REG + */ + +#define PCR_AC_XNPFCC_STAT_REG 0x00000734 +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCRF_AC_XNPDC_LBN 12 +#define PCRF_AC_XNPDC_WIDTH 8 +#define PCRF_AC_XNPHC_LBN 0 +#define PCRF_AC_XNPHC_WIDTH 12 + + +/* + * PC_XCFCC_STAT_REG(24bit): + * documentation to be written for sum_PC_XCFCC_STAT_REG + */ + +#define PCR_AC_XCFCC_STAT_REG 0x00000738 +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCRF_AC_XCDC_LBN 12 +#define PCRF_AC_XCDC_WIDTH 8 +#define PCRF_AC_XCHC_LBN 0 +#define PCRF_AC_XCHC_WIDTH 12 + + +/* + * PC_Q_STAT_REG(8bit): + * documentation to be written for sum_PC_Q_STAT_REG + */ + +#define PCR_AC_Q_STAT_REG 0x0000073c +/* falcona0,falconb0,sienaa0=pci_f0_config */ + +#define PCRF_AC_RQNE_LBN 2 +#define PCRF_AC_RQNE_WIDTH 1 +#define PCRF_AC_XRNE_LBN 1 +#define PCRF_AC_XRNE_WIDTH 1 +#define PCRF_AC_RCNR_LBN 0 +#define PCRF_AC_RCNR_WIDTH 1 + + +/* + * PC_VC_XMIT_ARB1_REG(32bit): + * VC Transmit Arbitration Register 1 + */ + +#define PCR_CC_VC_XMIT_ARB1_REG 0x00000740 +/* sienaa0=pci_f0_config */ + + + +/* + * PC_VC_XMIT_ARB2_REG(32bit): + * VC Transmit Arbitration Register 2 + */ + +#define PCR_CC_VC_XMIT_ARB2_REG 0x00000744 +/* sienaa0=pci_f0_config */ + + + +/* + * PC_VC0_P_RQ_CTL_REG(32bit): + * VC0 Posted Receive Queue Control + */ + +#define PCR_CC_VC0_P_RQ_CTL_REG 0x00000748 +/* sienaa0=pci_f0_config */ + + + +/* + * PC_VC0_NP_RQ_CTL_REG(32bit): + * VC0 Non-Posted Receive Queue Control + */ + +#define PCR_CC_VC0_NP_RQ_CTL_REG 0x0000074c +/* sienaa0=pci_f0_config */ + + + +/* + * PC_VC0_C_RQ_CTL_REG(32bit): + * VC0 Completion Receive Queue Control + */ + +#define PCR_CC_VC0_C_RQ_CTL_REG 0x00000750 +/* sienaa0=pci_f0_config */ + + + +/* + * PC_GEN2_REG(32bit): + * Gen2 Register + */ + +#define PCR_CC_GEN2_REG 0x0000080c +/* sienaa0=pci_f0_config */ + +#define PCRF_CC_SET_DE_EMPHASIS_LBN 20 +#define PCRF_CC_SET_DE_EMPHASIS_WIDTH 1 +#define PCRF_CC_CFG_TX_COMPLIANCE_LBN 19 +#define PCRF_CC_CFG_TX_COMPLIANCE_WIDTH 1 +#define PCRF_CC_CFG_TX_SWING_LBN 18 +#define PCRF_CC_CFG_TX_SWING_WIDTH 1 +#define PCRF_CC_DIR_SPEED_CHANGE_LBN 17 +#define PCRF_CC_DIR_SPEED_CHANGE_WIDTH 1 +#define PCRF_CC_LANE_ENABLE_LBN 8 +#define PCRF_CC_LANE_ENABLE_WIDTH 9 +#define PCRF_CC_NUM_FTS_LBN 0 +#define PCRF_CC_NUM_FTS_WIDTH 8 + + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_EFX_REGS_PCI_H */ diff --git a/sys/dev/sfxge/common/efx_rx.c b/sys/dev/sfxge/common/efx_rx.c new file mode 100644 index 000000000000..7d3d7c1f4699 --- /dev/null +++ b/sys/dev/sfxge/common/efx_rx.c @@ -0,0 +1,816 @@ +/*- + * Copyright 2007-2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "efsys.h" +#include "efx.h" +#include "efx_types.h" +#include "efx_regs.h" +#include "efx_impl.h" + + __checkReturn int +efx_rx_init( + __in efx_nic_t *enp) +{ + efx_oword_t oword; + unsigned int index; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); + + if (!(enp->en_mod_flags & EFX_MOD_EV)) { + rc = EINVAL; + goto fail1; + } + + if (enp->en_mod_flags & EFX_MOD_RX) { + rc = EINVAL; + goto fail2; + } + + EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword); + + EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_DESC_PUSH_EN, 0); + EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 0); + EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH, 0); + EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP, 0); + EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR, 0); + EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_USR_BUF_SIZE, 0x3000 / 32); + EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword); + + /* Zero the RSS table */ + for (index = 0; index < FR_BZ_RX_INDIRECTION_TBL_ROWS; + index++) { + EFX_ZERO_OWORD(oword); + EFX_BAR_TBL_WRITEO(enp, FR_BZ_RX_INDIRECTION_TBL, + index, &oword); + } + + enp->en_mod_flags |= EFX_MOD_RX; + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#if EFSYS_OPT_RX_HDR_SPLIT + __checkReturn int +efx_rx_hdr_split_enable( + __in efx_nic_t *enp, + __in unsigned int hdr_buf_size, + __in unsigned int pld_buf_size) +{ + unsigned int nhdr32; + unsigned int npld32; + efx_oword_t oword; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX); + EFSYS_ASSERT3U(enp->en_family, >=, EFX_FAMILY_SIENA); + + nhdr32 = hdr_buf_size / 32; + if ((nhdr32 == 0) || + (nhdr32 >= (1 << FRF_CZ_RX_HDR_SPLIT_HDR_BUF_SIZE_WIDTH)) || + ((hdr_buf_size % 32) != 0)) { + rc = EINVAL; + goto fail1; + } + + npld32 = pld_buf_size / 32; + if ((npld32 == 0) || + (npld32 >= (1 << FRF_CZ_RX_HDR_SPLIT_PLD_BUF_SIZE_WIDTH)) || + ((pld_buf_size % 32) != 0)) { + rc = EINVAL; + goto fail2; + } + + if (enp->en_rx_qcount > 0) { + rc = EBUSY; + goto fail3; + } + + EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword); + + EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_HDR_SPLIT_EN, 1); + EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_HDR_SPLIT_HDR_BUF_SIZE, nhdr32); + EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_HDR_SPLIT_PLD_BUF_SIZE, npld32); + + EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword); + + return (0); + +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} +#endif /* EFSYS_OPT_RX_HDR_SPLIT */ + + +#if EFSYS_OPT_RX_SCATTER + __checkReturn int +efx_rx_scatter_enable( + __in efx_nic_t *enp, + __in unsigned int buf_size) +{ + unsigned int nbuf32; + efx_oword_t oword; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX); + EFSYS_ASSERT3U(enp->en_family, >=, EFX_FAMILY_FALCON); + + nbuf32 = buf_size / 32; + if ((nbuf32 == 0) || + (nbuf32 >= (1 << FRF_BZ_RX_USR_BUF_SIZE_WIDTH)) || + ((buf_size % 32) != 0)) { + rc = EINVAL; + goto fail1; + } + + if (enp->en_rx_qcount > 0) { + rc = EBUSY; + goto fail2; + } + + /* Set scatter buffer size */ + EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword); + EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_USR_BUF_SIZE, nbuf32); + EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword); + + /* Enable scatter for packets not matching a filter */ + EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword); + EFX_SET_OWORD_FIELD(oword, FRF_BZ_SCATTER_ENBL_NO_MATCH_Q, 1); + EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword); + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} +#endif /* EFSYS_OPT_RX_SCATTER */ + + +#define EFX_RX_LFSR_HASH(_enp, _insert) \ + do { \ + efx_oword_t oword; \ + \ + EFX_BAR_READO((_enp), FR_AZ_RX_CFG_REG, &oword); \ + EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 0); \ + EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH, 0); \ + EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP, 0); \ + EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR, \ + (_insert) ? 1 : 0); \ + EFX_BAR_WRITEO((_enp), FR_AZ_RX_CFG_REG, &oword); \ + \ + if ((_enp)->en_family == EFX_FAMILY_SIENA) { \ + EFX_BAR_READO((_enp), FR_CZ_RX_RSS_IPV6_REG3, \ + &oword); \ + EFX_SET_OWORD_FIELD(oword, \ + FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 0); \ + EFX_BAR_WRITEO((_enp), FR_CZ_RX_RSS_IPV6_REG3, \ + &oword); \ + } \ + \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFX_RX_TOEPLITZ_IPV4_HASH(_enp, _insert, _ip, _tcp) \ + do { \ + efx_oword_t oword; \ + \ + EFX_BAR_READO((_enp), FR_AZ_RX_CFG_REG, &oword); \ + EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 1); \ + EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH, \ + (_ip) ? 1 : 0); \ + EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP, \ + (_tcp) ? 0 : 1); \ + EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR, \ + (_insert) ? 1 : 0); \ + EFX_BAR_WRITEO((_enp), FR_AZ_RX_CFG_REG, &oword); \ + \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + +#define EFX_RX_TOEPLITZ_IPV6_HASH(_enp, _ip, _tcp, _rc) \ + do { \ + efx_oword_t oword; \ + \ + if ((_enp)->en_family == EFX_FAMILY_FALCON) { \ + (_rc) = ((_ip) || (_tcp)) ? ENOTSUP : 0; \ + break; \ + } \ + \ + EFX_BAR_READO((_enp), FR_CZ_RX_RSS_IPV6_REG3, &oword); \ + EFX_SET_OWORD_FIELD(oword, \ + FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 1); \ + EFX_SET_OWORD_FIELD(oword, \ + FRF_CZ_RX_RSS_IPV6_IP_THASH_ENABLE, (_ip) ? 1 : 0); \ + EFX_SET_OWORD_FIELD(oword, \ + FRF_CZ_RX_RSS_IPV6_TCP_SUPPRESS, (_tcp) ? 0 : 1); \ + EFX_BAR_WRITEO((_enp), FR_CZ_RX_RSS_IPV6_REG3, &oword); \ + \ + (_rc) = 0; \ + \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + + +#if EFSYS_OPT_RX_SCALE + __checkReturn int +efx_rx_scale_mode_set( + __in efx_nic_t *enp, + __in efx_rx_hash_alg_t alg, + __in efx_rx_hash_type_t type, + __in boolean_t insert) +{ + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX); + EFSYS_ASSERT3U(enp->en_family, >=, EFX_FAMILY_FALCON); + + switch (alg) { + case EFX_RX_HASHALG_LFSR: + EFX_RX_LFSR_HASH(enp, insert); + break; + + case EFX_RX_HASHALG_TOEPLITZ: + EFX_RX_TOEPLITZ_IPV4_HASH(enp, insert, + type & (1 << EFX_RX_HASH_IPV4), + type & (1 << EFX_RX_HASH_TCPIPV4)); + + EFX_RX_TOEPLITZ_IPV6_HASH(enp, + type & (1 << EFX_RX_HASH_IPV6), + type & (1 << EFX_RX_HASH_TCPIPV6), + rc); + if (rc != 0) + goto fail1; + + break; + + default: + rc = EINVAL; + goto fail2; + } + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + EFX_RX_LFSR_HASH(enp, B_FALSE); + + return (rc); +} +#endif + +#if EFSYS_OPT_RX_SCALE + __checkReturn int +efx_rx_scale_toeplitz_ipv4_key_set( + __in efx_nic_t *enp, + __in_ecount(n) uint8_t *key, + __in size_t n) +{ + efx_oword_t oword; + unsigned int byte; + unsigned int offset; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX); + + byte = 0; + + /* Write toeplitz hash key */ + EFX_ZERO_OWORD(oword); + for (offset = (FRF_BZ_RX_RSS_TKEY_LBN + FRF_BZ_RX_RSS_TKEY_WIDTH) / 8; + offset > 0 && byte < n; + --offset) + oword.eo_u8[offset - 1] = key[byte++]; + + EFX_BAR_WRITEO(enp, FR_BZ_RX_RSS_TKEY_REG, &oword); + + byte = 0; + + /* Verify toeplitz hash key */ + EFX_BAR_READO(enp, FR_BZ_RX_RSS_TKEY_REG, &oword); + for (offset = (FRF_BZ_RX_RSS_TKEY_LBN + FRF_BZ_RX_RSS_TKEY_WIDTH) / 8; + offset > 0 && byte < n; + --offset) { + if (oword.eo_u8[offset - 1] != key[byte++]) { + rc = EFAULT; + goto fail1; + } + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} +#endif + +#if EFSYS_OPT_RX_SCALE + __checkReturn int +efx_rx_scale_toeplitz_ipv6_key_set( + __in efx_nic_t *enp, + __in_ecount(n) uint8_t *key, + __in size_t n) +{ + efx_oword_t oword; + unsigned int byte; + int offset; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX); + + byte = 0; + + /* Write toeplitz hash key 3 */ + EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword); + for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN + + FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH) / 8; + offset > 0 && byte < n; + --offset) + oword.eo_u8[offset - 1] = key[byte++]; + + EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword); + + /* Write toeplitz hash key 2 */ + EFX_ZERO_OWORD(oword); + for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN + + FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH) / 8; + offset > 0 && byte < n; + --offset) + oword.eo_u8[offset - 1] = key[byte++]; + + EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG2, &oword); + + /* Write toeplitz hash key 1 */ + EFX_ZERO_OWORD(oword); + for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN + + FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH) / 8; + offset > 0 && byte < n; + --offset) + oword.eo_u8[offset - 1] = key[byte++]; + + EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG1, &oword); + + byte = 0; + + /* Verify toeplitz hash key 3 */ + EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword); + for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN + + FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH) / 8; + offset > 0 && byte < n; + --offset) { + if (oword.eo_u8[offset - 1] != key[byte++]) { + rc = EFAULT; + goto fail1; + } + } + + /* Verify toeplitz hash key 2 */ + EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG2, &oword); + for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN + + FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH) / 8; + offset > 0 && byte < n; + --offset) { + if (oword.eo_u8[offset - 1] != key[byte++]) { + rc = EFAULT; + goto fail2; + } + } + + /* Verify toeplitz hash key 1 */ + EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG1, &oword); + for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN + + FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH) / 8; + offset > 0 && byte < n; + --offset) { + if (oword.eo_u8[offset - 1] != key[byte++]) { + rc = EFAULT; + goto fail3; + } + } + + return (0); + +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} +#endif + +#if EFSYS_OPT_RX_SCALE + __checkReturn int +efx_rx_scale_tbl_set( + __in efx_nic_t *enp, + __in_ecount(n) unsigned int *table, + __in size_t n) +{ + efx_oword_t oword; + int index; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX); + + EFX_STATIC_ASSERT(EFX_RSS_TBL_SIZE == FR_BZ_RX_INDIRECTION_TBL_ROWS); + EFX_STATIC_ASSERT(EFX_MAXRSS == (1 << FRF_BZ_IT_QUEUE_WIDTH)); + + if (n > FR_BZ_RX_INDIRECTION_TBL_ROWS) { + rc = EINVAL; + goto fail1; + } + + for (index = 0; index < FR_BZ_RX_INDIRECTION_TBL_ROWS; index++) { + uint32_t byte; + + /* Calculate the entry to place in the table */ + byte = (uint32_t)table[index % n]; + + EFSYS_PROBE2(table, int, index, uint32_t, byte); + + EFX_POPULATE_OWORD_1(oword, FRF_BZ_IT_QUEUE, byte); + + /* Write the table */ + EFX_BAR_TBL_WRITEO(enp, FR_BZ_RX_INDIRECTION_TBL, + index, &oword); + } + + for (index = FR_BZ_RX_INDIRECTION_TBL_ROWS - 1; index >= 0; --index) { + uint32_t byte; + + /* Determine if we're starting a new batch */ + byte = (uint32_t)table[index % n]; + + /* Read the table */ + EFX_BAR_TBL_READO(enp, FR_BZ_RX_INDIRECTION_TBL, + index, &oword); + + /* Verify the entry */ + if (EFX_OWORD_FIELD(oword, FRF_BZ_IT_QUEUE) != byte) { + rc = EFAULT; + goto fail2; + } + } + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} +#endif + +#if EFSYS_OPT_FILTER +extern __checkReturn int +efx_rx_filter_insert( + __in efx_rxq_t *erp, + __inout efx_filter_spec_t *spec) +{ + EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC); + EFSYS_ASSERT3P(spec, !=, NULL); + + spec->efs_dmaq_id = (uint16_t)erp->er_index; + return efx_filter_insert_filter(erp->er_enp, spec, B_FALSE); +} +#endif + +#if EFSYS_OPT_FILTER +extern __checkReturn int +efx_rx_filter_remove( + __in efx_rxq_t *erp, + __inout efx_filter_spec_t *spec) +{ + EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC); + EFSYS_ASSERT3P(spec, !=, NULL); + + spec->efs_dmaq_id = (uint16_t)erp->er_index; + return efx_filter_remove_filter(erp->er_enp, spec); +} +#endif + +extern void +efx_rx_qpost( + __in efx_rxq_t *erp, + __in_ecount(n) efsys_dma_addr_t *addrp, + __in size_t size, + __in unsigned int n, + __in unsigned int completed, + __in unsigned int added) +{ + efx_qword_t qword; + unsigned int i; + unsigned int offset; + unsigned int id; + + EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC); + + /* The client driver must not overfill the queue */ + EFSYS_ASSERT3U(added - completed + n, <=, + EFX_RXQ_LIMIT(erp->er_mask + 1)); + + id = added & (erp->er_mask); + for (i = 0; i < n; i++) { + EFSYS_PROBE4(rx_post, unsigned int, erp->er_index, + unsigned int, id, efsys_dma_addr_t, addrp[i], + size_t, size); + + EFX_POPULATE_QWORD_3(qword, + FSF_AZ_RX_KER_BUF_SIZE, (uint32_t)(size), + FSF_AZ_RX_KER_BUF_ADDR_DW0, + (uint32_t)(addrp[i] & 0xffffffff), + FSF_AZ_RX_KER_BUF_ADDR_DW1, + (uint32_t)(addrp[i] >> 32)); + + offset = id * sizeof (efx_qword_t); + EFSYS_MEM_WRITEQ(erp->er_esmp, offset, &qword); + + id = (id + 1) & (erp->er_mask); + } +} + + void +efx_rx_qpush( + __in efx_rxq_t *erp, + __in unsigned int added) +{ + efx_nic_t *enp = erp->er_enp; + uint32_t wptr; + efx_oword_t oword; + efx_dword_t dword; + + EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC); + + /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */ + EFSYS_PIO_WRITE_BARRIER(); + + /* Push the populated descriptors out */ + wptr = added & erp->er_mask; + + EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DESC_WPTR, wptr); + + /* Only write the third DWORD */ + EFX_POPULATE_DWORD_1(dword, + EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3)); + EFX_BAR_TBL_WRITED3(enp, FR_BZ_RX_DESC_UPD_REGP0, + erp->er_index, &dword, B_FALSE); +} + + void +efx_rx_qflush( + __in efx_rxq_t *erp) +{ + efx_nic_t *enp = erp->er_enp; + efx_oword_t oword; + uint32_t label; + + EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC); + + label = erp->er_index; + + /* Flush the queue */ + EFX_POPULATE_OWORD_2(oword, FRF_AZ_RX_FLUSH_DESCQ_CMD, 1, + FRF_AZ_RX_FLUSH_DESCQ, label); + EFX_BAR_WRITEO(enp, FR_AZ_RX_FLUSH_DESCQ_REG, &oword); +} + + void +efx_rx_qenable( + __in efx_rxq_t *erp) +{ + efx_nic_t *enp = erp->er_enp; + efx_oword_t oword; + + EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC); + + EFX_BAR_TBL_READO(enp, FR_AZ_RX_DESC_PTR_TBL, + erp->er_index, &oword); + + EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DC_HW_RPTR, 0); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DESCQ_HW_RPTR, 0); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DESCQ_EN, 1); + + EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL, + erp->er_index, &oword); +} + + __checkReturn int +efx_rx_qcreate( + __in efx_nic_t *enp, + __in unsigned int index, + __in unsigned int label, + __in efx_rxq_type_t type, + __in efsys_mem_t *esmp, + __in size_t n, + __in uint32_t id, + __in efx_evq_t *eep, + __deref_out efx_rxq_t **erpp) +{ + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + efx_rxq_t *erp; + efx_oword_t oword; + uint32_t size; + boolean_t split; + boolean_t jumbo; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX); + + EFX_STATIC_ASSERT(EFX_EV_RX_NLABELS == (1 << FRF_AZ_RX_DESCQ_LABEL_WIDTH)); + EFSYS_ASSERT3U(label, <, EFX_EV_RX_NLABELS); + EFSYS_ASSERT3U(enp->en_rx_qcount + 1, <, encp->enc_rxq_limit); + + if (!ISP2(n) || !(n & EFX_RXQ_NDESCS_MASK)) { + rc = EINVAL; + goto fail1; + } + if (index >= encp->enc_rxq_limit) { + rc = EINVAL; + goto fail2; + } + for (size = 0; (1 << size) <= (EFX_RXQ_MAXNDESCS / EFX_RXQ_MINNDESCS); + size++) + if ((1 << size) == (int)(n / EFX_RXQ_MINNDESCS)) + break; + if (id + (1 << size) >= encp->enc_buftbl_limit) { + rc = EINVAL; + goto fail3; + } + + switch (type) { + case EFX_RXQ_TYPE_DEFAULT: + split = B_FALSE; + jumbo = B_FALSE; + break; + +#if EFSYS_OPT_RX_HDR_SPLIT + case EFX_RXQ_TYPE_SPLIT_HEADER: + if ((enp->en_family < EFX_FAMILY_SIENA) || ((index & 1) != 0)) { + rc = EINVAL; + goto fail4; + } + split = B_TRUE; + jumbo = B_TRUE; + break; + + case EFX_RXQ_TYPE_SPLIT_PAYLOAD: + if ((enp->en_family < EFX_FAMILY_SIENA) || ((index & 1) == 0)) { + rc = EINVAL; + goto fail4; + } + split = B_FALSE; + jumbo = B_TRUE; + break; +#endif /* EFSYS_OPT_RX_HDR_SPLIT */ + +#if EFSYS_OPT_RX_SCATTER + case EFX_RXQ_TYPE_SCATTER: + if (enp->en_family < EFX_FAMILY_SIENA) { + rc = EINVAL; + goto fail4; + } + split = B_FALSE; + jumbo = B_TRUE; + break; +#endif /* EFSYS_OPT_RX_SCATTER */ + + default: + rc = EINVAL; + goto fail4; + } + + /* Allocate an RXQ object */ + EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_rxq_t), erp); + + if (erp == NULL) { + rc = ENOMEM; + goto fail5; + } + + erp->er_magic = EFX_RXQ_MAGIC; + erp->er_enp = enp; + erp->er_index = index; + erp->er_mask = n - 1; + erp->er_esmp = esmp; + + /* Set up the new descriptor queue */ + EFX_POPULATE_OWORD_10(oword, + FRF_CZ_RX_HDR_SPLIT, split, + FRF_AZ_RX_ISCSI_DDIG_EN, 0, + FRF_AZ_RX_ISCSI_HDIG_EN, 0, + FRF_AZ_RX_DESCQ_BUF_BASE_ID, id, + FRF_AZ_RX_DESCQ_EVQ_ID, eep->ee_index, + FRF_AZ_RX_DESCQ_OWNER_ID, 0, + FRF_AZ_RX_DESCQ_LABEL, label, + FRF_AZ_RX_DESCQ_SIZE, size, + FRF_AZ_RX_DESCQ_TYPE, 0, + FRF_AZ_RX_DESCQ_JUMBO, jumbo); + + EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL, + erp->er_index, &oword); + + enp->en_rx_qcount++; + *erpp = erp; + return (0); + +fail5: + EFSYS_PROBE(fail5); +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + void +efx_rx_qdestroy( + __in efx_rxq_t *erp) +{ + efx_nic_t *enp = erp->er_enp; + efx_oword_t oword; + + EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC); + + EFSYS_ASSERT(enp->en_rx_qcount != 0); + --enp->en_rx_qcount; + + /* Purge descriptor queue */ + EFX_ZERO_OWORD(oword); + + EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL, + erp->er_index, &oword); + + /* Free the RXQ object */ + EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp); +} + + void +efx_rx_fini( + __in efx_nic_t *enp) +{ + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX); + EFSYS_ASSERT3U(enp->en_rx_qcount, ==, 0); + + enp->en_mod_flags &= ~EFX_MOD_RX; +} diff --git a/sys/dev/sfxge/common/efx_sram.c b/sys/dev/sfxge/common/efx_sram.c new file mode 100644 index 000000000000..16a3229065dc --- /dev/null +++ b/sys/dev/sfxge/common/efx_sram.c @@ -0,0 +1,294 @@ +/*- + * Copyright 2007-2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "efsys.h" +#include "efx.h" +#include "efx_types.h" +#include "efx_regs.h" +#include "efx_impl.h" + + __checkReturn int +efx_sram_buf_tbl_set( + __in efx_nic_t *enp, + __in uint32_t id, + __in efsys_mem_t *esmp, + __in size_t n) +{ + efx_qword_t qword; + uint32_t start = id; + uint32_t stop = start + n; + efsys_dma_addr_t addr; + efx_oword_t oword; + unsigned int count; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); + + if (stop >= EFX_BUF_TBL_SIZE) { + rc = EFBIG; + goto fail1; + } + + /* Add the entries into the buffer table */ + addr = EFSYS_MEM_ADDR(esmp); + for (id = start; id != stop; id++) { + EFX_POPULATE_QWORD_5(qword, + FRF_AZ_IP_DAT_BUF_SIZE, 0, FRF_AZ_BUF_ADR_REGION, 0, + FRF_AZ_BUF_ADR_FBUF_DW0, + (uint32_t)((addr >> 12) & 0xffffffff), + FRF_AZ_BUF_ADR_FBUF_DW1, + (uint32_t)((addr >> 12) >> 32), + FRF_AZ_BUF_OWNER_ID_FBUF, 0); + + EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_FULL_TBL, + id, &qword); + + addr += EFX_BUF_SIZE; + } + + EFSYS_PROBE2(buf, uint32_t, start, uint32_t, stop - 1); + + /* Flush the write buffer */ + EFX_POPULATE_OWORD_2(oword, FRF_AZ_BUF_UPD_CMD, 1, + FRF_AZ_BUF_CLR_CMD, 0); + EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_UPD_REG, &oword); + + /* Poll for the last entry being written to the buffer table */ + EFSYS_ASSERT3U(id, ==, stop); + addr -= EFX_BUF_SIZE; + + count = 0; + do { + EFSYS_PROBE1(wait, unsigned int, count); + + /* Spin for 1 ms */ + EFSYS_SPIN(1000); + + EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_FULL_TBL, + id - 1, &qword); + + if (EFX_QWORD_FIELD(qword, FRF_AZ_BUF_ADR_FBUF_DW0) == + (uint32_t)((addr >> 12) & 0xffffffff) && + EFX_QWORD_FIELD(qword, FRF_AZ_BUF_ADR_FBUF_DW1) == + (uint32_t)((addr >> 12) >> 32)) + goto verify; + + } while (++count < 100); + + rc = ETIMEDOUT; + goto fail2; + +verify: + /* Verify the rest of the entries in the buffer table */ + while (--id != start) { + addr -= EFX_BUF_SIZE; + + /* Read the buffer table entry */ + EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_FULL_TBL, + id - 1, &qword); + + if (EFX_QWORD_FIELD(qword, FRF_AZ_BUF_ADR_FBUF_DW0) != + (uint32_t)((addr >> 12) & 0xffffffff) || + EFX_QWORD_FIELD(qword, FRF_AZ_BUF_ADR_FBUF_DW1) != + (uint32_t)((addr >> 12) >> 32)) { + rc = EFAULT; + goto fail3; + } + } + + return (0); + +fail3: + EFSYS_PROBE(fail3); + + id = stop; + +fail2: + EFSYS_PROBE(fail2); + + EFX_POPULATE_OWORD_4(oword, FRF_AZ_BUF_UPD_CMD, 0, + FRF_AZ_BUF_CLR_CMD, 1, FRF_AZ_BUF_CLR_END_ID, id - 1, + FRF_AZ_BUF_CLR_START_ID, start); + EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_UPD_REG, &oword); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + void +efx_sram_buf_tbl_clear( + __in efx_nic_t *enp, + __in uint32_t id, + __in size_t n) +{ + efx_oword_t oword; + uint32_t start = id; + uint32_t stop = start + n; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); + + EFSYS_ASSERT3U(stop, <, EFX_BUF_TBL_SIZE); + + EFSYS_PROBE2(buf, uint32_t, start, uint32_t, stop - 1); + + EFX_POPULATE_OWORD_4(oword, FRF_AZ_BUF_UPD_CMD, 0, + FRF_AZ_BUF_CLR_CMD, 1, FRF_AZ_BUF_CLR_END_ID, stop - 1, + FRF_AZ_BUF_CLR_START_ID, start); + EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_UPD_REG, &oword); +} + + +#if EFSYS_OPT_DIAG + +static void +efx_sram_byte_increment_set( + __in size_t row, + __in boolean_t negate, + __out efx_qword_t *eqp) +{ + size_t offset = row * FR_AZ_SRM_DBG_REG_STEP; + unsigned int index; + + _NOTE(ARGUNUSED(negate)) + + for (index = 0; index < sizeof (efx_qword_t); index++) + eqp->eq_u8[index] = offset + index; +} + +static void +efx_sram_all_the_same_set( + __in size_t row, + __in boolean_t negate, + __out efx_qword_t *eqp) +{ + _NOTE(ARGUNUSED(row)) + + if (negate) + EFX_SET_QWORD(*eqp); + else + EFX_ZERO_QWORD(*eqp); +} + +static void +efx_sram_bit_alternate_set( + __in size_t row, + __in boolean_t negate, + __out efx_qword_t *eqp) +{ + _NOTE(ARGUNUSED(row)) + + EFX_POPULATE_QWORD_2(*eqp, + EFX_DWORD_0, (negate) ? 0x55555555 : 0xaaaaaaaa, + EFX_DWORD_1, (negate) ? 0x55555555 : 0xaaaaaaaa); +} + +static void +efx_sram_byte_alternate_set( + __in size_t row, + __in boolean_t negate, + __out efx_qword_t *eqp) +{ + _NOTE(ARGUNUSED(row)) + + EFX_POPULATE_QWORD_2(*eqp, + EFX_DWORD_0, (negate) ? 0x00ff00ff : 0xff00ff00, + EFX_DWORD_1, (negate) ? 0x00ff00ff : 0xff00ff00); +} + +static void +efx_sram_byte_changing_set( + __in size_t row, + __in boolean_t negate, + __out efx_qword_t *eqp) +{ + size_t offset = row * FR_AZ_SRM_DBG_REG_STEP; + unsigned int index; + + for (index = 0; index < sizeof (efx_qword_t); index++) { + uint8_t byte; + + if (offset / 256 == 0) + byte = (uint8_t)((offset % 257) % 256); + else + byte = (uint8_t)(~((offset - 8) % 257) % 256); + + eqp->eq_u8[index] = (negate) ? ~byte : byte; + } +} + +static void +efx_sram_bit_sweep_set( + __in size_t row, + __in boolean_t negate, + __out efx_qword_t *eqp) +{ + size_t offset = row * FR_AZ_SRM_DBG_REG_STEP; + + if (negate) { + EFX_SET_QWORD(*eqp); + EFX_CLEAR_QWORD_BIT(*eqp, (offset / sizeof (efx_qword_t)) % 64); + } else { + EFX_ZERO_QWORD(*eqp); + EFX_SET_QWORD_BIT(*eqp, (offset / sizeof (efx_qword_t)) % 64); + } +} + +efx_sram_pattern_fn_t __cs __efx_sram_pattern_fns[] = { + efx_sram_byte_increment_set, + efx_sram_all_the_same_set, + efx_sram_bit_alternate_set, + efx_sram_byte_alternate_set, + efx_sram_byte_changing_set, + efx_sram_bit_sweep_set +}; + + __checkReturn int +efx_sram_test( + __in efx_nic_t *enp, + __in efx_pattern_type_t type) +{ + efx_nic_ops_t *enop = enp->en_enop; + efx_sram_pattern_fn_t func; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); + + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX)); + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX)); + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV)); + + /* Select pattern generator */ + EFSYS_ASSERT3U(type, <, EFX_PATTERN_NTYPES); + func = __efx_sram_pattern_fns[type]; + + return (enop->eno_sram_test(enp, func)); +} + +#endif /* EFSYS_OPT_DIAG */ diff --git a/sys/dev/sfxge/common/efx_tx.c b/sys/dev/sfxge/common/efx_tx.c new file mode 100644 index 000000000000..0dc347c34fdd --- /dev/null +++ b/sys/dev/sfxge/common/efx_tx.c @@ -0,0 +1,430 @@ +/*- + * Copyright 2007-2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "efsys.h" +#include "efx.h" +#include "efx_types.h" +#include "efx_regs.h" +#include "efx_impl.h" + +#if EFSYS_OPT_QSTATS +#define EFX_TX_QSTAT_INCR(_etp, _stat) \ + do { \ + (_etp)->et_stat[_stat]++; \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) +#else +#define EFX_TX_QSTAT_INCR(_etp, _stat) +#endif + + __checkReturn int +efx_tx_init( + __in efx_nic_t *enp) +{ + efx_oword_t oword; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); + + if (!(enp->en_mod_flags & EFX_MOD_EV)) { + rc = EINVAL; + goto fail1; + } + + if (enp->en_mod_flags & EFX_MOD_TX) { + rc = EINVAL; + goto fail2; + } + + EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0); + + /* + * Disable the timer-based TX DMA backoff and allow TX DMA to be + * controlled by the RX FIFO fill level (although always allow a + * minimal trickle). + */ + EFX_BAR_READO(enp, FR_AZ_TX_RESERVED_REG, &oword); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_RX_SPACER, 0xfe); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_RX_SPACER_EN, 1); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_ONE_PKT_PER_Q, 1); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PUSH_EN, 0); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DIS_NON_IP_EV, 1); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PREF_THRESHOLD, 2); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PREF_WD_TMR, 0x3fffff); + + /* + * Filter all packets less than 14 bytes to avoid parsing + * errors. + */ + EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1); + EFX_BAR_WRITEO(enp, FR_AZ_TX_RESERVED_REG, &oword); + + /* + * Do not set TX_NO_EOP_DISC_EN, since it limits packets to 16 + * descriptors (which is bad). + */ + EFX_BAR_READO(enp, FR_AZ_TX_CFG_REG, &oword); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_NO_EOP_DISC_EN, 0); + EFX_BAR_WRITEO(enp, FR_AZ_TX_CFG_REG, &oword); + + enp->en_mod_flags |= EFX_MOD_TX; + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#if EFSYS_OPT_FILTER +extern __checkReturn int +efx_tx_filter_insert( + __in efx_txq_t *etp, + __inout efx_filter_spec_t *spec) +{ + EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC); + EFSYS_ASSERT3P(spec, !=, NULL); + + spec->efs_dmaq_id = (uint16_t)etp->et_index; + return efx_filter_insert_filter(etp->et_enp, spec, B_FALSE); +} +#endif + +#if EFSYS_OPT_FILTER +extern __checkReturn int +efx_tx_filter_remove( + __in efx_txq_t *etp, + __inout efx_filter_spec_t *spec) +{ + EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC); + EFSYS_ASSERT3P(spec, !=, NULL); + + spec->efs_dmaq_id = (uint16_t)etp->et_index; + return efx_filter_remove_filter(etp->et_enp, spec); +} +#endif + +#define EFX_TX_DESC(_etp, _addr, _size, _eop, _added) \ + do { \ + unsigned int id; \ + size_t offset; \ + efx_qword_t qword; \ + \ + id = (_added)++ & (_etp)->et_mask; \ + offset = id * sizeof (efx_qword_t); \ + \ + EFSYS_PROBE5(tx_post, unsigned int, (_etp)->et_index, \ + unsigned int, id, efsys_dma_addr_t, (_addr), \ + size_t, (_size), boolean_t, (_eop)); \ + \ + EFX_POPULATE_QWORD_4(qword, \ + FSF_AZ_TX_KER_CONT, (_eop) ? 0 : 1, \ + FSF_AZ_TX_KER_BYTE_COUNT, (uint32_t)(_size), \ + FSF_AZ_TX_KER_BUF_ADDR_DW0, \ + (uint32_t)((_addr) & 0xffffffff), \ + FSF_AZ_TX_KER_BUF_ADDR_DW1, \ + (uint32_t)((_addr) >> 32)); \ + EFSYS_MEM_WRITEQ((_etp)->et_esmp, offset, &qword); \ + \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + + __checkReturn int +efx_tx_qpost( + __in efx_txq_t *etp, + __in_ecount(n) efx_buffer_t *eb, + __in unsigned int n, + __in unsigned int completed, + __inout unsigned int *addedp) +{ + unsigned int added = *addedp; + unsigned int i; + int rc = ENOSPC; + + EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC); + + if (added - completed + n > EFX_TXQ_LIMIT(etp->et_mask + 1)) + goto fail1; + + for (i = 0; i < n; i++) { + efx_buffer_t *ebp = &eb[i]; + efsys_dma_addr_t start = ebp->eb_addr; + size_t size = ebp->eb_size; + efsys_dma_addr_t end = start + size; + + /* Fragments must not span 4k boundaries. */ + EFSYS_ASSERT(P2ROUNDUP(start + 1, 4096) >= end); + + EFX_TX_DESC(etp, start, size, ebp->eb_eop, added); + } + + EFX_TX_QSTAT_INCR(etp, TX_POST); + + *addedp = added; + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + void +efx_tx_qpush( + __in efx_txq_t *etp, + __in unsigned int added) +{ + efx_nic_t *enp = etp->et_enp; + uint32_t wptr; + efx_dword_t dword; + efx_oword_t oword; + + EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC); + + /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */ + EFSYS_PIO_WRITE_BARRIER(); + + /* Push the populated descriptors out */ + wptr = added & etp->et_mask; + + EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DESC_WPTR, wptr); + + /* Only write the third DWORD */ + EFX_POPULATE_DWORD_1(dword, + EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3)); + EFX_BAR_TBL_WRITED3(enp, FR_BZ_TX_DESC_UPD_REGP0, + etp->et_index, &dword, B_FALSE); +} + + void +efx_tx_qflush( + __in efx_txq_t *etp) +{ + efx_nic_t *enp = etp->et_enp; + efx_oword_t oword; + uint32_t label; + + EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC); + + label = etp->et_index; + + /* Flush the queue */ + EFX_POPULATE_OWORD_2(oword, FRF_AZ_TX_FLUSH_DESCQ_CMD, 1, + FRF_AZ_TX_FLUSH_DESCQ, label); + EFX_BAR_WRITEO(enp, FR_AZ_TX_FLUSH_DESCQ_REG, &oword); +} + + void +efx_tx_qenable( + __in efx_txq_t *etp) +{ + efx_nic_t *enp = etp->et_enp; + efx_oword_t oword; + + EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC); + + EFX_BAR_TBL_READO(enp, FR_AZ_TX_DESC_PTR_TBL, + etp->et_index, &oword); + + EFSYS_PROBE5(tx_descq_ptr, unsigned int, etp->et_index, + uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_3), + uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_2), + uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_1), + uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_0)); + + EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DC_HW_RPTR, 0); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DESCQ_HW_RPTR, 0); + EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DESCQ_EN, 1); + + EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL, + etp->et_index, &oword); +} + + __checkReturn int +efx_tx_qcreate( + __in efx_nic_t *enp, + __in unsigned int index, + __in unsigned int label, + __in efsys_mem_t *esmp, + __in size_t n, + __in uint32_t id, + __in uint16_t flags, + __in efx_evq_t *eep, + __deref_out efx_txq_t **etpp) +{ + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + efx_txq_t *etp; + efx_oword_t oword; + uint32_t size; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX); + + EFX_STATIC_ASSERT(EFX_EV_TX_NLABELS == (1 << FRF_AZ_TX_DESCQ_LABEL_WIDTH)); + EFSYS_ASSERT3U(label, <, EFX_EV_TX_NLABELS); + EFSYS_ASSERT3U(enp->en_tx_qcount + 1, <, encp->enc_txq_limit); + + if (!ISP2(n) || !(n & EFX_TXQ_NDESCS_MASK)) { + rc = EINVAL; + goto fail1; + } + if (index >= encp->enc_txq_limit) { + rc = EINVAL; + goto fail2; + } + for (size = 0; (1 << size) <= (EFX_TXQ_MAXNDESCS / EFX_TXQ_MINNDESCS); + size++) + if ((1 << size) == (int)(n / EFX_TXQ_MINNDESCS)) + break; + if (id + (1 << size) >= encp->enc_buftbl_limit) { + rc = EINVAL; + goto fail3; + } + + /* Allocate an TXQ object */ + EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_txq_t), etp); + + if (etp == NULL) { + rc = ENOMEM; + goto fail4; + } + + etp->et_magic = EFX_TXQ_MAGIC; + etp->et_enp = enp; + etp->et_index = index; + etp->et_mask = n - 1; + etp->et_esmp = esmp; + + /* Set up the new descriptor queue */ + EFX_POPULATE_OWORD_6(oword, + FRF_AZ_TX_DESCQ_BUF_BASE_ID, id, + FRF_AZ_TX_DESCQ_EVQ_ID, eep->ee_index, + FRF_AZ_TX_DESCQ_OWNER_ID, 0, + FRF_AZ_TX_DESCQ_LABEL, label, + FRF_AZ_TX_DESCQ_SIZE, size, + FRF_AZ_TX_DESCQ_TYPE, 0); + + EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_NON_IP_DROP_DIS, 1); + EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_IP_CHKSM_DIS, + (flags & EFX_CKSUM_IPV4) ? 0 : 1); + EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_TCP_CHKSM_DIS, + (flags & EFX_CKSUM_TCPUDP) ? 0 : 1); + + EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL, + etp->et_index, &oword); + + enp->en_tx_qcount++; + *etpp = etp; + return (0); + +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#if EFSYS_OPT_NAMES +/* START MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock 78ca9ab00287fffb */ +static const char __cs * __cs __efx_tx_qstat_name[] = { + "post", + "unaligned_split", +}; +/* END MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock */ + + const char __cs * +efx_tx_qstat_name( + __in efx_nic_t *enp, + __in unsigned int id) +{ + _NOTE(ARGUNUSED(enp)) + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(id, <, TX_NQSTATS); + + return (__efx_tx_qstat_name[id]); +} +#endif /* EFSYS_OPT_NAMES */ + +#if EFSYS_OPT_QSTATS + void +efx_tx_qstats_update( + __in efx_txq_t *etp, + __inout_ecount(TX_NQSTATS) efsys_stat_t *stat) +{ + unsigned int id; + + EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC); + + for (id = 0; id < TX_NQSTATS; id++) { + efsys_stat_t *essp = &stat[id]; + + EFSYS_STAT_INCR(essp, etp->et_stat[id]); + etp->et_stat[id] = 0; + } +} +#endif /* EFSYS_OPT_QSTATS */ + + void +efx_tx_qdestroy( + __in efx_txq_t *etp) +{ + efx_nic_t *enp = etp->et_enp; + efx_oword_t oword; + + EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC); + + EFSYS_ASSERT(enp->en_tx_qcount != 0); + --enp->en_tx_qcount; + + /* Purge descriptor queue */ + EFX_ZERO_OWORD(oword); + + EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL, + etp->et_index, &oword); + + /* Free the TXQ object */ + EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp); +} + + void +efx_tx_fini( + __in efx_nic_t *enp) +{ + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX); + EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0); + + enp->en_mod_flags &= ~EFX_MOD_TX; +} diff --git a/sys/dev/sfxge/common/efx_types.h b/sys/dev/sfxge/common/efx_types.h new file mode 100644 index 000000000000..d691482039b5 --- /dev/null +++ b/sys/dev/sfxge/common/efx_types.h @@ -0,0 +1,1605 @@ +/*- + * Copyright 2007-2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Ackowledgement to Fen Systems Ltd. + */ + +#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 + +#define EFX_QWORD_0_LBN 0 +#define EFX_QWORD_0_WIDTH 64 + +#define EFX_QWORD_1_LBN 64 +#define EFX_QWORD_1_WIDTH 64 + +/* 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_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_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) + +#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_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) + +#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]) == ~((uint32_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_OWORD64(_oword) \ + EFX_POPULATE_OWORD_2(_oword, \ + EFX_QWORD_0, (uint64_t)-1, EFX_QWORD_1, (uint64_t)-1) + +#define EFX_SET_OWORD32(_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_QWORD64(_qword) \ + EFX_POPULATE_QWORD_1(_qword, \ + EFX_QWORD_0, (uint64_t)-1) + +#define EFX_SET_QWORD32(_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_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_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_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_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_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 EFX_SET_OWORD64 +#define EFX_SET_QWORD EFX_SET_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_SET_QWORD_BIT EFX_SET_QWORD_BIT64 +#define EFX_CLEAR_QWORD_BIT EFX_CLEAR_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_OR_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 EFX_SET_OWORD32 +#define EFX_SET_QWORD EFX_SET_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_SET_QWORD_BIT EFX_SET_QWORD_BIT32 +#define EFX_CLEAR_QWORD_BIT EFX_CLEAR_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_OR_QWORD32 +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_EFX_TYPES_H */ diff --git a/sys/dev/sfxge/common/efx_vpd.c b/sys/dev/sfxge/common/efx_vpd.c new file mode 100644 index 000000000000..699e890555bf --- /dev/null +++ b/sys/dev/sfxge/common/efx_vpd.c @@ -0,0 +1,999 @@ +/*- + * Copyright 2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "efsys.h" +#include "efx.h" +#include "efx_types.h" +#include "efx_regs.h" +#include "efx_impl.h" + +#if EFSYS_OPT_VPD + +#define TAG_TYPE_LBN 7 +#define TAG_TYPE_WIDTH 1 +#define TAG_TYPE_LARGE_ITEM_DECODE 1 +#define TAG_TYPE_SMALL_ITEM_DECODE 0 + +#define TAG_SMALL_ITEM_NAME_LBN 3 +#define TAG_SMALL_ITEM_NAME_WIDTH 4 +#define TAG_SMALL_ITEM_SIZE_LBN 0 +#define TAG_SMALL_ITEM_SIZE_WIDTH 3 + +#define TAG_LARGE_ITEM_NAME_LBN 0 +#define TAG_LARGE_ITEM_NAME_WIDTH 7 + +#define TAG_NAME_END_DECODE 0x0f +#define TAG_NAME_ID_STRING_DECODE 0x02 +#define TAG_NAME_VPD_R_DECODE 0x10 +#define TAG_NAME_VPD_W_DECODE 0x11 + +#if EFSYS_OPT_FALCON + +static efx_vpd_ops_t __cs __efx_vpd_falcon_ops = { + NULL, /* evpdo_init */ + falcon_vpd_size, /* evpdo_size */ + falcon_vpd_read, /* evpdo_read */ + falcon_vpd_verify, /* evpdo_verify */ + NULL, /* evpdo_reinit */ + falcon_vpd_get, /* evpdo_get */ + falcon_vpd_set, /* evpdo_set */ + falcon_vpd_next, /* evpdo_next */ + falcon_vpd_write, /* evpdo_write */ + NULL, /* evpdo_fini */ +}; + +#endif /* EFSYS_OPT_FALCON */ + +#if EFSYS_OPT_SIENA + +static efx_vpd_ops_t __cs __efx_vpd_siena_ops = { + siena_vpd_init, /* evpdo_init */ + siena_vpd_size, /* evpdo_size */ + siena_vpd_read, /* evpdo_read */ + siena_vpd_verify, /* evpdo_verify */ + siena_vpd_reinit, /* evpdo_reinit */ + siena_vpd_get, /* evpdo_get */ + siena_vpd_set, /* evpdo_set */ + siena_vpd_next, /* evpdo_next */ + siena_vpd_write, /* evpdo_write */ + siena_vpd_fini, /* evpdo_fini */ +}; + +#endif /* EFSYS_OPT_SIENA */ + + __checkReturn int +efx_vpd_init( + __in efx_nic_t *enp) +{ + efx_vpd_ops_t *evpdop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_VPD)); + + switch (enp->en_family) { +#if EFSYS_OPT_FALCON + case EFX_FAMILY_FALCON: + evpdop = (efx_vpd_ops_t *)&__efx_vpd_falcon_ops; + break; +#endif /* EFSYS_OPT_FALCON */ + +#if EFSYS_OPT_SIENA + case EFX_FAMILY_SIENA: + evpdop = (efx_vpd_ops_t *)&__efx_vpd_siena_ops; + break; +#endif /* EFSYS_OPT_SIENA */ + + default: + EFSYS_ASSERT(0); + rc = ENOTSUP; + goto fail1; + } + + if (evpdop->evpdo_init != NULL) { + if ((rc = evpdop->evpdo_init(enp)) != 0) + goto fail2; + } + + enp->en_evpdop = evpdop; + enp->en_mod_flags |= EFX_MOD_VPD; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_vpd_size( + __in efx_nic_t *enp, + __out size_t *sizep) +{ + efx_vpd_ops_t *evpdop = enp->en_evpdop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VPD); + + if ((rc = evpdop->evpdo_size(enp, sizep)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_vpd_read( + __in efx_nic_t *enp, + __out_bcount(size) caddr_t data, + __in size_t size) +{ + efx_vpd_ops_t *evpdop = enp->en_evpdop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VPD); + + if ((rc = evpdop->evpdo_read(enp, data, size)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_vpd_verify( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size) +{ + efx_vpd_ops_t *evpdop = enp->en_evpdop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VPD); + + if ((rc = evpdop->evpdo_verify(enp, data, size)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_vpd_reinit( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size) +{ + efx_vpd_ops_t *evpdop = enp->en_evpdop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VPD); + + if (evpdop->evpdo_reinit == NULL) { + rc = ENOTSUP; + goto fail1; + } + + if ((rc = evpdop->evpdo_reinit(enp, data, size)) != 0) + goto fail2; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_vpd_get( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size, + __inout efx_vpd_value_t *evvp) +{ + efx_vpd_ops_t *evpdop = enp->en_evpdop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VPD); + + if ((rc = evpdop->evpdo_get(enp, data, size, evvp)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_vpd_set( + __in efx_nic_t *enp, + __inout_bcount(size) caddr_t data, + __in size_t size, + __in efx_vpd_value_t *evvp) +{ + efx_vpd_ops_t *evpdop = enp->en_evpdop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VPD); + + if ((rc = evpdop->evpdo_set(enp, data, size, evvp)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_vpd_next( + __in efx_nic_t *enp, + __inout_bcount(size) caddr_t data, + __in size_t size, + __out efx_vpd_value_t *evvp, + __inout unsigned int *contp) +{ + efx_vpd_ops_t *evpdop = enp->en_evpdop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VPD); + + if ((rc = evpdop->evpdo_next(enp, data, size, evvp, contp)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_vpd_write( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size) +{ + efx_vpd_ops_t *evpdop = enp->en_evpdop; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VPD); + + if ((rc = evpdop->evpdo_write(enp, data, size)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +static __checkReturn int +efx_vpd_next_tag( + __in caddr_t data, + __in size_t size, + __inout unsigned int *offsetp, + __out efx_vpd_tag_t *tagp, + __out uint16_t *lengthp) +{ + efx_byte_t byte; + efx_word_t word; + uint8_t name; + uint16_t length; + size_t headlen; + int rc; + + if (*offsetp >= size) { + rc = EFAULT; + goto fail1; + } + + EFX_POPULATE_BYTE_1(byte, EFX_BYTE_0, data[*offsetp]); + + switch (EFX_BYTE_FIELD(byte, TAG_TYPE)) { + case TAG_TYPE_SMALL_ITEM_DECODE: + headlen = 1; + + name = EFX_BYTE_FIELD(byte, TAG_SMALL_ITEM_NAME); + length = (uint16_t)EFX_BYTE_FIELD(byte, TAG_SMALL_ITEM_SIZE); + + break; + + case TAG_TYPE_LARGE_ITEM_DECODE: + headlen = 3; + + if (*offsetp + headlen > size) { + rc = EFAULT; + goto fail2; + } + + name = EFX_BYTE_FIELD(byte, TAG_LARGE_ITEM_NAME); + EFX_POPULATE_WORD_2(word, + EFX_BYTE_0, data[*offsetp + 1], + EFX_BYTE_1, data[*offsetp + 2]); + length = EFX_WORD_FIELD(word, EFX_WORD_0); + + break; + + default: + rc = EFAULT; + goto fail2; + } + + if (*offsetp + headlen + length > size) { + rc = EFAULT; + goto fail3; + } + + EFX_STATIC_ASSERT(TAG_NAME_END_DECODE == EFX_VPD_END); + EFX_STATIC_ASSERT(TAG_NAME_ID_STRING_DECODE == EFX_VPD_ID); + EFX_STATIC_ASSERT(TAG_NAME_VPD_R_DECODE == EFX_VPD_RO); + EFX_STATIC_ASSERT(TAG_NAME_VPD_W_DECODE == EFX_VPD_RW); + if (name != EFX_VPD_END && name != EFX_VPD_ID && + name != EFX_VPD_RO) { + rc = EFAULT; + goto fail4; + } + + *tagp = name; + *lengthp = length; + *offsetp += headlen; + + return (0); + +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +static __checkReturn int +efx_vpd_next_keyword( + __in_bcount(size) caddr_t tag, + __in size_t size, + __in unsigned int pos, + __out efx_vpd_keyword_t *keywordp, + __out uint8_t *lengthp) +{ + efx_vpd_keyword_t keyword; + uint8_t length; + int rc; + + if (pos + 3U > size) { + rc = EFAULT; + goto fail1; + } + + keyword = EFX_VPD_KEYWORD(tag[pos], tag[pos + 1]); + length = tag[pos + 2]; + + if (length == 0 || pos + 3U + length > size) { + rc = EFAULT; + goto fail2; + } + + *keywordp = keyword; + *lengthp = length; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_vpd_hunk_length( + __in_bcount(size) caddr_t data, + __in size_t size, + __out size_t *lengthp) +{ + efx_vpd_tag_t tag; + unsigned int offset; + uint16_t taglen; + int rc; + + offset = 0; + _NOTE(CONSTANTCONDITION) + while (1) { + if ((rc = efx_vpd_next_tag(data, size, &offset, + &tag, &taglen)) != 0) + goto fail1; + offset += taglen; + if (tag == EFX_VPD_END) + break; + } + + *lengthp = offset; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_vpd_hunk_verify( + __in_bcount(size) caddr_t data, + __in size_t size, + __out_opt boolean_t *cksummedp) +{ + efx_vpd_tag_t tag; + efx_vpd_keyword_t keyword; + unsigned int offset; + unsigned int pos; + unsigned int i; + uint16_t taglen; + uint8_t keylen; + uint8_t cksum; + boolean_t cksummed = B_FALSE; + int rc; + + /* + * Parse every tag,keyword in the existing VPD. If the csum is present, + * the assert it is correct, and is the final keyword in the RO block. + */ + offset = 0; + _NOTE(CONSTANTCONDITION) + while (1) { + if ((rc = efx_vpd_next_tag(data, size, &offset, + &tag, &taglen)) != 0) + goto fail1; + if (tag == EFX_VPD_END) + break; + else if (tag == EFX_VPD_ID) + goto done; + + for (pos = 0; pos != taglen; pos += 3 + keylen) { + /* RV keyword must be the last in the block */ + if (cksummed) + goto fail2; + + if ((rc = efx_vpd_next_keyword(data + offset, + taglen, pos, &keyword, &keylen)) != 0) + goto fail3; + + if (keyword == EFX_VPD_KEYWORD('R', 'V')) { + cksum = 0; + for (i = 0; i < offset + pos + 4; i++) + cksum += data[i]; + + if (cksum != 0) { + rc = EFAULT; + goto fail4; + } + + cksummed = B_TRUE; + } + } + + done: + offset += taglen; + } + + if (!cksummed) { + rc = EFAULT; + goto fail5; + } + + if (cksummedp != NULL) + *cksummedp = cksummed; + + return (0); + +fail5: + EFSYS_PROBE(fail5); +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +static uint8_t __cs __efx_vpd_blank_pid[] = { + /* Large resource type ID length 1 */ + 0x82, 0x01, 0x00, + /* Product name ' ' */ + 0x32, +}; + +static uint8_t __cs __efx_vpd_blank_r[] = { + /* Large resource type VPD-R length 4 */ + 0x90, 0x04, 0x00, + /* RV keyword length 1 */ + 'R', 'V', 0x01, + /* RV payload checksum */ + 0x00, +}; + + __checkReturn int +efx_vpd_hunk_reinit( + __in caddr_t data, + __in size_t size, + __in boolean_t wantpid) +{ + unsigned int offset = 0; + unsigned int pos; + efx_byte_t byte; + uint8_t cksum; + int rc; + + if (size < 0x100) { + rc = ENOSPC; + goto fail1; + } + + if (wantpid) { + memcpy(data + offset, __efx_vpd_blank_pid, + sizeof (__efx_vpd_blank_pid)); + offset += sizeof (__efx_vpd_blank_pid); + } + + memcpy(data + offset, __efx_vpd_blank_r, sizeof (__efx_vpd_blank_r)); + offset += sizeof (__efx_vpd_blank_r); + + /* Update checksum */ + cksum = 0; + for (pos = 0; pos < offset; pos++) + cksum += data[pos]; + data[offset - 1] -= cksum; + + /* Append trailing tag */ + EFX_POPULATE_BYTE_3(byte, + TAG_TYPE, TAG_TYPE_SMALL_ITEM_DECODE, + TAG_SMALL_ITEM_NAME, TAG_NAME_END_DECODE, + TAG_SMALL_ITEM_SIZE, 0); + data[offset] = EFX_BYTE_FIELD(byte, EFX_BYTE_0); + offset++; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_vpd_hunk_next( + __in_bcount(size) caddr_t data, + __in size_t size, + __out efx_vpd_tag_t *tagp, + __out efx_vpd_keyword_t *keywordp, + __out_bcount_opt(*paylenp) unsigned int *payloadp, + __out_opt uint8_t *paylenp, + __inout unsigned int *contp) +{ + efx_vpd_tag_t tag; + efx_vpd_keyword_t keyword = 0; + unsigned int offset; + unsigned int pos; + unsigned int index; + uint16_t taglen; + uint8_t keylen; + uint8_t paylen; + int rc; + + offset = index = 0; + _NOTE(CONSTANTCONDITION) + while (1) { + if ((rc = efx_vpd_next_tag(data, size, &offset, + &tag, &taglen)) != 0) + goto fail1; + if (tag == EFX_VPD_END) + break; + + if (tag == EFX_VPD_ID) { + if (index == *contp) { + EFSYS_ASSERT3U(taglen, <, 0x100); + paylen = (uint8_t)MIN(taglen, 0xff); + + goto done; + } + } else { + for (pos = 0; pos != taglen; pos += 3 + keylen) { + if ((rc = efx_vpd_next_keyword(data + offset, + taglen, pos, &keyword, &keylen)) != 0) + goto fail2; + + if (index == *contp) { + offset += pos + 3; + paylen = keylen; + + goto done; + } + } + } + + offset += taglen; + } + + *contp = 0; + return (0); + +done: + *tagp = tag; + *keywordp = keyword; + if (payloadp != NULL) + *payloadp = offset; + if (paylenp != NULL) + *paylenp = paylen; + + ++(*contp); + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_vpd_hunk_get( + __in_bcount(size) caddr_t data, + __in size_t size, + __in efx_vpd_tag_t tag, + __in efx_vpd_keyword_t keyword, + __out unsigned int *payloadp, + __out uint8_t *paylenp) +{ + efx_vpd_tag_t itag; + efx_vpd_keyword_t ikeyword; + unsigned int offset; + unsigned int pos; + uint16_t taglen; + uint8_t keylen; + int rc; + + offset = 0; + _NOTE(CONSTANTCONDITION) + while (1) { + if ((rc = efx_vpd_next_tag(data, size, &offset, + &itag, &taglen)) != 0) + goto fail1; + if (itag == EFX_VPD_END) + break; + + if (itag == tag) { + if (itag == EFX_VPD_ID) { + EFSYS_ASSERT3U(taglen, <, 0x100); + + *paylenp = (uint8_t)MIN(taglen, 0xff); + *payloadp = offset; + return (0); + } + + for (pos = 0; pos != taglen; pos += 3 + keylen) { + if ((rc = efx_vpd_next_keyword(data + offset, + taglen, pos, &ikeyword, &keylen)) != 0) + goto fail2; + + if (ikeyword == keyword) { + *paylenp = keylen; + *payloadp = offset + pos + 3; + return (0); + } + } + } + + offset += taglen; + } + + /* Not an error */ + return (ENOENT); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_vpd_hunk_set( + __in_bcount(size) caddr_t data, + __in size_t size, + __in efx_vpd_value_t *evvp) +{ + efx_word_t word; + efx_vpd_tag_t tag; + efx_vpd_keyword_t keyword; + unsigned int offset; + unsigned int pos; + unsigned int taghead; + unsigned int source; + unsigned int dest; + unsigned int i; + uint16_t taglen; + uint8_t keylen; + uint8_t cksum; + size_t used; + int rc; + + switch (evvp->evv_tag) { + case EFX_VPD_ID: + if (evvp->evv_keyword != 0) { + rc = EINVAL; + goto fail1; + } + + /* Can't delete the ID keyword */ + if (evvp->evv_length == 0) { + rc = EINVAL; + goto fail1; + } + break; + + case EFX_VPD_RO: + if (evvp->evv_keyword == EFX_VPD_KEYWORD('R', 'V')) { + rc = EINVAL; + goto fail1; + } + break; + + default: + rc = EINVAL; + goto fail1; + } + + /* Determine total size of all current tags */ + if ((rc = efx_vpd_hunk_length(data, size, &used)) != 0) + goto fail2; + + offset = 0; + _NOTE(CONSTANTCONDITION) + while (1) { + taghead = offset; + if ((rc = efx_vpd_next_tag(data, size, &offset, + &tag, &taglen)) != 0) + goto fail3; + if (tag == EFX_VPD_END) + break; + else if (tag != evvp->evv_tag) { + offset += taglen; + continue; + } + + /* We only support modifying large resource tags */ + if (offset - taghead != 3) { + rc = EINVAL; + goto fail4; + } + + /* + * Work out the offset of the byte immediately after the + * old (=source) and new (=dest) new keyword/tag + */ + pos = 0; + if (tag == EFX_VPD_ID) { + source = offset + taglen; + dest = offset + evvp->evv_length; + goto check_space; + } + + EFSYS_ASSERT3U(tag, ==, EFX_VPD_RO); + source = dest = 0; + for (pos = 0; pos != taglen; pos += 3 + keylen) { + if ((rc = efx_vpd_next_keyword(data + offset, + taglen, pos, &keyword, &keylen)) != 0) + goto fail5; + + if (keyword == evvp->evv_keyword && + evvp->evv_length == 0) { + /* Deleting this keyword */ + source = offset + pos + 3 + keylen; + dest = offset + pos; + break; + + } else if (keyword == evvp->evv_keyword) { + /* Adjusting this keyword */ + source = offset + pos + 3 + keylen; + dest = offset + pos + 3 + evvp->evv_length; + break; + + } else if (keyword == EFX_VPD_KEYWORD('R', 'V')) { + /* The RV keyword must be at the end */ + EFSYS_ASSERT3U(pos + 3 + keylen, ==, taglen); + + /* + * The keyword doesn't already exist. If the + * user deleting a non-existant keyword then + * this is a no-op. + */ + if (evvp->evv_length == 0) + return (0); + + /* Insert this keyword before the RV keyword */ + source = offset + pos; + dest = offset + pos + 3 + evvp->evv_length; + break; + } + } + + check_space: + if (used + dest > size + source) { + rc = ENOSPC; + goto fail6; + } + + /* Move trailing data */ + (void) memmove(data + dest, data + source, used - source); + + /* Copy contents */ + memcpy(data + dest - evvp->evv_length, evvp->evv_value, + evvp->evv_length); + + /* Insert new keyword header if required */ + if (tag != EFX_VPD_ID && evvp->evv_length > 0) { + EFX_POPULATE_WORD_1(word, EFX_WORD_0, + evvp->evv_keyword); + data[offset + pos + 0] = + EFX_WORD_FIELD(word, EFX_BYTE_0); + data[offset + pos + 1] = + EFX_WORD_FIELD(word, EFX_BYTE_1); + data[offset + pos + 2] = evvp->evv_length; + } + + /* Modify tag length (large resource type) */ + taglen += (dest - source); + EFX_POPULATE_WORD_1(word, EFX_WORD_0, taglen); + data[offset - 2] = EFX_WORD_FIELD(word, EFX_BYTE_0); + data[offset - 1] = EFX_WORD_FIELD(word, EFX_BYTE_1); + + goto checksum; + } + + /* Unable to find the matching tag */ + rc = ENOENT; + goto fail7; + +checksum: + /* Find the RV tag, and update the checksum */ + offset = 0; + _NOTE(CONSTANTCONDITION) + while (1) { + if ((rc = efx_vpd_next_tag(data, size, &offset, + &tag, &taglen)) != 0) + goto fail8; + if (tag == EFX_VPD_END) + break; + if (tag == EFX_VPD_RO) { + for (pos = 0; pos != taglen; pos += 3 + keylen) { + if ((rc = efx_vpd_next_keyword(data + offset, + taglen, pos, &keyword, &keylen)) != 0) + goto fail9; + + if (keyword == EFX_VPD_KEYWORD('R', 'V')) { + cksum = 0; + for (i = 0; i < offset + pos + 3; i++) + cksum += data[i]; + data[i] = -cksum; + break; + } + } + } + + offset += taglen; + } + + /* Zero out the unused portion */ + (void) memset(data + offset + taglen, 0xff, size - offset - taglen); + + return (0); + +fail9: + EFSYS_PROBE(fail9); +fail8: + EFSYS_PROBE(fail8); +fail7: + EFSYS_PROBE(fail7); +fail6: + EFSYS_PROBE(fail6); +fail5: + EFSYS_PROBE(fail5); +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + void +efx_vpd_fini( + __in efx_nic_t *enp) +{ + efx_vpd_ops_t *evpdop = enp->en_evpdop; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VPD); + + if (evpdop->evpdo_fini != NULL) + evpdop->evpdo_fini(enp); + + enp->en_evpdop = NULL; + enp->en_mod_flags &= ~EFX_MOD_VPD; +} + +#endif /* EFSYS_OPT_VPD */ diff --git a/sys/dev/sfxge/common/efx_wol.c b/sys/dev/sfxge/common/efx_wol.c new file mode 100644 index 000000000000..74f11de20a86 --- /dev/null +++ b/sys/dev/sfxge/common/efx_wol.c @@ -0,0 +1,396 @@ +/*- + * Copyright 2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "efsys.h" +#include "efx.h" +#include "efx_types.h" +#include "efx_impl.h" + +#if EFSYS_OPT_WOL + + __checkReturn int +efx_wol_init( + __in efx_nic_t *enp) +{ + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_WOL)); + + if (~(encp->enc_features) & EFX_FEATURE_WOL) { + rc = ENOTSUP; + goto fail1; + } + + /* Current implementation is Siena specific */ + EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); + + enp->en_mod_flags |= EFX_MOD_WOL; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_wol_filter_clear( + __in efx_nic_t *enp) +{ + efx_mcdi_req_t req; + uint8_t payload[MC_CMD_WOL_FILTER_RESET_IN_LEN]; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL); + + req.emr_cmd = MC_CMD_WOL_FILTER_RESET; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_WOL_FILTER_RESET_IN_LEN; + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + MCDI_IN_SET_DWORD(req, WOL_FILTER_RESET_IN_MASK, + MC_CMD_WOL_FILTER_RESET_IN_WAKE_FILTERS | + MC_CMD_WOL_FILTER_RESET_IN_LIGHTSOUT_OFFLOADS); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_wol_filter_add( + __in efx_nic_t *enp, + __in efx_wol_type_t type, + __in efx_wol_param_t *paramp, + __out uint32_t *filter_idp) +{ + efx_mcdi_req_t req; + uint8_t payload[MAX(MC_CMD_WOL_FILTER_SET_IN_LEN, + MC_CMD_WOL_FILTER_SET_OUT_LEN)]; + efx_byte_t link_mask; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL); + + req.emr_cmd = MC_CMD_WOL_FILTER_SET; + (void) memset(payload, '\0', sizeof (payload)); + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_WOL_FILTER_SET_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_WOL_FILTER_SET_OUT_LEN; + + switch (type) { + case EFX_WOL_TYPE_MAGIC: + MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_FILTER_MODE, + MC_CMD_FILTER_MODE_SIMPLE); + MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_WOL_TYPE, + MC_CMD_WOL_TYPE_MAGIC); + EFX_MAC_ADDR_COPY( + MCDI_IN2(req, uint8_t, WOL_FILTER_SET_IN_MAGIC_MAC), + paramp->ewp_magic.mac_addr); + break; + + case EFX_WOL_TYPE_BITMAP: { + uint32_t swapped = 0; + efx_dword_t *dwordp; + unsigned int pos, bit; + + MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_FILTER_MODE, + MC_CMD_FILTER_MODE_SIMPLE); + MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_WOL_TYPE, + MC_CMD_WOL_TYPE_BITMAP); + + /* + * MC bitmask is supposed to be bit swapped + * amongst 32 bit words(!) + */ + + dwordp = MCDI_IN2(req, efx_dword_t, + WOL_FILTER_SET_IN_BITMAP_MASK); + + EFSYS_ASSERT3U(EFX_WOL_BITMAP_MASK_SIZE % 4, ==, 0); + + for (pos = 0; pos < EFX_WOL_BITMAP_MASK_SIZE; ++pos) { + uint8_t native = paramp->ewp_bitmap.mask[pos]; + + for (bit = 0; bit < 8; ++bit) { + swapped <<= 1; + swapped |= (native & 0x1); + native >>= 1; + } + + if ((pos & 3) == 3) { + EFX_POPULATE_DWORD_1(dwordp[pos >> 2], + EFX_DWORD_0, swapped); + swapped = 0; + } + } + + memcpy(MCDI_IN2(req, uint8_t, WOL_FILTER_SET_IN_BITMAP_BITMAP), + paramp->ewp_bitmap.value, + sizeof (paramp->ewp_bitmap.value)); + + EFSYS_ASSERT3U(paramp->ewp_bitmap.value_len, <=, + sizeof (paramp->ewp_bitmap.value)); + MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_BITMAP_LEN, + paramp->ewp_bitmap.value_len); + } + break; + + case EFX_WOL_TYPE_LINK: + MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_FILTER_MODE, + MC_CMD_FILTER_MODE_SIMPLE); + MCDI_IN_SET_DWORD(req, WOL_FILTER_SET_IN_WOL_TYPE, + MC_CMD_WOL_TYPE_LINK); + + EFX_ZERO_BYTE(link_mask); + EFX_SET_BYTE_FIELD(link_mask, MC_CMD_WOL_FILTER_SET_IN_LINK_UP, + 1); + MCDI_IN_SET_BYTE(req, WOL_FILTER_SET_IN_LINK_MASK, + link_mask.eb_u8[0]); + break; + + default: + EFSYS_ASSERT3U(type, !=, type); + } + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + if (req.emr_out_length_used < MC_CMD_WOL_FILTER_SET_OUT_LEN) { + rc = EMSGSIZE; + goto fail2; + } + + *filter_idp = MCDI_OUT_DWORD(req, WOL_FILTER_SET_OUT_FILTER_ID); + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +efx_wol_filter_remove( + __in efx_nic_t *enp, + __in uint32_t filter_id) +{ + efx_mcdi_req_t req; + uint8_t payload[MC_CMD_WOL_FILTER_REMOVE_IN_LEN]; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL); + + req.emr_cmd = MC_CMD_WOL_FILTER_REMOVE; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_WOL_FILTER_REMOVE_IN_LEN; + EFX_STATIC_ASSERT(MC_CMD_WOL_FILTER_REMOVE_OUT_LEN == 0); + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + MCDI_IN_SET_DWORD(req, WOL_FILTER_REMOVE_IN_FILTER_ID, filter_id); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + + __checkReturn int +efx_lightsout_offload_add( + __in efx_nic_t *enp, + __in efx_lightsout_offload_type_t type, + __in efx_lightsout_offload_param_t *paramp, + __out uint32_t *filter_idp) +{ + efx_mcdi_req_t req; + 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_OUT_LEN)]; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL); + + req.emr_cmd = MC_CMD_ADD_LIGHTSOUT_OFFLOAD; + req.emr_in_buf = payload; + req.emr_in_length = sizeof (type); + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN; + + switch (type) { + case EFX_LIGHTSOUT_OFFLOAD_TYPE_ARP: + req.emr_in_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_LEN; + MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL, + MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP); + EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, + ADD_LIGHTSOUT_OFFLOAD_IN_ARP_MAC), + paramp->elop_arp.mac_addr); + MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_ARP_IP, + paramp->elop_arp.ip); + break; + case EFX_LIGHTSOUT_OFFLOAD_TYPE_NS: + req.emr_in_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_LEN; + MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL, + MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS); + EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, + ADD_LIGHTSOUT_OFFLOAD_IN_NS_MAC), + paramp->elop_ns.mac_addr); + memcpy(MCDI_IN2(req, uint8_t, + ADD_LIGHTSOUT_OFFLOAD_IN_NS_SNIPV6), + paramp->elop_ns.solicited_node, + sizeof (paramp->elop_ns.solicited_node)); + memcpy(MCDI_IN2(req, uint8_t, ADD_LIGHTSOUT_OFFLOAD_IN_NS_IPV6), + paramp->elop_ns.ip, sizeof (paramp->elop_ns.ip)); + break; + default: + EFSYS_ASSERT3U(type, !=, type); + } + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + if (req.emr_out_length_used < MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN) { + rc = EMSGSIZE; + goto fail2; + } + + *filter_idp = MCDI_OUT_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_OUT_FILTER_ID); + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + + __checkReturn int +efx_lightsout_offload_remove( + __in efx_nic_t *enp, + __in efx_lightsout_offload_type_t type, + __in uint32_t filter_id) +{ + efx_mcdi_req_t req; + uint8_t payload[MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN]; + int rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL); + + req.emr_cmd = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD; + req.emr_in_buf = payload; + req.emr_in_length = sizeof (payload); + EFX_STATIC_ASSERT(MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN == 0); + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + switch (type) { + case EFX_LIGHTSOUT_OFFLOAD_TYPE_ARP: + MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL, + MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP); + break; + case EFX_LIGHTSOUT_OFFLOAD_TYPE_NS: + MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL, + MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS); + break; + default: + EFSYS_ASSERT3U(type, !=, type); + } + + MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_FILTER_ID, + filter_id); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + + void +efx_wol_fini( + __in efx_nic_t *enp) +{ + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL); + + enp->en_mod_flags &= ~EFX_MOD_WOL; +} + +#endif /* EFSYS_OPT_WOL */ diff --git a/sys/dev/sfxge/common/siena_flash.h b/sys/dev/sfxge/common/siena_flash.h new file mode 100644 index 000000000000..7df3995dee1b --- /dev/null +++ b/sys/dev/sfxge/common/siena_flash.h @@ -0,0 +1,132 @@ +/*- + * Copyright 2007-2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#ifndef _SYS_SIENA_FLASH_H +#define _SYS_SIENA_FLASH_H + +#pragma pack(1) + +/* Fixed locations near the start of flash (which may be in the internal PHY + * firmware header) point to the boot header. + * + * - parsed by MC boot ROM and firmware + * - reserved (but not parsed) by PHY firmware + * - opaque to driver + */ + +#define SIENA_MC_BOOT_PHY_FW_HDR_LEN (0x20) + +#define SIENA_MC_BOOT_PTR_LOCATION (0x18) /* First thing we try to boot */ +#define SIENA_MC_BOOT_ALT_PTR_LOCATION (0x1c) /* Alternative if that fails */ + +#define SIENA_MC_BOOT_HDR_LEN (0x200) + +#define SIENA_MC_BOOT_MAGIC (0x51E4A001) +#define SIENA_MC_BOOT_VERSION (1) + +typedef struct siena_mc_boot_hdr_s { /* GENERATED BY scripts/genfwdef */ + efx_dword_t magic; /* = SIENA_MC_BOOT_MAGIC */ + efx_word_t hdr_version; /* this structure definition is version 1 */ + efx_byte_t board_type; + efx_byte_t firmware_version_a; + efx_byte_t firmware_version_b; + efx_byte_t firmware_version_c; + efx_word_t checksum; /* of whole header area + firmware image */ + efx_word_t firmware_version_d; + efx_word_t reserved_a[1]; /* (set to 0) */ + efx_dword_t firmware_text_offset; /* offset to firmware .text */ + efx_dword_t firmware_text_size; /* length of firmware .text, in bytes */ + efx_dword_t firmware_data_offset; /* offset to firmware .data */ + efx_dword_t firmware_data_size; /* length of firmware .data, in bytes */ + efx_dword_t reserved_b[8]; /* (set to 0) */ +} siena_mc_boot_hdr_t; + +#define SIENA_MC_STATIC_CONFIG_MAGIC (0xBDCF5555) +#define SIENA_MC_STATIC_CONFIG_VERSION (0) + +typedef struct siena_mc_static_config_hdr_s { /* GENERATED BY scripts/genfwdef */ + efx_dword_t magic; /* = SIENA_MC_STATIC_CONFIG_MAGIC */ + efx_word_t length; /* of header area (i.e. not including VPD) */ + efx_byte_t version; + efx_byte_t csum; /* over header area (i.e. not including VPD) */ + efx_dword_t static_vpd_offset; + efx_dword_t static_vpd_length; + efx_dword_t capabilities; + efx_byte_t mac_addr_base[6]; + efx_byte_t green_mode_cal; /* Green mode calibration result */ + efx_byte_t green_mode_valid; /* Whether cal holds a valid value */ + efx_word_t mac_addr_count; + efx_word_t mac_addr_stride; + efx_dword_t reserved2[2]; /* (write as zero) */ + efx_dword_t num_dbi_items; + struct { + efx_word_t addr; + efx_word_t byte_enables; + efx_dword_t value; + } dbi[]; +} siena_mc_static_config_hdr_t; + +#define SIENA_MC_DYNAMIC_CONFIG_MAGIC (0xBDCFDDDD) +#define SIENA_MC_DYNAMIC_CONFIG_VERSION (0) + +typedef struct siena_mc_fw_version_s { /* GENERATED BY scripts/genfwdef */ + efx_dword_t fw_subtype; + efx_word_t version_w; + efx_word_t version_x; + efx_word_t version_y; + efx_word_t version_z; +} siena_mc_fw_version_t; + +typedef struct siena_mc_dynamic_config_hdr_s { /* GENERATED BY scripts/genfwdef */ + efx_dword_t magic; /* = SIENA_MC_DYNAMIC_CONFIG_MAGIC */ + efx_word_t length; /* of header area (i.e. not including VPD) */ + efx_byte_t version; + efx_byte_t csum; /* over header area (i.e. not including VPD) */ + efx_dword_t dynamic_vpd_offset; + efx_dword_t dynamic_vpd_length; + efx_dword_t num_fw_version_items; + siena_mc_fw_version_t fw_version[]; +} siena_mc_dynamic_config_hdr_t; + +#define SIENA_MC_EXPROM_SINGLE_MAGIC (0xAA55) /* little-endian uint16_t */ + +#define SIENA_MC_EXPROM_COMBO_MAGIC (0xB0070102) /* little-endian uint32_t */ + +typedef struct siena_mc_combo_rom_hdr_s { /* GENERATED BY scripts/genfwdef */ + efx_dword_t magic; /* = SIENA_MC_EXPROM_COMBO_MAGIC */ + efx_dword_t len1; /* length of first image */ + efx_dword_t len2; /* length of second image */ + efx_dword_t off1; /* offset of first byte to edit to combine images */ + efx_dword_t off2; /* offset of second byte to edit to combine images */ + efx_word_t infoblk0_off; /* infoblk offset */ + efx_word_t infoblk1_off; /* infoblk offset */ + efx_byte_t infoblk_len; /* length of space reserved for infoblk structures */ + efx_byte_t reserved[7]; /* (set to 0) */ +} siena_mc_combo_rom_hdr_t; + +#pragma pack() + +#endif /* _SYS_SIENA_FLASH_H */ diff --git a/sys/dev/sfxge/common/siena_impl.h b/sys/dev/sfxge/common/siena_impl.h new file mode 100644 index 000000000000..b566adb341c7 --- /dev/null +++ b/sys/dev/sfxge/common/siena_impl.h @@ -0,0 +1,477 @@ +/*- + * Copyright 2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SYS_SIENA_IMPL_H +#define _SYS_SIENA_IMPL_H + +#include "efx.h" +#include "efx_regs.h" +#include "efx_mcdi.h" +#include "siena_flash.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if EFSYS_OPT_PHY_PROPS + +/* START MKCONFIG GENERATED SienaPhyHeaderPropsBlock a8db1f8eb5106efd */ +typedef enum siena_phy_prop_e { + SIENA_PHY_NPROPS +} siena_phy_prop_t; + +/* END MKCONFIG GENERATED SienaPhyHeaderPropsBlock */ + +#endif /* EFSYS_OPT_PHY_PROPS */ + +#define SIENA_NVRAM_CHUNK 0x80 + +extern __checkReturn int +siena_nic_probe( + __in efx_nic_t *enp); + +#if EFSYS_OPT_PCIE_TUNE + +extern __checkReturn int +siena_nic_pcie_extended_sync( + __in efx_nic_t *enp); + +#endif + +extern __checkReturn int +siena_nic_reset( + __in efx_nic_t *enp); + +extern __checkReturn int +siena_nic_init( + __in efx_nic_t *enp); + +#if EFSYS_OPT_DIAG + +extern __checkReturn int +siena_nic_register_test( + __in efx_nic_t *enp); + +#endif /* EFSYS_OPT_DIAG */ + +extern void +siena_nic_fini( + __in efx_nic_t *enp); + +extern void +siena_nic_unprobe( + __in efx_nic_t *enp); + +#define SIENA_SRAM_ROWS 0x12000 + +extern void +siena_sram_init( + __in efx_nic_t *enp); + +#if EFSYS_OPT_DIAG + +extern __checkReturn int +siena_sram_test( + __in efx_nic_t *enp, + __in efx_sram_pattern_fn_t func); + +#endif /* EFSYS_OPT_DIAG */ + + +#if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD + +extern __checkReturn int +siena_nvram_partn_size( + __in efx_nic_t *enp, + __in unsigned int partn, + __out size_t *sizep); + +extern __checkReturn int +siena_nvram_partn_lock( + __in efx_nic_t *enp, + __in unsigned int partn); + +extern __checkReturn int +siena_nvram_partn_read( + __in efx_nic_t *enp, + __in unsigned int partn, + __in unsigned int offset, + __out_bcount(size) caddr_t data, + __in size_t size); + +extern __checkReturn int +siena_nvram_partn_erase( + __in efx_nic_t *enp, + __in unsigned int partn, + __in unsigned int offset, + __in size_t size); + +extern __checkReturn int +siena_nvram_partn_write( + __in efx_nic_t *enp, + __in unsigned int partn, + __in unsigned int offset, + __out_bcount(size) caddr_t data, + __in size_t size); + +extern void +siena_nvram_partn_unlock( + __in efx_nic_t *enp, + __in unsigned int partn); + +extern __checkReturn int +siena_nvram_get_dynamic_cfg( + __in efx_nic_t *enp, + __in unsigned int index, + __in boolean_t vpd, + __out siena_mc_dynamic_config_hdr_t **dcfgp, + __out size_t *sizep); + +#endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */ + +#if EFSYS_OPT_NVRAM + +#if EFSYS_OPT_DIAG + +extern __checkReturn int +siena_nvram_test( + __in efx_nic_t *enp); + +#endif /* EFSYS_OPT_DIAG */ + +extern __checkReturn int +siena_nvram_size( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __out size_t *sizep); + +extern __checkReturn int +siena_nvram_get_version( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __out uint32_t *subtypep, + __out_ecount(4) uint16_t version[4]); + +extern __checkReturn int +siena_nvram_rw_start( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __out size_t *pref_chunkp); + +extern __checkReturn int +siena_nvram_read_chunk( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __in unsigned int offset, + __out_bcount(size) caddr_t data, + __in size_t size); + +extern __checkReturn int +siena_nvram_erase( + __in efx_nic_t *enp, + __in efx_nvram_type_t type); + +extern __checkReturn int +siena_nvram_write_chunk( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __in unsigned int offset, + __in_bcount(size) caddr_t data, + __in size_t size); + +extern void +siena_nvram_rw_finish( + __in efx_nic_t *enp, + __in efx_nvram_type_t type); + +extern __checkReturn int +siena_nvram_set_version( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __out uint16_t version[4]); + +#endif /* EFSYS_OPT_NVRAM */ + +#if EFSYS_OPT_VPD + +extern __checkReturn int +siena_vpd_init( + __in efx_nic_t *enp); + +extern __checkReturn int +siena_vpd_size( + __in efx_nic_t *enp, + __out size_t *sizep); + +extern __checkReturn int +siena_vpd_read( + __in efx_nic_t *enp, + __out_bcount(size) caddr_t data, + __in size_t size); + +extern __checkReturn int +siena_vpd_verify( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size); + +extern __checkReturn int +siena_vpd_reinit( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size); + +extern __checkReturn int +siena_vpd_get( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size, + __inout efx_vpd_value_t *evvp); + +extern __checkReturn int +siena_vpd_set( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size, + __in efx_vpd_value_t *evvp); + +extern __checkReturn int +siena_vpd_next( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size, + __out efx_vpd_value_t *evvp, + __inout unsigned int *contp); + +extern __checkReturn int +siena_vpd_write( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size); + +extern void +siena_vpd_fini( + __in efx_nic_t *enp); + +#endif /* EFSYS_OPT_VPD */ + +typedef struct siena_link_state_s { + uint32_t sls_adv_cap_mask; + uint32_t sls_lp_cap_mask; + unsigned int sls_fcntl; + efx_link_mode_t sls_link_mode; +#if EFSYS_OPT_LOOPBACK + efx_loopback_type_t sls_loopback; +#endif + boolean_t sls_mac_up; +} siena_link_state_t; + +extern void +siena_phy_link_ev( + __in efx_nic_t *enp, + __in efx_qword_t *eqp, + __out efx_link_mode_t *link_modep); + +extern __checkReturn int +siena_phy_get_link( + __in efx_nic_t *enp, + __out siena_link_state_t *slsp); + +extern __checkReturn int +siena_phy_power( + __in efx_nic_t *enp, + __in boolean_t on); + +extern __checkReturn int +siena_phy_reconfigure( + __in efx_nic_t *enp); + +extern __checkReturn int +siena_phy_verify( + __in efx_nic_t *enp); + +extern __checkReturn int +siena_phy_oui_get( + __in efx_nic_t *enp, + __out uint32_t *ouip); + +#if EFSYS_OPT_PHY_STATS + +extern void +siena_phy_decode_stats( + __in efx_nic_t *enp, + __in uint32_t vmask, + __in_opt efsys_mem_t *esmp, + __out_opt uint64_t *smaskp, + __out_ecount_opt(EFX_PHY_NSTATS) uint32_t *stat); + +extern __checkReturn int +siena_phy_stats_update( + __in efx_nic_t *enp, + __in efsys_mem_t *esmp, + __out_ecount(EFX_PHY_NSTATS) uint32_t *stat); + +#endif /* EFSYS_OPT_PHY_STATS */ + +#if EFSYS_OPT_PHY_PROPS + +#if EFSYS_OPT_NAMES + +extern const char __cs * +siena_phy_prop_name( + __in efx_nic_t *enp, + __in unsigned int id); + +#endif /* EFSYS_OPT_NAMES */ + +extern __checkReturn int +siena_phy_prop_get( + __in efx_nic_t *enp, + __in unsigned int id, + __in uint32_t flags, + __out uint32_t *valp); + +extern __checkReturn int +siena_phy_prop_set( + __in efx_nic_t *enp, + __in unsigned int id, + __in uint32_t val); + +#endif /* EFSYS_OPT_PHY_PROPS */ + +#if EFSYS_OPT_PHY_BIST + +extern __checkReturn int +siena_phy_bist_start( + __in efx_nic_t *enp, + __in efx_phy_bist_type_t type); + +extern __checkReturn int +siena_phy_bist_poll( + __in efx_nic_t *enp, + __in efx_phy_bist_type_t type, + __out efx_phy_bist_result_t *resultp, + __out_opt __drv_when(count > 0, __notnull) + uint32_t *value_maskp, + __out_ecount_opt(count) __drv_when(count > 0, __notnull) + unsigned long *valuesp, + __in size_t count); + +extern void +siena_phy_bist_stop( + __in efx_nic_t *enp, + __in efx_phy_bist_type_t type); + +#endif /* EFSYS_OPT_PHY_BIST */ + +extern __checkReturn int +siena_mac_poll( + __in efx_nic_t *enp, + __out efx_link_mode_t *link_modep); + +extern __checkReturn int +siena_mac_up( + __in efx_nic_t *enp, + __out boolean_t *mac_upp); + +extern __checkReturn int +siena_mac_reconfigure( + __in efx_nic_t *enp); + +#if EFSYS_OPT_LOOPBACK + +extern __checkReturn int +siena_mac_loopback_set( + __in efx_nic_t *enp, + __in efx_link_mode_t link_mode, + __in efx_loopback_type_t loopback_type); + +#endif /* EFSYS_OPT_LOOPBACK */ + +#if EFSYS_OPT_MAC_STATS + +extern __checkReturn int +siena_mac_stats_clear( + __in efx_nic_t *enp); + +extern __checkReturn int +siena_mac_stats_upload( + __in efx_nic_t *enp, + __in efsys_mem_t *esmp); + +extern __checkReturn int +siena_mac_stats_periodic( + __in efx_nic_t *enp, + __in efsys_mem_t *esmp, + __in uint16_t period_ms, + __in boolean_t events); + +extern __checkReturn int +siena_mac_stats_update( + __in efx_nic_t *enp, + __in efsys_mem_t *esmp, + __out_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat, + __out_opt uint32_t *generationp); + +#endif /* EFSYS_OPT_MAC_STATS */ + +extern __checkReturn int +siena_mon_reset( + __in efx_nic_t *enp); + +extern __checkReturn int +siena_mon_reconfigure( + __in efx_nic_t *enp); + +#if EFSYS_OPT_MON_STATS + +extern void +siena_mon_decode_stats( + __in efx_nic_t *enp, + __in uint32_t dmask, + __in_opt efsys_mem_t *esmp, + __out_opt uint32_t *vmaskp, + __out_ecount_opt(EFX_MON_NSTATS) efx_mon_stat_value_t *value); + +extern __checkReturn int +siena_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); + +extern __checkReturn int +siena_mon_stats_update( + __in efx_nic_t *enp, + __in efsys_mem_t *esmp, + __out_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values); + +#endif /* EFSYS_OPT_MON_STATS */ + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_SIENA_IMPL_H */ diff --git a/sys/dev/sfxge/common/siena_mac.c b/sys/dev/sfxge/common/siena_mac.c new file mode 100644 index 000000000000..7facf1c133e4 --- /dev/null +++ b/sys/dev/sfxge/common/siena_mac.c @@ -0,0 +1,545 @@ +/*- + * Copyright 2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "efsys.h" +#include "efx.h" +#include "efx_impl.h" + +#if EFSYS_OPT_SIENA + + __checkReturn int +siena_mac_poll( + __in efx_nic_t *enp, + __out efx_link_mode_t *link_modep) +{ + efx_port_t *epp = &(enp->en_port); + siena_link_state_t sls; + int rc; + + if ((rc = siena_phy_get_link(enp, &sls)) != 0) + goto fail1; + + epp->ep_adv_cap_mask = sls.sls_adv_cap_mask; + epp->ep_fcntl = sls.sls_fcntl; + + *link_modep = sls.sls_link_mode; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + *link_modep = EFX_LINK_UNKNOWN; + + return (rc); +} + + __checkReturn int +siena_mac_up( + __in efx_nic_t *enp, + __out boolean_t *mac_upp) +{ + siena_link_state_t sls; + int rc; + + /* + * Because Siena doesn't *require* polling, we can't rely on + * siena_mac_poll() being executed to populate epp->ep_mac_up. + */ + if ((rc = siena_phy_get_link(enp, &sls)) != 0) + goto fail1; + + *mac_upp = sls.sls_mac_up; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_mac_reconfigure( + __in efx_nic_t *enp) +{ + efx_port_t *epp = &(enp->en_port); + uint8_t payload[MAX(MC_CMD_SET_MAC_IN_LEN, + MC_CMD_SET_MCAST_HASH_IN_LEN)]; + efx_mcdi_req_t req; + unsigned int fcntl; + int rc; + + req.emr_cmd = MC_CMD_SET_MAC; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_SET_MAC_IN_LEN; + EFX_STATIC_ASSERT(MC_CMD_SET_MAC_OUT_LEN == 0); + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + MCDI_IN_SET_DWORD(req, SET_MAC_IN_MTU, epp->ep_mac_pdu); + MCDI_IN_SET_DWORD(req, SET_MAC_IN_DRAIN, epp->ep_mac_drain ? 1 : 0); + EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, SET_MAC_IN_ADDR), + epp->ep_mac_addr); + MCDI_IN_POPULATE_DWORD_2(req, SET_MAC_IN_REJECT, + SET_MAC_IN_REJECT_UNCST, !epp->ep_unicst, + SET_MAC_IN_REJECT_BRDCST, !epp->ep_brdcst); + + if (epp->ep_fcntl_autoneg) + /* efx_fcntl_set() has already set the phy capabilities */ + fcntl = MC_CMD_FCNTL_AUTO; + else if (epp->ep_fcntl & EFX_FCNTL_RESPOND) + fcntl = (epp->ep_fcntl & EFX_FCNTL_GENERATE) + ? MC_CMD_FCNTL_BIDIR + : MC_CMD_FCNTL_RESPOND; + else + fcntl = MC_CMD_FCNTL_OFF; + + MCDI_IN_SET_DWORD(req, SET_MAC_IN_FCNTL, fcntl); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + /* Push multicast hash. Set the broadcast bit (0xff) appropriately */ + req.emr_cmd = MC_CMD_SET_MCAST_HASH; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_SET_MCAST_HASH_IN_LEN; + EFX_STATIC_ASSERT(MC_CMD_SET_MCAST_HASH_OUT_LEN == 0); + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + memcpy(MCDI_IN2(req, uint8_t, SET_MCAST_HASH_IN_HASH0), + epp->ep_multicst_hash, sizeof (epp->ep_multicst_hash)); + if (epp->ep_brdcst) + EFX_SET_OWORD_BIT(*MCDI_IN2(req, efx_oword_t, + SET_MCAST_HASH_IN_HASH1), 0x7f); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail2; + } + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#if EFSYS_OPT_LOOPBACK + + __checkReturn int +siena_mac_loopback_set( + __in efx_nic_t *enp, + __in efx_link_mode_t link_mode, + __in efx_loopback_type_t loopback_type) +{ + efx_port_t *epp = &(enp->en_port); + efx_phy_ops_t *epop = epp->ep_epop; + efx_loopback_type_t old_loopback_type; + efx_link_mode_t old_loopback_link_mode; + int rc; + + /* The PHY object handles this on Siena */ + old_loopback_type = epp->ep_loopback_type; + old_loopback_link_mode = epp->ep_loopback_link_mode; + epp->ep_loopback_type = loopback_type; + epp->ep_loopback_link_mode = link_mode; + + if ((rc = epop->epo_reconfigure(enp)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE(fail2); + + epp->ep_loopback_type = old_loopback_type; + epp->ep_loopback_link_mode = old_loopback_link_mode; + + return (rc); +} + +#endif /* EFSYS_OPT_LOOPBACK */ + +#if EFSYS_OPT_MAC_STATS + + __checkReturn int +siena_mac_stats_clear( + __in efx_nic_t *enp) +{ + uint8_t payload[MC_CMD_MAC_STATS_IN_LEN]; + efx_mcdi_req_t req; + int rc; + + req.emr_cmd = MC_CMD_MAC_STATS; + req.emr_in_buf = payload; + req.emr_in_length = sizeof (payload); + EFX_STATIC_ASSERT(MC_CMD_MAC_STATS_OUT_DMA_LEN == 0); + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + MCDI_IN_POPULATE_DWORD_3(req, MAC_STATS_IN_CMD, + MAC_STATS_IN_DMA, 0, + MAC_STATS_IN_CLEAR, 1, + MAC_STATS_IN_PERIODIC_CHANGE, 0); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_mac_stats_upload( + __in efx_nic_t *enp, + __in efsys_mem_t *esmp) +{ + uint8_t payload[MC_CMD_MAC_STATS_IN_LEN]; + efx_mcdi_req_t req; + size_t bytes; + int rc; + + EFX_STATIC_ASSERT(MC_CMD_MAC_NSTATS * sizeof (uint64_t) <= + EFX_MAC_STATS_SIZE); + + bytes = MC_CMD_MAC_NSTATS * sizeof (uint64_t); + + req.emr_cmd = MC_CMD_MAC_STATS; + req.emr_in_buf = payload; + req.emr_in_length = sizeof (payload); + EFX_STATIC_ASSERT(MC_CMD_MAC_STATS_OUT_DMA_LEN == 0); + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_LO, + EFSYS_MEM_ADDR(esmp) & 0xffffffff); + MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_HI, + EFSYS_MEM_ADDR(esmp) >> 32); + MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_LEN, bytes); + + /* + * The MC DMAs aggregate statistics for our convinience, so we can + * avoid having to pull the statistics buffer into the cache to + * maintain cumulative statistics. + */ + MCDI_IN_POPULATE_DWORD_3(req, MAC_STATS_IN_CMD, + MAC_STATS_IN_DMA, 1, + MAC_STATS_IN_CLEAR, 0, + MAC_STATS_IN_PERIODIC_CHANGE, 0); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_mac_stats_periodic( + __in efx_nic_t *enp, + __in efsys_mem_t *esmp, + __in uint16_t period, + __in boolean_t events) +{ + uint8_t payload[MC_CMD_MAC_STATS_IN_LEN]; + efx_mcdi_req_t req; + size_t bytes; + int rc; + + bytes = MC_CMD_MAC_NSTATS * sizeof (uint64_t); + + req.emr_cmd = MC_CMD_MAC_STATS; + req.emr_in_buf = payload; + req.emr_in_length = sizeof (payload); + EFX_STATIC_ASSERT(MC_CMD_MAC_STATS_OUT_DMA_LEN == 0); + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_LO, + EFSYS_MEM_ADDR(esmp) & 0xffffffff); + MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_HI, + EFSYS_MEM_ADDR(esmp) >> 32); + MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_LEN, bytes); + + /* + * The MC DMAs aggregate statistics for our convinience, so we can + * avoid having to pull the statistics buffer into the cache to + * maintain cumulative statistics. + */ + MCDI_IN_POPULATE_DWORD_6(req, MAC_STATS_IN_CMD, + MAC_STATS_IN_DMA, 0, + MAC_STATS_IN_CLEAR, 0, + MAC_STATS_IN_PERIODIC_CHANGE, 1, + MAC_STATS_IN_PERIODIC_ENABLE, period ? 1 : 0, + MAC_STATS_IN_PERIODIC_NOEVENT, events ? 0 : 1, + MAC_STATS_IN_PERIOD_MS, period); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + +#define SIENA_MAC_STAT_READ(_esmp, _field, _eqp) \ + EFSYS_MEM_READQ((_esmp), (_field) * sizeof (efx_qword_t), _eqp) + + __checkReturn int +siena_mac_stats_update( + __in efx_nic_t *enp, + __in efsys_mem_t *esmp, + __out_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat, + __out_opt uint32_t *generationp) +{ + efx_qword_t rx_pkts; + efx_qword_t value; + efx_qword_t generation_start; + efx_qword_t generation_end; + + _NOTE(ARGUNUSED(enp)) + + /* Read END first so we don't race with the MC */ + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_END, + &generation_end); + EFSYS_MEM_READ_BARRIER(); + + /* TX */ + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value); + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_CONTROL_PKTS, &value); + EFSYS_STAT_SUBR_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PAUSE_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PAUSE_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_UNICAST_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_UNICST_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTICAST_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULTICST_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BROADCAST_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_BRDCST_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BYTES, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_OCTETS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LT64_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value); + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_64_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_65_TO_127_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_65_TO_127_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_128_TO_255_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_128_TO_255_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_256_TO_511_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_256_TO_511_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_512_TO_1023_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_512_TO_1023_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_1024_TO_15XX_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_1024_TO_15XX_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value); + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_GTJUMBO_PKTS, &value); + EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BAD_FCS_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_ERRORS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_SGL_COL_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS, + &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULT_COL_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS, + &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_COL_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LATE_COLLISION_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LATE_COL_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_DEFERRED_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_DEF_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS, + &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_DEF_PKTS]), &value); + + /* RX */ + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BYTES, &rx_pkts); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_OCTETS]), &rx_pkts); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNICAST_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_UNICST_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MULTICAST_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MULTICST_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BROADCAST_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_BRDCST_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PAUSE_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PAUSE_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNDERSIZE_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value); + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_64_PKTS, &value); + EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_65_TO_127_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_65_TO_127_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_128_TO_255_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_128_TO_255_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_256_TO_511_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_256_TO_511_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_512_TO_1023_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_512_TO_1023_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_1024_TO_15XX_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_1024_TO_15XX_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value); + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_GTJUMBO_PKTS, &value); + EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BAD_FCS_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FCS_ERRORS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_OVERFLOW_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_DROP_EVENTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_FALSE_CARRIER_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FALSE_CARRIER_ERRORS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_SYMBOL_ERRORS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_ALIGN_ERROR_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_ALIGN_ERRORS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_INTERNAL_ERRORS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_JABBER_PKTS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_JABBER_PKTS]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_CHAR_ERR, &value); + EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_CHAR_ERR]), + &(value.eq_dword[0])); + EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_CHAR_ERR]), + &(value.eq_dword[1])); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_CHAR_ERR, &value); + EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_CHAR_ERR]), + &(value.eq_dword[0])); + EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_CHAR_ERR]), + &(value.eq_dword[1])); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_DISP_ERR, &value); + EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_DISP_ERR]), + &(value.eq_dword[0])); + EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_DISP_ERR]), + &(value.eq_dword[1])); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_DISP_ERR, &value); + EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_DISP_ERR]), + &(value.eq_dword[0])); + EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_DISP_ERR]), + &(value.eq_dword[1])); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MATCH_FAULT, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MATCH_FAULT]), &value); + + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_NODESC_DROPS, &value); + EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_NODESC_DROP_CNT]), &value); + + EFSYS_MEM_READ_BARRIER(); + SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_START, + &generation_start); + + /* Check that we didn't read the stats in the middle of a DMA */ + if (memcmp(&generation_start, &generation_end, + sizeof (generation_start))) + return (EAGAIN); + + if (generationp) + *generationp = EFX_QWORD_FIELD(generation_start, EFX_DWORD_0); + + return (0); +} + +#endif /* EFSYS_OPT_MAC_STATS */ + +#endif /* EFSYS_OPT_SIENA */ diff --git a/sys/dev/sfxge/common/siena_mon.c b/sys/dev/sfxge/common/siena_mon.c new file mode 100644 index 000000000000..de9a1df5ed8c --- /dev/null +++ b/sys/dev/sfxge/common/siena_mon.c @@ -0,0 +1,248 @@ +/*- + * Copyright 2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "efsys.h" +#include "efx.h" +#include "efx_impl.h" + +#if EFSYS_OPT_MON_SIENA + + __checkReturn int +siena_mon_reset( + __in efx_nic_t *enp) +{ + _NOTE(ARGUNUSED(enp)) + EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); + + return (0); +} + + __checkReturn int +siena_mon_reconfigure( + __in efx_nic_t *enp) +{ + _NOTE(ARGUNUSED(enp)) + EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); + + return (0); +} + +#if EFSYS_OPT_MON_STATS + +#define SIENA_MON_WRONG_PORT (uint16_t)0xffff + +static __cs uint16_t __siena_mon_port0_map[] = { + EFX_MON_STAT_INT_TEMP, /* MC_CMD_SENSOR_CONTROLLER_TEMP */ + EFX_MON_STAT_EXT_TEMP, /* MC_CMD_SENSOR_PHY_COMMON_TEMP */ + EFX_MON_STAT_INT_COOLING, /* MC_CMD_SENSOR_CONTROLLER_COOLING */ + EFX_MON_STAT_EXT_TEMP, /* MC_CMD_SENSOR_PHY0_TEMP */ + EFX_MON_STAT_EXT_COOLING, /* MC_CMD_SENSOR_PHY0_COOLING */ + SIENA_MON_WRONG_PORT, /* MC_CMD_SENSOR_PHY1_TEMP */ + SIENA_MON_WRONG_PORT, /* MC_CMD_SENSOR_PHY1_COOLING */ + EFX_MON_STAT_1V, /* MC_CMD_SENSOR_IN_1V0 */ + EFX_MON_STAT_1_2V, /* MC_CMD_SENSOR_IN_1V2 */ + EFX_MON_STAT_1_8V, /* MC_CMD_SENSOR_IN_1V8 */ + EFX_MON_STAT_2_5V, /* MC_CMD_SENSOR_IN_2V5 */ + EFX_MON_STAT_3_3V, /* MC_CMD_SENSOR_IN_3V3 */ + EFX_MON_STAT_12V, /* MC_CMD_SENSOR_IN_12V0 */ +}; + +static __cs uint16_t __siena_mon_port1_map[] = { + EFX_MON_STAT_INT_TEMP, /* MC_CMD_SENSOR_CONTROLLER_TEMP */ + EFX_MON_STAT_EXT_TEMP, /* MC_CMD_SENSOR_PHY_COMMON_TEMP */ + EFX_MON_STAT_INT_COOLING, /* MC_CMD_SENSOR_CONTROLLER_COOLING */ + SIENA_MON_WRONG_PORT, /* MC_CMD_SENSOR_PHY0_TEMP */ + SIENA_MON_WRONG_PORT, /* MC_CMD_SENSOR_PHY0_COOLING */ + EFX_MON_STAT_EXT_TEMP, /* MC_CMD_SENSOR_PHY1_TEMP */ + EFX_MON_STAT_EXT_COOLING, /* MC_CMD_SENSOR_PHY1_COOLING */ + EFX_MON_STAT_1V, /* MC_CMD_SENSOR_IN_1V0 */ + EFX_MON_STAT_1_2V, /* MC_CMD_SENSOR_IN_1V2 */ + EFX_MON_STAT_1_8V, /* MC_CMD_SENSOR_IN_1V8 */ + EFX_MON_STAT_2_5V, /* MC_CMD_SENSOR_IN_2V5 */ + EFX_MON_STAT_3_3V, /* MC_CMD_SENSOR_IN_3V3 */ + EFX_MON_STAT_12V, /* MC_CMD_SENSOR_IN_12V0 */ +}; + +#define SIENA_STATIC_SENSOR_ASSERT(_field) \ + EFX_STATIC_ASSERT(MC_CMD_SENSOR_STATE_ ## _field \ + == EFX_MON_STAT_STATE_ ## _field) + + void +siena_mon_decode_stats( + __in efx_nic_t *enp, + __in uint32_t dmask, + __in_opt efsys_mem_t *esmp, + __out_opt uint32_t *vmaskp, + __out_ecount_opt(EFX_MON_NSTATS) efx_mon_stat_value_t *value) +{ + efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip); + uint16_t *sensor_map; + uint16_t mc_sensor; + size_t mc_sensor_max; + uint32_t vmask = 0; + + /* Assert the MC_CMD_SENSOR and EFX_MON_STATE namespaces agree */ + SIENA_STATIC_SENSOR_ASSERT(OK); + SIENA_STATIC_SENSOR_ASSERT(WARNING); + SIENA_STATIC_SENSOR_ASSERT(FATAL); + SIENA_STATIC_SENSOR_ASSERT(BROKEN); + + EFX_STATIC_ASSERT(sizeof (__siena_mon_port1_map) + == sizeof (__siena_mon_port0_map)); + mc_sensor_max = EFX_ARRAY_SIZE(__siena_mon_port0_map); + sensor_map = (emip->emi_port == 1) + ? __siena_mon_port0_map + : __siena_mon_port1_map; + + /* + * dmask may legitimately contain sensors not understood by the driver + */ + for (mc_sensor = 0; mc_sensor < mc_sensor_max; ++mc_sensor) { + uint16_t efx_sensor = sensor_map[mc_sensor]; + + if (efx_sensor == SIENA_MON_WRONG_PORT) + continue; + EFSYS_ASSERT(efx_sensor < EFX_MON_NSTATS); + + if (~dmask & (1 << mc_sensor)) + continue; + + vmask |= (1 << efx_sensor); + if (value != NULL && esmp != NULL && !EFSYS_MEM_IS_NULL(esmp)) { + efx_mon_stat_value_t *emsvp = value + efx_sensor; + efx_dword_t dword; + EFSYS_MEM_READD(esmp, 4 * mc_sensor, &dword); + emsvp->emsv_value = + (uint16_t)EFX_DWORD_FIELD( + dword, + MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE); + emsvp->emsv_state = + (uint16_t)EFX_DWORD_FIELD( + dword, + MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE); + } + } + + if (vmaskp != NULL) + *vmaskp = vmask; +} + + __checkReturn int +siena_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_u.siena.enu_mip); + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + uint16_t ev_monitor; + uint16_t ev_state; + uint16_t ev_value; + uint16_t *sensor_map; + efx_mon_stat_t id; + int rc; + + sensor_map = (emip->emi_port == 1) + ? __siena_mon_port0_map + : __siena_mon_port1_map; + + ev_monitor = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_MONITOR); + ev_state = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_STATE); + ev_value = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_VALUE); + + /* Hardware must support this statistic */ + EFSYS_ASSERT((1 << ev_monitor) & encp->enc_siena_mon_stat_mask); + + /* But we don't have to understand it */ + if (ev_monitor >= EFX_ARRAY_SIZE(__siena_mon_port0_map)) { + rc = ENOTSUP; + goto fail1; + } + + id = sensor_map[ev_monitor]; + if (id == SIENA_MON_WRONG_PORT) + return (ENODEV); + EFSYS_ASSERT(id < EFX_MON_NSTATS); + + *idp = id; + valuep->emsv_value = ev_value; + valuep->emsv_state = ev_state; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_mon_stats_update( + __in efx_nic_t *enp, + __in efsys_mem_t *esmp, + __out_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values) +{ + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + uint32_t dmask = encp->enc_siena_mon_stat_mask; + uint32_t vmask; + uint8_t payload[MC_CMD_READ_SENSORS_IN_LEN]; + efx_mcdi_req_t req; + int rc; + + EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); + + req.emr_cmd = MC_CMD_READ_SENSORS; + req.emr_in_buf = payload; + req.emr_in_length = sizeof (payload); + EFX_STATIC_ASSERT(MC_CMD_READ_SENSORS_OUT_LEN == 0); + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + MCDI_IN_SET_DWORD(req, READ_SENSORS_IN_DMA_ADDR_LO, + EFSYS_MEM_ADDR(esmp) & 0xffffffff); + MCDI_IN_SET_DWORD(req, READ_SENSORS_IN_DMA_ADDR_HI, + EFSYS_MEM_ADDR(esmp) >> 32); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + siena_mon_decode_stats(enp, dmask, esmp, &vmask, values); + EFSYS_ASSERT(vmask == encp->enc_mon_stat_mask); + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#endif /* EFSYS_OPT_MON_STATS */ + +#endif /* EFSYS_OPT_MON_SIENA */ diff --git a/sys/dev/sfxge/common/siena_nic.c b/sys/dev/sfxge/common/siena_nic.c new file mode 100644 index 000000000000..9eb0db2f8a30 --- /dev/null +++ b/sys/dev/sfxge/common/siena_nic.c @@ -0,0 +1,964 @@ +/*- + * Copyright 2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "efsys.h" +#include "efx.h" +#include "efx_impl.h" + +#if EFSYS_OPT_SIENA + +static __checkReturn int +siena_nic_get_partn_mask( + __in efx_nic_t *enp, + __out unsigned int *maskp) +{ + efx_mcdi_req_t req; + uint8_t outbuf[MC_CMD_NVRAM_TYPES_OUT_LEN]; + int rc; + + req.emr_cmd = MC_CMD_NVRAM_TYPES; + EFX_STATIC_ASSERT(MC_CMD_NVRAM_TYPES_IN_LEN == 0); + req.emr_in_buf = NULL; + req.emr_in_length = 0; + req.emr_out_buf = outbuf; + req.emr_out_length = sizeof (outbuf); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + if (req.emr_out_length_used < MC_CMD_NVRAM_TYPES_OUT_LEN) { + rc = EMSGSIZE; + goto fail2; + } + + *maskp = MCDI_OUT_DWORD(req, NVRAM_TYPES_OUT_TYPES); + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +static __checkReturn int +siena_nic_exit_assertion_handler( + __in efx_nic_t *enp) +{ + efx_mcdi_req_t req; + uint8_t payload[MC_CMD_REBOOT_IN_LEN]; + int rc; + + req.emr_cmd = MC_CMD_REBOOT; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_REBOOT_IN_LEN; + EFX_STATIC_ASSERT(MC_CMD_REBOOT_OUT_LEN == 0); + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + MCDI_IN_SET_DWORD(req, REBOOT_IN_FLAGS, + MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0 && req.emr_rc != EIO) { + rc = req.emr_rc; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +static __checkReturn int +siena_nic_read_assertion( + __in efx_nic_t *enp) +{ + efx_mcdi_req_t req; + uint8_t payload[MAX(MC_CMD_GET_ASSERTS_IN_LEN, + MC_CMD_GET_ASSERTS_OUT_LEN)]; + const char *reason; + unsigned int flags; + unsigned int index; + unsigned int ofst; + int retry; + int rc; + + /* + * Before we attempt to chat to the MC, we should verify that the MC + * isn't in it's assertion handler, either due to a previous reboot, + * or because we're reinitializing due to an eec_exception(). + * + * Use GET_ASSERTS to read any assertion state that may be present. + * Retry this command twice. Once because a boot-time assertion failure + * might cause the 1st MCDI request to fail. And once again because + * we might race with siena_nic_exit_assertion_handler() running on the + * other port. + */ + retry = 2; + do { + req.emr_cmd = MC_CMD_GET_ASSERTS; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_GET_ASSERTS_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_GET_ASSERTS_OUT_LEN; + + MCDI_IN_SET_DWORD(req, GET_ASSERTS_IN_CLEAR, 1); + efx_mcdi_execute(enp, &req); + + } while ((req.emr_rc == EINTR || req.emr_rc == EIO) && retry-- > 0); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + if (req.emr_out_length_used < MC_CMD_GET_ASSERTS_OUT_LEN) { + rc = EMSGSIZE; + goto fail2; + } + + /* Print out any assertion state recorded */ + flags = MCDI_OUT_DWORD(req, GET_ASSERTS_OUT_GLOBAL_FLAGS); + if (flags == MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS) + return (0); + + reason = (flags == MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL) + ? "system-level assertion" + : (flags == MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL) + ? "thread-level assertion" + : (flags == MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED) + ? "watchdog reset" + : "unknown assertion"; + EFSYS_PROBE3(mcpu_assertion, + const char *, reason, unsigned int, + MCDI_OUT_DWORD(req, GET_ASSERTS_OUT_SAVED_PC_OFFS), + unsigned int, + MCDI_OUT_DWORD(req, GET_ASSERTS_OUT_THREAD_OFFS)); + + /* Print out the registers */ + ofst = MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST; + for (index = 1; index < 32; index++) { + EFSYS_PROBE2(mcpu_register, unsigned int, index, unsigned int, + EFX_DWORD_FIELD(*MCDI_OUT(req, efx_dword_t, ofst), + EFX_DWORD_0)); + ofst += sizeof (efx_dword_t); + } + EFSYS_ASSERT(ofst <= MC_CMD_GET_ASSERTS_OUT_LEN); + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +static __checkReturn int +siena_nic_attach( + __in efx_nic_t *enp, + __in boolean_t attach) +{ + efx_mcdi_req_t req; + uint8_t payload[MC_CMD_DRV_ATTACH_IN_LEN]; + int rc; + + req.emr_cmd = MC_CMD_DRV_ATTACH; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_DRV_ATTACH_IN_LEN; + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + MCDI_IN_SET_DWORD(req, DRV_ATTACH_IN_NEW_STATE, attach ? 1 : 0); + MCDI_IN_SET_DWORD(req, DRV_ATTACH_IN_UPDATE, 1); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + if (req.emr_out_length_used < MC_CMD_DRV_ATTACH_OUT_LEN) { + rc = EMSGSIZE; + goto fail2; + } + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#if EFSYS_OPT_PCIE_TUNE + + __checkReturn int +siena_nic_pcie_extended_sync( + __in efx_nic_t *enp) +{ + uint8_t inbuf[MC_CMD_WORKAROUND_IN_LEN]; + efx_mcdi_req_t req; + int rc; + + EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); + + req.emr_cmd = MC_CMD_WORKAROUND; + req.emr_in_buf = inbuf; + req.emr_in_length = sizeof (inbuf); + EFX_STATIC_ASSERT(MC_CMD_WORKAROUND_OUT_LEN == 0); + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + MCDI_IN_SET_DWORD(req, WORKAROUND_IN_TYPE, MC_CMD_WORKAROUND_BUG17230); + MCDI_IN_SET_DWORD(req, WORKAROUND_IN_ENABLED, 1); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#endif /* EFSYS_OPT_PCIE_TUNE */ + +static __checkReturn int +siena_board_cfg( + __in efx_nic_t *enp) +{ + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip); + uint8_t outbuf[MAX(MC_CMD_GET_BOARD_CFG_OUT_LEN, + MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN)]; + efx_mcdi_req_t req; + uint8_t *src; + int rc; + + /* Board configuration */ + req.emr_cmd = MC_CMD_GET_BOARD_CFG; + EFX_STATIC_ASSERT(MC_CMD_GET_BOARD_CFG_IN_LEN == 0); + req.emr_in_buf = NULL; + req.emr_in_length = 0; + req.emr_out_buf = outbuf; + req.emr_out_length = MC_CMD_GET_BOARD_CFG_OUT_LEN; + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + if (req.emr_out_length_used < MC_CMD_GET_BOARD_CFG_OUT_LEN) { + rc = EMSGSIZE; + goto fail2; + } + + if (emip->emi_port == 1) + src = MCDI_OUT2(req, uint8_t, + GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0); + else + src = MCDI_OUT2(req, uint8_t, + GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1); + EFX_MAC_ADDR_COPY(encp->enc_mac_addr, src); + + encp->enc_board_type = MCDI_OUT_DWORD(req, + GET_BOARD_CFG_OUT_BOARD_TYPE); + + /* Resource limits */ + req.emr_cmd = MC_CMD_GET_RESOURCE_LIMITS; + EFX_STATIC_ASSERT(MC_CMD_GET_RESOURCE_LIMITS_IN_LEN == 0); + req.emr_in_buf = NULL; + req.emr_in_length = 0; + req.emr_out_buf = outbuf; + req.emr_out_length = MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN; + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc == 0) { + if (req.emr_out_length_used < MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN) { + rc = EMSGSIZE; + goto fail3; + } + + encp->enc_evq_limit = MCDI_OUT_DWORD(req, + GET_RESOURCE_LIMITS_OUT_EVQ); + encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, + MCDI_OUT_DWORD(req, GET_RESOURCE_LIMITS_OUT_TXQ)); + encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, + MCDI_OUT_DWORD(req, GET_RESOURCE_LIMITS_OUT_RXQ)); + } else if (req.emr_rc == ENOTSUP) { + encp->enc_evq_limit = 1024; + encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET; + encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET; + } else { + rc = req.emr_rc; + goto fail4; + } + + encp->enc_buftbl_limit = SIENA_SRAM_ROWS - + (encp->enc_txq_limit * 16) - (encp->enc_rxq_limit * 64); + + return (0); + +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +static __checkReturn int +siena_phy_cfg( + __in efx_nic_t *enp) +{ + efx_port_t *epp = &(enp->en_port); + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + efx_mcdi_req_t req; + uint8_t outbuf[MC_CMD_GET_PHY_CFG_OUT_LEN]; + int rc; + + req.emr_cmd = MC_CMD_GET_PHY_CFG; + EFX_STATIC_ASSERT(MC_CMD_GET_PHY_CFG_IN_LEN == 0); + req.emr_in_buf = NULL; + req.emr_in_length = 0; + req.emr_out_buf = outbuf; + req.emr_out_length = sizeof (outbuf); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + if (req.emr_out_length_used < MC_CMD_GET_PHY_CFG_OUT_LEN) { + rc = EMSGSIZE; + goto fail2; + } + + encp->enc_phy_type = MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_TYPE); +#if EFSYS_OPT_NAMES + (void) strncpy(encp->enc_phy_name, + MCDI_OUT2(req, char, GET_PHY_CFG_OUT_NAME), + MIN(sizeof (encp->enc_phy_name) - 1, + MC_CMD_GET_PHY_CFG_OUT_NAME_LEN)); +#endif /* EFSYS_OPT_NAMES */ + (void) memset(encp->enc_phy_revision, 0, + sizeof (encp->enc_phy_revision)); + memcpy(encp->enc_phy_revision, + MCDI_OUT2(req, char, GET_PHY_CFG_OUT_REVISION), + MIN(sizeof (encp->enc_phy_revision) - 1, + MC_CMD_GET_PHY_CFG_OUT_REVISION_LEN)); +#if EFSYS_OPT_PHY_LED_CONTROL + encp->enc_led_mask = ((1 << EFX_PHY_LED_DEFAULT) | + (1 << EFX_PHY_LED_OFF) | + (1 << EFX_PHY_LED_ON)); +#endif /* EFSYS_OPT_PHY_LED_CONTROL */ + +#if EFSYS_OPT_PHY_PROPS + encp->enc_phy_nprops = 0; +#endif /* EFSYS_OPT_PHY_PROPS */ + + /* Get the media type of the fixed port, if recognised. */ + EFX_STATIC_ASSERT(MC_CMD_MEDIA_XAUI == EFX_PHY_MEDIA_XAUI); + EFX_STATIC_ASSERT(MC_CMD_MEDIA_CX4 == EFX_PHY_MEDIA_CX4); + EFX_STATIC_ASSERT(MC_CMD_MEDIA_KX4 == EFX_PHY_MEDIA_KX4); + EFX_STATIC_ASSERT(MC_CMD_MEDIA_XFP == EFX_PHY_MEDIA_XFP); + EFX_STATIC_ASSERT(MC_CMD_MEDIA_SFP_PLUS == EFX_PHY_MEDIA_SFP_PLUS); + EFX_STATIC_ASSERT(MC_CMD_MEDIA_BASE_T == EFX_PHY_MEDIA_BASE_T); + epp->ep_fixed_port_type = + MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_MEDIA_TYPE); + if (epp->ep_fixed_port_type >= EFX_PHY_MEDIA_NTYPES) + epp->ep_fixed_port_type = EFX_PHY_MEDIA_INVALID; + + epp->ep_phy_cap_mask = + MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_SUPPORTED_CAP); +#if EFSYS_OPT_PHY_FLAGS + encp->enc_phy_flags_mask = MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_FLAGS); +#endif /* EFSYS_OPT_PHY_FLAGS */ + + encp->enc_port = (uint8_t)MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_PRT); + + /* Populate internal state */ + encp->enc_siena_channel = + (uint8_t)MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_CHANNEL); + +#if EFSYS_OPT_PHY_STATS + encp->enc_siena_phy_stat_mask = + MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_STATS_MASK); + + /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */ + siena_phy_decode_stats(enp, encp->enc_siena_phy_stat_mask, + NULL, &encp->enc_phy_stat_mask, NULL); +#endif /* EFSYS_OPT_PHY_STATS */ + +#if EFSYS_OPT_PHY_BIST + encp->enc_bist_mask = 0; + if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS, + GET_PHY_CFG_OUT_BIST_CABLE_SHORT)) + encp->enc_bist_mask |= (1 << EFX_PHY_BIST_TYPE_CABLE_SHORT); + if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS, + GET_PHY_CFG_OUT_BIST_CABLE_LONG)) + encp->enc_bist_mask |= (1 << EFX_PHY_BIST_TYPE_CABLE_LONG); + if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS, + GET_PHY_CFG_OUT_BIST)) + encp->enc_bist_mask |= (1 << EFX_PHY_BIST_TYPE_NORMAL); +#endif /* EFSYS_OPT_BIST */ + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#if EFSYS_OPT_LOOPBACK + +static __checkReturn int +siena_loopback_cfg( + __in efx_nic_t *enp) +{ + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + efx_mcdi_req_t req; + uint8_t outbuf[MC_CMD_GET_LOOPBACK_MODES_OUT_LEN]; + int rc; + + req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES; + EFX_STATIC_ASSERT(MC_CMD_GET_LOOPBACK_MODES_IN_LEN == 0); + req.emr_in_buf = NULL; + req.emr_in_length = 0; + req.emr_out_buf = outbuf; + req.emr_out_length = sizeof (outbuf); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + if (req.emr_out_length_used < MC_CMD_GET_LOOPBACK_MODES_OUT_LEN) { + rc = EMSGSIZE; + goto fail2; + } + + /* + * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree + * in siena_phy.c:siena_phy_get_link() + */ + encp->enc_loopback_types[EFX_LINK_100FDX] = EFX_LOOPBACK_MASK & + MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_100M) & + MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_SUGGESTED); + encp->enc_loopback_types[EFX_LINK_1000FDX] = EFX_LOOPBACK_MASK & + MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_1G) & + MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_SUGGESTED); + encp->enc_loopback_types[EFX_LINK_10000FDX] = EFX_LOOPBACK_MASK & + MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_10G) & + MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_SUGGESTED); + encp->enc_loopback_types[EFX_LINK_UNKNOWN] = + (1 << EFX_LOOPBACK_OFF) | + encp->enc_loopback_types[EFX_LINK_100FDX] | + encp->enc_loopback_types[EFX_LINK_1000FDX] | + encp->enc_loopback_types[EFX_LINK_10000FDX]; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#endif /* EFSYS_OPT_LOOPBACK */ + +#if EFSYS_OPT_MON_STATS + +static __checkReturn int +siena_monitor_cfg( + __in efx_nic_t *enp) +{ + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + efx_mcdi_req_t req; + uint8_t outbuf[MCDI_CTL_SDU_LEN_MAX]; + int rc; + + req.emr_cmd = MC_CMD_SENSOR_INFO; + EFX_STATIC_ASSERT(MC_CMD_SENSOR_INFO_IN_LEN == 0); + req.emr_in_buf = NULL; + req.emr_in_length = 0; + req.emr_out_buf = outbuf; + req.emr_out_length = sizeof (outbuf); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + if (req.emr_out_length_used < MC_CMD_SENSOR_INFO_OUT_MASK_OFST + 4) { + rc = EMSGSIZE; + goto fail2; + } + + encp->enc_siena_mon_stat_mask = + MCDI_OUT_DWORD(req, SENSOR_INFO_OUT_MASK); + encp->enc_mon_type = EFX_MON_SFC90X0; + + siena_mon_decode_stats(enp, encp->enc_siena_mon_stat_mask, + NULL, &(encp->enc_mon_stat_mask), NULL); + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#endif /* EFSYS_OPT_MON_STATS */ + + __checkReturn int +siena_nic_probe( + __in efx_nic_t *enp) +{ + efx_port_t *epp = &(enp->en_port); + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + siena_link_state_t sls; + unsigned int mask; + int rc; + + EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); + + /* Read clear any assertion state */ + if ((rc = siena_nic_read_assertion(enp)) != 0) + goto fail1; + + /* Exit the assertion handler */ + if ((rc = siena_nic_exit_assertion_handler(enp)) != 0) + goto fail2; + + /* Wrestle control from the BMC */ + if ((rc = siena_nic_attach(enp, B_TRUE)) != 0) + goto fail3; + + if ((rc = siena_board_cfg(enp)) != 0) + goto fail4; + + encp->enc_evq_moderation_max = + EFX_EV_TIMER_QUANTUM << FRF_CZ_TIMER_VAL_WIDTH; + + if ((rc = siena_phy_cfg(enp)) != 0) + goto fail5; + + /* Obtain the default PHY advertised capabilities */ + if ((rc = siena_nic_reset(enp)) != 0) + goto fail6; + if ((rc = siena_phy_get_link(enp, &sls)) != 0) + goto fail7; + epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask; + epp->ep_adv_cap_mask = sls.sls_adv_cap_mask; + +#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM + if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0) + goto fail8; + enp->en_u.siena.enu_partn_mask = mask; +#endif + +#if EFSYS_OPT_MAC_STATS + /* Wipe the MAC statistics */ + if ((rc = siena_mac_stats_clear(enp)) != 0) + goto fail9; +#endif + +#if EFSYS_OPT_LOOPBACK + if ((rc = siena_loopback_cfg(enp)) != 0) + goto fail10; +#endif + +#if EFSYS_OPT_MON_STATS + if ((rc = siena_monitor_cfg(enp)) != 0) + goto fail11; +#endif + + encp->enc_features = enp->en_features; + + return (0); + +#if EFSYS_OPT_MON_STATS +fail11: + EFSYS_PROBE(fail11); +#endif +#if EFSYS_OPT_LOOPBACK +fail10: + EFSYS_PROBE(fail10); +#endif +#if EFSYS_OPT_MAC_STATS +fail9: + EFSYS_PROBE(fail9); +#endif +#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM +fail8: + EFSYS_PROBE(fail8); +#endif +fail7: + EFSYS_PROBE(fail7); +fail6: + EFSYS_PROBE(fail6); +fail5: + EFSYS_PROBE(fail5); +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_nic_reset( + __in efx_nic_t *enp) +{ + efx_mcdi_req_t req; + int rc; + + EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); + + /* siena_nic_reset() is called to recover from BADASSERT failures. */ + if ((rc = siena_nic_read_assertion(enp)) != 0) + goto fail1; + if ((rc = siena_nic_exit_assertion_handler(enp)) != 0) + goto fail2; + + req.emr_cmd = MC_CMD_PORT_RESET; + EFX_STATIC_ASSERT(MC_CMD_PORT_RESET_IN_LEN == 0); + req.emr_in_buf = NULL; + req.emr_in_length = 0; + EFX_STATIC_ASSERT(MC_CMD_PORT_RESET_OUT_LEN == 0); + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail3; + } + + return (0); + +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (0); +} + +static __checkReturn int +siena_nic_logging( + __in efx_nic_t *enp) +{ + efx_mcdi_req_t req; + uint8_t payload[MC_CMD_LOG_CTRL_IN_LEN]; + int rc; + + req.emr_cmd = MC_CMD_LOG_CTRL; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_LOG_CTRL_IN_LEN; + EFX_STATIC_ASSERT(MC_CMD_LOG_CTRL_OUT_LEN == 0); + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + MCDI_IN_SET_DWORD(req, LOG_CTRL_IN_LOG_DEST, + MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ); + MCDI_IN_SET_DWORD(req, LOG_CTRL_IN_LOG_DEST_EVQ, 0); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +static void +siena_nic_rx_cfg( + __in efx_nic_t *enp) +{ + efx_oword_t oword; + + /* + * RX_INGR_EN is always enabled on Siena, because we rely on + * the RX parser to be resiliant to missing SOP/EOP. + */ + EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword); + EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1); + EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword); + + /* Disable parsing of additional 802.1Q in Q packets */ + EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword); + EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0); + EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword); +} + +static void +siena_nic_usrev_dis( + __in efx_nic_t *enp) +{ + efx_oword_t oword; + + EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1); + EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword); +} + + __checkReturn int +siena_nic_init( + __in efx_nic_t *enp) +{ + int rc; + + EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); + + if ((rc = siena_nic_logging(enp)) != 0) + goto fail1; + + siena_sram_init(enp); + + /* Configure Siena's RX block */ + siena_nic_rx_cfg(enp); + + /* Disable USR_EVents for now */ + siena_nic_usrev_dis(enp); + + /* bug17057: Ensure set_link is called */ + if ((rc = siena_phy_reconfigure(enp)) != 0) + goto fail2; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + void +siena_nic_fini( + __in efx_nic_t *enp) +{ + _NOTE(ARGUNUSED(enp)) +} + + void +siena_nic_unprobe( + __in efx_nic_t *enp) +{ + (void) siena_nic_attach(enp, B_FALSE); +} + +#if EFSYS_OPT_DIAG + +static efx_register_set_t __cs __siena_registers[] = { + { FR_AZ_ADR_REGION_REG_OFST, 0, 1 }, + { FR_CZ_USR_EV_CFG_OFST, 0, 1 }, + { FR_AZ_RX_CFG_REG_OFST, 0, 1 }, + { FR_AZ_TX_CFG_REG_OFST, 0, 1 }, + { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 }, + { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 }, + { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 }, + { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 }, + { FR_AZ_DP_CTRL_REG_OFST, 0, 1 }, + { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1}, + { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1}, + { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1}, + { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1} +}; + +static const uint32_t __cs __siena_register_masks[] = { + 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, + 0x000103FF, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000, + 0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF, + 0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF, + 0x001FFFFF, 0x00000000, 0x00000000, 0x00000000, + 0x00000003, 0x00000000, 0x00000000, 0x00000000, + 0x000003FF, 0x00000000, 0x00000000, 0x00000000, + 0x00000FFF, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000 +}; + +static efx_register_set_t __cs __siena_tables[] = { + { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP, + FR_AZ_RX_FILTER_TBL0_ROWS }, + { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP, + FR_CZ_RX_MAC_FILTER_TBL0_ROWS }, + { FR_AZ_RX_DESC_PTR_TBL_OFST, + FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS }, + { FR_AZ_TX_DESC_PTR_TBL_OFST, + FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS }, + { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS }, + { FR_CZ_TX_FILTER_TBL0_OFST, + FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS }, + { FR_CZ_TX_MAC_FILTER_TBL0_OFST, + FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS } +}; + +static const uint32_t __cs __siena_table_masks[] = { + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF, + 0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000, + 0xFFFFFFFF, 0x0FFFFFFF, 0x01800000, 0x00000000, + 0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000, + 0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF, + 0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000, +}; + + __checkReturn int +siena_nic_register_test( + __in efx_nic_t *enp) +{ + efx_register_set_t *rsp; + const uint32_t *dwordp; + unsigned int nitems; + unsigned int count; + int rc; + + /* Fill out the register mask entries */ + EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks) + == EFX_ARRAY_SIZE(__siena_registers) * 4); + + nitems = EFX_ARRAY_SIZE(__siena_registers); + dwordp = __siena_register_masks; + for (count = 0; count < nitems; ++count) { + rsp = __siena_registers + count; + rsp->mask.eo_u32[0] = *dwordp++; + rsp->mask.eo_u32[1] = *dwordp++; + rsp->mask.eo_u32[2] = *dwordp++; + rsp->mask.eo_u32[3] = *dwordp++; + } + + /* Fill out the register table entries */ + EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks) + == EFX_ARRAY_SIZE(__siena_tables) * 4); + + nitems = EFX_ARRAY_SIZE(__siena_tables); + dwordp = __siena_table_masks; + for (count = 0; count < nitems; ++count) { + rsp = __siena_tables + count; + rsp->mask.eo_u32[0] = *dwordp++; + rsp->mask.eo_u32[1] = *dwordp++; + rsp->mask.eo_u32[2] = *dwordp++; + rsp->mask.eo_u32[3] = *dwordp++; + } + + if ((rc = efx_nic_test_registers(enp, __siena_registers, + EFX_ARRAY_SIZE(__siena_registers))) != 0) + goto fail1; + + if ((rc = efx_nic_test_tables(enp, __siena_tables, + EFX_PATTERN_BYTE_ALTERNATE, + EFX_ARRAY_SIZE(__siena_tables))) != 0) + goto fail2; + + if ((rc = efx_nic_test_tables(enp, __siena_tables, + EFX_PATTERN_BYTE_CHANGING, + EFX_ARRAY_SIZE(__siena_tables))) != 0) + goto fail3; + + if ((rc = efx_nic_test_tables(enp, __siena_tables, + EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0) + goto fail4; + + return (0); + +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#endif /* EFSYS_OPT_DIAG */ + +#endif /* EFSYS_OPT_SIENA */ diff --git a/sys/dev/sfxge/common/siena_nvram.c b/sys/dev/sfxge/common/siena_nvram.c new file mode 100644 index 000000000000..9cdd3add1d69 --- /dev/null +++ b/sys/dev/sfxge/common/siena_nvram.c @@ -0,0 +1,985 @@ +/*- + * Copyright 2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "efsys.h" +#include "efx.h" +#include "efx_types.h" +#include "efx_regs.h" +#include "efx_impl.h" + +#if EFSYS_OPT_SIENA + +#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM + + __checkReturn int +siena_nvram_partn_size( + __in efx_nic_t *enp, + __in unsigned int partn, + __out size_t *sizep) +{ + efx_mcdi_req_t req; + uint8_t payload[MAX(MC_CMD_NVRAM_INFO_IN_LEN, + MC_CMD_NVRAM_INFO_OUT_LEN)]; + int rc; + + if ((1 << partn) & ~enp->en_u.siena.enu_partn_mask) { + rc = ENOTSUP; + goto fail1; + } + + req.emr_cmd = MC_CMD_NVRAM_INFO; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_NVRAM_INFO_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_NVRAM_INFO_OUT_LEN; + + MCDI_IN_SET_DWORD(req, NVRAM_INFO_IN_TYPE, partn); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail2; + } + + if (req.emr_out_length_used < MC_CMD_NVRAM_INFO_OUT_LEN) { + rc = EMSGSIZE; + goto fail3; + } + + *sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_SIZE); + + return (0); + +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_nvram_partn_lock( + __in efx_nic_t *enp, + __in unsigned int partn) +{ + efx_mcdi_req_t req; + uint8_t payload[MC_CMD_NVRAM_UPDATE_START_IN_LEN]; + int rc; + + req.emr_cmd = MC_CMD_NVRAM_UPDATE_START; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_NVRAM_UPDATE_START_IN_LEN; + EFX_STATIC_ASSERT(MC_CMD_NVRAM_UPDATE_START_OUT_LEN == 0); + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_START_IN_TYPE, partn); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_nvram_partn_read( + __in efx_nic_t *enp, + __in unsigned int partn, + __in unsigned int offset, + __out_bcount(size) caddr_t data, + __in size_t size) +{ + efx_mcdi_req_t req; + uint8_t payload[MAX(MC_CMD_NVRAM_READ_IN_LEN, + MC_CMD_NVRAM_READ_OUT_LEN(SIENA_NVRAM_CHUNK))]; + size_t chunk; + int rc; + + while (size > 0) { + chunk = MIN(size, SIENA_NVRAM_CHUNK); + + req.emr_cmd = MC_CMD_NVRAM_READ; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_NVRAM_READ_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = + MC_CMD_NVRAM_READ_OUT_LEN(SIENA_NVRAM_CHUNK); + + MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_TYPE, partn); + MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_OFFSET, offset); + MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_LENGTH, chunk); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + if (req.emr_out_length_used < + MC_CMD_NVRAM_READ_OUT_LEN(chunk)) { + rc = EMSGSIZE; + goto fail2; + } + + memcpy(data, + MCDI_OUT2(req, uint8_t, NVRAM_READ_OUT_READ_BUFFER), + chunk); + + size -= chunk; + data += chunk; + offset += chunk; + } + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_nvram_partn_erase( + __in efx_nic_t *enp, + __in unsigned int partn, + __in unsigned int offset, + __in size_t size) +{ + efx_mcdi_req_t req; + uint8_t payload[MC_CMD_NVRAM_ERASE_IN_LEN]; + int rc; + + req.emr_cmd = MC_CMD_NVRAM_ERASE; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_NVRAM_ERASE_IN_LEN; + EFX_STATIC_ASSERT(MC_CMD_NVRAM_ERASE_OUT_LEN == 0); + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_TYPE, partn); + MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_OFFSET, offset); + MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_LENGTH, size); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_nvram_partn_write( + __in efx_nic_t *enp, + __in unsigned int partn, + __in unsigned int offset, + __out_bcount(size) caddr_t data, + __in size_t size) +{ + efx_mcdi_req_t req; + uint8_t payload[MC_CMD_NVRAM_WRITE_IN_LEN(SIENA_NVRAM_CHUNK)]; + size_t chunk; + int rc; + + while (size > 0) { + chunk = MIN(size, SIENA_NVRAM_CHUNK); + + req.emr_cmd = MC_CMD_NVRAM_WRITE; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_NVRAM_WRITE_IN_LEN(chunk); + EFX_STATIC_ASSERT(MC_CMD_NVRAM_WRITE_OUT_LEN == 0); + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_TYPE, partn); + MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_OFFSET, offset); + MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_LENGTH, chunk); + + memcpy(MCDI_IN2(req, uint8_t, NVRAM_WRITE_IN_WRITE_BUFFER), + data, chunk); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + size -= chunk; + data += chunk; + offset += chunk; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + void +siena_nvram_partn_unlock( + __in efx_nic_t *enp, + __in unsigned int partn) +{ + efx_mcdi_req_t req; + uint8_t payload[MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN]; + uint32_t reboot; + int rc; + + req.emr_cmd = MC_CMD_NVRAM_UPDATE_FINISH; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN; + EFX_STATIC_ASSERT(MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN == 0); + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + /* + * Reboot into the new image only for PHYs. The driver has to + * explicitly cope with an MC reboot after a firmware update. + */ + reboot = (partn == MC_CMD_NVRAM_TYPE_PHY_PORT0 || + partn == MC_CMD_NVRAM_TYPE_PHY_PORT1 || + partn == MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO); + + MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_IN_TYPE, partn); + MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_IN_REBOOT, reboot); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + return; + +fail1: + EFSYS_PROBE1(fail1, int, rc); +} + +#endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */ + +#if EFSYS_OPT_NVRAM + +typedef struct siena_parttbl_entry_s { + unsigned int partn; + unsigned int port; + efx_nvram_type_t nvtype; +} siena_parttbl_entry_t; + +static siena_parttbl_entry_t siena_parttbl[] = { + {MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO, 1, EFX_NVRAM_NULLPHY}, + {MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO, 2, EFX_NVRAM_NULLPHY}, + {MC_CMD_NVRAM_TYPE_MC_FW, 1, EFX_NVRAM_MC_FIRMWARE}, + {MC_CMD_NVRAM_TYPE_MC_FW, 2, EFX_NVRAM_MC_FIRMWARE}, + {MC_CMD_NVRAM_TYPE_MC_FW_BACKUP, 1, EFX_NVRAM_MC_GOLDEN}, + {MC_CMD_NVRAM_TYPE_MC_FW_BACKUP, 2, EFX_NVRAM_MC_GOLDEN}, + {MC_CMD_NVRAM_TYPE_EXP_ROM, 1, EFX_NVRAM_BOOTROM}, + {MC_CMD_NVRAM_TYPE_EXP_ROM, 2, EFX_NVRAM_BOOTROM}, + {MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT0, 1, EFX_NVRAM_BOOTROM_CFG}, + {MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1, 2, EFX_NVRAM_BOOTROM_CFG}, + {MC_CMD_NVRAM_TYPE_PHY_PORT0, 1, EFX_NVRAM_PHY}, + {MC_CMD_NVRAM_TYPE_PHY_PORT1, 2, EFX_NVRAM_PHY}, + {0, 0, 0}, +}; + +static __checkReturn siena_parttbl_entry_t * +siena_parttbl_entry( + __in efx_nic_t *enp, + __in efx_nvram_type_t type) +{ + efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip); + siena_parttbl_entry_t *entry; + + EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES); + + for (entry = siena_parttbl; entry->port > 0; ++entry) { + if (entry->port == emip->emi_port && entry->nvtype == type) + return (entry); + } + + return (NULL); +} + +#if EFSYS_OPT_DIAG + + __checkReturn int +siena_nvram_test( + __in efx_nic_t *enp) +{ + efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip); + siena_parttbl_entry_t *entry; + efx_mcdi_req_t req; + uint8_t payload[MAX(MC_CMD_NVRAM_TEST_IN_LEN, + MC_CMD_NVRAM_TEST_OUT_LEN)]; + int result; + int rc; + + req.emr_cmd = MC_CMD_NVRAM_TEST; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_NVRAM_TEST_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_NVRAM_TEST_OUT_LEN; + + /* + * Iterate over the list of supported partition types + * applicable to *this* port + */ + for (entry = siena_parttbl; entry->port > 0; ++entry) { + if (entry->port != emip->emi_port || + !(enp->en_u.siena.enu_partn_mask & (1 << entry->partn))) + continue; + + MCDI_IN_SET_DWORD(req, NVRAM_TEST_IN_TYPE, entry->partn); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + if (req.emr_out_length_used < MC_CMD_NVRAM_TEST_OUT_LEN) { + rc = EMSGSIZE; + goto fail2; + } + + result = MCDI_OUT_DWORD(req, NVRAM_TEST_OUT_RESULT); + if (result == MC_CMD_NVRAM_TEST_FAIL) { + + EFSYS_PROBE1(nvram_test_failure, int, entry->partn); + + rc = (EINVAL); + goto fail3; + } + } + + return (0); + +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#endif /* EFSYS_OPT_DIAG */ + + __checkReturn int +siena_nvram_size( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __out size_t *sizep) +{ + siena_parttbl_entry_t *entry; + int rc; + + if ((entry = siena_parttbl_entry(enp, type)) == NULL) { + rc = ENOTSUP; + goto fail1; + } + + if ((rc = siena_nvram_partn_size(enp, entry->partn, sizep)) != 0) + goto fail2; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + *sizep = 0; + + return (rc); +} + +#define SIENA_DYNAMIC_CFG_SIZE(_nitems) \ + (sizeof (siena_mc_dynamic_config_hdr_t) + ((_nitems) * \ + sizeof (((siena_mc_dynamic_config_hdr_t *)NULL)->fw_version[0]))) + + __checkReturn int +siena_nvram_get_dynamic_cfg( + __in efx_nic_t *enp, + __in unsigned int partn, + __in boolean_t vpd, + __out siena_mc_dynamic_config_hdr_t **dcfgp, + __out size_t *sizep) +{ + siena_mc_dynamic_config_hdr_t *dcfg; + size_t size; + uint8_t cksum; + unsigned int vpd_offset; + unsigned int vpd_length; + unsigned int hdr_length; + unsigned int nversions; + unsigned int pos; + unsigned int region; + int rc; + + EFSYS_ASSERT(partn == MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0 || + partn == MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1); + + /* + * Allocate sufficient memory for the entire dynamiccfg area, even + * if we're not actually going to read in the VPD. + */ + if ((rc = siena_nvram_partn_size(enp, partn, &size)) != 0) + goto fail1; + + EFSYS_KMEM_ALLOC(enp->en_esip, size, dcfg); + if (dcfg == NULL) { + rc = ENOMEM; + goto fail2; + } + + if ((rc = siena_nvram_partn_read(enp, partn, 0, + (caddr_t)dcfg, SIENA_NVRAM_CHUNK)) != 0) + goto fail3; + + /* Verify the magic */ + if (EFX_DWORD_FIELD(dcfg->magic, EFX_DWORD_0) + != SIENA_MC_DYNAMIC_CONFIG_MAGIC) + goto invalid1; + + /* All future versions of the structure must be backwards compatable */ + EFX_STATIC_ASSERT(SIENA_MC_DYNAMIC_CONFIG_VERSION == 0); + + hdr_length = EFX_WORD_FIELD(dcfg->length, EFX_WORD_0); + nversions = EFX_DWORD_FIELD(dcfg->num_fw_version_items, EFX_DWORD_0); + vpd_offset = EFX_DWORD_FIELD(dcfg->dynamic_vpd_offset, EFX_DWORD_0); + vpd_length = EFX_DWORD_FIELD(dcfg->dynamic_vpd_length, EFX_DWORD_0); + + /* Verify the hdr doesn't overflow the partn size */ + if (hdr_length > size || vpd_offset > size || vpd_length > size || + vpd_length + vpd_offset > size) + goto invalid2; + + /* Verify the header has room for all it's versions */ + if (hdr_length < SIENA_DYNAMIC_CFG_SIZE(0) || + hdr_length < SIENA_DYNAMIC_CFG_SIZE(nversions)) + goto invalid3; + + /* + * Read the remaining portion of the dcfg, either including + * the whole of VPD (there is no vpd length in this structure, + * so we have to parse each tag), or just the dcfg header itself + */ + region = vpd ? vpd_offset + vpd_length : hdr_length; + if (region > SIENA_NVRAM_CHUNK) { + if ((rc = siena_nvram_partn_read(enp, partn, SIENA_NVRAM_CHUNK, + (caddr_t)dcfg + SIENA_NVRAM_CHUNK, + region - SIENA_NVRAM_CHUNK)) != 0) + goto fail4; + } + + /* Verify checksum */ + cksum = 0; + for (pos = 0; pos < hdr_length; pos++) + cksum += ((uint8_t *)dcfg)[pos]; + if (cksum != 0) + goto invalid4; + + goto done; + +invalid4: + EFSYS_PROBE(invalid4); +invalid3: + EFSYS_PROBE(invalid3); +invalid2: + EFSYS_PROBE(invalid2); +invalid1: + EFSYS_PROBE(invalid1); + + /* + * Construct a new "null" dcfg, with an empty version vector, + * and an empty VPD chunk trailing. This has the neat side effect + * of testing the exception paths in the write path. + */ + EFX_POPULATE_DWORD_1(dcfg->magic, + EFX_DWORD_0, SIENA_MC_DYNAMIC_CONFIG_MAGIC); + EFX_POPULATE_WORD_1(dcfg->length, EFX_WORD_0, sizeof (*dcfg)); + EFX_POPULATE_BYTE_1(dcfg->version, EFX_BYTE_0, + SIENA_MC_DYNAMIC_CONFIG_VERSION); + EFX_POPULATE_DWORD_1(dcfg->dynamic_vpd_offset, + EFX_DWORD_0, sizeof (*dcfg)); + EFX_POPULATE_DWORD_1(dcfg->dynamic_vpd_length, EFX_DWORD_0, 0); + EFX_POPULATE_DWORD_1(dcfg->num_fw_version_items, EFX_DWORD_0, 0); + +done: + *dcfgp = dcfg; + *sizep = size; + + return (0); + +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); + + EFSYS_KMEM_FREE(enp->en_esip, size, dcfg); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +static __checkReturn int +siena_nvram_get_subtype( + __in efx_nic_t *enp, + __in unsigned int partn, + __out uint32_t *subtypep) +{ + efx_mcdi_req_t req; + uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LEN]; + efx_word_t *fw_list; + int rc; + + req.emr_cmd = MC_CMD_GET_BOARD_CFG; + EFX_STATIC_ASSERT(MC_CMD_GET_BOARD_CFG_IN_LEN == 0); + req.emr_in_buf = NULL; + req.emr_in_length = 0; + req.emr_out_buf = outbuf; + req.emr_out_length = sizeof (outbuf); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + if (req.emr_out_length_used < MC_CMD_GET_BOARD_CFG_OUT_LEN) { + rc = EMSGSIZE; + goto fail2; + } + + fw_list = MCDI_OUT2(req, efx_word_t, + GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST); + *subtypep = EFX_WORD_FIELD(fw_list[partn], EFX_WORD_0); + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_nvram_get_version( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __out uint32_t *subtypep, + __out_ecount(4) uint16_t version[4]) +{ + siena_mc_dynamic_config_hdr_t *dcfg; + siena_parttbl_entry_t *entry; + unsigned int dcfg_partn; + unsigned int partn; + int rc; + + if ((entry = siena_parttbl_entry(enp, type)) == NULL) { + rc = ENOTSUP; + goto fail1; + } + partn = entry->partn; + + if ((1 << partn) & ~enp->en_u.siena.enu_partn_mask) { + rc = ENOTSUP; + goto fail2; + } + + if ((rc = siena_nvram_get_subtype(enp, partn, subtypep)) != 0) + goto fail3; + + /* + * Some partitions are accessible from both ports (for instance BOOTROM) + * Find the highest version reported by all dcfg structures on ports + * that have access to this partition. + */ + version[0] = version[1] = version[2] = version[3] = 0; + for (entry = siena_parttbl; entry->port > 0; ++entry) { + unsigned int nitems; + uint16_t temp[4]; + size_t length; + + if (entry->partn != partn) + continue; + + dcfg_partn = (entry->port == 1) + ? MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0 + : MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1; + /* + * Ingore missing partitions on port 2, assuming they're due + * to to running on a single port part. + */ + if ((1 << dcfg_partn) & ~enp->en_u.siena.enu_partn_mask) { + if (entry->port == 2) + continue; + } + + if ((rc = siena_nvram_get_dynamic_cfg(enp, dcfg_partn, + B_FALSE, &dcfg, &length)) != 0) + goto fail4; + + nitems = EFX_DWORD_FIELD(dcfg->num_fw_version_items, + EFX_DWORD_0); + if (nitems < entry->partn) + goto done; + + temp[0] = EFX_WORD_FIELD(dcfg->fw_version[partn].version_w, + EFX_WORD_0); + temp[1] = EFX_WORD_FIELD(dcfg->fw_version[partn].version_x, + EFX_WORD_0); + temp[2] = EFX_WORD_FIELD(dcfg->fw_version[partn].version_y, + EFX_WORD_0); + temp[3] = EFX_WORD_FIELD(dcfg->fw_version[partn].version_z, + EFX_WORD_0); + if (memcmp(version, temp, sizeof (temp)) < 0) + memcpy(version, temp, sizeof (temp)); + + done: + EFSYS_KMEM_FREE(enp->en_esip, length, dcfg); + } + + return (0); + +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_nvram_rw_start( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __out size_t *chunk_sizep) +{ + siena_parttbl_entry_t *entry; + int rc; + + if ((entry = siena_parttbl_entry(enp, type)) == NULL) { + rc = ENOTSUP; + goto fail1; + } + + if ((rc = siena_nvram_partn_lock(enp, entry->partn)) != 0) + goto fail2; + + if (chunk_sizep != NULL) + *chunk_sizep = SIENA_NVRAM_CHUNK; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_nvram_read_chunk( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __in unsigned int offset, + __out_bcount(size) caddr_t data, + __in size_t size) +{ + siena_parttbl_entry_t *entry; + int rc; + + if ((entry = siena_parttbl_entry(enp, type)) == NULL) { + rc = ENOTSUP; + goto fail1; + } + + if ((rc = siena_nvram_partn_read(enp, entry->partn, + offset, data, size)) != 0) + goto fail2; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_nvram_erase( + __in efx_nic_t *enp, + __in efx_nvram_type_t type) +{ + siena_parttbl_entry_t *entry; + size_t size; + int rc; + + if ((entry = siena_parttbl_entry(enp, type)) == NULL) { + rc = ENOTSUP; + goto fail1; + } + + if ((rc = siena_nvram_partn_size(enp, entry->partn, &size)) != 0) + goto fail2; + + if ((rc = siena_nvram_partn_erase(enp, entry->partn, 0, size)) != 0) + goto fail3; + + return (0); + +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_nvram_write_chunk( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __in unsigned int offset, + __in_bcount(size) caddr_t data, + __in size_t size) +{ + siena_parttbl_entry_t *entry; + int rc; + + if ((entry = siena_parttbl_entry(enp, type)) == NULL) { + rc = ENOTSUP; + goto fail1; + } + + if ((rc = siena_nvram_partn_write(enp, entry->partn, + offset, data, size)) != 0) + goto fail2; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + void +siena_nvram_rw_finish( + __in efx_nic_t *enp, + __in efx_nvram_type_t type) +{ + siena_parttbl_entry_t *entry; + + if ((entry = siena_parttbl_entry(enp, type)) != NULL) + siena_nvram_partn_unlock(enp, entry->partn); +} + + __checkReturn int +siena_nvram_set_version( + __in efx_nic_t *enp, + __in efx_nvram_type_t type, + __out uint16_t version[4]) +{ + siena_mc_dynamic_config_hdr_t *dcfg = NULL; + siena_parttbl_entry_t *entry; + unsigned int dcfg_partn; + size_t partn_size; + unsigned int hdr_length; + unsigned int vpd_length; + unsigned int vpd_offset; + unsigned int nitems; + unsigned int required_hdr_length; + unsigned int pos; + uint8_t cksum; + uint32_t subtype; + size_t length; + int rc; + + if ((entry = siena_parttbl_entry(enp, type)) == NULL) { + rc = ENOTSUP; + goto fail1; + } + + dcfg_partn = (entry->port == 1) + ? MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0 + : MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1; + + if ((rc = siena_nvram_partn_size(enp, dcfg_partn, &partn_size)) != 0) + goto fail2; + + if ((rc = siena_nvram_partn_lock(enp, dcfg_partn)) != 0) + goto fail2; + + if ((rc = siena_nvram_get_dynamic_cfg(enp, dcfg_partn, + B_TRUE, &dcfg, &length)) != 0) + goto fail3; + + hdr_length = EFX_WORD_FIELD(dcfg->length, EFX_WORD_0); + nitems = EFX_DWORD_FIELD(dcfg->num_fw_version_items, EFX_DWORD_0); + vpd_length = EFX_DWORD_FIELD(dcfg->dynamic_vpd_length, EFX_DWORD_0); + vpd_offset = EFX_DWORD_FIELD(dcfg->dynamic_vpd_offset, EFX_DWORD_0); + + /* + * NOTE: This function will blatt any fields trailing the version + * vector, or the VPD chunk. + */ + required_hdr_length = SIENA_DYNAMIC_CFG_SIZE(entry->partn + 1); + if (required_hdr_length + vpd_length > length) { + rc = ENOSPC; + goto fail4; + } + + if (vpd_offset < required_hdr_length) { + (void) memmove((caddr_t)dcfg + required_hdr_length, + (caddr_t)dcfg + vpd_offset, vpd_length); + vpd_offset = required_hdr_length; + EFX_POPULATE_DWORD_1(dcfg->dynamic_vpd_offset, + EFX_DWORD_0, vpd_offset); + } + + if (hdr_length < required_hdr_length) { + (void) memset((caddr_t)dcfg + hdr_length, 0, + required_hdr_length - hdr_length); + hdr_length = required_hdr_length; + EFX_POPULATE_WORD_1(dcfg->length, + EFX_WORD_0, hdr_length); + } + + /* Get the subtype to insert into the fw_subtype array */ + if ((rc = siena_nvram_get_subtype(enp, entry->partn, &subtype)) != 0) + goto fail5; + + /* Fill out the new version */ + EFX_POPULATE_DWORD_1(dcfg->fw_version[entry->partn].fw_subtype, + EFX_DWORD_0, subtype); + EFX_POPULATE_WORD_1(dcfg->fw_version[entry->partn].version_w, + EFX_WORD_0, version[0]); + EFX_POPULATE_WORD_1(dcfg->fw_version[entry->partn].version_x, + EFX_WORD_0, version[1]); + EFX_POPULATE_WORD_1(dcfg->fw_version[entry->partn].version_y, + EFX_WORD_0, version[2]); + EFX_POPULATE_WORD_1(dcfg->fw_version[entry->partn].version_z, + EFX_WORD_0, version[3]); + + /* Update the version count */ + if (nitems < entry->partn + 1) { + nitems = entry->partn + 1; + EFX_POPULATE_DWORD_1(dcfg->num_fw_version_items, + EFX_DWORD_0, nitems); + } + + /* Update the checksum */ + cksum = 0; + for (pos = 0; pos < hdr_length; pos++) + cksum += ((uint8_t *)dcfg)[pos]; + dcfg->csum.eb_u8[0] -= cksum; + + /* Erase and write the new partition */ + if ((rc = siena_nvram_partn_erase(enp, dcfg_partn, 0, partn_size)) != 0) + goto fail6; + + /* Write out the new structure to nvram */ + if ((rc = siena_nvram_partn_write(enp, dcfg_partn, 0, + (caddr_t)dcfg, vpd_offset + vpd_length)) != 0) + goto fail7; + + EFSYS_KMEM_FREE(enp->en_esip, length, dcfg); + + siena_nvram_partn_unlock(enp, dcfg_partn); + + return (0); + +fail7: + EFSYS_PROBE(fail7); +fail6: + EFSYS_PROBE(fail6); +fail5: + EFSYS_PROBE(fail5); +fail4: + EFSYS_PROBE(fail4); + + EFSYS_KMEM_FREE(enp->en_esip, length, dcfg); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +#endif /* EFSYS_OPT_NVRAM */ + +#endif /* EFSYS_OPT_SIENA */ diff --git a/sys/dev/sfxge/common/siena_phy.c b/sys/dev/sfxge/common/siena_phy.c new file mode 100644 index 000000000000..7eb846821574 --- /dev/null +++ b/sys/dev/sfxge/common/siena_phy.c @@ -0,0 +1,857 @@ +/*- + * Copyright 2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "efsys.h" +#include "efx.h" +#include "efx_impl.h" + +#if EFSYS_OPT_SIENA + +static void +siena_phy_decode_cap( + __in uint32_t mcdi_cap, + __out uint32_t *maskp) +{ + uint32_t mask; + + mask = 0; + if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10HDX_LBN)) + mask |= (1 << EFX_PHY_CAP_10HDX); + if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10FDX_LBN)) + mask |= (1 << EFX_PHY_CAP_10FDX); + if (mcdi_cap & (1 << MC_CMD_PHY_CAP_100HDX_LBN)) + mask |= (1 << EFX_PHY_CAP_100HDX); + if (mcdi_cap & (1 << MC_CMD_PHY_CAP_100FDX_LBN)) + mask |= (1 << EFX_PHY_CAP_100FDX); + if (mcdi_cap & (1 << MC_CMD_PHY_CAP_1000HDX_LBN)) + mask |= (1 << EFX_PHY_CAP_1000HDX); + if (mcdi_cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN)) + mask |= (1 << EFX_PHY_CAP_1000FDX); + if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN)) + mask |= (1 << EFX_PHY_CAP_10000FDX); + if (mcdi_cap & (1 << MC_CMD_PHY_CAP_PAUSE_LBN)) + mask |= (1 << EFX_PHY_CAP_PAUSE); + if (mcdi_cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN)) + mask |= (1 << EFX_PHY_CAP_ASYM); + if (mcdi_cap & (1 << MC_CMD_PHY_CAP_AN_LBN)) + mask |= (1 << EFX_PHY_CAP_AN); + + *maskp = mask; +} + +static void +siena_phy_decode_link_mode( + __in efx_nic_t *enp, + __in uint32_t link_flags, + __in unsigned int speed, + __in unsigned int fcntl, + __out efx_link_mode_t *link_modep, + __out unsigned int *fcntlp) +{ + boolean_t fd = !!(link_flags & + (1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN)); + boolean_t up = !!(link_flags & + (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN)); + + _NOTE(ARGUNUSED(enp)) + + if (!up) + *link_modep = EFX_LINK_DOWN; + else if (speed == 10000 && fd) + *link_modep = EFX_LINK_10000FDX; + else if (speed == 1000) + *link_modep = fd ? EFX_LINK_1000FDX : EFX_LINK_1000HDX; + else if (speed == 100) + *link_modep = fd ? EFX_LINK_100FDX : EFX_LINK_100HDX; + else if (speed == 10) + *link_modep = fd ? EFX_LINK_10FDX : EFX_LINK_10HDX; + else + *link_modep = EFX_LINK_UNKNOWN; + + if (fcntl == MC_CMD_FCNTL_OFF) + *fcntlp = 0; + else if (fcntl == MC_CMD_FCNTL_RESPOND) + *fcntlp = EFX_FCNTL_RESPOND; + else if (fcntl == MC_CMD_FCNTL_BIDIR) + *fcntlp = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE; + else { + EFSYS_PROBE1(mc_pcol_error, int, fcntl); + *fcntlp = 0; + } +} + + void +siena_phy_link_ev( + __in efx_nic_t *enp, + __in efx_qword_t *eqp, + __out efx_link_mode_t *link_modep) +{ + efx_port_t *epp = &(enp->en_port); + unsigned int link_flags; + unsigned int speed; + unsigned int fcntl; + efx_link_mode_t link_mode; + uint32_t lp_cap_mask; + + /* + * Convert the LINKCHANGE speed enumeration into mbit/s, in the + * same way as GET_LINK encodes the speed + */ + switch (MCDI_EV_FIELD(*eqp, LINKCHANGE_SPEED)) { + case MCDI_EVENT_LINKCHANGE_SPEED_100M: + speed = 100; + break; + case MCDI_EVENT_LINKCHANGE_SPEED_1G: + speed = 1000; + break; + case MCDI_EVENT_LINKCHANGE_SPEED_10G: + speed = 10000; + break; + default: + speed = 0; + break; + } + + link_flags = MCDI_EV_FIELD(*eqp, LINKCHANGE_LINK_FLAGS); + siena_phy_decode_link_mode(enp, link_flags, speed, + MCDI_EV_FIELD(*eqp, LINKCHANGE_FCNTL), + &link_mode, &fcntl); + siena_phy_decode_cap(MCDI_EV_FIELD(*eqp, LINKCHANGE_LP_CAP), + &lp_cap_mask); + + /* + * It's safe to update ep_lp_cap_mask without the driver's port lock + * because presumably any concurrently running efx_port_poll() is + * only going to arrive at the same value. + * + * ep_fcntl has two meanings. It's either the link common fcntl + * (if the PHY supports AN), or it's the forced link state. If + * the former, it's safe to update the value for the same reason as + * for ep_lp_cap_mask. If the latter, then just ignore the value, + * because we can race with efx_mac_fcntl_set(). + */ + epp->ep_lp_cap_mask = lp_cap_mask; + if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN)) + epp->ep_fcntl = fcntl; + + *link_modep = link_mode; +} + + __checkReturn int +siena_phy_power( + __in efx_nic_t *enp, + __in boolean_t power) +{ + int rc; + + if (!power) + return (0); + + /* Check if the PHY is a zombie */ + if ((rc = siena_phy_verify(enp)) != 0) + goto fail1; + + enp->en_reset_flags |= EFX_RESET_PHY; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_phy_get_link( + __in efx_nic_t *enp, + __out siena_link_state_t *slsp) +{ + efx_mcdi_req_t req; + uint8_t outbuf[MC_CMD_GET_LINK_OUT_LEN]; + int rc; + + req.emr_cmd = MC_CMD_GET_LINK; + EFX_STATIC_ASSERT(MC_CMD_GET_LINK_IN_LEN == 0); + req.emr_in_buf = NULL; + req.emr_in_length = 0; + req.emr_out_buf = outbuf; + req.emr_out_length = sizeof (outbuf); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + if (req.emr_out_length_used < MC_CMD_GET_LINK_OUT_LEN) { + rc = EMSGSIZE; + goto fail2; + } + + siena_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_CAP), + &slsp->sls_adv_cap_mask); + siena_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_LP_CAP), + &slsp->sls_lp_cap_mask); + + siena_phy_decode_link_mode(enp, MCDI_OUT_DWORD(req, GET_LINK_OUT_FLAGS), + MCDI_OUT_DWORD(req, GET_LINK_OUT_LINK_SPEED), + MCDI_OUT_DWORD(req, GET_LINK_OUT_FCNTL), + &slsp->sls_link_mode, &slsp->sls_fcntl); + +#if EFSYS_OPT_LOOPBACK + /* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */ + EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF); + EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA); + EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC); + EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII); + EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS); + EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI); + EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII); + EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII); + EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR); + EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI); + EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR); + EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR); + EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR); + EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR); + EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY); + EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS); + EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS); + EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD); + + slsp->sls_loopback = MCDI_OUT_DWORD(req, GET_LINK_OUT_LOOPBACK_MODE); +#endif /* EFSYS_OPT_LOOPBACK */ + + slsp->sls_mac_up = MCDI_OUT_DWORD(req, GET_LINK_OUT_MAC_FAULT) == 0; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_phy_reconfigure( + __in efx_nic_t *enp) +{ + efx_port_t *epp = &(enp->en_port); + efx_mcdi_req_t req; + uint8_t payload[MAX(MC_CMD_SET_ID_LED_IN_LEN, + MC_CMD_SET_LINK_IN_LEN)]; + uint32_t cap_mask; + unsigned int led_mode; + unsigned int speed; + int rc; + + req.emr_cmd = MC_CMD_SET_LINK; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_SET_LINK_IN_LEN; + EFX_STATIC_ASSERT(MC_CMD_SET_LINK_OUT_LEN == 0); + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + cap_mask = epp->ep_adv_cap_mask; + MCDI_IN_POPULATE_DWORD_10(req, SET_LINK_IN_CAP, + PHY_CAP_10HDX, (cap_mask >> EFX_PHY_CAP_10HDX) & 0x1, + PHY_CAP_10FDX, (cap_mask >> EFX_PHY_CAP_10FDX) & 0x1, + PHY_CAP_100HDX, (cap_mask >> EFX_PHY_CAP_100HDX) & 0x1, + PHY_CAP_100FDX, (cap_mask >> EFX_PHY_CAP_100FDX) & 0x1, + PHY_CAP_1000HDX, (cap_mask >> EFX_PHY_CAP_1000HDX) & 0x1, + PHY_CAP_1000FDX, (cap_mask >> EFX_PHY_CAP_1000FDX) & 0x1, + PHY_CAP_10000FDX, (cap_mask >> EFX_PHY_CAP_10000FDX) & 0x1, + PHY_CAP_PAUSE, (cap_mask >> EFX_PHY_CAP_PAUSE) & 0x1, + PHY_CAP_ASYM, (cap_mask >> EFX_PHY_CAP_ASYM) & 0x1, + PHY_CAP_AN, (cap_mask >> EFX_PHY_CAP_AN) & 0x1); + +#if EFSYS_OPT_LOOPBACK + MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_MODE, + epp->ep_loopback_type); + switch (epp->ep_loopback_link_mode) { + case EFX_LINK_100FDX: + speed = 100; + break; + case EFX_LINK_1000FDX: + speed = 1000; + break; + case EFX_LINK_10000FDX: + speed = 10000; + break; + default: + speed = 0; + } +#else + MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_MODE, MC_CMD_LOOPBACK_NONE); + speed = 0; +#endif /* EFSYS_OPT_LOOPBACK */ + MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_SPEED, speed); + +#if EFSYS_OPT_PHY_FLAGS + MCDI_IN_SET_DWORD(req, SET_LINK_IN_FLAGS, epp->ep_phy_flags); +#else + MCDI_IN_SET_DWORD(req, SET_LINK_IN_FLAGS, 0); +#endif /* EFSYS_OPT_PHY_FLAGS */ + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + /* And set the blink mode */ + req.emr_cmd = MC_CMD_SET_ID_LED; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_SET_ID_LED_IN_LEN; + EFX_STATIC_ASSERT(MC_CMD_SET_ID_LED_OUT_LEN == 0); + req.emr_out_buf = NULL; + req.emr_out_length = 0; + +#if EFSYS_OPT_PHY_LED_CONTROL + switch (epp->ep_phy_led_mode) { + case EFX_PHY_LED_DEFAULT: + led_mode = MC_CMD_LED_DEFAULT; + break; + case EFX_PHY_LED_OFF: + led_mode = MC_CMD_LED_OFF; + break; + case EFX_PHY_LED_ON: + led_mode = MC_CMD_LED_ON; + break; + default: + EFSYS_ASSERT(0); + led_mode = MC_CMD_LED_DEFAULT; + } + + MCDI_IN_SET_DWORD(req, SET_ID_LED_IN_STATE, led_mode); +#else + MCDI_IN_SET_DWORD(req, SET_ID_LED_IN_STATE, MC_CMD_LED_DEFAULT); +#endif /* EFSYS_OPT_PHY_LED_CONTROL */ + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail2; + } + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_phy_verify( + __in efx_nic_t *enp) +{ + efx_mcdi_req_t req; + uint8_t outbuf[MC_CMD_GET_PHY_STATE_OUT_LEN]; + uint32_t state; + int rc; + + req.emr_cmd = MC_CMD_GET_PHY_STATE; + EFX_STATIC_ASSERT(MC_CMD_GET_PHY_STATE_IN_LEN == 0); + req.emr_in_buf = NULL; + req.emr_in_length = 0; + req.emr_out_buf = outbuf; + req.emr_out_length = sizeof (outbuf); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + if (req.emr_out_length_used < MC_CMD_GET_PHY_STATE_OUT_LEN) { + rc = EMSGSIZE; + goto fail2; + } + + state = MCDI_OUT_DWORD(req, GET_PHY_STATE_OUT_STATE); + if (state != MC_CMD_PHY_STATE_OK) { + if (state != MC_CMD_PHY_STATE_ZOMBIE) + EFSYS_PROBE1(mc_pcol_error, int, state); + rc = ENOTACTIVE; + goto fail3; + } + + return (0); + +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_phy_oui_get( + __in efx_nic_t *enp, + __out uint32_t *ouip) +{ + _NOTE(ARGUNUSED(enp, ouip)) + + return (ENOTSUP); +} + +#if EFSYS_OPT_PHY_STATS + +#define SIENA_SIMPLE_STAT_SET(_vmask, _esmp, _smask, _stat, \ + _mc_record, _efx_record) \ + if ((_vmask) & (1ULL << (_mc_record))) { \ + (_smask) |= (1ULL << (_efx_record)); \ + if ((_stat) != NULL && !EFSYS_MEM_IS_NULL(_esmp)) { \ + efx_dword_t dword; \ + EFSYS_MEM_READD(_esmp, (_mc_record) * 4, &dword);\ + (_stat)[_efx_record] = \ + EFX_DWORD_FIELD(dword, EFX_DWORD_0); \ + } \ + } + +#define SIENA_SIMPLE_STAT_SET2(_vmask, _esmp, _smask, _stat, _record) \ + SIENA_SIMPLE_STAT_SET(_vmask, _esmp, _smask, _stat, \ + MC_CMD_ ## _record, \ + EFX_PHY_STAT_ ## _record) + + void +siena_phy_decode_stats( + __in efx_nic_t *enp, + __in uint32_t vmask, + __in_opt efsys_mem_t *esmp, + __out_opt uint64_t *smaskp, + __out_ecount_opt(EFX_PHY_NSTATS) uint32_t *stat) +{ + uint64_t smask = 0; + + _NOTE(ARGUNUSED(enp)) + + SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, OUI); + SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, PMA_PMD_LINK_UP); + SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, PMA_PMD_RX_FAULT); + SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, PMA_PMD_TX_FAULT); + + if (vmask & (1 << MC_CMD_PMA_PMD_SIGNAL)) { + smask |= ((1ULL << EFX_PHY_STAT_PMA_PMD_SIGNAL_A) | + (1ULL << EFX_PHY_STAT_PMA_PMD_SIGNAL_B) | + (1ULL << EFX_PHY_STAT_PMA_PMD_SIGNAL_C) | + (1ULL << EFX_PHY_STAT_PMA_PMD_SIGNAL_D)); + if (stat != NULL && esmp != NULL && !EFSYS_MEM_IS_NULL(esmp)) { + efx_dword_t dword; + uint32_t sig; + EFSYS_MEM_READD(esmp, 4 * MC_CMD_PMA_PMD_SIGNAL, + &dword); + sig = EFX_DWORD_FIELD(dword, EFX_DWORD_0); + stat[EFX_PHY_STAT_PMA_PMD_SIGNAL_A] = (sig >> 1) & 1; + stat[EFX_PHY_STAT_PMA_PMD_SIGNAL_B] = (sig >> 2) & 1; + stat[EFX_PHY_STAT_PMA_PMD_SIGNAL_C] = (sig >> 3) & 1; + stat[EFX_PHY_STAT_PMA_PMD_SIGNAL_D] = (sig >> 4) & 1; + } + } + + SIENA_SIMPLE_STAT_SET(vmask, esmp, smask, stat, MC_CMD_PMA_PMD_SNR_A, + EFX_PHY_STAT_SNR_A); + SIENA_SIMPLE_STAT_SET(vmask, esmp, smask, stat, MC_CMD_PMA_PMD_SNR_B, + EFX_PHY_STAT_SNR_B); + SIENA_SIMPLE_STAT_SET(vmask, esmp, smask, stat, MC_CMD_PMA_PMD_SNR_C, + EFX_PHY_STAT_SNR_C); + SIENA_SIMPLE_STAT_SET(vmask, esmp, smask, stat, MC_CMD_PMA_PMD_SNR_D, + EFX_PHY_STAT_SNR_D); + + SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, PCS_LINK_UP); + SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, PCS_RX_FAULT); + SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, PCS_TX_FAULT); + SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, PCS_BER); + SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, PCS_BLOCK_ERRORS); + + SIENA_SIMPLE_STAT_SET(vmask, esmp, smask, stat, MC_CMD_PHYXS_LINK_UP, + EFX_PHY_STAT_PHY_XS_LINK_UP); + SIENA_SIMPLE_STAT_SET(vmask, esmp, smask, stat, MC_CMD_PHYXS_RX_FAULT, + EFX_PHY_STAT_PHY_XS_RX_FAULT); + SIENA_SIMPLE_STAT_SET(vmask, esmp, smask, stat, MC_CMD_PHYXS_TX_FAULT, + EFX_PHY_STAT_PHY_XS_TX_FAULT); + SIENA_SIMPLE_STAT_SET(vmask, esmp, smask, stat, MC_CMD_PHYXS_ALIGN, + EFX_PHY_STAT_PHY_XS_ALIGN); + + if (vmask & (1 << MC_CMD_PHYXS_SYNC)) { + smask |= ((1 << EFX_PHY_STAT_PHY_XS_SYNC_A) | + (1 << EFX_PHY_STAT_PHY_XS_SYNC_B) | + (1 << EFX_PHY_STAT_PHY_XS_SYNC_C) | + (1 << EFX_PHY_STAT_PHY_XS_SYNC_D)); + if (stat != NULL && !EFSYS_MEM_IS_NULL(esmp)) { + efx_dword_t dword; + uint32_t sync; + EFSYS_MEM_READD(esmp, 4 * MC_CMD_PHYXS_SYNC, &dword); + sync = EFX_DWORD_FIELD(dword, EFX_DWORD_0); + stat[EFX_PHY_STAT_PHY_XS_SYNC_A] = (sync >> 0) & 1; + stat[EFX_PHY_STAT_PHY_XS_SYNC_B] = (sync >> 1) & 1; + stat[EFX_PHY_STAT_PHY_XS_SYNC_C] = (sync >> 2) & 1; + stat[EFX_PHY_STAT_PHY_XS_SYNC_D] = (sync >> 3) & 1; + } + } + + SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, AN_LINK_UP); + SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, AN_COMPLETE); + + SIENA_SIMPLE_STAT_SET(vmask, esmp, smask, stat, MC_CMD_CL22_LINK_UP, + EFX_PHY_STAT_CL22EXT_LINK_UP); + + if (smaskp != NULL) + *smaskp = smask; +} + + __checkReturn int +siena_phy_stats_update( + __in efx_nic_t *enp, + __in efsys_mem_t *esmp, + __out_ecount(EFX_PHY_NSTATS) uint32_t *stat) +{ + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + uint32_t vmask = encp->enc_siena_phy_stat_mask; + uint8_t payload[MC_CMD_PHY_STATS_IN_LEN]; + uint64_t smask; + efx_mcdi_req_t req; + int rc; + + req.emr_cmd = MC_CMD_PHY_STATS; + req.emr_in_buf = payload; + req.emr_in_length = sizeof (payload); + EFX_STATIC_ASSERT(MC_CMD_PHY_STATS_OUT_DMA_LEN == 0); + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + MCDI_IN_SET_DWORD(req, PHY_STATS_IN_DMA_ADDR_LO, + EFSYS_MEM_ADDR(esmp) & 0xffffffff); + MCDI_IN_SET_DWORD(req, PHY_STATS_IN_DMA_ADDR_HI, + EFSYS_MEM_ADDR(esmp) >> 32); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + EFSYS_ASSERT3U(req.emr_out_length, ==, MC_CMD_PHY_STATS_OUT_DMA_LEN); + + siena_phy_decode_stats(enp, vmask, esmp, &smask, stat); + EFSYS_ASSERT(smask == encp->enc_phy_stat_mask); + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (0); +} + +#endif /* EFSYS_OPT_PHY_STATS */ + +#if EFSYS_OPT_PHY_PROPS + +#if EFSYS_OPT_NAMES + +extern const char __cs * +siena_phy_prop_name( + __in efx_nic_t *enp, + __in unsigned int id) +{ + _NOTE(ARGUNUSED(enp, id)) + + return (NULL); +} + +#endif /* EFSYS_OPT_NAMES */ + +extern __checkReturn int +siena_phy_prop_get( + __in efx_nic_t *enp, + __in unsigned int id, + __in uint32_t flags, + __out uint32_t *valp) +{ + _NOTE(ARGUNUSED(enp, id, flags, valp)) + + return (ENOTSUP); +} + +extern __checkReturn int +siena_phy_prop_set( + __in efx_nic_t *enp, + __in unsigned int id, + __in uint32_t val) +{ + _NOTE(ARGUNUSED(enp, id, val)) + + return (ENOTSUP); +} + +#endif /* EFSYS_OPT_PHY_PROPS */ + +#if EFSYS_OPT_PHY_BIST + + __checkReturn int +siena_phy_bist_start( + __in efx_nic_t *enp, + __in efx_phy_bist_type_t type) +{ + uint8_t payload[MC_CMD_START_BIST_IN_LEN]; + efx_mcdi_req_t req; + int rc; + + req.emr_cmd = MC_CMD_START_BIST; + req.emr_in_buf = payload; + req.emr_in_length = sizeof (payload); + EFX_STATIC_ASSERT(MC_CMD_START_BIST_OUT_LEN == 0); + req.emr_out_buf = NULL; + req.emr_out_length = 0; + + switch (type) { + case EFX_PHY_BIST_TYPE_NORMAL: + MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE, MC_CMD_PHY_BIST); + break; + case EFX_PHY_BIST_TYPE_CABLE_SHORT: + MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE, + MC_CMD_PHY_BIST_CABLE_SHORT); + break; + case EFX_PHY_BIST_TYPE_CABLE_LONG: + MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE, + MC_CMD_PHY_BIST_CABLE_LONG); + break; + default: + EFSYS_ASSERT(0); + } + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + +static __checkReturn unsigned long +siena_phy_sft9001_bist_status( + __in uint16_t code) +{ + switch (code) { + case MC_CMD_POLL_BIST_SFT9001_PAIR_BUSY: + return (EFX_PHY_CABLE_STATUS_BUSY); + case MC_CMD_POLL_BIST_SFT9001_INTER_PAIR_SHORT: + return (EFX_PHY_CABLE_STATUS_INTERPAIRSHORT); + case MC_CMD_POLL_BIST_SFT9001_INTRA_PAIR_SHORT: + return (EFX_PHY_CABLE_STATUS_INTRAPAIRSHORT); + case MC_CMD_POLL_BIST_SFT9001_PAIR_OPEN: + return (EFX_PHY_CABLE_STATUS_OPEN); + case MC_CMD_POLL_BIST_SFT9001_PAIR_OK: + return (EFX_PHY_CABLE_STATUS_OK); + default: + return (EFX_PHY_CABLE_STATUS_INVALID); + } +} + + __checkReturn int +siena_phy_bist_poll( + __in efx_nic_t *enp, + __in efx_phy_bist_type_t type, + __out efx_phy_bist_result_t *resultp, + __out_opt __drv_when(count > 0, __notnull) + uint32_t *value_maskp, + __out_ecount_opt(count) __drv_when(count > 0, __notnull) + unsigned long *valuesp, + __in size_t count) +{ + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + uint8_t payload[MCDI_CTL_SDU_LEN_MAX]; + uint32_t value_mask = 0; + efx_mcdi_req_t req; + uint32_t result; + int rc; + + req.emr_cmd = MC_CMD_POLL_BIST; + _NOTE(CONSTANTCONDITION) + EFSYS_ASSERT(MC_CMD_POLL_BIST_IN_LEN == 0); + req.emr_in_buf = NULL; + req.emr_in_length = 0; + req.emr_out_buf = payload; + req.emr_out_length = sizeof (payload); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + if (req.emr_out_length_used < MC_CMD_POLL_BIST_OUT_RESULT_OFST + 4) { + rc = EMSGSIZE; + goto fail2; + } + + if (count > 0) + (void) memset(valuesp, '\0', count * sizeof (unsigned long)); + + result = MCDI_OUT_DWORD(req, POLL_BIST_OUT_RESULT); + + /* Extract PHY specific results */ + if (result == MC_CMD_POLL_BIST_PASSED && + encp->enc_phy_type == EFX_PHY_SFT9001B && + req.emr_out_length_used >= MC_CMD_POLL_BIST_OUT_SFT9001_LEN && + (type == EFX_PHY_BIST_TYPE_CABLE_SHORT || + type == EFX_PHY_BIST_TYPE_CABLE_LONG)) { + uint16_t word; + + if (count > EFX_PHY_BIST_CABLE_LENGTH_A) { + if (valuesp != NULL) + valuesp[EFX_PHY_BIST_CABLE_LENGTH_A] = + MCDI_OUT_DWORD(req, + POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A); + value_mask |= (1 << EFX_PHY_BIST_CABLE_LENGTH_A); + } + + if (count > EFX_PHY_BIST_CABLE_LENGTH_B) { + if (valuesp != NULL) + valuesp[EFX_PHY_BIST_CABLE_LENGTH_B] = + MCDI_OUT_DWORD(req, + POLL_BIST_OUT_SFT9001_CABLE_LENGTH_B); + value_mask |= (1 << EFX_PHY_BIST_CABLE_LENGTH_B); + } + + if (count > EFX_PHY_BIST_CABLE_LENGTH_C) { + if (valuesp != NULL) + valuesp[EFX_PHY_BIST_CABLE_LENGTH_C] = + MCDI_OUT_DWORD(req, + POLL_BIST_OUT_SFT9001_CABLE_LENGTH_C); + value_mask |= (1 << EFX_PHY_BIST_CABLE_LENGTH_C); + } + + if (count > EFX_PHY_BIST_CABLE_LENGTH_D) { + if (valuesp != NULL) + valuesp[EFX_PHY_BIST_CABLE_LENGTH_D] = + MCDI_OUT_DWORD(req, + POLL_BIST_OUT_SFT9001_CABLE_LENGTH_D); + value_mask |= (1 << EFX_PHY_BIST_CABLE_LENGTH_D); + } + + if (count > EFX_PHY_BIST_CABLE_STATUS_A) { + if (valuesp != NULL) { + word = MCDI_OUT_WORD(req, + POLL_BIST_OUT_SFT9001_CABLE_STATUS_A); + valuesp[EFX_PHY_BIST_CABLE_STATUS_A] = + siena_phy_sft9001_bist_status(word); + } + value_mask |= (1 << EFX_PHY_BIST_CABLE_STATUS_A); + } + + if (count > EFX_PHY_BIST_CABLE_STATUS_B) { + if (valuesp != NULL) { + word = MCDI_OUT_WORD(req, + POLL_BIST_OUT_SFT9001_CABLE_STATUS_B); + valuesp[EFX_PHY_BIST_CABLE_STATUS_B] = + siena_phy_sft9001_bist_status(word); + } + value_mask |= (1 << EFX_PHY_BIST_CABLE_STATUS_B); + } + + if (count > EFX_PHY_BIST_CABLE_STATUS_C) { + if (valuesp != NULL) { + word = MCDI_OUT_WORD(req, + POLL_BIST_OUT_SFT9001_CABLE_STATUS_C); + valuesp[EFX_PHY_BIST_CABLE_STATUS_C] = + siena_phy_sft9001_bist_status(word); + } + value_mask |= (1 << EFX_PHY_BIST_CABLE_STATUS_C); + } + + if (count > EFX_PHY_BIST_CABLE_STATUS_D) { + if (valuesp != NULL) { + word = MCDI_OUT_WORD(req, + POLL_BIST_OUT_SFT9001_CABLE_STATUS_D); + valuesp[EFX_PHY_BIST_CABLE_STATUS_D] = + siena_phy_sft9001_bist_status(word); + } + value_mask |= (1 << EFX_PHY_BIST_CABLE_STATUS_D); + } + + } else if (result == MC_CMD_POLL_BIST_FAILED && + encp->enc_phy_type == EFX_PHY_QLX111V && + req.emr_out_length >= MC_CMD_POLL_BIST_OUT_MRSFP_LEN && + count > EFX_PHY_BIST_FAULT_CODE) { + if (valuesp != NULL) + valuesp[EFX_PHY_BIST_FAULT_CODE] = + MCDI_OUT_DWORD(req, POLL_BIST_OUT_MRSFP_TEST); + value_mask |= 1 << EFX_PHY_BIST_FAULT_CODE; + } + + if (value_maskp != NULL) + *value_maskp = value_mask; + + EFSYS_ASSERT(resultp != NULL); + if (result == MC_CMD_POLL_BIST_RUNNING) + *resultp = EFX_PHY_BIST_RESULT_RUNNING; + else if (result == MC_CMD_POLL_BIST_PASSED) + *resultp = EFX_PHY_BIST_RESULT_PASSED; + else + *resultp = EFX_PHY_BIST_RESULT_FAILED; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + void +siena_phy_bist_stop( + __in efx_nic_t *enp, + __in efx_phy_bist_type_t type) +{ + /* There is no way to stop BIST on Siena */ + _NOTE(ARGUNUSED(enp, type)) +} + +#endif /* EFSYS_OPT_PHY_BIST */ + +#endif /* EFSYS_OPT_SIENA */ diff --git a/sys/dev/sfxge/common/siena_sram.c b/sys/dev/sfxge/common/siena_sram.c new file mode 100644 index 000000000000..64fce989c019 --- /dev/null +++ b/sys/dev/sfxge/common/siena_sram.c @@ -0,0 +1,172 @@ +/*- + * Copyright 2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "efsys.h" +#include "efx.h" +#include "efx_impl.h" + +#if EFSYS_OPT_SIENA + + void +siena_sram_init( + __in efx_nic_t *enp) +{ + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + efx_oword_t oword; + uint32_t rx_base, tx_base; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); + + rx_base = encp->enc_buftbl_limit; + tx_base = rx_base + (encp->enc_rxq_limit * 64); + + /* Initialize the transmit descriptor cache */ + EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_TX_DC_BASE_ADR, tx_base); + EFX_BAR_WRITEO(enp, FR_AZ_SRM_TX_DC_CFG_REG, &oword); + + EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DC_SIZE, 1); /* 16 descriptors */ + EFX_BAR_WRITEO(enp, FR_AZ_TX_DC_CFG_REG, &oword); + + /* Initialize the receive descriptor cache */ + EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_RX_DC_BASE_ADR, rx_base); + EFX_BAR_WRITEO(enp, FR_AZ_SRM_RX_DC_CFG_REG, &oword); + + EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_SIZE, 3); /* 64 descriptors */ + EFX_BAR_WRITEO(enp, FR_AZ_RX_DC_CFG_REG, &oword); + + /* Set receive descriptor pre-fetch low water mark */ + EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DC_PF_LWM, 56); + EFX_BAR_WRITEO(enp, FR_AZ_RX_DC_PF_WM_REG, &oword); + + /* Set the event queue to use for SRAM updates */ + EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_UPD_EVQ_ID, 0); + EFX_BAR_WRITEO(enp, FR_AZ_SRM_UPD_EVQ_REG, &oword); +} + +#if EFSYS_OPT_DIAG + + __checkReturn int +siena_sram_test( + __in efx_nic_t *enp, + __in efx_sram_pattern_fn_t func) +{ + efx_oword_t oword; + efx_qword_t qword; + efx_qword_t verify; + size_t rows; + unsigned int wptr; + unsigned int rptr; + int rc; + + EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); + + /* Reconfigure into HALF buffer table mode */ + EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 0); + EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword); + + /* + * Move the descriptor caches up to the top of SRAM, and test + * all of SRAM below them. We only miss out one row here. + */ + rows = SIENA_SRAM_ROWS - 1; + EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_RX_DC_BASE_ADR, rows); + EFX_BAR_WRITEO(enp, FR_AZ_SRM_RX_DC_CFG_REG, &oword); + + EFX_POPULATE_OWORD_1(oword, FRF_AZ_SRM_TX_DC_BASE_ADR, rows + 1); + EFX_BAR_WRITEO(enp, FR_AZ_SRM_TX_DC_CFG_REG, &oword); + + /* + * Write the pattern through BUF_HALF_TBL. Write + * in 64 entry batches, waiting 1us in between each batch + * to guarantee not to overflow the SRAM fifo + */ + for (wptr = 0, rptr = 0; wptr < rows; ++wptr) { + func(wptr, B_FALSE, &qword); + EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_HALF_TBL, wptr, &qword); + + if ((wptr - rptr) < 64 && wptr < rows - 1) + continue; + + EFSYS_SPIN(1); + + for (; rptr <= wptr; ++rptr) { + func(rptr, B_FALSE, &qword); + EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_HALF_TBL, rptr, + &verify); + + if (!EFX_QWORD_IS_EQUAL(verify, qword)) { + rc = EFAULT; + goto fail1; + } + } + } + + /* And do the same negated */ + for (wptr = 0, rptr = 0; wptr < rows; ++wptr) { + func(wptr, B_TRUE, &qword); + EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_HALF_TBL, wptr, &qword); + + if ((wptr - rptr) < 64 && wptr < rows - 1) + continue; + + EFSYS_SPIN(1); + + for (; rptr <= wptr; ++rptr) { + func(rptr, B_TRUE, &qword); + EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_HALF_TBL, rptr, + &verify); + + if (!EFX_QWORD_IS_EQUAL(verify, qword)) { + rc = EFAULT; + goto fail2; + } + } + } + + /* Restore back to FULL buffer table mode */ + EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 1); + EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword); + + /* + * We don't need to reconfigure SRAM again because the API + * requires efx_nic_fini() to be called after an sram test. + */ + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + /* Restore back to FULL buffer table mode */ + EFX_POPULATE_OWORD_1(oword, FRF_AZ_BUF_TBL_MODE, 1); + EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_CFG_REG, &oword); + + return (rc); +} + +#endif /* EFSYS_OPT_DIAG */ + +#endif /* EFSYS_OPT_SIENA */ diff --git a/sys/dev/sfxge/common/siena_vpd.c b/sys/dev/sfxge/common/siena_vpd.c new file mode 100644 index 000000000000..5c446085ec2a --- /dev/null +++ b/sys/dev/sfxge/common/siena_vpd.c @@ -0,0 +1,603 @@ +/*- + * Copyright 2009 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 AUTHOR AND CONTRIBUTORS ``AS IS AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "efsys.h" +#include "efx.h" +#include "efx_types.h" +#include "efx_regs.h" +#include "efx_impl.h" + +#if EFSYS_OPT_VPD + +#if EFSYS_OPT_SIENA + +static __checkReturn int +siena_vpd_get_static( + __in efx_nic_t *enp, + __in unsigned int partn, + __deref_out_bcount_opt(*sizep) caddr_t *svpdp, + __out size_t *sizep) +{ + siena_mc_static_config_hdr_t *scfg; + caddr_t svpd; + size_t size; + uint8_t cksum; + unsigned int vpd_offset; + unsigned int vpd_length; + unsigned int hdr_length; + unsigned int pos; + unsigned int region; + int rc; + + EFSYS_ASSERT(partn == MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0 || + partn == MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1); + + /* Allocate sufficient memory for the entire static cfg area */ + if ((rc = siena_nvram_partn_size(enp, partn, &size)) != 0) + goto fail1; + + EFSYS_KMEM_ALLOC(enp->en_esip, size, scfg); + if (scfg == NULL) { + rc = ENOMEM; + goto fail2; + } + + if ((rc = siena_nvram_partn_read(enp, partn, 0, + (caddr_t)scfg, SIENA_NVRAM_CHUNK)) != 0) + goto fail3; + + /* Verify the magic number */ + if (EFX_DWORD_FIELD(scfg->magic, EFX_DWORD_0) != + SIENA_MC_STATIC_CONFIG_MAGIC) { + rc = EINVAL; + goto fail4; + } + + /* All future versions of the structure must be backwards compatable */ + EFX_STATIC_ASSERT(SIENA_MC_STATIC_CONFIG_VERSION == 0); + + hdr_length = EFX_WORD_FIELD(scfg->length, EFX_WORD_0); + vpd_offset = EFX_DWORD_FIELD(scfg->static_vpd_offset, EFX_DWORD_0); + vpd_length = EFX_DWORD_FIELD(scfg->static_vpd_length, EFX_DWORD_0); + + /* Verify the hdr doesn't overflow the sector size */ + if (hdr_length > size || vpd_offset > size || vpd_length > size || + vpd_length + vpd_offset > size) { + rc = EINVAL; + goto fail5; + } + + /* Read the remainder of scfg + static vpd */ + region = vpd_offset + vpd_length; + if (region > SIENA_NVRAM_CHUNK) { + if ((rc = siena_nvram_partn_read(enp, partn, SIENA_NVRAM_CHUNK, + (caddr_t)scfg + SIENA_NVRAM_CHUNK, + region - SIENA_NVRAM_CHUNK)) != 0) + goto fail6; + } + + /* Verify checksum */ + cksum = 0; + for (pos = 0; pos < hdr_length; pos++) + cksum += ((uint8_t *)scfg)[pos]; + if (cksum != 0) { + rc = EINVAL; + goto fail7; + } + + if (vpd_length == 0) + svpd = NULL; + else { + /* Copy the vpd data out */ + EFSYS_KMEM_ALLOC(enp->en_esip, vpd_length, svpd); + if (svpd == NULL) { + rc = ENOMEM; + goto fail8; + } + memcpy(svpd, (caddr_t)scfg + vpd_offset, vpd_length); + } + + EFSYS_KMEM_FREE(enp->en_esip, size, scfg); + + *svpdp = svpd; + *sizep = vpd_length; + + return (0); + +fail8: + EFSYS_PROBE(fail8); +fail7: + EFSYS_PROBE(fail7); +fail6: + EFSYS_PROBE(fail6); +fail5: + EFSYS_PROBE(fail5); +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); + + EFSYS_KMEM_FREE(enp->en_esip, size, scfg); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_vpd_init( + __in efx_nic_t *enp) +{ + efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip); + caddr_t svpd = NULL; + unsigned partn; + size_t size = 0; + int rc; + + EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); + + partn = (emip->emi_port == 1) + ? MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0 + : MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1; + + /* + * We need the static VPD sector to present a unified static+dynamic + * VPD, that is, basically on every read, write, verify cycle. Since + * it should *never* change we can just cache it here. + */ + if ((rc = siena_vpd_get_static(enp, partn, &svpd, &size)) != 0) + goto fail1; + + if (svpd != NULL && size > 0) { + if ((rc = efx_vpd_hunk_verify(svpd, size, NULL)) != 0) + goto fail2; + } + + enp->en_u.siena.enu_svpd = svpd; + enp->en_u.siena.enu_svpd_length = size; + + return (0); + +fail2: + EFSYS_PROBE(fail2); + + EFSYS_KMEM_FREE(enp->en_esip, size, svpd); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_vpd_size( + __in efx_nic_t *enp, + __out size_t *sizep) +{ + efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip); + unsigned int partn; + int rc; + + EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); + + /* + * This function returns the total size the user should allocate + * for all VPD operations. We've already cached the static vpd, + * so we just need to return an upper bound on the dynamic vpd. + * Since the dynamic_config structure can change under our feet, + * (as version numbers are inserted), just be safe and return the + * total size of the dynamic_config *sector* + */ + partn = (emip->emi_port == 1) + ? MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0 + : MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1; + + if ((rc = siena_nvram_partn_size(enp, partn, sizep)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_vpd_read( + __in efx_nic_t *enp, + __out_bcount(size) caddr_t data, + __in size_t size) +{ + efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip); + siena_mc_dynamic_config_hdr_t *dcfg; + unsigned int vpd_length; + unsigned int vpd_offset; + unsigned int dcfg_partn; + size_t dcfg_size; + int rc; + + EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); + + dcfg_partn = (emip->emi_port == 1) + ? MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0 + : MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1; + + if ((rc = siena_nvram_get_dynamic_cfg(enp, dcfg_partn, + B_TRUE, &dcfg, &dcfg_size)) != 0) + goto fail1; + + vpd_length = EFX_DWORD_FIELD(dcfg->dynamic_vpd_length, EFX_DWORD_0); + vpd_offset = EFX_DWORD_FIELD(dcfg->dynamic_vpd_offset, EFX_DWORD_0); + + if (vpd_length > size) { + rc = EFAULT; /* Invalid dcfg: header bigger than sector */ + goto fail2; + } + + EFSYS_ASSERT3U(vpd_length, <=, size); + memcpy(data, (caddr_t)dcfg + vpd_offset, vpd_length); + + /* Pad data with all-1s, consistent with update operations */ + memset(data + vpd_length, 0xff, size - vpd_length); + + EFSYS_KMEM_FREE(enp->en_esip, dcfg_size, dcfg); + + return (0); + +fail2: + EFSYS_PROBE(fail2); + + EFSYS_KMEM_FREE(enp->en_esip, dcfg_size, dcfg); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_vpd_verify( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size) +{ + efx_vpd_tag_t stag; + efx_vpd_tag_t dtag; + efx_vpd_keyword_t skey; + efx_vpd_keyword_t dkey; + unsigned int scont; + unsigned int dcont; + + int rc; + + EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); + + /* + * Strictly you could take the view that dynamic vpd is optional. + * Instead, to conform more closely to the read/verify/reinit() + * paradigm, we require dynamic vpd. siena_vpd_reinit() will + * reinitialize it as required. + */ + if ((rc = efx_vpd_hunk_verify(data, size, NULL)) != 0) + goto fail1; + + /* + * Verify that there is no duplication between the static and + * dynamic cfg sectors. + */ + if (enp->en_u.siena.enu_svpd_length == 0) + goto done; + + dcont = 0; + _NOTE(CONSTANTCONDITION) + while (1) { + if ((rc = efx_vpd_hunk_next(data, size, &dtag, + &dkey, NULL, NULL, &dcont)) != 0) + goto fail2; + if (dcont == 0) + break; + + scont = 0; + _NOTE(CONSTANTCONDITION) + while (1) { + if ((rc = efx_vpd_hunk_next( + enp->en_u.siena.enu_svpd, + enp->en_u.siena.enu_svpd_length, &stag, &skey, + NULL, NULL, &scont)) != 0) + goto fail3; + if (scont == 0) + break; + + if (stag == dtag && skey == dkey) { + rc = EEXIST; + goto fail4; + } + } + } + +done: + return (0); + +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_vpd_reinit( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size) +{ + boolean_t wantpid; + int rc; + + /* + * Only create a PID if the dynamic cfg doesn't have one + */ + if (enp->en_u.siena.enu_svpd_length == 0) + wantpid = B_TRUE; + else { + unsigned int offset; + uint8_t length; + + rc = efx_vpd_hunk_get(enp->en_u.siena.enu_svpd, + enp->en_u.siena.enu_svpd_length, + EFX_VPD_ID, 0, &offset, &length); + if (rc == 0) + wantpid = B_FALSE; + else if (rc == ENOENT) + wantpid = B_TRUE; + else + goto fail1; + } + + if ((rc = efx_vpd_hunk_reinit(data, size, wantpid)) != 0) + goto fail2; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_vpd_get( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size, + __inout efx_vpd_value_t *evvp) +{ + unsigned int offset; + uint8_t length; + int rc; + + EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); + + /* Attempt to satisfy the request from svpd first */ + if (enp->en_u.siena.enu_svpd_length > 0) { + if ((rc = efx_vpd_hunk_get(enp->en_u.siena.enu_svpd, + enp->en_u.siena.enu_svpd_length, evvp->evv_tag, + evvp->evv_keyword, &offset, &length)) == 0) { + evvp->evv_length = length; + memcpy(evvp->evv_value, + enp->en_u.siena.enu_svpd + offset, length); + return (0); + } else if (rc != ENOENT) + goto fail1; + } + + /* And then from the provided data buffer */ + if ((rc = efx_vpd_hunk_get(data, size, evvp->evv_tag, + evvp->evv_keyword, &offset, &length)) != 0) + goto fail2; + + evvp->evv_length = length; + memcpy(evvp->evv_value, data + offset, length); + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_vpd_set( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size, + __in efx_vpd_value_t *evvp) +{ + int rc; + + EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); + + /* If the provided (tag,keyword) exists in svpd, then it is readonly */ + if (enp->en_u.siena.enu_svpd_length > 0) { + unsigned int offset; + uint8_t length; + + if ((rc = efx_vpd_hunk_get(enp->en_u.siena.enu_svpd, + enp->en_u.siena.enu_svpd_length, evvp->evv_tag, + evvp->evv_keyword, &offset, &length)) == 0) { + rc = EACCES; + goto fail1; + } + } + + if ((rc = efx_vpd_hunk_set(data, size, evvp)) != 0) + goto fail2; + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + __checkReturn int +siena_vpd_next( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size, + __out efx_vpd_value_t *evvp, + __inout unsigned int *contp) +{ + _NOTE(ARGUNUSED(enp, data, size, evvp, contp)) + + return (ENOTSUP); +} + + __checkReturn int +siena_vpd_write( + __in efx_nic_t *enp, + __in_bcount(size) caddr_t data, + __in size_t size) +{ + efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip); + siena_mc_dynamic_config_hdr_t *dcfg; + unsigned int vpd_offset; + unsigned int dcfg_partn; + unsigned int hdr_length; + unsigned int pos; + uint8_t cksum; + size_t partn_size, dcfg_size; + size_t vpd_length; + int rc; + + EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); + + /* Determine total length of all tags */ + if ((rc = efx_vpd_hunk_length(data, size, &vpd_length)) != 0) + goto fail1; + + /* Lock dynamic config sector for write, and read structure only */ + dcfg_partn = (emip->emi_port == 1) + ? MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0 + : MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1; + + if ((rc = siena_nvram_partn_size(enp, dcfg_partn, &partn_size)) != 0) + goto fail2; + + if ((rc = siena_nvram_partn_lock(enp, dcfg_partn)) != 0) + goto fail2; + + if ((rc = siena_nvram_get_dynamic_cfg(enp, dcfg_partn, + B_FALSE, &dcfg, &dcfg_size)) != 0) + goto fail3; + + hdr_length = EFX_WORD_FIELD(dcfg->length, EFX_WORD_0); + + /* Allocated memory should have room for the new VPD */ + if (hdr_length + vpd_length > dcfg_size) { + rc = ENOSPC; + goto fail3; + } + + /* Copy in new vpd and update header */ + vpd_offset = dcfg_size - vpd_length; + EFX_POPULATE_DWORD_1(dcfg->dynamic_vpd_offset, + EFX_DWORD_0, vpd_offset); + memcpy((caddr_t)dcfg + vpd_offset, data, vpd_length); + EFX_POPULATE_DWORD_1(dcfg->dynamic_vpd_length, + EFX_DWORD_0, vpd_length); + + /* Update the checksum */ + cksum = 0; + for (pos = 0; pos < hdr_length; pos++) + cksum += ((uint8_t *)dcfg)[pos]; + dcfg->csum.eb_u8[0] -= cksum; + + /* Erase and write the new sector */ + if ((rc = siena_nvram_partn_erase(enp, dcfg_partn, 0, partn_size)) != 0) + goto fail4; + + /* Write out the new structure to nvram */ + if ((rc = siena_nvram_partn_write(enp, dcfg_partn, 0, (caddr_t)dcfg, + vpd_offset + vpd_length)) != 0) + goto fail5; + + EFSYS_KMEM_FREE(enp->en_esip, dcfg_size, dcfg); + + siena_nvram_partn_unlock(enp, dcfg_partn); + + return (0); + +fail5: + EFSYS_PROBE(fail5); +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); + + EFSYS_KMEM_FREE(enp->en_esip, dcfg_size, dcfg); +fail2: + EFSYS_PROBE(fail2); + + siena_nvram_partn_unlock(enp, dcfg_partn); +fail1: + EFSYS_PROBE1(fail1, int, rc); + + return (rc); +} + + void +siena_vpd_fini( + __in efx_nic_t *enp) +{ + EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); + + if (enp->en_u.siena.enu_svpd_length > 0) { + EFSYS_KMEM_FREE(enp->en_esip, enp->en_u.siena.enu_svpd_length, + enp->en_u.siena.enu_svpd); + + enp->en_u.siena.enu_svpd = NULL; + enp->en_u.siena.enu_svpd_length = 0; + } +} + +#endif /* EFSYS_OPT_SIENA */ + +#endif /* EFSYS_OPT_VPD */ diff --git a/sys/dev/sfxge/sfxge.c b/sys/dev/sfxge/sfxge.c new file mode 100644 index 000000000000..380215a3ef54 --- /dev/null +++ b/sys/dev/sfxge/sfxge.c @@ -0,0 +1,775 @@ +/*- + * Copyright (c) 2010-2011 Solarflare Communications, Inc. + * All rights reserved. + * + * This software was developed in part by Philip Paeps under contract for + * Solarflare Communications, Inc. + * + * 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include "common/efx.h" + +#include "sfxge.h" +#include "sfxge_rx.h" + +#define SFXGE_CAP (IFCAP_VLAN_MTU | \ + IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | IFCAP_TSO | \ + IFCAP_JUMBO_MTU | IFCAP_LRO | \ + IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE) +#define SFXGE_CAP_ENABLE SFXGE_CAP +#define SFXGE_CAP_FIXED (IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | \ + IFCAP_JUMBO_MTU | IFCAP_LINKSTATE) + +MALLOC_DEFINE(M_SFXGE, "sfxge", "Solarflare 10GigE driver"); + +static void +sfxge_reset(void *arg, int npending); + +static int +sfxge_start(struct sfxge_softc *sc) +{ + int rc; + + sx_assert(&sc->softc_lock, LA_XLOCKED); + + if (sc->init_state == SFXGE_STARTED) + return 0; + + if (sc->init_state != SFXGE_REGISTERED) { + rc = EINVAL; + goto fail; + } + + if ((rc = efx_nic_init(sc->enp)) != 0) + goto fail; + + /* Start processing interrupts. */ + if ((rc = sfxge_intr_start(sc)) != 0) + goto fail2; + + /* Start processing events. */ + if ((rc = sfxge_ev_start(sc)) != 0) + goto fail3; + + /* Start the receiver side. */ + if ((rc = sfxge_rx_start(sc)) != 0) + goto fail4; + + /* Start the transmitter side. */ + if ((rc = sfxge_tx_start(sc)) != 0) + goto fail5; + + /* Fire up the port. */ + if ((rc = sfxge_port_start(sc)) != 0) + goto fail6; + + sc->init_state = SFXGE_STARTED; + + /* Tell the stack we're running. */ + sc->ifnet->if_drv_flags |= IFF_DRV_RUNNING; + sc->ifnet->if_drv_flags &= ~IFF_DRV_OACTIVE; + + return (0); + +fail6: + sfxge_tx_stop(sc); + +fail5: + sfxge_rx_stop(sc); + +fail4: + sfxge_ev_stop(sc); + +fail3: + sfxge_intr_stop(sc); + +fail2: + efx_nic_fini(sc->enp); + +fail: + device_printf(sc->dev, "sfxge_start: %d\n", rc); + + return (rc); +} + +static void +sfxge_if_init(void *arg) +{ + struct sfxge_softc *sc; + + sc = (struct sfxge_softc *)arg; + + sx_xlock(&sc->softc_lock); + (void)sfxge_start(sc); + sx_xunlock(&sc->softc_lock); +} + +static void +sfxge_stop(struct sfxge_softc *sc) +{ + sx_assert(&sc->softc_lock, LA_XLOCKED); + + if (sc->init_state != SFXGE_STARTED) + return; + + sc->init_state = SFXGE_REGISTERED; + + /* Stop the port. */ + sfxge_port_stop(sc); + + /* Stop the transmitter. */ + sfxge_tx_stop(sc); + + /* Stop the receiver. */ + sfxge_rx_stop(sc); + + /* Stop processing events. */ + sfxge_ev_stop(sc); + + /* Stop processing interrupts. */ + sfxge_intr_stop(sc); + + efx_nic_fini(sc->enp); + + sc->ifnet->if_drv_flags &= ~IFF_DRV_RUNNING; +} + +static int +sfxge_if_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data) +{ + struct sfxge_softc *sc; + struct ifreq *ifr; + int error; + + ifr = (struct ifreq *)data; + sc = ifp->if_softc; + error = 0; + + switch (command) { + case SIOCSIFFLAGS: + sx_xlock(&sc->softc_lock); + if (ifp->if_flags & IFF_UP) { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + if ((ifp->if_flags ^ sc->if_flags) & + (IFF_PROMISC | IFF_ALLMULTI)) { + sfxge_mac_filter_set(sc); + } + } else + sfxge_start(sc); + } else + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + sfxge_stop(sc); + sc->if_flags = ifp->if_flags; + sx_xunlock(&sc->softc_lock); + break; + case SIOCSIFMTU: + if (ifr->ifr_mtu == ifp->if_mtu) { + /* Nothing to do */ + error = 0; + } else if (ifr->ifr_mtu > SFXGE_MAX_MTU) { + error = EINVAL; + } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + ifp->if_mtu = ifr->ifr_mtu; + error = 0; + } else { + /* Restart required */ + sx_xlock(&sc->softc_lock); + sfxge_stop(sc); + ifp->if_mtu = ifr->ifr_mtu; + error = sfxge_start(sc); + sx_xunlock(&sc->softc_lock); + if (error) { + ifp->if_flags &= ~IFF_UP; + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + if_down(ifp); + } + } + break; + case SIOCADDMULTI: + case SIOCDELMULTI: + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + sfxge_mac_filter_set(sc); + break; + case SIOCSIFCAP: + sx_xlock(&sc->softc_lock); + + /* + * The networking core already rejects attempts to + * enable capabilities we don't have. We still have + * to reject attempts to disable capabilities that we + * can't (yet) disable. + */ + if (~ifr->ifr_reqcap & SFXGE_CAP_FIXED) { + error = EINVAL; + sx_xunlock(&sc->softc_lock); + break; + } + + ifp->if_capenable = ifr->ifr_reqcap; + if (ifp->if_capenable & IFCAP_TXCSUM) + ifp->if_hwassist |= (CSUM_IP | CSUM_TCP | CSUM_UDP); + else + ifp->if_hwassist &= ~(CSUM_IP | CSUM_TCP | CSUM_UDP); + if (ifp->if_capenable & IFCAP_TSO) + ifp->if_hwassist |= CSUM_TSO; + else + ifp->if_hwassist &= ~CSUM_TSO; + + sx_xunlock(&sc->softc_lock); + break; + case SIOCSIFMEDIA: + case SIOCGIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &sc->media, command); + break; + default: + error = ether_ioctl(ifp, command, data); + } + + return (error); +} + +static void +sfxge_ifnet_fini(struct ifnet *ifp) +{ + struct sfxge_softc *sc = ifp->if_softc; + + sx_xlock(&sc->softc_lock); + sfxge_stop(sc); + sx_xunlock(&sc->softc_lock); + + ifmedia_removeall(&sc->media); + ether_ifdetach(ifp); + if_free(ifp); +} + +static int +sfxge_ifnet_init(struct ifnet *ifp, struct sfxge_softc *sc) +{ + const efx_nic_cfg_t *encp = efx_nic_cfg_get(sc->enp); + device_t dev; + int rc; + + dev = sc->dev; + sc->ifnet = ifp; + + if_initname(ifp, device_get_name(dev), device_get_unit(dev)); + ifp->if_init = sfxge_if_init; + ifp->if_softc = sc; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_ioctl = sfxge_if_ioctl; + + ifp->if_capabilities = SFXGE_CAP; + ifp->if_capenable = SFXGE_CAP_ENABLE; + ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO; + + ether_ifattach(ifp, encp->enc_mac_addr); + +#ifdef SFXGE_HAVE_MQ + ifp->if_transmit = sfxge_if_transmit; + ifp->if_qflush = sfxge_if_qflush; +#else + ifp->if_start = sfxge_if_start; + IFQ_SET_MAXLEN(&ifp->if_snd, SFXGE_NDESCS - 1); + ifp->if_snd.ifq_drv_maxlen = SFXGE_NDESCS - 1; + IFQ_SET_READY(&ifp->if_snd); + + mtx_init(&sc->tx_lock, "txq", NULL, MTX_DEF); +#endif + + if ((rc = sfxge_port_ifmedia_init(sc)) != 0) + goto fail; + + return 0; + +fail: + ether_ifdetach(sc->ifnet); + return rc; +} + +void +sfxge_sram_buf_tbl_alloc(struct sfxge_softc *sc, size_t n, uint32_t *idp) +{ + KASSERT(sc->buffer_table_next + n <= + efx_nic_cfg_get(sc->enp)->enc_buftbl_limit, + ("buffer table full")); + + *idp = sc->buffer_table_next; + sc->buffer_table_next += n; +} + +static int +sfxge_bar_init(struct sfxge_softc *sc) +{ + efsys_bar_t *esbp = &sc->bar; + + esbp->esb_rid = PCIR_BAR(EFX_MEM_BAR); + if ((esbp->esb_res = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY, + &esbp->esb_rid, RF_ACTIVE)) == NULL) { + device_printf(sc->dev, "Cannot allocate BAR region %d\n", + EFX_MEM_BAR); + return (ENXIO); + } + esbp->esb_tag = rman_get_bustag(esbp->esb_res); + esbp->esb_handle = rman_get_bushandle(esbp->esb_res); + mtx_init(&esbp->esb_lock, "sfxge_efsys_bar", NULL, MTX_DEF); + + return (0); +} + +static void +sfxge_bar_fini(struct sfxge_softc *sc) +{ + efsys_bar_t *esbp = &sc->bar; + + bus_release_resource(sc->dev, SYS_RES_MEMORY, esbp->esb_rid, + esbp->esb_res); + mtx_destroy(&esbp->esb_lock); +} + +static int +sfxge_create(struct sfxge_softc *sc) +{ + device_t dev; + efx_nic_t *enp; + int error; + + dev = sc->dev; + + sx_init(&sc->softc_lock, "sfxge_softc"); + + sc->stats_node = SYSCTL_ADD_NODE( + device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), + OID_AUTO, "stats", CTLFLAG_RD, NULL, "Statistics"); + if (!sc->stats_node) { + error = ENOMEM; + goto fail; + } + + TASK_INIT(&sc->task_reset, 0, sfxge_reset, sc); + + (void) pci_enable_busmaster(dev); + + /* Initialize DMA mappings. */ + if ((error = sfxge_dma_init(sc)) != 0) + goto fail; + + /* Map the device registers. */ + if ((error = sfxge_bar_init(sc)) != 0) + goto fail; + + error = efx_family(pci_get_vendor(dev), pci_get_device(dev), + &sc->family); + KASSERT(error == 0, ("Family should be filtered by sfxge_probe()")); + + /* Create the common code nic object. */ + mtx_init(&sc->enp_lock, "sfxge_nic", NULL, MTX_DEF); + if ((error = efx_nic_create(sc->family, (efsys_identifier_t *)sc, + &sc->bar, &sc->enp_lock, &enp)) != 0) + goto fail3; + sc->enp = enp; + + /* Initialize MCDI to talk to the microcontroller. */ + if ((error = sfxge_mcdi_init(sc)) != 0) + goto fail4; + + /* Probe the NIC and build the configuration data area. */ + if ((error = efx_nic_probe(enp)) != 0) + goto fail5; + + /* Initialize the NVRAM. */ + if ((error = efx_nvram_init(enp)) != 0) + goto fail6; + + /* Initialize the VPD. */ + if ((error = efx_vpd_init(enp)) != 0) + goto fail7; + + /* Reset the NIC. */ + if ((error = efx_nic_reset(enp)) != 0) + goto fail8; + + /* Initialize buffer table allocation. */ + sc->buffer_table_next = 0; + + /* Set up interrupts. */ + if ((error = sfxge_intr_init(sc)) != 0) + goto fail8; + + /* Initialize event processing state. */ + if ((error = sfxge_ev_init(sc)) != 0) + goto fail11; + + /* Initialize receive state. */ + if ((error = sfxge_rx_init(sc)) != 0) + goto fail12; + + /* Initialize transmit state. */ + if ((error = sfxge_tx_init(sc)) != 0) + goto fail13; + + /* Initialize port state. */ + if ((error = sfxge_port_init(sc)) != 0) + goto fail14; + + sc->init_state = SFXGE_INITIALIZED; + + return (0); + +fail14: + sfxge_tx_fini(sc); + +fail13: + sfxge_rx_fini(sc); + +fail12: + sfxge_ev_fini(sc); + +fail11: + sfxge_intr_fini(sc); + +fail8: + efx_vpd_fini(enp); + +fail7: + efx_nvram_fini(enp); + +fail6: + efx_nic_unprobe(enp); + +fail5: + sfxge_mcdi_fini(sc); + +fail4: + sc->enp = NULL; + efx_nic_destroy(enp); + mtx_destroy(&sc->enp_lock); + +fail3: + sfxge_bar_fini(sc); + (void) pci_disable_busmaster(sc->dev); + +fail: + sc->dev = NULL; + sx_destroy(&sc->softc_lock); + return (error); +} + +static void +sfxge_destroy(struct sfxge_softc *sc) +{ + efx_nic_t *enp; + + /* Clean up port state. */ + sfxge_port_fini(sc); + + /* Clean up transmit state. */ + sfxge_tx_fini(sc); + + /* Clean up receive state. */ + sfxge_rx_fini(sc); + + /* Clean up event processing state. */ + sfxge_ev_fini(sc); + + /* Clean up interrupts. */ + sfxge_intr_fini(sc); + + /* Tear down common code subsystems. */ + efx_nic_reset(sc->enp); + efx_vpd_fini(sc->enp); + efx_nvram_fini(sc->enp); + efx_nic_unprobe(sc->enp); + + /* Tear down MCDI. */ + sfxge_mcdi_fini(sc); + + /* Destroy common code context. */ + enp = sc->enp; + sc->enp = NULL; + efx_nic_destroy(enp); + + /* Free DMA memory. */ + sfxge_dma_fini(sc); + + /* Free mapped BARs. */ + sfxge_bar_fini(sc); + + (void) pci_disable_busmaster(sc->dev); + + taskqueue_drain(taskqueue_thread, &sc->task_reset); + + /* Destroy the softc lock. */ + sx_destroy(&sc->softc_lock); +} + +static int +sfxge_vpd_handler(SYSCTL_HANDLER_ARGS) +{ + struct sfxge_softc *sc = arg1; + efx_vpd_value_t value; + int rc; + + value.evv_tag = arg2 >> 16; + value.evv_keyword = arg2 & 0xffff; + if ((rc = efx_vpd_get(sc->enp, sc->vpd_data, sc->vpd_size, &value)) + != 0) + return rc; + + return SYSCTL_OUT(req, value.evv_value, value.evv_length); +} + +static void +sfxge_vpd_try_add(struct sfxge_softc *sc, struct sysctl_oid_list *list, + efx_vpd_tag_t tag, const char *keyword) +{ + struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev); + efx_vpd_value_t value; + + /* Check whether VPD tag/keyword is present */ + value.evv_tag = tag; + value.evv_keyword = EFX_VPD_KEYWORD(keyword[0], keyword[1]); + if (efx_vpd_get(sc->enp, sc->vpd_data, sc->vpd_size, &value) != 0) + return; + + SYSCTL_ADD_PROC( + ctx, list, OID_AUTO, keyword, CTLTYPE_STRING|CTLFLAG_RD, + sc, tag << 16 | EFX_VPD_KEYWORD(keyword[0], keyword[1]), + sfxge_vpd_handler, "A", ""); +} + +static int +sfxge_vpd_init(struct sfxge_softc *sc) +{ + struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev); + struct sysctl_oid *vpd_node; + struct sysctl_oid_list *vpd_list; + char keyword[3]; + efx_vpd_value_t value; + int rc; + + if ((rc = efx_vpd_size(sc->enp, &sc->vpd_size)) != 0) + goto fail; + sc->vpd_data = malloc(sc->vpd_size, M_SFXGE, M_WAITOK); + if ((rc = efx_vpd_read(sc->enp, sc->vpd_data, sc->vpd_size)) != 0) + goto fail2; + + /* Copy ID (product name) into device description, and log it. */ + value.evv_tag = EFX_VPD_ID; + if (efx_vpd_get(sc->enp, sc->vpd_data, sc->vpd_size, &value) == 0) { + value.evv_value[value.evv_length] = 0; + device_set_desc_copy(sc->dev, value.evv_value); + device_printf(sc->dev, "%s\n", value.evv_value); + } + + vpd_node = SYSCTL_ADD_NODE( + ctx, SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)), + OID_AUTO, "vpd", CTLFLAG_RD, NULL, "Vital Product Data"); + vpd_list = SYSCTL_CHILDREN(vpd_node); + + /* Add sysctls for all expected and any vendor-defined keywords. */ + sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, "PN"); + sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, "EC"); + sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, "SN"); + keyword[0] = 'V'; + keyword[2] = 0; + for (keyword[1] = '0'; keyword[1] <= '9'; keyword[1]++) + sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, keyword); + for (keyword[1] = 'A'; keyword[1] <= 'Z'; keyword[1]++) + sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, keyword); + + return 0; + +fail2: + free(sc->vpd_data, M_SFXGE); +fail: + return rc; +} + +static void +sfxge_vpd_fini(struct sfxge_softc *sc) +{ + free(sc->vpd_data, M_SFXGE); +} + +static void +sfxge_reset(void *arg, int npending) +{ + struct sfxge_softc *sc; + int rc; + + (void)npending; + + sc = (struct sfxge_softc *)arg; + + sx_xlock(&sc->softc_lock); + + if (sc->init_state != SFXGE_STARTED) + goto done; + + sfxge_stop(sc); + efx_nic_reset(sc->enp); + if ((rc = sfxge_start(sc)) != 0) + device_printf(sc->dev, + "reset failed (%d); interface is now stopped\n", + rc); + +done: + sx_xunlock(&sc->softc_lock); +} + +void +sfxge_schedule_reset(struct sfxge_softc *sc) +{ + taskqueue_enqueue(taskqueue_thread, &sc->task_reset); +} + +static int +sfxge_attach(device_t dev) +{ + struct sfxge_softc *sc; + struct ifnet *ifp; + int error; + + sc = device_get_softc(dev); + sc->dev = dev; + + /* Allocate ifnet. */ + ifp = if_alloc(IFT_ETHER); + if (ifp == NULL) { + device_printf(dev, "Couldn't allocate ifnet\n"); + error = ENOMEM; + goto fail; + } + sc->ifnet = ifp; + + /* Initialize hardware. */ + if ((error = sfxge_create(sc)) != 0) + goto fail2; + + /* Create the ifnet for the port. */ + if ((error = sfxge_ifnet_init(ifp, sc)) != 0) + goto fail3; + + if ((error = sfxge_vpd_init(sc)) != 0) + goto fail4; + + sc->init_state = SFXGE_REGISTERED; + + return (0); + +fail4: + sfxge_ifnet_fini(ifp); +fail3: + sfxge_destroy(sc); + +fail2: + if_free(sc->ifnet); + +fail: + return (error); +} + +static int +sfxge_detach(device_t dev) +{ + struct sfxge_softc *sc; + + sc = device_get_softc(dev); + + sfxge_vpd_fini(sc); + + /* Destroy the ifnet. */ + sfxge_ifnet_fini(sc->ifnet); + + /* Tear down hardware. */ + sfxge_destroy(sc); + + return (0); +} + +static int +sfxge_probe(device_t dev) +{ + uint16_t pci_vendor_id; + uint16_t pci_device_id; + efx_family_t family; + int rc; + + pci_vendor_id = pci_get_vendor(dev); + pci_device_id = pci_get_device(dev); + + rc = efx_family(pci_vendor_id, pci_device_id, &family); + if (rc) + return ENXIO; + + KASSERT(family == EFX_FAMILY_SIENA, ("impossible controller family")); + device_set_desc(dev, "Solarflare SFC9000 family"); + return 0; +} + +static device_method_t sfxge_methods[] = { + DEVMETHOD(device_probe, sfxge_probe), + DEVMETHOD(device_attach, sfxge_attach), + DEVMETHOD(device_detach, sfxge_detach), + + /* Bus interface. */ + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_driver_added, bus_generic_driver_added), + + { 0, 0 } +}; + +static devclass_t sfxge_devclass; + +static driver_t sfxge_driver = { + "sfxge", + sfxge_methods, + sizeof(struct sfxge_softc) +}; + +DRIVER_MODULE(sfxge, pci, sfxge_driver, sfxge_devclass, 0, 0); diff --git a/sys/dev/sfxge/sfxge.h b/sys/dev/sfxge/sfxge.h new file mode 100644 index 000000000000..4b6d19a6a6ae --- /dev/null +++ b/sys/dev/sfxge/sfxge.h @@ -0,0 +1,304 @@ +/*- + * Copyright (c) 2010-2011 Solarflare Communications, Inc. + * All rights reserved. + * + * This software was developed in part by Philip Paeps under contract for + * Solarflare Communications, Inc. + * + * 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _SFXGE_H +#define _SFXGE_H + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * Backward-compatibility + */ +#ifndef CACHE_LINE_SIZE +/* This should be right on most machines the driver will be used on, and + * we needn't care too much about wasting a few KB per interface. + */ +#define CACHE_LINE_SIZE 128 +#endif +#ifndef IFCAP_LINKSTATE +#define IFCAP_LINKSTATE 0 +#endif +#ifndef IFCAP_VLAN_HWTSO +#define IFCAP_VLAN_HWTSO 0 +#endif +#ifndef IFM_10G_T +#define IFM_10G_T IFM_UNKNOWN +#endif +#ifndef IFM_10G_KX4 +#define IFM_10G_KX4 IFM_10G_CX4 +#endif +#if __FreeBSD_version >= 800054 +/* Networking core is multiqueue aware. We can manage our own TX + * queues and use m_pkthdr.flowid. + */ +#define SFXGE_HAVE_MQ +#endif +#if (__FreeBSD_version >= 800501 && __FreeBSD_version < 900000) || \ + __FreeBSD_version >= 900003 +#define SFXGE_HAVE_DESCRIBE_INTR +#endif +#ifdef IFM_ETH_RXPAUSE +#define SFXGE_HAVE_PAUSE_MEDIAOPTS +#endif +#ifndef CTLTYPE_U64 +#define CTLTYPE_U64 CTLTYPE_QUAD +#endif + +#include "sfxge_rx.h" +#include "sfxge_tx.h" + +#define SFXGE_IP_ALIGN 2 + +#define SFXGE_ETHERTYPE_LOOPBACK 0x9000 /* Xerox loopback */ + +enum sfxge_evq_state { + SFXGE_EVQ_UNINITIALIZED = 0, + SFXGE_EVQ_INITIALIZED, + SFXGE_EVQ_STARTING, + SFXGE_EVQ_STARTED +}; + +#define SFXGE_EV_BATCH 16384 + +struct sfxge_evq { + struct sfxge_softc *sc __aligned(CACHE_LINE_SIZE); + struct mtx lock __aligned(CACHE_LINE_SIZE); + + enum sfxge_evq_state init_state; + unsigned int index; + efsys_mem_t mem; + unsigned int buf_base_id; + + boolean_t exception; + + efx_evq_t *common; + unsigned int read_ptr; + unsigned int rx_done; + unsigned int tx_done; + + /* Linked list of TX queues with completions to process */ + struct sfxge_txq *txq; + struct sfxge_txq **txqs; +}; + +#define SFXGE_NEVS 4096 +#define SFXGE_NDESCS 1024 +#define SFXGE_MODERATION 30 + +enum sfxge_intr_state { + SFXGE_INTR_UNINITIALIZED = 0, + SFXGE_INTR_INITIALIZED, + SFXGE_INTR_TESTING, + SFXGE_INTR_STARTED +}; + +struct sfxge_intr_hdl { + int eih_rid; + void *eih_tag; + struct resource *eih_res; +}; + +struct sfxge_intr { + enum sfxge_intr_state state; + struct resource *msix_res; + struct sfxge_intr_hdl *table; + int n_alloc; + int type; + efsys_mem_t status; + uint64_t mask; + uint32_t zero_count; +}; + +enum sfxge_mcdi_state { + SFXGE_MCDI_UNINITIALIZED = 0, + SFXGE_MCDI_INITIALIZED, + SFXGE_MCDI_BUSY, + SFXGE_MCDI_COMPLETED +}; + +struct sfxge_mcdi { + struct mtx lock; + struct cv cv; + enum sfxge_mcdi_state state; + efx_mcdi_transport_t transport; +}; + +struct sfxge_hw_stats { + clock_t update_time; + efsys_mem_t dma_buf; + void *decode_buf; +}; + +enum sfxge_port_state { + SFXGE_PORT_UNINITIALIZED = 0, + SFXGE_PORT_INITIALIZED, + SFXGE_PORT_STARTED +}; + +struct sfxge_port { + struct sfxge_softc *sc; + struct mtx lock; + enum sfxge_port_state init_state; +#ifndef SFXGE_HAVE_PAUSE_MEDIAOPTS + unsigned int wanted_fc; +#endif + struct sfxge_hw_stats phy_stats; + struct sfxge_hw_stats mac_stats; + efx_link_mode_t link_mode; +}; + +enum sfxge_softc_state { + SFXGE_UNINITIALIZED = 0, + SFXGE_INITIALIZED, + SFXGE_REGISTERED, + SFXGE_STARTED +}; + +struct sfxge_softc { + device_t dev; + struct sx softc_lock; + enum sfxge_softc_state init_state; + struct ifnet *ifnet; + unsigned int if_flags; + struct sysctl_oid *stats_node; + + struct task task_reset; + + efx_family_t family; + caddr_t vpd_data; + size_t vpd_size; + efx_nic_t *enp; + struct mtx enp_lock; + + bus_dma_tag_t parent_dma_tag; + efsys_bar_t bar; + + struct sfxge_intr intr; + struct sfxge_mcdi mcdi; + struct sfxge_port port; + uint32_t buffer_table_next; + + struct sfxge_evq *evq[SFXGE_RX_SCALE_MAX]; + unsigned int ev_moderation; + clock_t ev_stats_update_time; + uint64_t ev_stats[EV_NQSTATS]; + + uma_zone_t rxq_cache; + struct sfxge_rxq *rxq[SFXGE_RX_SCALE_MAX]; + unsigned int rx_indir_table[SFXGE_RX_SCALE_MAX]; + +#ifdef SFXGE_HAVE_MQ + struct sfxge_txq *txq[SFXGE_TXQ_NTYPES + SFXGE_RX_SCALE_MAX]; +#else + struct sfxge_txq *txq[SFXGE_TXQ_NTYPES]; +#endif + + struct ifmedia media; + + size_t rx_prefix_size; + size_t rx_buffer_size; + uma_zone_t rx_buffer_zone; + +#ifndef SFXGE_HAVE_MQ + struct mtx tx_lock __aligned(CACHE_LINE_SIZE); +#endif +}; + +#define SFXGE_LINK_UP(sc) ((sc)->port.link_mode != EFX_LINK_DOWN) +#define SFXGE_RUNNING(sc) ((sc)->ifnet->if_drv_flags & IFF_DRV_RUNNING) + +/* + * From sfxge.c. + */ +extern void sfxge_schedule_reset(struct sfxge_softc *sc); +extern void sfxge_sram_buf_tbl_alloc(struct sfxge_softc *sc, size_t n, + uint32_t *idp); + +/* + * From sfxge_dma.c. + */ +extern int sfxge_dma_init(struct sfxge_softc *sc); +extern void sfxge_dma_fini(struct sfxge_softc *sc); +extern int sfxge_dma_alloc(struct sfxge_softc *sc, bus_size_t len, + efsys_mem_t *esmp); +extern void sfxge_dma_free(efsys_mem_t *esmp); +extern int sfxge_dma_map_sg_collapse(bus_dma_tag_t tag, bus_dmamap_t map, + struct mbuf **mp, bus_dma_segment_t *segs, int *nsegs, int maxsegs); + +/* + * From sfxge_ev.c. + */ +extern int sfxge_ev_init(struct sfxge_softc *sc); +extern void sfxge_ev_fini(struct sfxge_softc *sc); +extern int sfxge_ev_start(struct sfxge_softc *sc); +extern void sfxge_ev_stop(struct sfxge_softc *sc); +extern int sfxge_ev_qpoll(struct sfxge_softc *sc, unsigned int index); + +/* + * From sfxge_intr.c. + */ +extern int sfxge_intr_init(struct sfxge_softc *sc); +extern void sfxge_intr_fini(struct sfxge_softc *sc); +extern int sfxge_intr_start(struct sfxge_softc *sc); +extern void sfxge_intr_stop(struct sfxge_softc *sc); + +/* + * From sfxge_mcdi.c. + */ +extern int sfxge_mcdi_init(struct sfxge_softc *sc); +extern void sfxge_mcdi_fini(struct sfxge_softc *sc); + +/* + * From sfxge_port.c. + */ +extern int sfxge_port_init(struct sfxge_softc *sc); +extern void sfxge_port_fini(struct sfxge_softc *sc); +extern int sfxge_port_start(struct sfxge_softc *sc); +extern void sfxge_port_stop(struct sfxge_softc *sc); +extern void sfxge_mac_link_update(struct sfxge_softc *sc, + efx_link_mode_t mode); +extern int sfxge_mac_filter_set(struct sfxge_softc *sc); +extern int sfxge_port_ifmedia_init(struct sfxge_softc *sc); + +#define SFXGE_MAX_MTU (9 * 1024) + +#endif /* _SFXGE_H */ diff --git a/sys/dev/sfxge/sfxge_dma.c b/sys/dev/sfxge/sfxge_dma.c new file mode 100644 index 000000000000..d69d4e26968b --- /dev/null +++ b/sys/dev/sfxge/sfxge_dma.c @@ -0,0 +1,202 @@ +/*- + * Copyright (c) 2010-2011 Solarflare Communications, Inc. + * All rights reserved. + * + * This software was developed in part by Philip Paeps under contract for + * Solarflare Communications, Inc. + * + * 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include + +#include "common/efx.h" + +#include "sfxge.h" + +static void +sfxge_dma_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) +{ + bus_addr_t *addr; + + addr = arg; + + if (error) { + *addr = 0; + return; + } + + *addr = segs[0].ds_addr; +} + +int +sfxge_dma_map_sg_collapse(bus_dma_tag_t tag, bus_dmamap_t map, + struct mbuf **mp, bus_dma_segment_t *segs, int *nsegs, int maxsegs) +{ + bus_dma_segment_t *psegs; + struct mbuf *m; + int seg_count; + int defragged; + int err; + + m = *mp; + defragged = err = seg_count = 0; + + KASSERT(m->m_pkthdr.len, ("packet has zero header length")); + +retry: + psegs = segs; + seg_count = 0; + if (m->m_next == NULL) { + sfxge_map_mbuf_fast(tag, map, m, segs); + *nsegs = 1; + return (0); + } +#if defined(__i386__) || defined(__amd64__) + while (m && seg_count < maxsegs) { + /* + * firmware doesn't like empty segments + */ + if (m->m_len != 0) { + seg_count++; + sfxge_map_mbuf_fast(tag, map, m, psegs); + psegs++; + } + m = m->m_next; + } +#else + err = bus_dmamap_load_mbuf_sg(tag, map, *mp, segs, &seg_count, 0); +#endif + if (seg_count == 0) { + err = EFBIG; + goto err_out; + } else if (err == EFBIG || seg_count >= maxsegs) { + if (!defragged) { + m = m_defrag(*mp, M_DONTWAIT); + if (m == NULL) { + err = ENOBUFS; + goto err_out; + } + *mp = m; + defragged = 1; + goto retry; + } + err = EFBIG; + goto err_out; + } + *nsegs = seg_count; + +err_out: + return (err); +} + +void +sfxge_dma_free(efsys_mem_t *esmp) +{ + + bus_dmamap_unload(esmp->esm_tag, esmp->esm_map); + bus_dmamem_free(esmp->esm_tag, esmp->esm_base, esmp->esm_map); + bus_dma_tag_destroy(esmp->esm_tag); + + esmp->esm_addr = 0; + esmp->esm_base = NULL; +} + +int +sfxge_dma_alloc(struct sfxge_softc *sc, bus_size_t len, efsys_mem_t *esmp) +{ + void *vaddr; + + /* Create the child DMA tag. */ + if (bus_dma_tag_create(sc->parent_dma_tag, PAGE_SIZE, 0, + 0x3FFFFFFFFFFFULL, BUS_SPACE_MAXADDR, NULL, NULL, len, 1, len, 0, + NULL, NULL, &esmp->esm_tag) != 0) { + device_printf(sc->dev, "Couldn't allocate txq DMA tag\n"); + return (ENOMEM); + } + + /* Allocate kernel memory. */ + if (bus_dmamem_alloc(esmp->esm_tag, (void **)&vaddr, + BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO, + &esmp->esm_map) != 0) { + device_printf(sc->dev, "Couldn't allocate DMA memory\n"); + bus_dma_tag_destroy(esmp->esm_tag); + return (ENOMEM); + } + + /* Load map into device memory. */ + if (bus_dmamap_load(esmp->esm_tag, esmp->esm_map, vaddr, len, + sfxge_dma_cb, &esmp->esm_addr, 0) != 0) { + device_printf(sc->dev, "Couldn't load DMA mapping\n"); + bus_dmamem_free(esmp->esm_tag, esmp->esm_base, esmp->esm_map); + bus_dma_tag_destroy(esmp->esm_tag); + return (ENOMEM); + } + + /* + * The callback gets error information about the mapping + * and will have set our vaddr to NULL if something went + * wrong. + */ + if (vaddr == NULL) + return (ENOMEM); + + esmp->esm_base = vaddr; + + return (0); +} + +void +sfxge_dma_fini(struct sfxge_softc *sc) +{ + + bus_dma_tag_destroy(sc->parent_dma_tag); +} + +int +sfxge_dma_init(struct sfxge_softc *sc) +{ + + /* Create the parent dma tag. */ + if (bus_dma_tag_create(bus_get_dma_tag(sc->dev), /* parent */ + 1, 0, /* algnmnt, boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + BUS_SPACE_MAXSIZE_32BIT, /* maxsize */ + BUS_SPACE_UNRESTRICTED, /* nsegments */ + BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* lock, lockarg */ + &sc->parent_dma_tag)) { + device_printf(sc->dev, "Cannot allocate parent DMA tag\n"); + return (ENOMEM); + } + + return (0); +} diff --git a/sys/dev/sfxge/sfxge_ev.c b/sys/dev/sfxge/sfxge_ev.c new file mode 100644 index 000000000000..b506b276a6cb --- /dev/null +++ b/sys/dev/sfxge/sfxge_ev.c @@ -0,0 +1,862 @@ +/*- + * Copyright (c) 2010-2011 Solarflare Communications, Inc. + * All rights reserved. + * + * This software was developed in part by Philip Paeps under contract for + * Solarflare Communications, Inc. + * + * 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include "common/efx.h" + +#include "sfxge.h" + +static void +sfxge_ev_qcomplete(struct sfxge_evq *evq, boolean_t eop) +{ + struct sfxge_softc *sc; + unsigned int index; + struct sfxge_rxq *rxq; + struct sfxge_txq *txq; + + sc = evq->sc; + index = evq->index; + rxq = sc->rxq[index]; + + if ((txq = evq->txq) != NULL) { + evq->txq = NULL; + evq->txqs = &(evq->txq); + + do { + struct sfxge_txq *next; + + next = txq->next; + txq->next = NULL; + + KASSERT(txq->evq_index == index, + ("txq->evq_index != index")); + + if (txq->pending != txq->completed) + sfxge_tx_qcomplete(txq); + + txq = next; + } while (txq != NULL); + } + + if (rxq->pending != rxq->completed) + sfxge_rx_qcomplete(rxq, eop); +} + +static boolean_t +sfxge_ev_rx(void *arg, uint32_t label, uint32_t id, uint32_t size, + uint16_t flags) +{ + struct sfxge_evq *evq; + struct sfxge_softc *sc; + struct sfxge_rxq *rxq; + unsigned int expected; + struct sfxge_rx_sw_desc *rx_desc; + + evq = arg; + sc = evq->sc; + + if (evq->exception) + goto done; + + rxq = sc->rxq[label]; + KASSERT(rxq != NULL, ("rxq == NULL")); + KASSERT(evq->index == rxq->index, + ("evq->index != rxq->index")); + + if (rxq->init_state != SFXGE_RXQ_STARTED) + goto done; + + expected = rxq->pending++ & (SFXGE_NDESCS - 1); + if (id != expected) { + evq->exception = B_TRUE; + + device_printf(sc->dev, "RX completion out of order" + " (id=%#x expected=%#x flags=%#x); resetting\n", + id, expected, flags); + sfxge_schedule_reset(sc); + + goto done; + } + + rx_desc = &rxq->queue[id]; + + KASSERT(rx_desc->flags == EFX_DISCARD, + ("rx_desc->flags != EFX_DISCARD")); + rx_desc->flags = flags; + + KASSERT(size < (1 << 16), ("size > (1 << 16)")); + rx_desc->size = (uint16_t)size; + prefetch_read_many(rx_desc->mbuf); + + evq->rx_done++; + + if (rxq->pending - rxq->completed >= SFXGE_RX_BATCH) + sfxge_ev_qcomplete(evq, B_FALSE); + +done: + return (evq->rx_done >= SFXGE_EV_BATCH); +} + +static boolean_t +sfxge_ev_exception(void *arg, uint32_t code, uint32_t data) +{ + struct sfxge_evq *evq; + struct sfxge_softc *sc; + + evq = (struct sfxge_evq *)arg; + sc = evq->sc; + + evq->exception = B_TRUE; + + if (code != EFX_EXCEPTION_UNKNOWN_SENSOREVT) { + device_printf(sc->dev, + "hardware exception (code=%u); resetting\n", + code); + sfxge_schedule_reset(sc); + } + + return (B_FALSE); +} + +static boolean_t +sfxge_ev_rxq_flush_done(void *arg, uint32_t label) +{ + struct sfxge_evq *evq; + struct sfxge_softc *sc; + struct sfxge_rxq *rxq; + unsigned int index; + uint16_t magic; + + evq = (struct sfxge_evq *)arg; + sc = evq->sc; + rxq = sc->rxq[label]; + + KASSERT(rxq != NULL, ("rxq == NULL")); + + /* Resend a software event on the correct queue */ + index = rxq->index; + evq = sc->evq[index]; + + KASSERT((label & SFXGE_MAGIC_DMAQ_LABEL_MASK) == label, + ("(label & SFXGE_MAGIC_DMAQ_LABEL_MASK) != level")); + magic = SFXGE_MAGIC_RX_QFLUSH_DONE | label; + + KASSERT(evq->init_state == SFXGE_EVQ_STARTED, + ("evq not started")); + efx_ev_qpost(evq->common, magic); + + return (B_FALSE); +} + +static boolean_t +sfxge_ev_rxq_flush_failed(void *arg, uint32_t label) +{ + struct sfxge_evq *evq; + struct sfxge_softc *sc; + struct sfxge_rxq *rxq; + unsigned int index; + uint16_t magic; + + evq = (struct sfxge_evq *)arg; + sc = evq->sc; + rxq = sc->rxq[label]; + + KASSERT(rxq != NULL, ("rxq == NULL")); + + /* Resend a software event on the correct queue */ + index = rxq->index; + evq = sc->evq[index]; + + KASSERT((label & SFXGE_MAGIC_DMAQ_LABEL_MASK) == label, + ("(label & SFXGE_MAGIC_DMAQ_LABEL_MASK) != label")); + magic = SFXGE_MAGIC_RX_QFLUSH_FAILED | label; + + KASSERT(evq->init_state == SFXGE_EVQ_STARTED, + ("evq not started")); + efx_ev_qpost(evq->common, magic); + + return (B_FALSE); +} + +static boolean_t +sfxge_ev_tx(void *arg, uint32_t label, uint32_t id) +{ + struct sfxge_evq *evq; + struct sfxge_softc *sc; + struct sfxge_txq *txq; + unsigned int stop; + unsigned int delta; + + evq = (struct sfxge_evq *)arg; + sc = evq->sc; + txq = sc->txq[label]; + + KASSERT(txq != NULL, ("txq == NULL")); + KASSERT(evq->index == txq->evq_index, + ("evq->index != txq->evq_index")); + + if (txq->init_state != SFXGE_TXQ_STARTED) + goto done; + + stop = (id + 1) & (SFXGE_NDESCS - 1); + id = txq->pending & (SFXGE_NDESCS - 1); + + delta = (stop >= id) ? (stop - id) : (SFXGE_NDESCS - id + stop); + txq->pending += delta; + + evq->tx_done++; + + if (txq->next == NULL && + evq->txqs != &(txq->next)) { + *(evq->txqs) = txq; + evq->txqs = &(txq->next); + } + + if (txq->pending - txq->completed >= SFXGE_TX_BATCH) + sfxge_tx_qcomplete(txq); + +done: + return (evq->tx_done >= SFXGE_EV_BATCH); +} + +static boolean_t +sfxge_ev_txq_flush_done(void *arg, uint32_t label) +{ + struct sfxge_evq *evq; + struct sfxge_softc *sc; + struct sfxge_txq *txq; + uint16_t magic; + + evq = (struct sfxge_evq *)arg; + sc = evq->sc; + txq = sc->txq[label]; + + KASSERT(txq != NULL, ("txq == NULL")); + KASSERT(txq->init_state == SFXGE_TXQ_INITIALIZED, + ("txq not initialized")); + + /* Resend a software event on the correct queue */ + evq = sc->evq[txq->evq_index]; + + KASSERT((label & SFXGE_MAGIC_DMAQ_LABEL_MASK) == label, + ("(label & SFXGE_MAGIC_DMAQ_LABEL_MASK) != label")); + magic = SFXGE_MAGIC_TX_QFLUSH_DONE | label; + + KASSERT(evq->init_state == SFXGE_EVQ_STARTED, + ("evq not started")); + efx_ev_qpost(evq->common, magic); + + return (B_FALSE); +} + +static boolean_t +sfxge_ev_software(void *arg, uint16_t magic) +{ + struct sfxge_evq *evq; + struct sfxge_softc *sc; + unsigned int label; + + evq = (struct sfxge_evq *)arg; + sc = evq->sc; + + label = magic & SFXGE_MAGIC_DMAQ_LABEL_MASK; + magic &= ~SFXGE_MAGIC_DMAQ_LABEL_MASK; + + switch (magic) { + case SFXGE_MAGIC_RX_QFLUSH_DONE: { + struct sfxge_rxq *rxq = sc->rxq[label]; + + KASSERT(rxq != NULL, ("rxq == NULL")); + KASSERT(evq->index == rxq->index, + ("evq->index != rxq->index")); + + sfxge_rx_qflush_done(rxq); + break; + } + case SFXGE_MAGIC_RX_QFLUSH_FAILED: { + struct sfxge_rxq *rxq = sc->rxq[label]; + + KASSERT(rxq != NULL, ("rxq == NULL")); + KASSERT(evq->index == rxq->index, + ("evq->index != rxq->index")); + + sfxge_rx_qflush_failed(rxq); + break; + } + case SFXGE_MAGIC_RX_QREFILL: { + struct sfxge_rxq *rxq = sc->rxq[label]; + + KASSERT(rxq != NULL, ("rxq == NULL")); + KASSERT(evq->index == rxq->index, + ("evq->index != rxq->index")); + + sfxge_rx_qrefill(rxq); + break; + } + case SFXGE_MAGIC_TX_QFLUSH_DONE: { + struct sfxge_txq *txq = sc->txq[label]; + + KASSERT(txq != NULL, ("txq == NULL")); + KASSERT(evq->index == txq->evq_index, + ("evq->index != txq->evq_index")); + + sfxge_tx_qflush_done(txq); + break; + } + default: + break; + } + + return (B_FALSE); +} + +static boolean_t +sfxge_ev_sram(void *arg, uint32_t code) +{ + (void)arg; + (void)code; + + switch (code) { + case EFX_SRAM_UPDATE: + EFSYS_PROBE(sram_update); + break; + + case EFX_SRAM_CLEAR: + EFSYS_PROBE(sram_clear); + break; + + case EFX_SRAM_ILLEGAL_CLEAR: + EFSYS_PROBE(sram_illegal_clear); + break; + + default: + KASSERT(B_FALSE, ("Impossible SRAM event")); + break; + } + + return (B_FALSE); +} + +static boolean_t +sfxge_ev_timer(void *arg, uint32_t index) +{ + (void)arg; + (void)index; + + return (B_FALSE); +} + +static boolean_t +sfxge_ev_wake_up(void *arg, uint32_t index) +{ + (void)arg; + (void)index; + + return (B_FALSE); +} + +static void +sfxge_ev_stat_update(struct sfxge_softc *sc) +{ + struct sfxge_evq *evq; + unsigned int index; + clock_t now; + + sx_xlock(&sc->softc_lock); + + if (sc->evq[0]->init_state != SFXGE_EVQ_STARTED) + goto out; + + now = ticks; + if (now - sc->ev_stats_update_time < hz) + goto out; + + sc->ev_stats_update_time = now; + + /* Add event counts from each event queue in turn */ + for (index = 0; index < sc->intr.n_alloc; index++) { + evq = sc->evq[index]; + mtx_lock(&evq->lock); + efx_ev_qstats_update(evq->common, sc->ev_stats); + mtx_unlock(&evq->lock); + } +out: + sx_xunlock(&sc->softc_lock); +} + +static int +sfxge_ev_stat_handler(SYSCTL_HANDLER_ARGS) +{ + struct sfxge_softc *sc = arg1; + unsigned int id = arg2; + + sfxge_ev_stat_update(sc); + + return SYSCTL_OUT(req, &sc->ev_stats[id], sizeof(sc->ev_stats[id])); +} + +static void +sfxge_ev_stat_init(struct sfxge_softc *sc) +{ + struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev); + struct sysctl_oid_list *stat_list; + unsigned int id; + char name[40]; + + stat_list = SYSCTL_CHILDREN(sc->stats_node); + + for (id = 0; id < EV_NQSTATS; id++) { + snprintf(name, sizeof(name), "ev_%s", + efx_ev_qstat_name(sc->enp, id)); + SYSCTL_ADD_PROC( + ctx, stat_list, + OID_AUTO, name, CTLTYPE_U64|CTLFLAG_RD, + sc, id, sfxge_ev_stat_handler, "Q", + ""); + } +} + +static void +sfxge_ev_qmoderate(struct sfxge_softc *sc, unsigned int idx, unsigned int us) +{ + struct sfxge_evq *evq; + efx_evq_t *eep; + + evq = sc->evq[idx]; + eep = evq->common; + + KASSERT(evq->init_state == SFXGE_EVQ_STARTED, + ("evq->init_state != SFXGE_EVQ_STARTED")); + + (void)efx_ev_qmoderate(eep, us); +} + +static int +sfxge_int_mod_handler(SYSCTL_HANDLER_ARGS) +{ + struct sfxge_softc *sc = arg1; + struct sfxge_intr *intr = &sc->intr; + unsigned int moderation; + int error; + int index; + + sx_xlock(&sc->softc_lock); + + if (req->newptr) { + if ((error = SYSCTL_IN(req, &moderation, sizeof(moderation))) + != 0) + goto out; + + /* We may not be calling efx_ev_qmoderate() now, + * so we have to range-check the value ourselves. + */ + if (moderation > + efx_nic_cfg_get(sc->enp)->enc_evq_moderation_max) { + error = EINVAL; + goto out; + } + + sc->ev_moderation = moderation; + if (intr->state == SFXGE_INTR_STARTED) { + for (index = 0; index < intr->n_alloc; index++) + sfxge_ev_qmoderate(sc, index, moderation); + } + } else { + error = SYSCTL_OUT(req, &sc->ev_moderation, + sizeof(sc->ev_moderation)); + } + +out: + sx_xunlock(&sc->softc_lock); + + return error; +} + +static boolean_t +sfxge_ev_initialized(void *arg) +{ + struct sfxge_evq *evq; + + evq = (struct sfxge_evq *)arg; + + KASSERT(evq->init_state == SFXGE_EVQ_STARTING, + ("evq not starting")); + + evq->init_state = SFXGE_EVQ_STARTED; + + return (0); +} + +static boolean_t +sfxge_ev_link_change(void *arg, efx_link_mode_t link_mode) +{ + struct sfxge_evq *evq; + struct sfxge_softc *sc; + + evq = (struct sfxge_evq *)arg; + sc = evq->sc; + + sfxge_mac_link_update(sc, link_mode); + + return (0); +} + +static const efx_ev_callbacks_t sfxge_ev_callbacks = { + .eec_initialized = sfxge_ev_initialized, + .eec_rx = sfxge_ev_rx, + .eec_tx = sfxge_ev_tx, + .eec_exception = sfxge_ev_exception, + .eec_rxq_flush_done = sfxge_ev_rxq_flush_done, + .eec_rxq_flush_failed = sfxge_ev_rxq_flush_failed, + .eec_txq_flush_done = sfxge_ev_txq_flush_done, + .eec_software = sfxge_ev_software, + .eec_sram = sfxge_ev_sram, + .eec_wake_up = sfxge_ev_wake_up, + .eec_timer = sfxge_ev_timer, + .eec_link_change = sfxge_ev_link_change, +}; + + +int +sfxge_ev_qpoll(struct sfxge_softc *sc, unsigned int index) +{ + struct sfxge_evq *evq; + int rc; + + evq = sc->evq[index]; + + mtx_lock(&evq->lock); + + if (evq->init_state != SFXGE_EVQ_STARTING && + evq->init_state != SFXGE_EVQ_STARTED) { + rc = EINVAL; + goto fail; + } + + /* Synchronize the DMA memory for reading */ + bus_dmamap_sync(evq->mem.esm_tag, evq->mem.esm_map, + BUS_DMASYNC_POSTREAD); + + KASSERT(evq->rx_done == 0, ("evq->rx_done != 0")); + KASSERT(evq->tx_done == 0, ("evq->tx_done != 0")); + KASSERT(evq->txq == NULL, ("evq->txq != NULL")); + KASSERT(evq->txqs == &evq->txq, ("evq->txqs != &evq->txq")); + + /* Poll the queue */ + efx_ev_qpoll(evq->common, &evq->read_ptr, &sfxge_ev_callbacks, evq); + + evq->rx_done = 0; + evq->tx_done = 0; + + /* Perform any pending completion processing */ + sfxge_ev_qcomplete(evq, B_TRUE); + + /* Re-prime the event queue for interrupts */ + if ((rc = efx_ev_qprime(evq->common, evq->read_ptr)) != 0) + goto fail; + + mtx_unlock(&evq->lock); + + return (0); + +fail: + mtx_unlock(&(evq->lock)); + return (rc); +} + +static void +sfxge_ev_qstop(struct sfxge_softc *sc, unsigned int index) +{ + struct sfxge_evq *evq; + + evq = sc->evq[index]; + + KASSERT(evq->init_state == SFXGE_EVQ_STARTED, + ("evq->init_state != SFXGE_EVQ_STARTED")); + + mtx_lock(&evq->lock); + evq->init_state = SFXGE_EVQ_INITIALIZED; + evq->read_ptr = 0; + evq->exception = B_FALSE; + + /* Add event counts before discarding the common evq state */ + efx_ev_qstats_update(evq->common, sc->ev_stats); + + efx_ev_qdestroy(evq->common); + efx_sram_buf_tbl_clear(sc->enp, evq->buf_base_id, + EFX_EVQ_NBUFS(SFXGE_NEVS)); + mtx_unlock(&evq->lock); +} + +static int +sfxge_ev_qstart(struct sfxge_softc *sc, unsigned int index) +{ + struct sfxge_evq *evq; + efsys_mem_t *esmp; + int count; + int rc; + + evq = sc->evq[index]; + esmp = &evq->mem; + + KASSERT(evq->init_state == SFXGE_EVQ_INITIALIZED, + ("evq->init_state != SFXGE_EVQ_INITIALIZED")); + + /* Clear all events. */ + (void)memset(esmp->esm_base, 0xff, EFX_EVQ_SIZE(SFXGE_NEVS)); + + /* Program the buffer table. */ + if ((rc = efx_sram_buf_tbl_set(sc->enp, evq->buf_base_id, esmp, + EFX_EVQ_NBUFS(SFXGE_NEVS))) != 0) + return rc; + + /* Create the common code event queue. */ + if ((rc = efx_ev_qcreate(sc->enp, index, esmp, SFXGE_NEVS, + evq->buf_base_id, &evq->common)) != 0) + goto fail; + + mtx_lock(&evq->lock); + + /* Set the default moderation */ + (void)efx_ev_qmoderate(evq->common, sc->ev_moderation); + + /* Prime the event queue for interrupts */ + if ((rc = efx_ev_qprime(evq->common, evq->read_ptr)) != 0) + goto fail2; + + evq->init_state = SFXGE_EVQ_STARTING; + + mtx_unlock(&evq->lock); + + /* Wait for the initialization event */ + count = 0; + do { + /* Pause for 100 ms */ + pause("sfxge evq init", hz / 10); + + /* Check to see if the test event has been processed */ + if (evq->init_state == SFXGE_EVQ_STARTED) + goto done; + + } while (++count < 20); + + rc = ETIMEDOUT; + goto fail3; + +done: + return (0); + +fail3: + mtx_lock(&evq->lock); + evq->init_state = SFXGE_EVQ_INITIALIZED; +fail2: + mtx_unlock(&evq->lock); + efx_ev_qdestroy(evq->common); +fail: + efx_sram_buf_tbl_clear(sc->enp, evq->buf_base_id, + EFX_EVQ_NBUFS(SFXGE_NEVS)); + + return (rc); +} + +void +sfxge_ev_stop(struct sfxge_softc *sc) +{ + struct sfxge_intr *intr; + efx_nic_t *enp; + int index; + + intr = &sc->intr; + enp = sc->enp; + + KASSERT(intr->state == SFXGE_INTR_STARTED, + ("Interrupts not started")); + + /* Stop the event queue(s) */ + index = intr->n_alloc; + while (--index >= 0) + sfxge_ev_qstop(sc, index); + + /* Tear down the event module */ + efx_ev_fini(enp); +} + +int +sfxge_ev_start(struct sfxge_softc *sc) +{ + struct sfxge_intr *intr; + int index; + int rc; + + intr = &sc->intr; + + KASSERT(intr->state == SFXGE_INTR_STARTED, + ("intr->state != SFXGE_INTR_STARTED")); + + /* Initialize the event module */ + if ((rc = efx_ev_init(sc->enp)) != 0) + return rc; + + /* Start the event queues */ + for (index = 0; index < intr->n_alloc; index++) { + if ((rc = sfxge_ev_qstart(sc, index)) != 0) + goto fail; + } + + return (0); + +fail: + /* Stop the event queue(s) */ + while (--index >= 0) + sfxge_ev_qstop(sc, index); + + /* Tear down the event module */ + efx_ev_fini(sc->enp); + + return (rc); +} + +static void +sfxge_ev_qfini(struct sfxge_softc *sc, unsigned int index) +{ + struct sfxge_evq *evq; + + evq = sc->evq[index]; + + KASSERT(evq->init_state == SFXGE_EVQ_INITIALIZED, + ("evq->init_state != SFXGE_EVQ_INITIALIZED")); + KASSERT(evq->txqs == &evq->txq, ("evq->txqs != &evq->txq")); + + sfxge_dma_free(&evq->mem); + + sc->evq[index] = NULL; + + mtx_destroy(&evq->lock); + + free(evq, M_SFXGE); +} + +static int +sfxge_ev_qinit(struct sfxge_softc *sc, unsigned int index) +{ + struct sfxge_evq *evq; + efsys_mem_t *esmp; + int rc; + + KASSERT(index < SFXGE_RX_SCALE_MAX, ("index >= SFXGE_RX_SCALE_MAX")); + + evq = malloc(sizeof(struct sfxge_evq), M_SFXGE, M_ZERO | M_WAITOK); + evq->sc = sc; + evq->index = index; + sc->evq[index] = evq; + esmp = &evq->mem; + + /* Initialise TX completion list */ + evq->txqs = &evq->txq; + + /* Allocate DMA space. */ + if ((rc = sfxge_dma_alloc(sc, EFX_EVQ_SIZE(SFXGE_NEVS), esmp)) != 0) + return (rc); + + /* Allocate buffer table entries. */ + sfxge_sram_buf_tbl_alloc(sc, EFX_EVQ_NBUFS(SFXGE_NEVS), + &evq->buf_base_id); + + mtx_init(&evq->lock, "evq", NULL, MTX_DEF); + + evq->init_state = SFXGE_EVQ_INITIALIZED; + + return (0); +} + +void +sfxge_ev_fini(struct sfxge_softc *sc) +{ + struct sfxge_intr *intr; + int index; + + intr = &sc->intr; + + KASSERT(intr->state == SFXGE_INTR_INITIALIZED, + ("intr->state != SFXGE_INTR_INITIALIZED")); + + sc->ev_moderation = 0; + + /* Tear down the event queue(s). */ + index = intr->n_alloc; + while (--index >= 0) + sfxge_ev_qfini(sc, index); +} + +int +sfxge_ev_init(struct sfxge_softc *sc) +{ + struct sysctl_ctx_list *sysctl_ctx = device_get_sysctl_ctx(sc->dev); + struct sysctl_oid *sysctl_tree = device_get_sysctl_tree(sc->dev); + struct sfxge_intr *intr; + int index; + int rc; + + intr = &sc->intr; + + KASSERT(intr->state == SFXGE_INTR_INITIALIZED, + ("intr->state != SFXGE_INTR_INITIALIZED")); + + /* Set default interrupt moderation; add a sysctl to + * read and change it. + */ + sc->ev_moderation = 30; + SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), + OID_AUTO, "int_mod", CTLTYPE_UINT|CTLFLAG_RW, + sc, 0, sfxge_int_mod_handler, "IU", + "sfxge interrupt moderation (us)"); + + /* + * Initialize the event queue(s) - one per interrupt. + */ + for (index = 0; index < intr->n_alloc; index++) { + if ((rc = sfxge_ev_qinit(sc, index)) != 0) + goto fail; + } + + sfxge_ev_stat_init(sc); + + return (0); + +fail: + while (--index >= 0) + sfxge_ev_qfini(sc, index); + + return (rc); +} diff --git a/sys/dev/sfxge/sfxge_intr.c b/sys/dev/sfxge/sfxge_intr.c new file mode 100644 index 000000000000..5cf13628efe3 --- /dev/null +++ b/sys/dev/sfxge/sfxge_intr.c @@ -0,0 +1,577 @@ +/*- + * Copyright (c) 2010-2011 Solarflare Communications, Inc. + * All rights reserved. + * + * This software was developed in part by Philip Paeps under contract for + * Solarflare Communications, Inc. + * + * 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "common/efx.h" + +#include "sfxge.h" + +static int +sfxge_intr_line_filter(void *arg) +{ + struct sfxge_evq *evq; + struct sfxge_softc *sc; + efx_nic_t *enp; + struct sfxge_intr *intr; + boolean_t fatal; + uint32_t qmask; + + evq = (struct sfxge_evq *)arg; + sc = evq->sc; + enp = sc->enp; + intr = &sc->intr; + + KASSERT(intr != NULL, ("intr == NULL")); + KASSERT(intr->type == EFX_INTR_LINE, + ("intr->type != EFX_INTR_LINE")); + + if (intr->state != SFXGE_INTR_STARTED && + intr->state != SFXGE_INTR_TESTING) + return FILTER_STRAY; + + if (intr->state == SFXGE_INTR_TESTING) { + intr->mask |= 1; /* only one interrupt */ + return FILTER_HANDLED; + } + + (void)efx_intr_status_line(enp, &fatal, &qmask); + + if (fatal) { + (void) efx_intr_disable(enp); + (void) efx_intr_fatal(enp); + return FILTER_HANDLED; + } + + if (qmask != 0) { + intr->zero_count = 0; + return FILTER_SCHEDULE_THREAD; + } + + /* SF bug 15783: If the function is not asserting its IRQ and + * we read the queue mask on the cycle before a flag is added + * to the mask, this inhibits the function from asserting the + * IRQ even though we don't see the flag set. To work around + * this, we must re-prime all event queues and report the IRQ + * as handled when we see a mask of zero. To allow for shared + * IRQs, we don't repeat this if we see a mask of zero twice + * or more in a row. + */ + if (intr->zero_count++ == 0) { + if (evq->init_state == SFXGE_EVQ_STARTED) { + if (efx_ev_qpending(evq->common, evq->read_ptr)) + return FILTER_SCHEDULE_THREAD; + efx_ev_qprime(evq->common, evq->read_ptr); + return FILTER_HANDLED; + } + } + + return FILTER_STRAY; +} + +static void +sfxge_intr_line(void *arg) +{ + struct sfxge_evq *evq = arg; + struct sfxge_softc *sc = evq->sc; + + (void)sfxge_ev_qpoll(sc, 0); +} + +static void +sfxge_intr_message(void *arg) +{ + struct sfxge_evq *evq; + struct sfxge_softc *sc; + efx_nic_t *enp; + struct sfxge_intr *intr; + unsigned int index; + boolean_t fatal; + + evq = (struct sfxge_evq *)arg; + sc = evq->sc; + enp = sc->enp; + intr = &sc->intr; + index = evq->index; + + KASSERT(intr != NULL, ("intr == NULL")); + KASSERT(intr->type == EFX_INTR_MESSAGE, + ("intr->type != EFX_INTR_MESSAGE")); + + if (intr->state != SFXGE_INTR_STARTED && + intr->state != SFXGE_INTR_TESTING) + return; + + if (intr->state == SFXGE_INTR_TESTING) { + uint64_t mask; + + do { + mask = intr->mask; + } while (atomic_cmpset_long(&intr->mask, mask, + mask | (1 << index)) == 0); + + return; + } + + (void)efx_intr_status_message(enp, index, &fatal); + + if (fatal) { + (void)efx_intr_disable(enp); + (void)efx_intr_fatal(enp); + return; + } + + (void)sfxge_ev_qpoll(sc, index); +} + +static int +sfxge_intr_bus_enable(struct sfxge_softc *sc) +{ + struct sfxge_intr *intr; + struct sfxge_intr_hdl *table; + driver_filter_t *filter; + driver_intr_t *handler; + int index; + int err; + + intr = &sc->intr; + table = intr->table; + + switch (intr->type) { + case EFX_INTR_MESSAGE: + filter = NULL; /* not shared */ + handler = sfxge_intr_message; + break; + + case EFX_INTR_LINE: + filter = sfxge_intr_line_filter; + handler = sfxge_intr_line; + break; + + default: + KASSERT(0, ("Invalid interrupt type")); + return EINVAL; + } + + /* Try to add the handlers */ + for (index = 0; index < intr->n_alloc; index++) { + if ((err = bus_setup_intr(sc->dev, table[index].eih_res, + INTR_MPSAFE|INTR_TYPE_NET, filter, handler, + sc->evq[index], &table[index].eih_tag)) != 0) { + goto fail; + } +#ifdef SFXGE_HAVE_DESCRIBE_INTR + if (intr->n_alloc > 1) + bus_describe_intr(sc->dev, table[index].eih_res, + table[index].eih_tag, "%d", index); +#endif + bus_bind_intr(sc->dev, table[index].eih_res, index); + + } + + return (0); + +fail: + /* Remove remaining handlers */ + while (--index >= 0) + bus_teardown_intr(sc->dev, table[index].eih_res, + table[index].eih_tag); + + return (err); +} + +static void +sfxge_intr_bus_disable(struct sfxge_softc *sc) +{ + struct sfxge_intr *intr; + struct sfxge_intr_hdl *table; + int i; + + intr = &sc->intr; + table = intr->table; + + /* Remove all handlers */ + for (i = 0; i < intr->n_alloc; i++) + bus_teardown_intr(sc->dev, table[i].eih_res, + table[i].eih_tag); +} + +static int +sfxge_intr_alloc(struct sfxge_softc *sc, int count) +{ + device_t dev; + struct sfxge_intr_hdl *table; + struct sfxge_intr *intr; + struct resource *res; + int rid; + int error; + int i; + + dev = sc->dev; + intr = &sc->intr; + error = 0; + + table = malloc(count * sizeof(struct sfxge_intr_hdl), + M_SFXGE, M_WAITOK); + intr->table = table; + + for (i = 0; i < count; i++) { + rid = i + 1; + res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_SHAREABLE | RF_ACTIVE); + if (res == NULL) { + device_printf(dev, "Couldn't allocate interrupts for " + "message %d\n", rid); + error = ENOMEM; + break; + } + table[i].eih_rid = rid; + table[i].eih_res = res; + } + + if (error) { + count = i - 1; + for (i = 0; i < count; i++) + bus_release_resource(dev, SYS_RES_IRQ, + table[i].eih_rid, table[i].eih_res); + } + + return (error); +} + +static void +sfxge_intr_teardown_msix(struct sfxge_softc *sc) +{ + device_t dev; + struct resource *resp; + int rid; + + dev = sc->dev; + resp = sc->intr.msix_res; + + rid = rman_get_rid(resp); + bus_release_resource(dev, SYS_RES_MEMORY, rid, resp); +} + +static int +sfxge_intr_setup_msix(struct sfxge_softc *sc) +{ + struct sfxge_intr *intr; + struct resource *resp; + device_t dev; + int count; + int rid; + + dev = sc->dev; + intr = &sc->intr; + + /* Check if MSI-X is available. */ + count = pci_msix_count(dev); + if (count == 0) + return (EINVAL); + + /* Limit the number of interrupts to the number of CPUs. */ + if (count > mp_ncpus) + count = mp_ncpus; + + /* Not very likely these days... */ + if (count > EFX_MAXRSS) + count = EFX_MAXRSS; + + rid = PCIR_BAR(4); + resp = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); + if (resp == NULL) + return (ENOMEM); + + if (pci_alloc_msix(dev, &count) != 0) { + bus_release_resource(dev, SYS_RES_MEMORY, rid, resp); + return (ENOMEM); + } + + /* Allocate interrupt handlers. */ + if (sfxge_intr_alloc(sc, count) != 0) { + bus_release_resource(dev, SYS_RES_MEMORY, rid, resp); + pci_release_msi(dev); + return (ENOMEM); + } + + intr->type = EFX_INTR_MESSAGE; + intr->n_alloc = count; + intr->msix_res = resp; + + return (0); +} + +static int +sfxge_intr_setup_msi(struct sfxge_softc *sc) +{ + struct sfxge_intr_hdl *table; + struct sfxge_intr *intr; + device_t dev; + int count; + int error; + + dev = sc->dev; + intr = &sc->intr; + table = intr->table; + + /* + * Check if MSI is available. All messages must be written to + * the same address and on x86 this means the IRQs have the + * same CPU affinity. So we only ever allocate 1. + */ + count = pci_msi_count(dev) ? 1 : 0; + if (count == 0) + return (EINVAL); + + if ((error = pci_alloc_msi(dev, &count)) != 0) + return (ENOMEM); + + /* Allocate interrupt handler. */ + if (sfxge_intr_alloc(sc, count) != 0) { + pci_release_msi(dev); + return (ENOMEM); + } + + intr->type = EFX_INTR_MESSAGE; + intr->n_alloc = count; + + return (0); +} + +static int +sfxge_intr_setup_fixed(struct sfxge_softc *sc) +{ + struct sfxge_intr_hdl *table; + struct sfxge_intr *intr; + struct resource *res; + device_t dev; + int rid; + + dev = sc->dev; + intr = &sc->intr; + + rid = 0; + res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_SHAREABLE | RF_ACTIVE); + if (res == NULL) + return (ENOMEM); + + table = malloc(sizeof(struct sfxge_intr_hdl), M_SFXGE, M_WAITOK); + table[0].eih_rid = rid; + table[0].eih_res = res; + + intr->type = EFX_INTR_LINE; + intr->n_alloc = 1; + intr->table = table; + + return (0); +} + +static const char *const __sfxge_err[] = { + "", + "SRAM out-of-bounds", + "Buffer ID out-of-bounds", + "Internal memory parity", + "Receive buffer ownership", + "Transmit buffer ownership", + "Receive descriptor ownership", + "Transmit descriptor ownership", + "Event queue ownership", + "Event queue FIFO overflow", + "Illegal address", + "SRAM parity" +}; + +void +sfxge_err(efsys_identifier_t *arg, unsigned int code, uint32_t dword0, + uint32_t dword1) +{ + struct sfxge_softc *sc = (struct sfxge_softc *)arg; + device_t dev = sc->dev; + + log(LOG_WARNING, "[%s%d] FATAL ERROR: %s (0x%08x%08x)", + device_get_name(dev), device_get_unit(dev), + __sfxge_err[code], dword1, dword0); +} + +void +sfxge_intr_stop(struct sfxge_softc *sc) +{ + struct sfxge_intr *intr; + + intr = &sc->intr; + + KASSERT(intr->state == SFXGE_INTR_STARTED, + ("Interrupts not started")); + + intr->state = SFXGE_INTR_INITIALIZED; + + /* Disable interrupts at the NIC */ + intr->mask = 0; + efx_intr_disable(sc->enp); + + /* Disable interrupts at the bus */ + sfxge_intr_bus_disable(sc); + + /* Tear down common code interrupt bits. */ + efx_intr_fini(sc->enp); +} + +int +sfxge_intr_start(struct sfxge_softc *sc) +{ + struct sfxge_intr *intr; + efsys_mem_t *esmp; + int rc; + + intr = &sc->intr; + esmp = &intr->status; + + KASSERT(intr->state == SFXGE_INTR_INITIALIZED, + ("Interrupts not initialized")); + + /* Zero the memory. */ + (void)memset(esmp->esm_base, 0, EFX_INTR_SIZE); + + /* Initialize common code interrupt bits. */ + (void)efx_intr_init(sc->enp, intr->type, esmp); + + /* Enable interrupts at the bus */ + if ((rc = sfxge_intr_bus_enable(sc)) != 0) + goto fail; + + intr->state = SFXGE_INTR_TESTING; + + /* Enable interrupts at the NIC */ + efx_intr_enable(sc->enp); + + intr->state = SFXGE_INTR_STARTED; + + return (0); + +fail: + /* Tear down common code interrupt bits. */ + efx_intr_fini(sc->enp); + + intr->state = SFXGE_INTR_INITIALIZED; + + return (rc); +} + +void +sfxge_intr_fini(struct sfxge_softc *sc) +{ + struct sfxge_intr_hdl *table; + struct sfxge_intr *intr; + efsys_mem_t *esmp; + device_t dev; + int i; + + dev = sc->dev; + intr = &sc->intr; + esmp = &intr->status; + table = intr->table; + + KASSERT(intr->state == SFXGE_INTR_INITIALIZED, + ("intr->state != SFXGE_INTR_INITIALIZED")); + + /* Free DMA memory. */ + sfxge_dma_free(esmp); + + /* Free interrupt handles. */ + for (i = 0; i < intr->n_alloc; i++) + bus_release_resource(dev, SYS_RES_IRQ, + table[i].eih_rid, table[i].eih_res); + + if (table[0].eih_rid != 0) + pci_release_msi(dev); + + if (intr->msix_res != NULL) + sfxge_intr_teardown_msix(sc); + + /* Free the handle table */ + free(table, M_SFXGE); + intr->table = NULL; + intr->n_alloc = 0; + + /* Clear the interrupt type */ + intr->type = EFX_INTR_INVALID; + + intr->state = SFXGE_INTR_UNINITIALIZED; +} + +int +sfxge_intr_init(struct sfxge_softc *sc) +{ + device_t dev; + struct sfxge_intr *intr; + efsys_mem_t *esmp; + int rc; + + dev = sc->dev; + intr = &sc->intr; + esmp = &intr->status; + + KASSERT(intr->state == SFXGE_INTR_UNINITIALIZED, + ("Interrupts already initialized")); + + /* Try to setup MSI-X or MSI interrupts if available. */ + if ((rc = sfxge_intr_setup_msix(sc)) == 0) + device_printf(dev, "Using MSI-X interrupts\n"); + else if ((rc = sfxge_intr_setup_msi(sc)) == 0) + device_printf(dev, "Using MSI interrupts\n"); + else if ((rc = sfxge_intr_setup_fixed(sc)) == 0) { + device_printf(dev, "Using fixed interrupts\n"); + } else { + device_printf(dev, "Couldn't setup interrupts\n"); + return (ENOMEM); + } + + /* Set up DMA for interrupts. */ + if ((rc = sfxge_dma_alloc(sc, EFX_INTR_SIZE, esmp)) != 0) + return (ENOMEM); + + intr->state = SFXGE_INTR_INITIALIZED; + + return (0); +} diff --git a/sys/dev/sfxge/sfxge_mcdi.c b/sys/dev/sfxge/sfxge_mcdi.c new file mode 100644 index 000000000000..6368ab4357b3 --- /dev/null +++ b/sys/dev/sfxge/sfxge_mcdi.c @@ -0,0 +1,250 @@ +/*- + * Copyright (c) 2010-2011 Solarflare Communications, Inc. + * All rights reserved. + * + * This software was developed in part by Philip Paeps under contract for + * Solarflare Communications, Inc. + * + * 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include "common/efx.h" +#include "common/efx_mcdi.h" +#include "common/efx_regs_mcdi.h" + +#include "sfxge.h" + +#define SFXGE_MCDI_POLL_INTERVAL_MIN 10 /* 10us in 1us units */ +#define SFXGE_MCDI_POLL_INTERVAL_MAX 100000 /* 100ms in 1us units */ +#define SFXGE_MCDI_WATCHDOG_INTERVAL 10000000 /* 10s in 1us units */ + +/* Acquire exclusive access to MCDI for the duration of a request. */ +static void +sfxge_mcdi_acquire(struct sfxge_mcdi *mcdi) +{ + + mtx_lock(&mcdi->lock); + KASSERT(mcdi->state != SFXGE_MCDI_UNINITIALIZED, + ("MCDI not initialized")); + + while (mcdi->state != SFXGE_MCDI_INITIALIZED) + (void)cv_wait_sig(&mcdi->cv, &mcdi->lock); + mcdi->state = SFXGE_MCDI_BUSY; + + mtx_unlock(&mcdi->lock); +} + +/* Release ownership of MCDI on request completion. */ +static void +sfxge_mcdi_release(struct sfxge_mcdi *mcdi) +{ + + mtx_lock(&mcdi->lock); + KASSERT((mcdi->state == SFXGE_MCDI_BUSY || + mcdi->state == SFXGE_MCDI_COMPLETED), + ("MCDI not busy or task not completed")); + + mcdi->state = SFXGE_MCDI_INITIALIZED; + cv_broadcast(&mcdi->cv); + + mtx_unlock(&mcdi->lock); +} + +static void +sfxge_mcdi_timeout(struct sfxge_softc *sc) +{ + device_t dev = sc->dev; + + log(LOG_WARNING, "[%s%d] MC_TIMEOUT", device_get_name(dev), + device_get_unit(dev)); + + EFSYS_PROBE(mcdi_timeout); + sfxge_schedule_reset(sc); +} + +static void +sfxge_mcdi_poll(struct sfxge_softc *sc) +{ + efx_nic_t *enp; + clock_t delay_total; + clock_t delay_us; + boolean_t aborted; + + delay_total = 0; + delay_us = SFXGE_MCDI_POLL_INTERVAL_MIN; + enp = sc->enp; + + do { + if (efx_mcdi_request_poll(enp)) { + EFSYS_PROBE1(mcdi_delay, clock_t, delay_total); + return; + } + + if (delay_total > SFXGE_MCDI_WATCHDOG_INTERVAL) { + aborted = efx_mcdi_request_abort(enp); + KASSERT(aborted, ("abort failed")); + sfxge_mcdi_timeout(sc); + return; + } + + /* Spin or block depending on delay interval. */ + if (delay_us < 1000000) + DELAY(delay_us); + else + pause("mcdi wait", delay_us * hz / 1000000); + + delay_total += delay_us; + + /* Exponentially back off the poll frequency. */ + delay_us = delay_us * 2; + if (delay_us > SFXGE_MCDI_POLL_INTERVAL_MAX) + delay_us = SFXGE_MCDI_POLL_INTERVAL_MAX; + + } while (1); +} + +static void +sfxge_mcdi_execute(void *arg, efx_mcdi_req_t *emrp) +{ + struct sfxge_softc *sc; + struct sfxge_mcdi *mcdi; + + sc = (struct sfxge_softc *)arg; + mcdi = &sc->mcdi; + + sfxge_mcdi_acquire(mcdi); + + /* Issue request and poll for completion. */ + efx_mcdi_request_start(sc->enp, emrp, B_FALSE); + sfxge_mcdi_poll(sc); + + sfxge_mcdi_release(mcdi); +} + +static void +sfxge_mcdi_ev_cpl(void *arg) +{ + struct sfxge_softc *sc; + struct sfxge_mcdi *mcdi; + + sc = (struct sfxge_softc *)arg; + mcdi = &sc->mcdi; + + mtx_lock(&mcdi->lock); + KASSERT(mcdi->state == SFXGE_MCDI_BUSY, ("MCDI not busy")); + mcdi->state = SFXGE_MCDI_COMPLETED; + cv_broadcast(&mcdi->cv); + mtx_unlock(&mcdi->lock); +} + +static void +sfxge_mcdi_exception(void *arg, efx_mcdi_exception_t eme) +{ + struct sfxge_softc *sc; + device_t dev; + + sc = (struct sfxge_softc *)arg; + dev = sc->dev; + + log(LOG_WARNING, "[%s%d] MC_%s", device_get_name(dev), + device_get_unit(dev), + (eme == EFX_MCDI_EXCEPTION_MC_REBOOT) + ? "REBOOT" + : (eme == EFX_MCDI_EXCEPTION_MC_BADASSERT) + ? "BADASSERT" : "UNKNOWN"); + + EFSYS_PROBE(mcdi_exception); + + sfxge_schedule_reset(sc); +} + +int +sfxge_mcdi_init(struct sfxge_softc *sc) +{ + efx_nic_t *enp; + struct sfxge_mcdi *mcdi; + efx_mcdi_transport_t *emtp; + int rc; + + enp = sc->enp; + mcdi = &sc->mcdi; + emtp = &mcdi->transport; + + KASSERT(mcdi->state == SFXGE_MCDI_UNINITIALIZED, + ("MCDI already initialized")); + + mtx_init(&mcdi->lock, "sfxge_mcdi", NULL, MTX_DEF); + + mcdi->state = SFXGE_MCDI_INITIALIZED; + + emtp->emt_context = sc; + emtp->emt_execute = sfxge_mcdi_execute; + emtp->emt_ev_cpl = sfxge_mcdi_ev_cpl; + emtp->emt_exception = sfxge_mcdi_exception; + + cv_init(&mcdi->cv, "sfxge_mcdi"); + + if ((rc = efx_mcdi_init(enp, emtp)) != 0) + goto fail; + + return (0); + +fail: + mtx_destroy(&mcdi->lock); + mcdi->state = SFXGE_MCDI_UNINITIALIZED; + return (rc); +} + +void +sfxge_mcdi_fini(struct sfxge_softc *sc) +{ + struct sfxge_mcdi *mcdi; + efx_nic_t *enp; + efx_mcdi_transport_t *emtp; + + enp = sc->enp; + mcdi = &sc->mcdi; + emtp = &mcdi->transport; + + mtx_lock(&mcdi->lock); + KASSERT(mcdi->state == SFXGE_MCDI_INITIALIZED, + ("MCDI not initialized")); + + efx_mcdi_fini(enp); + bzero(emtp, sizeof(*emtp)); + + cv_destroy(&mcdi->cv); + mtx_unlock(&mcdi->lock); + + mtx_destroy(&mcdi->lock); +} diff --git a/sys/dev/sfxge/sfxge_port.c b/sys/dev/sfxge/sfxge_port.c new file mode 100644 index 000000000000..773a074befb1 --- /dev/null +++ b/sys/dev/sfxge/sfxge_port.c @@ -0,0 +1,788 @@ +/*- + * Copyright (c) 2010-2011 Solarflare Communications, Inc. + * All rights reserved. + * + * This software was developed in part by Philip Paeps under contract for + * Solarflare Communications, Inc. + * + * 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include "common/efx.h" + +#include "sfxge.h" + +static int +sfxge_mac_stat_update(struct sfxge_softc *sc) +{ + struct sfxge_port *port = &sc->port; + efsys_mem_t *esmp = &(port->mac_stats.dma_buf); + clock_t now; + unsigned int count; + int rc; + + mtx_lock(&port->lock); + + if (port->init_state != SFXGE_PORT_STARTED) { + rc = 0; + goto out; + } + + now = ticks; + if (now - port->mac_stats.update_time < hz) { + rc = 0; + goto out; + } + + port->mac_stats.update_time = now; + + /* If we're unlucky enough to read statistics wduring the DMA, wait + * up to 10ms for it to finish (typically takes <500us) */ + for (count = 0; count < 100; ++count) { + EFSYS_PROBE1(wait, unsigned int, count); + + /* Synchronize the DMA memory for reading */ + bus_dmamap_sync(esmp->esm_tag, esmp->esm_map, + BUS_DMASYNC_POSTREAD); + + /* Try to update the cached counters */ + if ((rc = efx_mac_stats_update(sc->enp, esmp, + port->mac_stats.decode_buf, NULL)) != EAGAIN) + goto out; + + DELAY(100); + } + + rc = ETIMEDOUT; +out: + mtx_unlock(&port->lock); + return rc; +} + +static int +sfxge_mac_stat_handler(SYSCTL_HANDLER_ARGS) +{ + struct sfxge_softc *sc = arg1; + unsigned int id = arg2; + int rc; + + if ((rc = sfxge_mac_stat_update(sc)) != 0) + return rc; + + return SYSCTL_OUT(req, + (uint64_t *)sc->port.mac_stats.decode_buf + id, + sizeof(uint64_t)); +} + +static void +sfxge_mac_stat_init(struct sfxge_softc *sc) +{ + struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev); + struct sysctl_oid_list *stat_list; + unsigned int id; + const char *name; + + stat_list = SYSCTL_CHILDREN(sc->stats_node); + + /* Initialise the named stats */ + for (id = 0; id < EFX_MAC_NSTATS; id++) { + name = efx_mac_stat_name(sc->enp, id); + SYSCTL_ADD_PROC( + ctx, stat_list, + OID_AUTO, name, CTLTYPE_U64|CTLFLAG_RD, + sc, id, sfxge_mac_stat_handler, "Q", + ""); + } +} + +#ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS + +static unsigned int +sfxge_port_wanted_fc(struct sfxge_softc *sc) +{ + struct ifmedia_entry *ifm = sc->media.ifm_cur; + + if (ifm->ifm_media == (IFM_ETHER | IFM_AUTO)) + return EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE; + return ((ifm->ifm_media & IFM_ETH_RXPAUSE) ? EFX_FCNTL_RESPOND : 0) | + ((ifm->ifm_media & IFM_ETH_TXPAUSE) ? EFX_FCNTL_GENERATE : 0); +} + +static unsigned int +sfxge_port_link_fc_ifm(struct sfxge_softc *sc) +{ + unsigned int wanted_fc, link_fc; + + efx_mac_fcntl_get(sc->enp, &wanted_fc, &link_fc); + return ((link_fc & EFX_FCNTL_RESPOND) ? IFM_ETH_RXPAUSE : 0) | + ((link_fc & EFX_FCNTL_GENERATE) ? IFM_ETH_TXPAUSE : 0); +} + +#else /* !SFXGE_HAVE_PAUSE_MEDIAOPTS */ + +static unsigned int +sfxge_port_wanted_fc(struct sfxge_softc *sc) +{ + return sc->port.wanted_fc; +} + +static unsigned int +sfxge_port_link_fc_ifm(struct sfxge_softc *sc) +{ + return 0; +} + +static int +sfxge_port_wanted_fc_handler(SYSCTL_HANDLER_ARGS) +{ + struct sfxge_softc *sc; + struct sfxge_port *port; + unsigned int fcntl; + int error; + + sc = arg1; + port = &sc->port; + + mtx_lock(&port->lock); + + if (req->newptr) { + if ((error = SYSCTL_IN(req, &fcntl, sizeof(fcntl))) != 0) + goto out; + + if (port->wanted_fc == fcntl) + goto out; + + port->wanted_fc = fcntl; + + if (port->init_state != SFXGE_PORT_STARTED) + goto out; + + error = efx_mac_fcntl_set(sc->enp, port->wanted_fc, B_TRUE); + } else { + error = SYSCTL_OUT(req, &port->wanted_fc, + sizeof(port->wanted_fc)); + } + +out: + mtx_unlock(&port->lock); + + return (error); +} + +static int +sfxge_port_link_fc_handler(SYSCTL_HANDLER_ARGS) +{ + struct sfxge_softc *sc; + struct sfxge_port *port; + unsigned int wanted_fc, link_fc; + int error; + + sc = arg1; + port = &sc->port; + + mtx_lock(&port->lock); + if (port->init_state == SFXGE_PORT_STARTED && SFXGE_LINK_UP(sc)) + efx_mac_fcntl_get(sc->enp, &wanted_fc, &link_fc); + else + link_fc = 0; + error = SYSCTL_OUT(req, &link_fc, sizeof(link_fc)); + mtx_unlock(&port->lock); + + return (error); +} + +#endif /* SFXGE_HAVE_PAUSE_MEDIAOPTS */ + +static const int sfxge_link_speed_kbit[EFX_LINK_NMODES] = { + [EFX_LINK_10HDX] = 10000, + [EFX_LINK_10FDX] = 10000, + [EFX_LINK_100HDX] = 100000, + [EFX_LINK_100FDX] = 100000, + [EFX_LINK_1000HDX] = 1000000, + [EFX_LINK_1000FDX] = 1000000, + [EFX_LINK_10000FDX] = 10000000, +}; + +void +sfxge_mac_link_update(struct sfxge_softc *sc, efx_link_mode_t mode) +{ + struct sfxge_port *port; + int link_state; + + port = &sc->port; + + if (port->link_mode == mode) + return; + + port->link_mode = mode; + + /* Push link state update to the OS */ + link_state = (port->link_mode != EFX_LINK_DOWN ? + LINK_STATE_UP : LINK_STATE_DOWN); + sc->ifnet->if_baudrate = sfxge_link_speed_kbit[port->link_mode]; + if_link_state_change(sc->ifnet, link_state); +} + +static void +sfxge_mac_poll_work(void *arg, int npending) +{ + struct sfxge_softc *sc; + efx_nic_t *enp; + struct sfxge_port *port; + efx_link_mode_t mode; + + sc = (struct sfxge_softc *)arg; + enp = sc->enp; + port = &sc->port; + + mtx_lock(&port->lock); + + if (port->init_state != SFXGE_PORT_STARTED) + goto done; + + /* This may sleep waiting for MCDI completion */ + (void)efx_port_poll(enp, &mode); + sfxge_mac_link_update(sc, mode); + +done: + mtx_unlock(&port->lock); +} + +static int +sfxge_mac_filter_set_locked(struct sfxge_softc *sc) +{ + unsigned int bucket[EFX_MAC_HASH_BITS]; + struct ifnet *ifp = sc->ifnet; + struct ifmultiaddr *ifma; + struct sockaddr_dl *sa; + efx_nic_t *enp = sc->enp; + unsigned int index; + int rc; + + /* Set promisc-unicast and broadcast filter bits */ + if ((rc = efx_mac_filter_set(enp, !!(ifp->if_flags & IFF_PROMISC), + B_TRUE)) != 0) + return rc; + + /* Set multicast hash filter */ + if (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) { + for (index = 0; index < EFX_MAC_HASH_BITS; index++) + bucket[index] = 1; + } else { + /* Broadcast frames also go through the multicast + * filter, and the broadcast address hashes to + * 0xff. */ + bucket[0xff] = 1; + + IF_ADDR_LOCK(ifp); + TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { + if (ifma->ifma_addr->sa_family == AF_LINK) { + sa = (struct sockaddr_dl *)ifma->ifma_addr; + index = ether_crc32_le(LLADDR(sa), 6) & 0xff; + bucket[index] = 1; + } + } + IF_ADDR_UNLOCK(ifp); + } + return efx_mac_hash_set(enp, bucket); +} + +int +sfxge_mac_filter_set(struct sfxge_softc *sc) +{ + struct sfxge_port *port = &sc->port; + int rc; + + KASSERT(port->init_state == SFXGE_PORT_STARTED, ("port not started")); + + mtx_lock(&port->lock); + rc = sfxge_mac_filter_set_locked(sc); + mtx_unlock(&port->lock); + return rc; +} + +void +sfxge_port_stop(struct sfxge_softc *sc) +{ + struct sfxge_port *port; + efx_nic_t *enp; + + port = &sc->port; + enp = sc->enp; + + mtx_lock(&port->lock); + + KASSERT(port->init_state == SFXGE_PORT_STARTED, + ("port not started")); + + port->init_state = SFXGE_PORT_INITIALIZED; + + port->mac_stats.update_time = 0; + + /* This may call MCDI */ + (void)efx_mac_drain(enp, B_TRUE); + + (void)efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf, 0, B_FALSE); + + port->link_mode = EFX_LINK_UNKNOWN; + + /* Destroy the common code port object. */ + efx_port_fini(sc->enp); + + mtx_unlock(&port->lock); +} + +int +sfxge_port_start(struct sfxge_softc *sc) +{ + uint8_t mac_addr[ETHER_ADDR_LEN]; + struct ifnet *ifp = sc->ifnet; + struct sfxge_port *port; + efx_nic_t *enp; + size_t pdu; + int rc; + + port = &sc->port; + enp = sc->enp; + + mtx_lock(&port->lock); + + KASSERT(port->init_state == SFXGE_PORT_INITIALIZED, + ("port not initialized")); + + /* Initialize the port object in the common code. */ + if ((rc = efx_port_init(sc->enp)) != 0) + goto fail; + + /* Set the SDU */ + pdu = EFX_MAC_PDU(ifp->if_mtu); + if ((rc = efx_mac_pdu_set(enp, pdu)) != 0) + goto fail2; + + if ((rc = efx_mac_fcntl_set(enp, sfxge_port_wanted_fc(sc), B_TRUE)) + != 0) + goto fail2; + + /* Set the unicast address */ + IF_ADDR_LOCK(ifp); + bcopy(LLADDR((struct sockaddr_dl *)ifp->if_addr->ifa_addr), + mac_addr, sizeof(mac_addr)); + IF_ADDR_UNLOCK(ifp); + if ((rc = efx_mac_addr_set(enp, mac_addr)) != 0) + goto fail; + + sfxge_mac_filter_set_locked(sc); + + /* Update MAC stats by DMA every second */ + if ((rc = efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf, + 1000, B_FALSE)) != 0) + goto fail2; + + if ((rc = efx_mac_drain(enp, B_FALSE)) != 0) + goto fail3; + + if ((rc = efx_phy_adv_cap_set(sc->enp, sc->media.ifm_cur->ifm_data)) + != 0) + goto fail4; + + port->init_state = SFXGE_PORT_STARTED; + + /* Single poll in case there were missing initial events */ + mtx_unlock(&port->lock); + sfxge_mac_poll_work(sc, 0); + + return (0); + +fail4: + (void)efx_mac_drain(enp, B_TRUE); +fail3: + (void)efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf, + 0, B_FALSE); +fail2: + efx_port_fini(sc->enp); +fail: + mtx_unlock(&port->lock); + + return (rc); +} + +static int +sfxge_phy_stat_update(struct sfxge_softc *sc) +{ + struct sfxge_port *port = &sc->port; + efsys_mem_t *esmp = &port->phy_stats.dma_buf; + clock_t now; + unsigned int count; + int rc; + + mtx_lock(&port->lock); + + if (port->init_state != SFXGE_PORT_STARTED) { + rc = 0; + goto out; + } + + now = ticks; + if (now - port->phy_stats.update_time < hz) { + rc = 0; + goto out; + } + + port->phy_stats.update_time = now; + + /* If we're unlucky enough to read statistics wduring the DMA, wait + * up to 10ms for it to finish (typically takes <500us) */ + for (count = 0; count < 100; ++count) { + EFSYS_PROBE1(wait, unsigned int, count); + + /* Synchronize the DMA memory for reading */ + bus_dmamap_sync(esmp->esm_tag, esmp->esm_map, + BUS_DMASYNC_POSTREAD); + + /* Try to update the cached counters */ + if ((rc = efx_phy_stats_update(sc->enp, esmp, + port->phy_stats.decode_buf)) != EAGAIN) + goto out; + + DELAY(100); + } + + rc = ETIMEDOUT; +out: + mtx_unlock(&port->lock); + return rc; +} + +static int +sfxge_phy_stat_handler(SYSCTL_HANDLER_ARGS) +{ + struct sfxge_softc *sc = arg1; + unsigned int id = arg2; + int rc; + + if ((rc = sfxge_phy_stat_update(sc)) != 0) + return rc; + + return SYSCTL_OUT(req, + (uint32_t *)sc->port.phy_stats.decode_buf + id, + sizeof(uint32_t)); +} + +static void +sfxge_phy_stat_init(struct sfxge_softc *sc) +{ + struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev); + struct sysctl_oid_list *stat_list; + unsigned int id; + const char *name; + uint64_t stat_mask = efx_nic_cfg_get(sc->enp)->enc_phy_stat_mask; + + stat_list = SYSCTL_CHILDREN(sc->stats_node); + + /* Initialise the named stats */ + for (id = 0; id < EFX_PHY_NSTATS; id++) { + if (!(stat_mask & ((uint64_t)1 << id))) + continue; + name = efx_phy_stat_name(sc->enp, id); + SYSCTL_ADD_PROC( + ctx, stat_list, + OID_AUTO, name, CTLTYPE_UINT|CTLFLAG_RD, + sc, id, sfxge_phy_stat_handler, + id == EFX_PHY_STAT_OUI ? "IX" : "IU", + ""); + } +} + +void +sfxge_port_fini(struct sfxge_softc *sc) +{ + struct sfxge_port *port; + efsys_mem_t *esmp; + + port = &sc->port; + esmp = &port->mac_stats.dma_buf; + + KASSERT(port->init_state == SFXGE_PORT_INITIALIZED, + ("Port not initialized")); + + port->init_state = SFXGE_PORT_UNINITIALIZED; + + port->link_mode = EFX_LINK_UNKNOWN; + + /* Finish with PHY DMA memory */ + sfxge_dma_free(&port->phy_stats.dma_buf); + free(port->phy_stats.decode_buf, M_SFXGE); + + sfxge_dma_free(esmp); + free(port->mac_stats.decode_buf, M_SFXGE); + + mtx_destroy(&port->lock); + + port->sc = NULL; +} + +int +sfxge_port_init(struct sfxge_softc *sc) +{ + struct sfxge_port *port; + struct sysctl_ctx_list *sysctl_ctx; + struct sysctl_oid *sysctl_tree; + efsys_mem_t *mac_stats_buf, *phy_stats_buf; + int rc; + + port = &sc->port; + mac_stats_buf = &port->mac_stats.dma_buf; + phy_stats_buf = &port->phy_stats.dma_buf; + + KASSERT(port->init_state == SFXGE_PORT_UNINITIALIZED, + ("Port already initialized")); + + port->sc = sc; + + mtx_init(&port->lock, "sfxge_port", NULL, MTX_DEF); + + port->phy_stats.decode_buf = malloc(EFX_PHY_NSTATS * sizeof(uint32_t), + M_SFXGE, M_WAITOK | M_ZERO); + if ((rc = sfxge_dma_alloc(sc, EFX_PHY_STATS_SIZE, phy_stats_buf)) != 0) + goto fail; + bzero(phy_stats_buf->esm_base, phy_stats_buf->esm_size); + sfxge_phy_stat_init(sc); + + sysctl_ctx = device_get_sysctl_ctx(sc->dev); + sysctl_tree = device_get_sysctl_tree(sc->dev); + +#ifndef SFXGE_HAVE_PAUSE_MEDIAOPTS + /* If flow control cannot be configured or reported through + * ifmedia, provide sysctls for it. */ + port->wanted_fc = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE; + SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO, + "wanted_fc", CTLTYPE_UINT|CTLFLAG_RW, sc, 0, + sfxge_port_wanted_fc_handler, "IU", "wanted flow control mode"); + SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO, + "link_fc", CTLTYPE_UINT|CTLFLAG_RD, sc, 0, + sfxge_port_link_fc_handler, "IU", "link flow control mode"); +#endif + + port->mac_stats.decode_buf = malloc(EFX_MAC_NSTATS * sizeof(uint64_t), + M_SFXGE, M_WAITOK | M_ZERO); + if ((rc = sfxge_dma_alloc(sc, EFX_MAC_STATS_SIZE, mac_stats_buf)) != 0) + goto fail2; + bzero(mac_stats_buf->esm_base, mac_stats_buf->esm_size); + sfxge_mac_stat_init(sc); + + port->init_state = SFXGE_PORT_INITIALIZED; + + return (0); + +fail2: + free(port->mac_stats.decode_buf, M_SFXGE); + sfxge_dma_free(phy_stats_buf); +fail: + free(port->phy_stats.decode_buf, M_SFXGE); + (void)mtx_destroy(&port->lock); + port->sc = NULL; + return rc; +} + +static int sfxge_link_mode[EFX_PHY_MEDIA_NTYPES][EFX_LINK_NMODES] = { + [EFX_PHY_MEDIA_CX4] = { + [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_CX4, + }, + [EFX_PHY_MEDIA_KX4] = { + [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_KX4, + }, + [EFX_PHY_MEDIA_XFP] = { + /* Don't know the module type, but assume SR for now. */ + [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_SR, + }, + [EFX_PHY_MEDIA_SFP_PLUS] = { + /* Don't know the module type, but assume SX/SR for now. */ + [EFX_LINK_1000FDX] = IFM_ETHER | IFM_FDX | IFM_1000_SX, + [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_SR, + }, + [EFX_PHY_MEDIA_BASE_T] = { + [EFX_LINK_10HDX] = IFM_ETHER | IFM_HDX | IFM_10_T, + [EFX_LINK_10FDX] = IFM_ETHER | IFM_FDX | IFM_10_T, + [EFX_LINK_100HDX] = IFM_ETHER | IFM_HDX | IFM_100_TX, + [EFX_LINK_100FDX] = IFM_ETHER | IFM_FDX | IFM_100_TX, + [EFX_LINK_1000HDX] = IFM_ETHER | IFM_HDX | IFM_1000_T, + [EFX_LINK_1000FDX] = IFM_ETHER | IFM_FDX | IFM_1000_T, + [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_T, + }, +}; + +static void +sfxge_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) +{ + struct sfxge_softc *sc; + efx_phy_media_type_t medium_type; + efx_link_mode_t mode; + + sc = ifp->if_softc; + sx_xlock(&sc->softc_lock); + + ifmr->ifm_status = IFM_AVALID; + ifmr->ifm_active = IFM_ETHER; + + if (SFXGE_RUNNING(sc) && SFXGE_LINK_UP(sc)) { + ifmr->ifm_status |= IFM_ACTIVE; + + efx_phy_media_type_get(sc->enp, &medium_type); + mode = sc->port.link_mode; + ifmr->ifm_active |= sfxge_link_mode[medium_type][mode]; + ifmr->ifm_active |= sfxge_port_link_fc_ifm(sc); + } + + sx_xunlock(&sc->softc_lock); +} + +static int +sfxge_media_change(struct ifnet *ifp) +{ + struct sfxge_softc *sc; + struct ifmedia_entry *ifm; + int rc; + + sc = ifp->if_softc; + ifm = sc->media.ifm_cur; + + sx_xlock(&sc->softc_lock); + + if (!SFXGE_RUNNING(sc)) { + rc = 0; + goto out; + } + + rc = efx_mac_fcntl_set(sc->enp, sfxge_port_wanted_fc(sc), B_TRUE); + if (rc != 0) + goto out; + + rc = efx_phy_adv_cap_set(sc->enp, ifm->ifm_data); +out: + sx_xunlock(&sc->softc_lock); + + return rc; +} + +int sfxge_port_ifmedia_init(struct sfxge_softc *sc) +{ + efx_phy_media_type_t medium_type; + uint32_t cap_mask, mode_cap_mask; + efx_link_mode_t mode; + int mode_ifm, best_mode_ifm = 0; + int rc; + + /* We need port state to initialise the ifmedia list. */ + if ((rc = efx_nic_init(sc->enp)) != 0) + goto out; + if ((rc = efx_port_init(sc->enp)) != 0) + goto out2; + + /* + * Register ifconfig callbacks for querying and setting the + * link mode and link status. + */ + ifmedia_init(&sc->media, IFM_IMASK, sfxge_media_change, + sfxge_media_status); + + /* + * Map firmware medium type and capabilities to ifmedia types. + * ifmedia does not distinguish between forcing the link mode + * and disabling auto-negotiation. 1000BASE-T and 10GBASE-T + * require AN even if only one link mode is enabled, and for + * 100BASE-TX it is useful even if the link mode is forced. + * Therefore we never disable auto-negotiation. + * + * Also enable and advertise flow control by default. + */ + + efx_phy_media_type_get(sc->enp, &medium_type); + efx_phy_adv_cap_get(sc->enp, EFX_PHY_CAP_PERM, &cap_mask); + + EFX_STATIC_ASSERT(EFX_LINK_10HDX == EFX_PHY_CAP_10HDX + 1); + EFX_STATIC_ASSERT(EFX_LINK_10FDX == EFX_PHY_CAP_10FDX + 1); + EFX_STATIC_ASSERT(EFX_LINK_100HDX == EFX_PHY_CAP_100HDX + 1); + EFX_STATIC_ASSERT(EFX_LINK_100FDX == EFX_PHY_CAP_100FDX + 1); + EFX_STATIC_ASSERT(EFX_LINK_1000HDX == EFX_PHY_CAP_1000HDX + 1); + EFX_STATIC_ASSERT(EFX_LINK_1000FDX == EFX_PHY_CAP_1000FDX + 1); + EFX_STATIC_ASSERT(EFX_LINK_10000FDX == EFX_PHY_CAP_10000FDX + 1); + + for (mode = EFX_LINK_10HDX; mode <= EFX_LINK_10000FDX; mode++) { + mode_cap_mask = 1 << (mode - 1); + mode_ifm = sfxge_link_mode[medium_type][mode]; + + if ((cap_mask & mode_cap_mask) && mode_ifm) { + mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_AN); + +#ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS + /* No flow-control */ + ifmedia_add(&sc->media, mode_ifm, mode_cap_mask, NULL); + + /* Respond-only. If using AN, we implicitly + * offer symmetric as well, but that doesn't + * mean we *have* to generate pause frames. + */ + mode_cap_mask |= cap_mask & ((1 << EFX_PHY_CAP_PAUSE) | + (1 << EFX_PHY_CAP_ASYM)); + mode_ifm |= IFM_ETH_RXPAUSE; + ifmedia_add(&sc->media, mode_ifm, mode_cap_mask, NULL); + + /* Symmetric */ + mode_cap_mask &= ~(1 << EFX_PHY_CAP_ASYM); + mode_ifm |= IFM_ETH_TXPAUSE; +#else /* !SFXGE_HAVE_PAUSE_MEDIAOPTS */ + mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_PAUSE); +#endif + ifmedia_add(&sc->media, mode_ifm, mode_cap_mask, NULL); + + /* Link modes are numbered in order of speed, + * so assume the last one available is the best. + */ + best_mode_ifm = mode_ifm; + } + } + + if (cap_mask & (1 << EFX_PHY_CAP_AN)) { + /* Add autoselect mode. */ + mode_ifm = IFM_ETHER | IFM_AUTO; + ifmedia_add(&sc->media, mode_ifm, + cap_mask & ~(1 << EFX_PHY_CAP_ASYM), NULL); + best_mode_ifm = mode_ifm; + } + + if (best_mode_ifm) + ifmedia_set(&sc->media, best_mode_ifm); + + /* Now discard port state until interface is started. */ + efx_port_fini(sc->enp); +out2: + efx_nic_fini(sc->enp); +out: + return rc; +} diff --git a/sys/dev/sfxge/sfxge_rx.c b/sys/dev/sfxge/sfxge_rx.c new file mode 100644 index 000000000000..7dd5160f4c93 --- /dev/null +++ b/sys/dev/sfxge/sfxge_rx.c @@ -0,0 +1,1233 @@ +/*- + * Copyright (c) 2010-2011 Solarflare Communications, Inc. + * All rights reserved. + * + * This software was developed in part by Philip Paeps under contract for + * Solarflare Communications, Inc. + * + * 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "common/efx.h" + + +#include "sfxge.h" +#include "sfxge_rx.h" + +#define RX_REFILL_THRESHOLD (EFX_RXQ_LIMIT(SFXGE_NDESCS) * 9 / 10) +#define RX_REFILL_THRESHOLD_2 (RX_REFILL_THRESHOLD / 2) + +/* Size of the LRO hash table. Must be a power of 2. A larger table + * means we can accelerate a larger number of streams. + */ +static unsigned lro_table_size = 128; + +/* Maximum length of a hash chain. If chains get too long then the lookup + * time increases and may exceed the benefit of LRO. + */ +static unsigned lro_chain_max = 20; + +/* Maximum time (in ticks) that a connection can be idle before it's LRO + * state is discarded. + */ +static unsigned lro_idle_ticks; /* initialised in sfxge_rx_init() */ + +/* Number of packets with payload that must arrive in-order before a + * connection is eligible for LRO. The idea is we should avoid coalescing + * segments when the sender is in slow-start because reducing the ACK rate + * can damage performance. + */ +static int lro_slow_start_packets = 2000; + +/* Number of packets with payload that must arrive in-order following loss + * before a connection is eligible for LRO. The idea is we should avoid + * coalescing segments when the sender is recovering from loss, because + * reducing the ACK rate can damage performance. + */ +static int lro_loss_packets = 20; + +/* Flags for sfxge_lro_conn::l2_id; must not collide with EVL_VLID_MASK */ +#define SFXGE_LRO_L2_ID_VLAN 0x4000 +#define SFXGE_LRO_L2_ID_IPV6 0x8000 +#define SFXGE_LRO_CONN_IS_VLAN_ENCAP(c) ((c)->l2_id & SFXGE_LRO_L2_ID_VLAN) +#define SFXGE_LRO_CONN_IS_TCPIPV4(c) (!((c)->l2_id & SFXGE_LRO_L2_ID_IPV6)) + +/* Compare IPv6 addresses, avoiding conditional branches */ +static __inline unsigned long ipv6_addr_cmp(const struct in6_addr *left, + const struct in6_addr *right) +{ +#if LONG_BIT == 64 + const uint64_t *left64 = (const uint64_t *)left; + const uint64_t *right64 = (const uint64_t *)right; + return (left64[0] - right64[0]) | (left64[1] - right64[1]); +#else + return (left->s6_addr32[0] - right->s6_addr32[0]) | + (left->s6_addr32[1] - right->s6_addr32[1]) | + (left->s6_addr32[2] - right->s6_addr32[2]) | + (left->s6_addr32[3] - right->s6_addr32[3]); +#endif +} + +void +sfxge_rx_qflush_done(struct sfxge_rxq *rxq) +{ + + rxq->flush_state = SFXGE_FLUSH_DONE; +} + +void +sfxge_rx_qflush_failed(struct sfxge_rxq *rxq) +{ + + rxq->flush_state = SFXGE_FLUSH_FAILED; +} + +static uint8_t toep_key[] = { + 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, + 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, + 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, + 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, + 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa +}; + +static void +sfxge_rx_post_refill(void *arg) +{ + struct sfxge_rxq *rxq = arg; + struct sfxge_softc *sc; + unsigned int index; + struct sfxge_evq *evq; + uint16_t magic; + + sc = rxq->sc; + index = rxq->index; + evq = sc->evq[index]; + + magic = SFXGE_MAGIC_RX_QREFILL | index; + + /* This is guaranteed due to the start/stop order of rx and ev */ + KASSERT(evq->init_state == SFXGE_EVQ_STARTED, + ("evq not started")); + KASSERT(rxq->init_state == SFXGE_RXQ_STARTED, + ("rxq not started")); + efx_ev_qpost(evq->common, magic); +} + +static void +sfxge_rx_schedule_refill(struct sfxge_rxq *rxq, boolean_t retrying) +{ + /* Initially retry after 100 ms, but back off in case of + * repeated failures as we probably have to wait for the + * administrator to raise the pool limit. */ + if (retrying) + rxq->refill_delay = min(rxq->refill_delay * 2, 10 * hz); + else + rxq->refill_delay = hz / 10; + + callout_reset_curcpu(&rxq->refill_callout, rxq->refill_delay, + sfxge_rx_post_refill, rxq); +} + +static inline struct mbuf *sfxge_rx_alloc_mbuf(struct sfxge_softc *sc) +{ + struct mb_args args; + struct mbuf *m; + + /* Allocate mbuf structure */ + args.flags = M_PKTHDR; + args.type = MT_DATA; + m = (struct mbuf *)uma_zalloc_arg(zone_mbuf, &args, M_DONTWAIT); + + /* Allocate (and attach) packet buffer */ + if (m && !uma_zalloc_arg(sc->rx_buffer_zone, m, M_DONTWAIT)) { + uma_zfree(zone_mbuf, m); + m = NULL; + } + + return m; +} + +#define SFXGE_REFILL_BATCH 64 + +static void +sfxge_rx_qfill(struct sfxge_rxq *rxq, unsigned int target, boolean_t retrying) +{ + struct sfxge_softc *sc; + unsigned int index; + struct sfxge_evq *evq; + unsigned int batch; + unsigned int rxfill; + unsigned int mblksize; + int ntodo; + efsys_dma_addr_t addr[SFXGE_REFILL_BATCH]; + + sc = rxq->sc; + index = rxq->index; + evq = sc->evq[index]; + + prefetch_read_many(sc->enp); + prefetch_read_many(rxq->common); + + mtx_assert(&evq->lock, MA_OWNED); + + if (rxq->init_state != SFXGE_RXQ_STARTED) + return; + + rxfill = rxq->added - rxq->completed; + KASSERT(rxfill <= EFX_RXQ_LIMIT(SFXGE_NDESCS), + ("rxfill > EFX_RXQ_LIMIT(SFXGE_NDESCS)")); + ntodo = min(EFX_RXQ_LIMIT(SFXGE_NDESCS) - rxfill, target); + KASSERT(ntodo <= EFX_RXQ_LIMIT(SFXGE_NDESCS), + ("ntodo > EFX_RQX_LIMIT(SFXGE_NDESCS)")); + + if (ntodo == 0) + return; + + batch = 0; + mblksize = sc->rx_buffer_size; + while (ntodo-- > 0) { + unsigned int id; + struct sfxge_rx_sw_desc *rx_desc; + bus_dma_segment_t seg; + struct mbuf *m; + + id = (rxq->added + batch) & (SFXGE_NDESCS - 1); + rx_desc = &rxq->queue[id]; + KASSERT(rx_desc->mbuf == NULL, ("rx_desc->mbuf != NULL")); + + rx_desc->flags = EFX_DISCARD; + m = rx_desc->mbuf = sfxge_rx_alloc_mbuf(sc); + if (m == NULL) + break; + sfxge_map_mbuf_fast(rxq->mem.esm_tag, rxq->mem.esm_map, m, &seg); + addr[batch++] = seg.ds_addr; + + if (batch == SFXGE_REFILL_BATCH) { + efx_rx_qpost(rxq->common, addr, mblksize, batch, + rxq->completed, rxq->added); + rxq->added += batch; + batch = 0; + } + } + + if (ntodo != 0) + sfxge_rx_schedule_refill(rxq, retrying); + + if (batch != 0) { + efx_rx_qpost(rxq->common, addr, mblksize, batch, + rxq->completed, rxq->added); + rxq->added += batch; + } + + /* Make the descriptors visible to the hardware */ + bus_dmamap_sync(rxq->mem.esm_tag, rxq->mem.esm_map, + BUS_DMASYNC_PREWRITE); + + efx_rx_qpush(rxq->common, rxq->added); +} + +void +sfxge_rx_qrefill(struct sfxge_rxq *rxq) +{ + + if (rxq->init_state != SFXGE_RXQ_STARTED) + return; + + /* Make sure the queue is full */ + sfxge_rx_qfill(rxq, EFX_RXQ_LIMIT(SFXGE_NDESCS), B_TRUE); +} + +static void __sfxge_rx_deliver(struct sfxge_softc *sc, struct mbuf *m) +{ + struct ifnet *ifp = sc->ifnet; + + m->m_pkthdr.rcvif = ifp; + m->m_pkthdr.header = m->m_data; + m->m_pkthdr.csum_data = 0xffff; + ifp->if_input(ifp, m); +} + +static void +sfxge_rx_deliver(struct sfxge_softc *sc, struct sfxge_rx_sw_desc *rx_desc) +{ + struct mbuf *m = rx_desc->mbuf; + int csum_flags; + + /* Convert checksum flags */ + csum_flags = (rx_desc->flags & EFX_CKSUM_IPV4) ? + (CSUM_IP_CHECKED | CSUM_IP_VALID) : 0; + if (rx_desc->flags & EFX_CKSUM_TCPUDP) + csum_flags |= CSUM_DATA_VALID | CSUM_PSEUDO_HDR; + +#ifdef SFXGE_HAVE_MQ + /* The hash covers a 4-tuple for TCP only */ + if (rx_desc->flags & EFX_PKT_TCP) { + m->m_pkthdr.flowid = EFX_RX_HASH_VALUE(EFX_RX_HASHALG_TOEPLITZ, + mtod(m, uint8_t *)); + m->m_flags |= M_FLOWID; + } +#endif + m->m_data += sc->rx_prefix_size; + m->m_len = rx_desc->size - sc->rx_prefix_size; + m->m_pkthdr.len = m->m_len; + m->m_pkthdr.csum_flags = csum_flags; + __sfxge_rx_deliver(sc, rx_desc->mbuf); + + rx_desc->flags = EFX_DISCARD; + rx_desc->mbuf = NULL; +} + +static void +sfxge_lro_deliver(struct sfxge_lro_state *st, struct sfxge_lro_conn *c) +{ + struct sfxge_softc *sc = st->sc; + struct mbuf *m = c->mbuf; + struct tcphdr *c_th; + int csum_flags; + + KASSERT(m, ("no mbuf to deliver")); + + ++st->n_bursts; + + /* Finish off packet munging and recalculate IP header checksum. */ + if (SFXGE_LRO_CONN_IS_TCPIPV4(c)) { + struct ip *iph = c->nh; + iph->ip_len = htons(iph->ip_len); + iph->ip_sum = 0; + iph->ip_sum = in_cksum_hdr(iph); + c_th = (struct tcphdr *)(iph + 1); + csum_flags = (CSUM_DATA_VALID | CSUM_PSEUDO_HDR | + CSUM_IP_CHECKED | CSUM_IP_VALID); + } else { + struct ip6_hdr *iph = c->nh; + iph->ip6_plen = htons(iph->ip6_plen); + c_th = (struct tcphdr *)(iph + 1); + csum_flags = CSUM_DATA_VALID | CSUM_PSEUDO_HDR; + } + + c_th->th_win = c->th_last->th_win; + c_th->th_ack = c->th_last->th_ack; + if (c_th->th_off == c->th_last->th_off) { + /* Copy TCP options (take care to avoid going negative). */ + int optlen = ((c_th->th_off - 5) & 0xf) << 2u; + memcpy(c_th + 1, c->th_last + 1, optlen); + } + +#ifdef SFXGE_HAVE_MQ + m->m_pkthdr.flowid = c->conn_hash; + m->m_flags |= M_FLOWID; +#endif + m->m_pkthdr.csum_flags = csum_flags; + __sfxge_rx_deliver(sc, m); + + c->mbuf = NULL; + c->delivered = 1; +} + +/* Drop the given connection, and add it to the free list. */ +static void sfxge_lro_drop(struct sfxge_rxq *rxq, struct sfxge_lro_conn *c) +{ + unsigned bucket; + + KASSERT(!c->mbuf, ("found orphaned mbuf")); + + if (c->next_buf.mbuf) { + sfxge_rx_deliver(rxq->sc, &c->next_buf); + LIST_REMOVE(c, active_link); + } + + bucket = c->conn_hash & rxq->lro.conns_mask; + KASSERT(rxq->lro.conns_n[bucket] > 0, ("LRO: bucket fill level wrong")); + --rxq->lro.conns_n[bucket]; + TAILQ_REMOVE(&rxq->lro.conns[bucket], c, link); + TAILQ_INSERT_HEAD(&rxq->lro.free_conns, c, link); +} + +/* Stop tracking connections that have gone idle in order to keep hash + * chains short. + */ +static void sfxge_lro_purge_idle(struct sfxge_rxq *rxq, unsigned now) +{ + struct sfxge_lro_conn *c; + unsigned i; + + KASSERT(LIST_EMPTY(&rxq->lro.active_conns), + ("found active connections")); + + rxq->lro.last_purge_ticks = now; + for (i = 0; i <= rxq->lro.conns_mask; ++i) { + if (TAILQ_EMPTY(&rxq->lro.conns[i])) + continue; + + c = TAILQ_LAST(&rxq->lro.conns[i], sfxge_lro_tailq); + if (now - c->last_pkt_ticks > lro_idle_ticks) { + ++rxq->lro.n_drop_idle; + sfxge_lro_drop(rxq, c); + } + } +} + +static void +sfxge_lro_merge(struct sfxge_lro_state *st, struct sfxge_lro_conn *c, + struct mbuf *mbuf, struct tcphdr *th) +{ + struct tcphdr *c_th; + + /* Tack the new mbuf onto the chain. */ + KASSERT(!mbuf->m_next, ("mbuf already chained")); + c->mbuf_tail->m_next = mbuf; + c->mbuf_tail = mbuf; + + /* Increase length appropriately */ + c->mbuf->m_pkthdr.len += mbuf->m_len; + + /* Update the connection state flags */ + if (SFXGE_LRO_CONN_IS_TCPIPV4(c)) { + struct ip *iph = c->nh; + iph->ip_len += mbuf->m_len; + c_th = (struct tcphdr *)(iph + 1); + } else { + struct ip6_hdr *iph = c->nh; + iph->ip6_plen += mbuf->m_len; + c_th = (struct tcphdr *)(iph + 1); + } + c_th->th_flags |= (th->th_flags & TH_PUSH); + c->th_last = th; + ++st->n_merges; + + /* Pass packet up now if another segment could overflow the IP + * length. + */ + if (c->mbuf->m_pkthdr.len > 65536 - 9200) + sfxge_lro_deliver(st, c); +} + +static void +sfxge_lro_start(struct sfxge_lro_state *st, struct sfxge_lro_conn *c, + struct mbuf *mbuf, void *nh, struct tcphdr *th) +{ + /* Start the chain */ + c->mbuf = mbuf; + c->mbuf_tail = c->mbuf; + c->nh = nh; + c->th_last = th; + + mbuf->m_pkthdr.len = mbuf->m_len; + + /* Mangle header fields for later processing */ + if (SFXGE_LRO_CONN_IS_TCPIPV4(c)) { + struct ip *iph = nh; + iph->ip_len = ntohs(iph->ip_len); + } else { + struct ip6_hdr *iph = nh; + iph->ip6_plen = ntohs(iph->ip6_plen); + } +} + +/* Try to merge or otherwise hold or deliver (as appropriate) the + * packet buffered for this connection (c->next_buf). Return a flag + * indicating whether the connection is still active for LRO purposes. + */ +static int +sfxge_lro_try_merge(struct sfxge_rxq *rxq, struct sfxge_lro_conn *c) +{ + struct sfxge_rx_sw_desc *rx_buf = &c->next_buf; + char *eh = c->next_eh; + int data_length, hdr_length, dont_merge; + unsigned th_seq, pkt_length; + struct tcphdr *th; + unsigned now; + + if (SFXGE_LRO_CONN_IS_TCPIPV4(c)) { + struct ip *iph = c->next_nh; + th = (struct tcphdr *)(iph + 1); + pkt_length = ntohs(iph->ip_len) + (char *) iph - eh; + } else { + struct ip6_hdr *iph = c->next_nh; + th = (struct tcphdr *)(iph + 1); + pkt_length = ntohs(iph->ip6_plen) + (char *) th - eh; + } + + hdr_length = (char *) th + th->th_off * 4 - eh; + data_length = (min(pkt_length, rx_buf->size - rxq->sc->rx_prefix_size) - + hdr_length); + th_seq = ntohl(th->th_seq); + dont_merge = ((data_length <= 0) + | (th->th_flags & (TH_URG | TH_SYN | TH_RST | TH_FIN))); + + /* Check for options other than aligned timestamp. */ + if (th->th_off != 5) { + const uint32_t *opt_ptr = (const uint32_t *) (th + 1); + if (th->th_off == 8 && + opt_ptr[0] == ntohl((TCPOPT_NOP << 24) | + (TCPOPT_NOP << 16) | + (TCPOPT_TIMESTAMP << 8) | + TCPOLEN_TIMESTAMP)) { + /* timestamp option -- okay */ + } else { + dont_merge = 1; + } + } + + if (__predict_false(th_seq != c->next_seq)) { + /* Out-of-order, so start counting again. */ + if (c->mbuf) + sfxge_lro_deliver(&rxq->lro, c); + c->n_in_order_pkts -= lro_loss_packets; + c->next_seq = th_seq + data_length; + ++rxq->lro.n_misorder; + goto deliver_buf_out; + } + c->next_seq = th_seq + data_length; + + now = ticks; + if (now - c->last_pkt_ticks > lro_idle_ticks) { + ++rxq->lro.n_drop_idle; + if (c->mbuf) + sfxge_lro_deliver(&rxq->lro, c); + sfxge_lro_drop(rxq, c); + return 0; + } + c->last_pkt_ticks = ticks; + + if (c->n_in_order_pkts < lro_slow_start_packets) { + /* May be in slow-start, so don't merge. */ + ++rxq->lro.n_slow_start; + ++c->n_in_order_pkts; + goto deliver_buf_out; + } + + if (__predict_false(dont_merge)) { + if (c->mbuf) + sfxge_lro_deliver(&rxq->lro, c); + if (th->th_flags & (TH_FIN | TH_RST)) { + ++rxq->lro.n_drop_closed; + sfxge_lro_drop(rxq, c); + return 0; + } + goto deliver_buf_out; + } + + rx_buf->mbuf->m_data += rxq->sc->rx_prefix_size; + + if (__predict_true(c->mbuf != NULL)) { + /* Remove headers and any padding */ + rx_buf->mbuf->m_data += hdr_length; + rx_buf->mbuf->m_len = data_length; + + sfxge_lro_merge(&rxq->lro, c, rx_buf->mbuf, th); + } else { + /* Remove any padding */ + rx_buf->mbuf->m_len = pkt_length; + + sfxge_lro_start(&rxq->lro, c, rx_buf->mbuf, c->next_nh, th); + } + + rx_buf->mbuf = NULL; + return 1; + + deliver_buf_out: + sfxge_rx_deliver(rxq->sc, rx_buf); + return 1; +} + +static void sfxge_lro_new_conn(struct sfxge_lro_state *st, uint32_t conn_hash, + uint16_t l2_id, void *nh, struct tcphdr *th) +{ + unsigned bucket = conn_hash & st->conns_mask; + struct sfxge_lro_conn *c; + + if (st->conns_n[bucket] >= lro_chain_max) { + ++st->n_too_many; + return; + } + + if (!TAILQ_EMPTY(&st->free_conns)) { + c = TAILQ_FIRST(&st->free_conns); + TAILQ_REMOVE(&st->free_conns, c, link); + } else { + c = malloc(sizeof(*c), M_SFXGE, M_DONTWAIT); + if (c == NULL) + return; + c->mbuf = NULL; + c->next_buf.mbuf = NULL; + } + + /* Create the connection tracking data */ + ++st->conns_n[bucket]; + TAILQ_INSERT_HEAD(&st->conns[bucket], c, link); + c->l2_id = l2_id; + c->conn_hash = conn_hash; + c->source = th->th_sport; + c->dest = th->th_dport; + c->n_in_order_pkts = 0; + c->last_pkt_ticks = *(volatile int *)&ticks; + c->delivered = 0; + ++st->n_new_stream; + /* NB. We don't initialise c->next_seq, and it doesn't matter what + * value it has. Most likely the next packet received for this + * connection will not match -- no harm done. + */ +} + +/* Process mbuf and decide whether to dispatch it to the stack now or + * later. + */ +static void +sfxge_lro(struct sfxge_rxq *rxq, struct sfxge_rx_sw_desc *rx_buf) +{ + struct sfxge_softc *sc = rxq->sc; + struct mbuf *m = rx_buf->mbuf; + struct ether_header *eh; + struct sfxge_lro_conn *c; + uint16_t l2_id; + uint16_t l3_proto; + void *nh; + struct tcphdr *th; + uint32_t conn_hash; + unsigned bucket; + + /* Get the hardware hash */ + conn_hash = EFX_RX_HASH_VALUE(EFX_RX_HASHALG_TOEPLITZ, + mtod(m, uint8_t *)); + + eh = (struct ether_header *)(m->m_data + sc->rx_prefix_size); + if (eh->ether_type == htons(ETHERTYPE_VLAN)) { + struct ether_vlan_header *veh = (struct ether_vlan_header *)eh; + l2_id = EVL_VLANOFTAG(ntohs(veh->evl_tag)) | + SFXGE_LRO_L2_ID_VLAN; + l3_proto = veh->evl_proto; + nh = veh + 1; + } else { + l2_id = 0; + l3_proto = eh->ether_type; + nh = eh + 1; + } + + /* Check whether this is a suitable packet (unfragmented + * TCP/IPv4 or TCP/IPv6). If so, find the TCP header and + * length, and compute a hash if necessary. If not, return. + */ + if (l3_proto == htons(ETHERTYPE_IP)) { + struct ip *iph = nh; + if ((iph->ip_p - IPPROTO_TCP) | + (iph->ip_hl - (sizeof(*iph) >> 2u)) | + (iph->ip_off & htons(IP_MF | IP_OFFMASK))) + goto deliver_now; + th = (struct tcphdr *)(iph + 1); + } else if (l3_proto == htons(ETHERTYPE_IPV6)) { + struct ip6_hdr *iph = nh; + if (iph->ip6_nxt != IPPROTO_TCP) + goto deliver_now; + l2_id |= SFXGE_LRO_L2_ID_IPV6; + th = (struct tcphdr *)(iph + 1); + } else { + goto deliver_now; + } + + bucket = conn_hash & rxq->lro.conns_mask; + + TAILQ_FOREACH(c, &rxq->lro.conns[bucket], link) { + if ((c->l2_id - l2_id) | (c->conn_hash - conn_hash)) + continue; + if ((c->source - th->th_sport) | (c->dest - th->th_dport)) + continue; + if (c->mbuf) { + if (SFXGE_LRO_CONN_IS_TCPIPV4(c)) { + struct ip *c_iph, *iph = nh; + c_iph = c->nh; + if ((c_iph->ip_src.s_addr - iph->ip_src.s_addr) | + (c_iph->ip_dst.s_addr - iph->ip_dst.s_addr)) + continue; + } else { + struct ip6_hdr *c_iph, *iph = nh; + c_iph = c->nh; + if (ipv6_addr_cmp(&c_iph->ip6_src, &iph->ip6_src) | + ipv6_addr_cmp(&c_iph->ip6_dst, &iph->ip6_dst)) + continue; + } + } + + /* Re-insert at head of list to reduce lookup time. */ + TAILQ_REMOVE(&rxq->lro.conns[bucket], c, link); + TAILQ_INSERT_HEAD(&rxq->lro.conns[bucket], c, link); + + if (c->next_buf.mbuf) { + if (!sfxge_lro_try_merge(rxq, c)) + goto deliver_now; + } else { + LIST_INSERT_HEAD(&rxq->lro.active_conns, c, + active_link); + } + c->next_buf = *rx_buf; + c->next_eh = eh; + c->next_nh = nh; + + rx_buf->mbuf = NULL; + rx_buf->flags = EFX_DISCARD; + return; + } + + sfxge_lro_new_conn(&rxq->lro, conn_hash, l2_id, nh, th); + deliver_now: + sfxge_rx_deliver(sc, rx_buf); +} + +static void sfxge_lro_end_of_burst(struct sfxge_rxq *rxq) +{ + struct sfxge_lro_state *st = &rxq->lro; + struct sfxge_lro_conn *c; + unsigned t; + + while (!LIST_EMPTY(&st->active_conns)) { + c = LIST_FIRST(&st->active_conns); + if (!c->delivered && c->mbuf) + sfxge_lro_deliver(st, c); + if (sfxge_lro_try_merge(rxq, c)) { + if (c->mbuf) + sfxge_lro_deliver(st, c); + LIST_REMOVE(c, active_link); + } + c->delivered = 0; + } + + t = *(volatile int *)&ticks; + if (__predict_false(t != st->last_purge_ticks)) + sfxge_lro_purge_idle(rxq, t); +} + +void +sfxge_rx_qcomplete(struct sfxge_rxq *rxq, boolean_t eop) +{ + struct sfxge_softc *sc = rxq->sc; + int lro_enabled = sc->ifnet->if_capenable & IFCAP_LRO; + unsigned int index; + struct sfxge_evq *evq; + unsigned int completed; + unsigned int level; + struct mbuf *m; + struct sfxge_rx_sw_desc *prev = NULL; + + index = rxq->index; + evq = sc->evq[index]; + + mtx_assert(&evq->lock, MA_OWNED); + + completed = rxq->completed; + while (completed != rxq->pending) { + unsigned int id; + struct sfxge_rx_sw_desc *rx_desc; + + id = completed++ & (SFXGE_NDESCS - 1); + rx_desc = &rxq->queue[id]; + m = rx_desc->mbuf; + + if (rxq->init_state != SFXGE_RXQ_STARTED) + goto discard; + + if (rx_desc->flags & (EFX_ADDR_MISMATCH | EFX_DISCARD)) + goto discard; + + prefetch_read_many(mtod(m, caddr_t)); + + /* Check for loopback packets */ + if (!(rx_desc->flags & EFX_PKT_IPV4) && + !(rx_desc->flags & EFX_PKT_IPV6)) { + struct ether_header *etherhp; + + /*LINTED*/ + etherhp = mtod(m, struct ether_header *); + + if (etherhp->ether_type == + htons(SFXGE_ETHERTYPE_LOOPBACK)) { + EFSYS_PROBE(loopback); + + rxq->loopback++; + goto discard; + } + } + + /* Pass packet up the stack or into LRO (pipelined) */ + if (prev != NULL) { + if (lro_enabled) + sfxge_lro(rxq, prev); + else + sfxge_rx_deliver(sc, prev); + } + prev = rx_desc; + continue; + +discard: + /* Return the packet to the pool */ + m_free(m); + rx_desc->mbuf = NULL; + } + rxq->completed = completed; + + level = rxq->added - rxq->completed; + + /* Pass last packet up the stack or into LRO */ + if (prev != NULL) { + if (lro_enabled) + sfxge_lro(rxq, prev); + else + sfxge_rx_deliver(sc, prev); + } + + /* + * If there are any pending flows and this is the end of the + * poll then they must be completed. + */ + if (eop) + sfxge_lro_end_of_burst(rxq); + + /* Top up the queue if necessary */ + if (level < RX_REFILL_THRESHOLD) + sfxge_rx_qfill(rxq, EFX_RXQ_LIMIT(SFXGE_NDESCS), B_FALSE); +} + +static void +sfxge_rx_qstop(struct sfxge_softc *sc, unsigned int index) +{ + struct sfxge_rxq *rxq; + struct sfxge_evq *evq; + unsigned int count; + + rxq = sc->rxq[index]; + evq = sc->evq[index]; + + mtx_lock(&evq->lock); + + KASSERT(rxq->init_state == SFXGE_RXQ_STARTED, + ("rxq not started")); + + rxq->init_state = SFXGE_RXQ_INITIALIZED; + + callout_stop(&rxq->refill_callout); + +again: + rxq->flush_state = SFXGE_FLUSH_PENDING; + + /* Flush the receive queue */ + efx_rx_qflush(rxq->common); + + mtx_unlock(&evq->lock); + + count = 0; + do { + /* Spin for 100 ms */ + DELAY(100000); + + if (rxq->flush_state != SFXGE_FLUSH_PENDING) + break; + + } while (++count < 20); + + mtx_lock(&evq->lock); + + if (rxq->flush_state == SFXGE_FLUSH_FAILED) + goto again; + + rxq->flush_state = SFXGE_FLUSH_DONE; + + rxq->pending = rxq->added; + sfxge_rx_qcomplete(rxq, B_TRUE); + + KASSERT(rxq->completed == rxq->pending, + ("rxq->completed != rxq->pending")); + + rxq->added = 0; + rxq->pending = 0; + rxq->completed = 0; + rxq->loopback = 0; + + /* Destroy the common code receive queue. */ + efx_rx_qdestroy(rxq->common); + + efx_sram_buf_tbl_clear(sc->enp, rxq->buf_base_id, + EFX_RXQ_NBUFS(SFXGE_NDESCS)); + + mtx_unlock(&evq->lock); +} + +static int +sfxge_rx_qstart(struct sfxge_softc *sc, unsigned int index) +{ + struct sfxge_rxq *rxq; + efsys_mem_t *esmp; + struct sfxge_evq *evq; + int rc; + + rxq = sc->rxq[index]; + esmp = &rxq->mem; + evq = sc->evq[index]; + + KASSERT(rxq->init_state == SFXGE_RXQ_INITIALIZED, + ("rxq->init_state != SFXGE_RXQ_INITIALIZED")); + KASSERT(evq->init_state == SFXGE_EVQ_STARTED, + ("evq->init_state != SFXGE_EVQ_STARTED")); + + /* Program the buffer table. */ + if ((rc = efx_sram_buf_tbl_set(sc->enp, rxq->buf_base_id, esmp, + EFX_RXQ_NBUFS(SFXGE_NDESCS))) != 0) + return rc; + + /* Create the common code receive queue. */ + if ((rc = efx_rx_qcreate(sc->enp, index, index, EFX_RXQ_TYPE_DEFAULT, + esmp, SFXGE_NDESCS, rxq->buf_base_id, evq->common, + &rxq->common)) != 0) + goto fail; + + mtx_lock(&evq->lock); + + /* Enable the receive queue. */ + efx_rx_qenable(rxq->common); + + rxq->init_state = SFXGE_RXQ_STARTED; + + /* Try to fill the queue from the pool. */ + sfxge_rx_qfill(rxq, EFX_RXQ_LIMIT(SFXGE_NDESCS), B_FALSE); + + mtx_unlock(&evq->lock); + + return (0); + +fail: + efx_sram_buf_tbl_clear(sc->enp, rxq->buf_base_id, + EFX_RXQ_NBUFS(SFXGE_NDESCS)); + return rc; +} + +void +sfxge_rx_stop(struct sfxge_softc *sc) +{ + struct sfxge_intr *intr; + int index; + + intr = &sc->intr; + + /* Stop the receive queue(s) */ + index = intr->n_alloc; + while (--index >= 0) + sfxge_rx_qstop(sc, index); + + sc->rx_prefix_size = 0; + sc->rx_buffer_size = 0; + + efx_rx_fini(sc->enp); +} + +int +sfxge_rx_start(struct sfxge_softc *sc) +{ + struct sfxge_intr *intr; + int index; + int rc; + + intr = &sc->intr; + + /* Initialize the common code receive module. */ + if ((rc = efx_rx_init(sc->enp)) != 0) + return (rc); + + /* Calculate the receive packet buffer size. */ + sc->rx_prefix_size = EFX_RX_PREFIX_SIZE; + sc->rx_buffer_size = (EFX_MAC_PDU(sc->ifnet->if_mtu) + + sc->rx_prefix_size); + + /* Select zone for packet buffers */ + if (sc->rx_buffer_size <= MCLBYTES) + sc->rx_buffer_zone = zone_clust; + else if (sc->rx_buffer_size <= MJUMPAGESIZE) + sc->rx_buffer_zone = zone_jumbop; + else if (sc->rx_buffer_size <= MJUM9BYTES) + sc->rx_buffer_zone = zone_jumbo9; + else + sc->rx_buffer_zone = zone_jumbo16; + + /* + * Set up the scale table. Enable all hash types and hash insertion. + */ + for (index = 0; index < SFXGE_RX_SCALE_MAX; index++) + sc->rx_indir_table[index] = index % sc->intr.n_alloc; + if ((rc = efx_rx_scale_tbl_set(sc->enp, sc->rx_indir_table, + SFXGE_RX_SCALE_MAX)) != 0) + goto fail; + (void)efx_rx_scale_mode_set(sc->enp, EFX_RX_HASHALG_TOEPLITZ, + (1 << EFX_RX_HASH_IPV4) | (1 << EFX_RX_HASH_TCPIPV4) | + (1 << EFX_RX_HASH_IPV6) | (1 << EFX_RX_HASH_TCPIPV6), B_TRUE); + + if ((rc = efx_rx_scale_toeplitz_ipv4_key_set(sc->enp, toep_key, + sizeof(toep_key))) != 0) + goto fail; + + /* Start the receive queue(s). */ + for (index = 0; index < intr->n_alloc; index++) { + if ((rc = sfxge_rx_qstart(sc, index)) != 0) + goto fail2; + } + + return (0); + +fail2: + while (--index >= 0) + sfxge_rx_qstop(sc, index); + +fail: + efx_rx_fini(sc->enp); + + return (rc); +} + +static void sfxge_lro_init(struct sfxge_rxq *rxq) +{ + struct sfxge_lro_state *st = &rxq->lro; + unsigned i; + + st->conns_mask = lro_table_size - 1; + KASSERT(!((st->conns_mask + 1) & st->conns_mask), + ("lro_table_size must be a power of 2")); + st->sc = rxq->sc; + st->conns = malloc((st->conns_mask + 1) * sizeof(st->conns[0]), + M_SFXGE, M_WAITOK); + st->conns_n = malloc((st->conns_mask + 1) * sizeof(st->conns_n[0]), + M_SFXGE, M_WAITOK); + for (i = 0; i <= st->conns_mask; ++i) { + TAILQ_INIT(&st->conns[i]); + st->conns_n[i] = 0; + } + LIST_INIT(&st->active_conns); + TAILQ_INIT(&st->free_conns); +} + +static void sfxge_lro_fini(struct sfxge_rxq *rxq) +{ + struct sfxge_lro_state *st = &rxq->lro; + struct sfxge_lro_conn *c; + unsigned i; + + /* Return cleanly if sfxge_lro_init() has not been called. */ + if (st->conns == NULL) + return; + + KASSERT(LIST_EMPTY(&st->active_conns), ("found active connections")); + + for (i = 0; i <= st->conns_mask; ++i) { + while (!TAILQ_EMPTY(&st->conns[i])) { + c = TAILQ_LAST(&st->conns[i], sfxge_lro_tailq); + sfxge_lro_drop(rxq, c); + } + } + + while (!TAILQ_EMPTY(&st->free_conns)) { + c = TAILQ_FIRST(&st->free_conns); + TAILQ_REMOVE(&st->free_conns, c, link); + KASSERT(!c->mbuf, ("found orphaned mbuf")); + free(c, M_SFXGE); + } + + free(st->conns_n, M_SFXGE); + free(st->conns, M_SFXGE); + st->conns = NULL; +} + +static void +sfxge_rx_qfini(struct sfxge_softc *sc, unsigned int index) +{ + struct sfxge_rxq *rxq; + + rxq = sc->rxq[index]; + + KASSERT(rxq->init_state == SFXGE_RXQ_INITIALIZED, + ("rxq->init_state != SFXGE_RXQ_INITIALIZED")); + + /* Free the context array and the flow table. */ + free(rxq->queue, M_SFXGE); + sfxge_lro_fini(rxq); + + /* Release DMA memory. */ + sfxge_dma_free(&rxq->mem); + + sc->rxq[index] = NULL; + + free(rxq, M_SFXGE); +} + +static int +sfxge_rx_qinit(struct sfxge_softc *sc, unsigned int index) +{ + struct sfxge_rxq *rxq; + struct sfxge_evq *evq; + efsys_mem_t *esmp; + int rc; + + KASSERT(index < sc->intr.n_alloc, ("index >= %d", sc->intr.n_alloc)); + + rxq = malloc(sizeof(struct sfxge_rxq), M_SFXGE, M_ZERO | M_WAITOK); + rxq->sc = sc; + rxq->index = index; + + sc->rxq[index] = rxq; + esmp = &rxq->mem; + + evq = sc->evq[index]; + + /* Allocate and zero DMA space. */ + if ((rc = sfxge_dma_alloc(sc, EFX_RXQ_SIZE(SFXGE_NDESCS), esmp)) != 0) + return (rc); + (void)memset(esmp->esm_base, 0, EFX_RXQ_SIZE(SFXGE_NDESCS)); + + /* Allocate buffer table entries. */ + sfxge_sram_buf_tbl_alloc(sc, EFX_RXQ_NBUFS(SFXGE_NDESCS), + &rxq->buf_base_id); + + /* Allocate the context array and the flow table. */ + rxq->queue = malloc(sizeof(struct sfxge_rx_sw_desc) * SFXGE_NDESCS, + M_SFXGE, M_WAITOK | M_ZERO); + sfxge_lro_init(rxq); + + callout_init(&rxq->refill_callout, B_TRUE); + + rxq->init_state = SFXGE_RXQ_INITIALIZED; + + return (0); +} + +static const struct { + const char *name; + size_t offset; +} sfxge_rx_stats[] = { +#define SFXGE_RX_STAT(name, member) \ + { #name, offsetof(struct sfxge_rxq, member) } + SFXGE_RX_STAT(lro_merges, lro.n_merges), + SFXGE_RX_STAT(lro_bursts, lro.n_bursts), + SFXGE_RX_STAT(lro_slow_start, lro.n_slow_start), + SFXGE_RX_STAT(lro_misorder, lro.n_misorder), + SFXGE_RX_STAT(lro_too_many, lro.n_too_many), + SFXGE_RX_STAT(lro_new_stream, lro.n_new_stream), + SFXGE_RX_STAT(lro_drop_idle, lro.n_drop_idle), + SFXGE_RX_STAT(lro_drop_closed, lro.n_drop_closed) +}; + +static int +sfxge_rx_stat_handler(SYSCTL_HANDLER_ARGS) +{ + struct sfxge_softc *sc = arg1; + unsigned int id = arg2; + unsigned int sum, index; + + /* Sum across all RX queues */ + sum = 0; + for (index = 0; index < sc->intr.n_alloc; index++) + sum += *(unsigned int *)((caddr_t)sc->rxq[index] + + sfxge_rx_stats[id].offset); + + return SYSCTL_OUT(req, &sum, sizeof(sum)); +} + +static void +sfxge_rx_stat_init(struct sfxge_softc *sc) +{ + struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev); + struct sysctl_oid_list *stat_list; + unsigned int id; + + stat_list = SYSCTL_CHILDREN(sc->stats_node); + + for (id = 0; + id < sizeof(sfxge_rx_stats) / sizeof(sfxge_rx_stats[0]); + id++) { + SYSCTL_ADD_PROC( + ctx, stat_list, + OID_AUTO, sfxge_rx_stats[id].name, + CTLTYPE_UINT|CTLFLAG_RD, + sc, id, sfxge_rx_stat_handler, "IU", + ""); + } +} + +void +sfxge_rx_fini(struct sfxge_softc *sc) +{ + struct sfxge_intr *intr; + int index; + + intr = &sc->intr; + + index = intr->n_alloc; + while (--index >= 0) + sfxge_rx_qfini(sc, index); +} + +int +sfxge_rx_init(struct sfxge_softc *sc) +{ + struct sfxge_intr *intr; + int index; + int rc; + + if (lro_idle_ticks == 0) + lro_idle_ticks = hz / 10 + 1; /* 100 ms */ + + intr = &sc->intr; + + KASSERT(intr->state == SFXGE_INTR_INITIALIZED, + ("intr->state != SFXGE_INTR_INITIALIZED")); + + /* Initialize the receive queue(s) - one per interrupt. */ + for (index = 0; index < intr->n_alloc; index++) { + if ((rc = sfxge_rx_qinit(sc, index)) != 0) + goto fail; + } + + sfxge_rx_stat_init(sc); + + return (0); + +fail: + /* Tear down the receive queue(s). */ + while (--index >= 0) + sfxge_rx_qfini(sc, index); + + return (rc); +} diff --git a/sys/dev/sfxge/sfxge_rx.h b/sys/dev/sfxge/sfxge_rx.h new file mode 100644 index 000000000000..5a80fdbc054c --- /dev/null +++ b/sys/dev/sfxge/sfxge_rx.h @@ -0,0 +1,189 @@ +/*- + * Copyright (c) 2010-2011 Solarflare Communications, Inc. + * All rights reserved. + * + * This software was developed in part by Philip Paeps under contract for + * Solarflare Communications, Inc. + * + * 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _SFXGE_RX_H +#define _SFXGE_RX_H + +#define SFXGE_MAGIC_RESERVED 0x8000 + +#define SFXGE_MAGIC_DMAQ_LABEL_WIDTH 6 +#define SFXGE_MAGIC_DMAQ_LABEL_MASK \ + ((1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH) - 1) + +#define SFXGE_MAGIC_RX_QFLUSH_DONE \ + (SFXGE_MAGIC_RESERVED | (1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH)) + +#define SFXGE_MAGIC_RX_QFLUSH_FAILED \ + (SFXGE_MAGIC_RESERVED | (2 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH)) + +#define SFXGE_MAGIC_RX_QREFILL \ + (SFXGE_MAGIC_RESERVED | (3 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH)) + +#define SFXGE_MAGIC_TX_QFLUSH_DONE \ + (SFXGE_MAGIC_RESERVED | (4 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH)) + +#define SFXGE_RX_SCALE_MAX EFX_MAXRSS + +struct sfxge_rx_sw_desc { + struct mbuf *mbuf; + bus_dmamap_t map; + int flags; + int size; +}; + +/** + * struct sfxge_lro_conn - Connection state for software LRO + * @link: Link for hash table and free list. + * @active_link: Link for active_conns list + * @l2_id: Identifying information from layer 2 + * @conn_hash: Hash of connection 4-tuple + * @nh: IP (v4 or v6) header of super-packet + * @source: Source TCP port number + * @dest: Destination TCP port number + * @n_in_order_pkts: Number of in-order packets with payload. + * @next_seq: Next in-order sequence number. + * @last_pkt_ticks: Time we last saw a packet on this connection. + * @mbuf: The mbuf we are currently holding. + * If %NULL, then all following fields are undefined. + * @mbuf_tail: The tail of the frag_list of mbufs we're holding. + * Only valid after at least one merge. + * @th_last: The TCP header of the last packet merged. + * @next_buf: The next RX buffer to process. + * @next_eh: Ethernet header of the next buffer. + * @next_nh: IP header of the next buffer. + * @delivered: True if we've delivered a payload packet up this interrupt. + */ +struct sfxge_lro_conn { + TAILQ_ENTRY(sfxge_lro_conn) link; + LIST_ENTRY(sfxge_lro_conn) active_link; + uint16_t l2_id; + uint32_t conn_hash; + void *nh; + uint16_t source, dest; + int n_in_order_pkts; + unsigned next_seq; + unsigned last_pkt_ticks; + struct mbuf *mbuf; + struct mbuf *mbuf_tail; + struct tcphdr *th_last; + struct sfxge_rx_sw_desc next_buf; + void *next_eh; + void *next_nh; + int delivered; +}; + +/** + * struct sfxge_lro_state - Port state for software LRO + * @sc: The associated NIC. + * @conns_mask: Number of hash buckets - 1. + * @conns: Hash buckets for tracked connections. + * @conns_n: Length of linked list for each hash bucket. + * @active_conns: Connections that are holding a packet. + * Connections are self-linked when not in this list. + * @free_conns: Free sfxge_lro_conn instances. + * @last_purge_ticks: The value of ticks last time we purged idle + * connections. + * @n_merges: Number of packets absorbed by LRO. + * @n_bursts: Number of bursts spotted by LRO. + * @n_slow_start: Number of packets not merged because connection may be in + * slow-start. + * @n_misorder: Number of out-of-order packets seen in tracked streams. + * @n_too_many: Incremented when we're trying to track too many streams. + * @n_new_stream: Number of distinct streams we've tracked. + * @n_drop_idle: Number of streams discarded because they went idle. + * @n_drop_closed: Number of streams that have seen a FIN or RST. + */ +struct sfxge_lro_state { + struct sfxge_softc *sc; + unsigned conns_mask; + TAILQ_HEAD(sfxge_lro_tailq, sfxge_lro_conn) *conns; + unsigned *conns_n; + LIST_HEAD(, sfxge_lro_conn) active_conns; + TAILQ_HEAD(, sfxge_lro_conn) free_conns; + unsigned last_purge_ticks; + unsigned n_merges; + unsigned n_bursts; + unsigned n_slow_start; + unsigned n_misorder; + unsigned n_too_many; + unsigned n_new_stream; + unsigned n_drop_idle; + unsigned n_drop_closed; +}; + +enum sfxge_flush_state { + SFXGE_FLUSH_DONE = 0, + SFXGE_FLUSH_PENDING, + SFXGE_FLUSH_FAILED +}; + +enum sfxge_rxq_state { + SFXGE_RXQ_UNINITIALIZED = 0, + SFXGE_RXQ_INITIALIZED, + SFXGE_RXQ_STARTED +}; + +#define SFXGE_RX_BATCH 128 + +struct sfxge_rxq { + struct sfxge_softc *sc __aligned(CACHE_LINE_SIZE); + unsigned int index; + efsys_mem_t mem; + unsigned int buf_base_id; + enum sfxge_rxq_state init_state; + + struct sfxge_rx_sw_desc *queue __aligned(CACHE_LINE_SIZE); + unsigned int added; + unsigned int pending; + unsigned int completed; + unsigned int loopback; + struct sfxge_lro_state lro; + struct callout refill_callout; + unsigned int refill_delay; + + efx_rxq_t *common __aligned(CACHE_LINE_SIZE); + volatile enum sfxge_flush_state flush_state; +}; + +/* + * From sfxge_rx.c. + */ +extern int sfxge_rx_init(struct sfxge_softc *sc); +extern void sfxge_rx_fini(struct sfxge_softc *sc); +extern int sfxge_rx_start(struct sfxge_softc *sc); +extern void sfxge_rx_stop(struct sfxge_softc *sc); +extern void sfxge_rx_qcomplete(struct sfxge_rxq *rxq, boolean_t eop); +extern void sfxge_rx_qrefill(struct sfxge_rxq *rxq); +extern void sfxge_rx_qflush_done(struct sfxge_rxq *rxq); +extern void sfxge_rx_qflush_failed(struct sfxge_rxq *rxq); +extern void sfxge_rx_scale_update(void *arg, int npending); + +#endif diff --git a/sys/dev/sfxge/sfxge_tx.c b/sys/dev/sfxge/sfxge_tx.c new file mode 100644 index 000000000000..5f0aeceb3df3 --- /dev/null +++ b/sys/dev/sfxge/sfxge_tx.c @@ -0,0 +1,1491 @@ +/*- + * Copyright (c) 2010-2011 Solarflare Communications, Inc. + * All rights reserved. + * + * This software was developed in part by Philip Paeps under contract for + * Solarflare Communications, Inc. + * + * 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "common/efx.h" + +#include "sfxge.h" +#include "sfxge_tx.h" + +/* Set the block level to ensure there is space to generate a + * large number of descriptors for TSO. With minimum MSS and + * maximum mbuf length we might need more than a ring-ful of + * descriptors, but this should not happen in practice except + * due to deliberate attack. In that case we will truncate + * the output at a packet boundary. Allow for a reasonable + * minimum MSS of 512. + */ +#define SFXGE_TSO_MAX_DESC ((65535 / 512) * 2 + SFXGE_TX_MAPPING_MAX_SEG - 1) +#define SFXGE_TXQ_BLOCK_LEVEL (SFXGE_NDESCS - SFXGE_TSO_MAX_DESC) + +/* Forward declarations. */ +static inline void sfxge_tx_qdpl_service(struct sfxge_txq *txq); +static void sfxge_tx_qlist_post(struct sfxge_txq *txq); +static void sfxge_tx_qunblock(struct sfxge_txq *txq); +static int sfxge_tx_queue_tso(struct sfxge_txq *txq, struct mbuf *mbuf, + const bus_dma_segment_t *dma_seg, int n_dma_seg); + +void +sfxge_tx_qcomplete(struct sfxge_txq *txq) +{ + struct sfxge_softc *sc; + struct sfxge_evq *evq; + unsigned int completed; + + sc = txq->sc; + evq = sc->evq[txq->evq_index]; + + mtx_assert(&evq->lock, MA_OWNED); + + completed = txq->completed; + while (completed != txq->pending) { + struct sfxge_tx_mapping *stmp; + unsigned int id; + + id = completed++ & (SFXGE_NDESCS - 1); + + stmp = &txq->stmp[id]; + if (stmp->flags & TX_BUF_UNMAP) { + bus_dmamap_unload(txq->packet_dma_tag, stmp->map); + if (stmp->flags & TX_BUF_MBUF) { + struct mbuf *m = stmp->u.mbuf; + do + m = m_free(m); + while (m != NULL); + } else { + free(stmp->u.heap_buf, M_SFXGE); + } + stmp->flags = 0; + } + } + txq->completed = completed; + + /* Check whether we need to unblock the queue. */ + mb(); + if (txq->blocked) { + unsigned int level; + + level = txq->added - txq->completed; + if (level <= SFXGE_TXQ_UNBLOCK_LEVEL) + sfxge_tx_qunblock(txq); + } +} + +#ifdef SFXGE_HAVE_MQ + +/* + * Reorder the put list and append it to the get list. + */ +static void +sfxge_tx_qdpl_swizzle(struct sfxge_txq *txq) +{ + struct sfxge_tx_dpl *stdp; + struct mbuf *mbuf, *get_next, **get_tailp; + volatile uintptr_t *putp; + uintptr_t put; + unsigned int count; + + mtx_assert(&txq->lock, MA_OWNED); + + stdp = &txq->dpl; + + /* Acquire the put list. */ + putp = &stdp->std_put; + put = atomic_readandclear_long(putp); + mbuf = (void *)put; + + if (mbuf == NULL) + return; + + /* Reverse the put list. */ + get_tailp = &mbuf->m_nextpkt; + get_next = NULL; + + count = 0; + do { + struct mbuf *put_next; + + put_next = mbuf->m_nextpkt; + mbuf->m_nextpkt = get_next; + get_next = mbuf; + mbuf = put_next; + + count++; + } while (mbuf != NULL); + + /* Append the reversed put list to the get list. */ + KASSERT(*get_tailp == NULL, ("*get_tailp != NULL")); + *stdp->std_getp = get_next; + stdp->std_getp = get_tailp; + stdp->std_count += count; +} + +#endif /* SFXGE_HAVE_MQ */ + +static void +sfxge_tx_qreap(struct sfxge_txq *txq) +{ + mtx_assert(SFXGE_TXQ_LOCK(txq), MA_OWNED); + + txq->reaped = txq->completed; +} + +static void +sfxge_tx_qlist_post(struct sfxge_txq *txq) +{ + unsigned int old_added; + unsigned int level; + int rc; + + mtx_assert(SFXGE_TXQ_LOCK(txq), MA_OWNED); + + KASSERT(txq->n_pend_desc != 0, ("txq->n_pend_desc == 0")); + KASSERT(txq->n_pend_desc <= SFXGE_TSO_MAX_DESC, + ("txq->n_pend_desc too large")); + KASSERT(!txq->blocked, ("txq->blocked")); + + old_added = txq->added; + + /* Post the fragment list. */ + rc = efx_tx_qpost(txq->common, txq->pend_desc, txq->n_pend_desc, + txq->reaped, &txq->added); + KASSERT(rc == 0, ("efx_tx_qpost() failed")); + + /* If efx_tx_qpost() had to refragment, our information about + * buffers to free may be associated with the wrong + * descriptors. + */ + KASSERT(txq->added - old_added == txq->n_pend_desc, + ("efx_tx_qpost() refragmented descriptors")); + + level = txq->added - txq->reaped; + KASSERT(level <= SFXGE_NDESCS, ("overfilled TX queue")); + + /* Clear the fragment list. */ + txq->n_pend_desc = 0; + + /* Have we reached the block level? */ + if (level < SFXGE_TXQ_BLOCK_LEVEL) + return; + + /* Reap, and check again */ + sfxge_tx_qreap(txq); + level = txq->added - txq->reaped; + if (level < SFXGE_TXQ_BLOCK_LEVEL) + return; + + txq->blocked = 1; + + /* + * Avoid a race with completion interrupt handling that could leave + * the queue blocked. + */ + mb(); + sfxge_tx_qreap(txq); + level = txq->added - txq->reaped; + if (level < SFXGE_TXQ_BLOCK_LEVEL) { + mb(); + txq->blocked = 0; + } +} + +static int sfxge_tx_queue_mbuf(struct sfxge_txq *txq, struct mbuf *mbuf) +{ + bus_dmamap_t *used_map; + bus_dmamap_t map; + bus_dma_segment_t dma_seg[SFXGE_TX_MAPPING_MAX_SEG]; + unsigned int id; + struct sfxge_tx_mapping *stmp; + efx_buffer_t *desc; + int n_dma_seg; + int rc; + int i; + + KASSERT(!txq->blocked, ("txq->blocked")); + + if (mbuf->m_pkthdr.csum_flags & CSUM_TSO) + prefetch_read_many(mbuf->m_data); + + if (txq->init_state != SFXGE_TXQ_STARTED) { + rc = EINTR; + goto reject; + } + + /* Load the packet for DMA. */ + id = txq->added & (SFXGE_NDESCS - 1); + stmp = &txq->stmp[id]; + rc = bus_dmamap_load_mbuf_sg(txq->packet_dma_tag, stmp->map, + mbuf, dma_seg, &n_dma_seg, 0); + if (rc == EFBIG) { + /* Try again. */ + struct mbuf *new_mbuf = m_collapse(mbuf, M_DONTWAIT, + SFXGE_TX_MAPPING_MAX_SEG); + if (new_mbuf == NULL) + goto reject; + ++txq->collapses; + mbuf = new_mbuf; + rc = bus_dmamap_load_mbuf_sg(txq->packet_dma_tag, + stmp->map, mbuf, + dma_seg, &n_dma_seg, 0); + } + if (rc != 0) + goto reject; + + /* Make the packet visible to the hardware. */ + bus_dmamap_sync(txq->packet_dma_tag, stmp->map, BUS_DMASYNC_PREWRITE); + + used_map = &stmp->map; + + if (mbuf->m_pkthdr.csum_flags & CSUM_TSO) { + rc = sfxge_tx_queue_tso(txq, mbuf, dma_seg, n_dma_seg); + if (rc < 0) + goto reject_mapped; + stmp = &txq->stmp[rc]; + } else { + /* Add the mapping to the fragment list, and set flags + * for the buffer. + */ + i = 0; + for (;;) { + desc = &txq->pend_desc[i]; + desc->eb_addr = dma_seg[i].ds_addr; + desc->eb_size = dma_seg[i].ds_len; + if (i == n_dma_seg - 1) { + desc->eb_eop = 1; + break; + } + desc->eb_eop = 0; + i++; + + stmp->flags = 0; + if (__predict_false(stmp == + &txq->stmp[SFXGE_NDESCS - 1])) + stmp = &txq->stmp[0]; + else + stmp++; + } + txq->n_pend_desc = n_dma_seg; + } + + /* + * If the mapping required more than one descriptor + * then we need to associate the DMA map with the last + * descriptor, not the first. + */ + if (used_map != &stmp->map) { + map = stmp->map; + stmp->map = *used_map; + *used_map = map; + } + + stmp->u.mbuf = mbuf; + stmp->flags = TX_BUF_UNMAP | TX_BUF_MBUF; + + /* Post the fragment list. */ + sfxge_tx_qlist_post(txq); + + return 0; + +reject_mapped: + bus_dmamap_unload(txq->packet_dma_tag, *used_map); +reject: + /* Drop the packet on the floor. */ + m_freem(mbuf); + ++txq->drops; + + return rc; +} + +#ifdef SFXGE_HAVE_MQ + +/* + * Drain the deferred packet list into the transmit queue. + */ +static void +sfxge_tx_qdpl_drain(struct sfxge_txq *txq) +{ + struct sfxge_softc *sc; + struct sfxge_tx_dpl *stdp; + struct mbuf *mbuf, *next; + unsigned int count; + unsigned int pushed; + int rc; + + mtx_assert(&txq->lock, MA_OWNED); + + sc = txq->sc; + stdp = &txq->dpl; + pushed = txq->added; + + prefetch_read_many(sc->enp); + prefetch_read_many(txq->common); + + mbuf = stdp->std_get; + count = stdp->std_count; + + while (count != 0) { + KASSERT(mbuf != NULL, ("mbuf == NULL")); + + next = mbuf->m_nextpkt; + mbuf->m_nextpkt = NULL; + + ETHER_BPF_MTAP(sc->ifnet, mbuf); /* packet capture */ + + if (next != NULL) + prefetch_read_many(next); + + rc = sfxge_tx_queue_mbuf(txq, mbuf); + --count; + mbuf = next; + if (rc != 0) + continue; + + if (txq->blocked) + break; + + /* Push the fragments to the hardware in batches. */ + if (txq->added - pushed >= SFXGE_TX_BATCH) { + efx_tx_qpush(txq->common, txq->added); + pushed = txq->added; + } + } + + if (count == 0) { + KASSERT(mbuf == NULL, ("mbuf != NULL")); + stdp->std_get = NULL; + stdp->std_count = 0; + stdp->std_getp = &stdp->std_get; + } else { + stdp->std_get = mbuf; + stdp->std_count = count; + } + + if (txq->added != pushed) + efx_tx_qpush(txq->common, txq->added); + + KASSERT(txq->blocked || stdp->std_count == 0, + ("queue unblocked but count is non-zero")); +} + +#define SFXGE_TX_QDPL_PENDING(_txq) \ + ((_txq)->dpl.std_put != 0) + +/* + * Service the deferred packet list. + * + * NOTE: drops the txq mutex! + */ +static inline void +sfxge_tx_qdpl_service(struct sfxge_txq *txq) +{ + mtx_assert(&txq->lock, MA_OWNED); + + do { + if (SFXGE_TX_QDPL_PENDING(txq)) + sfxge_tx_qdpl_swizzle(txq); + + if (!txq->blocked) + sfxge_tx_qdpl_drain(txq); + + mtx_unlock(&txq->lock); + } while (SFXGE_TX_QDPL_PENDING(txq) && + mtx_trylock(&txq->lock)); +} + +/* + * Put a packet on the deferred packet list. + * + * If we are called with the txq lock held, we put the packet on the "get + * list", otherwise we atomically push it on the "put list". The swizzle + * function takes care of ordering. + * + * The length of the put list is bounded by SFXGE_TX_MAX_DEFFERED. We + * overload the csum_data field in the mbuf to keep track of this length + * because there is no cheap alternative to avoid races. + */ +static inline int +sfxge_tx_qdpl_put(struct sfxge_txq *txq, struct mbuf *mbuf, int locked) +{ + struct sfxge_tx_dpl *stdp; + + stdp = &txq->dpl; + + KASSERT(mbuf->m_nextpkt == NULL, ("mbuf->m_nextpkt != NULL")); + + if (locked) { + mtx_assert(&txq->lock, MA_OWNED); + + sfxge_tx_qdpl_swizzle(txq); + + *(stdp->std_getp) = mbuf; + stdp->std_getp = &mbuf->m_nextpkt; + stdp->std_count++; + } else { + volatile uintptr_t *putp; + uintptr_t old; + uintptr_t new; + unsigned old_len; + + putp = &stdp->std_put; + new = (uintptr_t)mbuf; + + do { + old = *putp; + if (old) { + struct mbuf *mp = (struct mbuf *)old; + old_len = mp->m_pkthdr.csum_data; + } else + old_len = 0; + if (old_len >= SFXGE_TX_MAX_DEFERRED) + return ENOBUFS; + mbuf->m_pkthdr.csum_data = old_len + 1; + mbuf->m_nextpkt = (void *)old; + } while (atomic_cmpset_long(putp, old, new) == 0); + } + + return (0); +} + +/* + * Called from if_transmit - will try to grab the txq lock and enqueue to the + * put list if it succeeds, otherwise will push onto the defer list. + */ +int +sfxge_tx_packet_add(struct sfxge_txq *txq, struct mbuf *m) +{ + int locked; + int rc; + + /* + * Try to grab the txq lock. If we are able to get the lock, + * the packet will be appended to the "get list" of the deferred + * packet list. Otherwise, it will be pushed on the "put list". + */ + locked = mtx_trylock(&txq->lock); + + /* + * Can only fail if we weren't able to get the lock. + */ + if (sfxge_tx_qdpl_put(txq, m, locked) != 0) { + KASSERT(!locked, + ("sfxge_tx_qdpl_put() failed locked")); + rc = ENOBUFS; + goto fail; + } + + /* + * Try to grab the lock again. + * + * If we are able to get the lock, we need to process the deferred + * packet list. If we are not able to get the lock, another thread + * is processing the list. + */ + if (!locked) + locked = mtx_trylock(&txq->lock); + + if (locked) { + /* Try to service the list. */ + sfxge_tx_qdpl_service(txq); + /* Lock has been dropped. */ + } + + return (0); + +fail: + return (rc); + +} + +static void +sfxge_tx_qdpl_flush(struct sfxge_txq *txq) +{ + struct sfxge_tx_dpl *stdp = &txq->dpl; + struct mbuf *mbuf, *next; + + mtx_lock(&txq->lock); + + sfxge_tx_qdpl_swizzle(txq); + for (mbuf = stdp->std_get; mbuf != NULL; mbuf = next) { + next = mbuf->m_nextpkt; + m_freem(mbuf); + } + stdp->std_get = NULL; + stdp->std_count = 0; + stdp->std_getp = &stdp->std_get; + + mtx_unlock(&txq->lock); +} + +void +sfxge_if_qflush(struct ifnet *ifp) +{ + struct sfxge_softc *sc; + int i; + + sc = ifp->if_softc; + + for (i = 0; i < SFXGE_TX_SCALE(sc); i++) + sfxge_tx_qdpl_flush(sc->txq[i]); +} + +/* + * TX start -- called by the stack. + */ +int +sfxge_if_transmit(struct ifnet *ifp, struct mbuf *m) +{ + struct sfxge_softc *sc; + struct sfxge_txq *txq; + int rc; + + sc = (struct sfxge_softc *)ifp->if_softc; + + KASSERT(ifp->if_flags & IFF_UP, ("interface not up")); + + if (!SFXGE_LINK_UP(sc)) { + m_freem(m); + return (0); + } + + /* Pick the desired transmit queue. */ + if (m->m_pkthdr.csum_flags & (CSUM_DELAY_DATA | CSUM_TSO)) { + int index = 0; + + if (m->m_flags & M_FLOWID) { + uint32_t hash = m->m_pkthdr.flowid; + + index = sc->rx_indir_table[hash % SFXGE_RX_SCALE_MAX]; + } + txq = sc->txq[SFXGE_TXQ_IP_TCP_UDP_CKSUM + index]; + } else if (m->m_pkthdr.csum_flags & CSUM_DELAY_IP) { + txq = sc->txq[SFXGE_TXQ_IP_CKSUM]; + } else { + txq = sc->txq[SFXGE_TXQ_NON_CKSUM]; + } + + rc = sfxge_tx_packet_add(txq, m); + + return (rc); +} + +#else /* !SFXGE_HAVE_MQ */ + +static void sfxge_if_start_locked(struct ifnet *ifp) +{ + struct sfxge_softc *sc = ifp->if_softc; + struct sfxge_txq *txq; + struct mbuf *mbuf; + unsigned int pushed[SFXGE_TXQ_NTYPES]; + unsigned int q_index; + + if ((ifp->if_drv_flags & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) != + IFF_DRV_RUNNING) + return; + + if (!sc->port.link_up) + return; + + for (q_index = 0; q_index < SFXGE_TXQ_NTYPES; q_index++) { + txq = sc->txq[q_index]; + pushed[q_index] = txq->added; + } + + while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { + IFQ_DRV_DEQUEUE(&ifp->if_snd, mbuf); + if (mbuf == NULL) + break; + + ETHER_BPF_MTAP(ifp, mbuf); /* packet capture */ + + /* Pick the desired transmit queue. */ + if (mbuf->m_pkthdr.csum_flags & (CSUM_DELAY_DATA | CSUM_TSO)) + q_index = SFXGE_TXQ_IP_TCP_UDP_CKSUM; + else if (mbuf->m_pkthdr.csum_flags & CSUM_DELAY_IP) + q_index = SFXGE_TXQ_IP_CKSUM; + else + q_index = SFXGE_TXQ_NON_CKSUM; + txq = sc->txq[q_index]; + + if (sfxge_tx_queue_mbuf(txq, mbuf) != 0) + continue; + + if (txq->blocked) { + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } + + /* Push the fragments to the hardware in batches. */ + if (txq->added - pushed[q_index] >= SFXGE_TX_BATCH) { + efx_tx_qpush(txq->common, txq->added); + pushed[q_index] = txq->added; + } + } + + for (q_index = 0; q_index < SFXGE_TXQ_NTYPES; q_index++) { + txq = sc->txq[q_index]; + if (txq->added != pushed[q_index]) + efx_tx_qpush(txq->common, txq->added); + } +} + +void sfxge_if_start(struct ifnet *ifp) +{ + struct sfxge_softc *sc = ifp->if_softc; + + mtx_lock(&sc->tx_lock); + sfxge_if_start_locked(ifp); + mtx_unlock(&sc->tx_lock); +} + +static inline void +sfxge_tx_qdpl_service(struct sfxge_txq *txq) +{ + struct sfxge_softc *sc = txq->sc; + struct ifnet *ifp = sc->ifnet; + + mtx_assert(&sc->tx_lock, MA_OWNED); + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + sfxge_if_start_locked(ifp); + mtx_unlock(&sc->tx_lock); +} + +#endif /* SFXGE_HAVE_MQ */ + +/* + * Software "TSO". Not quite as good as doing it in hardware, but + * still faster than segmenting in the stack. + */ + +struct sfxge_tso_state { + /* Output position */ + unsigned out_len; /* Remaining length in current segment */ + unsigned seqnum; /* Current sequence number */ + unsigned packet_space; /* Remaining space in current packet */ + + /* Input position */ + unsigned dma_seg_i; /* Current DMA segment number */ + uint64_t dma_addr; /* DMA address of current position */ + unsigned in_len; /* Remaining length in current mbuf */ + + const struct mbuf *mbuf; /* Input mbuf (head of chain) */ + u_short protocol; /* Network protocol (after VLAN decap) */ + ssize_t nh_off; /* Offset of network header */ + ssize_t tcph_off; /* Offset of TCP header */ + unsigned header_len; /* Number of bytes of header */ + int full_packet_size; /* Number of bytes to put in each outgoing + * segment */ +}; + +static inline const struct ip *tso_iph(const struct sfxge_tso_state *tso) +{ + KASSERT(tso->protocol == htons(ETHERTYPE_IP), + ("tso_iph() in non-IPv4 state")); + return (const struct ip *)(tso->mbuf->m_data + tso->nh_off); +} +static inline const struct ip6_hdr *tso_ip6h(const struct sfxge_tso_state *tso) +{ + KASSERT(tso->protocol == htons(ETHERTYPE_IPV6), + ("tso_ip6h() in non-IPv6 state")); + return (const struct ip6_hdr *)(tso->mbuf->m_data + tso->nh_off); +} +static inline const struct tcphdr *tso_tcph(const struct sfxge_tso_state *tso) +{ + return (const struct tcphdr *)(tso->mbuf->m_data + tso->tcph_off); +} + +/* Size of preallocated TSO header buffers. Larger blocks must be + * allocated from the heap. + */ +#define TSOH_STD_SIZE 128 + +/* At most half the descriptors in the queue at any time will refer to + * a TSO header buffer, since they must always be followed by a + * payload descriptor referring to an mbuf. + */ +#define TSOH_COUNT (SFXGE_NDESCS / 2u) +#define TSOH_PER_PAGE (PAGE_SIZE / TSOH_STD_SIZE) +#define TSOH_PAGE_COUNT ((TSOH_COUNT + TSOH_PER_PAGE - 1) / TSOH_PER_PAGE) + +static int tso_init(struct sfxge_txq *txq) +{ + struct sfxge_softc *sc = txq->sc; + int i, rc; + + /* Allocate TSO header buffers */ + txq->tsoh_buffer = malloc(TSOH_PAGE_COUNT * sizeof(txq->tsoh_buffer[0]), + M_SFXGE, M_WAITOK); + + for (i = 0; i < TSOH_PAGE_COUNT; i++) { + rc = sfxge_dma_alloc(sc, PAGE_SIZE, &txq->tsoh_buffer[i]); + if (rc) + goto fail; + } + + return 0; + +fail: + while (i-- > 0) + sfxge_dma_free(&txq->tsoh_buffer[i]); + free(txq->tsoh_buffer, M_SFXGE); + txq->tsoh_buffer = NULL; + return rc; +} + +static void tso_fini(struct sfxge_txq *txq) +{ + int i; + + if (txq->tsoh_buffer) { + for (i = 0; i < TSOH_PAGE_COUNT; i++) + sfxge_dma_free(&txq->tsoh_buffer[i]); + free(txq->tsoh_buffer, M_SFXGE); + } +} + +static void tso_start(struct sfxge_tso_state *tso, struct mbuf *mbuf) +{ + struct ether_header *eh = mtod(mbuf, struct ether_header *); + + tso->mbuf = mbuf; + + /* Find network protocol and header */ + tso->protocol = eh->ether_type; + if (tso->protocol == htons(ETHERTYPE_VLAN)) { + struct ether_vlan_header *veh = + mtod(mbuf, struct ether_vlan_header *); + tso->protocol = veh->evl_proto; + tso->nh_off = sizeof(*veh); + } else { + tso->nh_off = sizeof(*eh); + } + + /* Find TCP header */ + if (tso->protocol == htons(ETHERTYPE_IP)) { + KASSERT(tso_iph(tso)->ip_p == IPPROTO_TCP, + ("TSO required on non-TCP packet")); + tso->tcph_off = tso->nh_off + 4 * tso_iph(tso)->ip_hl; + } else { + KASSERT(tso->protocol == htons(ETHERTYPE_IPV6), + ("TSO required on non-IP packet")); + KASSERT(tso_ip6h(tso)->ip6_nxt == IPPROTO_TCP, + ("TSO required on non-TCP packet")); + tso->tcph_off = tso->nh_off + sizeof(struct ip6_hdr); + } + + /* We assume all headers are linear in the head mbuf */ + tso->header_len = tso->tcph_off + 4 * tso_tcph(tso)->th_off; + KASSERT(tso->header_len <= mbuf->m_len, ("packet headers fragmented")); + tso->full_packet_size = tso->header_len + mbuf->m_pkthdr.tso_segsz; + + tso->seqnum = ntohl(tso_tcph(tso)->th_seq); + + /* These flags must not be duplicated */ + KASSERT(!(tso_tcph(tso)->th_flags & (TH_URG | TH_SYN | TH_RST)), + ("incompatible TCP flag on TSO packet")); + + tso->out_len = mbuf->m_pkthdr.len - tso->header_len; +} + +/* + * tso_fill_packet_with_fragment - form descriptors for the current fragment + * + * Form descriptors for the current fragment, until we reach the end + * of fragment or end-of-packet. Return 0 on success, 1 if not enough + * space. + */ +static void tso_fill_packet_with_fragment(struct sfxge_txq *txq, + struct sfxge_tso_state *tso) +{ + efx_buffer_t *desc; + int n; + + if (tso->in_len == 0 || tso->packet_space == 0) + return; + + KASSERT(tso->in_len > 0, ("TSO input length went negative")); + KASSERT(tso->packet_space > 0, ("TSO packet space went negative")); + + n = min(tso->in_len, tso->packet_space); + + tso->packet_space -= n; + tso->out_len -= n; + tso->in_len -= n; + + desc = &txq->pend_desc[txq->n_pend_desc++]; + desc->eb_addr = tso->dma_addr; + desc->eb_size = n; + desc->eb_eop = tso->out_len == 0 || tso->packet_space == 0; + + tso->dma_addr += n; +} + +/* Callback from bus_dmamap_load() for long TSO headers. */ +static void tso_map_long_header(void *dma_addr_ret, + bus_dma_segment_t *segs, int nseg, + int error) +{ + *(uint64_t *)dma_addr_ret = ((__predict_true(error == 0) && + __predict_true(nseg == 1)) ? + segs->ds_addr : 0); +} + +/* + * tso_start_new_packet - generate a new header and prepare for the new packet + * + * Generate a new header and prepare for the new packet. Return 0 on + * success, or an error code if failed to alloc header. + */ +static int tso_start_new_packet(struct sfxge_txq *txq, + struct sfxge_tso_state *tso, + unsigned int id) +{ + struct sfxge_tx_mapping *stmp = &txq->stmp[id]; + struct tcphdr *tsoh_th; + unsigned ip_length; + caddr_t header; + uint64_t dma_addr; + bus_dmamap_t map; + efx_buffer_t *desc; + int rc; + + /* Allocate a DMA-mapped header buffer. */ + if (__predict_true(tso->header_len <= TSOH_STD_SIZE)) { + unsigned int page_index = (id / 2) / TSOH_PER_PAGE; + unsigned int buf_index = (id / 2) % TSOH_PER_PAGE; + + header = (txq->tsoh_buffer[page_index].esm_base + + buf_index * TSOH_STD_SIZE); + dma_addr = (txq->tsoh_buffer[page_index].esm_addr + + buf_index * TSOH_STD_SIZE); + map = txq->tsoh_buffer[page_index].esm_map; + + stmp->flags = 0; + } else { + /* We cannot use bus_dmamem_alloc() as that may sleep */ + header = malloc(tso->header_len, M_SFXGE, M_NOWAIT); + if (__predict_false(!header)) + return ENOMEM; + rc = bus_dmamap_load(txq->packet_dma_tag, stmp->map, + header, tso->header_len, + tso_map_long_header, &dma_addr, + BUS_DMA_NOWAIT); + if (__predict_false(dma_addr == 0)) { + if (rc == 0) { + /* Succeeded but got >1 segment */ + bus_dmamap_unload(txq->packet_dma_tag, + stmp->map); + rc = EINVAL; + } + free(header, M_SFXGE); + return rc; + } + map = stmp->map; + + txq->tso_long_headers++; + stmp->u.heap_buf = header; + stmp->flags = TX_BUF_UNMAP; + } + + tsoh_th = (struct tcphdr *)(header + tso->tcph_off); + + /* Copy and update the headers. */ + memcpy(header, tso->mbuf->m_data, tso->header_len); + + tsoh_th->th_seq = htonl(tso->seqnum); + tso->seqnum += tso->mbuf->m_pkthdr.tso_segsz; + if (tso->out_len > tso->mbuf->m_pkthdr.tso_segsz) { + /* This packet will not finish the TSO burst. */ + ip_length = tso->full_packet_size - tso->nh_off; + tsoh_th->th_flags &= ~(TH_FIN | TH_PUSH); + } else { + /* This packet will be the last in the TSO burst. */ + ip_length = tso->header_len - tso->nh_off + tso->out_len; + } + + if (tso->protocol == htons(ETHERTYPE_IP)) { + struct ip *tsoh_iph = (struct ip *)(header + tso->nh_off); + tsoh_iph->ip_len = htons(ip_length); + /* XXX We should increment ip_id, but FreeBSD doesn't + * currently allocate extra IDs for multiple segments. + */ + } else { + struct ip6_hdr *tsoh_iph = + (struct ip6_hdr *)(header + tso->nh_off); + tsoh_iph->ip6_plen = htons(ip_length - sizeof(*tsoh_iph)); + } + + /* Make the header visible to the hardware. */ + bus_dmamap_sync(txq->packet_dma_tag, map, BUS_DMASYNC_PREWRITE); + + tso->packet_space = tso->mbuf->m_pkthdr.tso_segsz; + txq->tso_packets++; + + /* Form a descriptor for this header. */ + desc = &txq->pend_desc[txq->n_pend_desc++]; + desc->eb_addr = dma_addr; + desc->eb_size = tso->header_len; + desc->eb_eop = 0; + + return 0; +} + +static int +sfxge_tx_queue_tso(struct sfxge_txq *txq, struct mbuf *mbuf, + const bus_dma_segment_t *dma_seg, int n_dma_seg) +{ + struct sfxge_tso_state tso; + unsigned int id, next_id; + + tso_start(&tso, mbuf); + + /* Grab the first payload fragment. */ + if (dma_seg->ds_len == tso.header_len) { + --n_dma_seg; + KASSERT(n_dma_seg, ("no payload found in TSO packet")); + ++dma_seg; + tso.in_len = dma_seg->ds_len; + tso.dma_addr = dma_seg->ds_addr; + } else { + tso.in_len = dma_seg->ds_len - tso.header_len; + tso.dma_addr = dma_seg->ds_addr + tso.header_len; + } + + id = txq->added & (SFXGE_NDESCS - 1); + if (__predict_false(tso_start_new_packet(txq, &tso, id))) + return -1; + + while (1) { + id = (id + 1) & (SFXGE_NDESCS - 1); + tso_fill_packet_with_fragment(txq, &tso); + + /* Move onto the next fragment? */ + if (tso.in_len == 0) { + --n_dma_seg; + if (n_dma_seg == 0) + break; + ++dma_seg; + tso.in_len = dma_seg->ds_len; + tso.dma_addr = dma_seg->ds_addr; + } + + /* End of packet? */ + if (tso.packet_space == 0) { + /* If the queue is now full due to tiny MSS, + * or we can't create another header, discard + * the remainder of the input mbuf but do not + * roll back the work we have done. + */ + if (txq->n_pend_desc > + SFXGE_TSO_MAX_DESC - (1 + SFXGE_TX_MAPPING_MAX_SEG)) + break; + next_id = (id + 1) & (SFXGE_NDESCS - 1); + if (__predict_false(tso_start_new_packet(txq, &tso, + next_id))) + break; + id = next_id; + } + } + + txq->tso_bursts++; + return id; +} + +static void +sfxge_tx_qunblock(struct sfxge_txq *txq) +{ + struct sfxge_softc *sc; + struct sfxge_evq *evq; + + sc = txq->sc; + evq = sc->evq[txq->evq_index]; + + mtx_assert(&evq->lock, MA_OWNED); + + if (txq->init_state != SFXGE_TXQ_STARTED) + return; + + mtx_lock(SFXGE_TXQ_LOCK(txq)); + + if (txq->blocked) { + unsigned int level; + + level = txq->added - txq->completed; + if (level <= SFXGE_TXQ_UNBLOCK_LEVEL) + txq->blocked = 0; + } + + sfxge_tx_qdpl_service(txq); + /* note: lock has been dropped */ +} + +void +sfxge_tx_qflush_done(struct sfxge_txq *txq) +{ + + txq->flush_state = SFXGE_FLUSH_DONE; +} + +static void +sfxge_tx_qstop(struct sfxge_softc *sc, unsigned int index) +{ + struct sfxge_txq *txq; + struct sfxge_evq *evq; + unsigned int count; + + txq = sc->txq[index]; + evq = sc->evq[txq->evq_index]; + + mtx_lock(SFXGE_TXQ_LOCK(txq)); + + KASSERT(txq->init_state == SFXGE_TXQ_STARTED, + ("txq->init_state != SFXGE_TXQ_STARTED")); + + txq->init_state = SFXGE_TXQ_INITIALIZED; + txq->flush_state = SFXGE_FLUSH_PENDING; + + /* Flush the transmit queue. */ + efx_tx_qflush(txq->common); + + mtx_unlock(SFXGE_TXQ_LOCK(txq)); + + count = 0; + do { + /* Spin for 100ms. */ + DELAY(100000); + + if (txq->flush_state != SFXGE_FLUSH_PENDING) + break; + } while (++count < 20); + + mtx_lock(&evq->lock); + mtx_lock(SFXGE_TXQ_LOCK(txq)); + + KASSERT(txq->flush_state != SFXGE_FLUSH_FAILED, + ("txq->flush_state == SFXGE_FLUSH_FAILED")); + + txq->flush_state = SFXGE_FLUSH_DONE; + + txq->blocked = 0; + txq->pending = txq->added; + + sfxge_tx_qcomplete(txq); + KASSERT(txq->completed == txq->added, + ("txq->completed != txq->added")); + + sfxge_tx_qreap(txq); + KASSERT(txq->reaped == txq->completed, + ("txq->reaped != txq->completed")); + + txq->added = 0; + txq->pending = 0; + txq->completed = 0; + txq->reaped = 0; + + /* Destroy the common code transmit queue. */ + efx_tx_qdestroy(txq->common); + txq->common = NULL; + + efx_sram_buf_tbl_clear(sc->enp, txq->buf_base_id, + EFX_TXQ_NBUFS(SFXGE_NDESCS)); + + mtx_unlock(&evq->lock); + mtx_unlock(SFXGE_TXQ_LOCK(txq)); +} + +static int +sfxge_tx_qstart(struct sfxge_softc *sc, unsigned int index) +{ + struct sfxge_txq *txq; + efsys_mem_t *esmp; + uint16_t flags; + struct sfxge_evq *evq; + int rc; + + txq = sc->txq[index]; + esmp = &txq->mem; + evq = sc->evq[txq->evq_index]; + + KASSERT(txq->init_state == SFXGE_TXQ_INITIALIZED, + ("txq->init_state != SFXGE_TXQ_INITIALIZED")); + KASSERT(evq->init_state == SFXGE_EVQ_STARTED, + ("evq->init_state != SFXGE_EVQ_STARTED")); + + /* Program the buffer table. */ + if ((rc = efx_sram_buf_tbl_set(sc->enp, txq->buf_base_id, esmp, + EFX_TXQ_NBUFS(SFXGE_NDESCS))) != 0) + return rc; + + /* Determine the kind of queue we are creating. */ + switch (txq->type) { + case SFXGE_TXQ_NON_CKSUM: + flags = 0; + break; + case SFXGE_TXQ_IP_CKSUM: + flags = EFX_CKSUM_IPV4; + break; + case SFXGE_TXQ_IP_TCP_UDP_CKSUM: + flags = EFX_CKSUM_IPV4 | EFX_CKSUM_TCPUDP; + break; + default: + KASSERT(0, ("Impossible TX queue")); + flags = 0; + break; + } + + /* Create the common code transmit queue. */ + if ((rc = efx_tx_qcreate(sc->enp, index, index, esmp, + SFXGE_NDESCS, txq->buf_base_id, flags, evq->common, + &txq->common)) != 0) + goto fail; + + mtx_lock(SFXGE_TXQ_LOCK(txq)); + + /* Enable the transmit queue. */ + efx_tx_qenable(txq->common); + + txq->init_state = SFXGE_TXQ_STARTED; + + mtx_unlock(SFXGE_TXQ_LOCK(txq)); + + return (0); + +fail: + efx_sram_buf_tbl_clear(sc->enp, txq->buf_base_id, + EFX_TXQ_NBUFS(SFXGE_NDESCS)); + return rc; +} + +void +sfxge_tx_stop(struct sfxge_softc *sc) +{ + const efx_nic_cfg_t *encp; + int index; + + index = SFXGE_TX_SCALE(sc); + while (--index >= 0) + sfxge_tx_qstop(sc, SFXGE_TXQ_IP_TCP_UDP_CKSUM + index); + + sfxge_tx_qstop(sc, SFXGE_TXQ_IP_CKSUM); + + encp = efx_nic_cfg_get(sc->enp); + sfxge_tx_qstop(sc, SFXGE_TXQ_NON_CKSUM); + + /* Tear down the transmit module */ + efx_tx_fini(sc->enp); +} + +int +sfxge_tx_start(struct sfxge_softc *sc) +{ + int index; + int rc; + + /* Initialize the common code transmit module. */ + if ((rc = efx_tx_init(sc->enp)) != 0) + return (rc); + + if ((rc = sfxge_tx_qstart(sc, SFXGE_TXQ_NON_CKSUM)) != 0) + goto fail; + + if ((rc = sfxge_tx_qstart(sc, SFXGE_TXQ_IP_CKSUM)) != 0) + goto fail2; + + for (index = 0; index < SFXGE_TX_SCALE(sc); index++) { + if ((rc = sfxge_tx_qstart(sc, SFXGE_TXQ_IP_TCP_UDP_CKSUM + + index)) != 0) + goto fail3; + } + + return (0); + +fail3: + while (--index >= 0) + sfxge_tx_qstop(sc, SFXGE_TXQ_IP_TCP_UDP_CKSUM + index); + + sfxge_tx_qstop(sc, SFXGE_TXQ_IP_CKSUM); + +fail2: + sfxge_tx_qstop(sc, SFXGE_TXQ_NON_CKSUM); + +fail: + efx_tx_fini(sc->enp); + + return (rc); +} + +/** + * Destroy a transmit queue. + */ +static void +sfxge_tx_qfini(struct sfxge_softc *sc, unsigned int index) +{ + struct sfxge_txq *txq; + unsigned int nmaps = SFXGE_NDESCS; + + txq = sc->txq[index]; + + KASSERT(txq->init_state == SFXGE_TXQ_INITIALIZED, + ("txq->init_state != SFXGE_TXQ_INITIALIZED")); + + if (txq->type == SFXGE_TXQ_IP_TCP_UDP_CKSUM) + tso_fini(txq); + + /* Free the context arrays. */ + free(txq->pend_desc, M_SFXGE); + while (nmaps--) + bus_dmamap_destroy(txq->packet_dma_tag, txq->stmp[nmaps].map); + free(txq->stmp, M_SFXGE); + + /* Release DMA memory mapping. */ + sfxge_dma_free(&txq->mem); + + sc->txq[index] = NULL; + +#ifdef SFXGE_HAVE_MQ + mtx_destroy(&txq->lock); +#endif + + free(txq, M_SFXGE); +} + +static int +sfxge_tx_qinit(struct sfxge_softc *sc, unsigned int txq_index, + enum sfxge_txq_type type, unsigned int evq_index) +{ + struct sfxge_txq *txq; + struct sfxge_evq *evq; +#ifdef SFXGE_HAVE_MQ + struct sfxge_tx_dpl *stdp; +#endif + efsys_mem_t *esmp; + unsigned int nmaps; + int rc; + + txq = malloc(sizeof(struct sfxge_txq), M_SFXGE, M_ZERO | M_WAITOK); + txq->sc = sc; + + sc->txq[txq_index] = txq; + esmp = &txq->mem; + + evq = sc->evq[evq_index]; + + /* Allocate and zero DMA space for the descriptor ring. */ + if ((rc = sfxge_dma_alloc(sc, EFX_TXQ_SIZE(SFXGE_NDESCS), esmp)) != 0) + return (rc); + (void)memset(esmp->esm_base, 0, EFX_TXQ_SIZE(SFXGE_NDESCS)); + + /* Allocate buffer table entries. */ + sfxge_sram_buf_tbl_alloc(sc, EFX_TXQ_NBUFS(SFXGE_NDESCS), + &txq->buf_base_id); + + /* Create a DMA tag for packet mappings. */ + if (bus_dma_tag_create(sc->parent_dma_tag, 1, 0x1000, 0x3FFFFFFFFFFFULL, + BUS_SPACE_MAXADDR, NULL, NULL, 0x11000, + SFXGE_TX_MAPPING_MAX_SEG, 0x1000, 0, NULL, NULL, + &txq->packet_dma_tag) != 0) { + device_printf(sc->dev, "Couldn't allocate txq DMA tag\n"); + rc = ENOMEM; + goto fail; + } + + /* Allocate pending descriptor array for batching writes. */ + txq->pend_desc = malloc(sizeof(efx_buffer_t) * SFXGE_NDESCS, + M_SFXGE, M_ZERO | M_WAITOK); + + /* Allocate and initialise mbuf DMA mapping array. */ + txq->stmp = malloc(sizeof(struct sfxge_tx_mapping) * SFXGE_NDESCS, + M_SFXGE, M_ZERO | M_WAITOK); + for (nmaps = 0; nmaps < SFXGE_NDESCS; nmaps++) { + rc = bus_dmamap_create(txq->packet_dma_tag, 0, + &txq->stmp[nmaps].map); + if (rc != 0) + goto fail2; + } + + if (type == SFXGE_TXQ_IP_TCP_UDP_CKSUM && + (rc = tso_init(txq)) != 0) + goto fail3; + +#ifdef SFXGE_HAVE_MQ + /* Initialize the deferred packet list. */ + stdp = &txq->dpl; + stdp->std_getp = &stdp->std_get; + + mtx_init(&txq->lock, "txq", NULL, MTX_DEF); +#endif + + txq->type = type; + txq->evq_index = evq_index; + txq->txq_index = txq_index; + txq->init_state = SFXGE_TXQ_INITIALIZED; + + return (0); + +fail3: + free(txq->pend_desc, M_SFXGE); +fail2: + while (nmaps--) + bus_dmamap_destroy(txq->packet_dma_tag, txq->stmp[nmaps].map); + free(txq->stmp, M_SFXGE); + bus_dma_tag_destroy(txq->packet_dma_tag); + +fail: + sfxge_dma_free(esmp); + + return (rc); +} + +static const struct { + const char *name; + size_t offset; +} sfxge_tx_stats[] = { +#define SFXGE_TX_STAT(name, member) \ + { #name, offsetof(struct sfxge_txq, member) } + SFXGE_TX_STAT(tso_bursts, tso_bursts), + SFXGE_TX_STAT(tso_packets, tso_packets), + SFXGE_TX_STAT(tso_long_headers, tso_long_headers), + SFXGE_TX_STAT(tx_collapses, collapses), + SFXGE_TX_STAT(tx_drops, drops), +}; + +static int +sfxge_tx_stat_handler(SYSCTL_HANDLER_ARGS) +{ + struct sfxge_softc *sc = arg1; + unsigned int id = arg2; + unsigned long sum; + unsigned int index; + + /* Sum across all TX queues */ + sum = 0; + for (index = 0; + index < SFXGE_TXQ_IP_TCP_UDP_CKSUM + SFXGE_TX_SCALE(sc); + index++) + sum += *(unsigned long *)((caddr_t)sc->txq[index] + + sfxge_tx_stats[id].offset); + + return SYSCTL_OUT(req, &sum, sizeof(sum)); +} + +static void +sfxge_tx_stat_init(struct sfxge_softc *sc) +{ + struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev); + struct sysctl_oid_list *stat_list; + unsigned int id; + + stat_list = SYSCTL_CHILDREN(sc->stats_node); + + for (id = 0; + id < sizeof(sfxge_tx_stats) / sizeof(sfxge_tx_stats[0]); + id++) { + SYSCTL_ADD_PROC( + ctx, stat_list, + OID_AUTO, sfxge_tx_stats[id].name, + CTLTYPE_ULONG|CTLFLAG_RD, + sc, id, sfxge_tx_stat_handler, "LU", + ""); + } +} + +void +sfxge_tx_fini(struct sfxge_softc *sc) +{ + int index; + + index = SFXGE_TX_SCALE(sc); + while (--index >= 0) + sfxge_tx_qfini(sc, SFXGE_TXQ_IP_TCP_UDP_CKSUM + index); + + sfxge_tx_qfini(sc, SFXGE_TXQ_IP_CKSUM); + sfxge_tx_qfini(sc, SFXGE_TXQ_NON_CKSUM); +} + + +int +sfxge_tx_init(struct sfxge_softc *sc) +{ + struct sfxge_intr *intr; + int index; + int rc; + + intr = &sc->intr; + + KASSERT(intr->state == SFXGE_INTR_INITIALIZED, + ("intr->state != SFXGE_INTR_INITIALIZED")); + + /* Initialize the transmit queues */ + if ((rc = sfxge_tx_qinit(sc, SFXGE_TXQ_NON_CKSUM, + SFXGE_TXQ_NON_CKSUM, 0)) != 0) + goto fail; + + if ((rc = sfxge_tx_qinit(sc, SFXGE_TXQ_IP_CKSUM, + SFXGE_TXQ_IP_CKSUM, 0)) != 0) + goto fail2; + + for (index = 0; index < SFXGE_TX_SCALE(sc); index++) { + if ((rc = sfxge_tx_qinit(sc, SFXGE_TXQ_IP_TCP_UDP_CKSUM + index, + SFXGE_TXQ_IP_TCP_UDP_CKSUM, index)) != 0) + goto fail3; + } + + sfxge_tx_stat_init(sc); + + return (0); + +fail3: + sfxge_tx_qfini(sc, SFXGE_TXQ_IP_CKSUM); + + while (--index >= 0) + sfxge_tx_qfini(sc, SFXGE_TXQ_IP_TCP_UDP_CKSUM + index); + +fail2: + sfxge_tx_qfini(sc, SFXGE_TXQ_NON_CKSUM); + +fail: + return (rc); +} diff --git a/sys/dev/sfxge/sfxge_tx.h b/sys/dev/sfxge/sfxge_tx.h new file mode 100644 index 000000000000..483a16a03cc3 --- /dev/null +++ b/sys/dev/sfxge/sfxge_tx.h @@ -0,0 +1,185 @@ +/*- + * Copyright (c) 2010-2011 Solarflare Communications, Inc. + * All rights reserved. + * + * This software was developed in part by Philip Paeps under contract for + * Solarflare Communications, Inc. + * + * 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _SFXGE_TX_H +#define _SFXGE_TX_H + +#include +#include +#include + +/* Maximum number of DMA segments needed to map an mbuf chain. With + * TSO, the mbuf length may be just over 64K, divided into 2K mbuf + * clusters. (The chain could be longer than this initially, but can + * be shortened with m_collapse().) + */ +#define SFXGE_TX_MAPPING_MAX_SEG (64 / 2 + 1) + +/* Maximum number of DMA segments needed to map an output packet. It + * could overlap all mbufs in the chain and also require an extra + * segment for a TSO header. + */ +#define SFXGE_TX_PACKET_MAX_SEG (SFXGE_TX_MAPPING_MAX_SEG + 1) + +/* + * Buffer mapping flags. + * + * Buffers and DMA mappings must be freed when the last descriptor + * referring to them is completed. Set the TX_BUF_UNMAP and + * TX_BUF_MBUF flags on the last descriptor generated for an mbuf + * chain. Set only the TX_BUF_UNMAP flag on a descriptor referring to + * a heap buffer. + */ +enum sfxge_tx_buf_flags { + TX_BUF_UNMAP = 1, + TX_BUF_MBUF = 2, +}; + +/* + * Buffer mapping information for descriptors in flight. + */ +struct sfxge_tx_mapping { + union { + struct mbuf *mbuf; + caddr_t heap_buf; + } u; + bus_dmamap_t map; + enum sfxge_tx_buf_flags flags; +}; + +#define SFXGE_TX_MAX_DEFERRED 64 + +/* + * Deferred packet list. + */ +struct sfxge_tx_dpl { + uintptr_t std_put; /* Head of put list. */ + struct mbuf *std_get; /* Head of get list. */ + struct mbuf **std_getp; /* Tail of get list. */ + unsigned int std_count; /* Count of packets. */ +}; + + +#define SFXGE_TX_BUFFER_SIZE 0x400 +#define SFXGE_TX_HEADER_SIZE 0x100 +#define SFXGE_TX_COPY_THRESHOLD 0x200 + +enum sfxge_txq_state { + SFXGE_TXQ_UNINITIALIZED = 0, + SFXGE_TXQ_INITIALIZED, + SFXGE_TXQ_STARTED +}; + +enum sfxge_txq_type { + SFXGE_TXQ_NON_CKSUM = 0, + SFXGE_TXQ_IP_CKSUM, + SFXGE_TXQ_IP_TCP_UDP_CKSUM, + SFXGE_TXQ_NTYPES +}; + +#define SFXGE_TXQ_UNBLOCK_LEVEL (EFX_TXQ_LIMIT(SFXGE_NDESCS) / 4) + +#define SFXGE_TX_BATCH 64 + +#ifdef SFXGE_HAVE_MQ +#define SFXGE_TXQ_LOCK(txq) (&(txq)->lock) +#define SFXGE_TX_SCALE(sc) ((sc)->intr.n_alloc) +#else +#define SFXGE_TXQ_LOCK(txq) (&(txq)->sc->tx_lock) +#define SFXGE_TX_SCALE(sc) 1 +#endif + +struct sfxge_txq { + /* The following fields should be written very rarely */ + struct sfxge_softc *sc; + enum sfxge_txq_state init_state; + enum sfxge_flush_state flush_state; + enum sfxge_txq_type type; + unsigned int txq_index; + unsigned int evq_index; + efsys_mem_t mem; + unsigned int buf_base_id; + + struct sfxge_tx_mapping *stmp; /* Packets in flight. */ + bus_dma_tag_t packet_dma_tag; + efx_buffer_t *pend_desc; + efx_txq_t *common; + struct sfxge_txq *next; + + efsys_mem_t *tsoh_buffer; + + /* This field changes more often and is read regularly on both + * the initiation and completion paths + */ + int blocked __aligned(CACHE_LINE_SIZE); + + /* The following fields change more often, and are used mostly + * on the initiation path + */ +#ifdef SFXGE_HAVE_MQ + struct mtx lock __aligned(CACHE_LINE_SIZE); + struct sfxge_tx_dpl dpl; /* Deferred packet list. */ + unsigned int n_pend_desc; +#else + unsigned int n_pend_desc __aligned(CACHE_LINE_SIZE); +#endif + unsigned int added; + unsigned int reaped; + /* Statistics */ + unsigned long tso_bursts; + unsigned long tso_packets; + unsigned long tso_long_headers; + unsigned long collapses; + unsigned long drops; + + /* The following fields change more often, and are used mostly + * on the completion path + */ + unsigned int pending __aligned(CACHE_LINE_SIZE); + unsigned int completed; +}; + +extern int sfxge_tx_packet_add(struct sfxge_txq *, struct mbuf *); + +extern int sfxge_tx_init(struct sfxge_softc *sc); +extern void sfxge_tx_fini(struct sfxge_softc *sc); +extern int sfxge_tx_start(struct sfxge_softc *sc); +extern void sfxge_tx_stop(struct sfxge_softc *sc); +extern void sfxge_tx_qcomplete(struct sfxge_txq *txq); +extern void sfxge_tx_qflush_done(struct sfxge_txq *txq); +#ifdef SFXGE_HAVE_MQ +extern void sfxge_if_qflush(struct ifnet *ifp); +extern int sfxge_if_transmit(struct ifnet *ifp, struct mbuf *m); +#else +extern void sfxge_if_start(struct ifnet *ifp); +#endif + +#endif diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 17d5be0b5a92..c3b13e1c575f 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -275,6 +275,7 @@ SUBDIR= ${_3dfx} \ sem \ send \ sf \ + sfxge \ sge \ siba_bwn \ siftr \ diff --git a/sys/modules/sfxge/Makefile b/sys/modules/sfxge/Makefile new file mode 100644 index 000000000000..f18e8adb01a6 --- /dev/null +++ b/sys/modules/sfxge/Makefile @@ -0,0 +1,25 @@ +# $FreeBSD$ + +KMOD= sfxge + +SFXGE= ${.CURDIR}/../../dev/sfxge + +SRCS= device_if.h bus_if.h pci_if.h +SRCS+= opt_inet.h opt_zero.h opt_sched.h + +.PATH: ${.CURDIR}/../../dev/sfxge +SRCS+= sfxge.c sfxge_dma.c sfxge_ev.c +SRCS+= sfxge_intr.c sfxge_mcdi.c +SRCS+= sfxge_port.c sfxge_rx.c sfxge_tx.c + +.PATH: ${.CURDIR}/../../dev/sfxge/common +SRCS+= efx_ev.c efx_intr.c efx_mac.c efx_mcdi.c efx_nic.c +SRCS+= efx_nvram.c efx_phy.c efx_port.c efx_rx.c efx_sram.c efx_tx.c +SRCS+= efx_vpd.c efx_wol.c + +SRCS+= siena_mac.c siena_nic.c siena_nvram.c siena_phy.c +SRCS+= siena_sram.c siena_vpd.c + +DEBUG_FLAGS= -g -DDEBUG=1 + +.include -- cgit v1.2.3