aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c57
-rw-r--r--drivers/infiniband/hw/ipath/ipath_iba6110.c13
-rw-r--r--drivers/infiniband/hw/ipath/ipath_iba6120.c16
-rw-r--r--drivers/infiniband/hw/ipath/ipath_init_chip.c6
-rw-r--r--drivers/infiniband/hw/ipath/ipath_intr.c13
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h1
6 files changed, 68 insertions, 38 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index e9639860b48d..8b611796f33e 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -706,9 +706,9 @@ void ipath_disarm_piobufs(struct ipath_devdata *dd, unsigned first,
706 u64 sendctrl, sendorig; 706 u64 sendctrl, sendorig;
707 707
708 ipath_cdbg(PKT, "disarm %u PIObufs first=%u\n", cnt, first); 708 ipath_cdbg(PKT, "disarm %u PIObufs first=%u\n", cnt, first);
709 sendorig = dd->ipath_sendctrl | INFINIPATH_S_DISARM; 709 sendorig = dd->ipath_sendctrl;
710 for (i = first; i < last; i++) { 710 for (i = first; i < last; i++) {
711 sendctrl = sendorig | 711 sendctrl = sendorig | INFINIPATH_S_DISARM |
712 (i << INFINIPATH_S_DISARMPIOBUF_SHIFT); 712 (i << INFINIPATH_S_DISARMPIOBUF_SHIFT);
713 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 713 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
714 sendctrl); 714 sendctrl);
@@ -719,12 +719,12 @@ void ipath_disarm_piobufs(struct ipath_devdata *dd, unsigned first,
719 * while we were looping; no critical bits that would require 719 * while we were looping; no critical bits that would require
720 * locking. 720 * locking.
721 * 721 *
722 * Write a 0, and then the original value, reading scratch in 722 * disable PIOAVAILUPD, then re-enable, reading scratch in
723 * between. This seems to avoid a chip timing race that causes 723 * between. This seems to avoid a chip timing race that causes
724 * pioavail updates to memory to stop. 724 * pioavail updates to memory to stop.
725 */ 725 */
726 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 726 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
727 0); 727 sendorig & ~IPATH_S_PIOBUFAVAILUPD);
728 sendorig = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); 728 sendorig = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
729 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 729 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
730 dd->ipath_sendctrl); 730 dd->ipath_sendctrl);
@@ -1596,6 +1596,35 @@ int ipath_waitfor_mdio_cmdready(struct ipath_devdata *dd)
1596 return ret; 1596 return ret;
1597} 1597}
1598 1598
1599
1600/*
1601 * Flush all sends that might be in the ready to send state, as well as any
1602 * that are in the process of being sent. Used whenever we need to be
1603 * sure the send side is idle. Cleans up all buffer state by canceling
1604 * all pio buffers, and issuing an abort, which cleans up anything in the
1605 * launch fifo. The cancel is superfluous on some chip versions, but
1606 * it's safer to always do it.
1607 * PIOAvail bits are updated by the chip as if normal send had happened.
1608 */
1609void ipath_cancel_sends(struct ipath_devdata *dd)
1610{
1611 ipath_dbg("Cancelling all in-progress send buffers\n");
1612 dd->ipath_lastcancel = jiffies+HZ/2; /* skip armlaunch errs a bit */
1613 /*
1614 * the abort bit is auto-clearing. We read scratch to be sure
1615 * that cancels and the abort have taken effect in the chip.
1616 */
1617 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
1618 INFINIPATH_S_ABORT);
1619 ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
1620 ipath_disarm_piobufs(dd, 0,
1621 (unsigned)(dd->ipath_piobcnt2k + dd->ipath_piobcnt4k));
1622
1623 /* and again, be sure all have hit the chip */
1624 ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
1625}
1626
1627
1599static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which) 1628static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which)
1600{ 1629{
1601 static const char *what[4] = { 1630 static const char *what[4] = {
@@ -1617,14 +1646,8 @@ static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which)
1617 INFINIPATH_IBCS_LINKTRAININGSTATE_MASK]); 1646 INFINIPATH_IBCS_LINKTRAININGSTATE_MASK]);
1618 /* flush all queued sends when going to DOWN or INIT, to be sure that 1647 /* flush all queued sends when going to DOWN or INIT, to be sure that
1619 * they don't block MAD packets */ 1648 * they don't block MAD packets */
1620 if (!linkcmd || linkcmd == INFINIPATH_IBCC_LINKCMD_INIT) { 1649 if (!linkcmd || linkcmd == INFINIPATH_IBCC_LINKCMD_INIT)
1621 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 1650 ipath_cancel_sends(dd);
1622 INFINIPATH_S_ABORT);
1623 ipath_disarm_piobufs(dd, dd->ipath_lastport_piobuf,
1624 (unsigned)(dd->ipath_piobcnt2k +
1625 dd->ipath_piobcnt4k) -
1626 dd->ipath_lastport_piobuf);
1627 }
1628 1651
1629 ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl, 1652 ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl,
1630 dd->ipath_ibcctrl | which); 1653 dd->ipath_ibcctrl | which);
@@ -1967,17 +1990,9 @@ void ipath_shutdown_device(struct ipath_devdata *dd)
1967 */ 1990 */
1968 udelay(5); 1991 udelay(5);
1969 1992
1970 /*
1971 * abort any armed or launched PIO buffers that didn't go. (self
1972 * clearing). Will cause any packet currently being transmitted to
1973 * go out with an EBP, and may also cause a short packet error on
1974 * the receiver.
1975 */
1976 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
1977 INFINIPATH_S_ABORT);
1978
1979 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_DISABLE << 1993 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_DISABLE <<
1980 INFINIPATH_IBCC_LINKINITCMD_SHIFT); 1994 INFINIPATH_IBCC_LINKINITCMD_SHIFT);
1995 ipath_cancel_sends(dd);
1981 1996
1982 /* disable IBC */ 1997 /* disable IBC */
1983 dd->ipath_control &= ~INFINIPATH_C_LINKENABLE; 1998 dd->ipath_control &= ~INFINIPATH_C_LINKENABLE;
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6110.c b/drivers/infiniband/hw/ipath/ipath_iba6110.c
index d8ac9f18bf49..34d159ad97b4 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba6110.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6110.c
@@ -509,6 +509,13 @@ static void ipath_ht_handle_hwerrors(struct ipath_devdata *dd, char *msg,
509 if (!hwerrs) { 509 if (!hwerrs) {
510 ipath_dbg("Clearing freezemode on ignored or " 510 ipath_dbg("Clearing freezemode on ignored or "
511 "recovered hardware error\n"); 511 "recovered hardware error\n");
512 /*
513 * clear all sends, becauase they have may been
514 * completed by usercode while in freeze mode, and
515 * therefore would not be sent, and eventually
516 * might cause the process to run out of bufs
517 */
518 ipath_cancel_sends(dd);
512 ctrl &= ~INFINIPATH_C_FREEZEMODE; 519 ctrl &= ~INFINIPATH_C_FREEZEMODE;
513 ipath_write_kreg(dd, dd->ipath_kregs->kr_control, 520 ipath_write_kreg(dd, dd->ipath_kregs->kr_control,
514 ctrl); 521 ctrl);
@@ -1566,11 +1573,6 @@ static int ipath_ht_early_init(struct ipath_devdata *dd)
1566 writel(16, piobuf); 1573 writel(16, piobuf);
1567 piobuf += pioincr; 1574 piobuf += pioincr;
1568 } 1575 }
1569 /*
1570 * self-clearing
1571 */
1572 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
1573 INFINIPATH_S_ABORT);
1574 1576
1575 ipath_get_eeprom_info(dd); 1577 ipath_get_eeprom_info(dd);
1576 if (dd->ipath_boardrev == 5 && dd->ipath_serial[0] == '1' && 1578 if (dd->ipath_boardrev == 5 && dd->ipath_serial[0] == '1' &&
@@ -1599,7 +1601,6 @@ static int ipath_ht_txe_recover(struct ipath_devdata *dd)
1599 } 1601 }
1600 dev_info(&dd->pcidev->dev, 1602 dev_info(&dd->pcidev->dev,
1601 "Recovering from TXE PIO parity error\n"); 1603 "Recovering from TXE PIO parity error\n");
1602 ipath_disarm_senderrbufs(dd, 1);
1603 return 1; 1604 return 1;
1604} 1605}
1605 1606
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c
index b931057bb3e8..0c34555d4979 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba6120.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c
@@ -430,8 +430,19 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
430 *dd->ipath_statusp |= IPATH_STATUS_HWERROR; 430 *dd->ipath_statusp |= IPATH_STATUS_HWERROR;
431 dd->ipath_flags &= ~IPATH_INITTED; 431 dd->ipath_flags &= ~IPATH_INITTED;
432 } else { 432 } else {
433 ipath_dbg("Clearing freezemode on ignored hardware " 433 static u32 freeze_cnt;
434 "error\n"); 434
435 freeze_cnt++;
436 ipath_dbg("Clearing freezemode on ignored or recovered "
437 "hardware error (%u)\n", freeze_cnt);
438 /*
439 * clear all sends, becauase they have may been
440 * completed by usercode while in freeze mode, and
441 * therefore would not be sent, and eventually
442 * might cause the process to run out of bufs
443 */
444 ipath_cancel_sends(dd);
445 ctrl &= ~INFINIPATH_C_FREEZEMODE;
435 ipath_write_kreg(dd, dd->ipath_kregs->kr_control, 446 ipath_write_kreg(dd, dd->ipath_kregs->kr_control,
436 dd->ipath_control); 447 dd->ipath_control);
437 } 448 }
@@ -1371,7 +1382,6 @@ static int ipath_pe_txe_recover(struct ipath_devdata *dd)
1371 dev_info(&dd->pcidev->dev, 1382 dev_info(&dd->pcidev->dev,
1372 "Recovering from TXE PIO parity error\n"); 1383 "Recovering from TXE PIO parity error\n");
1373 } 1384 }
1374 ipath_disarm_senderrbufs(dd, 1);
1375 return 1; 1385 return 1;
1376} 1386}
1377 1387
diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c
index 9f611553ffb3..5193d6945caa 100644
--- a/drivers/infiniband/hw/ipath/ipath_init_chip.c
+++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c
@@ -777,6 +777,12 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
777 piobufs, dd->ipath_pbufsport, uports); 777 piobufs, dd->ipath_pbufsport, uports);
778 778
779 dd->ipath_f_early_init(dd); 779 dd->ipath_f_early_init(dd);
780 /*
781 * cancel any possible active sends from early driver load.
782 * Follows early_init because some chips have to initialize
783 * PIO buffers in early_init to avoid false parity errors.
784 */
785 ipath_cancel_sends(dd);
780 786
781 /* early_init sets rcvhdrentsize and rcvhdrsize, so this must be 787 /* early_init sets rcvhdrentsize and rcvhdrsize, so this must be
782 * done after early_init */ 788 * done after early_init */
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index d9cdd00c8233..948091f7d5ac 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -93,7 +93,8 @@ void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite)
93 93
94 if (sbuf[0] || sbuf[1] || (piobcnt > 128 && (sbuf[2] || sbuf[3]))) { 94 if (sbuf[0] || sbuf[1] || (piobcnt > 128 && (sbuf[2] || sbuf[3]))) {
95 int i; 95 int i;
96 if (ipath_debug & (__IPATH_PKTDBG|__IPATH_DBG)) { 96 if (ipath_debug & (__IPATH_PKTDBG|__IPATH_DBG) &&
97 dd->ipath_lastcancel > jiffies) {
97 __IPATH_DBG_WHICH(__IPATH_PKTDBG|__IPATH_DBG, 98 __IPATH_DBG_WHICH(__IPATH_PKTDBG|__IPATH_DBG,
98 "SendbufErrs %lx %lx", sbuf[0], 99 "SendbufErrs %lx %lx", sbuf[0],
99 sbuf[1]); 100 sbuf[1]);
@@ -108,7 +109,8 @@ void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite)
108 ipath_clrpiobuf(dd, i); 109 ipath_clrpiobuf(dd, i);
109 ipath_disarm_piobufs(dd, i, 1); 110 ipath_disarm_piobufs(dd, i, 1);
110 } 111 }
111 dd->ipath_lastcancel = jiffies+3; /* no armlaunch for a bit */ 112 /* ignore armlaunch errs for a bit */
113 dd->ipath_lastcancel = jiffies+3;
112 } 114 }
113} 115}
114 116
@@ -290,12 +292,7 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd,
290 * Flush all queued sends when link went to DOWN or INIT, 292 * Flush all queued sends when link went to DOWN or INIT,
291 * to be sure that they don't block SMA and other MAD packets 293 * to be sure that they don't block SMA and other MAD packets
292 */ 294 */
293 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 295 ipath_cancel_sends(dd);
294 INFINIPATH_S_ABORT);
295 ipath_disarm_piobufs(dd, dd->ipath_lastport_piobuf,
296 (unsigned)(dd->ipath_piobcnt2k +
297 dd->ipath_piobcnt4k) -
298 dd->ipath_lastport_piobuf);
299 } 296 }
300 else if (lstate == IPATH_IBSTATE_INIT || lstate == IPATH_IBSTATE_ARM || 297 else if (lstate == IPATH_IBSTATE_INIT || lstate == IPATH_IBSTATE_ARM ||
301 lstate == IPATH_IBSTATE_ACTIVE) { 298 lstate == IPATH_IBSTATE_ACTIVE) {
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index 2a4414b948ee..2e85aeca5eac 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -676,6 +676,7 @@ int ipath_unordered_wc(void);
676 676
677void ipath_disarm_piobufs(struct ipath_devdata *, unsigned first, 677void ipath_disarm_piobufs(struct ipath_devdata *, unsigned first,
678 unsigned cnt); 678 unsigned cnt);
679void ipath_cancel_sends(struct ipath_devdata *);
679 680
680int ipath_create_rcvhdrq(struct ipath_devdata *, struct ipath_portdata *); 681int ipath_create_rcvhdrq(struct ipath_devdata *, struct ipath_portdata *);
681void ipath_free_pddata(struct ipath_devdata *, struct ipath_portdata *); 682void ipath_free_pddata(struct ipath_devdata *, struct ipath_portdata *);