📄 ipath_iba6110.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 * HT chip. */#include <linux/vmalloc.h>#include <linux/pci.h>#include <linux/delay.h>#include <linux/htirq.h>#include "ipath_kernel.h"#include "ipath_registers.h"static void ipath_setup_ht_setextled(struct ipath_devdata *, u64, u64);/* * This lists the InfiniPath registers, in the actual chip layout. * This structure should never be directly accessed. * * The names are in InterCap form because they're taken straight from * the chip specification. Since they're only used in this file, they * don't pollute the rest of the source.*/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 DebugPort; unsigned long long SendRegBase; unsigned long long UserRegBase; unsigned long long CounterRegBase; unsigned long long Scratch; unsigned long long ReservedMisc1; unsigned long long InterruptConfig; 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 ReservedRcv[10]; 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 ReservedSend[9]; unsigned long long SendBufferError; unsigned long long SendBufferErrorCONT1; unsigned long long SendBufferErrorCONT2; unsigned long long SendBufferErrorCONT3; unsigned long long ReservedSBE[4]; unsigned long long RcvHdrAddr0; unsigned long long RcvHdrAddr1; unsigned long long RcvHdrAddr2; unsigned long long RcvHdrAddr3; unsigned long long RcvHdrAddr4; unsigned long long RcvHdrAddr5; unsigned long long RcvHdrAddr6; unsigned long long RcvHdrAddr7; unsigned long long RcvHdrAddr8; unsigned long long ReservedRHA[7]; unsigned long long RcvHdrTailAddr0; unsigned long long RcvHdrTailAddr1; unsigned long long RcvHdrTailAddr2; unsigned long long RcvHdrTailAddr3; unsigned long long RcvHdrTailAddr4; unsigned long long RcvHdrTailAddr5; unsigned long long RcvHdrTailAddr6; unsigned long long RcvHdrTailAddr7; unsigned long long RcvHdrTailAddr8; unsigned long long ReservedRHTA[7]; unsigned long long Sync; /* Software only */ unsigned long long Dump; /* Software only */ unsigned long long SimVer; /* Software only */ unsigned long long ReservedSW[5]; unsigned long long SerdesConfig0; unsigned long long SerdesConfig1; unsigned long long SerdesStatus; unsigned long long XGXSConfig; unsigned long long ReservedSW2[4];};#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_ht_kregs = { .kr_control = IPATH_KREG_OFFSET(Control), .kr_counterregbase = IPATH_KREG_OFFSET(CounterRegBase), .kr_debugport = IPATH_KREG_OFFSET(DebugPort), .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_interruptconfig = IPATH_KREG_OFFSET(InterruptConfig), .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), /* * 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)};static const struct ipath_cregs ipath_ht_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), /* calc from Reg_CounterRegBase + offset */ .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<<9)-1)#define INFINIPATH_I_RCVAVAIL_MASK ((1U<<9)-1)/* kr_hwerrclear, kr_hwerrmask, kr_hwerrstatus, bits */#define INFINIPATH_HWE_HTCMEMPARITYERR_SHIFT 0#define INFINIPATH_HWE_HTCMEMPARITYERR_MASK 0x3FFFFFULL#define INFINIPATH_HWE_HTCLNKABYTE0CRCERR 0x0000000000800000ULL#define INFINIPATH_HWE_HTCLNKABYTE1CRCERR 0x0000000001000000ULL#define INFINIPATH_HWE_HTCLNKBBYTE0CRCERR 0x0000000002000000ULL#define INFINIPATH_HWE_HTCLNKBBYTE1CRCERR 0x0000000004000000ULL#define INFINIPATH_HWE_HTCMISCERR4 0x0000000008000000ULL#define INFINIPATH_HWE_HTCMISCERR5 0x0000000010000000ULL#define INFINIPATH_HWE_HTCMISCERR6 0x0000000020000000ULL#define INFINIPATH_HWE_HTCMISCERR7 0x0000000040000000ULL#define INFINIPATH_HWE_HTCBUSTREQPARITYERR 0x0000000080000000ULL#define INFINIPATH_HWE_HTCBUSTRESPPARITYERR 0x0000000100000000ULL#define INFINIPATH_HWE_HTCBUSIREQPARITYERR 0x0000000200000000ULL#define INFINIPATH_HWE_COREPLL_FBSLIP 0x0080000000000000ULL#define INFINIPATH_HWE_COREPLL_RFSLIP 0x0100000000000000ULL#define INFINIPATH_HWE_HTBPLL_FBSLIP 0x0200000000000000ULL#define INFINIPATH_HWE_HTBPLL_RFSLIP 0x0400000000000000ULL#define INFINIPATH_HWE_HTAPLL_FBSLIP 0x0800000000000000ULL#define INFINIPATH_HWE_HTAPLL_RFSLIP 0x1000000000000000ULL#define INFINIPATH_HWE_SERDESPLLFAILED 0x2000000000000000ULL/* kr_extstatus bits */#define INFINIPATH_EXTS_FREQSEL 0x2#define INFINIPATH_EXTS_SERDESSEL 0x4#define INFINIPATH_EXTS_MEMBIST_ENDTEST 0x0000000000004000#define INFINIPATH_EXTS_MEMBIST_CORRECT 0x0000000000008000/* TID entries (memory), HT-only */#define INFINIPATH_RT_ADDR_MASK 0xFFFFFFFFFFULL /* 40 bits valid */#define INFINIPATH_RT_VALID 0x8000000000000000ULL#define INFINIPATH_RT_ADDR_SHIFT 0#define INFINIPATH_RT_BUFSIZE_MASK 0x3FFFULL#define INFINIPATH_RT_BUFSIZE_SHIFT 48/* * masks and bits that are different in different chips, or present only * in one */static const ipath_err_t infinipath_hwe_htcmemparityerr_mask = INFINIPATH_HWE_HTCMEMPARITYERR_MASK;static const ipath_err_t infinipath_hwe_htcmemparityerr_shift = INFINIPATH_HWE_HTCMEMPARITYERR_SHIFT;static const ipath_err_t infinipath_hwe_htclnkabyte0crcerr = INFINIPATH_HWE_HTCLNKABYTE0CRCERR;static const ipath_err_t infinipath_hwe_htclnkabyte1crcerr = INFINIPATH_HWE_HTCLNKABYTE1CRCERR;static const ipath_err_t infinipath_hwe_htclnkbbyte0crcerr = INFINIPATH_HWE_HTCLNKBBYTE0CRCERR;static const ipath_err_t infinipath_hwe_htclnkbbyte1crcerr = INFINIPATH_HWE_HTCLNKBBYTE1CRCERR;#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))/* keep the code below somewhat more readonable; not used elsewhere */#define _IPATH_HTLINK0_CRCBITS (infinipath_hwe_htclnkabyte0crcerr | \ infinipath_hwe_htclnkabyte1crcerr)#define _IPATH_HTLINK1_CRCBITS (infinipath_hwe_htclnkbbyte0crcerr | \ infinipath_hwe_htclnkbbyte1crcerr)#define _IPATH_HTLANE0_CRCBITS (infinipath_hwe_htclnkabyte0crcerr | \ infinipath_hwe_htclnkbbyte0crcerr)#define _IPATH_HTLANE1_CRCBITS (infinipath_hwe_htclnkabyte1crcerr | \ infinipath_hwe_htclnkbbyte1crcerr)static void hwerr_crcbits(struct ipath_devdata *dd, ipath_err_t hwerrs, char *msg, size_t msgl){ char bitsmsg[64]; ipath_err_t crcbits = hwerrs & (_IPATH_HTLINK0_CRCBITS | _IPATH_HTLINK1_CRCBITS); /* don't check if 8bit HT */ if (dd->ipath_flags & IPATH_8BIT_IN_HT0) crcbits &= ~infinipath_hwe_htclnkabyte1crcerr; /* don't check if 8bit HT */ if (dd->ipath_flags & IPATH_8BIT_IN_HT1) crcbits &= ~infinipath_hwe_htclnkbbyte1crcerr; /* * we'll want to ignore link errors on link that is * not in use, if any. For now, complain about both */ if (crcbits) { u16 ctrl0, ctrl1; snprintf(bitsmsg, sizeof bitsmsg, "[HT%s lane %s CRC (%llx); powercycle to completely clear]", !(crcbits & _IPATH_HTLINK1_CRCBITS) ? "0 (A)" : (!(crcbits & _IPATH_HTLINK0_CRCBITS) ? "1 (B)" : "0+1 (A+B)"), !(crcbits & _IPATH_HTLANE1_CRCBITS) ? "0" : (!(crcbits & _IPATH_HTLANE0_CRCBITS) ? "1" : "0+1"), (unsigned long long) crcbits); strlcat(msg, bitsmsg, msgl); /* * print extra info for debugging. slave/primary * config word 4, 8 (link control 0, 1) */ if (pci_read_config_word(dd->pcidev, dd->ipath_ht_slave_off + 0x4, &ctrl0)) dev_info(&dd->pcidev->dev, "Couldn't read " "linkctrl0 of slave/primary " "config block\n"); else if (!(ctrl0 & 1 << 6)) /* not if EOC bit set */ ipath_dbg("HT linkctrl0 0x%x%s%s\n", ctrl0, ((ctrl0 >> 8) & 7) ? " CRC" : "", ((ctrl0 >> 4) & 1) ? "linkfail" : ""); if (pci_read_config_word(dd->pcidev, dd->ipath_ht_slave_off + 0x8, &ctrl1)) dev_info(&dd->pcidev->dev, "Couldn't read " "linkctrl1 of slave/primary " "config block\n"); else if (!(ctrl1 & 1 << 6)) /* not if EOC bit set */ ipath_dbg("HT linkctrl1 0x%x%s%s\n", ctrl1, ((ctrl1 >> 8) & 7) ? " CRC" : "", ((ctrl1 >> 4) & 1) ? "linkfail" : ""); /* disable until driver reloaded */ dd->ipath_hwerrmask &= ~crcbits; ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, dd->ipath_hwerrmask); ipath_dbg("HT crc errs: %s\n", msg); } else ipath_dbg("ignoring HT crc errors 0x%llx, " "not in use\n", (unsigned long long) (hwerrs & (_IPATH_HTLINK0_CRCBITS | _IPATH_HTLINK1_CRCBITS)));}/* 6110 specific hardware errors... */static const struct ipath_hwerror_msgs ipath_6110_hwerror_msgs[] = { INFINIPATH_HWE_MSG(HTCBUSIREQPARITYERR, "HTC Ireq Parity"), INFINIPATH_HWE_MSG(HTCBUSTREQPARITYERR, "HTC Treq Parity"), INFINIPATH_HWE_MSG(HTCBUSTRESPPARITYERR, "HTC Tresp Parity"), INFINIPATH_HWE_MSG(HTCMISCERR5, "HT core Misc5"), INFINIPATH_HWE_MSG(HTCMISCERR6, "HT core Misc6"), INFINIPATH_HWE_MSG(HTCMISCERR7, "HT core Misc7"),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -