ipath_iba6120.c 57.0 KB
Newer Older
1
/*
J
John Gregor 已提交
2
 * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
 * 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
35
 * InfiniPath PCIe chip.
36 37 38 39 40 41 42 43 44 45
 */

#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/delay.h>


#include "ipath_kernel.h"
#include "ipath_registers.h"

46 47
static void ipath_setup_pe_setextled(struct ipath_devdata *, u64, u64);

48 49
/*
 * This file contains all the chip-specific register information and
50
 * access functions for the QLogic InfiniPath PCI-Express chip.
51
 *
52
 * This lists the InfiniPath registers, in the actual chip layout.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
 * 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;
};

148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
struct _infinipath_do_not_use_counters {
	__u64 LBIntCnt;
	__u64 LBFlowStallCnt;
	__u64 Reserved1;
	__u64 TxUnsupVLErrCnt;
	__u64 TxDataPktCnt;
	__u64 TxFlowPktCnt;
	__u64 TxDwordCnt;
	__u64 TxLenErrCnt;
	__u64 TxMaxMinLenErrCnt;
	__u64 TxUnderrunCnt;
	__u64 TxFlowStallCnt;
	__u64 TxDroppedPktCnt;
	__u64 RxDroppedPktCnt;
	__u64 RxDataPktCnt;
	__u64 RxFlowPktCnt;
	__u64 RxDwordCnt;
	__u64 RxLenErrCnt;
	__u64 RxMaxMinLenErrCnt;
	__u64 RxICRCErrCnt;
	__u64 RxVCRCErrCnt;
	__u64 RxFlowCtrlErrCnt;
	__u64 RxBadFormatCnt;
	__u64 RxLinkProblemCnt;
	__u64 RxEBPCnt;
	__u64 RxLPCRCErrCnt;
	__u64 RxBufOvflCnt;
	__u64 RxTIDFullErrCnt;
	__u64 RxTIDValidErrCnt;
	__u64 RxPKeyMismatchCnt;
	__u64 RxP0HdrEgrOvflCnt;
	__u64 RxP1HdrEgrOvflCnt;
	__u64 RxP2HdrEgrOvflCnt;
	__u64 RxP3HdrEgrOvflCnt;
	__u64 RxP4HdrEgrOvflCnt;
	__u64 RxP5HdrEgrOvflCnt;
	__u64 RxP6HdrEgrOvflCnt;
	__u64 RxP7HdrEgrOvflCnt;
	__u64 RxP8HdrEgrOvflCnt;
	__u64 Reserved6;
	__u64 Reserved7;
	__u64 IBStatusChangeCnt;
	__u64 IBLinkErrRecoveryCnt;
	__u64 IBLinkDownedCnt;
	__u64 IBSymbolErrCnt;
};

#define IPATH_KREG_OFFSET(field) (offsetof( \
	struct _infinipath_do_not_use_kernel_regs, field) / sizeof(u64))
197
#define IPATH_CREG_OFFSET(field) (offsetof( \
198
	struct _infinipath_do_not_use_counters, field) / sizeof(u64))
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258

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),

	/*
259 260
	 * These should not be used directly via ipath_write_kreg64(),
	 * use them with ipath_write_kreg64_port(),
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
	 */
	.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 */
315 316
#define INFINIPATH_I_RCVURG_MASK ((1U<<5)-1)
#define INFINIPATH_I_RCVAVAIL_MASK ((1U<<5)-1)
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331

/* 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

332 333 334
#define IBA6120_IBCS_LINKTRAININGSTATE_MASK 0xf
#define IBA6120_IBCS_LINKSTATE_SHIFT 4

335 336 337 338 339 340 341 342 343 344 345 346 347 348
/* 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))

349 350 351
#define INFINIPATH_R_INTRAVAIL_SHIFT 16
#define INFINIPATH_R_TAILUPD_SHIFT 31

352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
/* 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"),
};

372 373 374 375
#define TXE_PIO_PARITY ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF | \
		        INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC) \
		        << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT)

376 377
static void ipath_pe_put_tid_2(struct ipath_devdata *, u64 __iomem *,
			       u32, unsigned long);
378

379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
/*
 * On platforms using this chip, and not having ordered WC stores, we
 * can get TXE parity errors due to speculative reads to the PIO buffers,
 * and this, due to a chip bug can result in (many) false parity error
 * reports.  So it's a debug print on those, and an info print on systems
 * where the speculative reads don't occur.
 */
static void ipath_pe_txe_recover(struct ipath_devdata *dd)
{
	if (ipath_unordered_wc())
		ipath_dbg("Recovering from TXE PIO parity error\n");
	else {
		++ipath_stats.sps_txeparity;
		dev_info(&dd->pcidev->dev,
			"Recovering from TXE PIO parity error\n");
	}
}


398 399 400 401 402 403 404 405 406 407 408
/**
 * 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.
 */
R
Roland Dreier 已提交
409 410
static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
				     size_t msgl)
411 412 413 414 415
{
	ipath_err_t hwerrs;
	u32 bits, ctrl;
	int isfatal = 0;
	char bitsmsg[64];
416
	int log_idx;
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443

	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");
		return;
	}
	ipath_stats.sps_hwerrs++;

	/* Always clear the error status register, except MEMBISTFAIL,
	 * regardless of whether we continue or stop using the chip.
	 * We want that set so we know it failed, even across driver reload.
	 * We'll still ignore it in the hwerrmask.  We do this partly for
	 * diagnostics, but also for support */
	ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear,
			 hwerrs&~INFINIPATH_HWE_MEMBISTFAILED);

	hwerrs &= dd->ipath_hwerrmask;

444 445 446 447 448
	/* We log some errors to EEPROM, check if we have any of those. */
	for (log_idx = 0; log_idx < IPATH_EEP_LOG_CNT; ++log_idx)
		if (hwerrs & dd->ipath_eep_st_masks[log_idx].hwerrs_to_log)
			ipath_inc_eeprom_err(dd, log_idx, 1);

449 450 451 452
	/*
	 * make sure we get this much out, unless told to be quiet,
	 * or it's occurred within the last 5 seconds
	 */
453 454 455 456
	if ((hwerrs & ~(dd->ipath_lasthwerror |
			((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF |
			  INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC)
			 << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT))) ||
457 458 459 460 461
	    (ipath_debug & __IPATH_VERBDBG))
		dev_info(&dd->pcidev->dev, "Hardware error: hwerr=0x%llx "
			 "(cleared)\n", (unsigned long long) hwerrs);
	dd->ipath_lasthwerror |= hwerrs;

462
	if (hwerrs & ~dd->ipath_hwe_bitsextant)
463 464
		ipath_dev_err(dd, "hwerror interrupt with unknown errors "
			      "%llx set\n", (unsigned long long)
465
			      (hwerrs & ~dd->ipath_hwe_bitsextant));
466 467 468

	ctrl = ipath_read_kreg32(dd, dd->ipath_kregs->kr_control);
	if (ctrl & INFINIPATH_C_FREEZEMODE) {
469 470 471 472 473 474 475 476
		/*
		 * parity errors in send memory are recoverable,
		 * just cancel the send (if indicated in * sendbuffererror),
		 * count the occurrence, unfreeze (if no other handled
		 * hardware error bits are set), and continue. They can
		 * occur if a processor speculative read is done to the PIO
		 * buffer while we are sending a packet, for example.
		 */
477 478
		if (hwerrs & TXE_PIO_PARITY) {
			ipath_pe_txe_recover(dd);
479
			hwerrs &= ~TXE_PIO_PARITY;
480 481
		}
		if (!hwerrs) {
482 483 484 485 486
			static u32 freeze_cnt;

			freeze_cnt++;
			ipath_dbg("Clearing freezemode on ignored or recovered "
				  "hardware error (%u)\n", freeze_cnt);
487
			ipath_clear_freeze(dd);
488 489 490 491 492 493
		}
	}

	*msg = '\0';

	if (hwerrs & INFINIPATH_HWE_MEMBISTFAILED) {
494
		strlcat(msg, "[Memory BIST test failed, InfiniPath hardware unusable]",
495 496 497 498 499 500 501
			msgl);
		/* ignore from now on, so disable until driver reloaded */
		*dd->ipath_statusp |= IPATH_STATUS_HWERROR;
		dd->ipath_hwerrmask &= ~INFINIPATH_HWE_MEMBISTFAILED;
		ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask,
				 dd->ipath_hwerrmask);
	}
