aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c33
-rw-r--r--drivers/infiniband/hw/ipath/ipath_intr.c40
2 files changed, 42 insertions, 31 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index eb745234d8c3..e2b0bc8ebaf4 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -870,7 +870,7 @@ void ipath_kreceive(struct ipath_devdata *dd)
870 const u32 maxcnt = dd->ipath_rcvhdrcnt * rsize; /* words */ 870 const u32 maxcnt = dd->ipath_rcvhdrcnt * rsize; /* words */
871 u32 etail = -1, l, hdrqtail; 871 u32 etail = -1, l, hdrqtail;
872 struct ips_message_header *hdr; 872 struct ips_message_header *hdr;
873 u32 eflags, i, etype, tlen, pkttot = 0; 873 u32 eflags, i, etype, tlen, pkttot = 0, updegr=0;
874 static u64 totcalls; /* stats, may eventually remove */ 874 static u64 totcalls; /* stats, may eventually remove */
875 char emsg[128]; 875 char emsg[128];
876 876
@@ -884,14 +884,14 @@ void ipath_kreceive(struct ipath_devdata *dd)
884 if (test_and_set_bit(0, &dd->ipath_rcv_pending)) 884 if (test_and_set_bit(0, &dd->ipath_rcv_pending))
885 goto bail; 885 goto bail;
886 886
887 if (dd->ipath_port0head == 887 l = dd->ipath_port0head;
888 (u32)le64_to_cpu(*dd->ipath_hdrqtailptr)) 888 if (l == (u32)le64_to_cpu(*dd->ipath_hdrqtailptr))
889 goto done; 889 goto done;
890 890
891 /* read only once at start for performance */ 891 /* read only once at start for performance */
892 hdrqtail = (u32)le64_to_cpu(*dd->ipath_hdrqtailptr); 892 hdrqtail = (u32)le64_to_cpu(*dd->ipath_hdrqtailptr);
893 893
894 for (i = 0, l = dd->ipath_port0head; l != hdrqtail; i++) { 894 for (i = 0; l != hdrqtail; i++) {
895 u32 qp; 895 u32 qp;
896 u8 *bthbytes; 896 u8 *bthbytes;
897 897
@@ -1002,15 +1002,26 @@ void ipath_kreceive(struct ipath_devdata *dd)
1002 l += rsize; 1002 l += rsize;
1003 if (l >= maxcnt) 1003 if (l >= maxcnt)
1004 l = 0; 1004 l = 0;
1005 if (etype != RCVHQ_RCV_TYPE_EXPECTED)
1006 updegr = 1;
1005 /* 1007 /*
1006 * update for each packet, to help prevent overflows if we 1008 * update head regs on last packet, and every 16 packets.
1007 * have lots of packets. 1009 * Reduce bus traffic, while still trying to prevent
1010 * rcvhdrq overflows, for when the queue is nearly full
1008 */ 1011 */
1009 (void)ipath_write_ureg(dd, ur_rcvhdrhead, 1012 if (l == hdrqtail || (i && !(i&0xf))) {
1010 dd->ipath_rhdrhead_intr_off | l, 0); 1013 u64 lval;
1011 if (etype != RCVHQ_RCV_TYPE_EXPECTED) 1014 if (l == hdrqtail) /* want interrupt only on last */
1012 (void)ipath_write_ureg(dd, ur_rcvegrindexhead, 1015 lval = dd->ipath_rhdrhead_intr_off | l;
1013 etail, 0); 1016 else
1017 lval = l;
1018 (void)ipath_write_ureg(dd, ur_rcvhdrhead, lval, 0);
1019 if (updegr) {
1020 (void)ipath_write_ureg(dd, ur_rcvegrindexhead,
1021 etail, 0);
1022 updegr = 0;
1023 }
1024 }
1014 } 1025 }
1015 1026
1016 pkttot += i; 1027 pkttot += i;
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index e8c8a25cd922..bad20a395265 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -383,7 +383,7 @@ static unsigned handle_frequent_errors(struct ipath_devdata *dd,
383 return supp_msgs; 383 return supp_msgs;
384} 384}
385 385
386static void handle_errors(struct ipath_devdata *dd, ipath_err_t errs) 386static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
387{ 387{
388 char msg[512]; 388 char msg[512];
389 u64 ignore_this_time = 0; 389 u64 ignore_this_time = 0;
@@ -480,7 +480,7 @@ static void handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
480 INFINIPATH_E_IBSTATUSCHANGED); 480 INFINIPATH_E_IBSTATUSCHANGED);
481 } 481 }
482 if (!errs) 482 if (!errs)
483 return; 483 return 0;
484 484
485 if (!noprint) 485 if (!noprint)
486 /* 486 /*
@@ -604,9 +604,7 @@ static void handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
604 wake_up_interruptible(&ipath_sma_state_wait); 604 wake_up_interruptible(&ipath_sma_state_wait);
605 } 605 }
606 606
607 if (chkerrpkts) 607 return chkerrpkts;
608 /* process possible error packets in hdrq */
609 ipath_kreceive(dd);
610} 608}
611 609
612/* this is separate to allow for better optimization of ipath_intr() */ 610/* this is separate to allow for better optimization of ipath_intr() */
@@ -765,10 +763,10 @@ static void handle_urcv(struct ipath_devdata *dd, u32 istat)
765irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs) 763irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
766{ 764{
767 struct ipath_devdata *dd = data; 765 struct ipath_devdata *dd = data;
768 u32 istat; 766 u32 istat, chk0rcv = 0;
769 ipath_err_t estat = 0; 767 ipath_err_t estat = 0;
770 irqreturn_t ret; 768 irqreturn_t ret;
771 u32 p0bits; 769 u32 p0bits, oldhead;
772 static unsigned unexpected = 0; 770 static unsigned unexpected = 0;
773 static const u32 port0rbits = (1U<<INFINIPATH_I_RCVAVAIL_SHIFT) | 771 static const u32 port0rbits = (1U<<INFINIPATH_I_RCVAVAIL_SHIFT) |
774 (1U<<INFINIPATH_I_RCVURG_SHIFT); 772 (1U<<INFINIPATH_I_RCVURG_SHIFT);
@@ -810,9 +808,8 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
810 * interrupts. We clear the interrupts first so that we don't 808 * interrupts. We clear the interrupts first so that we don't
811 * lose intr for later packets that arrive while we are processing. 809 * lose intr for later packets that arrive while we are processing.
812 */ 810 */
813 if (dd->ipath_port0head != 811 oldhead = dd->ipath_port0head;
814 (u32)le64_to_cpu(*dd->ipath_hdrqtailptr)) { 812 if (oldhead != (u32) le64_to_cpu(*dd->ipath_hdrqtailptr)) {
815 u32 oldhead = dd->ipath_port0head;
816 if (dd->ipath_flags & IPATH_GPIO_INTR) { 813 if (dd->ipath_flags & IPATH_GPIO_INTR) {
817 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear, 814 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear,
818 (u64) (1 << 2)); 815 (u64) (1 << 2));
@@ -830,6 +827,8 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
830 } 827 }
831 828
832 istat = ipath_read_kreg32(dd, dd->ipath_kregs->kr_intstatus); 829 istat = ipath_read_kreg32(dd, dd->ipath_kregs->kr_intstatus);
830 p0bits = port0rbits;
831
833 if (unlikely(!istat)) { 832 if (unlikely(!istat)) {
834 ipath_stats.sps_nullintr++; 833 ipath_stats.sps_nullintr++;
835 ret = IRQ_NONE; /* not our interrupt, or already handled */ 834 ret = IRQ_NONE; /* not our interrupt, or already handled */
@@ -867,10 +866,11 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
867 ipath_dev_err(dd, "Read of error status failed " 866 ipath_dev_err(dd, "Read of error status failed "
868 "(all bits set); ignoring\n"); 867 "(all bits set); ignoring\n");
869 else 868 else
870 handle_errors(dd, estat); 869 if (handle_errors(dd, estat))
870 /* force calling ipath_kreceive() */
871 chk0rcv = 1;
871 } 872 }
872 873
873 p0bits = port0rbits;
874 if (istat & INFINIPATH_I_GPIO) { 874 if (istat & INFINIPATH_I_GPIO) {
875 /* 875 /*
876 * Packets are available in the port 0 rcv queue. 876 * Packets are available in the port 0 rcv queue.
@@ -892,8 +892,10 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
892 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear, 892 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear,
893 (u64) (1 << 2)); 893 (u64) (1 << 2));
894 p0bits |= INFINIPATH_I_GPIO; 894 p0bits |= INFINIPATH_I_GPIO;
895 chk0rcv = 1;
895 } 896 }
896 } 897 }
898 chk0rcv |= istat & p0bits;
897 899
898 /* 900 /*
899 * clear the ones we will deal with on this round 901 * clear the ones we will deal with on this round
@@ -905,18 +907,16 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
905 ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, istat); 907 ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, istat);
906 908
907 /* 909 /*
908 * we check for both transition from empty to non-empty, and urgent 910 * handle port0 receive before checking for pio buffers available,
909 * packets (those with the interrupt bit set in the header), and 911 * since receives can overflow; piobuf waiters can afford a few
910 * if enabled, the GPIO bit 2 interrupt used for port0 on some 912 * extra cycles, since they were waiting anyway, and user's waiting
911 * HT-400 boards. 913 * for receive are at the bottom.
912 * Do this before checking for pio buffers available, since
913 * receives can overflow; piobuf waiters can afford a few
914 * extra cycles, since they were waiting anyway.
915 */ 914 */
916 if (istat & p0bits) { 915 if (chk0rcv) {
917 ipath_kreceive(dd); 916 ipath_kreceive(dd);
918 istat &= ~port0rbits; 917 istat &= ~port0rbits;
919 } 918 }
919
920 if (istat & ((infinipath_i_rcvavail_mask << 920 if (istat & ((infinipath_i_rcvavail_mask <<
921 INFINIPATH_I_RCVAVAIL_SHIFT) 921 INFINIPATH_I_RCVAVAIL_SHIFT)
922 | (infinipath_i_rcvurg_mask << 922 | (infinipath_i_rcvurg_mask <<