diff options
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_stats.c')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_stats.c | 54 |
1 files changed, 48 insertions, 6 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_stats.c b/drivers/infiniband/hw/ipath/ipath_stats.c index 73ed17d03188..bae4f56f7271 100644 --- a/drivers/infiniband/hw/ipath/ipath_stats.c +++ b/drivers/infiniband/hw/ipath/ipath_stats.c | |||
@@ -196,6 +196,45 @@ static void ipath_qcheck(struct ipath_devdata *dd) | |||
196 | } | 196 | } |
197 | } | 197 | } |
198 | 198 | ||
199 | static void ipath_chk_errormask(struct ipath_devdata *dd) | ||
200 | { | ||
201 | static u32 fixed; | ||
202 | u32 ctrl; | ||
203 | unsigned long errormask; | ||
204 | unsigned long hwerrs; | ||
205 | |||
206 | if (!dd->ipath_errormask || !(dd->ipath_flags & IPATH_INITTED)) | ||
207 | return; | ||
208 | |||
209 | errormask = ipath_read_kreg64(dd, dd->ipath_kregs->kr_errormask); | ||
210 | |||
211 | if (errormask == dd->ipath_errormask) | ||
212 | return; | ||
213 | fixed++; | ||
214 | |||
215 | hwerrs = ipath_read_kreg64(dd, dd->ipath_kregs->kr_hwerrstatus); | ||
216 | ctrl = ipath_read_kreg32(dd, dd->ipath_kregs->kr_control); | ||
217 | |||
218 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, | ||
219 | dd->ipath_errormask); | ||
220 | |||
221 | if ((hwerrs & dd->ipath_hwerrmask) || | ||
222 | (ctrl & INFINIPATH_C_FREEZEMODE)) { | ||
223 | /* force re-interrupt of pending events, just in case */ | ||
224 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, 0ULL); | ||
225 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, 0ULL); | ||
226 | ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, 0ULL); | ||
227 | dev_info(&dd->pcidev->dev, | ||
228 | "errormask fixed(%u) %lx -> %lx, ctrl %x hwerr %lx\n", | ||
229 | fixed, errormask, (unsigned long)dd->ipath_errormask, | ||
230 | ctrl, hwerrs); | ||
231 | } else | ||
232 | ipath_dbg("errormask fixed(%u) %lx -> %lx, no freeze\n", | ||
233 | fixed, errormask, | ||
234 | (unsigned long)dd->ipath_errormask); | ||
235 | } | ||
236 | |||
237 | |||
199 | /** | 238 | /** |
200 | * ipath_get_faststats - get word counters from chip before they overflow | 239 | * ipath_get_faststats - get word counters from chip before they overflow |
201 | * @opaque - contains a pointer to the infinipath device ipath_devdata | 240 | * @opaque - contains a pointer to the infinipath device ipath_devdata |
@@ -251,14 +290,13 @@ void ipath_get_faststats(unsigned long opaque) | |||
251 | dd->ipath_lasterror = 0; | 290 | dd->ipath_lasterror = 0; |
252 | if (dd->ipath_lasthwerror) | 291 | if (dd->ipath_lasthwerror) |
253 | dd->ipath_lasthwerror = 0; | 292 | dd->ipath_lasthwerror = 0; |
254 | if ((dd->ipath_maskederrs & ~dd->ipath_ignorederrs) | 293 | if (dd->ipath_maskederrs |
255 | && time_after(jiffies, dd->ipath_unmasktime)) { | 294 | && time_after(jiffies, dd->ipath_unmasktime)) { |
256 | char ebuf[256]; | 295 | char ebuf[256]; |
257 | int iserr; | 296 | int iserr; |
258 | iserr = ipath_decode_err(ebuf, sizeof ebuf, | 297 | iserr = ipath_decode_err(ebuf, sizeof ebuf, |
259 | (dd->ipath_maskederrs & ~dd-> | 298 | dd->ipath_maskederrs); |
260 | ipath_ignorederrs)); | 299 | if (dd->ipath_maskederrs & |
261 | if ((dd->ipath_maskederrs & ~dd->ipath_ignorederrs) & | ||
262 | ~(INFINIPATH_E_RRCVEGRFULL | INFINIPATH_E_RRCVHDRFULL | | 300 | ~(INFINIPATH_E_RRCVEGRFULL | INFINIPATH_E_RRCVHDRFULL | |
263 | INFINIPATH_E_PKTERRS )) | 301 | INFINIPATH_E_PKTERRS )) |
264 | ipath_dev_err(dd, "Re-enabling masked errors " | 302 | ipath_dev_err(dd, "Re-enabling masked errors " |
@@ -278,9 +316,12 @@ void ipath_get_faststats(unsigned long opaque) | |||
278 | ipath_cdbg(ERRPKT, "Re-enabling packet" | 316 | ipath_cdbg(ERRPKT, "Re-enabling packet" |
279 | " problem interrupt (%s)\n", ebuf); | 317 | " problem interrupt (%s)\n", ebuf); |
280 | } | 318 | } |
281 | dd->ipath_maskederrs = dd->ipath_ignorederrs; | 319 | |
320 | /* re-enable masked errors */ | ||
321 | dd->ipath_errormask |= dd->ipath_maskederrs; | ||
282 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, | 322 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, |
283 | ~dd->ipath_maskederrs); | 323 | dd->ipath_errormask); |
324 | dd->ipath_maskederrs = 0; | ||
284 | } | 325 | } |
285 | 326 | ||
286 | /* limit qfull messages to ~one per minute per port */ | 327 | /* limit qfull messages to ~one per minute per port */ |
@@ -294,6 +335,7 @@ void ipath_get_faststats(unsigned long opaque) | |||
294 | } | 335 | } |
295 | } | 336 | } |
296 | 337 | ||
338 | ipath_chk_errormask(dd); | ||
297 | done: | 339 | done: |
298 | mod_timer(&dd->ipath_stats_timer, jiffies + HZ * 5); | 340 | mod_timer(&dd->ipath_stats_timer, jiffies + HZ * 5); |
299 | } | 341 | } |