502 503 504 505 506 507 508

	ipath_format_hwerrors(hwerrs,
			      ipath_6120_hwerror_msgs,
			      sizeof(ipath_6120_hwerror_msgs)/
			      sizeof(ipath_6120_hwerror_msgs[0]),
			      msg, msgl);

509 510 511 512 513 514 515 516 517 518 519 520 521 522 523
	if (hwerrs & (INFINIPATH_HWE_PCIEMEMPARITYERR_MASK
		      << INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT)) {
		bits = (u32) ((hwerrs >>
			       INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT) &
			      INFINIPATH_HWE_PCIEMEMPARITYERR_MASK);
		snprintf(bitsmsg, sizeof bitsmsg,
			 "[PCIe Mem Parity Errs %x] ", bits);
		strlcat(msg, bitsmsg, msgl);
	}

#define _IPATH_PLL_FAIL (INFINIPATH_HWE_COREPLL_FBSLIP |	\
			 INFINIPATH_HWE_COREPLL_RFSLIP )

	if (hwerrs & _IPATH_PLL_FAIL) {
		snprintf(bitsmsg, sizeof bitsmsg,
524
			 "[PLL failed (%llx), InfiniPath hardware unusable]",
525 526 527 528 529 530 531 532 533 534
			 (unsigned long long) hwerrs & _IPATH_PLL_FAIL);
		strlcat(msg, bitsmsg, msgl);
		/* ignore from now on, so disable until driver reloaded */
		dd->ipath_hwerrmask &= ~(hwerrs & _IPATH_PLL_FAIL);
		ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask,
				 dd->ipath_hwerrmask);
	}

	if (hwerrs & INFINIPATH_HWE_SERDESPLLFAILED) {
		/*
D
Dave Olson 已提交
535
		 * If it occurs, it is left masked since the external
536 537 538 539 540 541 542
		 * interface is unused
		 */
		dd->ipath_hwerrmask &= ~INFINIPATH_HWE_SERDESPLLFAILED;
		ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask,
				 dd->ipath_hwerrmask);
	}

543 544
	if (*msg)
		ipath_dev_err(dd, "%s hardware error\n", msg);
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574
	if (isfatal && !ipath_diag_inuse && dd->ipath_freezemsg) {
		/*
		 * for /sys status file ; if no trailing } is copied, we'll
		 * know it was truncated.
		 */
		snprintf(dd->ipath_freezemsg, dd->ipath_freezelen,
			 "{%s}", msg);
	}
}

/**
 * ipath_pe_boardname - fill in the board name
 * @dd: the infinipath device
 * @name: the output buffer
 * @namelen: the size of the output buffer
 *
 * info is based on the board revision register
 */
static int ipath_pe_boardname(struct ipath_devdata *dd, char *name,
			      size_t namelen)
{
	char *n = NULL;
	u8 boardrev = dd->ipath_boardrev;
	int ret;

	switch (boardrev) {
	case 0:
		n = "InfiniPath_Emulation";
		break;
	case 1:
575
		n = "InfiniPath_QLE7140-Bringup";
576 577
		break;
	case 2:
578
		n = "InfiniPath_QLE7140";
579 580
		break;
	case 3:
581
		n = "InfiniPath_QMI7140";
582 583
		break;
	case 4:
584 585 586 587
		n = "InfiniPath_QEM7140";
		break;
	case 5:
		n = "InfiniPath_QMH7140";
588
		break;
589 590 591
	case 6:
		n = "InfiniPath_QLE7142";
		break;
592 593 594 595
	default:
		ipath_dev_err(dd,
			      "Don't yet know about board with ID %u\n",
			      boardrev);
596
		snprintf(name, namelen, "Unknown_InfiniPath_PCIe_%u",
597 598 599 600 601 602
			 boardrev);
		break;
	}
	if (n)
		snprintf(name, namelen, "%s", n);

603
	if (dd->ipath_majrev != 4 || !dd->ipath_minrev || dd->ipath_minrev>2) {
604
		ipath_dev_err(dd, "Unsupported InfiniPath hardware revision %u.%u!\n",
605 606
			      dd->ipath_majrev, dd->ipath_minrev);
		ret = 1;
607
	} else {
608
		ret = 0;
609 610 611
		if (dd->ipath_minrev >= 2)
			dd->ipath_f_put_tid = ipath_pe_put_tid_2;
	}
612

613 614 615 616 617 618 619 620

	/*
	 * set here, not in ipath_init_*_funcs because we have to do
	 * it after we can read chip registers.
	 */
	dd->ipath_ureg_align =
		ipath_read_kreg32(dd, dd->ipath_kregs->kr_pagealign);

621 622 623 624 625 626 627 628 629 630 631 632 633
	return ret;
}

/**
 * ipath_pe_init_hwerrors - enable hardware errors
 * @dd: the infinipath device
 *
 * now that we have finished initializing everything that might reasonably
 * cause a hardware error, and cleared those errors bits as they occur,
 * we can enable hardware errors in the mask (potentially enabling
 * freeze mode), and enable hardware errors as errors (along with
 * everything else) in errormask
 */
R
Roland Dreier 已提交
634
static void ipath_pe_init_hwerrors(struct ipath_devdata *dd)
635 636 637 638 639 640 641 642
{
	ipath_err_t val;
	u64 extsval;

	extsval = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extstatus);

	if (!(extsval & INFINIPATH_EXTS_MEMBIST_ENDTEST))
		ipath_dev_err(dd, "MemBIST did not complete!\n");
643 644
	if (extsval & INFINIPATH_EXTS_MEMBIST_FOUND)
		ipath_dbg("MemBIST corrected\n");
645 646 647 648 649 650

	val = ~0ULL;	/* barring bugs, all hwerrors become interrupts, */

	if (!dd->ipath_boardrev)	// no PLL for Emulator
		val &= ~INFINIPATH_HWE_SERDESPLLFAILED;

651 652 653 654 655 656
	if (dd->ipath_minrev < 2) {
		/* workaround bug 9460 in internal interface bus parity
		 * checking. Fixed (HW bug 9490) in Rev2.
		 */
		val &= ~INFINIPATH_HWE_PCIEBUSPARITYRADM;
	}
657 658 659 660 661 662 663
	dd->ipath_hwerrmask = val;
}

/**
 * ipath_pe_bringup_serdes - bring up the serdes
 * @dd: the infinipath device
 */
R
Roland Dreier 已提交
664
static int ipath_pe_bringup_serdes(struct ipath_devdata *dd)
665
{
666
	u64 val, config1, prev_val;
667
	int ret = 0;
668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696

	ipath_dbg("Trying to bringup serdes\n");

	if (ipath_read_kreg64(dd, dd->ipath_kregs->kr_hwerrstatus) &
	    INFINIPATH_HWE_SERDESPLLFAILED) {
		ipath_dbg("At start, serdes PLL failed bit set "
			  "in hwerrstatus, clearing and continuing\n");
		ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear,
				 INFINIPATH_HWE_SERDESPLLFAILED);
	}

	val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0);
	config1 = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig1);

	ipath_cdbg(VERBOSE, "SerDes status config0=%llx config1=%llx, "
		   "xgxsconfig %llx\n", (unsigned long long) val,
		   (unsigned long long) config1, (unsigned long long)
		   ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig));

	/*
	 * Force reset on, also set rxdetect enable.  Must do before reading
	 * serdesstatus at least for simulation, or some of the bits in
	 * serdes status will come back as undefined and cause simulation
	 * failures
	 */
	val |= INFINIPATH_SERDC0_RESET_PLL | INFINIPATH_SERDC0_RXDETECT_EN
		| INFINIPATH_SERDC0_L1PWR_DN;
	ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val);
	/* be sure chip saw it */
697
	ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
698 699 700 701 702 703 704 705 706 707 708 709 710
	udelay(5);		/* need pll reset set at least for a bit */
	/*
	 * after PLL is reset, set the per-lane Resets and TxIdle and
	 * clear the PLL reset and rxdetect (to get falling edge).
	 * Leave L1PWR bits set (permanently)
	 */
	val &= ~(INFINIPATH_SERDC0_RXDETECT_EN | INFINIPATH_SERDC0_RESET_PLL
		 | INFINIPATH_SERDC0_L1PWR_DN);
	val |= INFINIPATH_SERDC0_RESET_MASK | INFINIPATH_SERDC0_TXIDLE;
	ipath_cdbg(VERBOSE, "Clearing pll reset and setting lane resets "
		   "and txidle (%llx)\n", (unsigned long long) val);
	ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val);
	/* be sure chip saw it */
711
	ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
712 713 714 715 716 717 718 719 720 721 722 723
	/* need PLL reset clear for at least 11 usec before lane
	 * resets cleared; give it a few more to be sure */
	udelay(15);
	val &= ~(INFINIPATH_SERDC0_RESET_MASK | INFINIPATH_SERDC0_TXIDLE);

	ipath_cdbg(VERBOSE, "Clearing lane resets and txidle "
		   "(writing %llx)\n", (unsigned long long) val);
	ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val);
	/* be sure chip saw it */
	val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);

	val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig);
724
	prev_val = val;
725
	if (val & INFINIPATH_XGXS_RESET)
726
		val &= ~INFINIPATH_XGXS_RESET;
727 728 729 730 731 732 733 734
	if (((val >> INFINIPATH_XGXS_RX_POL_SHIFT) &
	     INFINIPATH_XGXS_RX_POL_MASK) != dd->ipath_rx_pol_inv ) {
		/* need to compensate for Tx inversion in partner */
		val &= ~(INFINIPATH_XGXS_RX_POL_MASK <<
		         INFINIPATH_XGXS_RX_POL_SHIFT);
		val |= dd->ipath_rx_pol_inv <<
			INFINIPATH_XGXS_RX_POL_SHIFT;
	}
735
	if (val != prev_val)
736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763
		ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val);

	val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0);

	/* clear current and de-emphasis bits */
	config1 &= ~0x0ffffffff00ULL;
	/* set current to 20ma */
	config1 |= 0x00000000000ULL;
	/* set de-emphasis to -5.68dB */
	config1 |= 0x0cccc000000ULL;
	ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig1, config1);

	ipath_cdbg(VERBOSE, "done: SerDes status config0=%llx "
		   "config1=%llx, sstatus=%llx xgxs=%llx\n",
		   (unsigned long long) val, (unsigned long long) config1,
		   (unsigned long long)
		   ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesstatus),
		   (unsigned long long)
		   ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig));

	return ret;
}

/**
 * ipath_pe_quiet_serdes - set serdes to txidle
 * @dd: the infinipath device
 * Called when driver is being unloaded
 */
R
Roland Dreier 已提交
764
static void ipath_pe_quiet_serdes(struct ipath_devdata *dd)
765 766 767 768 769 770 771 772 773 774 775
{
	u64 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0);

	val |= INFINIPATH_SERDC0_TXIDLE;
	ipath_dbg("Setting TxIdleEn on serdes (config0 = %llx)\n",
		  (unsigned long long) val);
	ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val);
}

static int ipath_pe_intconfig(struct ipath_devdata *dd)
{
776 777 778 779 780 781 782 783 784 785 786 787
	u32 chiprev;

	/*
	 * If the chip supports added error indication via GPIO pins,
	 * enable interrupts on those bits so the interrupt routine
	 * can count the events. Also set flag so interrupt routine
	 * can know they are expected.
	 */
	chiprev = dd->ipath_revision >> INFINIPATH_R_CHIPREVMINOR_SHIFT;
	if ((chiprev & INFINIPATH_R_CHIPREVMINOR_MASK) > 1) {
		/* Rev2+ reports extra errors via internal GPIO pins */
		dd->ipath_flags |= IPATH_GPIO_ERRINTRS;
788 789 790
		dd->ipath_gpio_mask |= IPATH_GPIO_ERRINTR_MASK;
		ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask,
				 dd->ipath_gpio_mask);
791
	}
792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819
	return 0;
}

/**
 * ipath_setup_pe_setextled - set the state of the two external LEDs
 * @dd: the infinipath device
 * @lst: the L state
 * @ltst: the LT state

 * These LEDs indicate the physical and logical state of IB link.
 * For this chip (at least with recommended board pinouts), LED1
 * is Yellow (logical state) and LED2 is Green (physical state),
 *
 * Note:  We try to match the Mellanox HCA LED behavior as best
 * we can.  Green indicates physical link state is OK (something is
 * plugged in, and we can train).
 * Amber indicates the link is logically up (ACTIVE).
 * Mellanox further blinks the amber LED to indicate data packet
 * activity, but we have no hardware support for that, so it would
 * require waking up every 10-20 msecs and checking the counters
 * on the chip, and then turning the LED off if appropriate.  That's
 * visible overhead, so not something we will do.
 *
 */
static void ipath_setup_pe_setextled(struct ipath_devdata *dd, u64 lst,
				     u64 ltst)
{
	u64 extctl;
820
	unsigned long flags = 0;
821 822 823 824 825 826

	/* the diags use the LED to indicate diag info, so we leave
	 * the external LED alone when the diags are running */
	if (ipath_diag_inuse)
		return;

827 828 829 830 831 832 833 834 835 836
	/* Allow override of LED display for, e.g. Locating system in rack */
	if (dd->ipath_led_override) {
		ltst = (dd->ipath_led_override & IPATH_LED_PHYS)
			? INFINIPATH_IBCS_LT_STATE_LINKUP
			: INFINIPATH_IBCS_LT_STATE_DISABLED;
		lst = (dd->ipath_led_override & IPATH_LED_LOG)
			? INFINIPATH_IBCS_L_STATE_ACTIVE
			: INFINIPATH_IBCS_L_STATE_DOWN;
	}

837
	spin_lock_irqsave(&dd->ipath_gpio_lock, flags);
838 839 840 841 842 843 844 845 846
	extctl = dd->ipath_extctrl & ~(INFINIPATH_EXTC_LED1PRIPORT_ON |
				       INFINIPATH_EXTC_LED2PRIPORT_ON);

	if (ltst & INFINIPATH_IBCS_LT_STATE_LINKUP)
		extctl |= INFINIPATH_EXTC_LED2PRIPORT_ON;
	if (lst == INFINIPATH_IBCS_L_STATE_ACTIVE)
		extctl |= INFINIPATH_EXTC_LED1PRIPORT_ON;
	dd->ipath_extctrl = extctl;
	ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, extctl);
847
	spin_unlock_irqrestore(&dd->ipath_gpio_lock, flags);
848 849 850 851 852 853 854 855
}

/**
 * ipath_setup_pe_cleanup - clean up any per-chip chip-specific stuff
 * @dd: the infinipath device
 *
 * This is called during driver unload.
 * We do the pci_disable_msi here, not in generic code, because it
856 857
 * isn't used for the HT chips. If we do end up needing pci_enable_msi
 * at some point in the future for HT, we'll move the call back
858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876
 * into the main init_one code.
 */
static void ipath_setup_pe_cleanup(struct ipath_devdata *dd)
{
	dd->ipath_msi_lo = 0;	/* just in case unload fails */
	pci_disable_msi(dd->pcidev);
}

/**
 * ipath_setup_pe_config - setup PCIe config related stuff
 * @dd: the infinipath device
 * @pdev: the PCI device
 *
 * The pci_enable_msi() call will fail on systems with MSI quirks
 * such as those with AMD8131, even if the device of interest is not
 * attached to that device, (in the 2.6.13 - 2.6.15 kernels, at least, fixed
 * late in 2.6.16).
 * All that can be done is to edit the kernel source to remove the quirk
 * check until that is fixed.
877 878 879 880
 * We do not need to call enable_msi() for our HyperTransport chip,
 * even though it uses MSI, and we want to avoid the quirk warning, so
 * So we call enable_msi only for PCIe.  If we do end up needing
 * pci_enable_msi at some point in the future for HT, we'll move the
881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896
 * call back into the main init_one code.
 * We save the msi lo and hi values, so we can restore them after
 * chip reset (the kernel PCI infrastructure doesn't yet handle that
 * correctly).
 */
static int ipath_setup_pe_config(struct ipath_devdata *dd,
				 struct pci_dev *pdev)
{
	int pos, ret;

	dd->ipath_msi_lo = 0;	/* used as a flag during reset processing */
	ret = pci_enable_msi(dd->pcidev);
	if (ret)
		ipath_dev_err(dd, "pci_enable_msi failed: %d, "
			      "interrupts may not work\n", ret);
	/* continue even if it fails, we may still be OK... */
897
	dd->ipath_irq = pdev->irq;
898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935

	if ((pos = pci_find_capability(dd->pcidev, PCI_CAP_ID_MSI))) {
		u16 control;
		pci_read_config_dword(dd->pcidev, pos + PCI_MSI_ADDRESS_LO,
				      &dd->ipath_msi_lo);
		pci_read_config_dword(dd->pcidev, pos + PCI_MSI_ADDRESS_HI,
				      &dd->ipath_msi_hi);
		pci_read_config_word(dd->pcidev, pos + PCI_MSI_FLAGS,
				     &control);
		/* now save the data (vector) info */
		pci_read_config_word(dd->pcidev,
				     pos + ((control & PCI_MSI_FLAGS_64BIT)
					    ? 12 : 8),
				     &dd->ipath_msi_data);
		ipath_cdbg(VERBOSE, "Read msi data 0x%x from config offset "
			   "0x%x, control=0x%x\n", dd->ipath_msi_data,
			   pos + ((control & PCI_MSI_FLAGS_64BIT) ? 12 : 8),
			   control);
		/* we save the cachelinesize also, although it doesn't
		 * really matter */
		pci_read_config_byte(dd->pcidev, PCI_CACHE_LINE_SIZE,
				     &dd->ipath_pci_cacheline);
	} else
		ipath_dev_err(dd, "Can't find MSI capability, "
			      "can't save MSI settings for reset\n");
	if ((pos = pci_find_capability(dd->pcidev, PCI_CAP_ID_EXP))) {
		u16 linkstat;
		pci_read_config_word(dd->pcidev, pos + PCI_EXP_LNKSTA,
				     &linkstat);
		linkstat >>= 4;
		linkstat &= 0x1f;
		if (linkstat != 8)
			ipath_dev_err(dd, "PCIe width %u, "
				      "performance reduced\n", linkstat);
	}
	else
		ipath_dev_err(dd, "Can't find PCI Express "
			      "capability!\n");
936 937 938 939 940 941 942 943

	dd->ipath_link_width_supported = IB_WIDTH_1X | IB_WIDTH_4X;
	dd->ipath_link_speed_supported = IPATH_IB_SDR;
	dd->ipath_link_width_enabled = IB_WIDTH_4X;
	dd->ipath_link_speed_enabled = dd->ipath_link_speed_supported;
	/* these can't change for this chip, so set once */
	dd->ipath_link_width_active = dd->ipath_link_width_enabled;
	dd->ipath_link_speed_active = dd->ipath_link_speed_enabled;
944 945 946
	return 0;
}

