Commit | Line | Data |
---|---|---|
3ec648c6 | 1 | // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause |
77241056 | 2 | /* |
05d6ac1d | 3 | * Copyright(c) 2015, 2016 Intel Corporation. |
77241056 MM |
4 | */ |
5 | ||
6 | #include <linux/pci.h> | |
7 | #include <linux/delay.h> | |
8737ce95 | 8 | #include <linux/bitmap.h> |
77241056 MM |
9 | |
10 | #include "hfi.h" | |
11 | #include "common.h" | |
12 | #include "sdma.h" | |
13 | ||
4061f3a4 MR |
14 | #define LINK_UP_DELAY 500 /* in microseconds */ |
15 | ||
641f348b JS |
16 | static void set_mgmt_allowed(struct hfi1_pportdata *ppd) |
17 | { | |
18 | u32 frame; | |
19 | struct hfi1_devdata *dd = ppd->dd; | |
20 | ||
21 | if (ppd->neighbor_type == NEIGHBOR_TYPE_HFI) { | |
22 | ppd->mgmt_allowed = 1; | |
23 | } else { | |
24 | read_8051_config(dd, REMOTE_LNI_INFO, GENERAL_CONFIG, &frame); | |
25 | ppd->mgmt_allowed = (frame >> MGMT_ALLOWED_SHIFT) | |
26 | & MGMT_ALLOWED_MASK; | |
27 | } | |
28 | } | |
29 | ||
30 | /* | |
31 | * Our neighbor has indicated that we are allowed to act as a fabric | |
32 | * manager, so place the full management partition key in the second | |
33 | * (0-based) pkey array position. Note that we should already have | |
34 | * the limited management partition key in array element 1, and also | |
35 | * that the port is not yet up when add_full_mgmt_pkey() is invoked. | |
36 | */ | |
37 | static void add_full_mgmt_pkey(struct hfi1_pportdata *ppd) | |
38 | { | |
39 | struct hfi1_devdata *dd = ppd->dd; | |
40 | ||
41 | /* Sanity check - ppd->pkeys[2] should be 0, or already initialized */ | |
42 | if (!((ppd->pkeys[2] == 0) || (ppd->pkeys[2] == FULL_MGMT_P_KEY))) | |
43 | dd_dev_warn(dd, "%s pkey[2] already set to 0x%x, resetting it to 0x%x\n", | |
44 | __func__, ppd->pkeys[2], FULL_MGMT_P_KEY); | |
45 | ppd->pkeys[2] = FULL_MGMT_P_KEY; | |
46 | (void)hfi1_set_ib_cfg(ppd, HFI1_IB_CFG_PKEYS, 0); | |
47 | hfi1_event_pkey_change(ppd->dd, ppd->port); | |
48 | } | |
49 | ||
77241056 MM |
50 | /** |
51 | * format_hwmsg - format a single hwerror message | |
510a8949 LJ |
52 | * @msg: message buffer |
53 | * @msgl: length of message buffer | |
54 | * @hwmsg: message to add to message buffer | |
77241056 MM |
55 | */ |
56 | static void format_hwmsg(char *msg, size_t msgl, const char *hwmsg) | |
57 | { | |
58 | strlcat(msg, "[", msgl); | |
59 | strlcat(msg, hwmsg, msgl); | |
60 | strlcat(msg, "]", msgl); | |
61 | } | |
62 | ||
63 | /** | |
64 | * hfi1_format_hwerrors - format hardware error messages for display | |
510a8949 LJ |
65 | * @hwerrs: hardware errors bit vector |
66 | * @hwerrmsgs: hardware error descriptions | |
67 | * @nhwerrmsgs: number of hwerrmsgs | |
68 | * @msg: message buffer | |
69 | * @msgl: message buffer length | |
77241056 MM |
70 | */ |
71 | void hfi1_format_hwerrors(u64 hwerrs, const struct hfi1_hwerror_msgs *hwerrmsgs, | |
72 | size_t nhwerrmsgs, char *msg, size_t msgl) | |
73 | { | |
74 | int i; | |
75 | ||
76 | for (i = 0; i < nhwerrmsgs; i++) | |
77 | if (hwerrs & hwerrmsgs[i].mask) | |
78 | format_hwmsg(msg, msgl, hwerrmsgs[i].msg); | |
79 | } | |
80 | ||
81 | static void signal_ib_event(struct hfi1_pportdata *ppd, enum ib_event_type ev) | |
82 | { | |
83 | struct ib_event event; | |
84 | struct hfi1_devdata *dd = ppd->dd; | |
85 | ||
86 | /* | |
87 | * Only call ib_dispatch_event() if the IB device has been | |
88 | * registered. HFI1_INITED is set iff the driver has successfully | |
89 | * registered with the IB core. | |
90 | */ | |
91 | if (!(dd->flags & HFI1_INITTED)) | |
92 | return; | |
ec3f2c12 | 93 | event.device = &dd->verbs_dev.rdi.ibdev; |
77241056 MM |
94 | event.element.port_num = ppd->port; |
95 | event.event = ev; | |
96 | ib_dispatch_event(&event); | |
97 | } | |
98 | ||
4061f3a4 MR |
99 | /** |
100 | * handle_linkup_change - finish linkup/down state changes | |
101 | * @dd: valid device | |
102 | * @linkup: link state information | |
103 | * | |
77241056 | 104 | * Handle a linkup or link down notification. |
4061f3a4 MR |
105 | * The HW needs time to finish its link up state change. Give it that chance. |
106 | * | |
77241056 | 107 | * This is called outside an interrupt. |
4061f3a4 | 108 | * |
77241056 MM |
109 | */ |
110 | void handle_linkup_change(struct hfi1_devdata *dd, u32 linkup) | |
111 | { | |
112 | struct hfi1_pportdata *ppd = &dd->pport[0]; | |
113 | enum ib_event_type ev; | |
114 | ||
115 | if (!(ppd->linkup ^ !!linkup)) | |
116 | return; /* no change, nothing to do */ | |
117 | ||
118 | if (linkup) { | |
119 | /* | |
120 | * Quick linkup and all link up on the simulator does not | |
121 | * trigger or implement: | |
122 | * - VerifyCap interrupt | |
123 | * - VerifyCap frames | |
124 | * But rather moves directly to LinkUp. | |
125 | * | |
126 | * Do the work of the VerifyCap interrupt handler, | |
127 | * handle_verify_cap(), but do not try moving the state to | |
128 | * LinkUp as we are already there. | |
129 | * | |
130 | * NOTE: This uses this device's vAU, vCU, and vl15_init for | |
131 | * the remote values. Both sides must be using the values. | |
132 | */ | |
d0d236ea | 133 | if (quick_linkup || dd->icode == ICODE_FUNCTIONAL_SIMULATOR) { |
b3e6b4bd BJ |
134 | set_up_vau(dd, dd->vau); |
135 | set_up_vl15(dd, dd->vl15_init); | |
77241056 | 136 | assign_remote_cm_au_table(dd, dd->vcu); |
77241056 MM |
137 | } |
138 | ||
98b9ee20 SS |
139 | ppd->neighbor_guid = |
140 | read_csr(dd, DC_DC8051_STS_REMOTE_GUID); | |
141 | ppd->neighbor_type = | |
142 | read_csr(dd, DC_DC8051_STS_REMOTE_NODE_TYPE) & | |
143 | DC_DC8051_STS_REMOTE_NODE_TYPE_VAL_MASK; | |
144 | ppd->neighbor_port_number = | |
145 | read_csr(dd, DC_DC8051_STS_REMOTE_PORT_NO) & | |
146 | DC_DC8051_STS_REMOTE_PORT_NO_VAL_SMASK; | |
147 | ppd->neighbor_fm_security = | |
148 | read_csr(dd, DC_DC8051_STS_REMOTE_FM_SECURITY) & | |
149 | DC_DC8051_STS_LOCAL_FM_SECURITY_DISABLED_MASK; | |
150 | dd_dev_info(dd, | |
151 | "Neighbor Guid %llx, Type %d, Port Num %d\n", | |
152 | ppd->neighbor_guid, ppd->neighbor_type, | |
153 | ppd->neighbor_port_number); | |
154 | ||
4061f3a4 MR |
155 | /* HW needs LINK_UP_DELAY to settle, give it that chance */ |
156 | udelay(LINK_UP_DELAY); | |
157 | ||
641f348b JS |
158 | /* |
159 | * 'MgmtAllowed' information, which is exchanged during | |
160 | * LNI, is available at this point. | |
161 | */ | |
162 | set_mgmt_allowed(ppd); | |
163 | ||
164 | if (ppd->mgmt_allowed) | |
165 | add_full_mgmt_pkey(ppd); | |
166 | ||
77241056 MM |
167 | /* physical link went up */ |
168 | ppd->linkup = 1; | |
a9c05e35 BM |
169 | ppd->offline_disabled_reason = |
170 | HFI1_ODR_MASK(OPA_LINKDOWN_REASON_NONE); | |
77241056 MM |
171 | |
172 | /* link widths are not available until the link is fully up */ | |
173 | get_linkup_link_widths(ppd); | |
174 | ||
175 | } else { | |
176 | /* physical link went down */ | |
177 | ppd->linkup = 0; | |
178 | ||
179 | /* clear HW details of the previous connection */ | |
5e2d6764 | 180 | ppd->actual_vls_operational = 0; |
77241056 MM |
181 | reset_link_credits(dd); |
182 | ||
183 | /* freeze after a link down to guarantee a clean egress */ | |
8638b77f | 184 | start_freeze_handling(ppd, FREEZE_SELF | FREEZE_LINK_DOWN); |
77241056 MM |
185 | |
186 | ev = IB_EVENT_PORT_ERR; | |
187 | ||
188 | hfi1_set_uevent_bits(ppd, _HFI1_EVENT_LINKDOWN_BIT); | |
189 | ||
190 | /* if we are down, the neighbor is down */ | |
191 | ppd->neighbor_normal = 0; | |
192 | ||
193 | /* notify IB of the link change */ | |
194 | signal_ib_event(ppd, ev); | |
195 | } | |
77241056 MM |
196 | } |
197 | ||
198 | /* | |
199 | * Handle receive or urgent interrupts for user contexts. This means a user | |
200 | * process was waiting for a packet to arrive, and didn't want to poll. | |
201 | */ | |
202 | void handle_user_interrupt(struct hfi1_ctxtdata *rcd) | |
203 | { | |
204 | struct hfi1_devdata *dd = rcd->dd; | |
205 | unsigned long flags; | |
206 | ||
207 | spin_lock_irqsave(&dd->uctxt_lock, flags); | |
8737ce95 | 208 | if (bitmap_empty(rcd->in_use_ctxts, HFI1_MAX_SHARED_CTXTS)) |
77241056 MM |
209 | goto done; |
210 | ||
211 | if (test_and_clear_bit(HFI1_CTXT_WAITING_RCV, &rcd->event_flags)) { | |
212 | wake_up_interruptible(&rcd->wait); | |
2250563e | 213 | hfi1_rcvctrl(dd, HFI1_RCVCTRL_INTRAVAIL_DIS, rcd); |
77241056 MM |
214 | } else if (test_and_clear_bit(HFI1_CTXT_WAITING_URG, |
215 | &rcd->event_flags)) { | |
216 | rcd->urgent++; | |
217 | wake_up_interruptible(&rcd->wait); | |
218 | } | |
219 | done: | |
220 | spin_unlock_irqrestore(&dd->uctxt_lock, flags); | |
221 | } |