1f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 2f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation. 3f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * All rights reserved. 4f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. 5f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 6f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * This software is available to you under a choice of one of two 7f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * licenses. You may choose to be licensed under the terms of the GNU 8f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * General Public License (GPL) Version 2, available from the file 9f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * COPYING in the main directory of this source tree, or the 10f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * OpenIB.org BSD license below: 11f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 12f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Redistribution and use in source and binary forms, with or 13f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * without modification, are permitted provided that the following 14f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * conditions are met: 15f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 16f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * - Redistributions of source code must retain the above 17f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * copyright notice, this list of conditions and the following 18f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * disclaimer. 19f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 20f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * - Redistributions in binary form must reproduce the above 21f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * copyright notice, this list of conditions and the following 22f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * disclaimer in the documentation and/or other materials 23f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * provided with the distribution. 24f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 25f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * SOFTWARE. 33f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 34f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 35f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * This file contains all of the code that is specific to the 36f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * QLogic_IB 7220 chip (except that specific to the SerDes) 37f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 38f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 39f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#include <linux/interrupt.h> 40f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#include <linux/pci.h> 41f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#include <linux/delay.h> 42e4dd23d753c3cb0d8533d353069e8b2e8a666360Paul Gortmaker#include <linux/module.h> 43f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#include <linux/io.h> 44f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#include <rdma/ib_verbs.h> 45f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 46f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#include "qib.h" 47f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#include "qib_7220.h" 48f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 49f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_setup_7220_setextled(struct qib_pportdata *, u32); 50f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_handle_hwerrors(struct qib_devdata *, char *, size_t); 51f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void sendctrl_7220_mod(struct qib_pportdata *ppd, u32 op); 52f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic u32 qib_7220_iblink_state(u64); 53f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic u8 qib_7220_phys_portstate(u64); 54f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_sdma_update_7220_tail(struct qib_pportdata *, u16); 55f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_set_ib_7220_lstate(struct qib_pportdata *, u16, u16); 56f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 57f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 58f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * This file contains almost all the chip-specific register information and 59f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * access functions for the QLogic QLogic_IB 7220 PCI-Express chip, with the 60f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * exception of SerDes support, which in in qib_sd7220.c. 61f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 62f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 63f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* Below uses machine-generated qib_chipnum_regs.h file */ 64f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define KREG_IDX(regname) (QIB_7220_##regname##_OFFS / sizeof(u64)) 65f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 66f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* Use defines to tie machine-generated names to lower-case names */ 67f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_control KREG_IDX(Control) 68f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_counterregbase KREG_IDX(CntrRegBase) 69f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_errclear KREG_IDX(ErrClear) 70f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_errmask KREG_IDX(ErrMask) 71f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_errstatus KREG_IDX(ErrStatus) 72f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_extctrl KREG_IDX(EXTCtrl) 73f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_extstatus KREG_IDX(EXTStatus) 74f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_gpio_clear KREG_IDX(GPIOClear) 75f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_gpio_mask KREG_IDX(GPIOMask) 76f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_gpio_out KREG_IDX(GPIOOut) 77f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_gpio_status KREG_IDX(GPIOStatus) 78f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_hrtbt_guid KREG_IDX(HRTBT_GUID) 79f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_hwdiagctrl KREG_IDX(HwDiagCtrl) 80f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_hwerrclear KREG_IDX(HwErrClear) 81f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_hwerrmask KREG_IDX(HwErrMask) 82f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_hwerrstatus KREG_IDX(HwErrStatus) 83f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_ibcctrl KREG_IDX(IBCCtrl) 84f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_ibcddrctrl KREG_IDX(IBCDDRCtrl) 85f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_ibcddrstatus KREG_IDX(IBCDDRStatus) 86f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_ibcstatus KREG_IDX(IBCStatus) 87f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_ibserdesctrl KREG_IDX(IBSerDesCtrl) 88f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_intclear KREG_IDX(IntClear) 89f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_intmask KREG_IDX(IntMask) 90f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_intstatus KREG_IDX(IntStatus) 91f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_ncmodectrl KREG_IDX(IBNCModeCtrl) 92f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_palign KREG_IDX(PageAlign) 93f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_partitionkey KREG_IDX(RcvPartitionKey) 94f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_portcnt KREG_IDX(PortCnt) 95f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_rcvbthqp KREG_IDX(RcvBTHQP) 96f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_rcvctrl KREG_IDX(RcvCtrl) 97f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_rcvegrbase KREG_IDX(RcvEgrBase) 98f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_rcvegrcnt KREG_IDX(RcvEgrCnt) 99f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_rcvhdrcnt KREG_IDX(RcvHdrCnt) 100f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_rcvhdrentsize KREG_IDX(RcvHdrEntSize) 101f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_rcvhdrsize KREG_IDX(RcvHdrSize) 102f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_rcvpktledcnt KREG_IDX(RcvPktLEDCnt) 103f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_rcvtidbase KREG_IDX(RcvTIDBase) 104f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_rcvtidcnt KREG_IDX(RcvTIDCnt) 105f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_revision KREG_IDX(Revision) 106f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_scratch KREG_IDX(Scratch) 107f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_sendbuffererror KREG_IDX(SendBufErr0) 108f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_sendctrl KREG_IDX(SendCtrl) 109f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_senddmabase KREG_IDX(SendDmaBase) 110f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_senddmabufmask0 KREG_IDX(SendDmaBufMask0) 111f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_senddmabufmask1 (KREG_IDX(SendDmaBufMask0) + 1) 112f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_senddmabufmask2 (KREG_IDX(SendDmaBufMask0) + 2) 113f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_senddmahead KREG_IDX(SendDmaHead) 114f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_senddmaheadaddr KREG_IDX(SendDmaHeadAddr) 115f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_senddmalengen KREG_IDX(SendDmaLenGen) 116f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_senddmastatus KREG_IDX(SendDmaStatus) 117f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_senddmatail KREG_IDX(SendDmaTail) 118f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_sendpioavailaddr KREG_IDX(SendBufAvailAddr) 119f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_sendpiobufbase KREG_IDX(SendBufBase) 120f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_sendpiobufcnt KREG_IDX(SendBufCnt) 121f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_sendpiosize KREG_IDX(SendBufSize) 122f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_sendregbase KREG_IDX(SendRegBase) 123f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_userregbase KREG_IDX(UserRegBase) 124f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_xgxs_cfg KREG_IDX(XGXSCfg) 125f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 126f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* These must only be written via qib_write_kreg_ctxt() */ 127f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_rcvhdraddr KREG_IDX(RcvHdrAddr0) 128f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define kr_rcvhdrtailaddr KREG_IDX(RcvHdrTailAddr0) 129f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 130f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 131f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define CREG_IDX(regname) ((QIB_7220_##regname##_OFFS - \ 132f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIB_7220_LBIntCnt_OFFS) / sizeof(u64)) 133f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 134f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_badformat CREG_IDX(RxVersionErrCnt) 135f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_erricrc CREG_IDX(RxICRCErrCnt) 136f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_errlink CREG_IDX(RxLinkMalformCnt) 137f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_errlpcrc CREG_IDX(RxLPCRCErrCnt) 138f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_errpkey CREG_IDX(RxPKeyMismatchCnt) 139f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_rcvflowctrl_err CREG_IDX(RxFlowCtrlViolCnt) 140f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_err_rlen CREG_IDX(RxLenErrCnt) 141f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_errslen CREG_IDX(TxLenErrCnt) 142f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_errtidfull CREG_IDX(RxTIDFullErrCnt) 143f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_errtidvalid CREG_IDX(RxTIDValidErrCnt) 144f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_errvcrc CREG_IDX(RxVCRCErrCnt) 145f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_ibstatuschange CREG_IDX(IBStatusChangeCnt) 146f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_lbint CREG_IDX(LBIntCnt) 147f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_invalidrlen CREG_IDX(RxMaxMinLenErrCnt) 148f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_invalidslen CREG_IDX(TxMaxMinLenErrCnt) 149f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_lbflowstall CREG_IDX(LBFlowStallCnt) 150f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_pktrcv CREG_IDX(RxDataPktCnt) 151f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_pktrcvflowctrl CREG_IDX(RxFlowPktCnt) 152f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_pktsend CREG_IDX(TxDataPktCnt) 153f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_pktsendflow CREG_IDX(TxFlowPktCnt) 154f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_portovfl CREG_IDX(RxP0HdrEgrOvflCnt) 155f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_rcvebp CREG_IDX(RxEBPCnt) 156f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_rcvovfl CREG_IDX(RxBufOvflCnt) 157f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_senddropped CREG_IDX(TxDroppedPktCnt) 158f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_sendstall CREG_IDX(TxFlowStallCnt) 159f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_sendunderrun CREG_IDX(TxUnderrunCnt) 160f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_wordrcv CREG_IDX(RxDwordCnt) 161f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_wordsend CREG_IDX(TxDwordCnt) 162f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_txunsupvl CREG_IDX(TxUnsupVLErrCnt) 163f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_rxdroppkt CREG_IDX(RxDroppedPktCnt) 164f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_iblinkerrrecov CREG_IDX(IBLinkErrRecoveryCnt) 165f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_iblinkdown CREG_IDX(IBLinkDownedCnt) 166f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_ibsymbolerr CREG_IDX(IBSymbolErrCnt) 167f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_vl15droppedpkt CREG_IDX(RxVL15DroppedPktCnt) 168f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_rxotherlocalphyerr CREG_IDX(RxOtherLocalPhyErrCnt) 169f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_excessbufferovfl CREG_IDX(ExcessBufferOvflCnt) 170f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_locallinkintegrityerr CREG_IDX(LocalLinkIntegrityErrCnt) 171f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_rxvlerr CREG_IDX(RxVlErrCnt) 172f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_rxdlidfltr CREG_IDX(RxDlidFltrCnt) 173f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_psstat CREG_IDX(PSStat) 174f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_psstart CREG_IDX(PSStart) 175f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_psinterval CREG_IDX(PSInterval) 176f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_psrcvdatacount CREG_IDX(PSRcvDataCount) 177f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_psrcvpktscount CREG_IDX(PSRcvPktsCount) 178f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_psxmitdatacount CREG_IDX(PSXmitDataCount) 179f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_psxmitpktscount CREG_IDX(PSXmitPktsCount) 180f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_psxmitwaitcount CREG_IDX(PSXmitWaitCount) 181f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_txsdmadesc CREG_IDX(TxSDmaDescCnt) 182f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define cr_pcieretrydiag CREG_IDX(PcieRetryBufDiagQwordCnt) 183f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 184f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define SYM_RMASK(regname, fldname) ((u64) \ 185f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIB_7220_##regname##_##fldname##_RMASK) 186f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define SYM_MASK(regname, fldname) ((u64) \ 187f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIB_7220_##regname##_##fldname##_RMASK << \ 188f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIB_7220_##regname##_##fldname##_LSB) 189f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define SYM_LSB(regname, fldname) (QIB_7220_##regname##_##fldname##_LSB) 190f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define SYM_FIELD(value, regname, fldname) ((u64) \ 191f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (((value) >> SYM_LSB(regname, fldname)) & \ 192f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_RMASK(regname, fldname))) 193f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define ERR_MASK(fldname) SYM_MASK(ErrMask, fldname##Mask) 194f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define HWE_MASK(fldname) SYM_MASK(HwErrMask, fldname##Mask) 195f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 196f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* ibcctrl bits */ 197f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_IBCC_LINKINITCMD_DISABLE 1 198f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* cycle through TS1/TS2 till OK */ 199f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_IBCC_LINKINITCMD_POLL 2 200f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* wait for TS1, then go on */ 201f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_IBCC_LINKINITCMD_SLEEP 3 202f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_IBCC_LINKINITCMD_SHIFT 16 203f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 204f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_IBCC_LINKCMD_DOWN 1 /* move to 0x11 */ 205f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_IBCC_LINKCMD_ARMED 2 /* move to 0x21 */ 206f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_IBCC_LINKCMD_ACTIVE 3 /* move to 0x31 */ 207f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 208f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define BLOB_7220_IBCHG 0x81 209f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 210f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 211f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * We could have a single register get/put routine, that takes a group type, 212f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * but this is somewhat clearer and cleaner. It also gives us some error 213f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * checking. 64 bit register reads should always work, but are inefficient 214f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * on opteron (the northbridge always generates 2 separate HT 32 bit reads), 215f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * so we use kreg32 wherever possible. User register and counter register 216f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * reads are always 32 bit reads, so only one form of those routines. 217f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 218f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 219f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/** 220f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_read_ureg32 - read 32-bit virtualized per-context register 221f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @dd: device 222f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @regno: register number 223f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @ctxt: context number 224f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 225f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Return the contents of a register that is virtualized to be per context. 226f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Returns -1 on errors (not distinguishable from valid contents at 227f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * runtime; we may add a separate error variable at some point). 228f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 229f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic inline u32 qib_read_ureg32(const struct qib_devdata *dd, 230f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell enum qib_ureg regno, int ctxt) 231f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 232f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!dd->kregbase || !(dd->flags & QIB_PRESENT)) 233f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return 0; 234f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 235f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->userbase) 236f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return readl(regno + (u64 __iomem *) 237f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ((char __iomem *)dd->userbase + 238f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->ureg_align * ctxt)); 239f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else 240f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return readl(regno + (u64 __iomem *) 241f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (dd->uregbase + 242f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (char __iomem *)dd->kregbase + 243f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->ureg_align * ctxt)); 244f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 245f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 246f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/** 247f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_write_ureg - write 32-bit virtualized per-context register 248f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @dd: device 249f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @regno: register number 250f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @value: value 251f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @ctxt: context 252f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 253f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Write the contents of a register that is virtualized to be per context. 254f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 255f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic inline void qib_write_ureg(const struct qib_devdata *dd, 256f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell enum qib_ureg regno, u64 value, int ctxt) 257f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 258f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 __iomem *ubase; 259f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 260f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->userbase) 261f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ubase = (u64 __iomem *) 262f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ((char __iomem *) dd->userbase + 263f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->ureg_align * ctxt); 264f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else 265f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ubase = (u64 __iomem *) 266f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (dd->uregbase + 267f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (char __iomem *) dd->kregbase + 268f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->ureg_align * ctxt); 269f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 270f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->kregbase && (dd->flags & QIB_PRESENT)) 271f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell writeq(value, &ubase[regno]); 272f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 273f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 274f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/** 275f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_write_kreg_ctxt - write a device's per-ctxt 64-bit kernel register 276f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @dd: the qlogic_ib device 277f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @regno: the register number to write 278f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @ctxt: the context containing the register 279f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @value: the value to write 280f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 281f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic inline void qib_write_kreg_ctxt(const struct qib_devdata *dd, 282f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell const u16 regno, unsigned ctxt, 283f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 value) 284f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 285f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, regno + ctxt, value); 286f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 287f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 288f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic inline void write_7220_creg(const struct qib_devdata *dd, 289f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u16 regno, u64 value) 290f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 291f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->cspec->cregbase && (dd->flags & QIB_PRESENT)) 292f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell writeq(value, &dd->cspec->cregbase[regno]); 293f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 294f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 295f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic inline u64 read_7220_creg(const struct qib_devdata *dd, u16 regno) 296f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 297f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!dd->cspec->cregbase || !(dd->flags & QIB_PRESENT)) 298f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return 0; 299f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return readq(&dd->cspec->cregbase[regno]); 300f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 301f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 302f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic inline u32 read_7220_creg32(const struct qib_devdata *dd, u16 regno) 303f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 304f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!dd->cspec->cregbase || !(dd->flags & QIB_PRESENT)) 305f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return 0; 306f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return readl(&dd->cspec->cregbase[regno]); 307f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 308f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 309f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* kr_revision bits */ 310f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_R_EMULATORREV_MASK ((1ULL << 22) - 1) 311f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_R_EMULATORREV_SHIFT 40 312f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 313f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* kr_control bits */ 314f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_C_RESET (1U << 7) 315f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 316f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* kr_intstatus, kr_intclear, kr_intmask bits */ 317f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_I_RCVURG_MASK ((1ULL << 17) - 1) 318f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_I_RCVURG_SHIFT 32 319f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_I_RCVAVAIL_MASK ((1ULL << 17) - 1) 320f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_I_RCVAVAIL_SHIFT 0 321f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_I_SERDESTRIMDONE (1ULL << 27) 322f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 323f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_C_FREEZEMODE 0x00000002 324f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_C_LINKENABLE 0x00000004 325f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 326f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_I_SDMAINT 0x8000000000000000ULL 327f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_I_SDMADISABLED 0x4000000000000000ULL 328f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_I_ERROR 0x0000000080000000ULL 329f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_I_SPIOSENT 0x0000000040000000ULL 330f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_I_SPIOBUFAVAIL 0x0000000020000000ULL 331f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_I_GPIO 0x0000000010000000ULL 332f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 333f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* variables for sanity checking interrupt and errors */ 334f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_I_BITSEXTANT \ 335f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (QLOGIC_IB_I_SDMAINT | QLOGIC_IB_I_SDMADISABLED | \ 336f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (QLOGIC_IB_I_RCVURG_MASK << QLOGIC_IB_I_RCVURG_SHIFT) | \ 337f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (QLOGIC_IB_I_RCVAVAIL_MASK << \ 338f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_I_RCVAVAIL_SHIFT) | \ 339f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_I_ERROR | QLOGIC_IB_I_SPIOSENT | \ 340f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_I_SPIOBUFAVAIL | QLOGIC_IB_I_GPIO | \ 341f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_I_SERDESTRIMDONE) 342f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 343f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IB_HWE_BITSEXTANT \ 344f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (HWE_MASK(RXEMemParityErr) | \ 345f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell HWE_MASK(TXEMemParityErr) | \ 346f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (QLOGIC_IB_HWE_PCIEMEMPARITYERR_MASK << \ 347f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_PCIEMEMPARITYERR_SHIFT) | \ 348f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_PCIE1PLLFAILED | \ 349f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_PCIE0PLLFAILED | \ 350f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_PCIEPOISONEDTLP | \ 351f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_PCIECPLTIMEOUT | \ 352f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_PCIEBUSPARITYXTLH | \ 353f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_PCIEBUSPARITYXADM | \ 354f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_PCIEBUSPARITYRADM | \ 355f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell HWE_MASK(PowerOnBISTFailed) | \ 356f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_COREPLL_FBSLIP | \ 357f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_COREPLL_RFSLIP | \ 358f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_SERDESPLLFAILED | \ 359f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell HWE_MASK(IBCBusToSPCParityErr) | \ 360f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell HWE_MASK(IBCBusFromSPCParityErr) | \ 361f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_PCIECPLDATAQUEUEERR | \ 362f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_PCIECPLHDRQUEUEERR | \ 363f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_SDMAMEMREADERR | \ 364f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_CLK_UC_PLLNOTLOCKED | \ 365f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_PCIESERDESQ0PCLKNOTDETECT | \ 366f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_PCIESERDESQ1PCLKNOTDETECT | \ 367f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_PCIESERDESQ2PCLKNOTDETECT | \ 368f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_PCIESERDESQ3PCLKNOTDETECT | \ 369f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_DDSRXEQMEMORYPARITYERR | \ 370f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_IB_UC_MEMORYPARITYERR | \ 371f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_PCIE_UC_OCT0MEMORYPARITYERR | \ 372f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_PCIE_UC_OCT1MEMORYPARITYERR) 373f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 374f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IB_E_BITSEXTANT \ 375f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (ERR_MASK(RcvFormatErr) | ERR_MASK(RcvVCRCErr) | \ 376f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(RcvICRCErr) | ERR_MASK(RcvMinPktLenErr) | \ 377f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(RcvMaxPktLenErr) | ERR_MASK(RcvLongPktLenErr) | \ 378f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(RcvShortPktLenErr) | ERR_MASK(RcvUnexpectedCharErr) | \ 379f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(RcvUnsupportedVLErr) | ERR_MASK(RcvEBPErr) | \ 380f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(RcvIBFlowErr) | ERR_MASK(RcvBadVersionErr) | \ 381f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(RcvEgrFullErr) | ERR_MASK(RcvHdrFullErr) | \ 382f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(RcvBadTidErr) | ERR_MASK(RcvHdrLenErr) | \ 383f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(RcvHdrErr) | ERR_MASK(RcvIBLostLinkErr) | \ 384f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SendSpecialTriggerErr) | \ 385f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaDisabledErr) | ERR_MASK(SendMinPktLenErr) | \ 386f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SendMaxPktLenErr) | ERR_MASK(SendUnderRunErr) | \ 387f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SendPktLenErr) | ERR_MASK(SendDroppedSmpPktErr) | \ 388f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SendDroppedDataPktErr) | \ 389f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SendPioArmLaunchErr) | \ 390f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SendUnexpectedPktNumErr) | \ 391f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SendUnsupportedVLErr) | ERR_MASK(SendBufMisuseErr) | \ 392f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaGenMismatchErr) | ERR_MASK(SDmaOutOfBoundErr) | \ 393f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaTailOutOfBoundErr) | ERR_MASK(SDmaBaseErr) | \ 394f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDma1stDescErr) | ERR_MASK(SDmaRpyTagErr) | \ 395f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaDwEnErr) | ERR_MASK(SDmaMissingDwErr) | \ 396f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaUnexpDataErr) | \ 397f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(IBStatusChanged) | ERR_MASK(InvalidAddrErr) | \ 398f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(ResetNegated) | ERR_MASK(HardwareErr) | \ 399f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaDescAddrMisalignErr) | \ 400f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(InvalidEEPCmd)) 401f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 402f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* kr_hwerrclear, kr_hwerrmask, kr_hwerrstatus, bits */ 403f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_PCIEMEMPARITYERR_MASK 0x00000000000000ffULL 404f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_PCIEMEMPARITYERR_SHIFT 0 405f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_PCIEPOISONEDTLP 0x0000000010000000ULL 406f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_PCIECPLTIMEOUT 0x0000000020000000ULL 407f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_PCIEBUSPARITYXTLH 0x0000000040000000ULL 408f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_PCIEBUSPARITYXADM 0x0000000080000000ULL 409f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_PCIEBUSPARITYRADM 0x0000000100000000ULL 410f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_COREPLL_FBSLIP 0x0080000000000000ULL 411f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_COREPLL_RFSLIP 0x0100000000000000ULL 412f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_PCIE1PLLFAILED 0x0400000000000000ULL 413f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_PCIE0PLLFAILED 0x0800000000000000ULL 414f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_SERDESPLLFAILED 0x1000000000000000ULL 415f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* specific to this chip */ 416f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_PCIECPLDATAQUEUEERR 0x0000000000000040ULL 417f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_PCIECPLHDRQUEUEERR 0x0000000000000080ULL 418f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_SDMAMEMREADERR 0x0000000010000000ULL 419f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_CLK_UC_PLLNOTLOCKED 0x2000000000000000ULL 420f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_PCIESERDESQ0PCLKNOTDETECT 0x0100000000000000ULL 421f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_PCIESERDESQ1PCLKNOTDETECT 0x0200000000000000ULL 422f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_PCIESERDESQ2PCLKNOTDETECT 0x0400000000000000ULL 423f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_PCIESERDESQ3PCLKNOTDETECT 0x0800000000000000ULL 424f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_DDSRXEQMEMORYPARITYERR 0x0000008000000000ULL 425f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_IB_UC_MEMORYPARITYERR 0x0000004000000000ULL 426f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_PCIE_UC_OCT0MEMORYPARITYERR 0x0000001000000000ULL 427f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_HWE_PCIE_UC_OCT1MEMORYPARITYERR 0x0000002000000000ULL 428f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 429f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_IBCC_LINKCMD_SHIFT 19 430f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 431f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* kr_ibcddrctrl bits */ 432f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_IBC_DLIDLMC_MASK 0xFFFFFFFFUL 433f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_IBC_DLIDLMC_SHIFT 32 434f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 435f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_IBC_HRTBT_MASK (SYM_RMASK(IBCDDRCtrl, HRTBT_AUTO) | \ 436f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_RMASK(IBCDDRCtrl, HRTBT_ENB)) 437f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_IBC_HRTBT_SHIFT SYM_LSB(IBCDDRCtrl, HRTBT_ENB) 438f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 439f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_IBC_LANE_REV_SUPPORTED (1<<8) 440f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_IBC_LREV_MASK 1 441f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_IBC_LREV_SHIFT 8 442f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_IBC_RXPOL_MASK 1 443f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_IBC_RXPOL_SHIFT 7 444f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_IBC_WIDTH_SHIFT 5 445f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_IBC_WIDTH_MASK 0x3 446f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_IBC_WIDTH_1X_ONLY (0 << IBA7220_IBC_WIDTH_SHIFT) 447f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_IBC_WIDTH_4X_ONLY (1 << IBA7220_IBC_WIDTH_SHIFT) 448f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_IBC_WIDTH_AUTONEG (2 << IBA7220_IBC_WIDTH_SHIFT) 449f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_IBC_SPEED_AUTONEG (1 << 1) 450f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_IBC_SPEED_SDR (1 << 2) 451f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_IBC_SPEED_DDR (1 << 3) 452f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_IBC_SPEED_AUTONEG_MASK (0x7 << 1) 453f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_IBC_IBTA_1_2_MASK (1) 454f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 455f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* kr_ibcddrstatus */ 456f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* link latency shift is 0, don't bother defining */ 457f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_DDRSTAT_LINKLAT_MASK 0x3ffffff 458f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 459f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* kr_extstatus bits */ 460f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_EXTS_FREQSEL 0x2 461f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_EXTS_SERDESSEL 0x4 462f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_EXTS_MEMBIST_ENDTEST 0x0000000000004000 463f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_EXTS_MEMBIST_DISABLED 0x0000000000008000 464f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 465f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* kr_xgxsconfig bits */ 466f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_XGXS_RESET 0x5ULL 467f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_XGXS_FC_SAFE (1ULL << 63) 468f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 469f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* kr_rcvpktledcnt */ 470f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_LEDBLINK_ON_SHIFT 32 /* 4ns period on after packet */ 471f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_LEDBLINK_OFF_SHIFT 0 /* 4ns period off before next on */ 472f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 473f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define _QIB_GPIO_SDA_NUM 1 474f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define _QIB_GPIO_SCL_NUM 0 475f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QIB_TWSI_EEPROM_DEV 0xA2 /* All Production 7220 cards. */ 476f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QIB_TWSI_TEMP_DEV 0x98 477f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 478f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* HW counter clock is at 4nsec */ 479f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QIB_7220_PSXMITWAIT_CHECK_RATE 4000 480f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 481f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_R_INTRAVAIL_SHIFT 17 482f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_R_PKEY_DIS_SHIFT 34 483f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_R_TAILUPD_SHIFT 35 484f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_R_CTXTCFG_SHIFT 36 485f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 486f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_HDRHEAD_PKTINT_SHIFT 32 /* interrupt cnt in upper 32 bits */ 487f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 488f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 489f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * the size bits give us 2^N, in KB units. 0 marks as invalid, 490f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * and 7 is reserved. We currently use only 2KB and 4KB 491f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 492f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_TID_SZ_SHIFT 37 /* shift to 3bit size selector */ 493f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_TID_SZ_2K (1UL << IBA7220_TID_SZ_SHIFT) /* 2KB */ 494f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_TID_SZ_4K (2UL << IBA7220_TID_SZ_SHIFT) /* 4KB */ 495f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_TID_PA_SHIFT 11U /* TID addr in chip stored w/o low bits */ 496f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define PBC_7220_VL15_SEND (1ULL << 63) /* pbc; VL15, no credit check */ 497f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define PBC_7220_VL15_SEND_CTRL (1ULL << 31) /* control version of same */ 498f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 499f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define AUTONEG_TRIES 5 /* sequential retries to negotiate DDR */ 500f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 501f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* packet rate matching delay multiplier */ 502f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic u8 rate_to_delay[2][2] = { 503f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1x, 4x */ 504f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell { 8, 2 }, /* SDR */ 505f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell { 4, 1 } /* DDR */ 506f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell}; 507f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 508f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic u8 ib_rate_to_delay[IB_RATE_120_GBPS + 1] = { 509f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [IB_RATE_2_5_GBPS] = 8, 510f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [IB_RATE_5_GBPS] = 4, 511f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [IB_RATE_10_GBPS] = 2, 512f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [IB_RATE_20_GBPS] = 1 513f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell}; 514f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 515f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_LINKSPEED_SHIFT SYM_LSB(IBCStatus, LinkSpeedActive) 516f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBA7220_LINKWIDTH_SHIFT SYM_LSB(IBCStatus, LinkWidthActive) 517f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 518f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* link training states, from IBC */ 519f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IB_7220_LT_STATE_DISABLED 0x00 520f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IB_7220_LT_STATE_LINKUP 0x01 521f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IB_7220_LT_STATE_POLLACTIVE 0x02 522f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IB_7220_LT_STATE_POLLQUIET 0x03 523f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IB_7220_LT_STATE_SLEEPDELAY 0x04 524f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IB_7220_LT_STATE_SLEEPQUIET 0x05 525f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IB_7220_LT_STATE_CFGDEBOUNCE 0x08 526f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IB_7220_LT_STATE_CFGRCVFCFG 0x09 527f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IB_7220_LT_STATE_CFGWAITRMT 0x0a 528f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IB_7220_LT_STATE_CFGIDLE 0x0b 529f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IB_7220_LT_STATE_RECOVERRETRAIN 0x0c 530f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IB_7220_LT_STATE_RECOVERWAITRMT 0x0e 531f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IB_7220_LT_STATE_RECOVERIDLE 0x0f 532f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 533f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* link state machine states from IBC */ 534f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IB_7220_L_STATE_DOWN 0x0 535f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IB_7220_L_STATE_INIT 0x1 536f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IB_7220_L_STATE_ARM 0x2 537f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IB_7220_L_STATE_ACTIVE 0x3 538f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IB_7220_L_STATE_ACT_DEFER 0x4 539f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 540f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic const u8 qib_7220_physportstate[0x20] = { 541f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [IB_7220_LT_STATE_DISABLED] = IB_PHYSPORTSTATE_DISABLED, 542f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [IB_7220_LT_STATE_LINKUP] = IB_PHYSPORTSTATE_LINKUP, 543f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [IB_7220_LT_STATE_POLLACTIVE] = IB_PHYSPORTSTATE_POLL, 544f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [IB_7220_LT_STATE_POLLQUIET] = IB_PHYSPORTSTATE_POLL, 545f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [IB_7220_LT_STATE_SLEEPDELAY] = IB_PHYSPORTSTATE_SLEEP, 546f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [IB_7220_LT_STATE_SLEEPQUIET] = IB_PHYSPORTSTATE_SLEEP, 547f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [IB_7220_LT_STATE_CFGDEBOUNCE] = 548f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IB_PHYSPORTSTATE_CFG_TRAIN, 549f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [IB_7220_LT_STATE_CFGRCVFCFG] = 550f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IB_PHYSPORTSTATE_CFG_TRAIN, 551f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [IB_7220_LT_STATE_CFGWAITRMT] = 552f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IB_PHYSPORTSTATE_CFG_TRAIN, 553f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [IB_7220_LT_STATE_CFGIDLE] = IB_PHYSPORTSTATE_CFG_TRAIN, 554f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [IB_7220_LT_STATE_RECOVERRETRAIN] = 555f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IB_PHYSPORTSTATE_LINK_ERR_RECOVER, 556f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [IB_7220_LT_STATE_RECOVERWAITRMT] = 557f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IB_PHYSPORTSTATE_LINK_ERR_RECOVER, 558f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [IB_7220_LT_STATE_RECOVERIDLE] = 559f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IB_PHYSPORTSTATE_LINK_ERR_RECOVER, 560f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [0x10] = IB_PHYSPORTSTATE_CFG_TRAIN, 561f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [0x11] = IB_PHYSPORTSTATE_CFG_TRAIN, 562f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [0x12] = IB_PHYSPORTSTATE_CFG_TRAIN, 563f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [0x13] = IB_PHYSPORTSTATE_CFG_TRAIN, 564f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [0x14] = IB_PHYSPORTSTATE_CFG_TRAIN, 565f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [0x15] = IB_PHYSPORTSTATE_CFG_TRAIN, 566f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [0x16] = IB_PHYSPORTSTATE_CFG_TRAIN, 567f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [0x17] = IB_PHYSPORTSTATE_CFG_TRAIN 568f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell}; 569f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 570f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellint qib_special_trigger; 571f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellmodule_param_named(special_trigger, qib_special_trigger, int, S_IRUGO); 572f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph CampbellMODULE_PARM_DESC(special_trigger, "Enable SpecialTrigger arm/launch"); 573f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 574f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBCBUSFRSPCPARITYERR HWE_MASK(IBCBusFromSPCParityErr) 575f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define IBCBUSTOSPCPARITYERR HWE_MASK(IBCBusToSPCParityErr) 576f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 577f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define SYM_MASK_BIT(regname, fldname, bit) ((u64) \ 578f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (1ULL << (SYM_LSB(regname, fldname) + (bit)))) 579f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 580f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define TXEMEMPARITYERR_PIOBUF \ 581f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK_BIT(HwErrMask, TXEMemParityErrMask, 0) 582f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define TXEMEMPARITYERR_PIOPBC \ 583f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK_BIT(HwErrMask, TXEMemParityErrMask, 1) 584f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define TXEMEMPARITYERR_PIOLAUNCHFIFO \ 585f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK_BIT(HwErrMask, TXEMemParityErrMask, 2) 586f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 587f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define RXEMEMPARITYERR_RCVBUF \ 588f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 0) 589f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define RXEMEMPARITYERR_LOOKUPQ \ 590f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 1) 591f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define RXEMEMPARITYERR_EXPTID \ 592f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 2) 593f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define RXEMEMPARITYERR_EAGERTID \ 594f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 3) 595f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define RXEMEMPARITYERR_FLAGBUF \ 596f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 4) 597f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define RXEMEMPARITYERR_DATAINFO \ 598f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 5) 599f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define RXEMEMPARITYERR_HDRINFO \ 600f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 6) 601f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 602f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 7220 specific hardware errors... */ 603f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic const struct qib_hwerror_msgs qib_7220_hwerror_msgs[] = { 604f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* generic hardware errors */ 605f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(IBCBUSFRSPCPARITYERR, "QIB2IB Parity"), 606f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(IBCBUSTOSPCPARITYERR, "IB2QIB Parity"), 607f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 608f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(TXEMEMPARITYERR_PIOBUF, 609f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "TXE PIOBUF Memory Parity"), 610f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(TXEMEMPARITYERR_PIOPBC, 611f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "TXE PIOPBC Memory Parity"), 612f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(TXEMEMPARITYERR_PIOLAUNCHFIFO, 613f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "TXE PIOLAUNCHFIFO Memory Parity"), 614f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 615f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_RCVBUF, 616f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RXE RCVBUF Memory Parity"), 617f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_LOOKUPQ, 618f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RXE LOOKUPQ Memory Parity"), 619f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_EAGERTID, 620f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RXE EAGERTID Memory Parity"), 621f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_EXPTID, 622f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RXE EXPTID Memory Parity"), 623f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_FLAGBUF, 624f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RXE FLAGBUF Memory Parity"), 625f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_DATAINFO, 626f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RXE DATAINFO Memory Parity"), 627f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_HDRINFO, 628f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RXE HDRINFO Memory Parity"), 629f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 630f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* chip-specific hardware errors */ 631f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIEPOISONEDTLP, 632f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "PCIe Poisoned TLP"), 633f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIECPLTIMEOUT, 634f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "PCIe completion timeout"), 635f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 636f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * In practice, it's unlikely wthat we'll see PCIe PLL, or bus 637f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * parity or memory parity error failures, because most likely we 638f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * won't be able to talk to the core of the chip. Nonetheless, we 639f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * might see them, if they are in parts of the PCIe core that aren't 640f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * essential. 641f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 642f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIE1PLLFAILED, 643f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "PCIePLL1"), 644f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIE0PLLFAILED, 645f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "PCIePLL0"), 646f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIEBUSPARITYXTLH, 647f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "PCIe XTLH core parity"), 648f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIEBUSPARITYXADM, 649f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "PCIe ADM TX core parity"), 650f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIEBUSPARITYRADM, 651f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "PCIe ADM RX core parity"), 652f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_SERDESPLLFAILED, 653f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "SerDes PLL"), 654f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIECPLDATAQUEUEERR, 655f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "PCIe cpl header queue"), 656f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIECPLHDRQUEUEERR, 657f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "PCIe cpl data queue"), 658f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_SDMAMEMREADERR, 659f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "Send DMA memory read"), 660f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_CLK_UC_PLLNOTLOCKED, 661f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "uC PLL clock not locked"), 662f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIESERDESQ0PCLKNOTDETECT, 663f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "PCIe serdes Q0 no clock"), 664f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIESERDESQ1PCLKNOTDETECT, 665f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "PCIe serdes Q1 no clock"), 666f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIESERDESQ2PCLKNOTDETECT, 667f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "PCIe serdes Q2 no clock"), 668f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIESERDESQ3PCLKNOTDETECT, 669f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "PCIe serdes Q3 no clock"), 670f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_DDSRXEQMEMORYPARITYERR, 671f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "DDS RXEQ memory parity"), 672f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_IB_UC_MEMORYPARITYERR, 673f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "IB uC memory parity"), 674f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIE_UC_OCT0MEMORYPARITYERR, 675f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "PCIe uC oct0 memory parity"), 676f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIE_UC_OCT1MEMORYPARITYERR, 677f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "PCIe uC oct1 memory parity"), 678f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell}; 679f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 680f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define RXE_PARITY (RXEMEMPARITYERR_EAGERTID|RXEMEMPARITYERR_EXPTID) 681f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 682f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_E_PKTERRS (\ 683f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SendPktLenErr) | \ 684f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SendDroppedDataPktErr) | \ 685f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(RcvVCRCErr) | \ 686f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(RcvICRCErr) | \ 687f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(RcvShortPktLenErr) | \ 688f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(RcvEBPErr)) 689f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 690f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* Convenience for decoding Send DMA errors */ 691f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define QLOGIC_IB_E_SDMAERRS ( \ 692f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaGenMismatchErr) | \ 693f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaOutOfBoundErr) | \ 694f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaTailOutOfBoundErr) | ERR_MASK(SDmaBaseErr) | \ 695f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDma1stDescErr) | ERR_MASK(SDmaRpyTagErr) | \ 696f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaDwEnErr) | ERR_MASK(SDmaMissingDwErr) | \ 697f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaUnexpDataErr) | \ 698f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaDescAddrMisalignErr) | \ 699f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaDisabledErr) | \ 700f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SendBufMisuseErr)) 701f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 702f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* These are all rcv-related errors which we want to count for stats */ 703f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define E_SUM_PKTERRS \ 704f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (ERR_MASK(RcvHdrLenErr) | ERR_MASK(RcvBadTidErr) | \ 705f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(RcvBadVersionErr) | ERR_MASK(RcvHdrErr) | \ 706f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(RcvLongPktLenErr) | ERR_MASK(RcvShortPktLenErr) | \ 707f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(RcvMaxPktLenErr) | ERR_MASK(RcvMinPktLenErr) | \ 708f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(RcvFormatErr) | ERR_MASK(RcvUnsupportedVLErr) | \ 709f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(RcvUnexpectedCharErr) | ERR_MASK(RcvEBPErr)) 710f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 711f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* These are all send-related errors which we want to count for stats */ 712f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define E_SUM_ERRS \ 713f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (ERR_MASK(SendPioArmLaunchErr) | ERR_MASK(SendUnexpectedPktNumErr) | \ 714f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SendDroppedDataPktErr) | ERR_MASK(SendDroppedSmpPktErr) | \ 715f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SendMaxPktLenErr) | ERR_MASK(SendUnsupportedVLErr) | \ 716f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SendMinPktLenErr) | ERR_MASK(SendPktLenErr) | \ 717f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(InvalidAddrErr)) 718f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 719f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 720f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * this is similar to E_SUM_ERRS, but can't ignore armlaunch, don't ignore 721f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * errors not related to freeze and cancelling buffers. Can't ignore 722f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * armlaunch because could get more while still cleaning up, and need 723f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * to cancel those as they happen. 724f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 725f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define E_SPKT_ERRS_IGNORE \ 726f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (ERR_MASK(SendDroppedDataPktErr) | ERR_MASK(SendDroppedSmpPktErr) | \ 727f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SendMaxPktLenErr) | ERR_MASK(SendMinPktLenErr) | \ 728f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SendPktLenErr)) 729f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 730f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 731f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * these are errors that can occur when the link changes state while 732f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * a packet is being sent or received. This doesn't cover things 733f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * like EBP or VCRC that can be the result of a sending having the 734f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * link change state, so we receive a "known bad" packet. 735f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 736f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define E_SUM_LINK_PKTERRS \ 737f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (ERR_MASK(SendDroppedDataPktErr) | ERR_MASK(SendDroppedSmpPktErr) | \ 738f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SendMinPktLenErr) | ERR_MASK(SendPktLenErr) | \ 739f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(RcvShortPktLenErr) | ERR_MASK(RcvMinPktLenErr) | \ 740f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(RcvUnexpectedCharErr)) 741f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 742f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void autoneg_7220_work(struct work_struct *); 743f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic u32 __iomem *qib_7220_getsendbuf(struct qib_pportdata *, u64, u32 *); 744f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 745f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 746f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Called when we might have an error that is specific to a particular 747f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * PIO buffer, and may need to cancel that buffer, so it can be re-used. 748f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * because we don't need to force the update of pioavail. 749f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 750f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_disarm_7220_senderrbufs(struct qib_pportdata *ppd) 751f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 752f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long sbuf[3]; 753f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = ppd->dd; 754f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 755f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 756f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * It's possible that sendbuffererror could have bits set; might 757f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * have already done this as a result of hardware error handling. 758f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 759f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* read these before writing errorclear */ 760f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sbuf[0] = qib_read_kreg64(dd, kr_sendbuffererror); 761f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sbuf[1] = qib_read_kreg64(dd, kr_sendbuffererror + 1); 762f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sbuf[2] = qib_read_kreg64(dd, kr_sendbuffererror + 2); 763f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 764f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (sbuf[0] || sbuf[1] || sbuf[2]) 765f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_disarm_piobufs_set(dd, sbuf, 766f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->piobcnt2k + dd->piobcnt4k); 767f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 768f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 769f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_txe_recover(struct qib_devdata *dd) 770f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 771f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_devinfo(dd->pcidev, "Recovering from TXE PIO parity error\n"); 772f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_disarm_7220_senderrbufs(dd->pport); 773f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 774f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 775f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 776f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * This is called with interrupts disabled and sdma_lock held. 777f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 778f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_sdma_sendctrl(struct qib_pportdata *ppd, unsigned op) 779f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 780f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = ppd->dd; 781f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 set_sendctrl = 0; 782f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 clr_sendctrl = 0; 783f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 784f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_SDMA_SENDCTRL_OP_ENABLE) 785f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell set_sendctrl |= SYM_MASK(SendCtrl, SDmaEnable); 786f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else 787f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell clr_sendctrl |= SYM_MASK(SendCtrl, SDmaEnable); 788f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 789f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_SDMA_SENDCTRL_OP_INTENABLE) 790f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell set_sendctrl |= SYM_MASK(SendCtrl, SDmaIntEnable); 791f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else 792f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell clr_sendctrl |= SYM_MASK(SendCtrl, SDmaIntEnable); 793f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 794f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_SDMA_SENDCTRL_OP_HALT) 795f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell set_sendctrl |= SYM_MASK(SendCtrl, SDmaHalt); 796f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else 797f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell clr_sendctrl |= SYM_MASK(SendCtrl, SDmaHalt); 798f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 799f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock(&dd->sendctrl_lock); 800f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 801f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->sendctrl |= set_sendctrl; 802f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->sendctrl &= ~clr_sendctrl; 803f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 804f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_sendctrl, dd->sendctrl); 805f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_scratch, 0); 806f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 807f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock(&dd->sendctrl_lock); 808f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 809f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 810f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_decode_7220_sdma_errs(struct qib_pportdata *ppd, 811f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 err, char *buf, size_t blen) 812f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 813f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell static const struct { 814f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 err; 815f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell const char *msg; 816f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } errs[] = { 817f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell { ERR_MASK(SDmaGenMismatchErr), 818f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "SDmaGenMismatch" }, 819f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell { ERR_MASK(SDmaOutOfBoundErr), 820f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "SDmaOutOfBound" }, 821f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell { ERR_MASK(SDmaTailOutOfBoundErr), 822f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "SDmaTailOutOfBound" }, 823f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell { ERR_MASK(SDmaBaseErr), 824f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "SDmaBase" }, 825f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell { ERR_MASK(SDma1stDescErr), 826f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "SDma1stDesc" }, 827f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell { ERR_MASK(SDmaRpyTagErr), 828f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "SDmaRpyTag" }, 829f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell { ERR_MASK(SDmaDwEnErr), 830f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "SDmaDwEn" }, 831f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell { ERR_MASK(SDmaMissingDwErr), 832f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "SDmaMissingDw" }, 833f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell { ERR_MASK(SDmaUnexpDataErr), 834f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "SDmaUnexpData" }, 835f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell { ERR_MASK(SDmaDescAddrMisalignErr), 836f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "SDmaDescAddrMisalign" }, 837f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell { ERR_MASK(SendBufMisuseErr), 838f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "SendBufMisuse" }, 839f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell { ERR_MASK(SDmaDisabledErr), 840f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "SDmaDisabled" }, 841f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell }; 842f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int i; 843f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell size_t bidx = 0; 844f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 845f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (i = 0; i < ARRAY_SIZE(errs); i++) { 846f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & errs[i].err) 847f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell bidx += scnprintf(buf + bidx, blen - bidx, 848f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "%s ", errs[i].msg); 849f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 850f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 851f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 852f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 853f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * This is called as part of link down clean up so disarm and flush 854f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * all send buffers so that SMP packets can be sent. 855f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 856f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_sdma_hw_clean_up(struct qib_pportdata *ppd) 857f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 858f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* This will trigger the Abort interrupt */ 859f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sendctrl_7220_mod(ppd, QIB_SENDCTRL_DISARM_ALL | QIB_SENDCTRL_FLUSH | 860f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIB_SENDCTRL_AVAIL_BLIP); 861f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->dd->upd_pio_shadow = 1; /* update our idea of what's busy */ 862f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 863f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 864f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_sdma_7220_setlengen(struct qib_pportdata *ppd) 865f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 866f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 867f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Set SendDmaLenGen and clear and set 868f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * the MSB of the generation count to enable generation checking 869f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * and load the internal generation counter. 870f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 871f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(ppd->dd, kr_senddmalengen, ppd->sdma_descq_cnt); 872f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(ppd->dd, kr_senddmalengen, 873f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->sdma_descq_cnt | 874f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (1ULL << QIB_7220_SendDmaLenGen_Generation_MSB)); 875f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 876f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 877f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_sdma_hw_start_up(struct qib_pportdata *ppd) 878f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 879f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_sdma_7220_setlengen(ppd); 880f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_sdma_update_7220_tail(ppd, 0); /* Set SendDmaTail */ 881f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->sdma_head_dma[0] = 0; 882f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 883f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 884f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define DISABLES_SDMA ( \ 885f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaDisabledErr) | \ 886f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaBaseErr) | \ 887f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaTailOutOfBoundErr) | \ 888f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaOutOfBoundErr) | \ 889f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDma1stDescErr) | \ 890f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaRpyTagErr) | \ 891f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaGenMismatchErr) | \ 892f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaDescAddrMisalignErr) | \ 893f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaMissingDwErr) | \ 894f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaDwEnErr)) 895f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 896f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void sdma_7220_errors(struct qib_pportdata *ppd, u64 errs) 897f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 898f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 899f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = ppd->dd; 900f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell char *msg; 901f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 902f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell errs &= QLOGIC_IB_E_SDMAERRS; 903f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 904f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell msg = dd->cspec->sdmamsgbuf; 905f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_decode_7220_sdma_errs(ppd, errs, msg, sizeof dd->cspec->sdmamsgbuf); 906f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->sdma_lock, flags); 907f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 908f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (errs & ERR_MASK(SendBufMisuseErr)) { 909f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long sbuf[3]; 910f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 911f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sbuf[0] = qib_read_kreg64(dd, kr_sendbuffererror); 912f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sbuf[1] = qib_read_kreg64(dd, kr_sendbuffererror + 1); 913f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sbuf[2] = qib_read_kreg64(dd, kr_sendbuffererror + 2); 914f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 915f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_dev_err(ppd->dd, 916f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "IB%u:%u SendBufMisuse: %04lx %016lx %016lx\n", 917f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->dd->unit, ppd->port, sbuf[2], sbuf[1], 918f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sbuf[0]); 919f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 920f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 921f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (errs & ERR_MASK(SDmaUnexpDataErr)) 922f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_dev_err(dd, "IB%u:%u SDmaUnexpData\n", ppd->dd->unit, 923f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->port); 924f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 925f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell switch (ppd->sdma_state.current_state) { 926f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case qib_sdma_state_s00_hw_down: 927f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* not expecting any interrupts */ 928f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 929f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 930f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case qib_sdma_state_s10_hw_start_up_wait: 931f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* handled in intr path */ 932f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 933f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 934f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case qib_sdma_state_s20_idle: 935f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* not expecting any interrupts */ 936f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 937f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 938f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case qib_sdma_state_s30_sw_clean_up_wait: 939f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* not expecting any interrupts */ 940f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 941f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 942f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case qib_sdma_state_s40_hw_clean_up_wait: 943f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (errs & ERR_MASK(SDmaDisabledErr)) 944f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell __qib_sdma_process_event(ppd, 945f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_sdma_event_e50_hw_cleaned); 946f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 947f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 948f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case qib_sdma_state_s50_hw_halt_wait: 949f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* handled in intr path */ 950f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 951f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 952f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case qib_sdma_state_s99_running: 953f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (errs & DISABLES_SDMA) 954f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell __qib_sdma_process_event(ppd, 955f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_sdma_event_e7220_err_halted); 956f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 957f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 958f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 959f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->sdma_lock, flags); 960f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 961f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 962f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 963f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Decode the error status into strings, deciding whether to always 964f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * print * it or not depending on "normal packet errors" vs everything 965f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * else. Return 1 if "real" errors, otherwise 0 if only packet 966f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * errors, so caller can decide what to print with the string. 967f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 968f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic int qib_decode_7220_err(struct qib_devdata *dd, char *buf, size_t blen, 969f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 err) 970f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 971f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int iserr = 1; 972f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 973f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell *buf = '\0'; 974f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & QLOGIC_IB_E_PKTERRS) { 975f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!(err & ~QLOGIC_IB_E_PKTERRS)) 976f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell iserr = 0; 977f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if ((err & ERR_MASK(RcvICRCErr)) && 978f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell !(err & (ERR_MASK(RcvVCRCErr) | ERR_MASK(RcvEBPErr)))) 979f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "CRC ", blen); 980f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!iserr) 981f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 982f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 983f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(RcvHdrLenErr)) 984f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "rhdrlen ", blen); 985f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(RcvBadTidErr)) 986f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "rbadtid ", blen); 987f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(RcvBadVersionErr)) 988f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "rbadversion ", blen); 989f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(RcvHdrErr)) 990f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "rhdr ", blen); 991f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(SendSpecialTriggerErr)) 992f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "sendspecialtrigger ", blen); 993f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(RcvLongPktLenErr)) 994f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "rlongpktlen ", blen); 995f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(RcvMaxPktLenErr)) 996f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "rmaxpktlen ", blen); 997f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(RcvMinPktLenErr)) 998f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "rminpktlen ", blen); 999f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(SendMinPktLenErr)) 1000f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "sminpktlen ", blen); 1001f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(RcvFormatErr)) 1002f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "rformaterr ", blen); 1003f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(RcvUnsupportedVLErr)) 1004f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "runsupvl ", blen); 1005f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(RcvUnexpectedCharErr)) 1006f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "runexpchar ", blen); 1007f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(RcvIBFlowErr)) 1008f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "ribflow ", blen); 1009f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(SendUnderRunErr)) 1010f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "sunderrun ", blen); 1011f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(SendPioArmLaunchErr)) 1012f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "spioarmlaunch ", blen); 1013f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(SendUnexpectedPktNumErr)) 1014f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "sunexperrpktnum ", blen); 1015f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(SendDroppedSmpPktErr)) 1016f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "sdroppedsmppkt ", blen); 1017f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(SendMaxPktLenErr)) 1018f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "smaxpktlen ", blen); 1019f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(SendUnsupportedVLErr)) 1020f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "sunsupVL ", blen); 1021f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(InvalidAddrErr)) 1022f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "invalidaddr ", blen); 1023f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(RcvEgrFullErr)) 1024f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "rcvegrfull ", blen); 1025f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(RcvHdrFullErr)) 1026f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "rcvhdrfull ", blen); 1027f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(IBStatusChanged)) 1028f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "ibcstatuschg ", blen); 1029f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(RcvIBLostLinkErr)) 1030f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "riblostlink ", blen); 1031f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(HardwareErr)) 1032f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "hardware ", blen); 1033f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(ResetNegated)) 1034f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "reset ", blen); 1035f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & QLOGIC_IB_E_SDMAERRS) 1036f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_decode_7220_sdma_errs(dd->pport, err, buf, blen); 1037f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (err & ERR_MASK(InvalidEEPCmd)) 1038f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(buf, "invalideepromcmd ", blen); 1039f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbelldone: 1040f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return iserr; 1041f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 1042f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1043f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void reenable_7220_chase(unsigned long opaque) 1044f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 1045f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_pportdata *ppd = (struct qib_pportdata *)opaque; 1046f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->chase_timer.expires = 0; 1047f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_set_ib_7220_lstate(ppd, QLOGIC_IB_IBCC_LINKCMD_DOWN, 1048f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_IBCC_LINKINITCMD_POLL); 1049f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 1050f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1051f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void handle_7220_chase(struct qib_pportdata *ppd, u64 ibcst) 1052f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 1053f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u8 ibclt; 10548482d5d1bc18c17429a89ad37f8b74d5a16de239Mike Marciniszyn unsigned long tnow; 1055f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1056f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ibclt = (u8)SYM_FIELD(ibcst, IBCStatus, LinkTrainingState); 1057f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1058f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1059f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Detect and handle the state chase issue, where we can 1060f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * get stuck if we are unlucky on timing on both sides of 1061f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * the link. If we are, we disable, set a timer, and 1062f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * then re-enable. 1063f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1064f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell switch (ibclt) { 1065f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case IB_7220_LT_STATE_CFGRCVFCFG: 1066f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case IB_7220_LT_STATE_CFGWAITRMT: 1067f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case IB_7220_LT_STATE_TXREVLANES: 1068f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case IB_7220_LT_STATE_CFGENH: 10698482d5d1bc18c17429a89ad37f8b74d5a16de239Mike Marciniszyn tnow = jiffies; 1070f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->cpspec->chase_end && 10718482d5d1bc18c17429a89ad37f8b74d5a16de239Mike Marciniszyn time_after(tnow, ppd->cpspec->chase_end)) { 1072f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->chase_end = 0; 1073f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_set_ib_7220_lstate(ppd, 1074f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_IBCC_LINKCMD_DOWN, 1075f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_IBCC_LINKINITCMD_DISABLE); 1076f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->chase_timer.expires = jiffies + 1077f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIB_CHASE_DIS_TIME; 1078f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell add_timer(&ppd->cpspec->chase_timer); 1079f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else if (!ppd->cpspec->chase_end) 1080f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->chase_end = tnow + QIB_CHASE_TIME; 1081f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 1082f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1083f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell default: 1084f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->chase_end = 0; 1085f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 1086f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1087f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 1088f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1089f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void handle_7220_errors(struct qib_devdata *dd, u64 errs) 1090f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 1091f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell char *msg; 1092f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 ignore_this_time = 0; 1093f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 iserr = 0; 1094f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int log_idx; 1095f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_pportdata *ppd = dd->pport; 1096f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 mask; 1097f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1098f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* don't report errors that are masked */ 1099f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell errs &= dd->cspec->errormask; 1100f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell msg = dd->cspec->emsgbuf; 1101f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1102f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* do these first, they are most important */ 1103f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (errs & ERR_MASK(HardwareErr)) 1104f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_7220_handle_hwerrors(dd, msg, sizeof dd->cspec->emsgbuf); 1105f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else 1106f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (log_idx = 0; log_idx < QIB_EEP_LOG_CNT; ++log_idx) 1107f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (errs & dd->eep_st_masks[log_idx].errs_to_log) 1108f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_inc_eeprom_err(dd, log_idx, 1); 1109f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1110f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (errs & QLOGIC_IB_E_SDMAERRS) 1111f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sdma_7220_errors(ppd, errs); 1112f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1113f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (errs & ~IB_E_BITSEXTANT) 11147fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn qib_dev_err(dd, 11157fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn "error interrupt with unknown errors %llx set\n", 11167fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn (unsigned long long) (errs & ~IB_E_BITSEXTANT)); 1117f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1118f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (errs & E_SUM_ERRS) { 1119f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_disarm_7220_senderrbufs(ppd); 1120f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if ((errs & E_SUM_LINK_PKTERRS) && 1121f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell !(ppd->lflags & QIBL_LINKACTIVE)) { 1122f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1123f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * This can happen when trying to bring the link 1124f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * up, but the IB link changes state at the "wrong" 1125f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * time. The IB logic then complains that the packet 1126f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * isn't valid. We don't want to confuse people, so 1127f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * we just don't print them, except at debug 1128f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1129f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ignore_this_time = errs & E_SUM_LINK_PKTERRS; 1130f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1131f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else if ((errs & E_SUM_LINK_PKTERRS) && 1132f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell !(ppd->lflags & QIBL_LINKACTIVE)) { 1133f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1134f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * This can happen when SMA is trying to bring the link 1135f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * up, but the IB link changes state at the "wrong" time. 1136f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * The IB logic then complains that the packet isn't 1137f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * valid. We don't want to confuse people, so we just 1138f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * don't print them, except at debug 1139f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1140f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ignore_this_time = errs & E_SUM_LINK_PKTERRS; 1141f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1142f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1143f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_errclear, errs); 1144f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1145f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell errs &= ~ignore_this_time; 1146f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!errs) 1147f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 1148f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1149f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1150f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * The ones we mask off are handled specially below 1151f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * or above. Also mask SDMADISABLED by default as it 1152f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * is too chatty. 1153f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1154f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell mask = ERR_MASK(IBStatusChanged) | 1155f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(RcvEgrFullErr) | ERR_MASK(RcvHdrFullErr) | 1156f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(HardwareErr) | ERR_MASK(SDmaDisabledErr); 1157f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1158f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_decode_7220_err(dd, msg, sizeof dd->cspec->emsgbuf, errs & ~mask); 1159f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1160f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (errs & E_SUM_PKTERRS) 1161f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_stats.sps_rcverrs++; 1162f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (errs & E_SUM_ERRS) 1163f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_stats.sps_txerrs++; 1164f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell iserr = errs & ~(E_SUM_PKTERRS | QLOGIC_IB_E_PKTERRS | 1165f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ERR_MASK(SDmaDisabledErr)); 1166f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1167f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (errs & ERR_MASK(IBStatusChanged)) { 1168f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 ibcs; 1169f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1170f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ibcs = qib_read_kreg64(dd, kr_ibcstatus); 1171f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) 1172f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell handle_7220_chase(ppd, ibcs); 1173f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1174f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* Update our picture of width and speed from chip */ 1175f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->link_width_active = 1176f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ((ibcs >> IBA7220_LINKWIDTH_SHIFT) & 1) ? 1177f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IB_WIDTH_4X : IB_WIDTH_1X; 1178f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->link_speed_active = 1179f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ((ibcs >> IBA7220_LINKSPEED_SHIFT) & 1) ? 1180f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIB_IB_DDR : QIB_IB_SDR; 1181f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1182f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1183f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Since going into a recovery state causes the link state 1184f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * to go down and since recovery is transitory, it is better 1185f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * if we "miss" ever seeing the link training state go into 1186f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * recovery (i.e., ignore this transition for link state 1187f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * special handling purposes) without updating lastibcstat. 1188f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1189f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (qib_7220_phys_portstate(ibcs) != 1190f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IB_PHYSPORTSTATE_LINK_ERR_RECOVER) 1191f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_handle_e_ibstatuschanged(ppd, ibcs); 1192f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1193f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1194f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (errs & ERR_MASK(ResetNegated)) { 11957fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn qib_dev_err(dd, 11967fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn "Got reset, requires re-init (unload and reload driver)\n"); 1197f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->flags &= ~QIB_INITTED; /* needs re-init */ 1198f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* mark as having had error */ 1199f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell *dd->devstatusp |= QIB_STATUS_HWERROR; 1200f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell *dd->pport->statusp &= ~QIB_STATUS_IB_CONF; 1201f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1202f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1203f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (*msg && iserr) 1204f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_dev_porterr(dd, ppd->port, "%s error\n", msg); 1205f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1206f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->state_wanted & ppd->lflags) 1207f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell wake_up_interruptible(&ppd->state_wait); 1208f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1209f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1210f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * If there were hdrq or egrfull errors, wake up any processes 1211f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * waiting in poll. We used to try to check which contexts had 1212f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * the overflow, but given the cost of that and the chip reads 1213f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * to support it, it's better to just wake everybody up if we 1214f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * get an overflow; waiters can poll again if it's not them. 1215f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1216f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (errs & (ERR_MASK(RcvEgrFullErr) | ERR_MASK(RcvHdrFullErr))) { 1217f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_handle_urcv(dd, ~0U); 1218f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (errs & ERR_MASK(RcvEgrFullErr)) 1219f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_stats.sps_buffull++; 1220f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else 1221f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_stats.sps_hdrfull++; 1222f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1223f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbelldone: 1224f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return; 1225f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 1226f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1227f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* enable/disable chip from delivering interrupts */ 1228f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_set_intr_state(struct qib_devdata *dd, u32 enable) 1229f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 1230f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (enable) { 1231f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->flags & QIB_BADINTR) 1232f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return; 1233f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_intmask, ~0ULL); 1234f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* force re-interrupt of any pending interrupts. */ 1235f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_intclear, 0ULL); 1236f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else 1237f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_intmask, 0ULL); 1238f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 1239f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1240f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 1241f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Try to cleanup as much as possible for anything that might have gone 1242f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * wrong while in freeze mode, such as pio buffers being written by user 1243f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * processes (causing armlaunch), send errors due to going into freeze mode, 1244f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * etc., and try to avoid causing extra interrupts while doing so. 1245f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Forcibly update the in-memory pioavail register copies after cleanup 1246f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * because the chip won't do it while in freeze mode (the register values 1247f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * themselves are kept correct). 1248f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Make sure that we don't lose any important interrupts by using the chip 1249f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * feature that says that writing 0 to a bit in *clear that is set in 1250f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * *status will cause an interrupt to be generated again (if allowed by 1251f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * the *mask value). 1252f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * This is in chip-specific code because of all of the register accesses, 1253f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * even though the details are similar on most chips. 1254f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1255f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_clear_freeze(struct qib_devdata *dd) 1256f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 1257f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* disable error interrupts, to avoid confusion */ 1258f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_errmask, 0ULL); 1259f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1260f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* also disable interrupts; errormask is sometimes overwriten */ 1261f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_7220_set_intr_state(dd, 0); 1262f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1263f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_cancel_sends(dd->pport); 1264f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1265f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* clear the freeze, and be sure chip saw it */ 1266f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_control, dd->control); 1267f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_read_kreg32(dd, kr_scratch); 1268f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1269f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* force in-memory update now we are out of freeze */ 1270f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_force_pio_avail_update(dd); 1271f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1272f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1273f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * force new interrupt if any hwerr, error or interrupt bits are 1274f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * still set, and clear "safe" send packet errors related to freeze 1275f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * and cancelling sends. Re-enable error interrupts before possible 1276f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * force of re-interrupt on pending interrupts. 1277f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1278f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_hwerrclear, 0ULL); 1279f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_errclear, E_SPKT_ERRS_IGNORE); 1280f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_errmask, dd->cspec->errormask); 1281f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_7220_set_intr_state(dd, 1); 1282f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 1283f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1284f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/** 1285f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_7220_handle_hwerrors - display hardware errors. 1286f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @dd: the qlogic_ib device 1287f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @msg: the output buffer 1288f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @msgl: the size of the output buffer 1289f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 1290f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Use same msg buffer as regular errors to avoid excessive stack 1291f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * use. Most hardware errors are catastrophic, but for right now, 1292f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * we'll print them and continue. We reuse the same message buffer as 1293f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * handle_7220_errors() to avoid excessive stack usage. 1294f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1295f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_handle_hwerrors(struct qib_devdata *dd, char *msg, 1296f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell size_t msgl) 1297f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 1298f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 hwerrs; 1299f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 bits, ctrl; 1300f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int isfatal = 0; 1301f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell char *bitsmsg; 1302f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int log_idx; 1303f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1304f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell hwerrs = qib_read_kreg64(dd, kr_hwerrstatus); 1305f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!hwerrs) 1306f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 1307f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (hwerrs == ~0ULL) { 13087fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn qib_dev_err(dd, 13097fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn "Read of hardware error status failed (all bits set); ignoring\n"); 1310f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 1311f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1312f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_stats.sps_hwerrs++; 1313f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1314f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1315f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Always clear the error status register, except MEMBISTFAIL, 1316f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * regardless of whether we continue or stop using the chip. 1317f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * We want that set so we know it failed, even across driver reload. 1318f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * We'll still ignore it in the hwerrmask. We do this partly for 1319f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * diagnostics, but also for support. 1320f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1321f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_hwerrclear, 1322f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell hwerrs & ~HWE_MASK(PowerOnBISTFailed)); 1323f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1324f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell hwerrs &= dd->cspec->hwerrmask; 1325f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1326f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* We log some errors to EEPROM, check if we have any of those. */ 1327f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (log_idx = 0; log_idx < QIB_EEP_LOG_CNT; ++log_idx) 1328f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (hwerrs & dd->eep_st_masks[log_idx].hwerrs_to_log) 1329f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_inc_eeprom_err(dd, log_idx, 1); 1330f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (hwerrs & ~(TXEMEMPARITYERR_PIOBUF | TXEMEMPARITYERR_PIOPBC | 1331f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell RXE_PARITY)) 13327fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn qib_devinfo(dd->pcidev, 13337fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn "Hardware error: hwerr=0x%llx (cleared)\n", 13347fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn (unsigned long long) hwerrs); 1335f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1336f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (hwerrs & ~IB_HWE_BITSEXTANT) 13377fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn qib_dev_err(dd, 13387fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn "hwerror interrupt with unknown errors %llx set\n", 13397fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn (unsigned long long) (hwerrs & ~IB_HWE_BITSEXTANT)); 1340f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1341f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (hwerrs & QLOGIC_IB_HWE_IB_UC_MEMORYPARITYERR) 1342f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_sd7220_clr_ibpar(dd); 1343f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1344f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ctrl = qib_read_kreg32(dd, kr_control); 1345f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if ((ctrl & QLOGIC_IB_C_FREEZEMODE) && !dd->diag_client) { 1346f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1347f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Parity errors in send memory are recoverable by h/w 1348f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * just do housekeeping, exit freeze mode and continue. 1349f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1350f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (hwerrs & (TXEMEMPARITYERR_PIOBUF | 1351f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell TXEMEMPARITYERR_PIOPBC)) { 1352f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_7220_txe_recover(dd); 1353f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell hwerrs &= ~(TXEMEMPARITYERR_PIOBUF | 1354f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell TXEMEMPARITYERR_PIOPBC); 1355f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1356f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (hwerrs) 1357f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell isfatal = 1; 1358f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else 1359f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_7220_clear_freeze(dd); 1360f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1361f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1362f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell *msg = '\0'; 1363f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1364f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (hwerrs & HWE_MASK(PowerOnBISTFailed)) { 1365f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell isfatal = 1; 13667fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn strlcat(msg, 13677fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn "[Memory BIST test failed, InfiniPath hardware unusable]", 13687fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn msgl); 1369f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* ignore from now on, so disable until driver reloaded */ 1370f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->hwerrmask &= ~HWE_MASK(PowerOnBISTFailed); 1371f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_hwerrmask, dd->cspec->hwerrmask); 1372f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1373f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1374f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_format_hwerrors(hwerrs, qib_7220_hwerror_msgs, 1375f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ARRAY_SIZE(qib_7220_hwerror_msgs), msg, msgl); 1376f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1377f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell bitsmsg = dd->cspec->bitsmsgbuf; 1378f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (hwerrs & (QLOGIC_IB_HWE_PCIEMEMPARITYERR_MASK << 1379f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_PCIEMEMPARITYERR_SHIFT)) { 1380f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell bits = (u32) ((hwerrs >> 1381f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_PCIEMEMPARITYERR_SHIFT) & 1382f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_PCIEMEMPARITYERR_MASK); 1383f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell snprintf(bitsmsg, sizeof dd->cspec->bitsmsgbuf, 1384f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "[PCIe Mem Parity Errs %x] ", bits); 1385f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(msg, bitsmsg, msgl); 1386f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1387f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1388f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define _QIB_PLL_FAIL (QLOGIC_IB_HWE_COREPLL_FBSLIP | \ 1389f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_COREPLL_RFSLIP) 1390f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1391f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (hwerrs & _QIB_PLL_FAIL) { 1392f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell isfatal = 1; 1393f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell snprintf(bitsmsg, sizeof dd->cspec->bitsmsgbuf, 1394f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "[PLL failed (%llx), InfiniPath hardware unusable]", 1395f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (unsigned long long) hwerrs & _QIB_PLL_FAIL); 1396f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(msg, bitsmsg, msgl); 1397f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* ignore from now on, so disable until driver reloaded */ 1398f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->hwerrmask &= ~(hwerrs & _QIB_PLL_FAIL); 1399f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_hwerrmask, dd->cspec->hwerrmask); 1400f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1401f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1402f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (hwerrs & QLOGIC_IB_HWE_SERDESPLLFAILED) { 1403f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1404f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * If it occurs, it is left masked since the eternal 1405f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * interface is unused. 1406f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1407f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->hwerrmask &= ~QLOGIC_IB_HWE_SERDESPLLFAILED; 1408f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_hwerrmask, dd->cspec->hwerrmask); 1409f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1410f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1411f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_dev_err(dd, "%s hardware error\n", msg); 1412f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1413f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (isfatal && !dd->diag_client) { 14147fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn qib_dev_err(dd, 14157fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn "Fatal Hardware Error, no longer usable, SN %.16s\n", 14167fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn dd->serial); 1417f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1418f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * For /sys status file and user programs to print; if no 1419f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * trailing brace is copied, we'll know it was truncated. 1420f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1421f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->freezemsg) 1422f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell snprintf(dd->freezemsg, dd->freezelen, 1423f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "{%s}", msg); 1424f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_disable_after_error(dd); 1425f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1426f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellbail:; 1427f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 1428f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1429f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/** 1430f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_7220_init_hwerrors - enable hardware errors 1431f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @dd: the qlogic_ib device 1432f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 1433f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * now that we have finished initializing everything that might reasonably 1434f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * cause a hardware error, and cleared those errors bits as they occur, 1435f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * we can enable hardware errors in the mask (potentially enabling 1436f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * freeze mode), and enable hardware errors as errors (along with 1437f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * everything else) in errormask 1438f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1439f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_init_hwerrors(struct qib_devdata *dd) 1440f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 1441f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 val; 1442f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 extsval; 1443f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1444f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell extsval = qib_read_kreg64(dd, kr_extstatus); 1445f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1446f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!(extsval & (QLOGIC_IB_EXTS_MEMBIST_ENDTEST | 1447f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_EXTS_MEMBIST_DISABLED))) 1448f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_dev_err(dd, "MemBIST did not complete!\n"); 1449f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (extsval & QLOGIC_IB_EXTS_MEMBIST_DISABLED) 1450f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_devinfo(dd->pcidev, "MemBIST is disabled.\n"); 1451f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1452f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = ~0ULL; /* default to all hwerrors become interrupts, */ 1453f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1454f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val &= ~QLOGIC_IB_HWE_IB_UC_MEMORYPARITYERR; 1455f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->hwerrmask = val; 1456f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1457f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_hwerrclear, ~HWE_MASK(PowerOnBISTFailed)); 1458f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_hwerrmask, dd->cspec->hwerrmask); 1459f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1460f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* clear all */ 1461f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_errclear, ~0ULL); 1462f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* enable errors that are masked, at least this first time. */ 1463f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_errmask, ~0ULL); 1464f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->errormask = qib_read_kreg64(dd, kr_errmask); 1465f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* clear any interrupts up to this point (ints still not enabled) */ 1466f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_intclear, ~0ULL); 1467f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 1468f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1469f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 1470f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Disable and enable the armlaunch error. Used for PIO bandwidth testing 1471f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * on chips that are count-based, rather than trigger-based. There is no 1472f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * reference counting, but that's also fine, given the intended use. 1473f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Only chip-specific because it's all register accesses 1474f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1475f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_set_7220_armlaunch(struct qib_devdata *dd, u32 enable) 1476f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 1477f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (enable) { 1478f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_errclear, ERR_MASK(SendPioArmLaunchErr)); 1479f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->errormask |= ERR_MASK(SendPioArmLaunchErr); 1480f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else 1481f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->errormask &= ~ERR_MASK(SendPioArmLaunchErr); 1482f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_errmask, dd->cspec->errormask); 1483f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 1484f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1485f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 1486f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Formerly took parameter <which> in pre-shifted, 1487f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * pre-merged form with LinkCmd and LinkInitCmd 1488f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * together, and assuming the zero was NOP. 1489f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1490f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_set_ib_7220_lstate(struct qib_pportdata *ppd, u16 linkcmd, 1491f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u16 linitcmd) 1492f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 1493f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 mod_wd; 1494f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = ppd->dd; 1495f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 1496f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1497f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (linitcmd == QLOGIC_IB_IBCC_LINKINITCMD_DISABLE) { 1498f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1499f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * If we are told to disable, note that so link-recovery 1500f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * code does not attempt to bring us back up. 1501f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1502f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->lflags_lock, flags); 1503f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags |= QIBL_IB_LINK_DISABLED; 1504f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->lflags_lock, flags); 1505f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else if (linitcmd || linkcmd == QLOGIC_IB_IBCC_LINKCMD_DOWN) { 1506f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1507f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Any other linkinitcmd will lead to LINKDOWN and then 1508f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * to INIT (if all is well), so clear flag to let 1509f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * link-recovery code attempt to bring us back up. 1510f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1511f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->lflags_lock, flags); 1512f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags &= ~QIBL_IB_LINK_DISABLED; 1513f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->lflags_lock, flags); 1514f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1515f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1516f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell mod_wd = (linkcmd << IBA7220_IBCC_LINKCMD_SHIFT) | 1517f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (linitcmd << QLOGIC_IB_IBCC_LINKINITCMD_SHIFT); 1518f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1519f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_ibcctrl, ppd->cpspec->ibcctrl | mod_wd); 1520f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* write to chip to prevent back-to-back writes of ibc reg */ 1521f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_scratch, 0); 1522f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 1523f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1524f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 1525f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * All detailed interaction with the SerDes has been moved to qib_sd7220.c 1526f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 1527f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * The portion of IBA7220-specific bringup_serdes() that actually deals with 1528f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * registers and memory within the SerDes itself is qib_sd7220_init(). 1529f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1530f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1531f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/** 1532f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_7220_bringup_serdes - bring up the serdes 1533f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @ppd: physical port on the qlogic_ib device 1534f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1535f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic int qib_7220_bringup_serdes(struct qib_pportdata *ppd) 1536f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 1537f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = ppd->dd; 1538f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 val, prev_val, guid, ibc; 1539f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int ret = 0; 1540f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1541f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* Put IBC in reset, sends disabled */ 1542f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->control &= ~QLOGIC_IB_C_LINKENABLE; 1543f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_control, 0ULL); 1544f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1545f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (qib_compat_ddr_negotiate) { 1546f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibdeltainprog = 1; 1547f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibsymsnap = read_7220_creg32(dd, cr_ibsymbolerr); 1548f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->iblnkerrsnap = 1549f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell read_7220_creg32(dd, cr_iblinkerrrecov); 1550f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1551f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1552f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* flowcontrolwatermark is in units of KBytes */ 1553f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ibc = 0x5ULL << SYM_LSB(IBCCtrl, FlowCtrlWaterMark); 1554f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1555f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * How often flowctrl sent. More or less in usecs; balance against 1556f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * watermark value, so that in theory senders always get a flow 1557f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * control update in time to not let the IB link go idle. 1558f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1559f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ibc |= 0x3ULL << SYM_LSB(IBCCtrl, FlowCtrlPeriod); 1560f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* max error tolerance */ 1561f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ibc |= 0xfULL << SYM_LSB(IBCCtrl, PhyerrThreshold); 1562f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* use "real" buffer space for */ 1563f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ibc |= 4ULL << SYM_LSB(IBCCtrl, CreditScale); 1564f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* IB credit flow control. */ 1565f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ibc |= 0xfULL << SYM_LSB(IBCCtrl, OverrunThreshold); 1566f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1567f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * set initial max size pkt IBC will send, including ICRC; it's the 1568f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * PIO buffer size in dwords, less 1; also see qib_set_mtu() 1569f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1570f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ibc |= ((u64)(ppd->ibmaxlen >> 2) + 1) << SYM_LSB(IBCCtrl, MaxPktLen); 1571f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcctrl = ibc; /* without linkcmd or linkinitcmd! */ 1572f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1573f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* initially come up waiting for TS1, without sending anything. */ 1574f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = ppd->cpspec->ibcctrl | (QLOGIC_IB_IBCC_LINKINITCMD_DISABLE << 1575f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_IBCC_LINKINITCMD_SHIFT); 1576f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_ibcctrl, val); 1577f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1578f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!ppd->cpspec->ibcddrctrl) { 1579f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* not on re-init after reset */ 1580f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcddrctrl = qib_read_kreg64(dd, kr_ibcddrctrl); 1581f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1582f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->link_speed_enabled == (QIB_IB_SDR | QIB_IB_DDR)) 1583f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcddrctrl |= 1584f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IBA7220_IBC_SPEED_AUTONEG_MASK | 1585f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IBA7220_IBC_IBTA_1_2_MASK; 1586f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else 1587f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcddrctrl |= 1588f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->link_speed_enabled == QIB_IB_DDR ? 1589f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IBA7220_IBC_SPEED_DDR : IBA7220_IBC_SPEED_SDR; 1590f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if ((ppd->link_width_enabled & (IB_WIDTH_1X | IB_WIDTH_4X)) == 1591f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (IB_WIDTH_1X | IB_WIDTH_4X)) 1592f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcddrctrl |= IBA7220_IBC_WIDTH_AUTONEG; 1593f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else 1594f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcddrctrl |= 1595f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->link_width_enabled == IB_WIDTH_4X ? 1596f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IBA7220_IBC_WIDTH_4X_ONLY : 1597f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IBA7220_IBC_WIDTH_1X_ONLY; 1598f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1599f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* always enable these on driver reload, not sticky */ 1600f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcddrctrl |= 1601f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IBA7220_IBC_RXPOL_MASK << IBA7220_IBC_RXPOL_SHIFT; 1602f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcddrctrl |= 1603f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IBA7220_IBC_HRTBT_MASK << IBA7220_IBC_HRTBT_SHIFT; 1604f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1605f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* enable automatic lane reversal detection for receive */ 1606f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcddrctrl |= IBA7220_IBC_LANE_REV_SUPPORTED; 1607f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else 1608f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* write to chip to prevent back-to-back writes of ibc reg */ 1609f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_scratch, 0); 1610f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1611f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_ibcddrctrl, ppd->cpspec->ibcddrctrl); 1612f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_scratch, 0); 1613f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1614f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_ncmodectrl, 0Ull); 1615f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_scratch, 0); 1616f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1617f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = qib_sd7220_init(dd); 1618f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1619f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = qib_read_kreg64(dd, kr_xgxs_cfg); 1620f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell prev_val = val; 1621f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val |= QLOGIC_IB_XGXS_FC_SAFE; 1622f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (val != prev_val) { 1623f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_xgxs_cfg, val); 1624f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_read_kreg32(dd, kr_scratch); 1625f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1626f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (val & QLOGIC_IB_XGXS_RESET) 1627f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val &= ~QLOGIC_IB_XGXS_RESET; 1628f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (val != prev_val) 1629f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_xgxs_cfg, val); 1630f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1631f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* first time through, set port guid */ 1632f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!ppd->guid) 1633f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->guid = dd->base_guid; 1634f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell guid = be64_to_cpu(ppd->guid); 1635f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1636f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_hrtbt_guid, guid); 1637f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!ret) { 1638f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->control |= QLOGIC_IB_C_LINKENABLE; 1639f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_control, dd->control); 1640f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else 1641f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* write to chip to prevent back-to-back writes of ibc reg */ 1642f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_scratch, 0); 1643f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return ret; 1644f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 1645f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1646f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/** 1647f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_7220_quiet_serdes - set serdes to txidle 1648f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @ppd: physical port of the qlogic_ib device 1649f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Called when driver is being unloaded 1650f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1651f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_quiet_serdes(struct qib_pportdata *ppd) 1652f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 1653f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 val; 1654f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = ppd->dd; 1655f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 1656f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1657f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* disable IBC */ 1658f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->control &= ~QLOGIC_IB_C_LINKENABLE; 1659f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_control, 1660f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->control | QLOGIC_IB_C_FREEZEMODE); 1661f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1662f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->chase_end = 0; 1663f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->cpspec->chase_timer.data) /* if initted */ 1664f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell del_timer_sync(&ppd->cpspec->chase_timer); 1665f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1666f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->cpspec->ibsymdelta || ppd->cpspec->iblnkerrdelta || 1667f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibdeltainprog) { 1668f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 diagc; 1669f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1670f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* enable counter writes */ 1671f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell diagc = qib_read_kreg64(dd, kr_hwdiagctrl); 1672f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_hwdiagctrl, 1673f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell diagc | SYM_MASK(HwDiagCtrl, CounterWrEnable)); 1674f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1675f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->cpspec->ibsymdelta || ppd->cpspec->ibdeltainprog) { 1676f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = read_7220_creg32(dd, cr_ibsymbolerr); 1677f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->cpspec->ibdeltainprog) 1678f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val -= val - ppd->cpspec->ibsymsnap; 1679f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val -= ppd->cpspec->ibsymdelta; 1680f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell write_7220_creg(dd, cr_ibsymbolerr, val); 1681f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1682f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->cpspec->iblnkerrdelta || ppd->cpspec->ibdeltainprog) { 1683f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = read_7220_creg32(dd, cr_iblinkerrrecov); 1684f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->cpspec->ibdeltainprog) 1685f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val -= val - ppd->cpspec->iblnkerrsnap; 1686f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val -= ppd->cpspec->iblnkerrdelta; 1687f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell write_7220_creg(dd, cr_iblinkerrrecov, val); 1688f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1689f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1690f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* and disable counter writes */ 1691f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_hwdiagctrl, diagc); 1692f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1693f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_set_ib_7220_lstate(ppd, 0, QLOGIC_IB_IBCC_LINKINITCMD_DISABLE); 1694f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1695f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->lflags_lock, flags); 1696f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags &= ~QIBL_IB_AUTONEG_INPROG; 1697f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->lflags_lock, flags); 1698f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell wake_up(&ppd->cpspec->autoneg_wait); 1699f06267104dd9112f11586830d22501d0e26245eaTejun Heo cancel_delayed_work_sync(&ppd->cpspec->autoneg_work); 1700f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1701f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell shutdown_7220_relock_poll(ppd->dd); 1702f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = qib_read_kreg64(ppd->dd, kr_xgxs_cfg); 1703f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val |= QLOGIC_IB_XGXS_RESET; 1704f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(ppd->dd, kr_xgxs_cfg, val); 1705f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 1706f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1707f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/** 1708f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_setup_7220_setextled - set the state of the two external LEDs 1709f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @dd: the qlogic_ib device 1710f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @on: whether the link is up or not 1711f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 1712f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * The exact combo of LEDs if on is true is determined by looking 1713f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * at the ibcstatus. 1714f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 1715f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * These LEDs indicate the physical and logical state of IB link. 1716f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * For this chip (at least with recommended board pinouts), LED1 1717f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * is Yellow (logical state) and LED2 is Green (physical state), 1718f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 1719f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Note: We try to match the Mellanox HCA LED behavior as best 1720f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * we can. Green indicates physical link state is OK (something is 1721f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * plugged in, and we can train). 1722f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Amber indicates the link is logically up (ACTIVE). 1723f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Mellanox further blinks the amber LED to indicate data packet 1724f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * activity, but we have no hardware support for that, so it would 1725f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * require waking up every 10-20 msecs and checking the counters 1726f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * on the chip, and then turning the LED off if appropriate. That's 1727f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * visible overhead, so not something we will do. 1728f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 1729f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1730f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_setup_7220_setextled(struct qib_pportdata *ppd, u32 on) 1731f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 1732f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = ppd->dd; 1733f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 extctl, ledblink = 0, val, lst, ltst; 1734f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 1735f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1736f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1737f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * The diags use the LED to indicate diag info, so we leave 1738f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * the external LED alone when the diags are running. 1739f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1740f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->diag_client) 1741f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return; 1742f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1743f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->led_override) { 1744f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ltst = (ppd->led_override & QIB_LED_PHYS) ? 1745f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IB_PHYSPORTSTATE_LINKUP : IB_PHYSPORTSTATE_DISABLED, 1746f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell lst = (ppd->led_override & QIB_LED_LOG) ? 1747f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IB_PORT_ACTIVE : IB_PORT_DOWN; 1748f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else if (on) { 1749f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = qib_read_kreg64(dd, kr_ibcstatus); 1750f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ltst = qib_7220_phys_portstate(val); 1751f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell lst = qib_7220_iblink_state(val); 1752f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else { 1753f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ltst = 0; 1754f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell lst = 0; 1755f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1756f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1757f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&dd->cspec->gpio_lock, flags); 1758f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell extctl = dd->cspec->extctrl & ~(SYM_MASK(EXTCtrl, LEDPriPortGreenOn) | 1759f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK(EXTCtrl, LEDPriPortYellowOn)); 1760f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ltst == IB_PHYSPORTSTATE_LINKUP) { 1761f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell extctl |= SYM_MASK(EXTCtrl, LEDPriPortGreenOn); 1762f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1763f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * counts are in chip clock (4ns) periods. 1764f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * This is 1/16 sec (66.6ms) on, 1765f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 3/16 sec (187.5 ms) off, with packets rcvd 1766f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1767f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ledblink = ((66600 * 1000UL / 4) << IBA7220_LEDBLINK_ON_SHIFT) 1768f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell | ((187500 * 1000UL / 4) << IBA7220_LEDBLINK_OFF_SHIFT); 1769f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1770f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (lst == IB_PORT_ACTIVE) 1771f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell extctl |= SYM_MASK(EXTCtrl, LEDPriPortYellowOn); 1772f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->extctrl = extctl; 1773f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_extctrl, extctl); 1774f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&dd->cspec->gpio_lock, flags); 1775f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1776f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ledblink) /* blink the LED on packet receive */ 1777f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_rcvpktledcnt, ledblink); 1778f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 1779f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1780f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_free_irq(struct qib_devdata *dd) 1781f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 1782f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->cspec->irq) { 1783f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell free_irq(dd->cspec->irq, dd); 1784f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->irq = 0; 1785f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1786f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_nomsi(dd); 1787f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 1788f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1789f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 1790f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_setup_7220_cleanup - clean up any per-chip chip-specific stuff 1791f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @dd: the qlogic_ib device 1792f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 1793f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * This is called during driver unload. 1794f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 1795f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1796f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_setup_7220_cleanup(struct qib_devdata *dd) 1797f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 1798f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_7220_free_irq(dd); 1799f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell kfree(dd->cspec->cntrs); 1800f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell kfree(dd->cspec->portcntrs); 1801f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 1802f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1803f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 1804f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * This is only called for SDmaInt. 1805f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * SDmaDisabled is handled on the error path. 1806f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1807f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void sdma_7220_intr(struct qib_pportdata *ppd, u64 istat) 1808f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 1809f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 1810f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1811f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->sdma_lock, flags); 1812f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1813f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell switch (ppd->sdma_state.current_state) { 1814f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case qib_sdma_state_s00_hw_down: 1815f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 1816f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1817f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case qib_sdma_state_s10_hw_start_up_wait: 1818f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell __qib_sdma_process_event(ppd, qib_sdma_event_e20_hw_started); 1819f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 1820f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1821f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case qib_sdma_state_s20_idle: 1822f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 1823f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1824f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case qib_sdma_state_s30_sw_clean_up_wait: 1825f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 1826f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1827f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case qib_sdma_state_s40_hw_clean_up_wait: 1828f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 1829f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1830f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case qib_sdma_state_s50_hw_halt_wait: 1831f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell __qib_sdma_process_event(ppd, qib_sdma_event_e60_hw_halted); 1832f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 1833f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1834f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case qib_sdma_state_s99_running: 1835f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* too chatty to print here */ 1836f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell __qib_sdma_intr(ppd); 1837f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 1838f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1839f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->sdma_lock, flags); 1840f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 1841f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1842f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_wantpiobuf_7220_intr(struct qib_devdata *dd, u32 needint) 1843f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 1844f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 1845f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1846f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&dd->sendctrl_lock, flags); 1847f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (needint) { 1848f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!(dd->sendctrl & SYM_MASK(SendCtrl, SendBufAvailUpd))) 1849f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 1850f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1851f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * blip the availupd off, next write will be on, so 1852f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * we ensure an avail update, regardless of threshold or 1853f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * buffers becoming free, whenever we want an interrupt 1854f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1855f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_sendctrl, dd->sendctrl & 1856f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ~SYM_MASK(SendCtrl, SendBufAvailUpd)); 1857f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_scratch, 0ULL); 1858f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->sendctrl |= SYM_MASK(SendCtrl, SendIntBufAvail); 1859f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else 1860f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->sendctrl &= ~SYM_MASK(SendCtrl, SendIntBufAvail); 1861f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_sendctrl, dd->sendctrl); 1862f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_scratch, 0ULL); 1863f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbelldone: 1864f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&dd->sendctrl_lock, flags); 1865f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 1866f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1867f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 1868f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Handle errors and unusual events first, separate function 1869f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * to improve cache hits for fast path interrupt handling. 1870f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1871f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic noinline void unlikely_7220_intr(struct qib_devdata *dd, u64 istat) 1872f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 1873f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (unlikely(istat & ~QLOGIC_IB_I_BITSEXTANT)) 1874f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_dev_err(dd, 1875f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "interrupt with unknown interrupts %Lx set\n", 1876f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell istat & ~QLOGIC_IB_I_BITSEXTANT); 1877f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1878f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (istat & QLOGIC_IB_I_GPIO) { 1879f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 gpiostatus; 1880f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1881f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1882f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Boards for this chip currently don't use GPIO interrupts, 1883f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * so clear by writing GPIOstatus to GPIOclear, and complain 1884f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * to alert developer. To avoid endless repeats, clear 1885f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * the bits in the mask, since there is some kind of 1886f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * programming error or chip problem. 1887f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1888f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell gpiostatus = qib_read_kreg32(dd, kr_gpio_status); 1889f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1890f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * In theory, writing GPIOstatus to GPIOclear could 1891f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * have a bad side-effect on some diagnostic that wanted 1892f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * to poll for a status-change, but the various shadows 1893f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * make that problematic at best. Diags will just suppress 1894f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * all GPIO interrupts during such tests. 1895f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1896f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_gpio_clear, gpiostatus); 1897f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1898f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (gpiostatus) { 1899f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell const u32 mask = qib_read_kreg32(dd, kr_gpio_mask); 1900f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 gpio_irq = mask & gpiostatus; 1901f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1902f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1903f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * A bit set in status and (chip) Mask register 1904f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * would cause an interrupt. Since we are not 1905f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * expecting any, report it. Also check that the 1906f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * chip reflects our shadow, report issues, 1907f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * and refresh from the shadow. 1908f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1909f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1910f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Clear any troublemakers, and update chip 1911f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * from shadow 1912f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1913f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->gpio_mask &= ~gpio_irq; 1914f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_gpio_mask, dd->cspec->gpio_mask); 1915f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1916f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1917f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1918f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (istat & QLOGIC_IB_I_ERROR) { 1919f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 estat; 1920f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1921f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_stats.sps_errints++; 1922f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell estat = qib_read_kreg64(dd, kr_errstatus); 1923f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!estat) 19247fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn qib_devinfo(dd->pcidev, 19257fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn "error interrupt (%Lx), but no error bits set!\n", 19267fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn istat); 1927f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else 1928f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell handle_7220_errors(dd, estat); 1929f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1930f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 1931f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1932f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic irqreturn_t qib_7220intr(int irq, void *data) 1933f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 1934f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = data; 1935f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell irqreturn_t ret; 1936f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 istat; 1937f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 ctxtrbits; 1938f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 rmask; 1939f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned i; 1940f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1941f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if ((dd->flags & (QIB_PRESENT | QIB_BADINTR)) != QIB_PRESENT) { 1942f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1943f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * This return value is not great, but we do not want the 1944f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * interrupt core code to remove our interrupt handler 1945f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * because we don't appear to be handling an interrupt 1946f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * during a chip reset. 1947f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1948f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = IRQ_HANDLED; 1949f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 1950f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1951f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1952f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell istat = qib_read_kreg64(dd, kr_intstatus); 1953f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1954f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (unlikely(!istat)) { 1955f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = IRQ_NONE; /* not our interrupt, or already handled */ 1956f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 1957f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1958f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (unlikely(istat == -1)) { 1959f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_bad_intrstatus(dd); 1960f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* don't know if it was our interrupt or not */ 1961f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = IRQ_NONE; 1962f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 1963f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1964f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 19651ed88dd7d0b361e677b2690f573e5c274bb25c87Mike Marciniszyn this_cpu_inc(*dd->int_counter); 1966f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (unlikely(istat & (~QLOGIC_IB_I_BITSEXTANT | 1967f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_I_GPIO | QLOGIC_IB_I_ERROR))) 1968f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unlikely_7220_intr(dd, istat); 1969f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1970f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1971f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Clear the interrupt bits we found set, relatively early, so we 1972f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * "know" know the chip will have seen this by the time we process 1973f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * the queue, and will re-interrupt if necessary. The processor 1974f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * itself won't take the interrupt again until we return. 1975f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1976f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_intclear, istat); 1977f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 1978f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 1979f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Handle kernel receive queues before checking for pio buffers 1980f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * available since receives can overflow; piobuf waiters can afford 1981f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * a few extra cycles, since they were waiting anyway. 1982f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1983f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ctxtrbits = istat & 1984f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ((QLOGIC_IB_I_RCVAVAIL_MASK << QLOGIC_IB_I_RCVAVAIL_SHIFT) | 1985f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (QLOGIC_IB_I_RCVURG_MASK << QLOGIC_IB_I_RCVURG_SHIFT)); 1986f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ctxtrbits) { 1987f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell rmask = (1ULL << QLOGIC_IB_I_RCVAVAIL_SHIFT) | 1988f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (1ULL << QLOGIC_IB_I_RCVURG_SHIFT); 1989f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (i = 0; i < dd->first_user_ctxt; i++) { 1990f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ctxtrbits & rmask) { 1991f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ctxtrbits &= ~rmask; 1992f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_kreceive(dd->rcd[i], NULL, NULL); 1993f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1994f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell rmask <<= 1; 1995f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 1996f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ctxtrbits) { 1997f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ctxtrbits = 1998f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (ctxtrbits >> QLOGIC_IB_I_RCVAVAIL_SHIFT) | 1999f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (ctxtrbits >> QLOGIC_IB_I_RCVURG_SHIFT); 2000f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_handle_urcv(dd, ctxtrbits); 2001f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2002f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2003f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2004f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* only call for SDmaInt */ 2005f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (istat & QLOGIC_IB_I_SDMAINT) 2006f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sdma_7220_intr(dd->pport, istat); 2007f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2008f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if ((istat & QLOGIC_IB_I_SPIOBUFAVAIL) && (dd->flags & QIB_INITTED)) 2009f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_ib_piobufavail(dd); 2010f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2011f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = IRQ_HANDLED; 2012f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellbail: 2013f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return ret; 2014f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 2015f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2016f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 2017f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Set up our chip-specific interrupt handler. 2018f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * The interrupt type has already been setup, so 2019f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * we just need to do the registration and error checking. 2020f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * If we are using MSI interrupts, we may fall back to 2021f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * INTx later, if the interrupt handler doesn't get called 2022f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * within 1/2 second (see verify_interrupt()). 2023f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2024f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_setup_7220_interrupt(struct qib_devdata *dd) 2025f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 2026f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!dd->cspec->irq) 20277fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn qib_dev_err(dd, 20287fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn "irq is 0, BIOS error? Interrupts won't work\n"); 2029f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else { 2030f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int ret = request_irq(dd->cspec->irq, qib_7220intr, 2031f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->msi_lo ? 0 : IRQF_SHARED, 2032f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIB_DRV_NAME, dd); 2033f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2034f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ret) 20357fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn qib_dev_err(dd, 20367fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn "Couldn't setup %s interrupt (irq=%d): %d\n", 20377fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn dd->msi_lo ? "MSI" : "INTx", 20387fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn dd->cspec->irq, ret); 2039f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2040f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 2041f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2042f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/** 2043f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_7220_boardname - fill in the board name 2044f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @dd: the qlogic_ib device 2045f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 2046f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * info is based on the board revision register 2047f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2048f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_boardname(struct qib_devdata *dd) 2049f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 2050f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell char *n; 2051f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 boardid, namelen; 2052f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2053f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell boardid = SYM_FIELD(dd->revision, Revision, 2054f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell BoardID); 2055f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2056f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell switch (boardid) { 2057f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case 1: 2058f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell n = "InfiniPath_QLE7240"; 2059f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 2060f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case 2: 2061f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell n = "InfiniPath_QLE7280"; 2062f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 2063f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell default: 2064f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_dev_err(dd, "Unknown 7220 board with ID %u\n", boardid); 2065f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell n = "Unknown_InfiniPath_7220"; 2066f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 2067f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2068f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2069f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell namelen = strlen(n) + 1; 2070f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->boardname = kmalloc(namelen, GFP_KERNEL); 2071f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!dd->boardname) 2072f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_dev_err(dd, "Failed allocation for board name: %s\n", n); 2073f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else 2074f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell snprintf(dd->boardname, namelen, "%s", n); 2075f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2076f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->majrev != 5 || !dd->minrev || dd->minrev > 2) 20777fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn qib_dev_err(dd, 20787fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn "Unsupported InfiniPath hardware revision %u.%u!\n", 20797fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn dd->majrev, dd->minrev); 2080f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2081f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell snprintf(dd->boardversion, sizeof(dd->boardversion), 2082f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "ChipABI %u.%u, %s, InfiniPath%u %u.%u, SW Compat %u\n", 2083f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIB_CHIP_VERS_MAJ, QIB_CHIP_VERS_MIN, dd->boardname, 2084f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (unsigned)SYM_FIELD(dd->revision, Revision_R, Arch), 2085f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->majrev, dd->minrev, 2086f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (unsigned)SYM_FIELD(dd->revision, Revision_R, SW)); 2087f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 2088f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2089f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 2090f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * This routine sleeps, so it can only be called from user context, not 2091f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * from interrupt context. 2092f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2093f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic int qib_setup_7220_reset(struct qib_devdata *dd) 2094f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 2095f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 val; 2096f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int i; 2097f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int ret; 2098f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u16 cmdval; 2099f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u8 int_line, clinesz; 2100f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 2101f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2102f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_pcie_getcmd(dd, &cmdval, &int_line, &clinesz); 2103f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2104f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* Use dev_err so it shows up in logs, etc. */ 2105f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_dev_err(dd, "Resetting InfiniPath unit %u\n", dd->unit); 2106f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2107f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* no interrupts till re-initted */ 2108f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_7220_set_intr_state(dd, 0); 2109f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2110f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->pport->cpspec->ibdeltainprog = 0; 2111f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->pport->cpspec->ibsymdelta = 0; 2112f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->pport->cpspec->iblnkerrdelta = 0; 2113f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2114f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 2115f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Keep chip from being accessed until we are ready. Use 2116f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * writeq() directly, to allow the write even though QIB_PRESENT 2117e9c549998dc24209847007e1f209f3b6c88d21baLucas De Marchi * isn't set. 2118f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2119f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->flags &= ~(QIB_INITTED | QIB_PRESENT); 21201ed88dd7d0b361e677b2690f573e5c274bb25c87Mike Marciniszyn /* so we check interrupts work again */ 21211ed88dd7d0b361e677b2690f573e5c274bb25c87Mike Marciniszyn dd->z_int_counter = qib_int_counter(dd); 2122f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = dd->control | QLOGIC_IB_C_RESET; 2123f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell writeq(val, &dd->kregbase[kr_control]); 2124f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell mb(); /* prevent compiler reordering around actual reset */ 2125f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2126f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (i = 1; i <= 5; i++) { 2127f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 2128f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Allow MBIST, etc. to complete; longer on each retry. 2129f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * We sometimes get machine checks from bus timeout if no 2130f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * response, so for now, make it *really* long. 2131f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2132f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell msleep(1000 + (1 + i) * 2000); 2133f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2134f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_pcie_reenable(dd, cmdval, int_line, clinesz); 2135f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2136f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 2137f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Use readq directly, so we don't need to mark it as PRESENT 2138f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * until we get a successful indication that all is well. 2139f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2140f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = readq(&dd->kregbase[kr_revision]); 2141f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (val == dd->revision) { 2142f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->flags |= QIB_PRESENT; /* it's back */ 2143f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = qib_reinit_intr(dd); 2144f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 2145f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2146f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2147f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = 0; /* failed */ 2148f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2149f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellbail: 2150f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ret) { 2151f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (qib_pcie_params(dd, dd->lbus_width, NULL, NULL)) 21527fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn qib_dev_err(dd, 21537fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn "Reset failed to setup PCIe or interrupts; continuing anyway\n"); 2154f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2155f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* hold IBC in reset, no sends, etc till later */ 2156f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_control, 0ULL); 2157f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2158f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* clear the reset error, init error/hwerror mask */ 2159f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_7220_init_hwerrors(dd); 2160f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2161f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* do setup similar to speed or link-width changes */ 2162f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->pport->cpspec->ibcddrctrl & IBA7220_IBC_IBTA_1_2_MASK) 2163f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->presets_needed = 1; 2164f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&dd->pport->lflags_lock, flags); 2165f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->pport->lflags |= QIBL_IB_FORCE_NOTIFY; 2166f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->pport->lflags &= ~QIBL_IB_AUTONEG_FAILED; 2167f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&dd->pport->lflags_lock, flags); 2168f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2169f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2170f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return ret; 2171f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 2172f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2173f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/** 2174f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_7220_put_tid - write a TID to the chip 2175f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @dd: the qlogic_ib device 2176f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @tidptr: pointer to the expected TID (in chip) to update 2177f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @tidtype: 0 for eager, 1 for expected 2178f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @pa: physical address of in memory buffer; tidinvalid if freeing 2179f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2180f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_put_tid(struct qib_devdata *dd, u64 __iomem *tidptr, 2181f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 type, unsigned long pa) 2182f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 2183f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (pa != dd->tidinvalid) { 2184f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 chippa = pa >> IBA7220_TID_PA_SHIFT; 2185f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2186f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* paranoia checks */ 2187f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (pa != (chippa << IBA7220_TID_PA_SHIFT)) { 2188f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_dev_err(dd, "Physaddr %lx not 2KB aligned!\n", 2189f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell pa); 2190f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return; 2191f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2192f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (chippa >= (1UL << IBA7220_TID_SZ_SHIFT)) { 21937fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn qib_dev_err(dd, 21947fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn "Physical page address 0x%lx larger than supported\n", 21957fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn pa); 2196f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return; 2197f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2198f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2199f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (type == RCVHQ_RCV_TYPE_EAGER) 2200f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell chippa |= dd->tidtemplate; 2201f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else /* for now, always full 4KB page */ 2202f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell chippa |= IBA7220_TID_SZ_4K; 2203f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell pa = chippa; 2204f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2205f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell writeq(pa, tidptr); 2206f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell mmiowb(); 2207f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 2208f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2209f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/** 2210f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_7220_clear_tids - clear all TID entries for a ctxt, expected and eager 2211f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @dd: the qlogic_ib device 2212f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @ctxt: the ctxt 2213f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 2214f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * clear all TID entries for a ctxt, expected and eager. 2215f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Used from qib_close(). On this chip, TIDs are only 32 bits, 2216f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * not 64, but they are still on 64 bit boundaries, so tidbase 2217f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * is declared as u64 * for the pointer math, even though we write 32 bits 2218f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2219f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_clear_tids(struct qib_devdata *dd, 2220f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_ctxtdata *rcd) 2221f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 2222f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 __iomem *tidbase; 2223f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long tidinv; 2224f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 ctxt; 2225f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int i; 2226f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2227f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!dd->kregbase || !rcd) 2228f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return; 2229f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2230f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ctxt = rcd->ctxt; 2231f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2232f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell tidinv = dd->tidinvalid; 2233f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell tidbase = (u64 __iomem *) 2234f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ((char __iomem *)(dd->kregbase) + 2235f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvtidbase + 2236f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ctxt * dd->rcvtidcnt * sizeof(*tidbase)); 2237f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2238f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (i = 0; i < dd->rcvtidcnt; i++) 2239f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_7220_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EXPECTED, 2240f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell tidinv); 2241f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2242f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell tidbase = (u64 __iomem *) 2243f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ((char __iomem *)(dd->kregbase) + 2244f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvegrbase + 2245f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell rcd->rcvegr_tid_base * sizeof(*tidbase)); 2246f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2247f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (i = 0; i < rcd->rcvegrcnt; i++) 2248f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_7220_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EAGER, 2249f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell tidinv); 2250f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 2251f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2252f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/** 2253f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_7220_tidtemplate - setup constants for TID updates 2254f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @dd: the qlogic_ib device 2255f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 2256f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * We setup stuff that we use a lot, to avoid calculating each time 2257f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2258f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_tidtemplate(struct qib_devdata *dd) 2259f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 2260f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->rcvegrbufsize == 2048) 2261f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->tidtemplate = IBA7220_TID_SZ_2K; 2262f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else if (dd->rcvegrbufsize == 4096) 2263f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->tidtemplate = IBA7220_TID_SZ_4K; 2264f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->tidinvalid = 0; 2265f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 2266f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2267f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/** 2268f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_init_7220_get_base_info - set chip-specific flags for user code 2269f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @rcd: the qlogic_ib ctxt 2270f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @kbase: qib_base_info pointer 2271f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 2272f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * We set the PCIE flag because the lower bandwidth on PCIe vs 2273f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * HyperTransport can affect some user packet algorithims. 2274f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2275f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic int qib_7220_get_base_info(struct qib_ctxtdata *rcd, 2276f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_base_info *kinfo) 2277f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 2278f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell kinfo->spi_runtime_flags |= QIB_RUNTIME_PCIE | 2279f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIB_RUNTIME_NODMA_RTAIL | QIB_RUNTIME_SDMA; 2280f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2281f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (rcd->dd->flags & QIB_USE_SPCL_TRIG) 2282f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell kinfo->spi_runtime_flags |= QIB_RUNTIME_SPECIAL_TRIGGER; 2283f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2284f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return 0; 2285f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 2286f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2287f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic struct qib_message_header * 2288f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellqib_7220_get_msgheader(struct qib_devdata *dd, __le32 *rhf_addr) 2289f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 2290f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 offset = qib_hdrget_offset(rhf_addr); 2291f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2292f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return (struct qib_message_header *) 2293f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (rhf_addr - dd->rhf_offset + offset); 2294f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 2295f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2296f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_config_ctxts(struct qib_devdata *dd) 2297f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 2298f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 2299f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 nchipctxts; 2300f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2301f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell nchipctxts = qib_read_kreg32(dd, kr_portcnt); 2302f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->numctxts = nchipctxts; 2303f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (qib_n_krcv_queues > 1) { 23042528ea60f94ef9e1e1cd82066d55f62a1d19fde1Mike Marciniszyn dd->qpn_mask = 0x3e; 2305f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->first_user_ctxt = qib_n_krcv_queues * dd->num_pports; 2306f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->first_user_ctxt > nchipctxts) 2307f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->first_user_ctxt = nchipctxts; 2308f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else 2309f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->first_user_ctxt = dd->num_pports; 2310f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->n_krcv_queues = dd->first_user_ctxt; 2311f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2312f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!qib_cfgctxts) { 2313f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int nctxts = dd->first_user_ctxt + num_online_cpus(); 2314f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2315f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (nctxts <= 5) 2316f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->ctxtcnt = 5; 2317f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else if (nctxts <= 9) 2318f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->ctxtcnt = 9; 2319f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else if (nctxts <= nchipctxts) 2320f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->ctxtcnt = nchipctxts; 2321f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else if (qib_cfgctxts <= nchipctxts) 2322f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->ctxtcnt = qib_cfgctxts; 2323f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!dd->ctxtcnt) /* none of the above, set to max */ 2324f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->ctxtcnt = nchipctxts; 2325f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2326f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 2327f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Chip can be configured for 5, 9, or 17 ctxts, and choice 2328f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * affects number of eager TIDs per ctxt (1K, 2K, 4K). 2329f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Lock to be paranoid about later motion, etc. 2330f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2331f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&dd->cspec->rcvmod_lock, flags); 2332f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->ctxtcnt > 9) 2333f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvctrl |= 2ULL << IBA7220_R_CTXTCFG_SHIFT; 2334f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else if (dd->ctxtcnt > 5) 2335f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvctrl |= 1ULL << IBA7220_R_CTXTCFG_SHIFT; 2336f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* else configure for default 5 receive ctxts */ 2337f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->qpn_mask) 2338f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvctrl |= 1ULL << QIB_7220_RcvCtrl_RcvQPMapEnable_LSB; 2339f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_rcvctrl, dd->rcvctrl); 2340f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&dd->cspec->rcvmod_lock, flags); 2341f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2342f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* kr_rcvegrcnt changes based on the number of contexts enabled */ 2343f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->rcvegrcnt = qib_read_kreg32(dd, kr_rcvegrcnt); 2344f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvhdrcnt = max(dd->cspec->rcvegrcnt, IBA7220_KRCVEGRCNT); 2345f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 2346f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2347f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic int qib_7220_get_ib_cfg(struct qib_pportdata *ppd, int which) 2348f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 2349f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int lsb, ret = 0; 2350f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 maskr; /* right-justified mask */ 2351f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2352f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell switch (which) { 2353f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_LWID_ENB: /* Get allowed Link-width */ 2354f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = ppd->link_width_enabled; 2355f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 2356f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2357f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_LWID: /* Get currently active Link-width */ 2358f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = ppd->link_width_active; 2359f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 2360f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2361f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_SPD_ENB: /* Get allowed Link speeds */ 2362f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = ppd->link_speed_enabled; 2363f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 2364f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2365f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_SPD: /* Get current Link spd */ 2366f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = ppd->link_speed_active; 2367f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 2368f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2369f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_RXPOL_ENB: /* Get Auto-RX-polarity enable */ 2370f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell lsb = IBA7220_IBC_RXPOL_SHIFT; 2371f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell maskr = IBA7220_IBC_RXPOL_MASK; 2372f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 2373f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2374f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_LREV_ENB: /* Get Auto-Lane-reversal enable */ 2375f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell lsb = IBA7220_IBC_LREV_SHIFT; 2376f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell maskr = IBA7220_IBC_LREV_MASK; 2377f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 2378f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2379f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_LINKLATENCY: 2380f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = qib_read_kreg64(ppd->dd, kr_ibcddrstatus) 2381f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell & IBA7220_DDRSTAT_LINKLAT_MASK; 2382f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 2383f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2384f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_OP_VLS: 2385f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = ppd->vls_operational; 2386f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 2387f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2388f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_VL_HIGH_CAP: 2389f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = 0; 2390f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 2391f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2392f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_VL_LOW_CAP: 2393f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = 0; 2394f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 2395f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2396f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_OVERRUN_THRESH: /* IB overrun threshold */ 2397f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = SYM_FIELD(ppd->cpspec->ibcctrl, IBCCtrl, 2398f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell OverrunThreshold); 2399f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 2400f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2401f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_PHYERR_THRESH: /* IB PHY error threshold */ 2402f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = SYM_FIELD(ppd->cpspec->ibcctrl, IBCCtrl, 2403f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell PhyerrThreshold); 2404f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 2405f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2406f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_LINKDEFAULT: /* IB link default (sleep/poll) */ 2407f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* will only take effect when the link state changes */ 2408f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = (ppd->cpspec->ibcctrl & 2409f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK(IBCCtrl, LinkDownDefaultState)) ? 2410f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IB_LINKINITCMD_SLEEP : IB_LINKINITCMD_POLL; 2411f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 2412f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2413f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_HRTBT: /* Get Heartbeat off/enable/auto */ 2414f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell lsb = IBA7220_IBC_HRTBT_SHIFT; 2415f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell maskr = IBA7220_IBC_HRTBT_MASK; 2416f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 2417f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2418f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_PMA_TICKS: 2419f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 2420f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 0x00 = 10x link transfer rate or 4 nsec. for 2.5Gbs 2421f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Since the clock is always 250MHz, the value is 1 or 0. 2422f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2423f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = (ppd->link_speed_active == QIB_IB_DDR); 2424f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 2425f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2426f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell default: 2427f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = -EINVAL; 2428f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 2429f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2430f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = (int)((ppd->cpspec->ibcddrctrl >> lsb) & maskr); 2431f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbelldone: 2432f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return ret; 2433f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 2434f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2435f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic int qib_7220_set_ib_cfg(struct qib_pportdata *ppd, int which, u32 val) 2436f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 2437f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = ppd->dd; 2438f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 maskr; /* right-justified mask */ 2439f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int lsb, ret = 0, setforce = 0; 2440f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u16 lcmd, licmd; 2441f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 2442e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov u32 tmp = 0; 2443f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2444f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell switch (which) { 2445f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_LIDLMC: 2446f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 2447f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Set LID and LMC. Combined to avoid possible hazard 2448f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * caller puts LMC in 16MSbits, DLID in 16LSbits of val 2449f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2450f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell lsb = IBA7220_IBC_DLIDLMC_SHIFT; 2451f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell maskr = IBA7220_IBC_DLIDLMC_MASK; 2452f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 2453f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2454f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_LWID_ENB: /* set allowed Link-width */ 2455f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 2456f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * As with speed, only write the actual register if 2457f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * the link is currently down, otherwise takes effect 2458f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * on next link change. 2459f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2460f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->link_width_enabled = val; 2461f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!(ppd->lflags & QIBL_LINKDOWN)) 2462f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 2463f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 2464f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * We set the QIBL_IB_FORCE_NOTIFY bit so updown 2465f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * will get called because we want update 2466f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * link_width_active, and the change may not take 2467f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * effect for some time (if we are in POLL), so this 2468f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * flag will force the updown routine to be called 2469f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * on the next ibstatuschange down interrupt, even 2470f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * if it's not an down->up transition. 2471f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2472f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val--; /* convert from IB to chip */ 2473f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell maskr = IBA7220_IBC_WIDTH_MASK; 2474f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell lsb = IBA7220_IBC_WIDTH_SHIFT; 2475f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell setforce = 1; 2476f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 2477f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2478f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_SPD_ENB: /* set allowed Link speeds */ 2479f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 2480f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * If we turn off IB1.2, need to preset SerDes defaults, 2481f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * but not right now. Set a flag for the next time 2482f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * we command the link down. As with width, only write the 2483f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * actual register if the link is currently down, otherwise 2484f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * takes effect on next link change. Since setting is being 248525985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * explicitly requested (via MAD or sysfs), clear autoneg 2486f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * failure status if speed autoneg is enabled. 2487f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2488f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->link_speed_enabled = val; 2489f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if ((ppd->cpspec->ibcddrctrl & IBA7220_IBC_IBTA_1_2_MASK) && 2490f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell !(val & (val - 1))) 2491f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->presets_needed = 1; 2492f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!(ppd->lflags & QIBL_LINKDOWN)) 2493f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 2494f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 2495f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * We set the QIBL_IB_FORCE_NOTIFY bit so updown 2496f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * will get called because we want update 2497f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * link_speed_active, and the change may not take 2498f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * effect for some time (if we are in POLL), so this 2499f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * flag will force the updown routine to be called 2500f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * on the next ibstatuschange down interrupt, even 2501f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * if it's not an down->up transition. 2502f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2503f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (val == (QIB_IB_SDR | QIB_IB_DDR)) { 2504f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = IBA7220_IBC_SPEED_AUTONEG_MASK | 2505f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IBA7220_IBC_IBTA_1_2_MASK; 2506f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->lflags_lock, flags); 2507f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags &= ~QIBL_IB_AUTONEG_FAILED; 2508f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->lflags_lock, flags); 2509f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else 2510f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = val == QIB_IB_DDR ? 2511f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IBA7220_IBC_SPEED_DDR : IBA7220_IBC_SPEED_SDR; 2512f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell maskr = IBA7220_IBC_SPEED_AUTONEG_MASK | 2513f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IBA7220_IBC_IBTA_1_2_MASK; 2514f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* IBTA 1.2 mode + speed bits are contiguous */ 2515f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell lsb = SYM_LSB(IBCDDRCtrl, IB_ENHANCED_MODE); 2516f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell setforce = 1; 2517f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 2518f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2519f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_RXPOL_ENB: /* set Auto-RX-polarity enable */ 2520f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell lsb = IBA7220_IBC_RXPOL_SHIFT; 2521f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell maskr = IBA7220_IBC_RXPOL_MASK; 2522f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 2523f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2524f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_LREV_ENB: /* set Auto-Lane-reversal enable */ 2525f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell lsb = IBA7220_IBC_LREV_SHIFT; 2526f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell maskr = IBA7220_IBC_LREV_MASK; 2527f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 2528f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2529f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_OVERRUN_THRESH: /* IB overrun threshold */ 2530f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell maskr = SYM_FIELD(ppd->cpspec->ibcctrl, IBCCtrl, 2531f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell OverrunThreshold); 2532f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (maskr != val) { 2533f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcctrl &= 2534f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ~SYM_MASK(IBCCtrl, OverrunThreshold); 2535f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcctrl |= (u64) val << 2536f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_LSB(IBCCtrl, OverrunThreshold); 2537f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_ibcctrl, ppd->cpspec->ibcctrl); 2538f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_scratch, 0); 2539f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2540f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 2541f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2542f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_PHYERR_THRESH: /* IB PHY error threshold */ 2543f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell maskr = SYM_FIELD(ppd->cpspec->ibcctrl, IBCCtrl, 2544f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell PhyerrThreshold); 2545f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (maskr != val) { 2546f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcctrl &= 2547f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ~SYM_MASK(IBCCtrl, PhyerrThreshold); 2548f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcctrl |= (u64) val << 2549f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_LSB(IBCCtrl, PhyerrThreshold); 2550f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_ibcctrl, ppd->cpspec->ibcctrl); 2551f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_scratch, 0); 2552f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2553f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 2554f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2555f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_PKEYS: /* update pkeys */ 2556f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell maskr = (u64) ppd->pkeys[0] | ((u64) ppd->pkeys[1] << 16) | 2557f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ((u64) ppd->pkeys[2] << 32) | 2558f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ((u64) ppd->pkeys[3] << 48); 2559f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_partitionkey, maskr); 2560f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 2561f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2562f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_LINKDEFAULT: /* IB link default (sleep/poll) */ 2563f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* will only take effect when the link state changes */ 2564f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (val == IB_LINKINITCMD_POLL) 2565f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcctrl &= 2566f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ~SYM_MASK(IBCCtrl, LinkDownDefaultState); 2567f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else /* SLEEP */ 2568f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcctrl |= 2569f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK(IBCCtrl, LinkDownDefaultState); 2570f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_ibcctrl, ppd->cpspec->ibcctrl); 2571f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_scratch, 0); 2572f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 2573f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2574f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_MTU: /* update the MTU in IBC */ 2575f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 2576f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Update our housekeeping variables, and set IBC max 2577f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * size, same as init code; max IBC is max we allow in 2578f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * buffer, less the qword pbc, plus 1 for ICRC, in dwords 2579f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Set even if it's unchanged, print debug message only 2580f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * on changes. 2581f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2582f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = (ppd->ibmaxlen >> 2) + 1; 2583f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcctrl &= ~SYM_MASK(IBCCtrl, MaxPktLen); 2584f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcctrl |= (u64)val << SYM_LSB(IBCCtrl, MaxPktLen); 2585f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_ibcctrl, ppd->cpspec->ibcctrl); 2586f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_scratch, 0); 2587f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 2588f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2589f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_LSTATE: /* set the IB link state */ 2590f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell switch (val & 0xffff0000) { 2591f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case IB_LINKCMD_DOWN: 2592f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell lcmd = QLOGIC_IB_IBCC_LINKCMD_DOWN; 2593f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!ppd->cpspec->ibdeltainprog && 2594f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_compat_ddr_negotiate) { 2595f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibdeltainprog = 1; 2596f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibsymsnap = 2597f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell read_7220_creg32(dd, cr_ibsymbolerr); 2598f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->iblnkerrsnap = 2599f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell read_7220_creg32(dd, cr_iblinkerrrecov); 2600f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2601f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 2602f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2603f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case IB_LINKCMD_ARMED: 2604f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell lcmd = QLOGIC_IB_IBCC_LINKCMD_ARMED; 2605f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 2606f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2607f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case IB_LINKCMD_ACTIVE: 2608f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell lcmd = QLOGIC_IB_IBCC_LINKCMD_ACTIVE; 2609f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 2610f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2611f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell default: 2612f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = -EINVAL; 2613f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_dev_err(dd, "bad linkcmd req 0x%x\n", val >> 16); 2614f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 2615f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2616f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell switch (val & 0xffff) { 2617f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case IB_LINKINITCMD_NOP: 2618f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell licmd = 0; 2619f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 2620f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2621f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case IB_LINKINITCMD_POLL: 2622f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell licmd = QLOGIC_IB_IBCC_LINKINITCMD_POLL; 2623f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 2624f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2625f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case IB_LINKINITCMD_SLEEP: 2626f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell licmd = QLOGIC_IB_IBCC_LINKINITCMD_SLEEP; 2627f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 2628f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2629f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case IB_LINKINITCMD_DISABLE: 2630f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell licmd = QLOGIC_IB_IBCC_LINKINITCMD_DISABLE; 2631f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->chase_end = 0; 2632f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 2633f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * stop state chase counter and timer, if running. 2634f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * wait forpending timer, but don't clear .data (ppd)! 2635f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2636f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->cpspec->chase_timer.expires) { 2637f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell del_timer_sync(&ppd->cpspec->chase_timer); 2638f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->chase_timer.expires = 0; 2639f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2640f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 2641f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2642f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell default: 2643f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = -EINVAL; 2644f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_dev_err(dd, "bad linkinitcmd req 0x%x\n", 2645f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val & 0xffff); 2646f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 2647f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2648f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_set_ib_7220_lstate(ppd, lcmd, licmd); 2649e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov 2650e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov maskr = IBA7220_IBC_WIDTH_MASK; 2651e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov lsb = IBA7220_IBC_WIDTH_SHIFT; 2652e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov tmp = (ppd->cpspec->ibcddrctrl >> lsb) & maskr; 2653e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov /* If the width active on the chip does not match the 2654e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov * width in the shadow register, write the new active 2655e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov * width to the chip. 2656e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov * We don't have to worry about speed as the speed is taken 2657e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov * care of by set_7220_ibspeed_fast called by ib_updown. 2658e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov */ 2659e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov if (ppd->link_width_enabled-1 != tmp) { 2660e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov ppd->cpspec->ibcddrctrl &= ~(maskr << lsb); 2661e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov ppd->cpspec->ibcddrctrl |= 2662e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov (((u64)(ppd->link_width_enabled-1) & maskr) << 2663e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov lsb); 2664e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov qib_write_kreg(dd, kr_ibcddrctrl, 2665e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov ppd->cpspec->ibcddrctrl); 2666e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov qib_write_kreg(dd, kr_scratch, 0); 2667e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov spin_lock_irqsave(&ppd->lflags_lock, flags); 2668e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov ppd->lflags |= QIBL_IB_FORCE_NOTIFY; 2669e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov spin_unlock_irqrestore(&ppd->lflags_lock, flags); 2670e800bd032c2623b10ef38a4d7d646e3e3c7bb3adMitko Haralanov } 2671f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 2672f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2673f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case QIB_IB_CFG_HRTBT: /* set Heartbeat off/enable/auto */ 2674f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (val > IBA7220_IBC_HRTBT_MASK) { 2675f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = -EINVAL; 2676f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 2677f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2678f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell lsb = IBA7220_IBC_HRTBT_SHIFT; 2679f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell maskr = IBA7220_IBC_HRTBT_MASK; 2680f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 2681f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2682f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell default: 2683f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = -EINVAL; 2684f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 2685f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2686f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcddrctrl &= ~(maskr << lsb); 2687f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcddrctrl |= (((u64) val & maskr) << lsb); 2688f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_ibcddrctrl, ppd->cpspec->ibcddrctrl); 2689f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_scratch, 0); 2690f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (setforce) { 2691f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->lflags_lock, flags); 2692f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags |= QIBL_IB_FORCE_NOTIFY; 2693f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->lflags_lock, flags); 2694f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2695f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellbail: 2696f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return ret; 2697f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 2698f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2699f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic int qib_7220_set_loopback(struct qib_pportdata *ppd, const char *what) 2700f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 2701f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int ret = 0; 2702f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 val, ddr; 2703f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2704f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!strncmp(what, "ibc", 3)) { 2705f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcctrl |= SYM_MASK(IBCCtrl, Loopback); 2706f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = 0; /* disable heart beat, so link will come up */ 2707f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_devinfo(ppd->dd->pcidev, "Enabling IB%u:%u IBC loopback\n", 2708f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->dd->unit, ppd->port); 2709f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else if (!strncmp(what, "off", 3)) { 2710f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcctrl &= ~SYM_MASK(IBCCtrl, Loopback); 2711f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* enable heart beat again */ 2712f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = IBA7220_IBC_HRTBT_MASK << IBA7220_IBC_HRTBT_SHIFT; 27137fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn qib_devinfo(ppd->dd->pcidev, 27147fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn "Disabling IB%u:%u IBC loopback (normal)\n", 27157fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn ppd->dd->unit, ppd->port); 2716f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else 2717f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = -EINVAL; 2718f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!ret) { 2719f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(ppd->dd, kr_ibcctrl, ppd->cpspec->ibcctrl); 2720f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ddr = ppd->cpspec->ibcddrctrl & ~(IBA7220_IBC_HRTBT_MASK 2721f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell << IBA7220_IBC_HRTBT_SHIFT); 2722f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcddrctrl = ddr | val; 2723f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(ppd->dd, kr_ibcddrctrl, 2724f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcddrctrl); 2725f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(ppd->dd, kr_scratch, 0); 2726f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2727f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return ret; 2728f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 2729f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2730f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_update_7220_usrhead(struct qib_ctxtdata *rcd, u64 hd, 273119ede2e422496b2a064b9b22823c6afb66ff927bMike Marciniszyn u32 updegr, u32 egrhd, u32 npkts) 2732f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 2733f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (updegr) 2734f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt); 2735eddfb675256f49d14e8c5763098afe3eb2c93701Ram Vepa mmiowb(); 2736eddfb675256f49d14e8c5763098afe3eb2c93701Ram Vepa qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); 2737eddfb675256f49d14e8c5763098afe3eb2c93701Ram Vepa mmiowb(); 2738f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 2739f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2740f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic u32 qib_7220_hdrqempty(struct qib_ctxtdata *rcd) 2741f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 2742f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 head, tail; 2743f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2744f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell head = qib_read_ureg32(rcd->dd, ur_rcvhdrhead, rcd->ctxt); 2745f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (rcd->rcvhdrtail_kvaddr) 2746f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell tail = qib_get_rcvhdrtail(rcd); 2747f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else 2748f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell tail = qib_read_ureg32(rcd->dd, ur_rcvhdrtail, rcd->ctxt); 2749f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return head == tail; 2750f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 2751f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2752f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 2753f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Modify the RCVCTRL register in chip-specific way. This 2754f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * is a function because bit positions and (future) register 2755f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * location is chip-specifc, but the needed operations are 2756f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * generic. <op> is a bit-mask because we often want to 2757f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * do multiple modifications. 2758f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2759f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void rcvctrl_7220_mod(struct qib_pportdata *ppd, unsigned int op, 2760f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int ctxt) 2761f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 2762f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = ppd->dd; 2763f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 mask, val; 2764f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 2765f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2766f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&dd->cspec->rcvmod_lock, flags); 2767f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_RCVCTRL_TAILUPD_ENB) 2768f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvctrl |= (1ULL << IBA7220_R_TAILUPD_SHIFT); 2769f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_RCVCTRL_TAILUPD_DIS) 2770f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvctrl &= ~(1ULL << IBA7220_R_TAILUPD_SHIFT); 2771f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_RCVCTRL_PKEY_ENB) 2772f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvctrl &= ~(1ULL << IBA7220_R_PKEY_DIS_SHIFT); 2773f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_RCVCTRL_PKEY_DIS) 2774f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvctrl |= (1ULL << IBA7220_R_PKEY_DIS_SHIFT); 2775f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ctxt < 0) 2776f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell mask = (1ULL << dd->ctxtcnt) - 1; 2777f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else 2778f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell mask = (1ULL << ctxt); 2779f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_RCVCTRL_CTXT_ENB) { 2780f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* always done for specific ctxt */ 2781f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvctrl |= (mask << SYM_LSB(RcvCtrl, PortEnable)); 2782f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!(dd->flags & QIB_NODMA_RTAIL)) 2783f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvctrl |= 1ULL << IBA7220_R_TAILUPD_SHIFT; 2784f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* Write these registers before the context is enabled. */ 2785f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg_ctxt(dd, kr_rcvhdrtailaddr, ctxt, 2786f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcd[ctxt]->rcvhdrqtailaddr_phys); 2787f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg_ctxt(dd, kr_rcvhdraddr, ctxt, 2788f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcd[ctxt]->rcvhdrq_phys); 2789f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcd[ctxt]->seq_cnt = 1; 2790f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2791f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_RCVCTRL_CTXT_DIS) 2792f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvctrl &= ~(mask << SYM_LSB(RcvCtrl, PortEnable)); 2793f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_RCVCTRL_INTRAVAIL_ENB) 2794f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvctrl |= (mask << IBA7220_R_INTRAVAIL_SHIFT); 2795f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_RCVCTRL_INTRAVAIL_DIS) 2796f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvctrl &= ~(mask << IBA7220_R_INTRAVAIL_SHIFT); 2797f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_rcvctrl, dd->rcvctrl); 2798f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if ((op & QIB_RCVCTRL_INTRAVAIL_ENB) && dd->rhdrhead_intr_off) { 2799f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* arm rcv interrupt */ 2800f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = qib_read_ureg32(dd, ur_rcvhdrhead, ctxt) | 2801f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rhdrhead_intr_off; 2802f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_ureg(dd, ur_rcvhdrhead, val, ctxt); 2803f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2804f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_RCVCTRL_CTXT_ENB) { 2805f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 2806f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Init the context registers also; if we were 2807f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * disabled, tail and head should both be zero 2808f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * already from the enable, but since we don't 280925985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * know, we have to do it explicitly. 2810f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2811f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = qib_read_ureg32(dd, ur_rcvegrindextail, ctxt); 2812f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_ureg(dd, ur_rcvegrindexhead, val, ctxt); 2813f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2814f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = qib_read_ureg32(dd, ur_rcvhdrtail, ctxt); 2815f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcd[ctxt]->head = val; 2816f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* If kctxt, interrupt on next receive. */ 2817f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ctxt < dd->first_user_ctxt) 2818f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val |= dd->rhdrhead_intr_off; 2819f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_ureg(dd, ur_rcvhdrhead, val, ctxt); 2820f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2821f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_RCVCTRL_CTXT_DIS) { 2822f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ctxt >= 0) { 2823f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg_ctxt(dd, kr_rcvhdrtailaddr, ctxt, 0); 2824f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg_ctxt(dd, kr_rcvhdraddr, ctxt, 0); 2825f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else { 2826f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned i; 2827f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2828f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (i = 0; i < dd->cfgctxts; i++) { 2829f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg_ctxt(dd, kr_rcvhdrtailaddr, 2830f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell i, 0); 2831f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg_ctxt(dd, kr_rcvhdraddr, i, 0); 2832f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2833f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2834f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2835f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&dd->cspec->rcvmod_lock, flags); 2836f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 2837f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2838f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 2839f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Modify the SENDCTRL register in chip-specific way. This 2840f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * is a function there may be multiple such registers with 2841f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * slightly different layouts. To start, we assume the 2842f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * "canonical" register layout of the first chips. 2843f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Chip requires no back-back sendctrl writes, so write 2844f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * scratch register after writing sendctrl 2845f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2846f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void sendctrl_7220_mod(struct qib_pportdata *ppd, u32 op) 2847f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 2848f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = ppd->dd; 2849f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 tmp_dd_sendctrl; 2850f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 2851f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2852f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&dd->sendctrl_lock, flags); 2853f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2854f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* First the ones that are "sticky", saved in shadow */ 2855f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_SENDCTRL_CLEAR) 2856f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->sendctrl = 0; 2857f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_SENDCTRL_SEND_DIS) 2858f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->sendctrl &= ~SYM_MASK(SendCtrl, SPioEnable); 2859f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else if (op & QIB_SENDCTRL_SEND_ENB) { 2860f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->sendctrl |= SYM_MASK(SendCtrl, SPioEnable); 2861f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->flags & QIB_USE_SPCL_TRIG) 2862f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->sendctrl |= SYM_MASK(SendCtrl, 2863f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SSpecialTriggerEn); 2864f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2865f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_SENDCTRL_AVAIL_DIS) 2866f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->sendctrl &= ~SYM_MASK(SendCtrl, SendBufAvailUpd); 2867f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else if (op & QIB_SENDCTRL_AVAIL_ENB) 2868f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->sendctrl |= SYM_MASK(SendCtrl, SendBufAvailUpd); 2869f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2870f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_SENDCTRL_DISARM_ALL) { 2871f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 i, last; 2872f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2873f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell tmp_dd_sendctrl = dd->sendctrl; 2874f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 2875f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * disarm any that are not yet launched, disabling sends 2876f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * and updates until done. 2877f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2878f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell last = dd->piobcnt2k + dd->piobcnt4k; 2879f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell tmp_dd_sendctrl &= 2880f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ~(SYM_MASK(SendCtrl, SPioEnable) | 2881f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK(SendCtrl, SendBufAvailUpd)); 2882f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (i = 0; i < last; i++) { 2883f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_sendctrl, 2884f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell tmp_dd_sendctrl | 2885f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK(SendCtrl, Disarm) | i); 2886f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_scratch, 0); 2887f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2888f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2889f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2890f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell tmp_dd_sendctrl = dd->sendctrl; 2891f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2892f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_SENDCTRL_FLUSH) 2893f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell tmp_dd_sendctrl |= SYM_MASK(SendCtrl, Abort); 2894f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_SENDCTRL_DISARM) 2895f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell tmp_dd_sendctrl |= SYM_MASK(SendCtrl, Disarm) | 2896f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ((op & QIB_7220_SendCtrl_DisarmPIOBuf_RMASK) << 2897f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_LSB(SendCtrl, DisarmPIOBuf)); 2898f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if ((op & QIB_SENDCTRL_AVAIL_BLIP) && 2899f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (dd->sendctrl & SYM_MASK(SendCtrl, SendBufAvailUpd))) 2900f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell tmp_dd_sendctrl &= ~SYM_MASK(SendCtrl, SendBufAvailUpd); 2901f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2902f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_sendctrl, tmp_dd_sendctrl); 2903f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_scratch, 0); 2904f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2905f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_SENDCTRL_AVAIL_BLIP) { 2906f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_sendctrl, dd->sendctrl); 2907f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_scratch, 0); 2908f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2909f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2910f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&dd->sendctrl_lock, flags); 2911f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2912f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (op & QIB_SENDCTRL_FLUSH) { 2913f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 v; 2914f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 2915f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * ensure writes have hit chip, then do a few 2916f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * more reads, to allow DMA of pioavail registers 2917f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * to occur, so in-memory copy is in sync with 2918f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * the chip. Not always safe to sleep. 2919f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2920f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell v = qib_read_kreg32(dd, kr_scratch); 2921f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_scratch, v); 2922f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell v = qib_read_kreg32(dd, kr_scratch); 2923f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_scratch, v); 2924f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_read_kreg32(dd, kr_scratch); 2925f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2926f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 2927f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2928f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/** 2929f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_portcntr_7220 - read a per-port counter 2930f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @dd: the qlogic_ib device 2931f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @creg: the counter to snapshot 2932f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2933f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic u64 qib_portcntr_7220(struct qib_pportdata *ppd, u32 reg) 2934f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 2935f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 ret = 0ULL; 2936f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = ppd->dd; 2937f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u16 creg; 2938f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 0xffff for unimplemented or synthesized counters */ 2939f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell static const u16 xlator[] = { 2940f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_PKTSEND] = cr_pktsend, 2941f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_WORDSEND] = cr_wordsend, 2942f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_PSXMITDATA] = cr_psxmitdatacount, 2943f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_PSXMITPKTS] = cr_psxmitpktscount, 2944f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_PSXMITWAIT] = cr_psxmitwaitcount, 2945f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_SENDSTALL] = cr_sendstall, 2946f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_PKTRCV] = cr_pktrcv, 2947f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_PSRCVDATA] = cr_psrcvdatacount, 2948f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_PSRCVPKTS] = cr_psrcvpktscount, 2949f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_RCVEBP] = cr_rcvebp, 2950f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_RCVOVFL] = cr_rcvovfl, 2951f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_WORDRCV] = cr_wordrcv, 2952f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_RXDROPPKT] = cr_rxdroppkt, 2953f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_RXLOCALPHYERR] = cr_rxotherlocalphyerr, 2954f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_RXVLERR] = cr_rxvlerr, 2955f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_ERRICRC] = cr_erricrc, 2956f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_ERRVCRC] = cr_errvcrc, 2957f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_ERRLPCRC] = cr_errlpcrc, 2958f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_BADFORMAT] = cr_badformat, 2959f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_ERR_RLEN] = cr_err_rlen, 2960f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_IBSYMBOLERR] = cr_ibsymbolerr, 2961f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_INVALIDRLEN] = cr_invalidrlen, 2962f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_UNSUPVL] = cr_txunsupvl, 2963f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_EXCESSBUFOVFL] = cr_excessbufferovfl, 2964f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_ERRLINK] = cr_errlink, 2965f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_IBLINKDOWN] = cr_iblinkdown, 2966f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_IBLINKERRRECOV] = cr_iblinkerrrecov, 2967f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_LLI] = cr_locallinkintegrityerr, 2968f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_PSINTERVAL] = cr_psinterval, 2969f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_PSSTART] = cr_psstart, 2970f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_PSSTAT] = cr_psstat, 2971f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_VL15PKTDROP] = cr_vl15droppedpkt, 2972f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_ERRPKEY] = cr_errpkey, 2973f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [QIBPORTCNTR_KHDROVFL] = 0xffff, 2974f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell }; 2975f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2976f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (reg >= ARRAY_SIZE(xlator)) { 2977f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_devinfo(ppd->dd->pcidev, 2978f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "Unimplemented portcounter %u\n", reg); 2979f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 2980f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2981f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell creg = xlator[reg]; 2982f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2983f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (reg == QIBPORTCNTR_KHDROVFL) { 2984f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int i; 2985f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2986f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* sum over all kernel contexts */ 2987f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (i = 0; i < dd->first_user_ctxt; i++) 2988f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret += read_7220_creg32(dd, cr_portovfl + i); 2989f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 2990f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (creg == 0xffff) 2991f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 2992f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 2993f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 2994f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * only fast incrementing counters are 64bit; use 32 bit reads to 2995f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * avoid two independent reads when on opteron 2996f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2997f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if ((creg == cr_wordsend || creg == cr_wordrcv || 2998f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell creg == cr_pktsend || creg == cr_pktrcv)) 2999f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = read_7220_creg(dd, creg); 3000f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else 3001f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = read_7220_creg32(dd, creg); 3002f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (creg == cr_ibsymbolerr) { 3003f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->pport->cpspec->ibdeltainprog) 3004f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret -= ret - ppd->cpspec->ibsymsnap; 3005f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret -= dd->pport->cpspec->ibsymdelta; 3006f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else if (creg == cr_iblinkerrrecov) { 3007f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->pport->cpspec->ibdeltainprog) 3008f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret -= ret - ppd->cpspec->iblnkerrsnap; 3009f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret -= dd->pport->cpspec->iblnkerrdelta; 3010f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3011f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbelldone: 3012f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return ret; 3013f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3014f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3015f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 3016f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Device counter names (not port-specific), one line per stat, 3017f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * single string. Used by utilities like ipathstats to print the stats 3018f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * in a way which works for different versions of drivers, without changing 3019f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * the utility. Names need to be 12 chars or less (w/o newline), for proper 3020f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * display by utility. 3021f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Non-error counters are first. 3022f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Start of "error" conters is indicated by a leading "E " on the first 3023f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * "error" counter, and doesn't count in label length. 3024f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * The EgrOvfl list needs to be last so we truncate them at the configured 3025f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * context count for the device. 3026f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * cntr7220indices contains the corresponding register indices. 3027f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3028f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic const char cntr7220names[] = 3029f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "Interrupts\n" 3030f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "HostBusStall\n" 3031f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "E RxTIDFull\n" 3032f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RxTIDInvalid\n" 3033f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "Ctxt0EgrOvfl\n" 3034f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "Ctxt1EgrOvfl\n" 3035f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "Ctxt2EgrOvfl\n" 3036f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "Ctxt3EgrOvfl\n" 3037f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "Ctxt4EgrOvfl\n" 3038f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "Ctxt5EgrOvfl\n" 3039f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "Ctxt6EgrOvfl\n" 3040f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "Ctxt7EgrOvfl\n" 3041f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "Ctxt8EgrOvfl\n" 3042f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "Ctxt9EgrOvfl\n" 3043f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "Ctx10EgrOvfl\n" 3044f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "Ctx11EgrOvfl\n" 3045f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "Ctx12EgrOvfl\n" 3046f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "Ctx13EgrOvfl\n" 3047f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "Ctx14EgrOvfl\n" 3048f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "Ctx15EgrOvfl\n" 3049f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "Ctx16EgrOvfl\n"; 3050f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3051f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic const size_t cntr7220indices[] = { 3052f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_lbint, 3053f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_lbflowstall, 3054f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_errtidfull, 3055f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_errtidvalid, 3056f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_portovfl + 0, 3057f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_portovfl + 1, 3058f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_portovfl + 2, 3059f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_portovfl + 3, 3060f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_portovfl + 4, 3061f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_portovfl + 5, 3062f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_portovfl + 6, 3063f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_portovfl + 7, 3064f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_portovfl + 8, 3065f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_portovfl + 9, 3066f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_portovfl + 10, 3067f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_portovfl + 11, 3068f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_portovfl + 12, 3069f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_portovfl + 13, 3070f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_portovfl + 14, 3071f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_portovfl + 15, 3072f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_portovfl + 16, 3073f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell}; 3074f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3075f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 3076f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * same as cntr7220names and cntr7220indices, but for port-specific counters. 3077f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * portcntr7220indices is somewhat complicated by some registers needing 3078f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * adjustments of various kinds, and those are ORed with _PORT_VIRT_FLAG 3079f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3080f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic const char portcntr7220names[] = 3081f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "TxPkt\n" 3082f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "TxFlowPkt\n" 3083f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "TxWords\n" 3084f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RxPkt\n" 3085f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RxFlowPkt\n" 3086f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RxWords\n" 3087f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "TxFlowStall\n" 3088f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "TxDmaDesc\n" /* 7220 and 7322-only */ 3089f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "E RxDlidFltr\n" /* 7220 and 7322-only */ 3090f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "IBStatusChng\n" 3091f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "IBLinkDown\n" 3092f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "IBLnkRecov\n" 3093f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "IBRxLinkErr\n" 3094f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "IBSymbolErr\n" 3095f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RxLLIErr\n" 3096f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RxBadFormat\n" 3097f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RxBadLen\n" 3098f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RxBufOvrfl\n" 3099f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RxEBP\n" 3100f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RxFlowCtlErr\n" 3101f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RxICRCerr\n" 3102f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RxLPCRCerr\n" 3103f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RxVCRCerr\n" 3104f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RxInvalLen\n" 3105f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RxInvalPKey\n" 3106f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RxPktDropped\n" 3107f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "TxBadLength\n" 3108f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "TxDropped\n" 3109f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "TxInvalLen\n" 3110f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "TxUnderrun\n" 3111f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "TxUnsupVL\n" 3112f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RxLclPhyErr\n" /* 7220 and 7322-only */ 3113f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RxVL15Drop\n" /* 7220 and 7322-only */ 3114f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "RxVlErr\n" /* 7220 and 7322-only */ 3115f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "XcessBufOvfl\n" /* 7220 and 7322-only */ 3116f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ; 3117f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3118f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define _PORT_VIRT_FLAG 0x8000 /* "virtual", need adjustments */ 3119f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic const size_t portcntr7220indices[] = { 3120f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_PKTSEND | _PORT_VIRT_FLAG, 3121f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_pktsendflow, 3122f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_WORDSEND | _PORT_VIRT_FLAG, 3123f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_PKTRCV | _PORT_VIRT_FLAG, 3124f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_pktrcvflowctrl, 3125f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_WORDRCV | _PORT_VIRT_FLAG, 3126f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_SENDSTALL | _PORT_VIRT_FLAG, 3127f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_txsdmadesc, 3128f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_rxdlidfltr, 3129f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_ibstatuschange, 3130f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_IBLINKDOWN | _PORT_VIRT_FLAG, 3131f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_IBLINKERRRECOV | _PORT_VIRT_FLAG, 3132f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_ERRLINK | _PORT_VIRT_FLAG, 3133f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_IBSYMBOLERR | _PORT_VIRT_FLAG, 3134f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_LLI | _PORT_VIRT_FLAG, 3135f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_BADFORMAT | _PORT_VIRT_FLAG, 3136f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_ERR_RLEN | _PORT_VIRT_FLAG, 3137f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_RCVOVFL | _PORT_VIRT_FLAG, 3138f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_RCVEBP | _PORT_VIRT_FLAG, 3139f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_rcvflowctrl_err, 3140f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_ERRICRC | _PORT_VIRT_FLAG, 3141f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_ERRLPCRC | _PORT_VIRT_FLAG, 3142f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_ERRVCRC | _PORT_VIRT_FLAG, 3143f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_INVALIDRLEN | _PORT_VIRT_FLAG, 3144f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_ERRPKEY | _PORT_VIRT_FLAG, 3145f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_RXDROPPKT | _PORT_VIRT_FLAG, 3146f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_invalidslen, 3147f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_senddropped, 3148f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_errslen, 3149f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_sendunderrun, 3150f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_txunsupvl, 3151f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_RXLOCALPHYERR | _PORT_VIRT_FLAG, 3152f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_VL15PKTDROP | _PORT_VIRT_FLAG, 3153f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_RXVLERR | _PORT_VIRT_FLAG, 3154f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBPORTCNTR_EXCESSBUFOVFL | _PORT_VIRT_FLAG, 3155f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell}; 3156f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3157f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* do all the setup to make the counter reads efficient later */ 3158f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void init_7220_cntrnames(struct qib_devdata *dd) 3159f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 3160f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int i, j = 0; 3161f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell char *s; 3162f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3163f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (i = 0, s = (char *)cntr7220names; s && j <= dd->cfgctxts; 3164f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell i++) { 3165f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* we always have at least one counter before the egrovfl */ 3166f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!j && !strncmp("Ctxt0EgrOvfl", s + 1, 12)) 3167f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell j = 1; 3168f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell s = strchr(s + 1, '\n'); 3169f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (s && j) 3170f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell j++; 3171f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3172f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->ncntrs = i; 3173f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!s) 3174f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* full list; size is without terminating null */ 3175f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->cntrnamelen = sizeof(cntr7220names) - 1; 3176f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else 3177f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->cntrnamelen = 1 + s - cntr7220names; 3178f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->cntrs = kmalloc(dd->cspec->ncntrs 3179f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * sizeof(u64), GFP_KERNEL); 3180f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!dd->cspec->cntrs) 3181f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_dev_err(dd, "Failed allocation for counters\n"); 3182f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3183f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (i = 0, s = (char *)portcntr7220names; s; i++) 3184f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell s = strchr(s + 1, '\n'); 3185f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->nportcntrs = i - 1; 3186f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->portcntrnamelen = sizeof(portcntr7220names) - 1; 3187f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->portcntrs = kmalloc(dd->cspec->nportcntrs 3188f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * sizeof(u64), GFP_KERNEL); 3189f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!dd->cspec->portcntrs) 3190f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_dev_err(dd, "Failed allocation for portcounters\n"); 3191f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3192f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3193f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic u32 qib_read_7220cntrs(struct qib_devdata *dd, loff_t pos, char **namep, 3194f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 **cntrp) 3195f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 3196f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 ret; 3197f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3198f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!dd->cspec->cntrs) { 3199f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = 0; 3200f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 3201f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3202f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3203f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (namep) { 3204f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell *namep = (char *)cntr7220names; 3205f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = dd->cspec->cntrnamelen; 3206f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (pos >= ret) 3207f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = 0; /* final read after getting everything */ 3208f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else { 3209f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 *cntr = dd->cspec->cntrs; 3210f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int i; 3211f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3212f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = dd->cspec->ncntrs * sizeof(u64); 3213f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!cntr || pos >= ret) { 3214f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* everything read, or couldn't get memory */ 3215f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = 0; 3216f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 3217f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3218f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3219f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell *cntrp = cntr; 3220f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (i = 0; i < dd->cspec->ncntrs; i++) 3221f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell *cntr++ = read_7220_creg32(dd, cntr7220indices[i]); 3222f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3223f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbelldone: 3224f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return ret; 3225f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3226f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3227f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic u32 qib_read_7220portcntrs(struct qib_devdata *dd, loff_t pos, u32 port, 3228f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell char **namep, u64 **cntrp) 3229f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 3230f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 ret; 3231f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3232f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!dd->cspec->portcntrs) { 3233f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = 0; 3234f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 3235f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3236f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (namep) { 3237f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell *namep = (char *)portcntr7220names; 3238f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = dd->cspec->portcntrnamelen; 3239f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (pos >= ret) 3240f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = 0; /* final read after getting everything */ 3241f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else { 3242f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 *cntr = dd->cspec->portcntrs; 3243f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_pportdata *ppd = &dd->pport[port]; 3244f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int i; 3245f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3246f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = dd->cspec->nportcntrs * sizeof(u64); 3247f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!cntr || pos >= ret) { 3248f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* everything read, or couldn't get memory */ 3249f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = 0; 3250f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 3251f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3252f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell *cntrp = cntr; 3253f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (i = 0; i < dd->cspec->nportcntrs; i++) { 3254f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (portcntr7220indices[i] & _PORT_VIRT_FLAG) 3255f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell *cntr++ = qib_portcntr_7220(ppd, 3256f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell portcntr7220indices[i] & 3257f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ~_PORT_VIRT_FLAG); 3258f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else 3259f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell *cntr++ = read_7220_creg32(dd, 3260f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell portcntr7220indices[i]); 3261f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3262f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3263f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbelldone: 3264f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return ret; 3265f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3266f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3267f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/** 3268f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_get_7220_faststats - get word counters from chip before they overflow 3269f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @opaque - contains a pointer to the qlogic_ib device qib_devdata 3270f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 3271f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * This needs more work; in particular, decision on whether we really 3272f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * need traffic_wds done the way it is 3273f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * called from add_timer 3274f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3275f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_get_7220_faststats(unsigned long opaque) 3276f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 3277f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = (struct qib_devdata *) opaque; 3278f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_pportdata *ppd = dd->pport; 3279f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 3280f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 traffic_wds; 3281f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3282f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 3283f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * don't access the chip while running diags, or memory diags can 3284f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * fail 3285f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3286f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!(dd->flags & QIB_INITTED) || dd->diag_client) 3287f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* but re-arm the timer, for diags case; won't hurt other */ 3288f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 3289f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3290f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 3291f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * We now try to maintain an activity timer, based on traffic 3292f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * exceeding a threshold, so we need to check the word-counts 3293f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * even if they are 64-bit. 3294f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3295f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell traffic_wds = qib_portcntr_7220(ppd, cr_wordsend) + 3296f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_portcntr_7220(ppd, cr_wordrcv); 3297f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&dd->eep_st_lock, flags); 3298f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell traffic_wds -= dd->traffic_wds; 3299f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->traffic_wds += traffic_wds; 3300f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (traffic_wds >= QIB_TRAFFIC_ACTIVE_THRESHOLD) 3301f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell atomic_add(5, &dd->active_time); /* S/B #define */ 3302f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&dd->eep_st_lock, flags); 3303f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbelldone: 3304f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell mod_timer(&dd->stats_timer, jiffies + HZ * ACTIVITY_TIMER); 3305f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3306f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3307f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 3308f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * If we are using MSI, try to fallback to INTx. 3309f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3310f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic int qib_7220_intr_fallback(struct qib_devdata *dd) 3311f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 3312f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!dd->msi_lo) 3313f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return 0; 3314f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 33157fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn qib_devinfo(dd->pcidev, 33167fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn "MSI interrupt not detected, trying INTx interrupts\n"); 3317f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_7220_free_irq(dd); 3318f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_enable_intx(dd->pcidev); 3319f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 3320f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Some newer kernels require free_irq before disable_msi, 3321f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * and irq can be changed during disable and INTx enable 3322f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * and we need to therefore use the pcidev->irq value, 3323f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * not our saved MSI value. 3324f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3325f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->irq = dd->pcidev->irq; 3326f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_setup_7220_interrupt(dd); 3327f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return 1; 3328f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3329f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3330f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 3331f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Reset the XGXS (between serdes and IBC). Slightly less intrusive 3332f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * than resetting the IBC or external link state, and useful in some 3333f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * cases to cause some retraining. To do this right, we reset IBC 3334f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * as well. 3335f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3336f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_xgxs_reset(struct qib_pportdata *ppd) 3337f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 3338f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 val, prev_val; 3339f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = ppd->dd; 3340f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3341f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell prev_val = qib_read_kreg64(dd, kr_xgxs_cfg); 3342f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = prev_val | QLOGIC_IB_XGXS_RESET; 3343f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell prev_val &= ~QLOGIC_IB_XGXS_RESET; /* be sure */ 3344f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_control, 3345f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->control & ~QLOGIC_IB_C_LINKENABLE); 3346f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_xgxs_cfg, val); 3347f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_read_kreg32(dd, kr_scratch); 3348f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_xgxs_cfg, prev_val); 3349f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_control, dd->control); 3350f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3351f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3352f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 3353f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * For this chip, we want to use the same buffer every time 3354f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * when we are trying to bring the link up (they are always VL15 3355f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * packets). At that link state the packet should always go out immediately 3356f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * (or at least be discarded at the tx interface if the link is down). 3357f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * If it doesn't, and the buffer isn't available, that means some other 3358f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * sender has gotten ahead of us, and is preventing our packet from going 3359f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * out. In that case, we flush all packets, and try again. If that still 3360f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * fails, we fail the request, and hope things work the next time around. 3361f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 3362f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * We don't need very complicated heuristics on whether the packet had 3363f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * time to go out or not, since even at SDR 1X, it goes out in very short 3364f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * time periods, covered by the chip reads done here and as part of the 3365f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * flush. 3366f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3367f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic u32 __iomem *get_7220_link_buf(struct qib_pportdata *ppd, u32 *bnum) 3368f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 3369f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 __iomem *buf; 3370f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 lbuf = ppd->dd->cspec->lastbuf_for_pio; 3371f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int do_cleanup; 3372f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 3373f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3374f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 3375f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * always blip to get avail list updated, since it's almost 3376f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * always needed, and is fairly cheap. 3377f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3378f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sendctrl_7220_mod(ppd->dd->pport, QIB_SENDCTRL_AVAIL_BLIP); 3379f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_read_kreg64(ppd->dd, kr_scratch); /* extra chip flush */ 3380f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell buf = qib_getsendbuf_range(ppd->dd, bnum, lbuf, lbuf); 3381f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (buf) 3382f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 3383f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3384f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->sdma_lock, flags); 3385f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->sdma_state.current_state == qib_sdma_state_s20_idle && 3386f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->sdma_state.current_state != qib_sdma_state_s00_hw_down) { 3387f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell __qib_sdma_process_event(ppd, qib_sdma_event_e00_go_hw_down); 3388f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell do_cleanup = 0; 3389f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else { 3390f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell do_cleanup = 1; 3391f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_7220_sdma_hw_clean_up(ppd); 3392f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3393f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->sdma_lock, flags); 3394f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3395f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (do_cleanup) { 3396f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_read_kreg64(ppd->dd, kr_scratch); /* extra chip flush */ 3397f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell buf = qib_getsendbuf_range(ppd->dd, bnum, lbuf, lbuf); 3398f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3399f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbelldone: 3400f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return buf; 3401f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3402f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3403f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 3404f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * This code for non-IBTA-compliant IB speed negotiation is only known to 3405f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * work for the SDR to DDR transition, and only between an HCA and a switch 3406f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * with recent firmware. It is based on observed heuristics, rather than 3407f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * actual knowledge of the non-compliant speed negotiation. 3408f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * It has a number of hard-coded fields, since the hope is to rewrite this 3409f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * when a spec is available on how the negoation is intended to work. 3410f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3411f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void autoneg_7220_sendpkt(struct qib_pportdata *ppd, u32 *hdr, 3412f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 dcnt, u32 *data) 3413f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 3414f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int i; 3415f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 pbc; 3416f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 __iomem *piobuf; 3417f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 pnum; 3418f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = ppd->dd; 3419f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3420f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell i = 0; 3421f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell pbc = 7 + dcnt + 1; /* 7 dword header, dword data, icrc */ 3422f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell pbc |= PBC_7220_VL15_SEND; 3423f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell while (!(piobuf = get_7220_link_buf(ppd, &pnum))) { 3424f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (i++ > 5) 3425f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return; 3426f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell udelay(2); 3427f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3428f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sendctrl_7220_mod(dd->pport, QIB_SENDCTRL_DISARM_BUF(pnum)); 3429f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell writeq(pbc, piobuf); 3430f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_flush_wc(); 3431f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_pio_copy(piobuf + 2, hdr, 7); 3432f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_pio_copy(piobuf + 9, data, dcnt); 3433f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->flags & QIB_USE_SPCL_TRIG) { 3434f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 spcl_off = (pnum >= dd->piobcnt2k) ? 2047 : 1023; 3435f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3436f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_flush_wc(); 3437f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell __raw_writel(0xaebecede, piobuf + spcl_off); 3438f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3439f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_flush_wc(); 3440f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_sendbuf_done(dd, pnum); 3441f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3442f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3443f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 3444f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * _start packet gets sent twice at start, _done gets sent twice at end 3445f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3446f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void autoneg_7220_send(struct qib_pportdata *ppd, int which) 3447f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 3448f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = ppd->dd; 3449f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell static u32 swapped; 3450f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 dw, i, hcnt, dcnt, *data; 3451f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell static u32 hdr[7] = { 0xf002ffff, 0x48ffff, 0x6400abba }; 3452f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell static u32 madpayload_start[0x40] = { 3453f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 0x1810103, 0x1, 0x0, 0x0, 0x2c90000, 0x2c9, 0x0, 0x0, 3454f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 0xffffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 3455f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 0x1, 0x1388, 0x15e, 0x1, /* rest 0's */ 3456f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell }; 3457f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell static u32 madpayload_done[0x40] = { 3458f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 0x1810103, 0x1, 0x0, 0x0, 0x2c90000, 0x2c9, 0x0, 0x0, 3459f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 0xffffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 3460f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 0x40000001, 0x1388, 0x15e, /* rest 0's */ 3461f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell }; 3462f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3463f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dcnt = ARRAY_SIZE(madpayload_start); 3464f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell hcnt = ARRAY_SIZE(hdr); 3465f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!swapped) { 3466f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* for maintainability, do it at runtime */ 3467f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (i = 0; i < hcnt; i++) { 3468f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dw = (__force u32) cpu_to_be32(hdr[i]); 3469f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell hdr[i] = dw; 3470f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3471f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (i = 0; i < dcnt; i++) { 3472f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dw = (__force u32) cpu_to_be32(madpayload_start[i]); 3473f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell madpayload_start[i] = dw; 3474f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dw = (__force u32) cpu_to_be32(madpayload_done[i]); 3475f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell madpayload_done[i] = dw; 3476f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3477f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell swapped = 1; 3478f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3479f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3480f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell data = which ? madpayload_done : madpayload_start; 3481f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3482f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell autoneg_7220_sendpkt(ppd, hdr, dcnt, data); 3483f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_read_kreg64(dd, kr_scratch); 3484f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell udelay(2); 3485f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell autoneg_7220_sendpkt(ppd, hdr, dcnt, data); 3486f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_read_kreg64(dd, kr_scratch); 3487f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell udelay(2); 3488f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3489f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3490f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 3491f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Do the absolute minimum to cause an IB speed change, and make it 3492f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * ready, but don't actually trigger the change. The caller will 3493f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * do that when ready (if link is in Polling training state, it will 3494f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * happen immediately, otherwise when link next goes down) 3495f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 3496f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * This routine should only be used as part of the DDR autonegotation 3497f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * code for devices that are not compliant with IB 1.2 (or code that 3498f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * fixes things up for same). 3499f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 3500f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * When link has gone down, and autoneg enabled, or autoneg has 3501f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * failed and we give up until next time we set both speeds, and 3502f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * then we want IBTA enabled as well as "use max enabled speed. 3503f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3504f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void set_7220_ibspeed_fast(struct qib_pportdata *ppd, u32 speed) 3505f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 3506f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcddrctrl &= ~(IBA7220_IBC_SPEED_AUTONEG_MASK | 3507f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IBA7220_IBC_IBTA_1_2_MASK); 3508f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3509f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (speed == (QIB_IB_SDR | QIB_IB_DDR)) 3510f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcddrctrl |= IBA7220_IBC_SPEED_AUTONEG_MASK | 3511f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IBA7220_IBC_IBTA_1_2_MASK; 3512f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else 3513f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcddrctrl |= speed == QIB_IB_DDR ? 3514f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IBA7220_IBC_SPEED_DDR : IBA7220_IBC_SPEED_SDR; 3515f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3516f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(ppd->dd, kr_ibcddrctrl, ppd->cpspec->ibcddrctrl); 3517f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(ppd->dd, kr_scratch, 0); 3518f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3519f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3520f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 3521f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * This routine is only used when we are not talking to another 3522f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * IB 1.2-compliant device that we think can do DDR. 3523f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * (This includes all existing switch chips as of Oct 2007.) 3524f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 1.2-compliant devices go directly to DDR prior to reaching INIT 3525f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3526f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void try_7220_autoneg(struct qib_pportdata *ppd) 3527f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 3528f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 3529f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3530f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 3531f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Required for older non-IB1.2 DDR switches. Newer 3532f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * non-IB-compliant switches don't need it, but so far, 3533f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * aren't bothered by it either. "Magic constant" 3534f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3535f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(ppd->dd, kr_ncmodectrl, 0x3b9dc07); 3536f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3537f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->lflags_lock, flags); 3538f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags |= QIBL_IB_AUTONEG_INPROG; 3539f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->lflags_lock, flags); 3540f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell autoneg_7220_send(ppd, 0); 3541f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell set_7220_ibspeed_fast(ppd, QIB_IB_DDR); 3542f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3543f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell toggle_7220_rclkrls(ppd->dd); 3544f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 2 msec is minimum length of a poll cycle */ 3545f06267104dd9112f11586830d22501d0e26245eaTejun Heo queue_delayed_work(ib_wq, &ppd->cpspec->autoneg_work, 3546f06267104dd9112f11586830d22501d0e26245eaTejun Heo msecs_to_jiffies(2)); 3547f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3548f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3549f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 3550f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Handle the empirically determined mechanism for auto-negotiation 3551f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * of DDR speed with switches. 3552f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3553f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void autoneg_7220_work(struct work_struct *work) 3554f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 3555f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_pportdata *ppd; 3556f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd; 3557f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 startms; 3558f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 i; 3559f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 3560f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3561f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd = &container_of(work, struct qib_chippport_specific, 3562f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell autoneg_work.work)->pportdata; 3563f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd = ppd->dd; 3564f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3565f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell startms = jiffies_to_msecs(jiffies); 3566f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3567f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 3568f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Busy wait for this first part, it should be at most a 3569f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * few hundred usec, since we scheduled ourselves for 2msec. 3570f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3571f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (i = 0; i < 25; i++) { 3572f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (SYM_FIELD(ppd->lastibcstat, IBCStatus, LinkTrainingState) 3573f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell == IB_7220_LT_STATE_POLLQUIET) { 3574f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_set_linkstate(ppd, QIB_IB_LINKDOWN_DISABLE); 3575f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 3576f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3577f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell udelay(100); 3578f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3579f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3580f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) 3581f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; /* we got there early or told to stop */ 3582f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3583f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* we expect this to timeout */ 3584f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (wait_event_timeout(ppd->cpspec->autoneg_wait, 3585f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell !(ppd->lflags & QIBL_IB_AUTONEG_INPROG), 3586f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell msecs_to_jiffies(90))) 3587f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 3588f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3589f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell toggle_7220_rclkrls(dd); 3590f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3591f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* we expect this to timeout */ 3592f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (wait_event_timeout(ppd->cpspec->autoneg_wait, 3593f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell !(ppd->lflags & QIBL_IB_AUTONEG_INPROG), 3594f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell msecs_to_jiffies(1700))) 3595f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto done; 3596f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3597f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell set_7220_ibspeed_fast(ppd, QIB_IB_SDR); 3598f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell toggle_7220_rclkrls(dd); 3599f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3600f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 3601f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Wait up to 250 msec for link to train and get to INIT at DDR; 3602f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * this should terminate early. 3603f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3604f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell wait_event_timeout(ppd->cpspec->autoneg_wait, 3605f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell !(ppd->lflags & QIBL_IB_AUTONEG_INPROG), 3606f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell msecs_to_jiffies(250)); 3607f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbelldone: 3608f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->lflags & QIBL_IB_AUTONEG_INPROG) { 3609f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->lflags_lock, flags); 3610f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags &= ~QIBL_IB_AUTONEG_INPROG; 3611f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->cspec->autoneg_tries == AUTONEG_TRIES) { 3612f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags |= QIBL_IB_AUTONEG_FAILED; 3613f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->autoneg_tries = 0; 3614f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3615f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->lflags_lock, flags); 3616f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell set_7220_ibspeed_fast(ppd, ppd->link_speed_enabled); 3617f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3618f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3619f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3620f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic u32 qib_7220_iblink_state(u64 ibcs) 3621f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 3622f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 state = (u32)SYM_FIELD(ibcs, IBCStatus, LinkState); 3623f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3624f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell switch (state) { 3625f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case IB_7220_L_STATE_INIT: 3626f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell state = IB_PORT_INIT; 3627f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 3628f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case IB_7220_L_STATE_ARM: 3629f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell state = IB_PORT_ARMED; 3630f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 3631f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case IB_7220_L_STATE_ACTIVE: 3632f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* fall through */ 3633f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case IB_7220_L_STATE_ACT_DEFER: 3634f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell state = IB_PORT_ACTIVE; 3635f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 3636f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell default: /* fall through */ 3637f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case IB_7220_L_STATE_DOWN: 3638f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell state = IB_PORT_DOWN; 3639f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 3640f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3641f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return state; 3642f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3643f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3644f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* returns the IBTA port state, rather than the IBC link training state */ 3645f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic u8 qib_7220_phys_portstate(u64 ibcs) 3646f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 3647f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u8 state = (u8)SYM_FIELD(ibcs, IBCStatus, LinkTrainingState); 3648f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return qib_7220_physportstate[state]; 3649f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3650f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3651f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic int qib_7220_ib_updown(struct qib_pportdata *ppd, int ibup, u64 ibcs) 3652f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 3653f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int ret = 0, symadj = 0; 3654f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = ppd->dd; 3655f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 3656f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3657f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->lflags_lock, flags); 3658f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags &= ~QIBL_IB_FORCE_NOTIFY; 3659f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->lflags_lock, flags); 3660f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3661f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!ibup) { 3662f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 3663f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * When the link goes down we don't want AEQ running, so it 3664f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * won't interfere with IBC training, etc., and we need 3665f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * to go back to the static SerDes preset values. 3666f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3667f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!(ppd->lflags & (QIBL_IB_AUTONEG_FAILED | 3668f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBL_IB_AUTONEG_INPROG))) 3669f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell set_7220_ibspeed_fast(ppd, ppd->link_speed_enabled); 3670f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) { 3671f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_sd7220_presets(dd); 3672f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_cancel_sends(ppd); /* initial disarm, etc. */ 3673f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->sdma_lock, flags); 3674f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (__qib_sdma_running(ppd)) 3675f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell __qib_sdma_process_event(ppd, 3676f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_sdma_event_e70_go_idle); 3677f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->sdma_lock, flags); 3678f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3679f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* this might better in qib_sd7220_presets() */ 3680f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell set_7220_relock_poll(dd, ibup); 3681f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else { 3682f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (qib_compat_ddr_negotiate && 3683f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell !(ppd->lflags & (QIBL_IB_AUTONEG_FAILED | 3684f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBL_IB_AUTONEG_INPROG)) && 3685f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->link_speed_active == QIB_IB_SDR && 3686f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (ppd->link_speed_enabled & (QIB_IB_DDR | QIB_IB_SDR)) == 3687f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (QIB_IB_DDR | QIB_IB_SDR) && 3688f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->autoneg_tries < AUTONEG_TRIES) { 3689f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* we are SDR, and DDR auto-negotiation enabled */ 3690f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ++dd->cspec->autoneg_tries; 3691f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!ppd->cpspec->ibdeltainprog) { 3692f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibdeltainprog = 1; 3693f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibsymsnap = read_7220_creg32(dd, 3694f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_ibsymbolerr); 3695f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->iblnkerrsnap = read_7220_creg32(dd, 3696f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_iblinkerrrecov); 3697f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3698f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell try_7220_autoneg(ppd); 3699f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = 1; /* no other IB status change processing */ 3700f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else if ((ppd->lflags & QIBL_IB_AUTONEG_INPROG) && 3701f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->link_speed_active == QIB_IB_SDR) { 3702f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell autoneg_7220_send(ppd, 1); 3703f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell set_7220_ibspeed_fast(ppd, QIB_IB_DDR); 3704f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell udelay(2); 3705f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell toggle_7220_rclkrls(dd); 3706f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = 1; /* no other IB status change processing */ 3707f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else { 3708f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if ((ppd->lflags & QIBL_IB_AUTONEG_INPROG) && 3709f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (ppd->link_speed_active & QIB_IB_DDR)) { 3710f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->lflags_lock, flags); 3711f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags &= ~(QIBL_IB_AUTONEG_INPROG | 3712f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBL_IB_AUTONEG_FAILED); 3713f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->lflags_lock, 3714f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell flags); 3715f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->autoneg_tries = 0; 3716f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* re-enable SDR, for next link down */ 3717f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell set_7220_ibspeed_fast(ppd, 3718f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->link_speed_enabled); 3719f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell wake_up(&ppd->cpspec->autoneg_wait); 3720f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell symadj = 1; 3721f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else if (ppd->lflags & QIBL_IB_AUTONEG_FAILED) { 3722f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 3723f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Clear autoneg failure flag, and do setup 3724f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * so we'll try next time link goes down and 3725f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * back to INIT (possibly connected to a 3726f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * different device). 3727f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3728f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->lflags_lock, flags); 3729f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags &= ~QIBL_IB_AUTONEG_FAILED; 3730f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->lflags_lock, 3731f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell flags); 3732f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibcddrctrl |= 3733f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell IBA7220_IBC_IBTA_1_2_MASK; 3734f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_ncmodectrl, 0); 3735f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell symadj = 1; 3736f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3737f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3738f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3739f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) 3740f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell symadj = 1; 3741f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3742f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!ret) { 3743f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->delay_mult = rate_to_delay 3744f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [(ibcs >> IBA7220_LINKSPEED_SHIFT) & 1] 3745f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [(ibcs >> IBA7220_LINKWIDTH_SHIFT) & 1]; 3746f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3747f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell set_7220_relock_poll(dd, ibup); 3748f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->sdma_lock, flags); 3749f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 3750f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Unlike 7322, the 7220 needs this, due to lack of 3751f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * interrupt in some cases when we have sdma active 3752f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * when the link goes down. 3753f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3754f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->sdma_state.current_state != 3755f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_sdma_state_s20_idle) 3756f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell __qib_sdma_process_event(ppd, 3757f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_sdma_event_e00_go_hw_down); 3758f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->sdma_lock, flags); 3759f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3760f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3761f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3762f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (symadj) { 3763f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->cpspec->ibdeltainprog) { 3764f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibdeltainprog = 0; 3765f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibsymdelta += read_7220_creg32(ppd->dd, 3766f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_ibsymbolerr) - ppd->cpspec->ibsymsnap; 3767f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->iblnkerrdelta += read_7220_creg32(ppd->dd, 3768f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_iblinkerrrecov) - ppd->cpspec->iblnkerrsnap; 3769f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3770f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else if (!ibup && qib_compat_ddr_negotiate && 3771f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell !ppd->cpspec->ibdeltainprog && 3772f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell !(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) { 3773f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibdeltainprog = 1; 3774f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->ibsymsnap = read_7220_creg32(ppd->dd, 3775f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_ibsymbolerr); 3776f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->iblnkerrsnap = read_7220_creg32(ppd->dd, 3777f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cr_iblinkerrrecov); 3778f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3779f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3780f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!ret) 3781f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_setup_7220_setextled(ppd, ibup); 3782f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return ret; 3783f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3784f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3785f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 3786f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Does read/modify/write to appropriate registers to 3787f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * set output and direction bits selected by mask. 3788f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * these are in their canonical postions (e.g. lsb of 3789f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * dir will end up in D48 of extctrl on existing chips). 3790f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * returns contents of GP Inputs. 3791f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3792f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic int gpio_7220_mod(struct qib_devdata *dd, u32 out, u32 dir, u32 mask) 3793f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 3794f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 read_val, new_out; 3795f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 3796f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3797f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (mask) { 3798f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* some bits being written, lock access to GPIO */ 3799f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dir &= mask; 3800f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell out &= mask; 3801f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&dd->cspec->gpio_lock, flags); 3802f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->extctrl &= ~((u64)mask << SYM_LSB(EXTCtrl, GPIOOe)); 3803f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->extctrl |= ((u64) dir << SYM_LSB(EXTCtrl, GPIOOe)); 3804f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell new_out = (dd->cspec->gpio_out & ~mask) | out; 3805f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3806f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_extctrl, dd->cspec->extctrl); 3807f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_gpio_out, new_out); 3808f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->gpio_out = new_out; 3809f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&dd->cspec->gpio_lock, flags); 3810f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3811f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 3812f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * It is unlikely that a read at this time would get valid 3813f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * data on a pin whose direction line was set in the same 3814f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * call to this function. We include the read here because 3815f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * that allows us to potentially combine a change on one pin with 3816f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * a read on another, and because the old code did something like 3817f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * this. 3818f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3819f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell read_val = qib_read_kreg64(dd, kr_extstatus); 3820f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return SYM_FIELD(read_val, EXTStatus, GPIOIn); 3821f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3822f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3823f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 3824f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Read fundamental info we need to use the chip. These are 3825f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * the registers that describe chip capabilities, and are 3826f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * saved in shadow registers. 3827f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3828f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void get_7220_chip_params(struct qib_devdata *dd) 3829f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 3830f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 val; 3831f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 piobufs; 3832f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int mtu; 3833f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3834f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->uregbase = qib_read_kreg32(dd, kr_userregbase); 3835f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3836f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvtidcnt = qib_read_kreg32(dd, kr_rcvtidcnt); 3837f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvtidbase = qib_read_kreg32(dd, kr_rcvtidbase); 3838f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvegrbase = qib_read_kreg32(dd, kr_rcvegrbase); 3839f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->palign = qib_read_kreg32(dd, kr_palign); 3840f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->piobufbase = qib_read_kreg64(dd, kr_sendpiobufbase); 3841f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->pio2k_bufbase = dd->piobufbase & 0xffffffff; 3842f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3843f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = qib_read_kreg64(dd, kr_sendpiosize); 3844f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->piosize2k = val & ~0U; 3845f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->piosize4k = val >> 32; 3846f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3847f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell mtu = ib_mtu_enum_to_int(qib_ibmtu); 3848f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (mtu == -1) 3849f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell mtu = QIB_DEFAULT_MTU; 3850f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->pport->ibmtu = (u32)mtu; 3851f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3852f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = qib_read_kreg64(dd, kr_sendpiobufcnt); 3853f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->piobcnt2k = val & ~0U; 3854f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->piobcnt4k = val >> 32; 3855f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* these may be adjusted in init_chip_wc_pat() */ 3856f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->pio2kbase = (u32 __iomem *) 3857f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ((char __iomem *) dd->kregbase + dd->pio2k_bufbase); 3858f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->piobcnt4k) { 3859f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->pio4kbase = (u32 __iomem *) 3860f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ((char __iomem *) dd->kregbase + 3861f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (dd->piobufbase >> 32)); 3862f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 3863f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 4K buffers take 2 pages; we use roundup just to be 3864f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * paranoid; we calculate it once here, rather than on 3865f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * ever buf allocate 3866f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3867f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->align4k = ALIGN(dd->piosize4k, dd->palign); 3868f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3869f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3870f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell piobufs = dd->piobcnt4k + dd->piobcnt2k; 3871f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3872f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->pioavregs = ALIGN(piobufs, sizeof(u64) * BITS_PER_BYTE / 2) / 3873f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (sizeof(u64) * BITS_PER_BYTE / 2); 3874f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3875f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3876f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 3877f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * The chip base addresses in cspec and cpspec have to be set 3878f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * after possible init_chip_wc_pat(), rather than in 3879f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_get_7220_chip_params(), so split out as separate function 3880f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3881f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void set_7220_baseaddrs(struct qib_devdata *dd) 3882f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 3883f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 cregbase; 3884f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* init after possible re-map in init_chip_wc_pat() */ 3885f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cregbase = qib_read_kreg32(dd, kr_counterregbase); 3886f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->cregbase = (u64 __iomem *) 3887f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ((char __iomem *) dd->kregbase + cregbase); 3888f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3889f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->egrtidbase = (u64 __iomem *) 3890f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ((char __iomem *) dd->kregbase + dd->rcvegrbase); 3891f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3892f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3893f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3894f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define SENDCTRL_SHADOWED (SYM_MASK(SendCtrl, SendIntBufAvail) | \ 3895f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK(SendCtrl, SPioEnable) | \ 3896f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK(SendCtrl, SSpecialTriggerEn) | \ 3897f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK(SendCtrl, SendBufAvailUpd) | \ 3898f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK(SendCtrl, AvailUpdThld) | \ 3899f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK(SendCtrl, SDmaEnable) | \ 3900f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK(SendCtrl, SDmaIntEnable) | \ 3901f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK(SendCtrl, SDmaHalt) | \ 3902f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_MASK(SendCtrl, SDmaSingleDescriptor)) 3903f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3904f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic int sendctrl_hook(struct qib_devdata *dd, 3905f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell const struct diag_observer *op, 3906f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 offs, u64 *data, u64 mask, int only_32) 3907f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 3908f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 3909f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned idx = offs / sizeof(u64); 3910f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 local_data, all_bits; 3911f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3912f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (idx != kr_sendctrl) { 3913f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_dev_err(dd, "SendCtrl Hook called with offs %X, %s-bit\n", 3914f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell offs, only_32 ? "32" : "64"); 3915f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return 0; 3916f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3917f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3918f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell all_bits = ~0ULL; 3919f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (only_32) 3920f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell all_bits >>= 32; 3921f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&dd->sendctrl_lock, flags); 3922f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if ((mask & all_bits) != all_bits) { 3923f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 3924f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * At least some mask bits are zero, so we need 3925f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * to read. The judgement call is whether from 3926f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * reg or shadow. First-cut: read reg, and complain 3927f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * if any bits which should be shadowed are different 3928f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * from their shadowed value. 3929f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3930f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (only_32) 3931f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell local_data = (u64)qib_read_kreg32(dd, idx); 3932f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else 3933f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell local_data = qib_read_kreg64(dd, idx); 3934f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_dev_err(dd, "Sendctrl -> %X, Shad -> %X\n", 3935f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (u32)local_data, (u32)dd->sendctrl); 3936f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if ((local_data & SENDCTRL_SHADOWED) != 3937f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (dd->sendctrl & SENDCTRL_SHADOWED)) 3938f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_dev_err(dd, "Sendctrl read: %X shadow is %X\n", 3939f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (u32)local_data, (u32) dd->sendctrl); 3940f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell *data = (local_data & ~mask) | (*data & mask); 3941f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3942f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (mask) { 3943f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 3944f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * At least some mask bits are one, so we need 3945f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * to write, but only shadow some bits. 3946f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3947f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 sval, tval; /* Shadowed, transient */ 3948f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3949f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 3950f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * New shadow val is bits we don't want to touch, 3951f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * ORed with bits we do, that are intended for shadow. 3952f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3953f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sval = (dd->sendctrl & ~mask); 3954f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sval |= *data & SENDCTRL_SHADOWED & mask; 3955f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->sendctrl = sval; 3956f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell tval = sval | (*data & ~SENDCTRL_SHADOWED & mask); 3957f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_dev_err(dd, "Sendctrl <- %X, Shad <- %X\n", 3958f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (u32)tval, (u32)sval); 3959f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_sendctrl, tval); 3960f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_scratch, 0Ull); 3961f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3962f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&dd->sendctrl_lock, flags); 3963f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3964f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return only_32 ? 4 : 8; 3965f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3966f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3967f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic const struct diag_observer sendctrl_observer = { 3968f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sendctrl_hook, kr_sendctrl * sizeof(u64), 3969f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell kr_sendctrl * sizeof(u64) 3970f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell}; 3971f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3972f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 3973f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * write the final few registers that depend on some of the 3974f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * init setup. Done late in init, just before bringing up 3975f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * the serdes. 3976f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 3977f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic int qib_late_7220_initreg(struct qib_devdata *dd) 3978f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 3979f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int ret = 0; 3980f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 val; 3981f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3982f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_rcvhdrentsize, dd->rcvhdrentsize); 3983f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_rcvhdrsize, dd->rcvhdrsize); 3984f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_rcvhdrcnt, dd->rcvhdrcnt); 3985f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_sendpioavailaddr, dd->pioavailregs_phys); 3986f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell val = qib_read_kreg64(dd, kr_sendpioavailaddr); 3987f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (val != dd->pioavailregs_phys) { 39887fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn qib_dev_err(dd, 39897fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn "Catastrophic software error, SendPIOAvailAddr written as %lx, read back as %llx\n", 39907fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn (unsigned long) dd->pioavailregs_phys, 39917fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn (unsigned long long) val); 3992f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = -EINVAL; 3993f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 3994f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_register_observer(dd, &sendctrl_observer); 3995f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return ret; 3996f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 3997f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 3998f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic int qib_init_7220_variables(struct qib_devdata *dd) 3999f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 4000f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_chippport_specific *cpspec; 4001f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_pportdata *ppd; 4002f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int ret = 0; 4003f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 sbufs, updthresh; 4004f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4005f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cpspec = (struct qib_chippport_specific *)(dd + 1); 4006f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd = &cpspec->pportdata; 4007f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->pport = ppd; 4008f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->num_pports = 1; 4009f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4010f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec = (struct qib_chip_specific *)(cpspec + dd->num_pports); 4011f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec = cpspec; 4012f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4013f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_init(&dd->cspec->sdepb_lock); 4014f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_init(&dd->cspec->rcvmod_lock); 4015f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_init(&dd->cspec->gpio_lock); 4016f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4017f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* we haven't yet set QIB_PRESENT, so use read directly */ 4018f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->revision = readq(&dd->kregbase[kr_revision]); 4019f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4020f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if ((dd->revision & 0xffffffffU) == 0xffffffffU) { 40217fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn qib_dev_err(dd, 40227fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn "Revision register read failure, giving up initialization\n"); 4023f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = -ENODEV; 4024f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 4025f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 4026f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->flags |= QIB_PRESENT; /* now register routines work */ 4027f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4028f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->majrev = (u8) SYM_FIELD(dd->revision, Revision_R, 4029f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ChipRevMajor); 4030f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->minrev = (u8) SYM_FIELD(dd->revision, Revision_R, 4031f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ChipRevMinor); 4032f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4033f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell get_7220_chip_params(dd); 4034f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_7220_boardname(dd); 4035f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4036f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 4037f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * GPIO bits for TWSI data and clock, 4038f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * used for serial EEPROM. 4039f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 4040f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->gpio_sda_num = _QIB_GPIO_SDA_NUM; 4041f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->gpio_scl_num = _QIB_GPIO_SCL_NUM; 4042f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->twsi_eeprom_dev = QIB_TWSI_EEPROM_DEV; 4043f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4044f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->flags |= QIB_HAS_INTX | QIB_HAS_LINK_LATENCY | 4045f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIB_NODMA_RTAIL | QIB_HAS_THRESH_UPDATE; 4046f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->flags |= qib_special_trigger ? 4047f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIB_USE_SPCL_TRIG : QIB_HAS_SEND_DMA; 4048f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4049f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 4050f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * EEPROM error log 0 is TXE Parity errors. 1 is RXE Parity. 4051f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 2 is Some Misc, 3 is reserved for future. 4052f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 4053f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->eep_st_masks[0].hwerrs_to_log = HWE_MASK(TXEMemParityErr); 4054f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4055f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->eep_st_masks[1].hwerrs_to_log = HWE_MASK(RXEMemParityErr); 4056f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4057f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->eep_st_masks[2].errs_to_log = ERR_MASK(ResetNegated); 4058f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4059f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell init_waitqueue_head(&cpspec->autoneg_wait); 4060f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell INIT_DELAYED_WORK(&cpspec->autoneg_work, autoneg_7220_work); 4061f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 40627d7632add8dd99f68b21546efff08a5a162de184Mike Marciniszyn ret = qib_init_pportdata(ppd, dd, 0, 1); 40637d7632add8dd99f68b21546efff08a5a162de184Mike Marciniszyn if (ret) 40647d7632add8dd99f68b21546efff08a5a162de184Mike Marciniszyn goto bail; 4065f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->link_width_supported = IB_WIDTH_1X | IB_WIDTH_4X; 4066f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->link_speed_supported = QIB_IB_SDR | QIB_IB_DDR; 4067f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4068f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->link_width_enabled = ppd->link_width_supported; 4069f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->link_speed_enabled = ppd->link_speed_supported; 4070f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 4071f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Set the initial values to reasonable default, will be set 4072f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * for real when link is up. 4073f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 4074f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->link_width_active = IB_WIDTH_4X; 4075f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->link_speed_active = QIB_IB_SDR; 4076f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->delay_mult = rate_to_delay[0][1]; 4077f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->vls_supported = IB_VL_VL0; 4078f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->vls_operational = ppd->vls_supported; 4079f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4080f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!qib_mini_init) 4081f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_rcvbthqp, QIB_KD_QP); 4082f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4083f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell init_timer(&ppd->cpspec->chase_timer); 4084f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->chase_timer.function = reenable_7220_chase; 4085f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->chase_timer.data = (unsigned long)ppd; 4086f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4087f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_num_cfg_vls = 1; /* if any 7220's, only one VL */ 4088f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4089f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvhdrentsize = QIB_RCVHDR_ENTSIZE; 4090f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvhdrsize = QIB_DFLT_RCVHDRSIZE; 4091f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rhf_offset = 4092f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvhdrentsize - sizeof(u64) / sizeof(u32); 4093f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4094f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* we always allocate at least 2048 bytes for eager buffers */ 4095f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = ib_mtu_enum_to_int(qib_ibmtu); 4096f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rcvegrbufsize = ret != -1 ? max(ret, 2048) : QIB_DEFAULT_MTU; 40979e1c0e43257b6df1ef012dd37c3f0f93b1ee47afMike Marciniszyn BUG_ON(!is_power_of_2(dd->rcvegrbufsize)); 40989e1c0e43257b6df1ef012dd37c3f0f93b1ee47afMike Marciniszyn dd->rcvegrbufsize_shift = ilog2(dd->rcvegrbufsize); 4099f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4100f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_7220_tidtemplate(dd); 4101f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4102f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 4103f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * We can request a receive interrupt for 1 or 4104f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * more packets from current offset. For now, we set this 4105f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * up for a single packet. 4106f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 4107f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->rhdrhead_intr_off = 1ULL << 32; 4108f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4109f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* setup the stats timer; the add_timer is done at end of init */ 4110f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell init_timer(&dd->stats_timer); 4111f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->stats_timer.function = qib_get_7220_faststats; 4112f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->stats_timer.data = (unsigned long) dd; 4113f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->stats_timer.expires = jiffies + ACTIVITY_TIMER * HZ; 4114f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4115f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 4116f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Control[4] has been added to change the arbitration within 4117f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * the SDMA engine between favoring data fetches over descriptor 4118f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * fetches. qib_sdma_fetch_arb==0 gives data fetches priority. 4119f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 4120f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (qib_sdma_fetch_arb) 4121f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->control |= 1 << 4; 4122f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4123f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->ureg_align = 0x10000; /* 64KB alignment */ 4124f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4125f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->piosize2kmax_dwords = (dd->piosize2k >> 2)-1; 4126f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_7220_config_ctxts(dd); 4127f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_set_ctxtcnt(dd); /* needed for PAT setup */ 4128f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4129f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (qib_wc_pat) { 4130f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = init_chip_wc_pat(dd, 0); 4131f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ret) 4132f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 4133f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 4134f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell set_7220_baseaddrs(dd); /* set chip access pointers now */ 4135f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4136f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = 0; 4137f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (qib_mini_init) 4138f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 4139f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4140f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = qib_create_ctxts(dd); 4141f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell init_7220_cntrnames(dd); 4142f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4143f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* use all of 4KB buffers for the kernel SDMA, zero if !SDMA. 4144f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * reserve the update threshold amount for other kernel use, such 4145f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * as sending SMI, MAD, and ACKs, or 3, whichever is greater, 4146f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * unless we aren't enabling SDMA, in which case we want to use 4147f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * all the 4k bufs for the kernel. 4148f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * if this was less than the update threshold, we could wait 4149f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * a long time for an update. Coded this way because we 4150f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * sometimes change the update threshold for various reasons, 4151f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * and we want this to remain robust. 4152f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 4153f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell updthresh = 8U; /* update threshold */ 4154f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->flags & QIB_HAS_SEND_DMA) { 4155f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->sdmabufcnt = dd->piobcnt4k; 4156f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sbufs = updthresh > 3 ? updthresh : 3; 4157f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else { 4158f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->sdmabufcnt = 0; 4159f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sbufs = dd->piobcnt4k; 4160f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 4161f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4162f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->lastbuf_for_pio = dd->piobcnt2k + dd->piobcnt4k - 4163f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->sdmabufcnt; 4164f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->lastctxt_piobuf = dd->cspec->lastbuf_for_pio - sbufs; 4165f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->lastbuf_for_pio--; /* range is <= , not < */ 4166bb77a077232e78476d7bc39c080f9e6685cbfd3cMike Marciniszyn dd->last_pio = dd->cspec->lastbuf_for_pio; 4167f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->pbufsctxt = dd->lastctxt_piobuf / 4168f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (dd->cfgctxts - dd->first_user_ctxt); 4169f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4170f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 4171f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * if we are at 16 user contexts, we will have one 7 sbufs 4172f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * per context, so drop the update threshold to match. We 4173f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * want to update before we actually run out, at low pbufs/ctxt 4174f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * so give ourselves some margin 4175f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 4176f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if ((dd->pbufsctxt - 2) < updthresh) 4177f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell updthresh = dd->pbufsctxt - 2; 4178f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4179f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->updthresh_dflt = updthresh; 4180f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->updthresh = updthresh; 4181f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4182f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* before full enable, no interrupts, no locking needed */ 4183f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->sendctrl |= (updthresh & SYM_RMASK(SendCtrl, AvailUpdThld)) 4184f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell << SYM_LSB(SendCtrl, AvailUpdThld); 4185f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4186f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->psxmitwait_supported = 1; 4187f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->psxmitwait_check_rate = QIB_7220_PSXMITWAIT_CHECK_RATE; 4188f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellbail: 4189f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return ret; 4190f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 4191f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4192f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic u32 __iomem *qib_7220_getsendbuf(struct qib_pportdata *ppd, u64 pbc, 4193f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 *pbufnum) 4194f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 4195f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 first, last, plen = pbc & QIB_PBC_LENGTH_MASK; 4196f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = ppd->dd; 4197f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 __iomem *buf; 4198f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4199f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (((pbc >> 32) & PBC_7220_VL15_SEND_CTRL) && 4200f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell !(ppd->lflags & (QIBL_IB_AUTONEG_INPROG | QIBL_LINKACTIVE))) 4201f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell buf = get_7220_link_buf(ppd, pbufnum); 4202f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else { 4203f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if ((plen + 1) > dd->piosize2kmax_dwords) 4204f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell first = dd->piobcnt2k; 4205f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell else 4206f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell first = 0; 4207f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* try 4k if all 2k busy, so same last for both sizes */ 4208f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell last = dd->cspec->lastbuf_for_pio; 4209f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell buf = qib_getsendbuf_range(dd, pbufnum, first, last); 4210f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 4211f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return buf; 4212f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 4213f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4214f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* these 2 "counters" are really control registers, and are always RW */ 4215f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_set_cntr_7220_sample(struct qib_pportdata *ppd, u32 intv, 4216f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 start) 4217f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 4218f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell write_7220_creg(ppd->dd, cr_psinterval, intv); 4219f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell write_7220_creg(ppd->dd, cr_psstart, start); 4220f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 4221f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4222f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 4223f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * NOTE: no real attempt is made to generalize the SDMA stuff. 4224f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * At some point "soon" we will have a new more generalized 4225f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * set of sdma interface, and then we'll clean this up. 4226f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 4227f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4228f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* Must be called with sdma_lock held, or before init finished */ 4229f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_sdma_update_7220_tail(struct qib_pportdata *ppd, u16 tail) 4230f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 4231f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* Commit writes to memory and advance the tail on the chip */ 4232f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell wmb(); 4233f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->sdma_descq_tail = tail; 4234f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(ppd->dd, kr_senddmatail, tail); 4235f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 4236f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4237f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_sdma_set_7220_desc_cnt(struct qib_pportdata *ppd, unsigned cnt) 4238f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 4239f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 4240f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4241f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic struct sdma_set_state_action sdma_7220_action_table[] = { 4242f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [qib_sdma_state_s00_hw_down] = { 4243f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_enable = 0, 4244f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_intenable = 0, 4245f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_halt = 0, 4246f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .go_s99_running_tofalse = 1, 4247f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell }, 4248f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [qib_sdma_state_s10_hw_start_up_wait] = { 4249f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_enable = 1, 4250f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_intenable = 1, 4251f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_halt = 1, 4252f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell }, 4253f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [qib_sdma_state_s20_idle] = { 4254f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_enable = 1, 4255f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_intenable = 1, 4256f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_halt = 1, 4257f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell }, 4258f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [qib_sdma_state_s30_sw_clean_up_wait] = { 4259f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_enable = 0, 4260f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_intenable = 1, 4261f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_halt = 0, 4262f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell }, 4263f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [qib_sdma_state_s40_hw_clean_up_wait] = { 4264f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_enable = 1, 4265f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_intenable = 1, 4266f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_halt = 1, 4267f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell }, 4268f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [qib_sdma_state_s50_hw_halt_wait] = { 4269f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_enable = 1, 4270f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_intenable = 1, 4271f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_halt = 1, 4272f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell }, 4273f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell [qib_sdma_state_s99_running] = { 4274f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_enable = 1, 4275f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_intenable = 1, 4276f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .op_halt = 0, 4277f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell .go_s99_running_totrue = 1, 4278f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell }, 4279f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell}; 4280f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4281f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_sdma_init_early(struct qib_pportdata *ppd) 4282f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 4283f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->sdma_state.set_state_action = sdma_7220_action_table; 4284f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 4285f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4286f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic int init_sdma_7220_regs(struct qib_pportdata *ppd) 4287f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 4288f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = ppd->dd; 4289f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned i, n; 4290f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 senddmabufmask[3] = { 0 }; 4291f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4292f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* Set SendDmaBase */ 4293f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_senddmabase, ppd->sdma_descq_phys); 4294f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_sdma_7220_setlengen(ppd); 4295f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_sdma_update_7220_tail(ppd, 0); /* Set SendDmaTail */ 4296f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* Set SendDmaHeadAddr */ 4297f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_senddmaheadaddr, ppd->sdma_head_phys); 4298f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4299f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 4300f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Reserve all the former "kernel" piobufs, using high number range 4301f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * so we get as many 4K buffers as possible 4302f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 4303f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell n = dd->piobcnt2k + dd->piobcnt4k; 4304f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell i = n - dd->cspec->sdmabufcnt; 4305f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4306f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (; i < n; ++i) { 4307f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned word = i / 64; 4308f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned bit = i & 63; 4309f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4310f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell BUG_ON(word >= 3); 4311f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell senddmabufmask[word] |= 1ULL << bit; 4312f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 4313f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_senddmabufmask0, senddmabufmask[0]); 4314f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_senddmabufmask1, senddmabufmask[1]); 4315f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_senddmabufmask2, senddmabufmask[2]); 4316f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4317f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->sdma_state.first_sendbuf = i; 4318f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->sdma_state.last_sendbuf = n; 4319f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4320f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return 0; 4321f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 4322f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4323f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* sdma_lock must be held */ 4324f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic u16 qib_sdma_7220_gethead(struct qib_pportdata *ppd) 4325f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 4326f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = ppd->dd; 4327f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int sane; 4328f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int use_dmahead; 4329f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u16 swhead; 4330f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u16 swtail; 4331f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u16 cnt; 4332f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u16 hwhead; 4333f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4334f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell use_dmahead = __qib_sdma_running(ppd) && 4335f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (dd->flags & QIB_HAS_SDMA_TIMEOUT); 4336f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellretry: 4337f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell hwhead = use_dmahead ? 4338f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (u16)le64_to_cpu(*ppd->sdma_head_dma) : 4339f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (u16)qib_read_kreg32(dd, kr_senddmahead); 4340f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4341f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell swhead = ppd->sdma_descq_head; 4342f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell swtail = ppd->sdma_descq_tail; 4343f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell cnt = ppd->sdma_descq_cnt; 4344f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4345f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (swhead < swtail) { 4346f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* not wrapped */ 4347f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sane = (hwhead >= swhead) & (hwhead <= swtail); 4348f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else if (swhead > swtail) { 4349f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* wrapped around */ 4350f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sane = ((hwhead >= swhead) && (hwhead < cnt)) || 4351f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (hwhead <= swtail); 4352f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else { 4353f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* empty */ 4354f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sane = (hwhead == swhead); 4355f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 4356f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4357f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (unlikely(!sane)) { 4358f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (use_dmahead) { 4359f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* try one more time, directly from the register */ 4360f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell use_dmahead = 0; 4361f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto retry; 4362f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 4363f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* assume no progress */ 4364f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell hwhead = swhead; 4365f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 4366f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4367f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return hwhead; 4368f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 4369f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4370f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic int qib_sdma_7220_busy(struct qib_pportdata *ppd) 4371f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 4372f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u64 hwstatus = qib_read_kreg64(ppd->dd, kr_senddmastatus); 4373f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4374f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return (hwstatus & SYM_MASK(SendDmaStatus, ScoreBoardDrainInProg)) || 4375f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (hwstatus & SYM_MASK(SendDmaStatus, AbortInProg)) || 4376f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (hwstatus & SYM_MASK(SendDmaStatus, InternalSDmaEnable)) || 4377f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell !(hwstatus & SYM_MASK(SendDmaStatus, ScbEmpty)); 4378f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 4379f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4380f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 4381f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Compute the amount of delay before sending the next packet if the 4382f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * port's send rate differs from the static rate set for the QP. 4383f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Since the delay affects this packet but the amount of the delay is 4384f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * based on the length of the previous packet, use the last delay computed 4385f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * and save the delay count for this packet to be used next time 4386f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * we get here. 4387f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 4388f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic u32 qib_7220_setpbc_control(struct qib_pportdata *ppd, u32 plen, 4389f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u8 srate, u8 vl) 4390f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 4391f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u8 snd_mult = ppd->delay_mult; 4392f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u8 rcv_mult = ib_rate_to_delay[srate]; 4393f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 ret = ppd->cpspec->last_delay_mult; 4394f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4395f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->cpspec->last_delay_mult = (rcv_mult > snd_mult) ? 4396f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (plen * (rcv_mult - snd_mult) + 1) >> 1 : 0; 4397f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4398f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* Indicate VL15, if necessary */ 4399f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (vl == 15) 4400f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret |= PBC_7220_VL15_SEND_CTRL; 4401f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return ret; 4402f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 4403f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4404f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_initvl15_bufs(struct qib_devdata *dd) 4405f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 4406f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 4407f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4408f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_init_ctxt(struct qib_ctxtdata *rcd) 4409f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 4410f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!rcd->ctxt) { 4411f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell rcd->rcvegrcnt = IBA7220_KRCVEGRCNT; 4412f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell rcd->rcvegr_tid_base = 0; 4413f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else { 4414f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell rcd->rcvegrcnt = rcd->dd->cspec->rcvegrcnt; 4415f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell rcd->rcvegr_tid_base = IBA7220_KRCVEGRCNT + 4416f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell (rcd->ctxt - 1) * rcd->rcvegrcnt; 4417f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 4418f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 4419f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4420f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_7220_txchk_change(struct qib_devdata *dd, u32 start, 4421f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 len, u32 which, struct qib_ctxtdata *rcd) 4422f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 4423f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int i; 4424f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 4425f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4426f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell switch (which) { 4427f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case TXCHK_CHG_TYPE_KERN: 4428f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* see if we need to raise avail update threshold */ 4429f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&dd->uctxt_lock, flags); 4430f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (i = dd->first_user_ctxt; 4431f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->updthresh != dd->cspec->updthresh_dflt 4432f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell && i < dd->cfgctxts; i++) 4433f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->rcd[i] && dd->rcd[i]->subctxt_cnt && 4434f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ((dd->rcd[i]->piocnt / dd->rcd[i]->subctxt_cnt) - 1) 4435f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell < dd->cspec->updthresh_dflt) 4436f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 4437f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&dd->uctxt_lock, flags); 4438f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (i == dd->cfgctxts) { 4439f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&dd->sendctrl_lock, flags); 4440f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->updthresh = dd->cspec->updthresh_dflt; 4441f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->sendctrl &= ~SYM_MASK(SendCtrl, AvailUpdThld); 4442f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->sendctrl |= (dd->cspec->updthresh & 4443f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_RMASK(SendCtrl, AvailUpdThld)) << 4444f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_LSB(SendCtrl, AvailUpdThld); 4445f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&dd->sendctrl_lock, flags); 4446f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sendctrl_7220_mod(dd->pport, QIB_SENDCTRL_AVAIL_BLIP); 4447f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 4448f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 4449f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case TXCHK_CHG_TYPE_USER: 4450f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&dd->sendctrl_lock, flags); 4451f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (rcd && rcd->subctxt_cnt && ((rcd->piocnt 4452f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell / rcd->subctxt_cnt) - 1) < dd->cspec->updthresh) { 4453f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->updthresh = (rcd->piocnt / 4454f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell rcd->subctxt_cnt) - 1; 4455f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->sendctrl &= ~SYM_MASK(SendCtrl, AvailUpdThld); 4456f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->sendctrl |= (dd->cspec->updthresh & 4457f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell SYM_RMASK(SendCtrl, AvailUpdThld)) 4458f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell << SYM_LSB(SendCtrl, AvailUpdThld); 4459f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&dd->sendctrl_lock, flags); 4460f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sendctrl_7220_mod(dd->pport, QIB_SENDCTRL_AVAIL_BLIP); 4461f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else 4462f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&dd->sendctrl_lock, flags); 4463f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 4464f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 4465f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 4466f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4467f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void writescratch(struct qib_devdata *dd, u32 val) 4468f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 4469f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_scratch, val); 4470f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 4471f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4472f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#define VALID_TS_RD_REG_MASK 0xBF 4473f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/** 4474f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_7220_tempsense_read - read register of temp sensor via TWSI 4475f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @dd: the qlogic_ib device 4476f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @regnum: register to read from 4477f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 4478f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * returns reg contents (0..255) or < 0 for error 4479f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 4480f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic int qib_7220_tempsense_rd(struct qib_devdata *dd, int regnum) 4481f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 4482f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int ret; 4483f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u8 rdata; 4484f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4485f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (regnum > 7) { 4486f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = -EINVAL; 4487f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 4488f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 4489f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4490f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* return a bogus value for (the one) register we do not have */ 4491f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!((1 << regnum) & VALID_TS_RD_REG_MASK)) { 4492f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = 0; 4493f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 4494f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 4495f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4496f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = mutex_lock_interruptible(&dd->eep_lock); 4497f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ret) 4498f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 4499f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4500f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = qib_twsi_blk_rd(dd, QIB_TWSI_TEMP_DEV, regnum, &rdata, 1); 4501f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!ret) 4502f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = rdata; 4503f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4504f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell mutex_unlock(&dd->eep_lock); 4505f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4506f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 4507f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * There are three possibilities here: 4508f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * ret is actual value (0..255) 4509f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * ret is -ENXIO or -EINVAL from twsi code or this file 4510f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * ret is -EINTR from mutex_lock_interruptible. 4511f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 4512f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellbail: 4513f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return ret; 4514f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 4515f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 45168469ba39a6b77917e8879680aed17229bf72f263Mike Marciniszyn#ifdef CONFIG_INFINIBAND_QIB_DCA 45178469ba39a6b77917e8879680aed17229bf72f263Mike Marciniszynstatic int qib_7220_notify_dca(struct qib_devdata *dd, unsigned long event) 45188469ba39a6b77917e8879680aed17229bf72f263Mike Marciniszyn{ 45198469ba39a6b77917e8879680aed17229bf72f263Mike Marciniszyn return 0; 45208469ba39a6b77917e8879680aed17229bf72f263Mike Marciniszyn} 45218469ba39a6b77917e8879680aed17229bf72f263Mike Marciniszyn#endif 45228469ba39a6b77917e8879680aed17229bf72f263Mike Marciniszyn 4523f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* Dummy function, as 7220 boards never disable EEPROM Write */ 4524f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic int qib_7220_eeprom_wen(struct qib_devdata *dd, int wen) 4525f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 4526f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return 1; 4527f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 4528f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4529f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/** 4530f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_init_iba7220_funcs - set up the chip-specific function pointers 4531f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @dev: the pci_dev for qlogic_ib device 4532f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @ent: pci_device_id struct for this dev 4533f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 4534f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * This is global, and is called directly at init to set up the 4535f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * chip-specific function pointers for later use. 4536f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 4537f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstruct qib_devdata *qib_init_iba7220_funcs(struct pci_dev *pdev, 4538f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell const struct pci_device_id *ent) 4539f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 4540f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd; 4541f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int ret; 4542f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 boardid, minwidth; 4543f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4544f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd = qib_alloc_devdata(pdev, sizeof(struct qib_chip_specific) + 4545f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell sizeof(struct qib_chippport_specific)); 4546f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (IS_ERR(dd)) 4547f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 4548f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4549f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_bringup_serdes = qib_7220_bringup_serdes; 4550f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_cleanup = qib_setup_7220_cleanup; 4551f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_clear_tids = qib_7220_clear_tids; 4552f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_free_irq = qib_7220_free_irq; 4553f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_get_base_info = qib_7220_get_base_info; 4554f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_get_msgheader = qib_7220_get_msgheader; 4555f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_getsendbuf = qib_7220_getsendbuf; 4556f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_gpio_mod = gpio_7220_mod; 4557f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_eeprom_wen = qib_7220_eeprom_wen; 4558f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_hdrqempty = qib_7220_hdrqempty; 4559f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_ib_updown = qib_7220_ib_updown; 4560f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_init_ctxt = qib_7220_init_ctxt; 4561f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_initvl15_bufs = qib_7220_initvl15_bufs; 4562f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_intr_fallback = qib_7220_intr_fallback; 4563f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_late_initreg = qib_late_7220_initreg; 4564f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_setpbc_control = qib_7220_setpbc_control; 4565f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_portcntr = qib_portcntr_7220; 4566f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_put_tid = qib_7220_put_tid; 4567f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_quiet_serdes = qib_7220_quiet_serdes; 4568f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_rcvctrl = rcvctrl_7220_mod; 4569f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_read_cntrs = qib_read_7220cntrs; 4570f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_read_portcntrs = qib_read_7220portcntrs; 4571f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_reset = qib_setup_7220_reset; 4572f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_init_sdma_regs = init_sdma_7220_regs; 4573f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_sdma_busy = qib_sdma_7220_busy; 4574f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_sdma_gethead = qib_sdma_7220_gethead; 4575f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_sdma_sendctrl = qib_7220_sdma_sendctrl; 4576f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_sdma_set_desc_cnt = qib_sdma_set_7220_desc_cnt; 4577f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_sdma_update_tail = qib_sdma_update_7220_tail; 4578f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_sdma_hw_clean_up = qib_7220_sdma_hw_clean_up; 4579f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_sdma_hw_start_up = qib_7220_sdma_hw_start_up; 4580f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_sdma_init_early = qib_7220_sdma_init_early; 4581f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_sendctrl = sendctrl_7220_mod; 4582f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_set_armlaunch = qib_set_7220_armlaunch; 4583f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_set_cntr_sample = qib_set_cntr_7220_sample; 4584f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_iblink_state = qib_7220_iblink_state; 4585f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_ibphys_portstate = qib_7220_phys_portstate; 4586f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_get_ib_cfg = qib_7220_get_ib_cfg; 4587f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_set_ib_cfg = qib_7220_set_ib_cfg; 4588f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_set_ib_loopback = qib_7220_set_loopback; 4589f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_set_intr_state = qib_7220_set_intr_state; 4590f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_setextled = qib_setup_7220_setextled; 4591f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_txchk_change = qib_7220_txchk_change; 4592f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_update_usrhead = qib_update_7220_usrhead; 4593f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_wantpiobuf_intr = qib_wantpiobuf_7220_intr; 4594f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_xgxs_reset = qib_7220_xgxs_reset; 4595f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_writescratch = writescratch; 4596f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_tempsense_rd = qib_7220_tempsense_rd; 45978469ba39a6b77917e8879680aed17229bf72f263Mike Marciniszyn#ifdef CONFIG_INFINIBAND_QIB_DCA 45988469ba39a6b77917e8879680aed17229bf72f263Mike Marciniszyn dd->f_notify_dca = qib_7220_notify_dca; 45998469ba39a6b77917e8879680aed17229bf72f263Mike Marciniszyn#endif 4600f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 4601f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Do remaining pcie setup and save pcie values in dd. 4602f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Any error printing is already done by the init code. 4603f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * On return, we have the chip mapped, but chip registers 4604f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * are not set up until start of qib_init_7220_variables. 4605f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 4606f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = qib_pcie_ddinit(dd, pdev, ent); 4607f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ret < 0) 4608f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail_free; 4609f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4610f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* initialize chip-specific variables */ 4611f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ret = qib_init_7220_variables(dd); 4612f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ret) 4613f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail_cleanup; 4614f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4615f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (qib_mini_init) 4616f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 4617f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4618f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell boardid = SYM_FIELD(dd->revision, Revision, 4619f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell BoardID); 4620f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell switch (boardid) { 4621f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case 0: 4622f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case 2: 4623f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case 10: 4624f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell case 12: 4625f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell minwidth = 16; /* x16 capable boards */ 4626f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 4627f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell default: 4628f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell minwidth = 8; /* x8 capable boards */ 4629f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell break; 4630f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 4631f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (qib_pcie_params(dd, minwidth, NULL, NULL)) 46327fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn qib_dev_err(dd, 46337fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn "Failed to setup PCIe or interrupts; continuing anyway\n"); 4634f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4635f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* save IRQ for possible later use */ 4636f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->cspec->irq = pdev->irq; 4637f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4638f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (qib_read_kreg64(dd, kr_hwerrstatus) & 4639f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_SERDESPLLFAILED) 4640f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_hwerrclear, 4641f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QLOGIC_IB_HWE_SERDESPLLFAILED); 4642f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4643f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* setup interrupt handler (interrupt type handled above) */ 4644f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_setup_7220_interrupt(dd); 4645f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_7220_init_hwerrors(dd); 4646f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4647f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* clear diagctrl register, in case diags were running and crashed */ 4648f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_write_kreg(dd, kr_hwdiagctrl, 0); 4649f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4650f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto bail; 4651f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 4652f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellbail_cleanup: 4653f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_pcie_ddcleanup(dd); 4654f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellbail_free: 4655f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_free_devdata(dd); 4656f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd = ERR_PTR(ret); 4657f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellbail: 4658f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return dd; 4659f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 4660