947
static void ipath_init_pe_variables(struct ipath_devdata *dd)
948
{
949 950 951 952 953 954 955
	/*
	 * setup the register offsets, since they are different for each
	 * chip
	 */
	dd->ipath_kregs = &ipath_pe_kregs;
	dd->ipath_cregs = &ipath_pe_cregs;

956 957 958 959
	/*
	 * bits for selecting i2c direction and values,
	 * used for I2C serial flash
	 */
960 961 962 963
	dd->ipath_gpio_sda_num = _IPATH_GPIO_SDA_NUM;
	dd->ipath_gpio_scl_num = _IPATH_GPIO_SCL_NUM;
	dd->ipath_gpio_sda = IPATH_GPIO_SDA;
	dd->ipath_gpio_scl = IPATH_GPIO_SCL;
964

965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995
	/*
	 * Fill in data for field-values that change in newer chips.
	 * We dynamically specify only the mask for LINKTRAININGSTATE
	 * and only the shift for LINKSTATE, as they are the only ones
	 * that change.  Also precalculate the 3 link states of interest
	 * and the combined mask.
	 */
	dd->ibcs_ls_shift = IBA6120_IBCS_LINKSTATE_SHIFT;
	dd->ibcs_lts_mask = IBA6120_IBCS_LINKTRAININGSTATE_MASK;
	dd->ibcs_mask = (INFINIPATH_IBCS_LINKSTATE_MASK <<
		dd->ibcs_ls_shift) | dd->ibcs_lts_mask;
	dd->ib_init = (INFINIPATH_IBCS_LT_STATE_LINKUP <<
		INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) |
		(INFINIPATH_IBCS_L_STATE_INIT << dd->ibcs_ls_shift);
	dd->ib_arm = (INFINIPATH_IBCS_LT_STATE_LINKUP <<
		INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) |
		(INFINIPATH_IBCS_L_STATE_ARM << dd->ibcs_ls_shift);
	dd->ib_active = (INFINIPATH_IBCS_LT_STATE_LINKUP <<
		INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) |
		(INFINIPATH_IBCS_L_STATE_ACTIVE << dd->ibcs_ls_shift);

	/*
	 * Fill in data for ibcc field-values that change in newer chips.
	 * We dynamically specify only the mask for LINKINITCMD
	 * and only the shift for LINKCMD and MAXPKTLEN, as they are
	 * the only ones that change.
	 */
	dd->ibcc_lic_mask = INFINIPATH_IBCC_LINKINITCMD_MASK;
	dd->ibcc_lc_shift = INFINIPATH_IBCC_LINKCMD_SHIFT;
	dd->ibcc_mpl_shift = INFINIPATH_IBCC_MAXPKTLEN_SHIFT;

996 997 998 999 1000 1001
	/* Fill in shifts for RcvCtrl. */
	dd->ipath_r_portenable_shift = INFINIPATH_R_PORTENABLE_SHIFT;
	dd->ipath_r_intravail_shift = INFINIPATH_R_INTRAVAIL_SHIFT;
	dd->ipath_r_tailupd_shift = INFINIPATH_R_TAILUPD_SHIFT;
	dd->ipath_r_portcfg_shift = 0; /* Not on IBA6120 */

1002
	/* variables for sanity checking interrupt and errors */
1003
	dd->ipath_hwe_bitsextant =
1004 1005
		(INFINIPATH_HWE_RXEMEMPARITYERR_MASK <<
		 INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT) |
1006 1007
		(INFINIPATH_HWE_TXEMEMPARITYERR_MASK <<
		 INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) |
1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022
		(INFINIPATH_HWE_PCIEMEMPARITYERR_MASK <<
		 INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT) |
		INFINIPATH_HWE_PCIE1PLLFAILED |
		INFINIPATH_HWE_PCIE0PLLFAILED |
		INFINIPATH_HWE_PCIEPOISONEDTLP |
		INFINIPATH_HWE_PCIECPLTIMEOUT |
		INFINIPATH_HWE_PCIEBUSPARITYXTLH |
		INFINIPATH_HWE_PCIEBUSPARITYXADM |
		INFINIPATH_HWE_PCIEBUSPARITYRADM |
		INFINIPATH_HWE_MEMBISTFAILED |
		INFINIPATH_HWE_COREPLL_FBSLIP |
		INFINIPATH_HWE_COREPLL_RFSLIP |
		INFINIPATH_HWE_SERDESPLLFAILED |
		INFINIPATH_HWE_IBCBUSTOSPCPARITYERR |
		INFINIPATH_HWE_IBCBUSFRSPCPARITYERR;
1023
	dd->ipath_i_bitsextant =
1024 1025 1026 1027 1028
		(INFINIPATH_I_RCVURG_MASK << INFINIPATH_I_RCVURG_SHIFT) |
		(INFINIPATH_I_RCVAVAIL_MASK <<
		 INFINIPATH_I_RCVAVAIL_SHIFT) |
		INFINIPATH_I_ERROR | INFINIPATH_I_SPIOSENT |
		INFINIPATH_I_SPIOBUFAVAIL | INFINIPATH_I_GPIO;
1029
	dd->ipath_e_bitsextant =
1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046
		INFINIPATH_E_RFORMATERR | INFINIPATH_E_RVCRC |
		INFINIPATH_E_RICRC | INFINIPATH_E_RMINPKTLEN |
		INFINIPATH_E_RMAXPKTLEN | INFINIPATH_E_RLONGPKTLEN |
		INFINIPATH_E_RSHORTPKTLEN | INFINIPATH_E_RUNEXPCHAR |
		INFINIPATH_E_RUNSUPVL | INFINIPATH_E_REBP |
		INFINIPATH_E_RIBFLOW | INFINIPATH_E_RBADVERSION |
		INFINIPATH_E_RRCVEGRFULL | INFINIPATH_E_RRCVHDRFULL |
		INFINIPATH_E_RBADTID | INFINIPATH_E_RHDRLEN |
		INFINIPATH_E_RHDR | INFINIPATH_E_RIBLOSTLINK |
		INFINIPATH_E_SMINPKTLEN | INFINIPATH_E_SMAXPKTLEN |
		INFINIPATH_E_SUNDERRUN | INFINIPATH_E_SPKTLEN |
		INFINIPATH_E_SDROPPEDSMPPKT | INFINIPATH_E_SDROPPEDDATAPKT |
		INFINIPATH_E_SPIOARMLAUNCH | INFINIPATH_E_SUNEXPERRPKTNUM |
		INFINIPATH_E_SUNSUPVL | INFINIPATH_E_IBSTATUSCHANGED |
		INFINIPATH_E_INVALIDADDR | INFINIPATH_E_RESET |
		INFINIPATH_E_HARDWARE;

1047 1048
	dd->ipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK;
	dd->ipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK;
1049 1050
	dd->ipath_i_rcvavail_shift = INFINIPATH_I_RCVAVAIL_SHIFT;
	dd->ipath_i_rcvurg_shift = INFINIPATH_I_RCVURG_SHIFT;
1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071

	/*
	 * EEPROM error log 0 is TXE Parity errors. 1 is RXE Parity.
	 * 2 is Some Misc, 3 is reserved for future.
	 */
	dd->ipath_eep_st_masks[0].hwerrs_to_log =
		INFINIPATH_HWE_TXEMEMPARITYERR_MASK <<
		INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT;

	/* Ignore errors in PIO/PBC on systems with unordered write-combining */
	if (ipath_unordered_wc())
		dd->ipath_eep_st_masks[0].hwerrs_to_log &= ~TXE_PIO_PARITY;

	dd->ipath_eep_st_masks[1].hwerrs_to_log =
		INFINIPATH_HWE_RXEMEMPARITYERR_MASK <<
		INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT;

	dd->ipath_eep_st_masks[2].errs_to_log =
		INFINIPATH_E_INVALIDADDR | INFINIPATH_E_RESET;


1072
	dd->delay_mult = 2; /* SDR, 4X, can't change */
1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146
}

/* setup the MSI stuff again after a reset.  I'd like to just call
 * pci_enable_msi() and request_irq() again, but when I do that,
 * the MSI enable bit doesn't get set in the command word, and
 * we switch to to a different interrupt vector, which is confusing,
 * so I instead just do it all inline.  Perhaps somehow can tie this
 * into the PCIe hotplug support at some point
 * Note, because I'm doing it all here, I don't call pci_disable_msi()
 * or free_irq() at the start of ipath_setup_pe_reset().
 */
static int ipath_reinit_msi(struct ipath_devdata *dd)
{
	int pos;
	u16 control;
	int ret;

	if (!dd->ipath_msi_lo) {
		dev_info(&dd->pcidev->dev, "Can't restore MSI config, "
			 "initial setup failed?\n");
		ret = 0;
		goto bail;
	}

	if (!(pos = pci_find_capability(dd->pcidev, PCI_CAP_ID_MSI))) {
		ipath_dev_err(dd, "Can't find MSI capability, "
			      "can't restore MSI settings\n");
		ret = 0;
		goto bail;
	}
	ipath_cdbg(VERBOSE, "Writing msi_lo 0x%x to config offset 0x%x\n",
		   dd->ipath_msi_lo, pos + PCI_MSI_ADDRESS_LO);
	pci_write_config_dword(dd->pcidev, pos + PCI_MSI_ADDRESS_LO,
			       dd->ipath_msi_lo);
	ipath_cdbg(VERBOSE, "Writing msi_lo 0x%x to config offset 0x%x\n",
		   dd->ipath_msi_hi, pos + PCI_MSI_ADDRESS_HI);
	pci_write_config_dword(dd->pcidev, pos + PCI_MSI_ADDRESS_HI,
			       dd->ipath_msi_hi);
	pci_read_config_word(dd->pcidev, pos + PCI_MSI_FLAGS, &control);
	if (!(control & PCI_MSI_FLAGS_ENABLE)) {
		ipath_cdbg(VERBOSE, "MSI control at off %x was %x, "
			   "setting MSI enable (%x)\n", pos + PCI_MSI_FLAGS,
			   control, control | PCI_MSI_FLAGS_ENABLE);
		control |= PCI_MSI_FLAGS_ENABLE;
		pci_write_config_word(dd->pcidev, pos + PCI_MSI_FLAGS,
				      control);
	}
	/* now rewrite the data (vector) info */
	pci_write_config_word(dd->pcidev, pos +
			      ((control & PCI_MSI_FLAGS_64BIT) ? 12 : 8),
			      dd->ipath_msi_data);
	/* we restore the cachelinesize also, although it doesn't really
	 * matter */
	pci_write_config_byte(dd->pcidev, PCI_CACHE_LINE_SIZE,
			      dd->ipath_pci_cacheline);
	/* and now set the pci master bit again */
	pci_set_master(dd->pcidev);
	ret = 1;

bail:
	return ret;
}

