aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ipath/ipath_driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_driver.c')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c33
1 files changed, 22 insertions, 11 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;