Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/infiniband/hw/qib/qib_intr.c
15112 views
1
/*
2
* Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation.
3
* All rights reserved.
4
* Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
5
*
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:
11
*
12
* Redistribution and use in source and binary forms, with or
13
* without modification, are permitted provided that the following
14
* conditions are met:
15
*
16
* - Redistributions of source code must retain the above
17
* copyright notice, this list of conditions and the following
18
* disclaimer.
19
*
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.
24
*
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
32
* SOFTWARE.
33
*/
34
35
#include <linux/pci.h>
36
#include <linux/delay.h>
37
38
#include "qib.h"
39
#include "qib_common.h"
40
41
/**
42
* qib_format_hwmsg - format a single hwerror message
43
* @msg message buffer
44
* @msgl length of message buffer
45
* @hwmsg message to add to message buffer
46
*/
47
static void qib_format_hwmsg(char *msg, size_t msgl, const char *hwmsg)
48
{
49
strlcat(msg, "[", msgl);
50
strlcat(msg, hwmsg, msgl);
51
strlcat(msg, "]", msgl);
52
}
53
54
/**
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
59
* @msg message buffer
60
* @msgl message buffer length
61
*/
62
void qib_format_hwerrors(u64 hwerrs, const struct qib_hwerror_msgs *hwerrmsgs,
63
size_t nhwerrmsgs, char *msg, size_t msgl)
64
{
65
int i;
66
67
for (i = 0; i < nhwerrmsgs; i++)
68
if (hwerrs & hwerrmsgs[i].mask)
69
qib_format_hwmsg(msg, msgl, hwerrmsgs[i].msg);
70
}
71
72
static void signal_ib_event(struct qib_pportdata *ppd, enum ib_event_type ev)
73
{
74
struct ib_event event;
75
struct qib_devdata *dd = ppd->dd;
76
77
event.device = &dd->verbs_dev.ibdev;
78
event.element.port_num = ppd->port;
79
event.event = ev;
80
ib_dispatch_event(&event);
81
}
82
83
void qib_handle_e_ibstatuschanged(struct qib_pportdata *ppd, u64 ibcs)
84
{
85
struct qib_devdata *dd = ppd->dd;
86
unsigned long flags;
87
u32 lstate;
88
u8 ltstate;
89
enum ib_event_type ev = 0;
90
91
lstate = dd->f_iblink_state(ibcs); /* linkstate */
92
ltstate = dd->f_ibphys_portstate(ibcs);
93
94
/*
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.
99
*
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.
102
*/
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);
116
}
117
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);
129
} else {
130
ppd->lflags |= QIBL_LINKINIT | QIBL_LINKV;
131
ppd->lflags &= ~(QIBL_LINKARMED |
132
QIBL_LINKDOWN | QIBL_LINKACTIVE);
133
}
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 */
142
*ppd->statusp |=
143
QIB_STATUS_IB_READY | QIB_STATUS_IB_CONF;
144
qib_clear_symerror_on_linkup((unsigned long)ppd);
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);
155
}
156
} else { /* down */
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;
165
}
166
167
skip_ibchange:
168
ppd->lastibcstat = ibcs;
169
if (ev)
170
signal_ib_event(ppd, ev);
171
return;
172
}
173
174
void qib_clear_symerror_on_linkup(unsigned long opaque)
175
{
176
struct qib_pportdata *ppd = (struct qib_pportdata *)opaque;
177
178
if (ppd->lflags & QIBL_LINKACTIVE)
179
return;
180
181
ppd->ibport_data.z_symbol_error_counter =
182
ppd->dd->f_portcntr(ppd, QIBPORTCNTR_IBSYMBOLERR);
183
}
184
185
/*
186
* Handle receive interrupts for user ctxts; this means a user
187
* process was waiting for a packet to arrive, and didn't want
188
* to poll.
189
*/
190
void qib_handle_urcv(struct qib_devdata *dd, u64 ctxtr)
191
{
192
struct qib_ctxtdata *rcd;
193
unsigned long flags;
194
int i;
195
196
spin_lock_irqsave(&dd->uctxt_lock, flags);
197
for (i = dd->first_user_ctxt; dd->rcd && i < dd->cfgctxts; i++) {
198
if (!(ctxtr & (1ULL << i)))
199
continue;
200
rcd = dd->rcd[i];
201
if (!rcd || !rcd->cnt)
202
continue;
203
204
if (test_and_clear_bit(QIB_CTXT_WAITING_RCV, &rcd->flag)) {
205
wake_up_interruptible(&rcd->wait);
206
dd->f_rcvctrl(rcd->ppd, QIB_RCVCTRL_INTRAVAIL_DIS,
207
rcd->ctxt);
208
} else if (test_and_clear_bit(QIB_CTXT_WAITING_URG,
209
&rcd->flag)) {
210
rcd->urgent++;
211
wake_up_interruptible(&rcd->wait);
212
}
213
}
214
spin_unlock_irqrestore(&dd->uctxt_lock, flags);
215
}
216
217
void qib_bad_intrstatus(struct qib_devdata *dd)
218
{
219
static int allbits;
220
221
/* separate routine, for better optimization of qib_intr() */
222
223
/*
224
* We print the message and disable interrupts, in hope of
225
* having a better chance of debugging the problem.
226
*/
227
qib_dev_err(dd, "Read of chip interrupt status failed"
228
" disabling interrupts\n");
229
if (allbits++) {
230
/* disable interrupt delivery, something is very wrong */
231
if (allbits == 2)
232
dd->f_set_intr_state(dd, 0);
233
if (allbits == 3) {
234
qib_dev_err(dd, "2nd bad interrupt status, "
235
"unregistering interrupts\n");
236
dd->flags |= QIB_BADINTR;
237
dd->flags &= ~QIB_INITTED;
238
dd->f_free_irq(dd);
239
}
240
}
241
}
242
243