aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ipath
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-30 19:36:33 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-30 19:36:33 -0400
commit4dcf39c6cc5f9f01c46aa71fe95cae9927edeeab (patch)
tree84de77738748fdfa54778833b440f7bf009639eb /drivers/infiniband/hw/ipath
parentaf9473118979f3b09ee5d92fdbd8014cf085f7c5 (diff)
parent78d1e02fac0595a8aa8a5064d1bd0c0ea55b22b0 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband: IB/ipath: Workaround problem of errormask register being overwritten IB/ipath: Fix some issues with buffer cancel and sendctrl register update IB/ipath: Use faster put_tid_2 routine after initialization IB/ipath: Remove unsafe fastrcvint code from interrupt handler IB/ehca: Move extern declarations from .c files to .h files IB/mlx4: Whitespace fix IB/ehca: Fix include order to better match kernel style mlx4_core: Remove kfree() in mlx4_mr_alloc() error flow RDMA/amso1100: Initialize the wait_queue_head_t in the c2_qp structure
Diffstat (limited to 'drivers/infiniband/hw/ipath')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_common.h3
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c11
-rw-r--r--drivers/infiniband/hw/ipath/ipath_iba6120.c20
-rw-r--r--drivers/infiniband/hw/ipath/ipath_init_chip.c7
-rw-r--r--drivers/infiniband/hw/ipath/ipath_intr.c63
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h13
-rw-r--r--drivers/infiniband/hw/ipath/ipath_stats.c54
7 files changed, 92 insertions, 79 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_common.h b/drivers/infiniband/hw/ipath/ipath_common.h
index b4b786d0dfca..6ad822c35930 100644
--- a/drivers/infiniband/hw/ipath/ipath_common.h
+++ b/drivers/infiniband/hw/ipath/ipath_common.h
@@ -100,8 +100,7 @@ struct infinipath_stats {
100 __u64 sps_hwerrs; 100 __u64 sps_hwerrs;
101 /* number of times IB link changed state unexpectedly */ 101 /* number of times IB link changed state unexpectedly */
102 __u64 sps_iblink; 102 __u64 sps_iblink;
103 /* kernel receive interrupts that didn't read intstat */ 103 __u64 sps_unused; /* was fastrcvint, no longer implemented */
104 __u64 sps_fastrcvint;
105 /* number of kernel (port0) packets received */ 104 /* number of kernel (port0) packets received */
106 __u64 sps_port0pkts; 105 __u64 sps_port0pkts;
107 /* number of "ethernet" packets sent by driver */ 106 /* number of "ethernet" packets sent by driver */
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index 09c5fd84b1e3..6ccba365a24c 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -740,7 +740,7 @@ void ipath_disarm_piobufs(struct ipath_devdata *dd, unsigned first,
740 * pioavail updates to memory to stop. 740 * pioavail updates to memory to stop.
741 */ 741 */
742 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 742 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
743 sendorig & ~IPATH_S_PIOBUFAVAILUPD); 743 sendorig & ~INFINIPATH_S_PIOBUFAVAILUPD);
744 sendorig = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); 744 sendorig = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
745 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 745 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
746 dd->ipath_sendctrl); 746 dd->ipath_sendctrl);
@@ -1614,7 +1614,7 @@ int ipath_waitfor_mdio_cmdready(struct ipath_devdata *dd)
1614 * it's safer to always do it. 1614 * it's safer to always do it.
1615 * PIOAvail bits are updated by the chip as if normal send had happened. 1615 * PIOAvail bits are updated by the chip as if normal send had happened.
1616 */ 1616 */
1617void ipath_cancel_sends(struct ipath_devdata *dd) 1617void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl)
1618{ 1618{
1619 ipath_dbg("Cancelling all in-progress send buffers\n"); 1619 ipath_dbg("Cancelling all in-progress send buffers\n");
1620 dd->ipath_lastcancel = jiffies+HZ/2; /* skip armlaunch errs a bit */ 1620 dd->ipath_lastcancel = jiffies+HZ/2; /* skip armlaunch errs a bit */
@@ -1627,6 +1627,9 @@ void ipath_cancel_sends(struct ipath_devdata *dd)
1627 ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); 1627 ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
1628 ipath_disarm_piobufs(dd, 0, 1628 ipath_disarm_piobufs(dd, 0,
1629 (unsigned)(dd->ipath_piobcnt2k + dd->ipath_piobcnt4k)); 1629 (unsigned)(dd->ipath_piobcnt2k + dd->ipath_piobcnt4k));
1630 if (restore_sendctrl) /* else done by caller later */
1631 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
1632 dd->ipath_sendctrl);
1630 1633
1631 /* and again, be sure all have hit the chip */ 1634 /* and again, be sure all have hit the chip */
1632 ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); 1635 ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
@@ -1655,7 +1658,7 @@ static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which)
1655 /* flush all queued sends when going to DOWN or INIT, to be sure that 1658 /* flush all queued sends when going to DOWN or INIT, to be sure that
1656 * they don't block MAD packets */ 1659 * they don't block MAD packets */
1657 if (!linkcmd || linkcmd == INFINIPATH_IBCC_LINKCMD_INIT) 1660 if (!linkcmd || linkcmd == INFINIPATH_IBCC_LINKCMD_INIT)
1658 ipath_cancel_sends(dd); 1661 ipath_cancel_sends(dd, 1);
1659 1662
1660 ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl, 1663 ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl,
1661 dd->ipath_ibcctrl | which); 1664 dd->ipath_ibcctrl | which);
@@ -2000,7 +2003,7 @@ void ipath_shutdown_device(struct ipath_devdata *dd)
2000 2003
2001 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_DISABLE << 2004 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_DISABLE <<
2002 INFINIPATH_IBCC_LINKINITCMD_SHIFT); 2005 INFINIPATH_IBCC_LINKINITCMD_SHIFT);
2003 ipath_cancel_sends(dd); 2006 ipath_cancel_sends(dd, 0);
2004 2007
2005 /* disable IBC */ 2008 /* disable IBC */
2006 dd->ipath_control &= ~INFINIPATH_C_LINKENABLE; 2009 dd->ipath_control &= ~INFINIPATH_C_LINKENABLE;
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c
index 9868ccda5f26..5b6ac9a1a709 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba6120.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c
@@ -321,6 +321,8 @@ static const struct ipath_hwerror_msgs ipath_6120_hwerror_msgs[] = {
321 << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) 321 << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT)
322 322
323static int ipath_pe_txe_recover(struct ipath_devdata *); 323static int ipath_pe_txe_recover(struct ipath_devdata *);
324static void ipath_pe_put_tid_2(struct ipath_devdata *, u64 __iomem *,
325 u32, unsigned long);
324 326
325/** 327/**
326 * ipath_pe_handle_hwerrors - display hardware errors. 328 * ipath_pe_handle_hwerrors - display hardware errors.
@@ -555,8 +557,11 @@ static int ipath_pe_boardname(struct ipath_devdata *dd, char *name,
555 ipath_dev_err(dd, "Unsupported InfiniPath hardware revision %u.%u!\n", 557 ipath_dev_err(dd, "Unsupported InfiniPath hardware revision %u.%u!\n",
556 dd->ipath_majrev, dd->ipath_minrev); 558 dd->ipath_majrev, dd->ipath_minrev);
557 ret = 1; 559 ret = 1;
558 } else 560 } else {
559 ret = 0; 561 ret = 0;
562 if (dd->ipath_minrev >= 2)
563 dd->ipath_f_put_tid = ipath_pe_put_tid_2;
564 }
560 565
561 return ret; 566 return ret;
562} 567}
@@ -1220,7 +1225,7 @@ static void ipath_pe_clear_tids(struct ipath_devdata *dd, unsigned port)
1220 port * dd->ipath_rcvtidcnt * sizeof(*tidbase)); 1225 port * dd->ipath_rcvtidcnt * sizeof(*tidbase));
1221 1226
1222 for (i = 0; i < dd->ipath_rcvtidcnt; i++) 1227 for (i = 0; i < dd->ipath_rcvtidcnt; i++)
1223 ipath_pe_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EXPECTED, 1228 dd->ipath_f_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EXPECTED,
1224 tidinv); 1229 tidinv);
1225 1230
1226 tidbase = (u64 __iomem *) 1231 tidbase = (u64 __iomem *)
@@ -1229,7 +1234,7 @@ static void ipath_pe_clear_tids(struct ipath_devdata *dd, unsigned port)
1229 port * dd->ipath_rcvegrcnt * sizeof(*tidbase)); 1234 port * dd->ipath_rcvegrcnt * sizeof(*tidbase));
1230 1235
1231 for (i = 0; i < dd->ipath_rcvegrcnt; i++) 1236 for (i = 0; i < dd->ipath_rcvegrcnt; i++)
1232 ipath_pe_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EAGER, 1237 dd->ipath_f_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EAGER,
1233 tidinv); 1238 tidinv);
1234} 1239}
1235 1240
@@ -1395,10 +1400,11 @@ void ipath_init_iba6120_funcs(struct ipath_devdata *dd)
1395 dd->ipath_f_quiet_serdes = ipath_pe_quiet_serdes; 1400 dd->ipath_f_quiet_serdes = ipath_pe_quiet_serdes;
1396 dd->ipath_f_bringup_serdes = ipath_pe_bringup_serdes; 1401 dd->ipath_f_bringup_serdes = ipath_pe_bringup_serdes;
1397 dd->ipath_f_clear_tids = ipath_pe_clear_tids; 1402 dd->ipath_f_clear_tids = ipath_pe_clear_tids;
1398 if (dd->ipath_minrev >= 2) 1403 /*
1399 dd->ipath_f_put_tid = ipath_pe_put_tid_2; 1404 * this may get changed after we read the chip revision,
1400 else 1405 * but we start with the safe version for all revs
1401 dd->ipath_f_put_tid = ipath_pe_put_tid; 1406 */
1407 dd->ipath_f_put_tid = ipath_pe_put_tid;
1402 dd->ipath_f_cleanup = ipath_setup_pe_cleanup; 1408 dd->ipath_f_cleanup = ipath_setup_pe_cleanup;
1403 dd->ipath_f_setextled = ipath_setup_pe_setextled; 1409 dd->ipath_f_setextled = ipath_setup_pe_setextled;
1404 dd->ipath_f_get_base_info = ipath_pe_get_base_info; 1410 dd->ipath_f_get_base_info = ipath_pe_get_base_info;
diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c
index 49951d583804..9dd0bacf8461 100644
--- a/drivers/infiniband/hw/ipath/ipath_init_chip.c
+++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c
@@ -782,7 +782,7 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
782 * Follows early_init because some chips have to initialize 782 * Follows early_init because some chips have to initialize
783 * PIO buffers in early_init to avoid false parity errors. 783 * PIO buffers in early_init to avoid false parity errors.
784 */ 784 */
785 ipath_cancel_sends(dd); 785 ipath_cancel_sends(dd, 0);
786 786
787 /* early_init sets rcvhdrentsize and rcvhdrsize, so this must be 787 /* early_init sets rcvhdrentsize and rcvhdrsize, so this must be
788 * done after early_init */ 788 * done after early_init */
@@ -851,13 +851,14 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
851 ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, 851 ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask,
852 dd->ipath_hwerrmask); 852 dd->ipath_hwerrmask);
853 853
854 dd->ipath_maskederrs = dd->ipath_ignorederrs;
855 /* clear all */ 854 /* clear all */
856 ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, -1LL); 855 ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, -1LL);
857 /* enable errors that are masked, at least this first time. */ 856 /* enable errors that are masked, at least this first time. */
858 ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, 857 ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask,
859 ~dd->ipath_maskederrs); 858 ~dd->ipath_maskederrs);
860 /* clear any interrups up to this point (ints still not enabled) */ 859 dd->ipath_errormask = ipath_read_kreg64(dd,
860 dd->ipath_kregs->kr_errormask);
861 /* clear any interrupts up to this point (ints still not enabled) */
861 ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, -1LL); 862 ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, -1LL);
862 863
863 /* 864 /*
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index 1fd91c59f246..b29fe7e9b11a 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -303,7 +303,7 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd,
303 * Flush all queued sends when link went to DOWN or INIT, 303 * Flush all queued sends when link went to DOWN or INIT,
304 * to be sure that they don't block SMA and other MAD packets 304 * to be sure that they don't block SMA and other MAD packets
305 */ 305 */
306 ipath_cancel_sends(dd); 306 ipath_cancel_sends(dd, 1);
307 } 307 }
308 else if (lstate == IPATH_IBSTATE_INIT || lstate == IPATH_IBSTATE_ARM || 308 else if (lstate == IPATH_IBSTATE_INIT || lstate == IPATH_IBSTATE_ARM ||
309 lstate == IPATH_IBSTATE_ACTIVE) { 309 lstate == IPATH_IBSTATE_ACTIVE) {
@@ -517,10 +517,7 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
517 517
518 supp_msgs = handle_frequent_errors(dd, errs, msg, &noprint); 518 supp_msgs = handle_frequent_errors(dd, errs, msg, &noprint);
519 519
520 /* 520 /* don't report errors that are masked */
521 * don't report errors that are masked (includes those always
522 * ignored)
523 */
524 errs &= ~dd->ipath_maskederrs; 521 errs &= ~dd->ipath_maskederrs;
525 522
526 /* do these first, they are most important */ 523 /* do these first, they are most important */
@@ -566,19 +563,19 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
566 * ones on this particular interrupt, which also isn't great 563 * ones on this particular interrupt, which also isn't great
567 */ 564 */
568 dd->ipath_maskederrs |= dd->ipath_lasterror | errs; 565 dd->ipath_maskederrs |= dd->ipath_lasterror | errs;
566 dd->ipath_errormask &= ~dd->ipath_maskederrs;
569 ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, 567 ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask,
570 ~dd->ipath_maskederrs); 568 dd->ipath_errormask);
571 s_iserr = ipath_decode_err(msg, sizeof msg, 569 s_iserr = ipath_decode_err(msg, sizeof msg,
572 (dd->ipath_maskederrs & ~dd-> 570 dd->ipath_maskederrs);
573 ipath_ignorederrs));
574 571
575 if ((dd->ipath_maskederrs & ~dd->ipath_ignorederrs) & 572 if (dd->ipath_maskederrs &
576 ~(INFINIPATH_E_RRCVEGRFULL | 573 ~(INFINIPATH_E_RRCVEGRFULL |
577 INFINIPATH_E_RRCVHDRFULL | INFINIPATH_E_PKTERRS)) 574 INFINIPATH_E_RRCVHDRFULL | INFINIPATH_E_PKTERRS))
578 ipath_dev_err(dd, "Temporarily disabling " 575 ipath_dev_err(dd, "Temporarily disabling "
579 "error(s) %llx reporting; too frequent (%s)\n", 576 "error(s) %llx reporting; too frequent (%s)\n",
580 (unsigned long long) (dd->ipath_maskederrs & 577 (unsigned long long)dd->ipath_maskederrs,
581 ~dd->ipath_ignorederrs), msg); 578 msg);
582 else { 579 else {
583 /* 580 /*
584 * rcvegrfull and rcvhdrqfull are "normal", 581 * rcvegrfull and rcvhdrqfull are "normal",
@@ -793,19 +790,22 @@ void ipath_clear_freeze(struct ipath_devdata *dd)
793 /* disable error interrupts, to avoid confusion */ 790 /* disable error interrupts, to avoid confusion */
794 ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, 0ULL); 791 ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, 0ULL);
795 792
793 /* also disable interrupts; errormask is sometimes overwriten */
794 ipath_write_kreg(dd, dd->ipath_kregs->kr_intmask, 0ULL);
795
796 /* 796 /*
797 * clear all sends, because they have may been 797 * clear all sends, because they have may been
798 * completed by usercode while in freeze mode, and 798 * completed by usercode while in freeze mode, and
799 * therefore would not be sent, and eventually 799 * therefore would not be sent, and eventually
800 * might cause the process to run out of bufs 800 * might cause the process to run out of bufs
801 */ 801 */
802 ipath_cancel_sends(dd); 802 ipath_cancel_sends(dd, 0);
803 ipath_write_kreg(dd, dd->ipath_kregs->kr_control, 803 ipath_write_kreg(dd, dd->ipath_kregs->kr_control,
804 dd->ipath_control); 804 dd->ipath_control);
805 805
806 /* ensure pio avail updates continue */ 806 /* ensure pio avail updates continue */
807 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 807 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
808 dd->ipath_sendctrl & ~IPATH_S_PIOBUFAVAILUPD); 808 dd->ipath_sendctrl & ~INFINIPATH_S_PIOBUFAVAILUPD);
809 ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); 809 ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
810 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 810 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
811 dd->ipath_sendctrl); 811 dd->ipath_sendctrl);
@@ -817,7 +817,7 @@ void ipath_clear_freeze(struct ipath_devdata *dd)
817 for (i = 0; i < dd->ipath_pioavregs; i++) { 817 for (i = 0; i < dd->ipath_pioavregs; i++) {
818 /* deal with 6110 chip bug */ 818 /* deal with 6110 chip bug */
819 im = i > 3 ? ((i&1) ? i-1 : i+1) : i; 819 im = i > 3 ? ((i&1) ? i-1 : i+1) : i;
820 val = ipath_read_kreg64(dd, 0x1000+(im*sizeof(u64))); 820 val = ipath_read_kreg64(dd, (0x1000/sizeof(u64))+im);
821 dd->ipath_pioavailregs_dma[i] = dd->ipath_pioavailshadow[i] 821 dd->ipath_pioavailregs_dma[i] = dd->ipath_pioavailshadow[i]
822 = le64_to_cpu(val); 822 = le64_to_cpu(val);
823 } 823 }
@@ -832,7 +832,8 @@ void ipath_clear_freeze(struct ipath_devdata *dd)
832 ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, 832 ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear,
833 E_SPKT_ERRS_IGNORE); 833 E_SPKT_ERRS_IGNORE);
834 ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, 834 ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask,
835 ~dd->ipath_maskederrs); 835 dd->ipath_errormask);
836 ipath_write_kreg(dd, dd->ipath_kregs->kr_intmask, -1LL);
836 ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, 0ULL); 837 ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, 0ULL);
837} 838}
838 839
@@ -1002,7 +1003,6 @@ irqreturn_t ipath_intr(int irq, void *data)
1002 u32 istat, chk0rcv = 0; 1003 u32 istat, chk0rcv = 0;
1003 ipath_err_t estat = 0; 1004 ipath_err_t estat = 0;
1004 irqreturn_t ret; 1005 irqreturn_t ret;
1005 u32 oldhead, curtail;
1006 static unsigned unexpected = 0; 1006 static unsigned unexpected = 0;
1007 static const u32 port0rbits = (1U<<INFINIPATH_I_RCVAVAIL_SHIFT) | 1007 static const u32 port0rbits = (1U<<INFINIPATH_I_RCVAVAIL_SHIFT) |
1008 (1U<<INFINIPATH_I_RCVURG_SHIFT); 1008 (1U<<INFINIPATH_I_RCVURG_SHIFT);
@@ -1035,36 +1035,6 @@ irqreturn_t ipath_intr(int irq, void *data)
1035 goto bail; 1035 goto bail;
1036 } 1036 }
1037 1037
1038 /*
1039 * We try to avoid reading the interrupt status register, since
1040 * that's a PIO read, and stalls the processor for up to about
1041 * ~0.25 usec. The idea is that if we processed a port0 packet,
1042 * we blindly clear the port 0 receive interrupt bits, and nothing
1043 * else, then return. If other interrupts are pending, the chip
1044 * will re-interrupt us as soon as we write the intclear register.
1045 * We then won't process any more kernel packets (if not the 2nd
1046 * time, then the 3rd or 4th) and we'll then handle the other
1047 * interrupts. We clear the interrupts first so that we don't
1048 * lose intr for later packets that arrive while we are processing.
1049 */
1050 oldhead = dd->ipath_port0head;
1051 curtail = (u32)le64_to_cpu(*dd->ipath_hdrqtailptr);
1052 if (oldhead != curtail) {
1053 if (dd->ipath_flags & IPATH_GPIO_INTR) {
1054 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear,
1055 (u64) (1 << IPATH_GPIO_PORT0_BIT));
1056 istat = port0rbits | INFINIPATH_I_GPIO;
1057 }
1058 else
1059 istat = port0rbits;
1060 ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, istat);
1061 ipath_kreceive(dd);
1062 if (oldhead != dd->ipath_port0head) {
1063 ipath_stats.sps_fastrcvint++;
1064 goto done;
1065 }
1066 }
1067
1068 istat = ipath_read_kreg32(dd, dd->ipath_kregs->kr_intstatus); 1038 istat = ipath_read_kreg32(dd, dd->ipath_kregs->kr_intstatus);
1069 1039
1070 if (unlikely(!istat)) { 1040 if (unlikely(!istat)) {
@@ -1225,7 +1195,6 @@ irqreturn_t ipath_intr(int irq, void *data)
1225 handle_layer_pioavail(dd); 1195 handle_layer_pioavail(dd);
1226 } 1196 }
1227 1197
1228done:
1229 ret = IRQ_HANDLED; 1198 ret = IRQ_HANDLED;
1230 1199
1231bail: 1200bail:
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index ace63ef78e6f..7a7966f7e4ff 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -261,18 +261,10 @@ struct ipath_devdata {
261 * limiting of hwerror reporting 261 * limiting of hwerror reporting
262 */ 262 */
263 ipath_err_t ipath_lasthwerror; 263 ipath_err_t ipath_lasthwerror;
264 /* 264 /* errors masked because they occur too fast */
265 * errors masked because they occur too fast, also includes errors
266 * that are always ignored (ipath_ignorederrs)
267 */
268 ipath_err_t ipath_maskederrs; 265 ipath_err_t ipath_maskederrs;
269 /* time in jiffies at which to re-enable maskederrs */ 266 /* time in jiffies at which to re-enable maskederrs */
270 unsigned long ipath_unmasktime; 267 unsigned long ipath_unmasktime;
271 /*
272 * errors always ignored (masked), at least for a given
273 * chip/device, because they are wrong or not useful
274 */
275 ipath_err_t ipath_ignorederrs;
276 /* count of egrfull errors, combined for all ports */ 268 /* count of egrfull errors, combined for all ports */
277 u64 ipath_last_tidfull; 269 u64 ipath_last_tidfull;
278 /* for ipath_qcheck() */ 270 /* for ipath_qcheck() */
@@ -436,6 +428,7 @@ struct ipath_devdata {
436 u64 ipath_lastibcstat; 428 u64 ipath_lastibcstat;
437 /* hwerrmask shadow */ 429 /* hwerrmask shadow */
438 ipath_err_t ipath_hwerrmask; 430 ipath_err_t ipath_hwerrmask;
431 ipath_err_t ipath_errormask; /* errormask shadow */
439 /* interrupt config reg shadow */ 432 /* interrupt config reg shadow */
440 u64 ipath_intconfig; 433 u64 ipath_intconfig;
441 /* kr_sendpiobufbase value */ 434 /* kr_sendpiobufbase value */
@@ -683,7 +676,7 @@ int ipath_unordered_wc(void);
683 676
684void ipath_disarm_piobufs(struct ipath_devdata *, unsigned first, 677void ipath_disarm_piobufs(struct ipath_devdata *, unsigned first,
685 unsigned cnt); 678 unsigned cnt);
686void ipath_cancel_sends(struct ipath_devdata *); 679void ipath_cancel_sends(struct ipath_devdata *, int);
687 680
688int ipath_create_rcvhdrq(struct ipath_devdata *, struct ipath_portdata *); 681int ipath_create_rcvhdrq(struct ipath_devdata *, struct ipath_portdata *);
689void ipath_free_pddata(struct ipath_devdata *, struct ipath_portdata *); 682void ipath_free_pddata(struct ipath_devdata *, struct ipath_portdata *);
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
199static 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);
297done: 339done:
298 mod_timer(&dd->ipath_stats_timer, jiffies + HZ * 5); 340 mod_timer(&dd->ipath_stats_timer, jiffies + HZ * 5);
299} 341}