2 * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation.
4 * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
6 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35 #include <linux/pci.h>
36 #include <linux/delay.h>
39 #include "qib_common.h"
42 * qib_format_hwmsg - format a single hwerror message
44 * @msgl length of message buffer
45 * @hwmsg message to add to message buffer
47 static void qib_format_hwmsg(char *msg
, size_t msgl
, const char *hwmsg
)
49 strlcat(msg
, "[", msgl
);
50 strlcat(msg
, hwmsg
, msgl
);
51 strlcat(msg
, "]", msgl
);
55 * qib_format_hwerrors - format hardware error messages for display
56 * @hwerrs hardware errors bit vector
57 * @hwerrmsgs hardware error descriptions
58 * @nhwerrmsgs number of hwerrmsgs
60 * @msgl message buffer length
62 void qib_format_hwerrors(u64 hwerrs
, const struct qib_hwerror_msgs
*hwerrmsgs
,
63 size_t nhwerrmsgs
, char *msg
, size_t msgl
)
67 for (i
= 0; i
< nhwerrmsgs
; i
++)
68 if (hwerrs
& hwerrmsgs
[i
].mask
)
69 qib_format_hwmsg(msg
, msgl
, hwerrmsgs
[i
].msg
);
72 static void signal_ib_event(struct qib_pportdata
*ppd
, enum ib_event_type ev
)
74 struct ib_event event
;
75 struct qib_devdata
*dd
= ppd
->dd
;
77 event
.device
= &dd
->verbs_dev
.ibdev
;
78 event
.element
.port_num
= ppd
->port
;
80 ib_dispatch_event(&event
);
83 void qib_handle_e_ibstatuschanged(struct qib_pportdata
*ppd
, u64 ibcs
)
85 struct qib_devdata
*dd
= ppd
->dd
;
89 enum ib_event_type ev
= 0;
91 lstate
= dd
->f_iblink_state(ibcs
); /* linkstate */
92 ltstate
= dd
->f_ibphys_portstate(ibcs
);
95 * If linkstate transitions into INIT from any of the various down
96 * states, or if it transitions from any of the up (INIT or better)
97 * states into any of the down states (except link recovery), then
98 * call the chip-specific code to take appropriate actions.
100 if (lstate
>= IB_PORT_INIT
&& (ppd
->lflags
& QIBL_LINKDOWN
) &&
101 ltstate
== IB_PHYSPORTSTATE_LINKUP
) {
102 /* transitioned to UP */
103 if (dd
->f_ib_updown(ppd
, 1, ibcs
))
104 goto skip_ibchange
; /* chip-code handled */
105 } else if (ppd
->lflags
& (QIBL_LINKINIT
| QIBL_LINKARMED
|
106 QIBL_LINKACTIVE
| QIBL_IB_FORCE_NOTIFY
)) {
107 if (ltstate
!= IB_PHYSPORTSTATE_LINKUP
&&
108 ltstate
<= IB_PHYSPORTSTATE_CFG_TRAIN
&&
109 dd
->f_ib_updown(ppd
, 0, ibcs
))
110 goto skip_ibchange
; /* chip-code handled */
111 qib_set_uevent_bits(ppd
, _QIB_EVENT_LINKDOWN_BIT
);
114 if (lstate
!= IB_PORT_DOWN
) {
115 /* lstate is INIT, ARMED, or ACTIVE */
116 if (lstate
!= IB_PORT_ACTIVE
) {
117 *ppd
->statusp
&= ~QIB_STATUS_IB_READY
;
118 if (ppd
->lflags
& QIBL_LINKACTIVE
)
119 ev
= IB_EVENT_PORT_ERR
;
120 spin_lock_irqsave(&ppd
->lflags_lock
, flags
);
121 if (lstate
== IB_PORT_ARMED
) {
122 ppd
->lflags
|= QIBL_LINKARMED
| QIBL_LINKV
;
123 ppd
->lflags
&= ~(QIBL_LINKINIT
|
124 QIBL_LINKDOWN
| QIBL_LINKACTIVE
);
126 ppd
->lflags
|= QIBL_LINKINIT
| QIBL_LINKV
;
127 ppd
->lflags
&= ~(QIBL_LINKARMED
|
128 QIBL_LINKDOWN
| QIBL_LINKACTIVE
);
130 spin_unlock_irqrestore(&ppd
->lflags_lock
, flags
);
131 /* start a 75msec timer to clear symbol errors */
132 mod_timer(&ppd
->symerr_clear_timer
,
133 msecs_to_jiffies(75));
134 } else if (ltstate
== IB_PHYSPORTSTATE_LINKUP
&&
135 !(ppd
->lflags
& QIBL_LINKACTIVE
)) {
136 /* active, but not active defered */
137 qib_hol_up(ppd
); /* useful only for 6120 now */
139 QIB_STATUS_IB_READY
| QIB_STATUS_IB_CONF
;
140 qib_clear_symerror_on_linkup((unsigned long)ppd
);
141 spin_lock_irqsave(&ppd
->lflags_lock
, flags
);
142 ppd
->lflags
|= QIBL_LINKACTIVE
| QIBL_LINKV
;
143 ppd
->lflags
&= ~(QIBL_LINKINIT
|
144 QIBL_LINKDOWN
| QIBL_LINKARMED
);
145 spin_unlock_irqrestore(&ppd
->lflags_lock
, flags
);
146 if (dd
->flags
& QIB_HAS_SEND_DMA
)
147 qib_sdma_process_event(ppd
,
148 qib_sdma_event_e30_go_running
);
149 ev
= IB_EVENT_PORT_ACTIVE
;
150 dd
->f_setextled(ppd
, 1);
153 if (ppd
->lflags
& QIBL_LINKACTIVE
)
154 ev
= IB_EVENT_PORT_ERR
;
155 spin_lock_irqsave(&ppd
->lflags_lock
, flags
);
156 ppd
->lflags
|= QIBL_LINKDOWN
| QIBL_LINKV
;
157 ppd
->lflags
&= ~(QIBL_LINKINIT
|
158 QIBL_LINKACTIVE
| QIBL_LINKARMED
);
159 spin_unlock_irqrestore(&ppd
->lflags_lock
, flags
);
160 *ppd
->statusp
&= ~QIB_STATUS_IB_READY
;
164 ppd
->lastibcstat
= ibcs
;
166 signal_ib_event(ppd
, ev
);
170 void qib_clear_symerror_on_linkup(unsigned long opaque
)
172 struct qib_pportdata
*ppd
= (struct qib_pportdata
*)opaque
;
174 if (ppd
->lflags
& QIBL_LINKACTIVE
)
177 ppd
->ibport_data
.z_symbol_error_counter
=
178 ppd
->dd
->f_portcntr(ppd
, QIBPORTCNTR_IBSYMBOLERR
);
182 * Handle receive interrupts for user ctxts; this means a user
183 * process was waiting for a packet to arrive, and didn't want
186 void qib_handle_urcv(struct qib_devdata
*dd
, u64 ctxtr
)
188 struct qib_ctxtdata
*rcd
;
192 spin_lock_irqsave(&dd
->uctxt_lock
, flags
);
193 for (i
= dd
->first_user_ctxt
; dd
->rcd
&& i
< dd
->cfgctxts
; i
++) {
194 if (!(ctxtr
& (1ULL << i
)))
197 if (!rcd
|| !rcd
->cnt
)
200 if (test_and_clear_bit(QIB_CTXT_WAITING_RCV
, &rcd
->flag
)) {
201 wake_up_interruptible(&rcd
->wait
);
202 dd
->f_rcvctrl(rcd
->ppd
, QIB_RCVCTRL_INTRAVAIL_DIS
,
204 } else if (test_and_clear_bit(QIB_CTXT_WAITING_URG
,
207 wake_up_interruptible(&rcd
->wait
);
210 spin_unlock_irqrestore(&dd
->uctxt_lock
, flags
);
213 void qib_bad_intrstatus(struct qib_devdata
*dd
)
217 /* separate routine, for better optimization of qib_intr() */
220 * We print the message and disable interrupts, in hope of
221 * having a better chance of debugging the problem.
223 qib_dev_err(dd
, "Read of chip interrupt status failed"
224 " disabling interrupts\n");
226 /* disable interrupt delivery, something is very wrong */
228 dd
->f_set_intr_state(dd
, 0);
230 qib_dev_err(dd
, "2nd bad interrupt status, "
231 "unregistering interrupts\n");
232 dd
->flags
|= QIB_BADINTR
;
233 dd
->flags
&= ~QIB_INITTED
;