/* This routine sleeps, so it can only be called from user context, not
 * from interrupt context.  If we need interrupt context, we can split
 * it into two routines.
*/
static int ipath_setup_pe_reset(struct ipath_devdata *dd)
{
	u64 val;
	int i;
	int ret;

	/* Use ERROR so it shows up in logs, etc. */
1147
	ipath_dev_err(dd, "Resetting InfiniPath unit %u\n", dd->ipath_unit);
1148 1149
	/* keep chip from being accessed in a few places */
	dd->ipath_flags &= ~(IPATH_INITTED|IPATH_PRESENT);
1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174
	val = dd->ipath_control | INFINIPATH_C_RESET;
	ipath_write_kreg(dd, dd->ipath_kregs->kr_control, val);
	mb();

	for (i = 1; i <= 5; i++) {
		int r;
		/* allow MBIST, etc. to complete; longer on each retry.
		 * We sometimes get machine checks from bus timeout if no
		 * response, so for now, make it *really* long.
		 */
		msleep(1000 + (1 + i) * 2000);
		if ((r =
		     pci_write_config_dword(dd->pcidev, PCI_BASE_ADDRESS_0,
					    dd->ipath_pcibar0)))
			ipath_dev_err(dd, "rewrite of BAR0 failed: %d\n",
				      r);
		if ((r =
		     pci_write_config_dword(dd->pcidev, PCI_BASE_ADDRESS_1,
					    dd->ipath_pcibar1)))
			ipath_dev_err(dd, "rewrite of BAR1 failed: %d\n",
				      r);
		/* now re-enable memory access */
		if ((r = pci_enable_device(dd->pcidev)))
			ipath_dev_err(dd, "pci_enable_device failed after "
				      "reset: %d\n", r);
1175 1176
		/* whether it worked or not, mark as present, again */
		dd->ipath_flags |= IPATH_PRESENT;
1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199
		val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_revision);
		if (val == dd->ipath_revision) {
			ipath_cdbg(VERBOSE, "Got matching revision "
				   "register %llx on try %d\n",
				   (unsigned long long) val, i);
			ret = ipath_reinit_msi(dd);
			goto bail;
		}
		/* Probably getting -1 back */
		ipath_dbg("Didn't get expected revision register, "
			  "got %llx, try %d\n", (unsigned long long) val,
			  i + 1);
	}
	ret = 0; /* failed */

bail:
	return ret;
}

/**
 * ipath_pe_put_tid - write a TID in chip
 * @dd: the infinipath device
 * @tidptr: pointer to the expected TID (in chip) to udpate
1200
 * @tidtype: RCVHQ_RCV_TYPE_EAGER (1) for eager, RCVHQ_RCV_TYPE_EXPECTED (0) for expected
1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225
 * @pa: physical address of in memory buffer; ipath_tidinvalid if freeing
 *
 * This exists as a separate routine to allow for special locking etc.
 * It's used for both the full cleanup on exit, as well as the normal
 * setup and teardown.
 */
static void ipath_pe_put_tid(struct ipath_devdata *dd, u64 __iomem *tidptr,
			     u32 type, unsigned long pa)
{
	u32 __iomem *tidp32 = (u32 __iomem *)tidptr;
	unsigned long flags = 0; /* keep gcc quiet */

	if (pa != dd->ipath_tidinvalid) {
		if (pa & ((1U << 11) - 1)) {
			dev_info(&dd->pcidev->dev, "BUG: physaddr %lx "
				 "not 4KB aligned!\n", pa);
			return;
		}
		pa >>= 11;
		/* paranoia check */
		if (pa & (7<<29))
			ipath_dev_err(dd,
				      "BUG: Physical page address 0x%lx "
				      "has bits set in 31-29\n", pa);

1226
		if (type == RCVHQ_RCV_TYPE_EAGER)
1227 1228 1229 1230 1231
			pa |= dd->ipath_tidtemplate;
		else /* for now, always full 4KB page */
			pa |= 2 << 29;
	}

1232 1233 1234 1235 1236 1237 1238 1239
	/*
	 * Workaround chip bug 9437 by writing the scratch register
	 * before and after the TID, and with an io write barrier.
	 * We use a spinlock around the writes, so they can't intermix
	 * with other TID (eager or expected) writes (the chip bug
	 * is triggered by back to back TID writes). Unfortunately, this
	 * call can be done from interrupt level for the port 0 eager TIDs,
	 * so we have to use irqsave locks.
1240 1241 1242 1243 1244 1245 1246 1247 1248
	 */
	spin_lock_irqsave(&dd->ipath_tid_lock, flags);
	ipath_write_kreg(dd, dd->ipath_kregs->kr_scratch, 0xfeeddeaf);
	if (dd->ipath_kregbase)
		writel(pa, tidp32);
	ipath_write_kreg(dd, dd->ipath_kregs->kr_scratch, 0xdeadbeef);
	mmiowb();
	spin_unlock_irqrestore(&dd->ipath_tid_lock, flags);
}
1249 1250 1251 1252
/**
 * ipath_pe_put_tid_2 - write a TID in chip, Revision 2 or higher
 * @dd: the infinipath device
 * @tidptr: pointer to the expected TID (in chip) to udpate
1253
 * @tidtype: RCVHQ_RCV_TYPE_EAGER (1) for eager, RCVHQ_RCV_TYPE_EXPECTED (0) for expected
1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267
 * @pa: physical address of in memory buffer; ipath_tidinvalid if freeing
 *
 * This exists as a separate routine to allow for selection of the
 * appropriate "flavor". The static calls in cleanup just use the
 * revision-agnostic form, as they are not performance critical.
 */
static void ipath_pe_put_tid_2(struct ipath_devdata *dd, u64 __iomem *tidptr,
			     u32 type, unsigned long pa)
{
	u32 __iomem *tidp32 = (u32 __iomem *)tidptr;

	if (pa != dd->ipath_tidinvalid) {
		if (pa & ((1U << 11) - 1)) {
			dev_info(&dd->pcidev->dev, "BUG: physaddr %lx "
1268
				 "not 2KB aligned!\n", pa);
1269 1270 1271 1272 1273 1274 1275 1276 1277
			return;
		}
		pa >>= 11;
		/* paranoia check */
		if (pa & (7<<29))
			ipath_dev_err(dd,
				      "BUG: Physical page address 0x%lx "
				      "has bits set in 31-29\n", pa);

1278
		if (type == RCVHQ_RCV_TYPE_EAGER)
1279 1280 1281 1282 1283 1284 1285 1286 1287
			pa |= dd->ipath_tidtemplate;
		else /* for now, always full 4KB page */
			pa |= 2 << 29;
	}
	if (dd->ipath_kregbase)
		writel(pa, tidp32);
	mmiowb();
}

1288 1289 1290 1291 1292 1293 1294

/**
 * ipath_pe_clear_tid - clear all TID entries for a port, expected and eager
 * @dd: the infinipath device
 * @port: the port
 *
 * clear all TID entries for a port, expected and eager.
1295
 * Used from ipath_close().  On this chip, TIDs are only 32 bits,
1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316
 * not 64, but they are still on 64 bit boundaries, so tidbase
 * is declared as u64 * for the pointer math, even though we write 32 bits
 */
static void ipath_pe_clear_tids(struct ipath_devdata *dd, unsigned port)
{
	u64 __iomem *tidbase;
	unsigned long tidinv;
	int i;

	if (!dd->ipath_kregbase)
		return;

	ipath_cdbg(VERBOSE, "Invalidate TIDs for port %u\n", port);

	tidinv = dd->ipath_tidinvalid;
	tidbase = (u64 __iomem *)
		((char __iomem *)(dd->ipath_kregbase) +
		 dd->ipath_rcvtidbase +
		 port * dd->ipath_rcvtidcnt * sizeof(*tidbase));

	for (i = 0; i < dd->ipath_rcvtidcnt; i++)
1317
		dd->ipath_f_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EXPECTED,
1318
				 tidinv);
1319 1320 1321 1322 1323 1324 1325

	tidbase = (u64 __iomem *)
		((char __iomem *)(dd->ipath_kregbase) +
		 dd->ipath_rcvegrbase +
		 port * dd->ipath_rcvegrcnt * sizeof(*tidbase));

	for (i = 0; i < dd->ipath_rcvegrcnt; i++)
1326
		dd->ipath_f_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EAGER,
1327
				 tidinv);
1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364
}

/**
 * ipath_pe_tidtemplate - setup constants for TID updates
 * @dd: the infinipath device
 *
 * We setup stuff that we use a lot, to avoid calculating each time
 */
static void ipath_pe_tidtemplate(struct ipath_devdata *dd)
{
	u32 egrsize = dd->ipath_rcvegrbufsize;

	/* For now, we always allocate 4KB buffers (at init) so we can
	 * receive max size packets.  We may want a module parameter to
	 * specify 2KB or 4KB and/or make be per port instead of per device
	 * for those who want to reduce memory footprint.  Note that the
	 * ipath_rcvhdrentsize size must be large enough to hold the largest
	 * IB header (currently 96 bytes) that we expect to handle (plus of
	 * course the 2 dwords of RHF).
	 */
	if (egrsize == 2048)
		dd->ipath_tidtemplate = 1U << 29;
	else if (egrsize == 4096)
		dd->ipath_tidtemplate = 2U << 29;
	else {
		egrsize = 4096;
		dev_info(&dd->pcidev->dev, "BUG: unsupported egrbufsize "
			 "%u, using %u\n", dd->ipath_rcvegrbufsize,
			 egrsize);
		dd->ipath_tidtemplate = 2U << 29;
	}
	dd->ipath_tidinvalid = 0;
}

static int ipath_pe_early_init(struct ipath_devdata *dd)
{
	dd->ipath_flags |= IPATH_4BYTE_TID;
1365 1366
	if (ipath_unordered_wc())
		dd->ipath_flags |= IPATH_PIO_FLUSH_WC;
1367 1368

	/*
1369 1370 1371
	 * For openfabrics, we need to be able to handle an IB header of
	 * 24 dwords.  HT chip has arbitrary sized receive buffers, so we
	 * made them the same size as the PIO buffers.  This chip does not
1372 1373 1374 1375 1376 1377
	 * handle arbitrary size buffers, so we need the header large enough
	 * to handle largest IB header, but still have room for a 2KB MTU
	 * standard IB packet.
	 */
	dd->ipath_rcvhdrentsize = 24;
	dd->ipath_rcvhdrsize = IPATH_DFLT_RCVHDRSIZE;
1378 1379 1380
	dd->ipath_rhf_offset = 0;
	dd->ipath_egrtidbase = (u64 __iomem *)
		((char __iomem *) dd->ipath_kregbase + dd->ipath_rcvegrbase);
1381

1382 1383 1384 1385
	/*
	 * To truly support a 4KB MTU (for usermode), we need to
	 * bump this to a larger value.  For now, we use them for
	 * the kernel only.
1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397
	 */
	dd->ipath_rcvegrbufsize = 2048;
	/*
	 * the min() check here is currently a nop, but it may not always
	 * be, depending on just how we do ipath_rcvegrbufsize
	 */
	dd->ipath_ibmaxlen = min(dd->ipath_piosize2k,
				 dd->ipath_rcvegrbufsize +
				 (dd->ipath_rcvhdrentsize << 2));
	dd->ipath_init_ibmaxlen = dd->ipath_ibmaxlen;

	/*
1398
	 * We can request a receive interrupt for 1 or
1399
	 * more packets from current offset.  For now, we set this
1400
	 * up for a single packet.
1401 1402 1403
	 */
	dd->ipath_rhdrhead_intr_off = 1ULL<<32;

1404 1405
	ipath_get_eeprom_info(dd);

1406 1407 1408 1409 1410 1411 1412 1413 1414 1415
	return 0;
}

int __attribute__((weak)) ipath_unordered_wc(void)
{
	return 0;
}

/**
 * ipath_init_pe_get_base_info - set chip-specific flags for user code
1416
 * @pd: the infinipath port
1417 1418 1419
 * @kbase: ipath_base_info pointer
 *
 * We set the PCIE flag because the lower bandwidth on PCIe vs
R
Robert P. J. Day 已提交
1420
 * HyperTransport can affect some user packet algorithms.
1421 1422 1423 1424
 */
static int ipath_pe_get_base_info(struct ipath_portdata *pd, void *kbase)
{
	struct ipath_base_info *kinfo = kbase;
1425
	struct ipath_devdata *dd;
1426 1427 1428 1429 1430 1431 1432 1433

	if (ipath_unordered_wc()) {
		kinfo->spi_runtime_flags |= IPATH_RUNTIME_FORCE_WC_ORDER;
		ipath_cdbg(PROC, "Intel processor, forcing WC order\n");
	}
	else
		ipath_cdbg(PROC, "Not Intel processor, WC ordered\n");

1434 1435 1436 1437 1438 1439
	if (pd == NULL)
		goto done;

	dd = pd->port_dd;

done:
1440 1441
	kinfo->spi_runtime_flags |= IPATH_RUNTIME_PCIE |
		IPATH_RUNTIME_FORCE_PIOAVAIL | IPATH_RUNTIME_PIO_REGSWAPPED;
1442 1443 1444
	return 0;
}

1445 1446 1447 1448 1449 1450
static void ipath_pe_free_irq(struct ipath_devdata *dd)
{
	free_irq(dd->ipath_irq, dd);
	dd->ipath_irq = 0;
}

1451 1452 1453 1454 1455 1456 1457 1458

static struct ipath_message_header *
ipath_pe_get_msgheader(struct ipath_devdata *dd, __le32 *rhf_addr)
{
	return (struct ipath_message_header *)
		&rhf_addr[sizeof(u64) / sizeof(u32)];
}

1459 1460 1461 1462 1463 1464 1465 1466
static void ipath_pe_config_ports(struct ipath_devdata *dd, ushort cfgports)
{
	dd->ipath_portcnt =
		ipath_read_kreg32(dd, dd->ipath_kregs->kr_portcnt);
	dd->ipath_p0_rcvegrcnt =
		ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvegrcnt);
}

