aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_diag.c22
-rw-r--r--drivers/infiniband/hw/ipath/ipath_iba6120.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.c62
4 files changed, 53 insertions, 35 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_diag.c b/drivers/infiniband/hw/ipath/ipath_diag.c
index cf25cdab02f9..4137c7770f1b 100644
--- a/drivers/infiniband/hw/ipath/ipath_diag.c
+++ b/drivers/infiniband/hw/ipath/ipath_diag.c
@@ -446,19 +446,21 @@ static ssize_t ipath_diagpkt_write(struct file *fp,
446 dd->ipath_unit, plen - 1, pbufn); 446 dd->ipath_unit, plen - 1, pbufn);
447 447
448 if (dp.pbc_wd == 0) 448 if (dp.pbc_wd == 0)
449 /* Legacy operation, use computed pbc_wd */
450 dp.pbc_wd = plen; 449 dp.pbc_wd = plen;
451
452 /* we have to flush after the PBC for correctness on some cpus
453 * or WC buffer can be written out of order */
454 writeq(dp.pbc_wd, piobuf); 450 writeq(dp.pbc_wd, piobuf);
455 ipath_flush_wc(); 451 /*
456 /* copy all by the trigger word, then flush, so it's written 452 * Copy all by the trigger word, then flush, so it's written
457 * to chip before trigger word, then write trigger word, then 453 * to chip before trigger word, then write trigger word, then
458 * flush again, so packet is sent. */ 454 * flush again, so packet is sent.
459 __iowrite32_copy(piobuf + 2, tmpbuf, clen - 1); 455 */
460 ipath_flush_wc(); 456 if (dd->ipath_flags & IPATH_PIO_FLUSH_WC) {
461 __raw_writel(tmpbuf[clen - 1], piobuf + clen + 1); 457 ipath_flush_wc();
458 __iowrite32_copy(piobuf + 2, tmpbuf, clen - 1);
459 ipath_flush_wc();
460 __raw_writel(tmpbuf[clen - 1], piobuf + clen + 1);
461 } else
462 __iowrite32_copy(piobuf + 2, tmpbuf, clen);
463
462 ipath_flush_wc(); 464 ipath_flush_wc();
463 465
464 ret = sizeof(dp); 466 ret = sizeof(dp);
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c
index 5b6ac9a1a709..a324c6f7aeba 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba6120.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c
@@ -1273,6 +1273,8 @@ static void ipath_pe_tidtemplate(struct ipath_devdata *dd)
1273static int ipath_pe_early_init(struct ipath_devdata *dd) 1273static int ipath_pe_early_init(struct ipath_devdata *dd)
1274{ 1274{
1275 dd->ipath_flags |= IPATH_4BYTE_TID; 1275 dd->ipath_flags |= IPATH_4BYTE_TID;
1276 if (ipath_unordered_wc())
1277 dd->ipath_flags |= IPATH_PIO_FLUSH_WC;
1276 1278
1277 /* 1279 /*
1278 * For openfabrics, we need to be able to handle an IB header of 1280 * For openfabrics, we need to be able to handle an IB header of
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index 7a7966f7e4ff..d983f92b9bcb 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -724,6 +724,8 @@ int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv);
724#define IPATH_LINKACTIVE 0x200 724#define IPATH_LINKACTIVE 0x200
725 /* link current state is unknown */ 725 /* link current state is unknown */
726#define IPATH_LINKUNK 0x400 726#define IPATH_LINKUNK 0x400
727 /* Write combining flush needed for PIO */
728#define IPATH_PIO_FLUSH_WC 0x1000
727 /* no IB cable, or no device on IB cable */ 729 /* no IB cable, or no device on IB cable */
728#define IPATH_NOCABLE 0x4000 730#define IPATH_NOCABLE 0x4000
729 /* Supports port zero per packet receive interrupts via 731 /* Supports port zero per packet receive interrupts via
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index 16aa61fd8085..559d4a662937 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -631,7 +631,7 @@ static inline u32 clear_upper_bytes(u32 data, u32 n, u32 off)
631#endif 631#endif
632 632
633static void copy_io(u32 __iomem *piobuf, struct ipath_sge_state *ss, 633static void copy_io(u32 __iomem *piobuf, struct ipath_sge_state *ss,
634 u32 length) 634 u32 length, unsigned flush_wc)
635{ 635{
636 u32 extra = 0; 636 u32 extra = 0;
637 u32 data = 0; 637 u32 data = 0;
@@ -757,11 +757,14 @@ static void copy_io(u32 __iomem *piobuf, struct ipath_sge_state *ss,
757 } 757 }
758 /* Update address before sending packet. */ 758 /* Update address before sending packet. */
759 update_sge(ss, length); 759 update_sge(ss, length);
760 /* must flush early everything before trigger word */ 760 if (flush_wc) {
761 ipath_flush_wc(); 761 /* must flush early everything before trigger word */
762 __raw_writel(last, piobuf); 762 ipath_flush_wc();
763 /* be sure trigger word is written */ 763 __raw_writel(last, piobuf);
764 ipath_flush_wc(); 764 /* be sure trigger word is written */
765 ipath_flush_wc();
766 } else
767 __raw_writel(last, piobuf);
765} 768}
766 769
767/** 770/**
@@ -776,6 +779,7 @@ int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords,
776 u32 *hdr, u32 len, struct ipath_sge_state *ss) 779 u32 *hdr, u32 len, struct ipath_sge_state *ss)
777{ 780{
778 u32 __iomem *piobuf; 781 u32 __iomem *piobuf;
782 unsigned flush_wc;
779 u32 plen; 783 u32 plen;
780 int ret; 784 int ret;
781 785
@@ -799,47 +803,55 @@ int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords,
799 * or WC buffer can be written out of order. 803 * or WC buffer can be written out of order.
800 */ 804 */
801 writeq(plen, piobuf); 805 writeq(plen, piobuf);
802 ipath_flush_wc();
803 piobuf += 2; 806 piobuf += 2;
807
808 flush_wc = dd->ipath_flags & IPATH_PIO_FLUSH_WC;
804 if (len == 0) { 809 if (len == 0) {
805 /* 810 /*
806 * If there is just the header portion, must flush before 811 * If there is just the header portion, must flush before
807 * writing last word of header for correctness, and after 812 * writing last word of header for correctness, and after
808 * the last header word (trigger word). 813 * the last header word (trigger word).
809 */ 814 */
810 __iowrite32_copy(piobuf, hdr, hdrwords - 1); 815 if (flush_wc) {
811 ipath_flush_wc(); 816 ipath_flush_wc();
812 __raw_writel(hdr[hdrwords - 1], piobuf + hdrwords - 1); 817 __iowrite32_copy(piobuf, hdr, hdrwords - 1);
813 ipath_flush_wc(); 818 ipath_flush_wc();
814 ret = 0; 819 __raw_writel(hdr[hdrwords - 1], piobuf + hdrwords - 1);
815 goto bail; 820 ipath_flush_wc();
821 } else
822 __iowrite32_copy(piobuf, hdr, hdrwords);
823 goto done;
816 } 824 }
817 825
826 if (flush_wc)
827 ipath_flush_wc();
818 __iowrite32_copy(piobuf, hdr, hdrwords); 828 __iowrite32_copy(piobuf, hdr, hdrwords);
819 piobuf += hdrwords; 829 piobuf += hdrwords;
820 830
821 /* The common case is aligned and contained in one segment. */ 831 /* The common case is aligned and contained in one segment. */
822 if (likely(ss->num_sge == 1 && len <= ss->sge.length && 832 if (likely(ss->num_sge == 1 && len <= ss->sge.length &&
823 !((unsigned long)ss->sge.vaddr & (sizeof(u32) - 1)))) { 833 !((unsigned long)ss->sge.vaddr & (sizeof(u32) - 1)))) {
824 u32 w; 834 u32 dwords;
825 u32 *addr = (u32 *) ss->sge.vaddr; 835 u32 *addr = (u32 *) ss->sge.vaddr;
826 836
827 /* Update address before sending packet. */ 837 /* Update address before sending packet. */
828 update_sge(ss, len); 838 update_sge(ss, len);
829 /* Need to round up for the last dword in the packet. */ 839 /* Need to round up for the last dword in the packet. */
830 w = (len + 3) >> 2; 840 dwords = (len + 3) >> 2;
831 __iowrite32_copy(piobuf, addr, w - 1); 841 if (flush_wc) {
832 /* must flush early everything before trigger word */ 842 __iowrite32_copy(piobuf, addr, dwords - 1);
833 ipath_flush_wc(); 843 /* must flush early everything before trigger word */
834 __raw_writel(addr[w - 1], piobuf + w - 1); 844 ipath_flush_wc();
835 /* be sure trigger word is written */ 845 __raw_writel(addr[dwords - 1], piobuf + dwords - 1);
836 ipath_flush_wc(); 846 /* be sure trigger word is written */
837 ret = 0; 847 ipath_flush_wc();
838 goto bail; 848 } else
849 __iowrite32_copy(piobuf, addr, dwords);
850 goto done;
839 } 851 }
840 copy_io(piobuf, ss, len); 852 copy_io(piobuf, ss, len, flush_wc);
853done:
841 ret = 0; 854 ret = 0;
842
843bail: 855bail:
844 return ret; 856 return ret;
845} 857}