aboutsummaryrefslogtreecommitdiff
path: root/drivers/infiniband/hw/ipath/ipath_intr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_intr.c')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_intr.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index dde5dfc9fcf..ed82ecbb02d 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -366,6 +366,22 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd,
dd->ipath_ibpollcnt = 0; /* not poll*, now */
ipath_stats.sps_iblink++;
+ if (ibstate != init && dd->ipath_lastlinkrecov && ipath_linkrecovery) {
+ u64 linkrecov;
+ linkrecov = ipath_snap_cntr(dd,
+ dd->ipath_cregs->cr_iblinkerrrecovcnt);
+ if (linkrecov != dd->ipath_lastlinkrecov) {
+ ipath_dbg("IB linkrecov up %Lx (%s %s) recov %Lu\n",
+ ibcs, ib_linkstate(dd, ibcs),
+ ipath_ibcstatus_str[ltstate],
+ linkrecov);
+ /* and no more until active again */
+ dd->ipath_lastlinkrecov = 0;
+ ipath_set_linkstate(dd, IPATH_IB_LINKDOWN);
+ goto skip_ibchange;
+ }
+ }
+
if (ibstate == init || ibstate == arm || ibstate == active) {
*dd->ipath_statusp &= ~IPATH_STATUS_IB_NOCABLE;
if (ibstate == init || ibstate == arm) {
@@ -392,6 +408,8 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd,
IPATH_NOCABLE);
ipath_hol_down(dd);
} else { /* active */
+ dd->ipath_lastlinkrecov = ipath_snap_cntr(dd,
+ dd->ipath_cregs->cr_iblinkerrrecovcnt);
*dd->ipath_statusp |=
IPATH_STATUS_IB_READY | IPATH_STATUS_IB_CONF;
dd->ipath_flags |= IPATH_LINKACTIVE;