blob: e48981994b107c0794331247a6789e7b2d50a3d5 [file] [log] [blame]
/*
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* GPL LICENSE SUMMARY
*
* Copyright(c) 2015 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* BSD LICENSE
*
* Copyright(c) 2015 Intel Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* This file contains all of the code that is specific to the HFI chip
*/
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include "hfi.h"
#include "trace.h"
#include "mad.h"
#include "pio.h"
#include "sdma.h"
#include "eprom.h"
#define NUM_IB_PORTS 1
uint kdeth_qp;
module_param_named(kdeth_qp, kdeth_qp, uint, S_IRUGO);
MODULE_PARM_DESC(kdeth_qp, "Set the KDETH queue pair prefix");
uint num_vls = HFI1_MAX_VLS_SUPPORTED;
module_param(num_vls, uint, S_IRUGO);
MODULE_PARM_DESC(num_vls, "Set number of Virtual Lanes to use (1-8)");
/*
* Default time to aggregate two 10K packets from the idle state
* (timer not running). The timer starts at the end of the first packet,
* so only the time for one 10K packet and header plus a bit extra is needed.
* 10 * 1024 + 64 header byte = 10304 byte
* 10304 byte / 12.5 GB/s = 824.32ns
*/
uint rcv_intr_timeout = (824 + 16); /* 16 is for coalescing interrupt */
module_param(rcv_intr_timeout, uint, S_IRUGO);
MODULE_PARM_DESC(rcv_intr_timeout, "Receive interrupt mitigation timeout in ns");
uint rcv_intr_count = 16; /* same as qib */
module_param(rcv_intr_count, uint, S_IRUGO);
MODULE_PARM_DESC(rcv_intr_count, "Receive interrupt mitigation count");
ushort link_crc_mask = SUPPORTED_CRCS;
module_param(link_crc_mask, ushort, S_IRUGO);
MODULE_PARM_DESC(link_crc_mask, "CRCs to use on the link");
uint loopback;
module_param_named(loopback, loopback, uint, S_IRUGO);
MODULE_PARM_DESC(loopback, "Put into loopback mode (1 = serdes, 3 = external cable");
/* Other driver tunables */
uint rcv_intr_dynamic = 1; /* enable dynamic mode for rcv int mitigation*/
static ushort crc_14b_sideband = 1;
static uint use_flr = 1;
uint quick_linkup; /* skip LNI */
struct flag_table {
u64 flag; /* the flag */
char *str; /* description string */
u16 extra; /* extra information */
u16 unused0;
u32 unused1;
};
/* str must be a string constant */
#define FLAG_ENTRY(str, extra, flag) {flag, str, extra}
#define FLAG_ENTRY0(str, flag) {flag, str, 0}
/* Send Error Consequences */
#define SEC_WRITE_DROPPED 0x1
#define SEC_PACKET_DROPPED 0x2
#define SEC_SC_HALTED 0x4 /* per-context only */
#define SEC_SPC_FREEZE 0x8 /* per-HFI only */
#define VL15CTXT 1
#define MIN_KERNEL_KCTXTS 2
#define NUM_MAP_REGS 32
/* Bit offset into the GUID which carries HFI id information */
#define GUID_HFI_INDEX_SHIFT 39
/* extract the emulation revision */
#define emulator_rev(dd) ((dd)->irev >> 8)
/* parallel and serial emulation versions are 3 and 4 respectively */
#define is_emulator_p(dd) ((((dd)->irev) & 0xf) == 3)
#define is_emulator_s(dd) ((((dd)->irev) & 0xf) == 4)
/* RSM fields */
/* packet type */
#define IB_PACKET_TYPE 2ull
#define QW_SHIFT 6ull
/* QPN[7..1] */
#define QPN_WIDTH 7ull
/* LRH.BTH: QW 0, OFFSET 48 - for match */
#define LRH_BTH_QW 0ull
#define LRH_BTH_BIT_OFFSET 48ull
#define LRH_BTH_OFFSET(off) ((LRH_BTH_QW << QW_SHIFT) | (off))
#define LRH_BTH_MATCH_OFFSET LRH_BTH_OFFSET(LRH_BTH_BIT_OFFSET)
#define LRH_BTH_SELECT
#define LRH_BTH_MASK 3ull
#define LRH_BTH_VALUE 2ull
/* LRH.SC[3..0] QW 0, OFFSET 56 - for match */
#define LRH_SC_QW 0ull
#define LRH_SC_BIT_OFFSET 56ull
#define LRH_SC_OFFSET(off) ((LRH_SC_QW << QW_SHIFT) | (off))
#define LRH_SC_MATCH_OFFSET LRH_SC_OFFSET(LRH_SC_BIT_OFFSET)
#define LRH_SC_MASK 128ull
#define LRH_SC_VALUE 0ull
/* SC[n..0] QW 0, OFFSET 60 - for select */
#define LRH_SC_SELECT_OFFSET ((LRH_SC_QW << QW_SHIFT) | (60ull))
/* QPN[m+n:1] QW 1, OFFSET 1 */
#define QPN_SELECT_OFFSET ((1ull << QW_SHIFT) | (1ull))
/* defines to build power on SC2VL table */
#define SC2VL_VAL( \
num, \
sc0, sc0val, \
sc1, sc1val, \
sc2, sc2val, \
sc3, sc3val, \
sc4, sc4val, \
sc5, sc5val, \
sc6, sc6val, \
sc7, sc7val) \
( \
((u64)(sc0val) << SEND_SC2VLT##num##_SC##sc0##_SHIFT) | \
((u64)(sc1val) << SEND_SC2VLT##num##_SC##sc1##_SHIFT) | \
((u64)(sc2val) << SEND_SC2VLT##num##_SC##sc2##_SHIFT) | \
((u64)(sc3val) << SEND_SC2VLT##num##_SC##sc3##_SHIFT) | \
((u64)(sc4val) << SEND_SC2VLT##num##_SC##sc4##_SHIFT) | \
((u64)(sc5val) << SEND_SC2VLT##num##_SC##sc5##_SHIFT) | \
((u64)(sc6val) << SEND_SC2VLT##num##_SC##sc6##_SHIFT) | \
((u64)(sc7val) << SEND_SC2VLT##num##_SC##sc7##_SHIFT) \
)
#define DC_SC_VL_VAL( \
range, \
e0, e0val, \
e1, e1val, \
e2, e2val, \
e3, e3val, \
e4, e4val, \
e5, e5val, \
e6, e6val, \
e7, e7val, \
e8, e8val, \
e9, e9val, \
e10, e10val, \
e11, e11val, \
e12, e12val, \
e13, e13val, \
e14, e14val, \
e15, e15val) \
( \
((u64)(e0val) << DCC_CFG_SC_VL_TABLE_##range##_ENTRY##e0##_SHIFT) | \
((u64)(e1val) << DCC_CFG_SC_VL_TABLE_##range##_ENTRY##e1##_SHIFT) | \
((u64)(e2val) << DCC_CFG_SC_VL_TABLE_##range##_ENTRY##e2##_SHIFT) | \
((u64)(e3val) << DCC_CFG_SC_VL_TABLE_##range##_ENTRY##e3##_SHIFT) | \
((u64)(e4val) << DCC_CFG_SC_VL_TABLE_##range##_ENTRY##e4##_SHIFT) | \
((u64)(e5val) << DCC_CFG_SC_VL_TABLE_##range##_ENTRY##e5##_SHIFT) | \
((u64)(e6val) << DCC_CFG_SC_VL_TABLE_##range##_ENTRY##e6##_SHIFT) | \
((u64)(e7val) << DCC_CFG_SC_VL_TABLE_##range##_ENTRY##e7##_SHIFT) | \
((u64)(e8val) << DCC_CFG_SC_VL_TABLE_##range##_ENTRY##e8##_SHIFT) | \
((u64)(e9val) << DCC_CFG_SC_VL_TABLE_##range##_ENTRY##e9##_SHIFT) | \
((u64)(e10val) << DCC_CFG_SC_VL_TABLE_##range##_ENTRY##e10##_SHIFT) | \
((u64)(e11val) << DCC_CFG_SC_VL_TABLE_##range##_ENTRY##e11##_SHIFT) | \
((u64)(e12val) << DCC_CFG_SC_VL_TABLE_##range##_ENTRY##e12##_SHIFT) | \
((u64)(e13val) << DCC_CFG_SC_VL_TABLE_##range##_ENTRY##e13##_SHIFT) | \
((u64)(e14val) << DCC_CFG_SC_VL_TABLE_##range##_ENTRY##e14##_SHIFT) | \
((u64)(e15val) << DCC_CFG_SC_VL_TABLE_##range##_ENTRY##e15##_SHIFT) \
)
/* all CceStatus sub-block freeze bits */
#define ALL_FROZE (CCE_STATUS_SDMA_FROZE_SMASK \
| CCE_STATUS_RXE_FROZE_SMASK \
| CCE_STATUS_TXE_FROZE_SMASK \
| CCE_STATUS_TXE_PIO_FROZE_SMASK)
/* all CceStatus sub-block TXE pause bits */
#define ALL_TXE_PAUSE (CCE_STATUS_TXE_PIO_PAUSED_SMASK \
| CCE_STATUS_TXE_PAUSED_SMASK \
| CCE_STATUS_SDMA_PAUSED_SMASK)
/* all CceStatus sub-block RXE pause bits */
#define ALL_RXE_PAUSE CCE_STATUS_RXE_PAUSED_SMASK
/*
* CCE Error flags.
*/
static struct flag_table cce_err_status_flags[] = {
/* 0*/ FLAG_ENTRY0("CceCsrParityErr",
CCE_ERR_STATUS_CCE_CSR_PARITY_ERR_SMASK),
/* 1*/ FLAG_ENTRY0("CceCsrReadBadAddrErr",
CCE_ERR_STATUS_CCE_CSR_READ_BAD_ADDR_ERR_SMASK),
/* 2*/ FLAG_ENTRY0("CceCsrWriteBadAddrErr",
CCE_ERR_STATUS_CCE_CSR_WRITE_BAD_ADDR_ERR_SMASK),
/* 3*/ FLAG_ENTRY0("CceTrgtAsyncFifoParityErr",
CCE_ERR_STATUS_CCE_TRGT_ASYNC_FIFO_PARITY_ERR_SMASK),
/* 4*/ FLAG_ENTRY0("CceTrgtAccessErr",
CCE_ERR_STATUS_CCE_TRGT_ACCESS_ERR_SMASK),
/* 5*/ FLAG_ENTRY0("CceRspdDataParityErr",
CCE_ERR_STATUS_CCE_RSPD_DATA_PARITY_ERR_SMASK),
/* 6*/ FLAG_ENTRY0("CceCli0AsyncFifoParityErr",
CCE_ERR_STATUS_CCE_CLI0_ASYNC_FIFO_PARITY_ERR_SMASK),
/* 7*/ FLAG_ENTRY0("CceCsrCfgBusParityErr",
CCE_ERR_STATUS_CCE_CSR_CFG_BUS_PARITY_ERR_SMASK),
/* 8*/ FLAG_ENTRY0("CceCli2AsyncFifoParityErr",
CCE_ERR_STATUS_CCE_CLI2_ASYNC_FIFO_PARITY_ERR_SMASK),
/* 9*/ FLAG_ENTRY0("CceCli1AsyncFifoPioCrdtParityErr",
CCE_ERR_STATUS_CCE_CLI1_ASYNC_FIFO_PIO_CRDT_PARITY_ERR_SMASK),
/*10*/ FLAG_ENTRY0("CceCli1AsyncFifoPioCrdtParityErr",
CCE_ERR_STATUS_CCE_CLI1_ASYNC_FIFO_SDMA_HD_PARITY_ERR_SMASK),
/*11*/ FLAG_ENTRY0("CceCli1AsyncFifoRxdmaParityError",
CCE_ERR_STATUS_CCE_CLI1_ASYNC_FIFO_RXDMA_PARITY_ERROR_SMASK),
/*12*/ FLAG_ENTRY0("CceCli1AsyncFifoDbgParityError",
CCE_ERR_STATUS_CCE_CLI1_ASYNC_FIFO_DBG_PARITY_ERROR_SMASK),
/*13*/ FLAG_ENTRY0("PcicRetryMemCorErr",
CCE_ERR_STATUS_PCIC_RETRY_MEM_COR_ERR_SMASK),
/*14*/ FLAG_ENTRY0("PcicRetryMemCorErr",
CCE_ERR_STATUS_PCIC_RETRY_SOT_MEM_COR_ERR_SMASK),
/*15*/ FLAG_ENTRY0("PcicPostHdQCorErr",
CCE_ERR_STATUS_PCIC_POST_HD_QCOR_ERR_SMASK),
/*16*/ FLAG_ENTRY0("PcicPostHdQCorErr",
CCE_ERR_STATUS_PCIC_POST_DAT_QCOR_ERR_SMASK),
/*17*/ FLAG_ENTRY0("PcicPostHdQCorErr",
CCE_ERR_STATUS_PCIC_CPL_HD_QCOR_ERR_SMASK),
/*18*/ FLAG_ENTRY0("PcicCplDatQCorErr",
CCE_ERR_STATUS_PCIC_CPL_DAT_QCOR_ERR_SMASK),
/*19*/ FLAG_ENTRY0("PcicNPostHQParityErr",
CCE_ERR_STATUS_PCIC_NPOST_HQ_PARITY_ERR_SMASK),
/*20*/ FLAG_ENTRY0("PcicNPostDatQParityErr",
CCE_ERR_STATUS_PCIC_NPOST_DAT_QPARITY_ERR_SMASK),
/*21*/ FLAG_ENTRY0("PcicRetryMemUncErr",
CCE_ERR_STATUS_PCIC_RETRY_MEM_UNC_ERR_SMASK),
/*22*/ FLAG_ENTRY0("PcicRetrySotMemUncErr",
CCE_ERR_STATUS_PCIC_RETRY_SOT_MEM_UNC_ERR_SMASK),
/*23*/ FLAG_ENTRY0("PcicPostHdQUncErr",
CCE_ERR_STATUS_PCIC_POST_HD_QUNC_ERR_SMASK),
/*24*/ FLAG_ENTRY0("PcicPostDatQUncErr",
CCE_ERR_STATUS_PCIC_POST_DAT_QUNC_ERR_SMASK),
/*25*/ FLAG_ENTRY0("PcicCplHdQUncErr",
CCE_ERR_STATUS_PCIC_CPL_HD_QUNC_ERR_SMASK),
/*26*/ FLAG_ENTRY0("PcicCplDatQUncErr",
CCE_ERR_STATUS_PCIC_CPL_DAT_QUNC_ERR_SMASK),
/*27*/ FLAG_ENTRY0("PcicTransmitFrontParityErr",
CCE_ERR_STATUS_PCIC_TRANSMIT_FRONT_PARITY_ERR_SMASK),
/*28*/ FLAG_ENTRY0("PcicTransmitBackParityErr",
CCE_ERR_STATUS_PCIC_TRANSMIT_BACK_PARITY_ERR_SMASK),
/*29*/ FLAG_ENTRY0("PcicReceiveParityErr",
CCE_ERR_STATUS_PCIC_RECEIVE_PARITY_ERR_SMASK),
/*30*/ FLAG_ENTRY0("CceTrgtCplTimeoutErr",
CCE_ERR_STATUS_CCE_TRGT_CPL_TIMEOUT_ERR_SMASK),
/*31*/ FLAG_ENTRY0("LATriggered",
CCE_ERR_STATUS_LA_TRIGGERED_SMASK),
/*32*/ FLAG_ENTRY0("CceSegReadBadAddrErr",
CCE_ERR_STATUS_CCE_SEG_READ_BAD_ADDR_ERR_SMASK),
/*33*/ FLAG_ENTRY0("CceSegWriteBadAddrErr",
CCE_ERR_STATUS_CCE_SEG_WRITE_BAD_ADDR_ERR_SMASK),
/*34*/ FLAG_ENTRY0("CceRcplAsyncFifoParityErr",
CCE_ERR_STATUS_CCE_RCPL_ASYNC_FIFO_PARITY_ERR_SMASK),
/*35*/ FLAG_ENTRY0("CceRxdmaConvFifoParityErr",
CCE_ERR_STATUS_CCE_RXDMA_CONV_FIFO_PARITY_ERR_SMASK),
/*36*/ FLAG_ENTRY0("CceMsixTableCorErr",
CCE_ERR_STATUS_CCE_MSIX_TABLE_COR_ERR_SMASK),
/*37*/ FLAG_ENTRY0("CceMsixTableUncErr",
CCE_ERR_STATUS_CCE_MSIX_TABLE_UNC_ERR_SMASK),
/*38*/ FLAG_ENTRY0("CceIntMapCorErr",
CCE_ERR_STATUS_CCE_INT_MAP_COR_ERR_SMASK),
/*39*/ FLAG_ENTRY0("CceIntMapUncErr",
CCE_ERR_STATUS_CCE_INT_MAP_UNC_ERR_SMASK),
/*40*/ FLAG_ENTRY0("CceMsixCsrParityErr",
CCE_ERR_STATUS_CCE_MSIX_CSR_PARITY_ERR_SMASK),
/*41-63 reserved*/
};
/*
* Misc Error flags
*/
#define MES(text) MISC_ERR_STATUS_MISC_##text##_ERR_SMASK
static struct flag_table misc_err_status_flags[] = {
/* 0*/ FLAG_ENTRY0("CSR_PARITY", MES(CSR_PARITY)),
/* 1*/ FLAG_ENTRY0("CSR_READ_BAD_ADDR", MES(CSR_READ_BAD_ADDR)),
/* 2*/ FLAG_ENTRY0("CSR_WRITE_BAD_ADDR", MES(CSR_WRITE_BAD_ADDR)),
/* 3*/ FLAG_ENTRY0("SBUS_WRITE_FAILED", MES(SBUS_WRITE_FAILED)),
/* 4*/ FLAG_ENTRY0("KEY_MISMATCH", MES(KEY_MISMATCH)),
/* 5*/ FLAG_ENTRY0("FW_AUTH_FAILED", MES(FW_AUTH_FAILED)),
/* 6*/ FLAG_ENTRY0("EFUSE_CSR_PARITY", MES(EFUSE_CSR_PARITY)),
/* 7*/ FLAG_ENTRY0("EFUSE_READ_BAD_ADDR", MES(EFUSE_READ_BAD_ADDR)),
/* 8*/ FLAG_ENTRY0("EFUSE_WRITE", MES(EFUSE_WRITE)),
/* 9*/ FLAG_ENTRY0("EFUSE_DONE_PARITY", MES(EFUSE_DONE_PARITY)),
/*10*/ FLAG_ENTRY0("INVALID_EEP_CMD", MES(INVALID_EEP_CMD)),
/*11*/ FLAG_ENTRY0("MBIST_FAIL", MES(MBIST_FAIL)),
/*12*/ FLAG_ENTRY0("PLL_LOCK_FAIL", MES(PLL_LOCK_FAIL))
};
/*
* TXE PIO Error flags and consequences
*/
static struct flag_table pio_err_status_flags[] = {
/* 0*/ FLAG_ENTRY("PioWriteBadCtxt",
SEC_WRITE_DROPPED,
SEND_PIO_ERR_STATUS_PIO_WRITE_BAD_CTXT_ERR_SMASK),
/* 1*/ FLAG_ENTRY("PioWriteAddrParity",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_WRITE_ADDR_PARITY_ERR_SMASK),
/* 2*/ FLAG_ENTRY("PioCsrParity",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_CSR_PARITY_ERR_SMASK),
/* 3*/ FLAG_ENTRY("PioSbMemFifo0",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_SB_MEM_FIFO0_ERR_SMASK),
/* 4*/ FLAG_ENTRY("PioSbMemFifo1",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_SB_MEM_FIFO1_ERR_SMASK),
/* 5*/ FLAG_ENTRY("PioPccFifoParity",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_PCC_FIFO_PARITY_ERR_SMASK),
/* 6*/ FLAG_ENTRY("PioPecFifoParity",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_PEC_FIFO_PARITY_ERR_SMASK),
/* 7*/ FLAG_ENTRY("PioSbrdctlCrrelParity",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_SBRDCTL_CRREL_PARITY_ERR_SMASK),
/* 8*/ FLAG_ENTRY("PioSbrdctrlCrrelFifoParity",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_SBRDCTRL_CRREL_FIFO_PARITY_ERR_SMASK),
/* 9*/ FLAG_ENTRY("PioPktEvictFifoParityErr",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_PKT_EVICT_FIFO_PARITY_ERR_SMASK),
/*10*/ FLAG_ENTRY("PioSmPktResetParity",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_SM_PKT_RESET_PARITY_ERR_SMASK),
/*11*/ FLAG_ENTRY("PioVlLenMemBank0Unc",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_VL_LEN_MEM_BANK0_UNC_ERR_SMASK),
/*12*/ FLAG_ENTRY("PioVlLenMemBank1Unc",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_VL_LEN_MEM_BANK1_UNC_ERR_SMASK),
/*13*/ FLAG_ENTRY("PioVlLenMemBank0Cor",
0,
SEND_PIO_ERR_STATUS_PIO_VL_LEN_MEM_BANK0_COR_ERR_SMASK),
/*14*/ FLAG_ENTRY("PioVlLenMemBank1Cor",
0,
SEND_PIO_ERR_STATUS_PIO_VL_LEN_MEM_BANK1_COR_ERR_SMASK),
/*15*/ FLAG_ENTRY("PioCreditRetFifoParity",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_CREDIT_RET_FIFO_PARITY_ERR_SMASK),
/*16*/ FLAG_ENTRY("PioPpmcPblFifo",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_PPMC_PBL_FIFO_ERR_SMASK),
/*17*/ FLAG_ENTRY("PioInitSmIn",
0,
SEND_PIO_ERR_STATUS_PIO_INIT_SM_IN_ERR_SMASK),
/*18*/ FLAG_ENTRY("PioPktEvictSmOrArbSm",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_PKT_EVICT_SM_OR_ARB_SM_ERR_SMASK),
/*19*/ FLAG_ENTRY("PioHostAddrMemUnc",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_HOST_ADDR_MEM_UNC_ERR_SMASK),
/*20*/ FLAG_ENTRY("PioHostAddrMemCor",
0,
SEND_PIO_ERR_STATUS_PIO_HOST_ADDR_MEM_COR_ERR_SMASK),
/*21*/ FLAG_ENTRY("PioWriteDataParity",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_WRITE_DATA_PARITY_ERR_SMASK),
/*22*/ FLAG_ENTRY("PioStateMachine",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_STATE_MACHINE_ERR_SMASK),
/*23*/ FLAG_ENTRY("PioWriteQwValidParity",
SEC_WRITE_DROPPED|SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_WRITE_QW_VALID_PARITY_ERR_SMASK),
/*24*/ FLAG_ENTRY("PioBlockQwCountParity",
SEC_WRITE_DROPPED|SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_BLOCK_QW_COUNT_PARITY_ERR_SMASK),
/*25*/ FLAG_ENTRY("PioVlfVlLenParity",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_VLF_VL_LEN_PARITY_ERR_SMASK),
/*26*/ FLAG_ENTRY("PioVlfSopParity",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_VLF_SOP_PARITY_ERR_SMASK),
/*27*/ FLAG_ENTRY("PioVlFifoParity",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_VL_FIFO_PARITY_ERR_SMASK),
/*28*/ FLAG_ENTRY("PioPpmcBqcMemParity",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_PPMC_BQC_MEM_PARITY_ERR_SMASK),
/*29*/ FLAG_ENTRY("PioPpmcSopLen",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_PPMC_SOP_LEN_ERR_SMASK),
/*30-31 reserved*/
/*32*/ FLAG_ENTRY("PioCurrentFreeCntParity",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_CURRENT_FREE_CNT_PARITY_ERR_SMASK),
/*33*/ FLAG_ENTRY("PioLastReturnedCntParity",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_LAST_RETURNED_CNT_PARITY_ERR_SMASK),
/*34*/ FLAG_ENTRY("PioPccSopHeadParity",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_PCC_SOP_HEAD_PARITY_ERR_SMASK),
/*35*/ FLAG_ENTRY("PioPecSopHeadParityErr",
SEC_SPC_FREEZE,
SEND_PIO_ERR_STATUS_PIO_PEC_SOP_HEAD_PARITY_ERR_SMASK),
/*36-63 reserved*/
};
/* TXE PIO errors that cause an SPC freeze */
#define ALL_PIO_FREEZE_ERR \
(SEND_PIO_ERR_STATUS_PIO_WRITE_ADDR_PARITY_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_CSR_PARITY_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_SB_MEM_FIFO0_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_SB_MEM_FIFO1_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_PCC_FIFO_PARITY_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_PEC_FIFO_PARITY_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_SBRDCTL_CRREL_PARITY_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_SBRDCTRL_CRREL_FIFO_PARITY_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_PKT_EVICT_FIFO_PARITY_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_SM_PKT_RESET_PARITY_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_VL_LEN_MEM_BANK0_UNC_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_VL_LEN_MEM_BANK1_UNC_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_CREDIT_RET_FIFO_PARITY_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_PPMC_PBL_FIFO_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_PKT_EVICT_SM_OR_ARB_SM_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_HOST_ADDR_MEM_UNC_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_WRITE_DATA_PARITY_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_STATE_MACHINE_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_WRITE_QW_VALID_PARITY_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_BLOCK_QW_COUNT_PARITY_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_VLF_VL_LEN_PARITY_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_VLF_SOP_PARITY_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_VL_FIFO_PARITY_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_PPMC_BQC_MEM_PARITY_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_PPMC_SOP_LEN_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_CURRENT_FREE_CNT_PARITY_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_LAST_RETURNED_CNT_PARITY_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_PCC_SOP_HEAD_PARITY_ERR_SMASK \
| SEND_PIO_ERR_STATUS_PIO_PEC_SOP_HEAD_PARITY_ERR_SMASK)
/*
* TXE SDMA Error flags
*/
static struct flag_table sdma_err_status_flags[] = {
/* 0*/ FLAG_ENTRY0("SDmaRpyTagErr",
SEND_DMA_ERR_STATUS_SDMA_RPY_TAG_ERR_SMASK),
/* 1*/ FLAG_ENTRY0("SDmaCsrParityErr",
SEND_DMA_ERR_STATUS_SDMA_CSR_PARITY_ERR_SMASK),
/* 2*/ FLAG_ENTRY0("SDmaPcieReqTrackingUncErr",
SEND_DMA_ERR_STATUS_SDMA_PCIE_REQ_TRACKING_UNC_ERR_SMASK),
/* 3*/ FLAG_ENTRY0("SDmaPcieReqTrackingCorErr",
SEND_DMA_ERR_STATUS_SDMA_PCIE_REQ_TRACKING_COR_ERR_SMASK),
/*04-63 reserved*/
};
/* TXE SDMA errors that cause an SPC freeze */
#define ALL_SDMA_FREEZE_ERR \
(SEND_DMA_ERR_STATUS_SDMA_RPY_TAG_ERR_SMASK \
| SEND_DMA_ERR_STATUS_SDMA_CSR_PARITY_ERR_SMASK \
| SEND_DMA_ERR_STATUS_SDMA_PCIE_REQ_TRACKING_UNC_ERR_SMASK)
/*
* TXE Egress Error flags
*/
#define SEES(text) SEND_EGRESS_ERR_STATUS_##text##_ERR_SMASK
static struct flag_table egress_err_status_flags[] = {
/* 0*/ FLAG_ENTRY0("TxPktIntegrityMemCorErr", SEES(TX_PKT_INTEGRITY_MEM_COR)),
/* 1*/ FLAG_ENTRY0("TxPktIntegrityMemUncErr", SEES(TX_PKT_INTEGRITY_MEM_UNC)),
/* 2 reserved */
/* 3*/ FLAG_ENTRY0("TxEgressFifoUnderrunOrParityErr",
SEES(TX_EGRESS_FIFO_UNDERRUN_OR_PARITY)),
/* 4*/ FLAG_ENTRY0("TxLinkdownErr", SEES(TX_LINKDOWN)),
/* 5*/ FLAG_ENTRY0("TxIncorrectLinkStateErr", SEES(TX_INCORRECT_LINK_STATE)),
/* 6 reserved */
/* 7*/ FLAG_ENTRY0("TxPioLaunchIntfParityErr",
SEES(TX_PIO_LAUNCH_INTF_PARITY)),
/* 8*/ FLAG_ENTRY0("TxSdmaLaunchIntfParityErr",
SEES(TX_SDMA_LAUNCH_INTF_PARITY)),
/* 9-10 reserved */
/*11*/ FLAG_ENTRY0("TxSbrdCtlStateMachineParityErr",
SEES(TX_SBRD_CTL_STATE_MACHINE_PARITY)),
/*12*/ FLAG_ENTRY0("TxIllegalVLErr", SEES(TX_ILLEGAL_VL)),
/*13*/ FLAG_ENTRY0("TxLaunchCsrParityErr", SEES(TX_LAUNCH_CSR_PARITY)),
/*14*/ FLAG_ENTRY0("TxSbrdCtlCsrParityErr", SEES(TX_SBRD_CTL_CSR_PARITY)),
/*15*/ FLAG_ENTRY0("TxConfigParityErr", SEES(TX_CONFIG_PARITY)),
/*16*/ FLAG_ENTRY0("TxSdma0DisallowedPacketErr",
SEES(TX_SDMA0_DISALLOWED_PACKET)),
/*17*/ FLAG_ENTRY0("TxSdma1DisallowedPacketErr",
SEES(TX_SDMA1_DISALLOWED_PACKET)),
/*18*/ FLAG_ENTRY0("TxSdma2DisallowedPacketErr",
SEES(TX_SDMA2_DISALLOWED_PACKET)),
/*19*/ FLAG_ENTRY0("TxSdma3DisallowedPacketErr",
SEES(TX_SDMA3_DISALLOWED_PACKET)),
/*20*/ FLAG_ENTRY0("TxSdma4DisallowedPacketErr",
SEES(TX_SDMA4_DISALLOWED_PACKET)),
/*21*/ FLAG_ENTRY0("TxSdma5DisallowedPacketErr",
SEES(TX_SDMA5_DISALLOWED_PACKET)),
/*22*/ FLAG_ENTRY0("TxSdma6DisallowedPacketErr",
SEES(TX_SDMA6_DISALLOWED_PACKET)),
/*23*/ FLAG_ENTRY0("TxSdma7DisallowedPacketErr",
SEES(TX_SDMA7_DISALLOWED_PACKET)),
/*24*/ FLAG_ENTRY0("TxSdma8DisallowedPacketErr",
SEES(TX_SDMA8_DISALLOWED_PACKET)),
/*25*/ FLAG_ENTRY0("TxSdma9DisallowedPacketErr",
SEES(TX_SDMA9_DISALLOWED_PACKET)),
/*26*/ FLAG_ENTRY0("TxSdma10DisallowedPacketErr",
SEES(TX_SDMA10_DISALLOWED_PACKET)),
/*27*/ FLAG_ENTRY0("TxSdma11DisallowedPacketErr",
SEES(TX_SDMA11_DISALLOWED_PACKET)),
/*28*/ FLAG_ENTRY0("TxSdma12DisallowedPacketErr",
SEES(TX_SDMA12_DISALLOWED_PACKET)),
/*29*/ FLAG_ENTRY0("TxSdma13DisallowedPacketErr",
SEES(TX_SDMA13_DISALLOWED_PACKET)),
/*30*/ FLAG_ENTRY0("TxSdma14DisallowedPacketErr",
SEES(TX_SDMA14_DISALLOWED_PACKET)),
/*31*/ FLAG_ENTRY0("TxSdma15DisallowedPacketErr",
SEES(TX_SDMA15_DISALLOWED_PACKET)),
/*32*/ FLAG_ENTRY0("TxLaunchFifo0UncOrParityErr",
SEES(TX_LAUNCH_FIFO0_UNC_OR_PARITY)),
/*33*/ FLAG_ENTRY0("TxLaunchFifo1UncOrParityErr",
SEES(TX_LAUNCH_FIFO1_UNC_OR_PARITY)),
/*34*/ FLAG_ENTRY0("TxLaunchFifo2UncOrParityErr",
SEES(TX_LAUNCH_FIFO2_UNC_OR_PARITY)),
/*35*/ FLAG_ENTRY0("TxLaunchFifo3UncOrParityErr",
SEES(TX_LAUNCH_FIFO3_UNC_OR_PARITY)),
/*36*/ FLAG_ENTRY0("TxLaunchFifo4UncOrParityErr",
SEES(TX_LAUNCH_FIFO4_UNC_OR_PARITY)),
/*37*/ FLAG_ENTRY0("TxLaunchFifo5UncOrParityErr",
SEES(TX_LAUNCH_FIFO5_UNC_OR_PARITY)),
/*38*/ FLAG_ENTRY0("TxLaunchFifo6UncOrParityErr",
SEES(TX_LAUNCH_FIFO6_UNC_OR_PARITY)),
/*39*/ FLAG_ENTRY0("TxLaunchFifo7UncOrParityErr",
SEES(TX_LAUNCH_FIFO7_UNC_OR_PARITY)),
/*40*/ FLAG_ENTRY0("TxLaunchFifo8UncOrParityErr",
SEES(TX_LAUNCH_FIFO8_UNC_OR_PARITY)),
/*41*/ FLAG_ENTRY0("TxCreditReturnParityErr", SEES(TX_CREDIT_RETURN_PARITY)),
/*42*/ FLAG_ENTRY0("TxSbHdrUncErr", SEES(TX_SB_HDR_UNC)),
/*43*/ FLAG_ENTRY0("TxReadSdmaMemoryUncErr", SEES(TX_READ_SDMA_MEMORY_UNC)),
/*44*/ FLAG_ENTRY0("TxReadPioMemoryUncErr", SEES(TX_READ_PIO_MEMORY_UNC)),
/*45*/ FLAG_ENTRY0("TxEgressFifoUncErr", SEES(TX_EGRESS_FIFO_UNC)),
/*46*/ FLAG_ENTRY0("TxHcrcInsertionErr", SEES(TX_HCRC_INSERTION)),
/*47*/ FLAG_ENTRY0("TxCreditReturnVLErr", SEES(TX_CREDIT_RETURN_VL)),
/*48*/ FLAG_ENTRY0("TxLaunchFifo0CorErr", SEES(TX_LAUNCH_FIFO0_COR)),
/*49*/ FLAG_ENTRY0("TxLaunchFifo1CorErr", SEES(TX_LAUNCH_FIFO1_COR)),
/*50*/ FLAG_ENTRY0("TxLaunchFifo2CorErr", SEES(TX_LAUNCH_FIFO2_COR)),
/*51*/ FLAG_ENTRY0("TxLaunchFifo3CorErr", SEES(TX_LAUNCH_FIFO3_COR)),
/*52*/ FLAG_ENTRY0("TxLaunchFifo4CorErr", SEES(TX_LAUNCH_FIFO4_COR)),
/*53*/ FLAG_ENTRY0("TxLaunchFifo5CorErr", SEES(TX_LAUNCH_FIFO5_COR)),
/*54*/ FLAG_ENTRY0("TxLaunchFifo6CorErr", SEES(TX_LAUNCH_FIFO6_COR)),
/*55*/ FLAG_ENTRY0("TxLaunchFifo7CorErr", SEES(TX_LAUNCH_FIFO7_COR)),
/*56*/ FLAG_ENTRY0("TxLaunchFifo8CorErr", SEES(TX_LAUNCH_FIFO8_COR)),
/*57*/ FLAG_ENTRY0("TxCreditOverrunErr", SEES(TX_CREDIT_OVERRUN)),
/*58*/ FLAG_ENTRY0("TxSbHdrCorErr", SEES(TX_SB_HDR_COR)),
/*59*/ FLAG_ENTRY0("TxReadSdmaMemoryCorErr", SEES(TX_READ_SDMA_MEMORY_COR)),
/*60*/ FLAG_ENTRY0("TxReadPioMemoryCorErr", SEES(TX_READ_PIO_MEMORY_COR)),
/*61*/ FLAG_ENTRY0("TxEgressFifoCorErr", SEES(TX_EGRESS_FIFO_COR)),
/*62*/ FLAG_ENTRY0("TxReadSdmaMemoryCsrUncErr",
SEES(TX_READ_SDMA_MEMORY_CSR_UNC)),
/*63*/ FLAG_ENTRY0("TxReadPioMemoryCsrUncErr",
SEES(TX_READ_PIO_MEMORY_CSR_UNC)),
};
/*
* TXE Egress Error Info flags
*/
#define SEEI(text) SEND_EGRESS_ERR_INFO_##text##_ERR_SMASK
static struct flag_table egress_err_info_flags[] = {
/* 0*/ FLAG_ENTRY0("Reserved", 0ull),
/* 1*/ FLAG_ENTRY0("VLErr", SEEI(VL)),
/* 2*/ FLAG_ENTRY0("JobKeyErr", SEEI(JOB_KEY)),
/* 3*/ FLAG_ENTRY0("JobKeyErr", SEEI(JOB_KEY)),
/* 4*/ FLAG_ENTRY0("PartitionKeyErr", SEEI(PARTITION_KEY)),
/* 5*/ FLAG_ENTRY0("SLIDErr", SEEI(SLID)),
/* 6*/ FLAG_ENTRY0("OpcodeErr", SEEI(OPCODE)),
/* 7*/ FLAG_ENTRY0("VLMappingErr", SEEI(VL_MAPPING)),
/* 8*/ FLAG_ENTRY0("RawErr", SEEI(RAW)),
/* 9*/ FLAG_ENTRY0("RawIPv6Err", SEEI(RAW_IPV6)),
/*10*/ FLAG_ENTRY0("GRHErr", SEEI(GRH)),
/*11*/ FLAG_ENTRY0("BypassErr", SEEI(BYPASS)),
/*12*/ FLAG_ENTRY0("KDETHPacketsErr", SEEI(KDETH_PACKETS)),
/*13*/ FLAG_ENTRY0("NonKDETHPacketsErr", SEEI(NON_KDETH_PACKETS)),
/*14*/ FLAG_ENTRY0("TooSmallIBPacketsErr", SEEI(TOO_SMALL_IB_PACKETS)),
/*15*/ FLAG_ENTRY0("TooSmallBypassPacketsErr", SEEI(TOO_SMALL_BYPASS_PACKETS)),
/*16*/ FLAG_ENTRY0("PbcTestErr", SEEI(PBC_TEST)),
/*17*/ FLAG_ENTRY0("BadPktLenErr", SEEI(BAD_PKT_LEN)),
/*18*/ FLAG_ENTRY0("TooLongIBPacketErr", SEEI(TOO_LONG_IB_PACKET)),
/*19*/ FLAG_ENTRY0("TooLongBypassPacketsErr", SEEI(TOO_LONG_BYPASS_PACKETS)),
/*20*/ FLAG_ENTRY0("PbcStaticRateControlErr", SEEI(PBC_STATIC_RATE_CONTROL)),
/*21*/ FLAG_ENTRY0("BypassBadPktLenErr", SEEI(BAD_PKT_LEN)),
};
/* TXE Egress errors that cause an SPC freeze */
#define ALL_TXE_EGRESS_FREEZE_ERR \
(SEES(TX_EGRESS_FIFO_UNDERRUN_OR_PARITY) \
| SEES(TX_PIO_LAUNCH_INTF_PARITY) \
| SEES(TX_SDMA_LAUNCH_INTF_PARITY) \
| SEES(TX_SBRD_CTL_STATE_MACHINE_PARITY) \
| SEES(TX_LAUNCH_CSR_PARITY) \
| SEES(TX_SBRD_CTL_CSR_PARITY) \
| SEES(TX_CONFIG_PARITY) \
| SEES(TX_LAUNCH_FIFO0_UNC_OR_PARITY) \
| SEES(TX_LAUNCH_FIFO1_UNC_OR_PARITY) \
| SEES(TX_LAUNCH_FIFO2_UNC_OR_PARITY) \
| SEES(TX_LAUNCH_FIFO3_UNC_OR_PARITY) \
| SEES(TX_LAUNCH_FIFO4_UNC_OR_PARITY) \
| SEES(TX_LAUNCH_FIFO5_UNC_OR_PARITY) \
| SEES(TX_LAUNCH_FIFO6_UNC_OR_PARITY) \
| SEES(TX_LAUNCH_FIFO7_UNC_OR_PARITY) \
| SEES(TX_LAUNCH_FIFO8_UNC_OR_PARITY) \
| SEES(TX_CREDIT_RETURN_PARITY))
/*
* TXE Send error flags
*/
#define SES(name) SEND_ERR_STATUS_SEND_##name##_ERR_SMASK
static struct flag_table send_err_status_flags[] = {
/* 0*/ FLAG_ENTRY0("SDmaRpyTagErr", SES(CSR_PARITY)),
/* 1*/ FLAG_ENTRY0("SendCsrReadBadAddrErr", SES(CSR_READ_BAD_ADDR)),
/* 2*/ FLAG_ENTRY0("SendCsrWriteBadAddrErr", SES(CSR_WRITE_BAD_ADDR))
};
/*
* TXE Send Context Error flags and consequences
*/
static struct flag_table sc_err_status_flags[] = {
/* 0*/ FLAG_ENTRY("InconsistentSop",
SEC_PACKET_DROPPED | SEC_SC_HALTED,
SEND_CTXT_ERR_STATUS_PIO_INCONSISTENT_SOP_ERR_SMASK),
/* 1*/ FLAG_ENTRY("DisallowedPacket",
SEC_PACKET_DROPPED | SEC_SC_HALTED,
SEND_CTXT_ERR_STATUS_PIO_DISALLOWED_PACKET_ERR_SMASK),
/* 2*/ FLAG_ENTRY("WriteCrossesBoundary",
SEC_WRITE_DROPPED | SEC_SC_HALTED,
SEND_CTXT_ERR_STATUS_PIO_WRITE_CROSSES_BOUNDARY_ERR_SMASK),
/* 3*/ FLAG_ENTRY("WriteOverflow",
SEC_WRITE_DROPPED | SEC_SC_HALTED,
SEND_CTXT_ERR_STATUS_PIO_WRITE_OVERFLOW_ERR_SMASK),
/* 4*/ FLAG_ENTRY("WriteOutOfBounds",
SEC_WRITE_DROPPED | SEC_SC_HALTED,
SEND_CTXT_ERR_STATUS_PIO_WRITE_OUT_OF_BOUNDS_ERR_SMASK),
/* 5-63 reserved*/
};
/*
* RXE Receive Error flags
*/
#define RXES(name) RCV_ERR_STATUS_RX_##name##_ERR_SMASK
static struct flag_table rxe_err_status_flags[] = {
/* 0*/ FLAG_ENTRY0("RxDmaCsrCorErr", RXES(DMA_CSR_COR)),
/* 1*/ FLAG_ENTRY0("RxDcIntfParityErr", RXES(DC_INTF_PARITY)),
/* 2*/ FLAG_ENTRY0("RxRcvHdrUncErr", RXES(RCV_HDR_UNC)),
/* 3*/ FLAG_ENTRY0("RxRcvHdrCorErr", RXES(RCV_HDR_COR)),
/* 4*/ FLAG_ENTRY0("RxRcvDataUncErr", RXES(RCV_DATA_UNC)),
/* 5*/ FLAG_ENTRY0("RxRcvDataCorErr", RXES(RCV_DATA_COR)),
/* 6*/ FLAG_ENTRY0("RxRcvQpMapTableUncErr", RXES(RCV_QP_MAP_TABLE_UNC)),
/* 7*/ FLAG_ENTRY0("RxRcvQpMapTableCorErr", RXES(RCV_QP_MAP_TABLE_COR)),
/* 8*/ FLAG_ENTRY0("RxRcvCsrParityErr", RXES(RCV_CSR_PARITY)),
/* 9*/ FLAG_ENTRY0("RxDcSopEopParityErr", RXES(DC_SOP_EOP_PARITY)),
/*10*/ FLAG_ENTRY0("RxDmaFlagUncErr", RXES(DMA_FLAG_UNC)),
/*11*/ FLAG_ENTRY0("RxDmaFlagCorErr", RXES(DMA_FLAG_COR)),
/*12*/ FLAG_ENTRY0("RxRcvFsmEncodingErr", RXES(RCV_FSM_ENCODING)),
/*13*/ FLAG_ENTRY0("RxRbufFreeListUncErr", RXES(RBUF_FREE_LIST_UNC)),
/*14*/ FLAG_ENTRY0("RxRbufFreeListCorErr", RXES(RBUF_FREE_LIST_COR)),
/*15*/ FLAG_ENTRY0("RxRbufLookupDesRegUncErr", RXES(RBUF_LOOKUP_DES_REG_UNC)),
/*16*/ FLAG_ENTRY0("RxRbufLookupDesRegUncCorErr",
RXES(RBUF_LOOKUP_DES_REG_UNC_COR)),
/*17*/ FLAG_ENTRY0("RxRbufLookupDesUncErr", RXES(RBUF_LOOKUP_DES_UNC)),
/*18*/ FLAG_ENTRY0("RxRbufLookupDesCorErr", RXES(RBUF_LOOKUP_DES_COR)),
/*19*/ FLAG_ENTRY0("RxRbufBlockListReadUncErr",
RXES(RBUF_BLOCK_LIST_READ_UNC)),
/*20*/ FLAG_ENTRY0("RxRbufBlockListReadCorErr",
RXES(RBUF_BLOCK_LIST_READ_COR)),
/*21*/ FLAG_ENTRY0("RxRbufCsrQHeadBufNumParityErr",
RXES(RBUF_CSR_QHEAD_BUF_NUM_PARITY)),
/*22*/ FLAG_ENTRY0("RxRbufCsrQEntCntParityErr",
RXES(RBUF_CSR_QENT_CNT_PARITY)),
/*23*/ FLAG_ENTRY0("RxRbufCsrQNextBufParityErr",
RXES(RBUF_CSR_QNEXT_BUF_PARITY)),
/*24*/ FLAG_ENTRY0("RxRbufCsrQVldBitParityErr",
RXES(RBUF_CSR_QVLD_BIT_PARITY)),
/*25*/ FLAG_ENTRY0("RxRbufCsrQHdPtrParityErr", RXES(RBUF_CSR_QHD_PTR_PARITY)),
/*26*/ FLAG_ENTRY0("RxRbufCsrQTlPtrParityErr", RXES(RBUF_CSR_QTL_PTR_PARITY)),
/*27*/ FLAG_ENTRY0("RxRbufCsrQNumOfPktParityErr",
RXES(RBUF_CSR_QNUM_OF_PKT_PARITY)),
/*28*/ FLAG_ENTRY0("RxRbufCsrQEOPDWParityErr", RXES(RBUF_CSR_QEOPDW_PARITY)),
/*29*/ FLAG_ENTRY0("RxRbufCtxIdParityErr", RXES(RBUF_CTX_ID_PARITY)),
/*30*/ FLAG_ENTRY0("RxRBufBadLookupErr", RXES(RBUF_BAD_LOOKUP)),
/*31*/ FLAG_ENTRY0("RxRbufFullErr", RXES(RBUF_FULL)),
/*32*/ FLAG_ENTRY0("RxRbufEmptyErr", RXES(RBUF_EMPTY)),
/*33*/ FLAG_ENTRY0("RxRbufFlRdAddrParityErr", RXES(RBUF_FL_RD_ADDR_PARITY)),
/*34*/ FLAG_ENTRY0("RxRbufFlWrAddrParityErr", RXES(RBUF_FL_WR_ADDR_PARITY)),
/*35*/ FLAG_ENTRY0("RxRbufFlInitdoneParityErr",
RXES(RBUF_FL_INITDONE_PARITY)),
/*36*/ FLAG_ENTRY0("RxRbufFlInitWrAddrParityErr",
RXES(RBUF_FL_INIT_WR_ADDR_PARITY)),
/*37*/ FLAG_ENTRY0("RxRbufNextFreeBufUncErr", RXES(RBUF_NEXT_FREE_BUF_UNC)),
/*38*/ FLAG_ENTRY0("RxRbufNextFreeBufCorErr", RXES(RBUF_NEXT_FREE_BUF_COR)),
/*39*/ FLAG_ENTRY0("RxLookupDesPart1UncErr", RXES(LOOKUP_DES_PART1_UNC)),
/*40*/ FLAG_ENTRY0("RxLookupDesPart1UncCorErr",
RXES(LOOKUP_DES_PART1_UNC_COR)),
/*41*/ FLAG_ENTRY0("RxLookupDesPart2ParityErr",
RXES(LOOKUP_DES_PART2_PARITY)),
/*42*/ FLAG_ENTRY0("RxLookupRcvArrayUncErr", RXES(LOOKUP_RCV_ARRAY_UNC)),
/*43*/ FLAG_ENTRY0("RxLookupRcvArrayCorErr", RXES(LOOKUP_RCV_ARRAY_COR)),
/*44*/ FLAG_ENTRY0("RxLookupCsrParityErr", RXES(LOOKUP_CSR_PARITY)),
/*45*/ FLAG_ENTRY0("RxHqIntrCsrParityErr", RXES(HQ_INTR_CSR_PARITY)),
/*46*/ FLAG_ENTRY0("RxHqIntrFsmErr", RXES(HQ_INTR_FSM)),
/*47*/ FLAG_ENTRY0("RxRbufDescPart1UncErr", RXES(RBUF_DESC_PART1_UNC)),
/*48*/ FLAG_ENTRY0("RxRbufDescPart1CorErr", RXES(RBUF_DESC_PART1_COR)),
/*49*/ FLAG_ENTRY0("RxRbufDescPart2UncErr", RXES(RBUF_DESC_PART2_UNC)),
/*50*/ FLAG_ENTRY0("RxRbufDescPart2CorErr", RXES(RBUF_DESC_PART2_COR)),
/*51*/ FLAG_ENTRY0("RxDmaHdrFifoRdUncErr", RXES(DMA_HDR_FIFO_RD_UNC)),
/*52*/ FLAG_ENTRY0("RxDmaHdrFifoRdCorErr", RXES(DMA_HDR_FIFO_RD_COR)),
/*53*/ FLAG_ENTRY0("RxDmaDataFifoRdUncErr", RXES(DMA_DATA_FIFO_RD_UNC)),
/*54*/ FLAG_ENTRY0("RxDmaDataFifoRdCorErr", RXES(DMA_DATA_FIFO_RD_COR)),
/*55*/ FLAG_ENTRY0("RxRbufDataUncErr", RXES(RBUF_DATA_UNC)),
/*56*/ FLAG_ENTRY0("RxRbufDataCorErr", RXES(RBUF_DATA_COR)),
/*57*/ FLAG_ENTRY0("RxDmaCsrParityErr", RXES(DMA_CSR_PARITY)),
/*58*/ FLAG_ENTRY0("RxDmaEqFsmEncodingErr", RXES(DMA_EQ_FSM_ENCODING)),
/*59*/ FLAG_ENTRY0("RxDmaDqFsmEncodingErr", RXES(DMA_DQ_FSM_ENCODING)),
/*60*/ FLAG_ENTRY0("RxDmaCsrUncErr", RXES(DMA_CSR_UNC)),
/*61*/ FLAG_ENTRY0("RxCsrReadBadAddrErr", RXES(CSR_READ_BAD_ADDR)),
/*62*/ FLAG_ENTRY0("RxCsrWriteBadAddrErr", RXES(CSR_WRITE_BAD_ADDR)),
/*63*/ FLAG_ENTRY0("RxCsrParityErr", RXES(CSR_PARITY))
};
/* RXE errors that will trigger an SPC freeze */
#define ALL_RXE_FREEZE_ERR \
(RCV_ERR_STATUS_RX_RCV_QP_MAP_TABLE_UNC_ERR_SMASK \
| RCV_ERR_STATUS_RX_RCV_CSR_PARITY_ERR_SMASK \
| RCV_ERR_STATUS_RX_DMA_FLAG_UNC_ERR_SMASK \
| RCV_ERR_STATUS_RX_RCV_FSM_ENCODING_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_FREE_LIST_UNC_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_LOOKUP_DES_REG_UNC_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_LOOKUP_DES_REG_UNC_COR_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_LOOKUP_DES_UNC_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_BLOCK_LIST_READ_UNC_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_CSR_QHEAD_BUF_NUM_PARITY_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_CSR_QENT_CNT_PARITY_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_CSR_QNEXT_BUF_PARITY_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_CSR_QVLD_BIT_PARITY_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_CSR_QHD_PTR_PARITY_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_CSR_QTL_PTR_PARITY_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_CSR_QNUM_OF_PKT_PARITY_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_CSR_QEOPDW_PARITY_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_CTX_ID_PARITY_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_BAD_LOOKUP_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_FULL_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_EMPTY_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_FL_RD_ADDR_PARITY_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_FL_WR_ADDR_PARITY_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_FL_INITDONE_PARITY_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_FL_INIT_WR_ADDR_PARITY_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_NEXT_FREE_BUF_UNC_ERR_SMASK \
| RCV_ERR_STATUS_RX_LOOKUP_DES_PART1_UNC_ERR_SMASK \
| RCV_ERR_STATUS_RX_LOOKUP_DES_PART1_UNC_COR_ERR_SMASK \
| RCV_ERR_STATUS_RX_LOOKUP_DES_PART2_PARITY_ERR_SMASK \
| RCV_ERR_STATUS_RX_LOOKUP_RCV_ARRAY_UNC_ERR_SMASK \
| RCV_ERR_STATUS_RX_LOOKUP_CSR_PARITY_ERR_SMASK \
| RCV_ERR_STATUS_RX_HQ_INTR_CSR_PARITY_ERR_SMASK \
| RCV_ERR_STATUS_RX_HQ_INTR_FSM_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_DESC_PART1_UNC_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_DESC_PART1_COR_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_DESC_PART2_UNC_ERR_SMASK \
| RCV_ERR_STATUS_RX_DMA_HDR_FIFO_RD_UNC_ERR_SMASK \
| RCV_ERR_STATUS_RX_DMA_DATA_FIFO_RD_UNC_ERR_SMASK \
| RCV_ERR_STATUS_RX_RBUF_DATA_UNC_ERR_SMASK \
| RCV_ERR_STATUS_RX_DMA_CSR_PARITY_ERR_SMASK \
| RCV_ERR_STATUS_RX_DMA_EQ_FSM_ENCODING_ERR_SMASK \
| RCV_ERR_STATUS_RX_DMA_DQ_FSM_ENCODING_ERR_SMASK \
| RCV_ERR_STATUS_RX_DMA_CSR_UNC_ERR_SMASK \
| RCV_ERR_STATUS_RX_CSR_PARITY_ERR_SMASK)
#define RXE_FREEZE_ABORT_MASK \
(RCV_ERR_STATUS_RX_DMA_CSR_UNC_ERR_SMASK | \
RCV_ERR_STATUS_RX_DMA_HDR_FIFO_RD_UNC_ERR_SMASK | \
RCV_ERR_STATUS_RX_DMA_DATA_FIFO_RD_UNC_ERR_SMASK)
/*
* DCC Error Flags
*/
#define DCCE(name) DCC_ERR_FLG_##name##_SMASK
static struct flag_table dcc_err_flags[] = {
FLAG_ENTRY0("bad_l2_err", DCCE(BAD_L2_ERR)),
FLAG_ENTRY0("bad_sc_err", DCCE(BAD_SC_ERR)),
FLAG_ENTRY0("bad_mid_tail_err", DCCE(BAD_MID_TAIL_ERR)),
FLAG_ENTRY0("bad_preemption_err", DCCE(BAD_PREEMPTION_ERR)),
FLAG_ENTRY0("preemption_err", DCCE(PREEMPTION_ERR)),
FLAG_ENTRY0("preemptionvl15_err", DCCE(PREEMPTIONVL15_ERR)),
FLAG_ENTRY0("bad_vl_marker_err", DCCE(BAD_VL_MARKER_ERR)),
FLAG_ENTRY0("bad_dlid_target_err", DCCE(BAD_DLID_TARGET_ERR)),
FLAG_ENTRY0("bad_lver_err", DCCE(BAD_LVER_ERR)),
FLAG_ENTRY0("uncorrectable_err", DCCE(UNCORRECTABLE_ERR)),
FLAG_ENTRY0("bad_crdt_ack_err", DCCE(BAD_CRDT_ACK_ERR)),
FLAG_ENTRY0("unsup_pkt_type", DCCE(UNSUP_PKT_TYPE)),
FLAG_ENTRY0("bad_ctrl_flit_err", DCCE(BAD_CTRL_FLIT_ERR)),
FLAG_ENTRY0("event_cntr_parity_err", DCCE(EVENT_CNTR_PARITY_ERR)),
FLAG_ENTRY0("event_cntr_rollover_err", DCCE(EVENT_CNTR_ROLLOVER_ERR)),
FLAG_ENTRY0("link_err", DCCE(LINK_ERR)),
FLAG_ENTRY0("misc_cntr_rollover_err", DCCE(MISC_CNTR_ROLLOVER_ERR)),
FLAG_ENTRY0("bad_ctrl_dist_err", DCCE(BAD_CTRL_DIST_ERR)),
FLAG_ENTRY0("bad_tail_dist_err", DCCE(BAD_TAIL_DIST_ERR)),
FLAG_ENTRY0("bad_head_dist_err", DCCE(BAD_HEAD_DIST_ERR)),
FLAG_ENTRY0("nonvl15_state_err", DCCE(NONVL15_STATE_ERR)),
FLAG_ENTRY0("vl15_multi_err", DCCE(VL15_MULTI_ERR)),
FLAG_ENTRY0("bad_pkt_length_err", DCCE(BAD_PKT_LENGTH_ERR)),
FLAG_ENTRY0("unsup_vl_err", DCCE(UNSUP_VL_ERR)),
FLAG_ENTRY0("perm_nvl15_err", DCCE(PERM_NVL15_ERR)),
FLAG_ENTRY0("slid_zero_err", DCCE(SLID_ZERO_ERR)),
FLAG_ENTRY0("dlid_zero_err", DCCE(DLID_ZERO_ERR)),
FLAG_ENTRY0("length_mtu_err", DCCE(LENGTH_MTU_ERR)),
FLAG_ENTRY0("rx_early_drop_err", DCCE(RX_EARLY_DROP_ERR)),
FLAG_ENTRY0("late_short_err", DCCE(LATE_SHORT_ERR)),
FLAG_ENTRY0("late_long_err", DCCE(LATE_LONG_ERR)),
FLAG_ENTRY0("late_ebp_err", DCCE(LATE_EBP_ERR)),
FLAG_ENTRY0("fpe_tx_fifo_ovflw_err", DCCE(FPE_TX_FIFO_OVFLW_ERR)),
FLAG_ENTRY0("fpe_tx_fifo_unflw_err", DCCE(FPE_TX_FIFO_UNFLW_ERR)),
FLAG_ENTRY0("csr_access_blocked_host", DCCE(CSR_ACCESS_BLOCKED_HOST)),
FLAG_ENTRY0("csr_access_blocked_uc", DCCE(CSR_ACCESS_BLOCKED_UC)),
FLAG_ENTRY0("tx_ctrl_parity_err", DCCE(TX_CTRL_PARITY_ERR)),
FLAG_ENTRY0("tx_ctrl_parity_mbe_err", DCCE(TX_CTRL_PARITY_MBE_ERR)),
FLAG_ENTRY0("tx_sc_parity_err", DCCE(TX_SC_PARITY_ERR)),
FLAG_ENTRY0("rx_ctrl_parity_mbe_err", DCCE(RX_CTRL_PARITY_MBE_ERR)),
FLAG_ENTRY0("csr_parity_err", DCCE(CSR_PARITY_ERR)),
FLAG_ENTRY0("csr_inval_addr", DCCE(CSR_INVAL_ADDR)),
FLAG_ENTRY0("tx_byte_shft_parity_err", DCCE(TX_BYTE_SHFT_PARITY_ERR)),
FLAG_ENTRY0("rx_byte_shft_parity_err", DCCE(RX_BYTE_SHFT_PARITY_ERR)),
FLAG_ENTRY0("fmconfig_err", DCCE(FMCONFIG_ERR)),
FLAG_ENTRY0("rcvport_err", DCCE(RCVPORT_ERR)),
};
/*
* LCB error flags
*/
#define LCBE(name) DC_LCB_ERR_FLG_##name##_SMASK
static struct flag_table lcb_err_flags[] = {
/* 0*/ FLAG_ENTRY0("CSR_PARITY_ERR", LCBE(CSR_PARITY_ERR)),
/* 1*/ FLAG_ENTRY0("INVALID_CSR_ADDR", LCBE(INVALID_CSR_ADDR)),
/* 2*/ FLAG_ENTRY0("RST_FOR_FAILED_DESKEW", LCBE(RST_FOR_FAILED_DESKEW)),
/* 3*/ FLAG_ENTRY0("ALL_LNS_FAILED_REINIT_TEST",
LCBE(ALL_LNS_FAILED_REINIT_TEST)),
/* 4*/ FLAG_ENTRY0("LOST_REINIT_STALL_OR_TOS", LCBE(LOST_REINIT_STALL_OR_TOS)),
/* 5*/ FLAG_ENTRY0("TX_LESS_THAN_FOUR_LNS", LCBE(TX_LESS_THAN_FOUR_LNS)),
/* 6*/ FLAG_ENTRY0("RX_LESS_THAN_FOUR_LNS", LCBE(RX_LESS_THAN_FOUR_LNS)),
/* 7*/ FLAG_ENTRY0("SEQ_CRC_ERR", LCBE(SEQ_CRC_ERR)),
/* 8*/ FLAG_ENTRY0("REINIT_FROM_PEER", LCBE(REINIT_FROM_PEER)),
/* 9*/ FLAG_ENTRY0("REINIT_FOR_LN_DEGRADE", LCBE(REINIT_FOR_LN_DEGRADE)),
/*10*/ FLAG_ENTRY0("CRC_ERR_CNT_HIT_LIMIT", LCBE(CRC_ERR_CNT_HIT_LIMIT)),
/*11*/ FLAG_ENTRY0("RCLK_STOPPED", LCBE(RCLK_STOPPED)),
/*12*/ FLAG_ENTRY0("UNEXPECTED_REPLAY_MARKER", LCBE(UNEXPECTED_REPLAY_MARKER)),
/*13*/ FLAG_ENTRY0("UNEXPECTED_ROUND_TRIP_MARKER",
LCBE(UNEXPECTED_ROUND_TRIP_MARKER)),
/*14*/ FLAG_ENTRY0("ILLEGAL_NULL_LTP", LCBE(ILLEGAL_NULL_LTP)),
/*15*/ FLAG_ENTRY0("ILLEGAL_FLIT_ENCODING", LCBE(ILLEGAL_FLIT_ENCODING)),
/*16*/ FLAG_ENTRY0("FLIT_INPUT_BUF_OFLW", LCBE(FLIT_INPUT_BUF_OFLW)),
/*17*/ FLAG_ENTRY0("VL_ACK_INPUT_BUF_OFLW", LCBE(VL_ACK_INPUT_BUF_OFLW)),
/*18*/ FLAG_ENTRY0("VL_ACK_INPUT_PARITY_ERR", LCBE(VL_ACK_INPUT_PARITY_ERR)),
/*19*/ FLAG_ENTRY0("VL_ACK_INPUT_WRONG_CRC_MODE",
LCBE(VL_ACK_INPUT_WRONG_CRC_MODE)),
/*20*/ FLAG_ENTRY0("FLIT_INPUT_BUF_MBE", LCBE(FLIT_INPUT_BUF_MBE)),
/*21*/ FLAG_ENTRY0("FLIT_INPUT_BUF_SBE", LCBE(FLIT_INPUT_BUF_SBE)),
/*22*/ FLAG_ENTRY0("REPLAY_BUF_MBE", LCBE(REPLAY_BUF_MBE)),
/*23*/ FLAG_ENTRY0("REPLAY_BUF_SBE", LCBE(REPLAY_BUF_SBE)),
/*24*/ FLAG_ENTRY0("CREDIT_RETURN_FLIT_MBE", LCBE(CREDIT_RETURN_FLIT_MBE)),
/*25*/ FLAG_ENTRY0("RST_FOR_LINK_TIMEOUT", LCBE(RST_FOR_LINK_TIMEOUT)),
/*26*/ FLAG_ENTRY0("RST_FOR_INCOMPLT_RND_TRIP",
LCBE(RST_FOR_INCOMPLT_RND_TRIP)),
/*27*/ FLAG_ENTRY0("HOLD_REINIT", LCBE(HOLD_REINIT)),
/*28*/ FLAG_ENTRY0("NEG_EDGE_LINK_TRANSFER_ACTIVE",
LCBE(NEG_EDGE_LINK_TRANSFER_ACTIVE)),
/*29*/ FLAG_ENTRY0("REDUNDANT_FLIT_PARITY_ERR",
LCBE(REDUNDANT_FLIT_PARITY_ERR))
};
/*
* DC8051 Error Flags
*/
#define D8E(name) DC_DC8051_ERR_FLG_##name##_SMASK
static struct flag_table dc8051_err_flags[] = {
FLAG_ENTRY0("SET_BY_8051", D8E(SET_BY_8051)),
FLAG_ENTRY0("LOST_8051_HEART_BEAT", D8E(LOST_8051_HEART_BEAT)),
FLAG_ENTRY0("CRAM_MBE", D8E(CRAM_MBE)),
FLAG_ENTRY0("CRAM_SBE", D8E(CRAM_SBE)),
FLAG_ENTRY0("DRAM_MBE", D8E(DRAM_MBE)),
FLAG_ENTRY0("DRAM_SBE", D8E(DRAM_SBE)),
FLAG_ENTRY0("IRAM_MBE", D8E(IRAM_MBE)),
FLAG_ENTRY0("IRAM_SBE", D8E(IRAM_SBE)),
FLAG_ENTRY0("UNMATCHED_SECURE_MSG_ACROSS_BCC_LANES",
D8E(UNMATCHED_SECURE_MSG_ACROSS_BCC_LANES)),
FLAG_ENTRY0("INVALID_CSR_ADDR", D8E(INVALID_CSR_ADDR)),
};
/*
* DC8051 Information Error flags
*
* Flags in DC8051_DBG_ERR_INFO_SET_BY_8051.ERROR field.
*/
static struct flag_table dc8051_info_err_flags[] = {
FLAG_ENTRY0("Spico ROM check failed", SPICO_ROM_FAILED),
FLAG_ENTRY0("Unknown frame received", UNKNOWN_FRAME),
FLAG_ENTRY0("Target BER not met", TARGET_BER_NOT_MET),
FLAG_ENTRY0("Serdes internal loopback failure",
FAILED_SERDES_INTERNAL_LOOPBACK),
FLAG_ENTRY0("Failed SerDes init", FAILED_SERDES_INIT),
FLAG_ENTRY0("Failed LNI(Polling)", FAILED_LNI_POLLING),
FLAG_ENTRY0("Failed LNI(Debounce)", FAILED_LNI_DEBOUNCE),
FLAG_ENTRY0("Failed LNI(EstbComm)", FAILED_LNI_ESTBCOMM),
FLAG_ENTRY0("Failed LNI(OptEq)", FAILED_LNI_OPTEQ),
FLAG_ENTRY0("Failed LNI(VerifyCap_1)", FAILED_LNI_VERIFY_CAP1),
FLAG_ENTRY0("Failed LNI(VerifyCap_2)", FAILED_LNI_VERIFY_CAP2),
FLAG_ENTRY0("Failed LNI(ConfigLT)", FAILED_LNI_CONFIGLT)
};
/*
* DC8051 Information Host Information flags
*
* Flags in DC8051_DBG_ERR_INFO_SET_BY_8051.HOST_MSG field.
*/
static struct flag_table dc8051_info_host_msg_flags[] = {
FLAG_ENTRY0("Host request done", 0x0001),
FLAG_ENTRY0("BC SMA message", 0x0002),
FLAG_ENTRY0("BC PWR_MGM message", 0x0004),
FLAG_ENTRY0("BC Unknown message (BCC)", 0x0008),
FLAG_ENTRY0("BC Unknown message (LCB)", 0x0010),
FLAG_ENTRY0("External device config request", 0x0020),
FLAG_ENTRY0("VerifyCap all frames received", 0x0040),
FLAG_ENTRY0("LinkUp achieved", 0x0080),
FLAG_ENTRY0("Link going down", 0x0100),
};
static u32 encoded_size(u32 size);
static u32 chip_to_opa_lstate(struct hfi1_devdata *dd, u32 chip_lstate);
static int set_physical_link_state(struct hfi1_devdata *dd, u64 state);
static void read_vc_remote_phy(struct hfi1_devdata *dd, u8 *power_management,
u8 *continuous);
static void read_vc_remote_fabric(struct hfi1_devdata *dd, u8 *vau, u8 *z,
u8 *vcu, u16 *vl15buf, u8 *crc_sizes);
static void read_vc_remote_link_width(struct hfi1_devdata *dd,
u8 *remote_tx_rate, u16 *link_widths);
static void read_vc_local_link_width(struct hfi1_devdata *dd, u8 *misc_bits,
u8 *flag_bits, u16 *link_widths);
static void read_remote_device_id(struct hfi1_devdata *dd, u16 *device_id,
u8 *device_rev);
static void read_mgmt_allowed(struct hfi1_devdata *dd, u8 *mgmt_allowed);
static void read_local_lni(struct hfi1_devdata *dd, u8 *enable_lane_rx);
static int read_tx_settings(struct hfi1_devdata *dd, u8 *enable_lane_tx,
u8 *tx_polarity_inversion,
u8 *rx_polarity_inversion, u8 *max_rate);
static void handle_sdma_eng_err(struct hfi1_devdata *dd,
unsigned int context, u64 err_status);
static void handle_qsfp_int(struct hfi1_devdata *dd, u32 source, u64 reg);
static void handle_dcc_err(struct hfi1_devdata *dd,
unsigned int context, u64 err_status);
static void handle_lcb_err(struct hfi1_devdata *dd,
unsigned int context, u64 err_status);
static void handle_8051_interrupt(struct hfi1_devdata *dd, u32 unused, u64 reg);
static void handle_cce_err(struct hfi1_devdata *dd, u32 unused, u64 reg);
static void handle_rxe_err(struct hfi1_devdata *dd, u32 unused, u64 reg);
static void handle_misc_err(struct hfi1_devdata *dd, u32 unused, u64 reg);
static void handle_pio_err(struct hfi1_devdata *dd, u32 unused, u64 reg);
static void handle_sdma_err(struct hfi1_devdata *dd, u32 unused, u64 reg);
static void handle_egress_err(struct hfi1_devdata *dd, u32 unused, u64 reg);
static void handle_txe_err(struct hfi1_devdata *dd, u32 unused, u64 reg);
static void set_partition_keys(struct hfi1_pportdata *);
static const char *link_state_name(u32 state);
static const char *link_state_reason_name(struct hfi1_pportdata *ppd,
u32 state);
static int do_8051_command(struct hfi1_devdata *dd, u32 type, u64 in_data,
u64 *out_data);
static int read_idle_sma(struct hfi1_devdata *dd, u64 *data);
static int thermal_init(struct hfi1_devdata *dd);
static int wait_logical_linkstate(struct hfi1_pportdata *ppd, u32 state,
int msecs);
static void read_planned_down_reason_code(struct hfi1_devdata *dd, u8 *pdrrc);
static void handle_temp_err(struct hfi1_devdata *);
static void dc_shutdown(struct hfi1_devdata *);
static void dc_start(struct hfi1_devdata *);
/*
* Error interrupt table entry. This is used as input to the interrupt
* "clear down" routine used for all second tier error interrupt register.
* Second tier interrupt registers have a single bit representing them
* in the top-level CceIntStatus.
*/
struct err_reg_info {
u32 status; /* status CSR offset */
u32 clear; /* clear CSR offset */
u32 mask; /* mask CSR offset */
void (*handler)(struct hfi1_devdata *dd, u32 source, u64 reg);
const char *desc;
};
#define NUM_MISC_ERRS (IS_GENERAL_ERR_END - IS_GENERAL_ERR_START)
#define NUM_DC_ERRS (IS_DC_END - IS_DC_START)
#define NUM_VARIOUS (IS_VARIOUS_END - IS_VARIOUS_START)
/*
* Helpers for building HFI and DC error interrupt table entries. Different
* helpers are needed because of inconsistent register names.
*/
#define EE(reg, handler, desc) \
{ reg##_STATUS, reg##_CLEAR, reg##_MASK, \
handler, desc }
#define DC_EE1(reg, handler, desc) \
{ reg##_FLG, reg##_FLG_CLR, reg##_FLG_EN, handler, desc }
#define DC_EE2(reg, handler, desc) \
{ reg##_FLG, reg##_CLR, reg##_EN, handler, desc }
/*
* Table of the "misc" grouping of error interrupts. Each entry refers to
* another register containing more information.
*/
static const struct err_reg_info misc_errs[NUM_MISC_ERRS] = {
/* 0*/ EE(CCE_ERR, handle_cce_err, "CceErr"),
/* 1*/ EE(RCV_ERR, handle_rxe_err, "RxeErr"),
/* 2*/ EE(MISC_ERR, handle_misc_err, "MiscErr"),
/* 3*/ { 0, 0, 0, NULL }, /* reserved */
/* 4*/ EE(SEND_PIO_ERR, handle_pio_err, "PioErr"),
/* 5*/ EE(SEND_DMA_ERR, handle_sdma_err, "SDmaErr"),
/* 6*/ EE(SEND_EGRESS_ERR, handle_egress_err, "EgressErr"),
/* 7*/ EE(SEND_ERR, handle_txe_err, "TxeErr")
/* the rest are reserved */
};
/*
* Index into the Various section of the interrupt sources
* corresponding to the Critical Temperature interrupt.
*/
#define TCRIT_INT_SOURCE 4
/*
* SDMA error interrupt entry - refers to another register containing more
* information.
*/
static const struct err_reg_info sdma_eng_err =
EE(SEND_DMA_ENG_ERR, handle_sdma_eng_err, "SDmaEngErr");
static const struct err_reg_info various_err[NUM_VARIOUS] = {
/* 0*/ { 0, 0, 0, NULL }, /* PbcInt */
/* 1*/ { 0, 0, 0, NULL }, /* GpioAssertInt */
/* 2*/ EE(ASIC_QSFP1, handle_qsfp_int, "QSFP1"),
/* 3*/ EE(ASIC_QSFP2, handle_qsfp_int, "QSFP2"),
/* 4*/ { 0, 0, 0, NULL }, /* TCritInt */
/* rest are reserved */
};
/*
* The DC encoding of mtu_cap for 10K MTU in the DCC_CFG_PORT_CONFIG
* register can not be derived from the MTU value because 10K is not
* a power of 2. Therefore, we need a constant. Everything else can
* be calculated.
*/
#define DCC_CFG_PORT_MTU_CAP_10240 7
/*
* Table of the DC grouping of error interrupts. Each entry refers to
* another register containing more information.
*/
static const struct err_reg_info dc_errs[NUM_DC_ERRS] = {
/* 0*/ DC_EE1(DCC_ERR, handle_dcc_err, "DCC Err"),
/* 1*/ DC_EE2(DC_LCB_ERR, handle_lcb_err, "LCB Err"),
/* 2*/ DC_EE2(DC_DC8051_ERR, handle_8051_interrupt, "DC8051 Interrupt"),
/* 3*/ /* dc_lbm_int - special, see is_dc_int() */
/* the rest are reserved */
};
struct cntr_entry {
/*
* counter name
*/
char *name;
/*
* csr to read for name (if applicable)
*/
u64 csr;
/*
* offset into dd or ppd to store the counter's value
*/
int offset;
/*
* flags
*/
u8 flags;
/*
* accessor for stat element, context either dd or ppd
*/
u64 (*rw_cntr)(const struct cntr_entry *,
void *context,
int vl,
int mode,
u64 data);
};
#define C_RCV_HDR_OVF_FIRST C_RCV_HDR_OVF_0
#define C_RCV_HDR_OVF_LAST C_RCV_HDR_OVF_159
#define CNTR_ELEM(name, csr, offset, flags, accessor) \
{ \
name, \
csr, \
offset, \
flags, \
accessor \
}
/* 32bit RXE */
#define RXE32_PORT_CNTR_ELEM(name, counter, flags) \
CNTR_ELEM(#name, \
(counter * 8 + RCV_COUNTER_ARRAY32), \
0, flags | CNTR_32BIT, \
port_access_u32_csr)
#define RXE32_DEV_CNTR_ELEM(name, counter, flags) \
CNTR_ELEM(#name, \
(counter * 8 + RCV_COUNTER_ARRAY32), \
0, flags | CNTR_32BIT, \
dev_access_u32_csr)
/* 64bit RXE */
#define RXE64_PORT_CNTR_ELEM(name, counter, flags) \
CNTR_ELEM(#name, \
(counter * 8 + RCV_COUNTER_ARRAY64), \
0, flags, \
port_access_u64_csr)
#define RXE64_DEV_CNTR_ELEM(name, counter, flags) \
CNTR_ELEM(#name, \
(counter * 8 + RCV_COUNTER_ARRAY64), \
0, flags, \
dev_access_u64_csr)
#define OVR_LBL(ctx) C_RCV_HDR_OVF_ ## ctx
#define OVR_ELM(ctx) \
CNTR_ELEM("RcvHdrOvr" #ctx, \
(RCV_HDR_OVFL_CNT + ctx*0x100), \
0, CNTR_NORMAL, port_access_u64_csr)
/* 32bit TXE */
#define TXE32_PORT_CNTR_ELEM(name, counter, flags) \
CNTR_ELEM(#name, \
(counter * 8 + SEND_COUNTER_ARRAY32), \
0, flags | CNTR_32BIT, \
port_access_u32_csr)
/* 64bit TXE */
#define TXE64_PORT_CNTR_ELEM(name, counter, flags) \
CNTR_ELEM(#name, \
(counter * 8 + SEND_COUNTER_ARRAY64), \
0, flags, \
port_access_u64_csr)
# define TX64_DEV_CNTR_ELEM(name, counter, flags) \
CNTR_ELEM(#name,\
counter * 8 + SEND_COUNTER_ARRAY64, \
0, \
flags, \
dev_access_u64_csr)
/* CCE */
#define CCE_PERF_DEV_CNTR_ELEM(name, counter, flags) \
CNTR_ELEM(#name, \
(counter * 8 + CCE_COUNTER_ARRAY32), \
0, flags | CNTR_32BIT, \
dev_access_u32_csr)
#define CCE_INT_DEV_CNTR_ELEM(name, counter, flags) \
CNTR_ELEM(#name, \
(counter * 8 + CCE_INT_COUNTER_ARRAY32), \
0, flags | CNTR_32BIT, \
dev_access_u32_csr)
/* DC */
#define DC_PERF_CNTR(name, counter, flags) \
CNTR_ELEM(#name, \
counter, \
0, \
flags, \
dev_access_u64_csr)
#define DC_PERF_CNTR_LCB(name, counter, flags) \
CNTR_ELEM(#name, \
counter, \
0, \
flags, \
dc_access_lcb_cntr)
/* ibp counters */
#define SW_IBP_CNTR(name, cntr) \
CNTR_ELEM(#name, \
0, \
0, \
CNTR_SYNTH, \
access_ibp_##cntr)
u64 read_csr(const struct hfi1_devdata *dd, u32 offset)
{
u64 val;
if (dd->flags & HFI1_PRESENT) {
val = readq((void __iomem *)dd->kregbase + offset);
return val;
}
return -1;
}
void write_csr(const struct hfi1_devdata *dd, u32 offset, u64 value)
{
if (dd->flags & HFI1_PRESENT)
writeq(value, (void __iomem *)dd->kregbase + offset);
}
void __iomem *get_csr_addr(
struct hfi1_devdata *dd,
u32 offset)
{
return (void __iomem *)dd->kregbase + offset;
}
static inline u64 read_write_csr(const struct hfi1_devdata *dd, u32 csr,
int mode, u64 value)
{
u64 ret;
if (mode == CNTR_MODE_R) {
ret = read_csr(dd, csr);
} else if (mode == CNTR_MODE_W) {
write_csr(dd, csr, value);
ret = value;
} else {
dd_dev_err(dd, "Invalid cntr register access mode");
return 0;
}
hfi1_cdbg(CNTR, "csr 0x%x val 0x%llx mode %d", csr, ret, mode);
return ret;
}
/* Dev Access */
static u64 dev_access_u32_csr(const struct cntr_entry *entry,
void *context, int vl, int mode, u64 data)
{
struct hfi1_devdata *dd = context;
if (vl != CNTR_INVALID_VL)
return 0;
return read_write_csr(dd, entry->csr, mode, data);
}
static u64 dev_access_u64_csr(const struct cntr_entry *entry, void *context,
int vl, int mode, u64 data)
{
struct hfi1_devdata *dd = context;
u64 val = 0;
u64 csr = entry->csr;
if (entry->flags & CNTR_VL) {
if (vl == CNTR_INVALID_VL)
return 0;
csr += 8 * vl;
} else {
if (vl != CNTR_INVALID_VL)
return 0;
}
val = read_write_csr(dd, csr, mode, data);
return val;
}
static u64 dc_access_lcb_cntr(const struct cntr_entry *entry, void *context,
int vl, int mode, u64 data)
{
struct hfi1_devdata *dd = context;
u32 csr = entry->csr;
int ret = 0;
if (vl != CNTR_INVALID_VL)
return 0;
if (mode == CNTR_MODE_R)
ret = read_lcb_csr(dd, csr, &data);
else if (mode == CNTR_MODE_W)
ret = write_lcb_csr(dd, csr, data);
if (ret) {
dd_dev_err(dd, "Could not acquire LCB for counter 0x%x", csr);
return 0;
}
hfi1_cdbg(CNTR, "csr 0x%x val 0x%llx mode %d", csr, data, mode);
return data;
}
/* Port Access */
static u64 port_access_u32_csr(const struct cntr_entry *entry, void *context,
int vl, int mode, u64 data)
{
struct hfi1_pportdata *ppd = context;
if (vl != CNTR_INVALID_VL)
return 0;
return read_write_csr(ppd->dd, entry->csr, mode, data);
}
static u64 port_access_u64_csr(const struct cntr_entry *entry,
void *context, int vl, int mode, u64 data)
{
struct hfi1_pportdata *ppd = context;
u64 val;
u64 csr = entry->csr;
if (entry->flags & CNTR_VL) {
if (vl == CNTR_INVALID_VL)
return 0;
csr += 8 * vl;
} else {
if (vl != CNTR_INVALID_VL)
return 0;
}
val = read_write_csr(ppd->dd, csr, mode, data);
return val;
}
/* Software defined */
static inline u64 read_write_sw(struct hfi1_devdata *dd, u64 *cntr, int mode,
u64 data)
{
u64 ret;
if (mode == CNTR_MODE_R) {
ret = *cntr;
} else if (mode == CNTR_MODE_W) {
*cntr = data;
ret = data;
} else {
dd_dev_err(dd, "Invalid cntr sw access mode");
return 0;
}
hfi1_cdbg(CNTR, "val 0x%llx mode %d", ret, mode);
return ret;
}
static u64 access_sw_link_dn_cnt(const struct cntr_entry *entry, void *context,
int vl, int mode, u64 data)
{
struct hfi1_pportdata *ppd = context;
if (vl != CNTR_INVALID_VL)
return 0;
return read_write_sw(ppd->dd, &ppd->link_downed, mode, data);
}
static u64 access_sw_link_up_cnt(const struct cntr_entry *entry, void *context,
int vl, int mode, u64 data)
{
struct hfi1_pportdata *ppd = context;
if (vl != CNTR_INVALID_VL)
return 0;
return read_write_sw(ppd->dd, &ppd->link_up, mode, data);
}
static u64 access_sw_xmit_discards(const struct cntr_entry *entry,
void *context, int vl, int mode, u64 data)
{
struct hfi1_pportdata *ppd = context;
if (vl != CNTR_INVALID_VL)
return 0;
return read_write_sw(ppd->dd, &ppd->port_xmit_discards, mode, data);
}
static u64 access_xmit_constraint_errs(const struct cntr_entry *entry,
void *context, int vl, int mode, u64 data)
{
struct hfi1_pportdata *ppd = context;
if (vl != CNTR_INVALID_VL)
return 0;
return read_write_sw(ppd->dd, &ppd->port_xmit_constraint_errors,
mode, data);
}
static u64 access_rcv_constraint_errs(const struct cntr_entry *entry,
void *context, int vl, int mode, u64 data)
{
struct hfi1_pportdata *ppd = context;
if (vl != CNTR_INVALID_VL)
return 0;
return read_write_sw(ppd->dd, &ppd->port_rcv_constraint_errors,
mode, data);
}
u64 get_all_cpu_total(u64 __percpu *cntr)
{
int cpu;
u64 counter = 0;
for_each_possible_cpu(cpu)
counter += *per_cpu_ptr(cntr, cpu);
return counter;
}
static u64 read_write_cpu(struct hfi1_devdata *dd, u64 *z_val,
u64 __percpu *cntr,
int vl, int mode, u64 data)
{
u64 ret = 0;
if (vl != CNTR_INVALID_VL)
return 0;
if (mode == CNTR_MODE_R) {
ret = get_all_cpu_total(cntr) - *z_val;
} else if (mode == CNTR_MODE_W) {
/* A write can only zero the counter */
if (data == 0)
*z_val = get_all_cpu_total(cntr);
else
dd_dev_err(dd, "Per CPU cntrs can only be zeroed");
} else {
dd_dev_err(dd, "Invalid cntr sw cpu access mode");
return 0;
}
return ret;
}
static u64 access_sw_cpu_intr(const struct cntr_entry *entry,
void *context, int vl, int mode, u64 data)
{
struct hfi1_devdata *dd = context;
return read_write_cpu(dd, &dd->z_int_counter, dd->int_counter, vl,
mode, data);
}
static u64 access_sw_cpu_rcv_limit(const struct cntr_entry *entry,
void *context, int vl, int mode, u64 data)
{
struct hfi1_devdata *dd = context;
return read_write_cpu(dd, &dd->z_rcv_limit, dd->rcv_limit, vl,
mode, data);
}
static u64 access_sw_pio_wait(const struct cntr_entry *entry,
void *context, int vl, int mode, u64 data)
{
struct hfi1_devdata *dd = context;
return dd->verbs_dev.n_piowait;
}
static u64 access_sw_vtx_wait(const struct cntr_entry *entry,
void *context, int vl, int mode, u64 data)
{
struct hfi1_devdata *dd = context;
return dd->verbs_dev.n_txwait;
}
static u64 access_sw_kmem_wait(const struct cntr_entry *entry,
void *context, int vl, int mode, u64 data)
{
struct hfi1_devdata *dd = context;
return dd->verbs_dev.n_kmem_wait;
}
static u64 access_sw_send_schedule(const struct cntr_entry *entry,
void *context, int vl, int mode, u64 data)
{
struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
return dd->verbs_dev.n_send_schedule;
}
#define def_access_sw_cpu(cntr) \
static u64 access_sw_cpu_##cntr(const struct cntr_entry *entry, \
void *context, int vl, int mode, u64 data) \
{ \
struct hfi1_pportdata *ppd = (struct hfi1_pportdata *)context; \
return read_write_cpu(ppd->dd, &ppd->ibport_data.z_ ##cntr, \
ppd->ibport_data.cntr, vl, \
mode, data); \
}
def_access_sw_cpu(rc_acks);
def_access_sw_cpu(rc_qacks);
def_access_sw_cpu(rc_delayed_comp);
#define def_access_ibp_counter(cntr) \
static u64 access_ibp_##cntr(const struct cntr_entry *entry, \
void *context, int vl, int mode, u64 data) \
{ \
struct hfi1_pportdata *ppd = (struct hfi1_pportdata *)context; \
\
if (vl != CNTR_INVALID_VL) \
return 0; \
\
return read_write_sw(ppd->dd, &ppd->ibport_data.n_ ##cntr, \
mode, data); \
}
def_access_ibp_counter(loop_pkts);
def_access_ibp_counter(rc_resends);
def_access_ibp_counter(rnr_naks);
def_access_ibp_counter(other_naks);
def_access_ibp_counter(rc_timeouts);
def_access_ibp_counter(pkt_drops);
def_access_ibp_counter(dmawait);
def_access_ibp_counter(rc_seqnak);
def_access_ibp_counter(rc_dupreq);
def_access_ibp_counter(rdma_seq);
def_access_ibp_counter(unaligned);
def_access_ibp_counter(seq_naks);
static struct cntr_entry dev_cntrs[DEV_CNTR_LAST] = {
[C_RCV_OVF] = RXE32_DEV_CNTR_ELEM(RcvOverflow, RCV_BUF_OVFL_CNT, CNTR_SYNTH),
[C_RX_TID_FULL] = RXE32_DEV_CNTR_ELEM(RxTIDFullEr, RCV_TID_FULL_ERR_CNT,
CNTR_NORMAL),
[C_RX_TID_INVALID] = RXE32_DEV_CNTR_ELEM(RxTIDInvalid, RCV_TID_VALID_ERR_CNT,
CNTR_NORMAL),
[C_RX_TID_FLGMS] = RXE32_DEV_CNTR_ELEM(RxTidFLGMs,
RCV_TID_FLOW_GEN_MISMATCH_CNT,
CNTR_NORMAL),
[C_RX_CTX_RHQS] = RXE32_DEV_CNTR_ELEM(RxCtxRHQS, RCV_CONTEXT_RHQ_STALL,
CNTR_NORMAL),
[C_RX_CTX_EGRS] = RXE32_DEV_CNTR_ELEM(RxCtxEgrS, RCV_CONTEXT_EGR_STALL,
CNTR_NORMAL),
[C_RCV_TID_FLSMS] = RXE32_DEV_CNTR_ELEM(RxTidFLSMs,
RCV_TID_FLOW_SEQ_MISMATCH_CNT, CNTR_NORMAL),
[C_CCE_PCI_CR_ST] = CCE_PERF_DEV_CNTR_ELEM(CcePciCrSt,
CCE_PCIE_POSTED_CRDT_STALL_CNT, CNTR_NORMAL),
[C_CCE_PCI_TR_ST] = CCE_PERF_DEV_CNTR_ELEM(CcePciTrSt, CCE_PCIE_TRGT_STALL_CNT,
CNTR_NORMAL),
[C_CCE_PIO_WR_ST] = CCE_PERF_DEV_CNTR_ELEM(CcePioWrSt, CCE_PIO_WR_STALL_CNT,
CNTR_NORMAL),
[C_CCE_ERR_INT] = CCE_INT_DEV_CNTR_ELEM(CceErrInt, CCE_ERR_INT_CNT,
CNTR_NORMAL),
[C_CCE_SDMA_INT] = CCE_INT_DEV_CNTR_ELEM(CceSdmaInt, CCE_SDMA_INT_CNT,
CNTR_NORMAL),
[C_CCE_MISC_INT] = CCE_INT_DEV_CNTR_ELEM(CceMiscInt, CCE_MISC_INT_CNT,
CNTR_NORMAL),
[C_CCE_RCV_AV_INT] = CCE_INT_DEV_CNTR_ELEM(CceRcvAvInt, CCE_RCV_AVAIL_INT_CNT,
CNTR_NORMAL),
[C_CCE_RCV_URG_INT] = CCE_INT_DEV_CNTR_ELEM(CceRcvUrgInt,
CCE_RCV_URGENT_INT_CNT, CNTR_NORMAL),
[C_CCE_SEND_CR_INT] = CCE_INT_DEV_CNTR_ELEM(CceSndCrInt,
CCE_SEND_CREDIT_INT_CNT, CNTR_NORMAL),
[C_DC_UNC_ERR] = DC_PERF_CNTR(DcUnctblErr, DCC_ERR_UNCORRECTABLE_CNT,
CNTR_SYNTH),
[C_DC_RCV_ERR] = DC_PERF_CNTR(DcRecvErr, DCC_ERR_PORTRCV_ERR_CNT, CNTR_SYNTH),
[C_DC_FM_CFG_ERR] = DC_PERF_CNTR(DcFmCfgErr, DCC_ERR_FMCONFIG_ERR_CNT,
CNTR_SYNTH),
[C_DC_RMT_PHY_ERR] = DC_PERF_CNTR(DcRmtPhyErr, DCC_ERR_RCVREMOTE_PHY_ERR_CNT,
CNTR_SYNTH),
[C_DC_DROPPED_PKT] = DC_PERF_CNTR(DcDroppedPkt, DCC_ERR_DROPPED_PKT_CNT,
CNTR_SYNTH),
[C_DC_MC_XMIT_PKTS] = DC_PERF_CNTR(DcMcXmitPkts,
DCC_PRF_PORT_XMIT_MULTICAST_CNT, CNTR_SYNTH),
[C_DC_MC_RCV_PKTS] = DC_PERF_CNTR(DcMcRcvPkts,
DCC_PRF_PORT_RCV_MULTICAST_PKT_CNT,
CNTR_SYNTH),
[C_DC_XMIT_CERR] = DC_PERF_CNTR(DcXmitCorr,
DCC_PRF_PORT_XMIT_CORRECTABLE_CNT, CNTR_SYNTH),
[C_DC_RCV_CERR] = DC_PERF_CNTR(DcRcvCorrCnt, DCC_PRF_PORT_RCV_CORRECTABLE_CNT,
CNTR_SYNTH),
[C_DC_RCV_FCC] = DC_PERF_CNTR(DcRxFCntl, DCC_PRF_RX_FLOW_CRTL_CNT,
CNTR_SYNTH),
[C_DC_XMIT_FCC] = DC_PERF_CNTR(DcXmitFCntl, DCC_PRF_TX_FLOW_CRTL_CNT,
CNTR_SYNTH),
[C_DC_XMIT_FLITS] = DC_PERF_CNTR(DcXmitFlits, DCC_PRF_PORT_XMIT_DATA_CNT,
CNTR_SYNTH),
[C_DC_RCV_FLITS] = DC_PERF_CNTR(DcRcvFlits, DCC_PRF_PORT_RCV_DATA_CNT,
CNTR_SYNTH),
[C_DC_XMIT_PKTS] = DC_PERF_CNTR(DcXmitPkts, DCC_PRF_PORT_XMIT_PKTS_CNT,
CNTR_SYNTH),
[C_DC_RCV_PKTS] = DC_PERF_CNTR(DcRcvPkts, DCC_PRF_PORT_RCV_PKTS_CNT,
CNTR_SYNTH),
[C_DC_RX_FLIT_VL] = DC_PERF_CNTR(DcRxFlitVl, DCC_PRF_PORT_VL_RCV_DATA_CNT,
CNTR_SYNTH | CNTR_VL),
[C_DC_RX_PKT_VL] = DC_PERF_CNTR(DcRxPktVl, DCC_PRF_PORT_VL_RCV_PKTS_CNT,
CNTR_SYNTH | CNTR_VL),
[C_DC_RCV_FCN] = DC_PERF_CNTR(DcRcvFcn, DCC_PRF_PORT_RCV_FECN_CNT, CNTR_SYNTH),
[C_DC_RCV_FCN_VL] = DC_PERF_CNTR(DcRcvFcnVl, DCC_PRF_PORT_VL_RCV_FECN_CNT,
CNTR_SYNTH | CNTR_VL),
[C_DC_RCV_BCN] = DC_PERF_CNTR(DcRcvBcn, DCC_PRF_PORT_RCV_BECN_CNT, CNTR_SYNTH),
[C_DC_RCV_BCN_VL] = DC_PERF_CNTR(DcRcvBcnVl, DCC_PRF_PORT_VL_RCV_BECN_CNT,
CNTR_SYNTH | CNTR_VL),
[C_DC_RCV_BBL] = DC_PERF_CNTR(DcRcvBbl, DCC_PRF_PORT_RCV_BUBBLE_CNT,
CNTR_SYNTH),
[C_DC_RCV_BBL_VL] = DC_PERF_CNTR(DcRcvBblVl, DCC_PRF_PORT_VL_RCV_BUBBLE_CNT,
CNTR_SYNTH | CNTR_VL),
[C_DC_MARK_FECN] = DC_PERF_CNTR(DcMarkFcn, DCC_PRF_PORT_MARK_FECN_CNT,
CNTR_SYNTH),
[C_DC_MARK_FECN_VL] = DC_PERF_CNTR(DcMarkFcnVl, DCC_PRF_PORT_VL_MARK_FECN_CNT,
CNTR_SYNTH | CNTR_VL),
[C_DC_TOTAL_CRC] =
DC_PERF_CNTR_LCB(DcTotCrc, DC_LCB_ERR_INFO_TOTAL_CRC_ERR,
CNTR_SYNTH),
[C_DC_CRC_LN0] = DC_PERF_CNTR_LCB(DcCrcLn0, DC_LCB_ERR_INFO_CRC_ERR_LN0,
CNTR_SYNTH),
[C_DC_CRC_LN1] = DC_PERF_CNTR_LCB(DcCrcLn1, DC_LCB_ERR_INFO_CRC_ERR_LN1,
CNTR_SYNTH),
[C_DC_CRC_LN2] = DC_PERF_CNTR_LCB(DcCrcLn2, DC_LCB_ERR_INFO_CRC_ERR_LN2,
CNTR_SYNTH),
[C_DC_CRC_LN3] = DC_PERF_CNTR_LCB(DcCrcLn3, DC_LCB_ERR_INFO_CRC_ERR_LN3,
CNTR_SYNTH),
[C_DC_CRC_MULT_LN] =
DC_PERF_CNTR_LCB(DcMultLn, DC_LCB_ERR_INFO_CRC_ERR_MULTI_LN,
CNTR_SYNTH),
[C_DC_TX_REPLAY] = DC_PERF_CNTR_LCB(DcTxReplay, DC_LCB_ERR_INFO_TX_REPLAY_CNT,
CNTR_SYNTH),
[C_DC_RX_REPLAY] = DC_PERF_CNTR_LCB(DcRxReplay, DC_LCB_ERR_INFO_RX_REPLAY_CNT,
CNTR_SYNTH),
[C_DC_SEQ_CRC_CNT] =
DC_PERF_CNTR_LCB(DcLinkSeqCrc, DC_LCB_ERR_INFO_SEQ_CRC_CNT,
CNTR_SYNTH),
[C_DC_ESC0_ONLY_CNT] =
DC_PERF_CNTR_LCB(DcEsc0, DC_LCB_ERR_INFO_ESCAPE_0_ONLY_CNT,
CNTR_SYNTH),
[C_DC_ESC0_PLUS1_CNT] =
DC_PERF_CNTR_LCB(DcEsc1, DC_LCB_ERR_INFO_ESCAPE_0_PLUS1_CNT,
CNTR_SYNTH),
[C_DC_ESC0_PLUS2_CNT] =
DC_PERF_CNTR_LCB(DcEsc0Plus2, DC_LCB_ERR_INFO_ESCAPE_0_PLUS2_CNT,
CNTR_SYNTH),
[C_DC_REINIT_FROM_PEER_CNT] =
DC_PERF_CNTR_LCB(DcReinitPeer, DC_LCB_ERR_INFO_REINIT_FROM_PEER_CNT,
CNTR_SYNTH),
[C_DC_SBE_CNT] = DC_PERF_CNTR_LCB(DcSbe, DC_LCB_ERR_INFO_SBE_CNT,
CNTR_SYNTH),
[C_DC_MISC_FLG_CNT] =
DC_PERF_CNTR_LCB(DcMiscFlg, DC_LCB_ERR_INFO_MISC_FLG_CNT,
CNTR_SYNTH),
[C_DC_PRF_GOOD_LTP_CNT] =
DC_PERF_CNTR_LCB(DcGoodLTP, DC_LCB_PRF_GOOD_LTP_CNT, CNTR_SYNTH),
[C_DC_PRF_ACCEPTED_LTP_CNT] =
DC_PERF_CNTR_LCB(DcAccLTP, DC_LCB_PRF_ACCEPTED_LTP_CNT,
CNTR_SYNTH),
[C_DC_PRF_RX_FLIT_CNT] =
DC_PERF_CNTR_LCB(DcPrfRxFlit, DC_LCB_PRF_RX_FLIT_CNT, CNTR_SYNTH),
[C_DC_PRF_TX_FLIT_CNT] =
DC_PERF_CNTR_LCB(DcPrfTxFlit, DC_LCB_PRF_TX_FLIT_CNT, CNTR_SYNTH),
[C_DC_PRF_CLK_CNTR] =
DC_PERF_CNTR_LCB(DcPrfClk, DC_LCB_PRF_CLK_CNTR, CNTR_SYNTH),
[C_DC_PG_DBG_FLIT_CRDTS_CNT] =
DC_PERF_CNTR_LCB(DcFltCrdts, DC_LCB_PG_DBG_FLIT_CRDTS_CNT, CNTR_SYNTH),
[C_DC_PG_STS_PAUSE_COMPLETE_CNT] =
DC_PERF_CNTR_LCB(DcPauseComp, DC_LCB_PG_STS_PAUSE_COMPLETE_CNT,
CNTR_SYNTH),
[C_DC_PG_STS_TX_SBE_CNT] =
DC_PERF_CNTR_LCB(DcStsTxSbe, DC_LCB_PG_STS_TX_SBE_CNT, CNTR_SYNTH),
[C_DC_PG_STS_TX_MBE_CNT] =
DC_PERF_CNTR_LCB(DcStsTxMbe, DC_LCB_PG_STS_TX_MBE_CNT,
CNTR_SYNTH),
[C_SW_CPU_INTR] = CNTR_ELEM("Intr", 0, 0, CNTR_NORMAL,
access_sw_cpu_intr),
[C_SW_CPU_RCV_LIM] = CNTR_ELEM("RcvLimit", 0, 0, CNTR_NORMAL,
access_sw_cpu_rcv_limit),
[C_SW_VTX_WAIT] = CNTR_ELEM("vTxWait", 0, 0, CNTR_NORMAL,
access_sw_vtx_wait),
[C_SW_PIO_WAIT] = CNTR_ELEM("PioWait", 0, 0, CNTR_NORMAL,
access_sw_pio_wait),
[C_SW_KMEM_WAIT] = CNTR_ELEM("KmemWait", 0, 0, CNTR_NORMAL,
access_sw_kmem_wait),
[C_SW_SEND_SCHED] = CNTR_ELEM("SendSched", 0, 0, CNTR_NORMAL,
access_sw_send_schedule),
};
static struct cntr_entry port_cntrs[PORT_CNTR_LAST] = {
[C_TX_UNSUP_VL] = TXE32_PORT_CNTR_ELEM(TxUnVLErr, SEND_UNSUP_VL_ERR_CNT,
CNTR_NORMAL),
[C_TX_INVAL_LEN] = TXE32_PORT_CNTR_ELEM(TxInvalLen, SEND_LEN_ERR_CNT,
CNTR_NORMAL),
[C_TX_MM_LEN_ERR] = TXE32_PORT_CNTR_ELEM(TxMMLenErr, SEND_MAX_MIN_LEN_ERR_CNT,
CNTR_NORMAL),
[C_TX_UNDERRUN] = TXE32_PORT_CNTR_ELEM(TxUnderrun, SEND_UNDERRUN_CNT,
CNTR_NORMAL),
[C_TX_FLOW_STALL] = TXE32_PORT_CNTR_ELEM(TxFlowStall, SEND_FLOW_STALL_CNT,
CNTR_NORMAL),
[C_TX_DROPPED] = TXE32_PORT_CNTR_ELEM(TxDropped, SEND_DROPPED_PKT_CNT,
CNTR_NORMAL),
[C_TX_HDR_ERR] = TXE32_PORT_CNTR_ELEM(TxHdrErr, SEND_HEADERS_ERR_CNT,
CNTR_NORMAL),
[C_TX_PKT] = TXE64_PORT_CNTR_ELEM(TxPkt, SEND_DATA_PKT_CNT, CNTR_NORMAL),
[C_TX_WORDS] = TXE64_PORT_CNTR_ELEM(TxWords, SEND_DWORD_CNT, CNTR_NORMAL),
[C_TX_WAIT] = TXE64_PORT_CNTR_ELEM(TxWait, SEND_WAIT_CNT, CNTR_SYNTH),
[C_TX_FLIT_VL] = TXE64_PORT_CNTR_ELEM(TxFlitVL, SEND_DATA_VL0_CNT,
CNTR_SYNTH | CNTR_VL),
[C_TX_PKT_VL] = TXE64_PORT_CNTR_ELEM(TxPktVL, SEND_DATA_PKT_VL0_CNT,
CNTR_SYNTH | CNTR_VL),
[C_TX_WAIT_VL] = TXE64_PORT_CNTR_ELEM(TxWaitVL, SEND_WAIT_VL0_CNT,
CNTR_SYNTH | CNTR_VL),
[C_RX_PKT] = RXE64_PORT_CNTR_ELEM(RxPkt, RCV_DATA_PKT_CNT, CNTR_NORMAL),
[C_RX_WORDS] = RXE64_PORT_CNTR_ELEM(RxWords, RCV_DWORD_CNT, CNTR_NORMAL),
[C_SW_LINK_DOWN] = CNTR_ELEM("SwLinkDown", 0, 0, CNTR_SYNTH | CNTR_32BIT,
access_sw_link_dn_cnt),
[C_SW_LINK_UP] = CNTR_ELEM("SwLinkUp", 0, 0, CNTR_SYNTH | CNTR_32BIT,
access_sw_link_up_cnt),
[C_SW_XMIT_DSCD] = CNTR_ELEM("XmitDscd", 0, 0, CNTR_SYNTH | CNTR_32BIT,
access_sw_xmit_discards),
[C_SW_XMIT_DSCD_VL] = CNTR_ELEM("XmitDscdVl", 0, 0,
CNTR_SYNTH | CNTR_32BIT | CNTR_VL,
access_sw_xmit_discards),
[C_SW_XMIT_CSTR_ERR] = CNTR_ELEM("XmitCstrErr", 0, 0, CNTR_SYNTH,
access_xmit_constraint_errs),
[C_SW_RCV_CSTR_ERR] = CNTR_ELEM("RcvCstrErr", 0, 0, CNTR_SYNTH,
access_rcv_constraint_errs),
[C_SW_IBP_LOOP_PKTS] = SW_IBP_CNTR(LoopPkts, loop_pkts),
[C_SW_IBP_RC_RESENDS] = SW_IBP_CNTR(RcResend, rc_resends),
[C_SW_IBP_RNR_NAKS] = SW_IBP_CNTR(RnrNak, rnr_naks),
[C_SW_IBP_OTHER_NAKS] = SW_IBP_CNTR(OtherNak, other_naks),
[C_SW_IBP_RC_TIMEOUTS] = SW_IBP_CNTR(RcTimeOut, rc_timeouts),
[C_SW_IBP_PKT_DROPS] = SW_IBP_CNTR(PktDrop, pkt_drops),
[C_SW_IBP_DMA_WAIT] = SW_IBP_CNTR(DmaWait, dmawait),
[C_SW_IBP_RC_SEQNAK] = SW_IBP_CNTR(RcSeqNak, rc_seqnak),
[C_SW_IBP_RC_DUPREQ] = SW_IBP_CNTR(RcDupRew, rc_dupreq),
[C_SW_IBP_RDMA_SEQ] = SW_IBP_CNTR(RdmaSeq, rdma_seq),
[C_SW_IBP_UNALIGNED] = SW_IBP_CNTR(Unaligned, unaligned),
[C_SW_IBP_SEQ_NAK] = SW_IBP_CNTR(SeqNak, seq_naks),
[C_SW_CPU_RC_ACKS] = CNTR_ELEM("RcAcks", 0, 0, CNTR_NORMAL,
access_sw_cpu_rc_acks),
[C_SW_CPU_RC_QACKS] = CNTR_ELEM("RcQacks", 0, 0, CNTR_NORMAL,
access_sw_cpu_rc_qacks),
[C_SW_CPU_RC_DELAYED_COMP] = CNTR_ELEM("RcDelayComp", 0, 0, CNTR_NORMAL,
access_sw_cpu_rc_delayed_comp),
[OVR_LBL(0)] = OVR_ELM(0), [OVR_LBL(1)] = OVR_ELM(1),
[OVR_LBL(2)] = OVR_ELM(2), [OVR_LBL(3)] = OVR_ELM(3),
[OVR_LBL(4)] = OVR_ELM(4), [OVR_LBL(5)] = OVR_ELM(5),
[OVR_LBL(6)] = OVR_ELM(6), [OVR_LBL(7)] = OVR_ELM(7),
[OVR_LBL(8)] = OVR_ELM(8), [OVR_LBL(9)] = OVR_ELM(9),
[OVR_LBL(10)] = OVR_ELM(10), [OVR_LBL(11)] = OVR_ELM(11),
[OVR_LBL(12)] = OVR_ELM(12), [OVR_LBL(13)] = OVR_ELM(13),
[OVR_LBL(14)] = OVR_ELM(14), [OVR_LBL(15)] = OVR_ELM(15),
[OVR_LBL(16)] = OVR_ELM(16), [OVR_LBL(17)] = OVR_ELM(17),
[OVR_LBL(18)] = OVR_ELM(18), [OVR_LBL(19)] = OVR_ELM(19),
[OVR_LBL(20)] = OVR_ELM(20), [OVR_LBL(21)] = OVR_ELM(21),
[OVR_LBL(22)] = OVR_ELM(22), [OVR_LBL(23)] = OVR_ELM(23),
[OVR_LBL(24)] = OVR_ELM(24), [OVR_LBL(25)] = OVR_ELM(25),
[OVR_LBL(26)] = OVR_ELM(26), [OVR_LBL(27)] = OVR_ELM(27),
[OVR_LBL(28)] = OVR_ELM(28), [OVR_LBL(29)] = OVR_ELM(29),
[OVR_LBL(30)] = OVR_ELM(30), [OVR_LBL(31)] = OVR_ELM(31),
[OVR_LBL(32)] = OVR_ELM(32), [OVR_LBL(33)] = OVR_ELM(33),
[OVR_LBL(34)] = OVR_ELM(34), [OVR_LBL(35)] = OVR_ELM(35),
[OVR_LBL(36)] = OVR_ELM(36), [OVR_LBL(37)] = OVR_ELM(37),
[OVR_LBL(38)] = OVR_ELM(38), [OVR_LBL(39)] = OVR_ELM(39),
[OVR_LBL(40)] = OVR_ELM(40), [OVR_LBL(41)] = OVR_ELM(41),
[OVR_LBL(42)] = OVR_ELM(42), [OVR_LBL(43)] = OVR_ELM(43),
[OVR_LBL(44)] = OVR_ELM(44), [OVR_LBL(45)] = OVR_ELM(45),
[OVR_LBL(46)] = OVR_ELM(46), [OVR_LBL(47)] = OVR_ELM(47),
[OVR_LBL(48)] = OVR_ELM(48), [OVR_LBL(49)] = OVR_ELM(49),
[OVR_LBL(50)] = OVR_ELM(50), [OVR_LBL(51)] = OVR_ELM(51),
[OVR_LBL(52)] = OVR_ELM(52), [OVR_LBL(53)] = OVR_ELM(53),
[OVR_LBL(54)] = OVR_ELM(54), [OVR_LBL(55)] = OVR_ELM(55),
[OVR_LBL(56)] = OVR_ELM(56), [OVR_LBL(57)] = OVR_ELM(57),
[OVR_LBL(58)] = OVR_ELM(58), [OVR_LBL(59)] = OVR_ELM(59),
[OVR_LBL(60)] = OVR_ELM(60), [OVR_LBL(61)] = OVR_ELM(61),
[OVR_LBL(62)] = OVR_ELM(62), [OVR_LBL(63)] = OVR_ELM(63),
[OVR_LBL(64)] = OVR_ELM(64), [OVR_LBL(65)] = OVR_ELM(65),
[OVR_LBL(66)] = OVR_ELM(66), [OVR_LBL(67)] = OVR_ELM(67),
[OVR_LBL(68)] = OVR_ELM(68), [OVR_LBL(69)] = OVR_ELM(69),
[OVR_LBL(70)] = OVR_ELM(70), [OVR_LBL(71)] = OVR_ELM(71),
[OVR_LBL(72)] = OVR_ELM(72), [OVR_LBL(73)] = OVR_ELM(73),
[OVR_LBL(74)] = OVR_ELM(74), [OVR_LBL(75)] = OVR_ELM(75),
[OVR_LBL(76)] = OVR_ELM(76), [OVR_LBL(77)] = OVR_ELM(77),
[OVR_LBL(78)] = OVR_ELM(78), [OVR_LBL(79)] = OVR_ELM(79),
[OVR_LBL(80)] = OVR_ELM(80), [OVR_LBL(81)] = OVR_ELM(81),
[OVR_LBL(82)] = OVR_ELM(82), [OVR_LBL(83)] = OVR_ELM(83),
[OVR_LBL(84)] = OVR_ELM(84), [OVR_LBL(85)] = OVR_ELM(85),
[OVR_LBL(86)] = OVR_ELM(86), [OVR_LBL(87)] = OVR_ELM(87),
[OVR_LBL(88)] = OVR_ELM(88), [OVR_LBL(89)] = OVR_ELM(89),
[OVR_LBL(90)] = OVR_ELM(90), [OVR_LBL(91)] = OVR_ELM(91),
[OVR_LBL(92)] = OVR_ELM(92), [OVR_LBL(93)] = OVR_ELM(93),
[OVR_LBL(94)] = OVR_ELM(94), [OVR_LBL(95)] = OVR_ELM(95),
[OVR_LBL(96)] = OVR_ELM(96), [OVR_LBL(97)] = OVR_ELM(97),
[OVR_LBL(98)] = OVR_ELM(98), [OVR_LBL(99)] = OVR_ELM(99),
[OVR_LBL(100)] = OVR_ELM(100), [OVR_LBL(101)] = OVR_ELM(101),
[OVR_LBL(102)] = OVR_ELM(102), [OVR_LBL(103)] = OVR_ELM(103),
[OVR_LBL(104)] = OVR_ELM(104), [OVR_LBL(105)] = OVR_ELM(105),
[OVR_LBL(106)] = OVR_ELM(106), [OVR_LBL(107)] = OVR_ELM(107),
[OVR_LBL(108)] = OVR_ELM(108), [OVR_LBL(109)] = OVR_ELM(109),
[OVR_LBL(110)] = OVR_ELM(110), [OVR_LBL(111)] = OVR_ELM(111),
[OVR_LBL(112)] = OVR_ELM(112), [OVR_LBL(113)] = OVR_ELM(113),
[OVR_LBL(114)] = OVR_ELM(114), [OVR_LBL(115)] = OVR_ELM(115),
[OVR_LBL(116)] = OVR_ELM(116), [OVR_LBL(117)] = OVR_ELM(117),
[OVR_LBL(118)] = OVR_ELM(118), [OVR_LBL(119)] = OVR_ELM(119),
[OVR_LBL(120)] = OVR_ELM(120), [OVR_LBL(121)] = OVR_ELM(121),
[OVR_LBL(122)] = OVR_ELM(122), [OVR_LBL(123)] = OVR_ELM(123),
[OVR_LBL(124)] = OVR_ELM(124), [OVR_LBL(125)] = OVR_ELM(125),
[OVR_LBL(126)] = OVR_ELM(126), [OVR_LBL(127)] = OVR_ELM(127),
[OVR_LBL(128)] = OVR_ELM(128), [OVR_LBL(129)] = OVR_ELM(129),
[OVR_LBL(130)] = OVR_ELM(130), [OVR_LBL(131)] = OVR_ELM(131),
[OVR_LBL(132)] = OVR_ELM(132), [OVR_LBL(133)] = OVR_ELM(133),
[OVR_LBL(134)] = OVR_ELM(134), [OVR_LBL(135)] = OVR_ELM(135),
[OVR_LBL(136)] = OVR_ELM(136), [OVR_LBL(137)] = OVR_ELM(137),
[OVR_LBL(138)] = OVR_ELM(138), [OVR_LBL(139)] = OVR_ELM(139),
[OVR_LBL(140)] = OVR_ELM(140), [OVR_LBL(141)] = OVR_ELM(141),
[OVR_LBL(142)] = OVR_ELM(142), [OVR_LBL(143)] = OVR_ELM(143),
[OVR_LBL(144)] = OVR_ELM(144), [OVR_LBL(145)] = OVR_ELM(145),
[OVR_LBL(146)] = OVR_ELM(146), [OVR_LBL(147)] = OVR_ELM(147),
[OVR_LBL(148)] = OVR_ELM(148), [OVR_LBL(149)] = OVR_ELM(149),
[OVR_LBL(150)] = OVR_ELM(150), [OVR_LBL(151)] = OVR_ELM(151),
[OVR_LBL(152)] = OVR_ELM(152), [OVR_LBL(153)] = OVR_ELM(153),
[OVR_LBL(154)] = OVR_ELM(154), [OVR_LBL(155)] = OVR_ELM(155),
[OVR_LBL(156)] = OVR_ELM(156), [OVR_LBL(157)] = OVR_ELM(157),
[OVR_LBL(158)] = OVR_ELM(158), [OVR_LBL(159)] = OVR_ELM(159),
};
/* ======================================================================== */
/* return true if this is chip revision revision a0 */
int is_a0(struct hfi1_devdata *dd)
{
return ((dd->revision >> CCE_REVISION_CHIP_REV_MINOR_SHIFT)
& CCE_REVISION_CHIP_REV_MINOR_MASK) == 0;
}
/* return true if this is chip revision revision a */
int is_ax(struct hfi1_devdata *dd)
{
u8 chip_rev_minor =
dd->revision >> CCE_REVISION_CHIP_REV_MINOR_SHIFT
& CCE_REVISION_CHIP_REV_MINOR_MASK;
return (chip_rev_minor & 0xf0) == 0;
}
/* return true if this is chip revision revision b */
int is_bx(struct hfi1_devdata *dd)
{
u8 chip_rev_minor =
dd->revision >> CCE_REVISION_CHIP_REV_MINOR_SHIFT
& CCE_REVISION_CHIP_REV_MINOR_MASK;
return !!(chip_rev_minor & 0x10);
}
/*
* Append string s to buffer buf. Arguments curp and len are the current
* position and remaining length, respectively.
*
* return 0 on success, 1 on out of room
*/
static int append_str(char *buf, char **curp, int *lenp, const char *s)
{
char *p = *curp;
int len = *lenp;
int result = 0; /* success */
char c;
/* add a comma, if first in the buffer */
if (p != buf) {
if (len == 0) {
result = 1; /* out of room */
goto done;
}
*p++ = ',';
len--;
}
/* copy the string */
while ((c = *s++) != 0) {
if (len == 0) {
result = 1; /* out of room */
goto done;
}
*p++ = c;
len--;
}
done:
/* write return values */
*curp = p;
*lenp = len;
return result;
}
/*
* Using the given flag table, print a comma separated string into
* the buffer. End in '*' if the buffer is too short.
*/
static char *flag_string(char *buf, int buf_len, u64 flags,
struct flag_table *table, int table_size)
{
char extra[32];
char *p = buf;
int len = buf_len;
int no_room = 0;
int i;
/* make sure there is at least 2 so we can form "*" */
if (len < 2)
return "";
len--; /* leave room for a nul */
for (i = 0; i < table_size; i++) {
if (flags & table[i].flag) {
no_room = append_str(buf, &p, &len, table[i].str);
if (no_room)
break;
flags &= ~table[i].flag;
}
}
/* any undocumented bits left? */
if (!no_room && flags) {
snprintf(extra, sizeof(extra), "bits 0x%llx", flags);
no_room = append_str(buf, &p, &len, extra);
}
/* add * if ran out of room */
if (no_room) {
/* may need to back up to add space for a '*' */
if (len == 0)
--p;
*p++ = '*';
}
/* add final nul - space already allocated above */
*p = 0;
return buf;
}
/* first 8 CCE error interrupt source names */
static const char * const cce_misc_names[] = {
"CceErrInt", /* 0 */
"RxeErrInt", /* 1 */
"MiscErrInt", /* 2 */
"Reserved3", /* 3 */
"PioErrInt", /* 4 */
"SDmaErrInt", /* 5 */
"EgressErrInt", /* 6 */
"TxeErrInt" /* 7 */
};
/*
* Return the miscellaneous error interrupt name.
*/
static char *is_misc_err_name(char *buf, size_t bsize, unsigned int source)
{
if (source < ARRAY_SIZE(cce_misc_names))
strncpy(buf, cce_misc_names[source], bsize);
else
snprintf(buf,
bsize,
"Reserved%u",
source + IS_GENERAL_ERR_START);
return buf;
}
/*
* Return the SDMA engine error interrupt name.
*/
static char *is_sdma_eng_err_name(char *buf, size_t bsize, unsigned int source)
{
snprintf(buf, bsize, "SDmaEngErrInt%u", source);
return buf;
}
/*
* Return the send context error interrupt name.
*/
static char *is_sendctxt_err_name(char *buf, size_t bsize, unsigned int source)
{
snprintf(buf, bsize, "SendCtxtErrInt%u", source);
return buf;
}
static const char * const various_names[] = {
"PbcInt",
"GpioAssertInt",
"Qsfp1Int",
"Qsfp2Int",
"TCritInt"
};
/*
* Return the various interrupt name.
*/
static char *is_various_name(char *buf, size_t bsize, unsigned int source)
{
if (source < ARRAY_SIZE(various_names))
strncpy(buf, various_names[source], bsize);
else
snprintf(buf, bsize, "Reserved%u", source+IS_VARIOUS_START);
return buf;
}
/*
* Return the DC interrupt name.
*/
static char *is_dc_name(char *buf, size_t bsize, unsigned int source)
{
static const char * const dc_int_names[] = {
"common",
"lcb",
"8051",
"lbm" /* local block merge */
};
if (source < ARRAY_SIZE(dc_int_names))
snprintf(buf, bsize, "dc_%s_int", dc_int_names[source]);
else
snprintf(buf, bsize, "DCInt%u", source);
return buf;
}
static const char * const sdma_int_names[] = {
"SDmaInt",
"SdmaIdleInt",
"SdmaProgressInt",
};
/*
* Return the SDMA engine interrupt name.
*/
static char *is_sdma_eng_name(char *buf, size_t bsize, unsigned int source)
{
/* what interrupt */
unsigned int what = source / TXE_NUM_SDMA_ENGINES;
/* which engine */
unsigned int which = source % TXE_NUM_SDMA_ENGINES;
if (likely(what < 3))
snprintf(buf, bsize, "%s%u", sdma_int_names[what], which);
else
snprintf(buf, bsize, "Invalid SDMA interrupt %u", source);
return buf;
}
/*
* Return the receive available interrupt name.
*/
static char *is_rcv_avail_name(char *buf, size_t bsize, unsigned int source)
{
snprintf(buf, bsize, "RcvAvailInt%u", source);
return buf;
}
/*
* Return the receive urgent interrupt name.
*/
static char *is_rcv_urgent_name(char *buf, size_t bsize, unsigned int source)
{
snprintf(buf, bsize, "RcvUrgentInt%u", source);
return buf;
}
/*
* Return the send credit interrupt name.
*/
static char *is_send_credit_name(char *buf, size_t bsize, unsigned int source)
{
snprintf(buf, bsize, "SendCreditInt%u", source);
return buf;
}
/*
* Return the reserved interrupt name.
*/
static char *is_reserved_name(char *buf, size_t bsize, unsigned int source)
{
snprintf(buf, bsize, "Reserved%u", source + IS_RESERVED_START);
return buf;
}
static char *cce_err_status_string(char *buf, int buf_len, u64 flags)
{
return flag_string(buf, buf_len, flags,
cce_err_status_flags, ARRAY_SIZE(cce_err_status_flags));
}
static char *rxe_err_status_string(char *buf, int buf_len, u64 flags)
{
return flag_string(buf, buf_len, flags,
rxe_err_status_flags, ARRAY_SIZE(rxe_err_status_flags));
}
static char *misc_err_status_string(char *buf, int buf_len, u64 flags)
{
return flag_string(buf, buf_len, flags, misc_err_status_flags,
ARRAY_SIZE(misc_err_status_flags));
}
static char *pio_err_status_string(char *buf, int buf_len, u64 flags)
{
return flag_string(buf, buf_len, flags,
pio_err_status_flags, ARRAY_SIZE(pio_err_status_flags));
}
static char *sdma_err_status_string(char *buf, int buf_len, u64 flags)
{
return flag_string(buf, buf_len, flags,
sdma_err_status_flags,
ARRAY_SIZE(sdma_err_status_flags));
}
static char *egress_err_status_string(char *buf, int buf_len, u64 flags)
{
return flag_string(buf, buf_len, flags,
egress_err_status_flags, ARRAY_SIZE(egress_err_status_flags));
}
static char *egress_err_info_string(char *buf, int buf_len, u64 flags)
{
return flag_string(buf, buf_len, flags,
egress_err_info_flags, ARRAY_SIZE(egress_err_info_flags));
}
static char *send_err_status_string(char *buf, int buf_len, u64 flags)
{
return flag_string(buf, buf_len, flags,
send_err_status_flags,
ARRAY_SIZE(send_err_status_flags));
}
static void handle_cce_err(struct hfi1_devdata *dd, u32 unused, u64 reg)
{
char buf[96];
/*
* For most these errors, there is nothing that can be done except
* report or record it.
*/
dd_dev_info(dd, "CCE Error: %s\n",
cce_err_status_string(buf, sizeof(buf), reg));
if ((reg & CCE_ERR_STATUS_CCE_CLI2_ASYNC_FIFO_PARITY_ERR_SMASK)
&& is_a0(dd)
&& (dd->icode != ICODE_FUNCTIONAL_SIMULATOR)) {
/* this error requires a manual drop into SPC freeze mode */
/* then a fix up */
start_freeze_handling(dd->pport, FREEZE_SELF);
}
}
/*
* Check counters for receive errors that do not have an interrupt
* associated with them.
*/
#define RCVERR_CHECK_TIME 10
static void update_rcverr_timer(unsigned long opaque)
{
struct hfi1_devdata *dd = (struct hfi1_devdata *)opaque;
struct hfi1_pportdata *ppd = dd->pport;
u32 cur_ovfl_cnt = read_dev_cntr(dd, C_RCV_OVF, CNTR_INVALID_VL);
if (dd->rcv_ovfl_cnt < cur_ovfl_cnt &&
ppd->port_error_action & OPA_PI_MASK_EX_BUFFER_OVERRUN) {
dd_dev_info(dd, "%s: PortErrorAction bounce\n", __func__);
set_link_down_reason(ppd,
OPA_LINKDOWN_REASON_EXCESSIVE_BUFFER_OVERRUN, 0,
OPA_LINKDOWN_REASON_EXCESSIVE_BUFFER_OVERRUN);
queue_work(ppd->hfi1_wq, &ppd->link_bounce_work);
}
dd->rcv_ovfl_cnt = (u32) cur_ovfl_cnt;
mod_timer(&dd->rcverr_timer, jiffies + HZ * RCVERR_CHECK_TIME);
}
static int init_rcverr(struct hfi1_devdata *dd)
{
setup_timer(&dd->rcverr_timer, update_rcverr_timer, (unsigned long)dd);
/* Assume the hardware counter has been reset */
dd->rcv_ovfl_cnt = 0;
return mod_timer(&dd->rcverr_timer, jiffies + HZ * RCVERR_CHECK_TIME);
}
static void free_rcverr(struct hfi1_devdata *dd)
{
if (dd->rcverr_timer.data)
del_timer_sync(&dd->rcverr_timer);
dd->rcverr_timer.data = 0;
}
static void handle_rxe_err(struct hfi1_devdata *dd, u32 unused, u64 reg)
{
char buf[96];
dd_dev_info(dd, "Receive Error: %s\n",
rxe_err_status_string(buf, sizeof(buf), reg));
if (reg & ALL_RXE_FREEZE_ERR) {
int flags = 0;
/*
* Freeze mode recovery is disabled for the errors
* in RXE_FREEZE_ABORT_MASK
*/
if (is_a0(dd) && (reg & RXE_FREEZE_ABORT_MASK))
flags = FREEZE_ABORT;
start_freeze_handling(dd->pport, flags);
}
}
static void handle_misc_err(struct hfi1_devdata *dd, u32 unused, u64 reg)
{
char buf[96];
dd_dev_info(dd, "Misc Error: %s",
misc_err_status_string(buf, sizeof(buf), reg));
}
static void handle_pio_err(struct hfi1_devdata *dd, u32 unused, u64 reg)
{
char buf[96];
dd_dev_info(dd, "PIO Error: %s\n",
pio_err_status_string(buf, sizeof(buf), reg));
if (reg & ALL_PIO_FREEZE_ERR)
start_freeze_handling(dd->pport, 0);
}
static void handle_sdma_err(struct hfi1_devdata *dd, u32 unused, u64 reg)
{
char buf[96];
dd_dev_info(dd, "SDMA Error: %s\n",
sdma_err_status_string(buf, sizeof(buf), reg));
if (reg & ALL_SDMA_FREEZE_ERR)
start_freeze_handling(dd->pport, 0);
}
static void count_port_inactive(struct hfi1_devdata *dd)
{
struct hfi1_pportdata *ppd = dd->pport;
if (ppd->port_xmit_discards < ~(u64)0)
ppd->port_xmit_discards++;
}
/*
* We have had a "disallowed packet" error during egress. Determine the
* integrity check which failed, and update relevant error counter, etc.
*
* Note that the SEND_EGRESS_ERR_INFO register has only a single
* bit of state per integrity check, and so we can miss the reason for an
* egress error if more than one packet fails the same integrity check
* since we cleared the corresponding bit in SEND_EGRESS_ERR_INFO.
*/
static void handle_send_egress_err_info(struct hfi1_devdata *dd)
{
struct hfi1_pportdata *ppd = dd->pport;
u64 src = read_csr(dd, SEND_EGRESS_ERR_SOURCE); /* read first */
u64 info = read_csr(dd, SEND_EGRESS_ERR_INFO);
char buf[96];
/* clear down all observed info as quickly as possible after read */
write_csr(dd, SEND_EGRESS_ERR_INFO, info);
dd_dev_info(dd,
"Egress Error Info: 0x%llx, %s Egress Error Src 0x%llx\n",
info, egress_err_info_string(buf, sizeof(buf), info), src);
/* Eventually add other counters for each bit */
if (info & SEND_EGRESS_ERR_INFO_TOO_LONG_IB_PACKET_ERR_SMASK) {
if (ppd->port_xmit_discards < ~(u64)0)
ppd->port_xmit_discards++;
}
}
/*
* Input value is a bit position within the SEND_EGRESS_ERR_STATUS
* register. Does it represent a 'port inactive' error?
*/
static inline int port_inactive_err(u64 posn)
{
return (posn >= SEES(TX_LINKDOWN) &&
posn <= SEES(TX_INCORRECT_LINK_STATE));
}
/*
* Input value is a bit position within the SEND_EGRESS_ERR_STATUS
* register. Does it represent a 'disallowed packet' error?
*/
static inline int disallowed_pkt_err(u64 posn)
{
return (posn >= SEES(TX_SDMA0_DISALLOWED_PACKET) &&
posn <= SEES(TX_SDMA15_DISALLOWED_PACKET));
}
static void handle_egress_err(struct hfi1_devdata *dd, u32 unused, u64 reg)
{
u64 reg_copy = reg, handled = 0;
char buf[96];
if (reg & ALL_TXE_EGRESS_FREEZE_ERR)
start_freeze_handling(dd->pport, 0);
if (is_a0(dd) && (reg &
SEND_EGRESS_ERR_STATUS_TX_CREDIT_RETURN_VL_ERR_SMASK)
&& (dd->icode != ICODE_FUNCTIONAL_SIMULATOR))
start_freeze_handling(dd->pport, 0);
while (reg_copy) {
int posn = fls64(reg_copy);
/*
* fls64() returns a 1-based offset, but we generally
* want 0-based offsets.
*/
int shift = posn - 1;
if (port_inactive_err(shift)) {
count_port_inactive(dd);
handled |= (1ULL << shift);
} else if (disallowed_pkt_err(shift)) {
handle_send_egress_err_info(dd);
handled |= (1ULL << shift);
}
clear_bit(shift, (unsigned long *)&reg_copy);
}
reg &= ~handled;
if (reg)
dd_dev_info(dd, "Egress Error: %s\n",
egress_err_status_string(buf, sizeof(buf), reg));
}
static void handle_txe_err(struct hfi1_devdata *dd, u32 unused, u64 reg)
{
char buf[96];
dd_dev_info(dd, "Send Error: %s\n",
send_err_status_string(buf, sizeof(buf), reg));
}
/*
* The maximum number of times the error clear down will loop before
* blocking a repeating error. This value is arbitrary.
*/
#define MAX_CLEAR_COUNT 20
/*
* Clear and handle an error register. All error interrupts are funneled
* through here to have a central location to correctly handle single-
* or multi-shot errors.
*
* For non per-context registers, call this routine with a context value
* of 0 so the per-context offset is zero.
*
* If the handler loops too many times, assume that something is wrong
* and can't be fixed, so mask the error bits.
*/
static void interrupt_clear_down(struct hfi1_devdata *dd,
u32 context,
const struct err_reg_info *eri)
{
u64 reg;
u32 count;
/* read in a loop until no more errors are seen */
count = 0;
while (1) {
reg = read_kctxt_csr(dd, context, eri->status);
if (reg == 0)
break;
write_kctxt_csr(dd, context, eri->clear, reg);
if (likely(eri->handler))
eri->handler(dd, context, reg);
count++;
if (count > MAX_CLEAR_COUNT) {
u64 mask;
dd_dev_err(dd, "Repeating %s bits 0x%llx - masking\n",
eri->desc, reg);
/*
* Read-modify-write so any other masked bits
* remain masked.
*/
mask = read_kctxt_csr(dd, context, eri->mask);
mask &= ~reg;
write_kctxt_csr(dd, context, eri->mask, mask);
break;
}
}
}
/*
* CCE block "misc" interrupt. Source is < 16.
*/
static void is_misc_err_int(struct hfi1_devdata *dd, unsigned int source)
{
const struct err_reg_info *eri = &misc_errs[source];
if (eri->handler) {
interrupt_clear_down(dd, 0, eri);
} else {
dd_dev_err(dd, "Unexpected misc interrupt (%u) - reserved\n",
source);
}
}
static char *send_context_err_status_string(char *buf, int buf_len, u64 flags)
{
return flag_string(buf, buf_len, flags,
sc_err_status_flags, ARRAY_SIZE(sc_err_status_flags));
}
/*
* Send context error interrupt. Source (hw_context) is < 160.
*
* All send context errors cause the send context to halt. The normal
* clear-down mechanism cannot be used because we cannot clear the
* error bits until several other long-running items are done first.
* This is OK because with the context halted, nothing else is going
* to happen on it anyway.
*/
static void is_sendctxt_err_int(struct hfi1_devdata *dd,
unsigned int hw_context)
{
struct send_context_info *sci;
struct send_context *sc;
char flags[96];
u64 status;
u32 sw_index;
sw_index = dd->hw_to_sw[hw_context];
if (sw_index >= dd->num_send_contexts) {
dd_dev_err(dd,
"out of range sw index %u for send context %u\n",
sw_index, hw_context);
return;
}
sci = &dd->send_contexts[sw_index];
sc = sci->sc;
if (!sc) {
dd_dev_err(dd, "%s: context %u(%u): no sc?\n", __func__,
sw_index, hw_context);
return;
}
/* tell the software that a halt has begun */
sc_stop(sc, SCF_HALTED);
status = read_kctxt_csr(dd, hw_context, SEND_CTXT_ERR_STATUS);
dd_dev_info(dd, "Send Context %u(%u) Error: %s\n", sw_index, hw_context,
send_context_err_status_string(flags, sizeof(flags), status));
if (status & SEND_CTXT_ERR_STATUS_PIO_DISALLOWED_PACKET_ERR_SMASK)
handle_send_egress_err_info(dd);
/*
* Automatically restart halted kernel contexts out of interrupt
* context. User contexts must ask the driver to restart the context.
*/
if (sc->type != SC_USER)
queue_work(dd->pport->hfi1_wq, &sc->halt_work);
}
static void handle_sdma_eng_err(struct hfi1_devdata *dd,
unsigned int source, u64 status)
{
struct sdma_engine *sde;
sde = &dd->per_sdma[source];
#ifdef CONFIG_SDMA_VERBOSITY
dd_dev_err(sde->dd, "CONFIG SDMA(%u) %s:%d %s()\n", sde->this_idx,
slashstrip(__FILE__), __LINE__, __func__);
dd_dev_err(sde->dd, "CONFIG SDMA(%u) source: %u status 0x%llx\n",
sde->this_idx, source, (unsigned long long)status);
#endif
sdma_engine_error(sde, status);
}
/*
* CCE block SDMA error interrupt. Source is < 16.
*/
static void is_sdma_eng_err_int(struct hfi1_devdata *dd, unsigned int source)
{
#ifdef CONFIG_SDMA_VERBOSITY
struct sdma_engine *sde = &dd->per_sdma[source];
dd_dev_err(dd, "CONFIG SDMA(%u) %s:%d %s()\n", sde->this_idx,
slashstrip(__FILE__), __LINE__, __func__);
dd_dev_err(dd, "CONFIG SDMA(%u) source: %u\n", sde->this_idx,
source);
sdma_dumpstate(sde);
#endif
interrupt_clear_down(dd, source, &sdma_eng_err);
}
/*
* CCE block "various" interrupt. Source is < 8.
*/
static void is_various_int(struct hfi1_devdata *dd, unsigned int source)
{
const struct err_reg_info *eri = &various_err[source];
/*
* TCritInt cannot go through interrupt_clear_down()
* because it is not a second tier interrupt. The handler
* should be called directly.
*/
if (source == TCRIT_INT_SOURCE)
handle_temp_err(dd);
else if (eri->handler)
interrupt_clear_down(dd, 0, eri);
else
dd_dev_info(dd,
"%s: Unimplemented/reserved interrupt %d\n",
__func__, source);
}
static void handle_qsfp_int(struct hfi1_devdata *dd, u32 src_ctx, u64 reg)
{
/* source is always zero */
struct hfi1_pportdata *ppd = dd->pport;
unsigned long flags;
u64 qsfp_int_mgmt = (u64)(QSFP_HFI0_INT_N | QSFP_HFI0_MODPRST_N);
if (reg & QSFP_HFI0_MODPRST_N) {
dd_dev_info(dd, "%s: ModPresent triggered QSFP interrupt\n",
__func__);
if (!qsfp_mod_present(ppd)) {
ppd->driver_link_ready = 0;
/*
* Cable removed, reset all our information about the
* cache and cable capabilities
*/
spin_lock_irqsave(&ppd->qsfp_info.qsfp_lock, flags);
/*
* We don't set cache_refresh_required here as we expect
* an interrupt when a cable is inserted
*/
ppd->qsfp_info.cache_valid = 0;
ppd->qsfp_info.qsfp_interrupt_functional = 0;
spin_unlock_irqrestore(&ppd->qsfp_info.qsfp_lock,
flags);
write_csr(dd,
dd->hfi1_id ?
ASIC_QSFP2_INVERT :
ASIC_QSFP1_INVERT,
qsfp_int_mgmt);
if (ppd->host_link_state == HLS_DN_POLL) {
/*
* The link is still in POLL. This means
* that the normal link down processing
* will not happen. We have to do it here
* before turning the DC off.
*/
queue_work(ppd->hfi1_wq, &ppd->link_down_work);
}
} else {
spin_lock_irqsave(&ppd->qsfp_info.qsfp_lock, flags);
ppd->qsfp_info.cache_valid = 0;
ppd->qsfp_info.cache_refresh_required = 1;
spin_unlock_irqrestore(&ppd->qsfp_info.qsfp_lock,
flags);
qsfp_int_mgmt &= ~(u64)QSFP_HFI0_MODPRST_N;
write_csr(dd,
dd->hfi1_id ?
ASIC_QSFP2_INVERT :
ASIC_QSFP1_INVERT,
qsfp_int_mgmt);
}
}
if (reg & QSFP_HFI0_INT_N) {
dd_dev_info(dd, "%s: IntN triggered QSFP interrupt\n",
__func__);
spin_lock_irqsave(&ppd->qsfp_info.qsfp_lock, flags);
ppd->qsfp_info.check_interrupt_flags = 1;
ppd->qsfp_info.qsfp_interrupt_functional = 1;
spin_unlock_irqrestore(&ppd->qsfp_info.qsfp_lock, flags);
}
/* Schedule the QSFP work only if there is a cable attached. */
if (qsfp_mod_present(ppd))
queue_work(ppd->hfi1_wq, &ppd->qsfp_info.qsfp_work);
}
static int request_host_lcb_access(struct hfi1_devdata *dd)
{
int ret;
ret = do_8051_command(dd, HCMD_MISC,
(u64)HCMD_MISC_REQUEST_LCB_ACCESS << LOAD_DATA_FIELD_ID_SHIFT,
NULL);
if (ret != HCMD_SUCCESS) {
dd_dev_err(dd, "%s: command failed with error %d\n",
__func__, ret);
}
return ret == HCMD_SUCCESS ? 0 : -EBUSY;
}
static int request_8051_lcb_access(struct hfi1_devdata *dd)
{
int ret;
ret = do_8051_command(dd, HCMD_MISC,
(u64)HCMD_MISC_GRANT_LCB_ACCESS << LOAD_DATA_FIELD_ID_SHIFT,
NULL);
if (ret != HCMD_SUCCESS) {
dd_dev_err(dd, "%s: command failed with error %d\n",
__func__, ret);
}
return ret == HCMD_SUCCESS ? 0 : -EBUSY;
}
/*
* Set the LCB selector - allow host access. The DCC selector always
* points to the host.
*/
static inline void set_host_lcb_access(struct hfi1_devdata *dd)
{
write_csr(dd, DC_DC8051_CFG_CSR_ACCESS_SEL,
DC_DC8051_CFG_CSR_ACCESS_SEL_DCC_SMASK
| DC_DC8051_CFG_CSR_ACCESS_SEL_LCB_SMASK);
}
/*
* Clear the LCB selector - allow 8051 access. The DCC selector always
* points to the host.
*/
static inline void set_8051_lcb_access(struct hfi1_devdata *dd)
{
write_csr(dd, DC_DC8051_CFG_CSR_ACCESS_SEL,
DC_DC8051_CFG_CSR_ACCESS_SEL_DCC_SMASK);
}
/*
* Acquire LCB access from the 8051. If the host already has access,
* just increment a counter. Otherwise, inform the 8051 that the
* host is taking access.
*
* Returns:
* 0 on success
* -EBUSY if the 8051 has control and cannot be disturbed
* -errno if unable to acquire access from the 8051
*/
int acquire_lcb_access(struct hfi1_devdata *dd, int sleep_ok)
{
struct hfi1_pportdata *ppd = dd->pport;
int ret = 0;
/*
* Use the host link state lock so the operation of this routine
* { link state check, selector change, count increment } can occur
* as a unit against a link state change. Otherwise there is a
* race between the state change and the count increment.
*/
if (sleep_ok) {
mutex_lock(&ppd->hls_lock);
} else {
while (!mutex_trylock(&ppd->hls_lock))
udelay(1);
}
/* this access is valid only when the link is up */
if ((ppd->host_link_state & HLS_UP) == 0) {
dd_dev_info(dd, "%s: link state %s not up\n",
__func__, link_state_name(ppd->host_link_state));
ret = -EBUSY;
goto done;
}
if (dd->lcb_access_count == 0) {
ret = request_host_lcb_access(dd);
if (ret) {
dd_dev_err(dd,
"%s: unable to acquire LCB access, err %d\n",
__func__, ret);
goto done;
}
set_host_lcb_access(dd);
}
dd->lcb_access_count++;
done:
mutex_unlock(&ppd->hls_lock);
return ret;
}
/*
* Release LCB access by decrementing the use count. If the count is moving
* from 1 to 0, inform 8051 that it has control back.
*
* Returns:
* 0 on success
* -errno if unable to release access to the 8051
*/
int release_lcb_access(struct hfi1_devdata *dd, int sleep_ok)
{
int ret = 0;
/*
* Use the host link state lock because the acquire needed it.
* Here, we only need to keep { selector change, count decrement }
* as a unit.
*/
if (sleep_ok) {
mutex_lock(&dd->pport->hls_lock);
} else {
while (!mutex_trylock(&dd->pport->hls_lock))
udelay(1);
}
if (dd->lcb_access_count == 0) {
dd_dev_err(dd, "%s: LCB access count is zero. Skipping.\n",
__func__);
goto done;
}
if (dd->lcb_access_count == 1) {
set_8051_lcb_access(dd);
ret = request_8051_lcb_access(dd);
if (ret) {
dd_dev_err(dd,
"%s: unable to release LCB access, err %d\n",
__func__, ret);
/* restore host access if the grant didn't work */
set_host_lcb_access(dd);
goto done;
}
}
dd->lcb_access_count--;
done:
mutex_unlock(&dd->pport->hls_lock);
return ret;
}
/*
* Initialize LCB access variables and state. Called during driver load,
* after most of the initialization is finished.
*
* The DC default is LCB access on for the host. The driver defaults to
* leaving access to the 8051. Assign access now - this constrains the call
* to this routine to be after all LCB set-up is done. In particular, after
* hf1_init_dd() -> set_up_interrupts() -> clear_all_interrupts()
*/
static void init_lcb_access(struct hfi1_devdata *dd)
{
dd->lcb_access_count = 0;
}
/*
* Write a response back to a 8051 request.
*/
static void hreq_response(struct hfi1_devdata *dd, u8 return_code, u16 rsp_data)
{
write_csr(dd, DC_DC8051_CFG_EXT_DEV_0,
DC_DC8051_CFG_EXT_DEV_0_COMPLETED_SMASK
| (u64)return_code << DC_DC8051_CFG_EXT_DEV_0_RETURN_CODE_SHIFT
| (u64)rsp_data << DC_DC8051_CFG_EXT_DEV_0_RSP_DATA_SHIFT);
}
/*
* Handle requests from the 8051.
*/
static void handle_8051_request(struct hfi1_devdata *dd)
{
u64 reg;
u16 data;
u8 type;
reg = read_csr(dd, DC_DC8051_CFG_EXT_DEV_1);
if ((reg & DC_DC8051_CFG_EXT_DEV_1_REQ_NEW_SMASK) == 0)
return; /* no request */
/* zero out COMPLETED so the response is seen */
write_csr(dd, DC_DC8051_CFG_EXT_DEV_0, 0);
/* extract request details */
type = (reg >> DC_DC8051_CFG_EXT_DEV_1_REQ_TYPE_SHIFT)
& DC_DC8051_CFG_EXT_DEV_1_REQ_TYPE_MASK;
data = (reg >> DC_DC8051_CFG_EXT_DEV_1_REQ_DATA_SHIFT)
& DC_DC8051_CFG_EXT_DEV_1_REQ_DATA_MASK;
switch (type) {
case HREQ_LOAD_CONFIG:
case HREQ_SAVE_CONFIG:
case HREQ_READ_CONFIG:
case HREQ_SET_TX_EQ_ABS:
case HREQ_SET_TX_EQ_REL:
case HREQ_ENABLE:
dd_dev_info(dd, "8051 request: request 0x%x not supported\n",
type);
hreq_response(dd, HREQ_NOT_SUPPORTED, 0);
break;
case HREQ_CONFIG_DONE:
hreq_response(dd, HREQ_SUCCESS, 0);
break;
case HREQ_INTERFACE_TEST:
hreq_response(dd, HREQ_SUCCESS, data);
break;
default:
dd_dev_err(dd, "8051 request: unknown request 0x%x\n", type);
hreq_response(dd, HREQ_NOT_SUPPORTED, 0);
break;
}
}
static void write_global_credit(struct hfi1_devdata *dd,
u8 vau, u16 total, u16 shared)
{
write_csr(dd, SEND_CM_GLOBAL_CREDIT,
((u64)total
<< SEND_CM_GLOBAL_CREDIT_TOTAL_CREDIT_LIMIT_SHIFT)
| ((u64)shared
<< SEND_CM_GLOBAL_CREDIT_SHARED_LIMIT_SHIFT)
| ((u64)vau << SEND_CM_GLOBAL_CREDIT_AU_SHIFT));
}
/*
* Set up initial VL15 credits of the remote. Assumes the rest of
* the CM credit registers are zero from a previous global or credit reset .
*/
void set_up_vl15(struct hfi1_devdata *dd, u8 vau, u16 vl15buf)
{
/* leave shared count at zero for both global and VL15 */
write_global_credit(dd, vau, vl15buf, 0);
/* We may need some credits for another VL when sending packets
* with the snoop interface. Dividing it down the middle for VL15
* and VL0 should suffice.
*/
if (unlikely(dd->hfi1_snoop.mode_flag == HFI1_PORT_SNOOP_MODE)) {
write_csr(dd, SEND_CM_CREDIT_VL15, (u64)(vl15buf >> 1)
<< SEND_CM_CREDIT_VL15_DEDICATED_LIMIT_VL_SHIFT);
write_csr(dd, SEND_CM_CREDIT_VL, (u64)(vl15buf >> 1)
<< SEND_CM_CREDIT_VL_DEDICATED_LIMIT_VL_SHIFT);
} else {
write_csr(dd, SEND_CM_CREDIT_VL15, (u64)vl15buf
<< SEND_CM_CREDIT_VL15_DEDICATED_LIMIT_VL_SHIFT);
}
}
/*
* Zero all credit details from the previous connection and
* reset the CM manager's internal counters.
*/
void