1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565
static void ipath_pe_read_counters(struct ipath_devdata *dd,
				   struct infinipath_counters *cntrs)
{
	cntrs->LBIntCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(LBIntCnt));
	cntrs->LBFlowStallCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(LBFlowStallCnt));
	cntrs->TxSDmaDescCnt = 0;
	cntrs->TxUnsupVLErrCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxUnsupVLErrCnt));
	cntrs->TxDataPktCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxDataPktCnt));
	cntrs->TxFlowPktCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxFlowPktCnt));
	cntrs->TxDwordCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxDwordCnt));
	cntrs->TxLenErrCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxLenErrCnt));
	cntrs->TxMaxMinLenErrCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxMaxMinLenErrCnt));
	cntrs->TxUnderrunCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxUnderrunCnt));
	cntrs->TxFlowStallCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxFlowStallCnt));
	cntrs->TxDroppedPktCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxDroppedPktCnt));
	cntrs->RxDroppedPktCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxDroppedPktCnt));
	cntrs->RxDataPktCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxDataPktCnt));
	cntrs->RxFlowPktCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxFlowPktCnt));
	cntrs->RxDwordCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxDwordCnt));
	cntrs->RxLenErrCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxLenErrCnt));
	cntrs->RxMaxMinLenErrCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxMaxMinLenErrCnt));
	cntrs->RxICRCErrCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxICRCErrCnt));
	cntrs->RxVCRCErrCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxVCRCErrCnt));
	cntrs->RxFlowCtrlErrCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxFlowCtrlErrCnt));
	cntrs->RxBadFormatCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxBadFormatCnt));
	cntrs->RxLinkProblemCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxLinkProblemCnt));
	cntrs->RxEBPCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxEBPCnt));
	cntrs->RxLPCRCErrCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxLPCRCErrCnt));
	cntrs->RxBufOvflCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxBufOvflCnt));
	cntrs->RxTIDFullErrCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxTIDFullErrCnt));
	cntrs->RxTIDValidErrCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxTIDValidErrCnt));
	cntrs->RxPKeyMismatchCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxPKeyMismatchCnt));
	cntrs->RxP0HdrEgrOvflCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP0HdrEgrOvflCnt));
	cntrs->RxP1HdrEgrOvflCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP1HdrEgrOvflCnt));
	cntrs->RxP2HdrEgrOvflCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP2HdrEgrOvflCnt));
	cntrs->RxP3HdrEgrOvflCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP3HdrEgrOvflCnt));
	cntrs->RxP4HdrEgrOvflCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP4HdrEgrOvflCnt));
	cntrs->RxP5HdrEgrOvflCnt = 0;
	cntrs->RxP6HdrEgrOvflCnt = 0;
	cntrs->RxP7HdrEgrOvflCnt = 0;
	cntrs->RxP8HdrEgrOvflCnt = 0;
	cntrs->RxP9HdrEgrOvflCnt = 0;
	cntrs->RxP10HdrEgrOvflCnt = 0;
	cntrs->RxP11HdrEgrOvflCnt = 0;
	cntrs->RxP12HdrEgrOvflCnt = 0;
	cntrs->RxP13HdrEgrOvflCnt = 0;
	cntrs->RxP14HdrEgrOvflCnt = 0;
	cntrs->RxP15HdrEgrOvflCnt = 0;
	cntrs->RxP16HdrEgrOvflCnt = 0;
	cntrs->IBStatusChangeCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(IBStatusChangeCnt));
	cntrs->IBLinkErrRecoveryCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(IBLinkErrRecoveryCnt));
	cntrs->IBLinkDownedCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(IBLinkDownedCnt));
	cntrs->IBSymbolErrCnt =
		ipath_snap_cntr(dd, IPATH_CREG_OFFSET(IBSymbolErrCnt));
	cntrs->RxVL15DroppedPktCnt = 0;
	cntrs->RxOtherLocalPhyErrCnt = 0;
	cntrs->PcieRetryBufDiagQwordCnt = 0;
	cntrs->ExcessBufferOvflCnt = dd->ipath_overrun_thresh_errs;
	cntrs->LocalLinkIntegrityErrCnt = dd->ipath_lli_errs;
	cntrs->RxVlErrCnt = 0;
	cntrs->RxDlidFltrCnt = 0;
}

1566

1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648
/* no interrupt fallback for these chips */
static int ipath_pe_nointr_fallback(struct ipath_devdata *dd)
{
	return 0;
}


/*
 * reset the XGXS (between serdes and IBC).  Slightly less intrusive
 * than resetting the IBC or external link state, and useful in some
 * cases to cause some retraining.  To do this right, we reset IBC
 * as well.
 */
static void ipath_pe_xgxs_reset(struct ipath_devdata *dd)
{
	u64 val, prev_val;

	prev_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig);
	val = prev_val | INFINIPATH_XGXS_RESET;
	prev_val &= ~INFINIPATH_XGXS_RESET; /* be sure */
	ipath_write_kreg(dd, dd->ipath_kregs->kr_control,
			 dd->ipath_control & ~INFINIPATH_C_LINKENABLE);
	ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val);
	ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch);
	ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, prev_val);
	ipath_write_kreg(dd, dd->ipath_kregs->kr_control,
			 dd->ipath_control);
}


static int ipath_pe_get_ib_cfg(struct ipath_devdata *dd, int which)
{
	int ret;

	switch (which) {
	case IPATH_IB_CFG_LWID:
		ret = dd->ipath_link_width_active;
		break;
	case IPATH_IB_CFG_SPD:
		ret = dd->ipath_link_speed_active;
		break;
	case IPATH_IB_CFG_LWID_ENB:
		ret = dd->ipath_link_width_enabled;
		break;
	case IPATH_IB_CFG_SPD_ENB:
		ret = dd->ipath_link_speed_enabled;
		break;
	default:
		ret =  -ENOTSUPP;
		break;
	}
	return ret;
}


/* we assume range checking is already done, if needed */
static int ipath_pe_set_ib_cfg(struct ipath_devdata *dd, int which, u32 val)
{
	int ret = 0;

	if (which == IPATH_IB_CFG_LWID_ENB)
		dd->ipath_link_width_enabled = val;
	else if (which == IPATH_IB_CFG_SPD_ENB)
		dd->ipath_link_speed_enabled = val;
	else
		ret = -ENOTSUPP;
	return ret;
}

static void ipath_pe_config_jint(struct ipath_devdata *dd, u16 a, u16 b)
{
}


static int ipath_pe_ib_updown(struct ipath_devdata *dd, int ibup, u64 ibcs)
{
	ipath_setup_pe_setextled(dd, ipath_ib_linkstate(dd, ibcs),
		ipath_ib_linktrstate(dd, ibcs));
	return 0;
}


1649
/**
1650
 * ipath_init_iba6120_funcs - set up the chip-specific function pointers
1651 1652 1653 1654 1655
 * @dd: the infinipath device
 *
 * This is global, and is called directly at init to set up the
 * chip-specific function pointers for later use.
 */
1656
void ipath_init_iba6120_funcs(struct ipath_devdata *dd)
1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667
{
	dd->ipath_f_intrsetup = ipath_pe_intconfig;
	dd->ipath_f_bus = ipath_setup_pe_config;
	dd->ipath_f_reset = ipath_setup_pe_reset;
	dd->ipath_f_get_boardname = ipath_pe_boardname;
	dd->ipath_f_init_hwerrors = ipath_pe_init_hwerrors;
	dd->ipath_f_early_init = ipath_pe_early_init;
	dd->ipath_f_handle_hwerrors = ipath_pe_handle_hwerrors;
	dd->ipath_f_quiet_serdes = ipath_pe_quiet_serdes;
	dd->ipath_f_bringup_serdes = ipath_pe_bringup_serdes;
	dd->ipath_f_clear_tids = ipath_pe_clear_tids;
1668
	/*
1669
	 * _f_put_tid may get changed after we read the chip revision,
1670 1671 1672
	 * but we start with the safe version for all revs
	 */
	dd->ipath_f_put_tid = ipath_pe_put_tid;
1673 1674 1675
	dd->ipath_f_cleanup = ipath_setup_pe_cleanup;
	dd->ipath_f_setextled = ipath_setup_pe_setextled;
	dd->ipath_f_get_base_info = ipath_pe_get_base_info;
1676
	dd->ipath_f_free_irq = ipath_pe_free_irq;
1677
	dd->ipath_f_tidtemplate = ipath_pe_tidtemplate;
1678 1679 1680
	dd->ipath_f_intr_fallback = ipath_pe_nointr_fallback;
	dd->ipath_f_xgxs_reset = ipath_pe_xgxs_reset;
	dd->ipath_f_get_msgheader = ipath_pe_get_msgheader;
1681
	dd->ipath_f_config_ports = ipath_pe_config_ports;
1682
	dd->ipath_f_read_counters = ipath_pe_read_counters;
1683 1684 1685 1686
	dd->ipath_f_get_ib_cfg = ipath_pe_get_ib_cfg;
	dd->ipath_f_set_ib_cfg = ipath_pe_set_ib_cfg;
	dd->ipath_f_config_jint = ipath_pe_config_jint;
	dd->ipath_f_ib_updown = ipath_pe_ib_updown;
1687 1688


1689
	/* initialize chip-specific variables */
1690
	ipath_init_pe_variables(dd);
1691 1692
}