📄 ipath_iba6120.c
字号:
/* * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved. * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * OpenIB.org BSD license below: * * 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. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. *//* * This file contains all of the code that is specific to the * InfiniPath PCIe chip. */#include <linux/interrupt.h>#include <linux/pci.h>#include <linux/delay.h>#include "ipath_kernel.h"#include "ipath_registers.h"static void ipath_setup_pe_setextled(struct ipath_devdata *, u64, u64);/* * This file contains all the chip-specific register information and * access functions for the QLogic InfiniPath PCI-Express chip. * * This lists the InfiniPath registers, in the actual chip layout. * This structure should never be directly accessed. */struct _infinipath_do_not_use_kernel_regs { unsigned long long Revision; unsigned long long Control; unsigned long long PageAlign; unsigned long long PortCnt; unsigned long long DebugPortSelect; unsigned long long Reserved0; unsigned long long SendRegBase; unsigned long long UserRegBase; unsigned long long CounterRegBase; unsigned long long Scratch; unsigned long long Reserved1; unsigned long long Reserved2; unsigned long long IntBlocked; unsigned long long IntMask; unsigned long long IntStatus; unsigned long long IntClear; unsigned long long ErrorMask; unsigned long long ErrorStatus; unsigned long long ErrorClear; unsigned long long HwErrMask; unsigned long long HwErrStatus; unsigned long long HwErrClear; unsigned long long HwDiagCtrl; unsigned long long MDIO; unsigned long long IBCStatus; unsigned long long IBCCtrl; unsigned long long ExtStatus; unsigned long long ExtCtrl; unsigned long long GPIOOut; unsigned long long GPIOMask; unsigned long long GPIOStatus; unsigned long long GPIOClear; unsigned long long RcvCtrl; unsigned long long RcvBTHQP; unsigned long long RcvHdrSize; unsigned long long RcvHdrCnt; unsigned long long RcvHdrEntSize; unsigned long long RcvTIDBase; unsigned long long RcvTIDCnt; unsigned long long RcvEgrBase; unsigned long long RcvEgrCnt; unsigned long long RcvBufBase; unsigned long long RcvBufSize; unsigned long long RxIntMemBase; unsigned long long RxIntMemSize; unsigned long long RcvPartitionKey; unsigned long long Reserved3; unsigned long long RcvPktLEDCnt; unsigned long long Reserved4[8]; unsigned long long SendCtrl; unsigned long long SendPIOBufBase; unsigned long long SendPIOSize; unsigned long long SendPIOBufCnt; unsigned long long SendPIOAvailAddr; unsigned long long TxIntMemBase; unsigned long long TxIntMemSize; unsigned long long Reserved5; unsigned long long PCIeRBufTestReg0; unsigned long long PCIeRBufTestReg1; unsigned long long Reserved51[6]; unsigned long long SendBufferError; unsigned long long SendBufferErrorCONT1; unsigned long long Reserved6SBE[6]; unsigned long long RcvHdrAddr0; unsigned long long RcvHdrAddr1; unsigned long long RcvHdrAddr2; unsigned long long RcvHdrAddr3; unsigned long long RcvHdrAddr4; unsigned long long Reserved7RHA[11]; unsigned long long RcvHdrTailAddr0; unsigned long long RcvHdrTailAddr1; unsigned long long RcvHdrTailAddr2; unsigned long long RcvHdrTailAddr3; unsigned long long RcvHdrTailAddr4; unsigned long long Reserved8RHTA[11]; unsigned long long Reserved9SW[8]; unsigned long long SerdesConfig0; unsigned long long SerdesConfig1; unsigned long long SerdesStatus; unsigned long long XGXSConfig; unsigned long long IBPLLCfg; unsigned long long Reserved10SW2[3]; unsigned long long PCIEQ0SerdesConfig0; unsigned long long PCIEQ0SerdesConfig1; unsigned long long PCIEQ0SerdesStatus; unsigned long long Reserved11; unsigned long long PCIEQ1SerdesConfig0; unsigned long long PCIEQ1SerdesConfig1; unsigned long long PCIEQ1SerdesStatus; unsigned long long Reserved12;};#define IPATH_KREG_OFFSET(field) (offsetof(struct \ _infinipath_do_not_use_kernel_regs, field) / sizeof(u64))#define IPATH_CREG_OFFSET(field) (offsetof( \ struct infinipath_counters, field) / sizeof(u64))static const struct ipath_kregs ipath_pe_kregs = { .kr_control = IPATH_KREG_OFFSET(Control), .kr_counterregbase = IPATH_KREG_OFFSET(CounterRegBase), .kr_debugportselect = IPATH_KREG_OFFSET(DebugPortSelect), .kr_errorclear = IPATH_KREG_OFFSET(ErrorClear), .kr_errormask = IPATH_KREG_OFFSET(ErrorMask), .kr_errorstatus = IPATH_KREG_OFFSET(ErrorStatus), .kr_extctrl = IPATH_KREG_OFFSET(ExtCtrl), .kr_extstatus = IPATH_KREG_OFFSET(ExtStatus), .kr_gpio_clear = IPATH_KREG_OFFSET(GPIOClear), .kr_gpio_mask = IPATH_KREG_OFFSET(GPIOMask), .kr_gpio_out = IPATH_KREG_OFFSET(GPIOOut), .kr_gpio_status = IPATH_KREG_OFFSET(GPIOStatus), .kr_hwdiagctrl = IPATH_KREG_OFFSET(HwDiagCtrl), .kr_hwerrclear = IPATH_KREG_OFFSET(HwErrClear), .kr_hwerrmask = IPATH_KREG_OFFSET(HwErrMask), .kr_hwerrstatus = IPATH_KREG_OFFSET(HwErrStatus), .kr_ibcctrl = IPATH_KREG_OFFSET(IBCCtrl), .kr_ibcstatus = IPATH_KREG_OFFSET(IBCStatus), .kr_intblocked = IPATH_KREG_OFFSET(IntBlocked), .kr_intclear = IPATH_KREG_OFFSET(IntClear), .kr_intmask = IPATH_KREG_OFFSET(IntMask), .kr_intstatus = IPATH_KREG_OFFSET(IntStatus), .kr_mdio = IPATH_KREG_OFFSET(MDIO), .kr_pagealign = IPATH_KREG_OFFSET(PageAlign), .kr_partitionkey = IPATH_KREG_OFFSET(RcvPartitionKey), .kr_portcnt = IPATH_KREG_OFFSET(PortCnt), .kr_rcvbthqp = IPATH_KREG_OFFSET(RcvBTHQP), .kr_rcvbufbase = IPATH_KREG_OFFSET(RcvBufBase), .kr_rcvbufsize = IPATH_KREG_OFFSET(RcvBufSize), .kr_rcvctrl = IPATH_KREG_OFFSET(RcvCtrl), .kr_rcvegrbase = IPATH_KREG_OFFSET(RcvEgrBase), .kr_rcvegrcnt = IPATH_KREG_OFFSET(RcvEgrCnt), .kr_rcvhdrcnt = IPATH_KREG_OFFSET(RcvHdrCnt), .kr_rcvhdrentsize = IPATH_KREG_OFFSET(RcvHdrEntSize), .kr_rcvhdrsize = IPATH_KREG_OFFSET(RcvHdrSize), .kr_rcvintmembase = IPATH_KREG_OFFSET(RxIntMemBase), .kr_rcvintmemsize = IPATH_KREG_OFFSET(RxIntMemSize), .kr_rcvtidbase = IPATH_KREG_OFFSET(RcvTIDBase), .kr_rcvtidcnt = IPATH_KREG_OFFSET(RcvTIDCnt), .kr_revision = IPATH_KREG_OFFSET(Revision), .kr_scratch = IPATH_KREG_OFFSET(Scratch), .kr_sendbuffererror = IPATH_KREG_OFFSET(SendBufferError), .kr_sendctrl = IPATH_KREG_OFFSET(SendCtrl), .kr_sendpioavailaddr = IPATH_KREG_OFFSET(SendPIOAvailAddr), .kr_sendpiobufbase = IPATH_KREG_OFFSET(SendPIOBufBase), .kr_sendpiobufcnt = IPATH_KREG_OFFSET(SendPIOBufCnt), .kr_sendpiosize = IPATH_KREG_OFFSET(SendPIOSize), .kr_sendregbase = IPATH_KREG_OFFSET(SendRegBase), .kr_txintmembase = IPATH_KREG_OFFSET(TxIntMemBase), .kr_txintmemsize = IPATH_KREG_OFFSET(TxIntMemSize), .kr_userregbase = IPATH_KREG_OFFSET(UserRegBase), .kr_serdesconfig0 = IPATH_KREG_OFFSET(SerdesConfig0), .kr_serdesconfig1 = IPATH_KREG_OFFSET(SerdesConfig1), .kr_serdesstatus = IPATH_KREG_OFFSET(SerdesStatus), .kr_xgxsconfig = IPATH_KREG_OFFSET(XGXSConfig), .kr_ibpllcfg = IPATH_KREG_OFFSET(IBPLLCfg), /* * These should not be used directly via ipath_write_kreg64(), * use them with ipath_write_kreg64_port(), */ .kr_rcvhdraddr = IPATH_KREG_OFFSET(RcvHdrAddr0), .kr_rcvhdrtailaddr = IPATH_KREG_OFFSET(RcvHdrTailAddr0), /* The rcvpktled register controls one of the debug port signals, so * a packet activity LED can be connected to it. */ .kr_rcvpktledcnt = IPATH_KREG_OFFSET(RcvPktLEDCnt), .kr_pcierbuftestreg0 = IPATH_KREG_OFFSET(PCIeRBufTestReg0), .kr_pcierbuftestreg1 = IPATH_KREG_OFFSET(PCIeRBufTestReg1), .kr_pcieq0serdesconfig0 = IPATH_KREG_OFFSET(PCIEQ0SerdesConfig0), .kr_pcieq0serdesconfig1 = IPATH_KREG_OFFSET(PCIEQ0SerdesConfig1), .kr_pcieq0serdesstatus = IPATH_KREG_OFFSET(PCIEQ0SerdesStatus), .kr_pcieq1serdesconfig0 = IPATH_KREG_OFFSET(PCIEQ1SerdesConfig0), .kr_pcieq1serdesconfig1 = IPATH_KREG_OFFSET(PCIEQ1SerdesConfig1), .kr_pcieq1serdesstatus = IPATH_KREG_OFFSET(PCIEQ1SerdesStatus)};static const struct ipath_cregs ipath_pe_cregs = { .cr_badformatcnt = IPATH_CREG_OFFSET(RxBadFormatCnt), .cr_erricrccnt = IPATH_CREG_OFFSET(RxICRCErrCnt), .cr_errlinkcnt = IPATH_CREG_OFFSET(RxLinkProblemCnt), .cr_errlpcrccnt = IPATH_CREG_OFFSET(RxLPCRCErrCnt), .cr_errpkey = IPATH_CREG_OFFSET(RxPKeyMismatchCnt), .cr_errrcvflowctrlcnt = IPATH_CREG_OFFSET(RxFlowCtrlErrCnt), .cr_err_rlencnt = IPATH_CREG_OFFSET(RxLenErrCnt), .cr_errslencnt = IPATH_CREG_OFFSET(TxLenErrCnt), .cr_errtidfull = IPATH_CREG_OFFSET(RxTIDFullErrCnt), .cr_errtidvalid = IPATH_CREG_OFFSET(RxTIDValidErrCnt), .cr_errvcrccnt = IPATH_CREG_OFFSET(RxVCRCErrCnt), .cr_ibstatuschange = IPATH_CREG_OFFSET(IBStatusChangeCnt), .cr_intcnt = IPATH_CREG_OFFSET(LBIntCnt), .cr_invalidrlencnt = IPATH_CREG_OFFSET(RxMaxMinLenErrCnt), .cr_invalidslencnt = IPATH_CREG_OFFSET(TxMaxMinLenErrCnt), .cr_lbflowstallcnt = IPATH_CREG_OFFSET(LBFlowStallCnt), .cr_pktrcvcnt = IPATH_CREG_OFFSET(RxDataPktCnt), .cr_pktrcvflowctrlcnt = IPATH_CREG_OFFSET(RxFlowPktCnt), .cr_pktsendcnt = IPATH_CREG_OFFSET(TxDataPktCnt), .cr_pktsendflowcnt = IPATH_CREG_OFFSET(TxFlowPktCnt), .cr_portovflcnt = IPATH_CREG_OFFSET(RxP0HdrEgrOvflCnt), .cr_rcvebpcnt = IPATH_CREG_OFFSET(RxEBPCnt), .cr_rcvovflcnt = IPATH_CREG_OFFSET(RxBufOvflCnt), .cr_senddropped = IPATH_CREG_OFFSET(TxDroppedPktCnt), .cr_sendstallcnt = IPATH_CREG_OFFSET(TxFlowStallCnt), .cr_sendunderruncnt = IPATH_CREG_OFFSET(TxUnderrunCnt), .cr_wordrcvcnt = IPATH_CREG_OFFSET(RxDwordCnt), .cr_wordsendcnt = IPATH_CREG_OFFSET(TxDwordCnt), .cr_unsupvlcnt = IPATH_CREG_OFFSET(TxUnsupVLErrCnt), .cr_rxdroppktcnt = IPATH_CREG_OFFSET(RxDroppedPktCnt), .cr_iblinkerrrecovcnt = IPATH_CREG_OFFSET(IBLinkErrRecoveryCnt), .cr_iblinkdowncnt = IPATH_CREG_OFFSET(IBLinkDownedCnt), .cr_ibsymbolerrcnt = IPATH_CREG_OFFSET(IBSymbolErrCnt)};/* kr_intstatus, kr_intclear, kr_intmask bits */#define INFINIPATH_I_RCVURG_MASK ((1U<<5)-1)#define INFINIPATH_I_RCVAVAIL_MASK ((1U<<5)-1)/* kr_hwerrclear, kr_hwerrmask, kr_hwerrstatus, bits */#define INFINIPATH_HWE_PCIEMEMPARITYERR_MASK 0x000000000000003fULL#define INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT 0#define INFINIPATH_HWE_PCIEPOISONEDTLP 0x0000000010000000ULL#define INFINIPATH_HWE_PCIECPLTIMEOUT 0x0000000020000000ULL#define INFINIPATH_HWE_PCIEBUSPARITYXTLH 0x0000000040000000ULL#define INFINIPATH_HWE_PCIEBUSPARITYXADM 0x0000000080000000ULL#define INFINIPATH_HWE_PCIEBUSPARITYRADM 0x0000000100000000ULL#define INFINIPATH_HWE_COREPLL_FBSLIP 0x0080000000000000ULL#define INFINIPATH_HWE_COREPLL_RFSLIP 0x0100000000000000ULL#define INFINIPATH_HWE_PCIE1PLLFAILED 0x0400000000000000ULL#define INFINIPATH_HWE_PCIE0PLLFAILED 0x0800000000000000ULL#define INFINIPATH_HWE_SERDESPLLFAILED 0x1000000000000000ULL/* kr_extstatus bits */#define INFINIPATH_EXTS_FREQSEL 0x2#define INFINIPATH_EXTS_SERDESSEL 0x4#define INFINIPATH_EXTS_MEMBIST_ENDTEST 0x0000000000004000#define INFINIPATH_EXTS_MEMBIST_FOUND 0x0000000000008000#define _IPATH_GPIO_SDA_NUM 1#define _IPATH_GPIO_SCL_NUM 0#define IPATH_GPIO_SDA (1ULL << \ (_IPATH_GPIO_SDA_NUM+INFINIPATH_EXTC_GPIOOE_SHIFT))#define IPATH_GPIO_SCL (1ULL << \ (_IPATH_GPIO_SCL_NUM+INFINIPATH_EXTC_GPIOOE_SHIFT))/* 6120 specific hardware errors... */static const struct ipath_hwerror_msgs ipath_6120_hwerror_msgs[] = { INFINIPATH_HWE_MSG(PCIEPOISONEDTLP, "PCIe Poisoned TLP"), INFINIPATH_HWE_MSG(PCIECPLTIMEOUT, "PCIe completion timeout"), /* * In practice, it's unlikely wthat we'll see PCIe PLL, or bus * parity or memory parity error failures, because most likely we * won't be able to talk to the core of the chip. Nonetheless, we * might see them, if they are in parts of the PCIe core that aren't * essential. */ INFINIPATH_HWE_MSG(PCIE1PLLFAILED, "PCIePLL1"), INFINIPATH_HWE_MSG(PCIE0PLLFAILED, "PCIePLL0"), INFINIPATH_HWE_MSG(PCIEBUSPARITYXTLH, "PCIe XTLH core parity"), INFINIPATH_HWE_MSG(PCIEBUSPARITYXADM, "PCIe ADM TX core parity"), INFINIPATH_HWE_MSG(PCIEBUSPARITYRADM, "PCIe ADM RX core parity"), INFINIPATH_HWE_MSG(RXDSYNCMEMPARITYERR, "Rx Dsync"), INFINIPATH_HWE_MSG(SERDESPLLFAILED, "SerDes PLL"),};#define TXE_PIO_PARITY ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF | \ INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC) \ << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT)static int ipath_pe_txe_recover(struct ipath_devdata *);static void ipath_pe_put_tid_2(struct ipath_devdata *, u64 __iomem *, u32, unsigned long);/** * ipath_pe_handle_hwerrors - display hardware errors. * @dd: the infinipath device * @msg: the output buffer * @msgl: the size of the output buffer * * Use same msg buffer as regular errors to avoid excessive stack * use. Most hardware errors are catastrophic, but for right now, * we'll print them and continue. We reuse the same message buffer as * ipath_handle_errors() to avoid excessive stack usage. */static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg, size_t msgl){ ipath_err_t hwerrs; u32 bits, ctrl; int isfatal = 0; char bitsmsg[64]; int log_idx; hwerrs = ipath_read_kreg64(dd, dd->ipath_kregs->kr_hwerrstatus); if (!hwerrs) { /* * better than printing cofusing messages * This seems to be related to clearing the crc error, or * the pll error during init. */ ipath_cdbg(VERBOSE, "Called but no hardware errors set\n"); return; } else if (hwerrs == ~0ULL) { ipath_dev_err(dd, "Read of hardware error status failed " "(all bits set); ignoring\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -