diff options
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_driver.c')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_driver.c | 33 |
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; |