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
.rdi
.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 * ppd->lflags could be 0 if this is the first time the interrupt
101 * handlers has been called but the link is already up.
103 if (lstate
>= IB_PORT_INIT
&&
104 (!ppd
->lflags
|| (ppd
->lflags
& QIBL_LINKDOWN
)) &&
105 ltstate
== IB_PHYSPORTSTATE_LINKUP
) {
106 /* transitioned to UP */
107 if (dd
->f_ib_updown(ppd
, 1, ibcs
))
108 goto skip_ibchange
; /* chip-code handled */
109 } else if (ppd
->lflags
& (QIBL_LINKINIT
| QIBL_LINKARMED
|
110 QIBL_LINKACTIVE
| QIBL_IB_FORCE_NOTIFY
)) {
111 if (ltstate
!= IB_PHYSPORTSTATE_LINKUP
&&
112 ltstate
<= IB_PHYSPORTSTATE_CFG_TRAIN
&&
113 dd
->f_ib_updown(ppd
, 0, ibcs
))
114 goto skip_ibchange
; /* chip-code handled */
115 qib_set_uevent_bits(ppd
, _QIB_EVENT_LINKDOWN_BIT
);
118 if (lstate
!= IB_PORT_DOWN
) {
119 /* lstate is INIT, ARMED, or ACTIVE */
120 if (lstate
!= IB_PORT_ACTIVE
) {
121 *ppd
->statusp
&= ~QIB_STATUS_IB_READY
;
122 if (ppd
->lflags
& QIBL_LINKACTIVE
)
123 ev
= IB_EVENT_PORT_ERR
;
124 spin_lock_irqsave(&ppd
->lflags_lock
, flags
);
125 if (lstate
== IB_PORT_ARMED
) {
126 ppd
->lflags
|= QIBL_LINKARMED
| QIBL_LINKV
;
127 ppd
->lflags
&= ~(QIBL_LINKINIT
|
128 QIBL_LINKDOWN
| QIBL_LINKACTIVE
);
130 ppd
->lflags
|= QIBL_LINKINIT
| QIBL_LINKV
;
131 ppd
->lflags
&= ~(QIBL_LINKARMED
|
132 QIBL_LINKDOWN
| QIBL_LINKACTIVE
);
134 spin_unlock_irqrestore(&ppd
->lflags_lock
, flags
);
135 /* start a 75msec timer to clear symbol errors */
136 mod_timer(&ppd
->symerr_clear_timer
,
137 msecs_to_jiffies(75));
138 } else if (ltstate
== IB_PHYSPORTSTATE_LINKUP
&&
139 !(ppd
->lflags
& QIBL_LINKACTIVE
)) {
140 /* active, but not active defered */
141 qib_hol_up(ppd
); /* useful only for 6120 now */
143 QIB_STATUS_IB_READY
| QIB_STATUS_IB_CONF
;
144 qib_clear_symerror_on_linkup(&ppd
->symerr_clear_timer
);
145 spin_lock_irqsave(&ppd
->lflags_lock
, flags
);
146 ppd
->lflags
|= QIBL_LINKACTIVE
| QIBL_LINKV
;
147 ppd
->lflags
&= ~(QIBL_LINKINIT
|
148 QIBL_LINKDOWN
| QIBL_LINKARMED
);
149 spin_unlock_irqrestore(&ppd
->lflags_lock
, flags
);
150 if (dd
->flags
& QIB_HAS_SEND_DMA
)
151 qib_sdma_process_event(ppd
,
152 qib_sdma_event_e30_go_running
);
153 ev
= IB_EVENT_PORT_ACTIVE
;
154 dd
->f_setextled(ppd
, 1);
157 if (ppd
->lflags
& QIBL_LINKACTIVE
)
158 ev
= IB_EVENT_PORT_ERR
;
159 spin_lock_irqsave(&ppd
->lflags_lock
, flags
);
160 ppd
->lflags
|= QIBL_LINKDOWN
| QIBL_LINKV
;
161 ppd
->lflags
&= ~(QIBL_LINKINIT
|
162 QIBL_LINKACTIVE
| QIBL_LINKARMED
);
163 spin_unlock_irqrestore(&ppd
->lflags_lock
, flags
);
164 *ppd
->statusp
&= ~QIB_STATUS_IB_READY
;
168 ppd
->lastibcstat
= ibcs
;
170 signal_ib_event(ppd
, ev
);
173 void qib_clear_symerror_on_linkup(struct timer_list
*t
)
175 struct qib_pportdata
*ppd
= from_timer(ppd
, t
, symerr_clear_timer
);
177 if (ppd
->lflags
& QIBL_LINKACTIVE
)
180 ppd
->ibport_data
.z_symbol_error_counter
=
181 ppd
->dd
->f_portcntr(ppd
, QIBPORTCNTR_IBSYMBOLERR
);
185 * Handle receive interrupts for user ctxts; this means a user
186 * process was waiting for a packet to arrive, and didn't want
189 void qib_handle_urcv(struct qib_devdata
*dd
, u64 ctxtr
)
191 struct qib_ctxtdata
*rcd
;
195 spin_lock_irqsave(&dd
->uctxt_lock
, flags
);
196 for (i
= dd
->first_user_ctxt
; dd
->rcd
&& i
< dd
->cfgctxts
; i
++) {
197 if (!(ctxtr
& (1ULL << i
)))
200 if (!rcd
|| !rcd
->cnt
)
203 if (test_and_clear_bit(QIB_CTXT_WAITING_RCV
, &rcd
->flag
)) {
204 wake_up_interruptible(&rcd
->wait
);
205 dd
->f_rcvctrl(rcd
->ppd
, QIB_RCVCTRL_INTRAVAIL_DIS
,
207 } else if (test_and_clear_bit(QIB_CTXT_WAITING_URG
,
210 wake_up_interruptible(&rcd
->wait
);
213 spin_unlock_irqrestore(&dd
->uctxt_lock
, flags
);
216 void qib_bad_intrstatus(struct qib_devdata
*dd
)
220 /* separate routine, for better optimization of qib_intr() */
223 * We print the message and disable interrupts, in hope of
224 * having a better chance of debugging the problem.
227 "Read of chip interrupt status failed disabling interrupts\n");
229 /* disable interrupt delivery, something is very wrong */
231 dd
->f_set_intr_state(dd
, 0);
234 "2nd bad interrupt status, unregistering interrupts\n");
235 dd
->flags
|= QIB_BADINTR
;
236 dd
->flags
&= ~QIB_INITTED
;