diff options
author | Ralph Campbell <ralph.campbell@qlogic.com> | 2008-04-17 00:09:29 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2008-04-17 00:09:29 -0400 |
commit | 9355fb6a064723c71e80e9c78de3140b43bfb52d (patch) | |
tree | dd0fffeb6633aed6cb2c946a05bf33e05f2e9436 /drivers | |
parent | 2ba3f56eb402672ff83601b5990b219d39577636 (diff) |
IB/ipath: Add support for 7220 receive queue changes
Newer HCAs have a HW option to write a sequence number to each receive
queue entry and avoid a separate DMA of the tail register to memory.
This patch adds support for these changes.
Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_common.h | 31 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_driver.c | 194 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_file_ops.c | 34 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_iba6110.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_iba6120.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_init_chip.c | 152 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_intr.c | 46 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_kernel.h | 53 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_registers.h | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_stats.c | 14 |
10 files changed, 305 insertions, 225 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_common.h b/drivers/infiniband/hw/ipath/ipath_common.h index 591901aab6b7..edd4183c3a28 100644 --- a/drivers/infiniband/hw/ipath/ipath_common.h +++ b/drivers/infiniband/hw/ipath/ipath_common.h | |||
@@ -198,7 +198,7 @@ typedef enum _ipath_ureg { | |||
198 | #define IPATH_RUNTIME_FORCE_WC_ORDER 0x4 | 198 | #define IPATH_RUNTIME_FORCE_WC_ORDER 0x4 |
199 | #define IPATH_RUNTIME_RCVHDR_COPY 0x8 | 199 | #define IPATH_RUNTIME_RCVHDR_COPY 0x8 |
200 | #define IPATH_RUNTIME_MASTER 0x10 | 200 | #define IPATH_RUNTIME_MASTER 0x10 |
201 | /* 0x20 and 0x40 are no longer used, but are reserved for ABI compatibility */ | 201 | #define IPATH_RUNTIME_NODMA_RTAIL 0x80 |
202 | #define IPATH_RUNTIME_FORCE_PIOAVAIL 0x400 | 202 | #define IPATH_RUNTIME_FORCE_PIOAVAIL 0x400 |
203 | #define IPATH_RUNTIME_PIO_REGSWAPPED 0x800 | 203 | #define IPATH_RUNTIME_PIO_REGSWAPPED 0x800 |
204 | 204 | ||
@@ -662,8 +662,12 @@ struct infinipath_counters { | |||
662 | #define INFINIPATH_RHF_LENGTH_SHIFT 0 | 662 | #define INFINIPATH_RHF_LENGTH_SHIFT 0 |
663 | #define INFINIPATH_RHF_RCVTYPE_MASK 0x7 | 663 | #define INFINIPATH_RHF_RCVTYPE_MASK 0x7 |
664 | #define INFINIPATH_RHF_RCVTYPE_SHIFT 11 | 664 | #define INFINIPATH_RHF_RCVTYPE_SHIFT 11 |
665 | #define INFINIPATH_RHF_EGRINDEX_MASK 0x7FF | 665 | #define INFINIPATH_RHF_EGRINDEX_MASK 0xFFF |
666 | #define INFINIPATH_RHF_EGRINDEX_SHIFT 16 | 666 | #define INFINIPATH_RHF_EGRINDEX_SHIFT 16 |
667 | #define INFINIPATH_RHF_SEQ_MASK 0xF | ||
668 | #define INFINIPATH_RHF_SEQ_SHIFT 0 | ||
669 | #define INFINIPATH_RHF_HDRQ_OFFSET_MASK 0x7FF | ||
670 | #define INFINIPATH_RHF_HDRQ_OFFSET_SHIFT 4 | ||
667 | #define INFINIPATH_RHF_H_ICRCERR 0x80000000 | 671 | #define INFINIPATH_RHF_H_ICRCERR 0x80000000 |
668 | #define INFINIPATH_RHF_H_VCRCERR 0x40000000 | 672 | #define INFINIPATH_RHF_H_VCRCERR 0x40000000 |
669 | #define INFINIPATH_RHF_H_PARITYERR 0x20000000 | 673 | #define INFINIPATH_RHF_H_PARITYERR 0x20000000 |
@@ -673,6 +677,8 @@ struct infinipath_counters { | |||
673 | #define INFINIPATH_RHF_H_TIDERR 0x02000000 | 677 | #define INFINIPATH_RHF_H_TIDERR 0x02000000 |
674 | #define INFINIPATH_RHF_H_MKERR 0x01000000 | 678 | #define INFINIPATH_RHF_H_MKERR 0x01000000 |
675 | #define INFINIPATH_RHF_H_IBERR 0x00800000 | 679 | #define INFINIPATH_RHF_H_IBERR 0x00800000 |
680 | #define INFINIPATH_RHF_H_ERR_MASK 0xFF800000 | ||
681 | #define INFINIPATH_RHF_L_USE_EGR 0x80000000 | ||
676 | #define INFINIPATH_RHF_L_SWA 0x00008000 | 682 | #define INFINIPATH_RHF_L_SWA 0x00008000 |
677 | #define INFINIPATH_RHF_L_SWB 0x00004000 | 683 | #define INFINIPATH_RHF_L_SWB 0x00004000 |
678 | 684 | ||
@@ -696,6 +702,7 @@ struct infinipath_counters { | |||
696 | /* SendPIO per-buffer control */ | 702 | /* SendPIO per-buffer control */ |
697 | #define INFINIPATH_SP_TEST 0x40 | 703 | #define INFINIPATH_SP_TEST 0x40 |
698 | #define INFINIPATH_SP_TESTEBP 0x20 | 704 | #define INFINIPATH_SP_TESTEBP 0x20 |
705 | #define INFINIPATH_SP_TRIGGER_SHIFT 15 | ||
699 | 706 | ||
700 | /* SendPIOAvail bits */ | 707 | /* SendPIOAvail bits */ |
701 | #define INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT 1 | 708 | #define INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT 1 |
@@ -762,6 +769,7 @@ struct ether_header { | |||
762 | #define IPATH_MSN_MASK 0xFFFFFF | 769 | #define IPATH_MSN_MASK 0xFFFFFF |
763 | #define IPATH_QPN_MASK 0xFFFFFF | 770 | #define IPATH_QPN_MASK 0xFFFFFF |
764 | #define IPATH_MULTICAST_LID_BASE 0xC000 | 771 | #define IPATH_MULTICAST_LID_BASE 0xC000 |
772 | #define IPATH_EAGER_TID_ID INFINIPATH_I_TID_MASK | ||
765 | #define IPATH_MULTICAST_QPN 0xFFFFFF | 773 | #define IPATH_MULTICAST_QPN 0xFFFFFF |
766 | 774 | ||
767 | /* Receive Header Queue: receive type (from infinipath) */ | 775 | /* Receive Header Queue: receive type (from infinipath) */ |
@@ -781,7 +789,7 @@ struct ether_header { | |||
781 | */ | 789 | */ |
782 | static inline __u32 ipath_hdrget_err_flags(const __le32 * rbuf) | 790 | static inline __u32 ipath_hdrget_err_flags(const __le32 * rbuf) |
783 | { | 791 | { |
784 | return __le32_to_cpu(rbuf[1]); | 792 | return __le32_to_cpu(rbuf[1]) & INFINIPATH_RHF_H_ERR_MASK; |
785 | } | 793 | } |
786 | 794 | ||
787 | static inline __u32 ipath_hdrget_rcv_type(const __le32 * rbuf) | 795 | static inline __u32 ipath_hdrget_rcv_type(const __le32 * rbuf) |
@@ -802,6 +810,23 @@ static inline __u32 ipath_hdrget_index(const __le32 * rbuf) | |||
802 | & INFINIPATH_RHF_EGRINDEX_MASK; | 810 | & INFINIPATH_RHF_EGRINDEX_MASK; |
803 | } | 811 | } |
804 | 812 | ||
813 | static inline __u32 ipath_hdrget_seq(const __le32 *rbuf) | ||
814 | { | ||
815 | return (__le32_to_cpu(rbuf[1]) >> INFINIPATH_RHF_SEQ_SHIFT) | ||
816 | & INFINIPATH_RHF_SEQ_MASK; | ||
817 | } | ||
818 | |||
819 | static inline __u32 ipath_hdrget_offset(const __le32 *rbuf) | ||
820 | { | ||
821 | return (__le32_to_cpu(rbuf[1]) >> INFINIPATH_RHF_HDRQ_OFFSET_SHIFT) | ||
822 | & INFINIPATH_RHF_HDRQ_OFFSET_MASK; | ||
823 | } | ||
824 | |||
825 | static inline __u32 ipath_hdrget_use_egr_buf(const __le32 *rbuf) | ||
826 | { | ||
827 | return __le32_to_cpu(rbuf[0]) & INFINIPATH_RHF_L_USE_EGR; | ||
828 | } | ||
829 | |||
805 | static inline __u32 ipath_hdrget_ipath_ver(__le32 hdrword) | 830 | static inline __u32 ipath_hdrget_ipath_ver(__le32 hdrword) |
806 | { | 831 | { |
807 | return (__le32_to_cpu(hdrword) >> INFINIPATH_I_VERS_SHIFT) | 832 | return (__le32_to_cpu(hdrword) >> INFINIPATH_I_VERS_SHIFT) |
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index 58fcb355f59f..d1bbee50b5ba 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c | |||
@@ -41,7 +41,6 @@ | |||
41 | 41 | ||
42 | #include "ipath_kernel.h" | 42 | #include "ipath_kernel.h" |
43 | #include "ipath_verbs.h" | 43 | #include "ipath_verbs.h" |
44 | #include "ipath_common.h" | ||
45 | 44 | ||
46 | static void ipath_update_pio_bufs(struct ipath_devdata *); | 45 | static void ipath_update_pio_bufs(struct ipath_devdata *); |
47 | 46 | ||
@@ -720,6 +719,8 @@ static void __devexit cleanup_device(struct ipath_devdata *dd) | |||
720 | tmpp = dd->ipath_pageshadow; | 719 | tmpp = dd->ipath_pageshadow; |
721 | dd->ipath_pageshadow = NULL; | 720 | dd->ipath_pageshadow = NULL; |
722 | vfree(tmpp); | 721 | vfree(tmpp); |
722 | |||
723 | dd->ipath_egrtidbase = NULL; | ||
723 | } | 724 | } |
724 | 725 | ||
725 | /* | 726 | /* |
@@ -1078,18 +1079,17 @@ static void ipath_rcv_hdrerr(struct ipath_devdata *dd, | |||
1078 | u32 eflags, | 1079 | u32 eflags, |
1079 | u32 l, | 1080 | u32 l, |
1080 | u32 etail, | 1081 | u32 etail, |
1081 | u64 *rc) | 1082 | __le32 *rhf_addr, |
1083 | struct ipath_message_header *hdr) | ||
1082 | { | 1084 | { |
1083 | char emsg[128]; | 1085 | char emsg[128]; |
1084 | struct ipath_message_header *hdr; | ||
1085 | 1086 | ||
1086 | get_rhf_errstring(eflags, emsg, sizeof emsg); | 1087 | get_rhf_errstring(eflags, emsg, sizeof emsg); |
1087 | hdr = (struct ipath_message_header *)&rc[1]; | ||
1088 | ipath_cdbg(PKT, "RHFerrs %x hdrqtail=%x typ=%u " | 1088 | ipath_cdbg(PKT, "RHFerrs %x hdrqtail=%x typ=%u " |
1089 | "tlen=%x opcode=%x egridx=%x: %s\n", | 1089 | "tlen=%x opcode=%x egridx=%x: %s\n", |
1090 | eflags, l, | 1090 | eflags, l, |
1091 | ipath_hdrget_rcv_type((__le32 *) rc), | 1091 | ipath_hdrget_rcv_type(rhf_addr), |
1092 | ipath_hdrget_length_in_bytes((__le32 *) rc), | 1092 | ipath_hdrget_length_in_bytes(rhf_addr), |
1093 | be32_to_cpu(hdr->bth[0]) >> 24, | 1093 | be32_to_cpu(hdr->bth[0]) >> 24, |
1094 | etail, emsg); | 1094 | etail, emsg); |
1095 | 1095 | ||
@@ -1114,55 +1114,52 @@ static void ipath_rcv_hdrerr(struct ipath_devdata *dd, | |||
1114 | */ | 1114 | */ |
1115 | void ipath_kreceive(struct ipath_portdata *pd) | 1115 | void ipath_kreceive(struct ipath_portdata *pd) |
1116 | { | 1116 | { |
1117 | u64 *rc; | ||
1118 | struct ipath_devdata *dd = pd->port_dd; | 1117 | struct ipath_devdata *dd = pd->port_dd; |
1118 | __le32 *rhf_addr; | ||
1119 | void *ebuf; | 1119 | void *ebuf; |
1120 | const u32 rsize = dd->ipath_rcvhdrentsize; /* words */ | 1120 | const u32 rsize = dd->ipath_rcvhdrentsize; /* words */ |
1121 | const u32 maxcnt = dd->ipath_rcvhdrcnt * rsize; /* words */ | 1121 | const u32 maxcnt = dd->ipath_rcvhdrcnt * rsize; /* words */ |
1122 | u32 etail = -1, l, hdrqtail; | 1122 | u32 etail = -1, l, hdrqtail; |
1123 | struct ipath_message_header *hdr; | 1123 | struct ipath_message_header *hdr; |
1124 | u32 eflags, i, etype, tlen, pkttot = 0, updegr=0, reloop=0; | 1124 | u32 eflags, i, etype, tlen, pkttot = 0, updegr = 0, reloop = 0; |
1125 | static u64 totcalls; /* stats, may eventually remove */ | 1125 | static u64 totcalls; /* stats, may eventually remove */ |
1126 | 1126 | int last; | |
1127 | if (!dd->ipath_hdrqtailptr) { | ||
1128 | ipath_dev_err(dd, | ||
1129 | "hdrqtailptr not set, can't do receives\n"); | ||
1130 | goto bail; | ||
1131 | } | ||
1132 | 1127 | ||
1133 | l = pd->port_head; | 1128 | l = pd->port_head; |
1134 | hdrqtail = ipath_get_rcvhdrtail(pd); | 1129 | rhf_addr = (__le32 *) pd->port_rcvhdrq + l + dd->ipath_rhf_offset; |
1135 | if (l == hdrqtail) | 1130 | if (dd->ipath_flags & IPATH_NODMA_RTAIL) { |
1136 | goto bail; | 1131 | u32 seq = ipath_hdrget_seq(rhf_addr); |
1137 | 1132 | ||
1138 | reloop: | 1133 | if (seq != pd->port_seq_cnt) |
1139 | for (i = 0; l != hdrqtail; i++) { | 1134 | goto bail; |
1140 | u32 qp; | 1135 | hdrqtail = 0; |
1141 | u8 *bthbytes; | 1136 | } else { |
1142 | 1137 | hdrqtail = ipath_get_rcvhdrtail(pd); | |
1143 | rc = (u64 *) (pd->port_rcvhdrq + (l << 2)); | 1138 | if (l == hdrqtail) |
1144 | hdr = (struct ipath_message_header *)&rc[1]; | 1139 | goto bail; |
1145 | /* | 1140 | smp_rmb(); |
1146 | * could make a network order version of IPATH_KD_QP, and | 1141 | } |
1147 | * do the obvious shift before masking to speed this up. | ||
1148 | */ | ||
1149 | qp = ntohl(hdr->bth[1]) & 0xffffff; | ||
1150 | bthbytes = (u8 *) hdr->bth; | ||
1151 | 1142 | ||
1152 | eflags = ipath_hdrget_err_flags((__le32 *) rc); | 1143 | reloop: |
1153 | etype = ipath_hdrget_rcv_type((__le32 *) rc); | 1144 | for (last = 0, i = 1; !last; i++) { |
1145 | hdr = dd->ipath_f_get_msgheader(dd, rhf_addr); | ||
1146 | eflags = ipath_hdrget_err_flags(rhf_addr); | ||
1147 | etype = ipath_hdrget_rcv_type(rhf_addr); | ||
1154 | /* total length */ | 1148 | /* total length */ |
1155 | tlen = ipath_hdrget_length_in_bytes((__le32 *) rc); | 1149 | tlen = ipath_hdrget_length_in_bytes(rhf_addr); |
1156 | ebuf = NULL; | 1150 | ebuf = NULL; |
1157 | if (etype != RCVHQ_RCV_TYPE_EXPECTED) { | 1151 | if ((dd->ipath_flags & IPATH_NODMA_RTAIL) ? |
1152 | ipath_hdrget_use_egr_buf(rhf_addr) : | ||
1153 | (etype != RCVHQ_RCV_TYPE_EXPECTED)) { | ||
1158 | /* | 1154 | /* |
1159 | * it turns out that the chips uses an eager buffer | 1155 | * It turns out that the chip uses an eager buffer |
1160 | * for all non-expected packets, whether it "needs" | 1156 | * for all non-expected packets, whether it "needs" |
1161 | * one or not. So always get the index, but don't | 1157 | * one or not. So always get the index, but don't |
1162 | * set ebuf (so we try to copy data) unless the | 1158 | * set ebuf (so we try to copy data) unless the |
1163 | * length requires it. | 1159 | * length requires it. |
1164 | */ | 1160 | */ |
1165 | etail = ipath_hdrget_index((__le32 *) rc); | 1161 | etail = ipath_hdrget_index(rhf_addr); |
1162 | updegr = 1; | ||
1166 | if (tlen > sizeof(*hdr) || | 1163 | if (tlen > sizeof(*hdr) || |
1167 | etype == RCVHQ_RCV_TYPE_NON_KD) | 1164 | etype == RCVHQ_RCV_TYPE_NON_KD) |
1168 | ebuf = ipath_get_egrbuf(dd, etail); | 1165 | ebuf = ipath_get_egrbuf(dd, etail); |
@@ -1173,75 +1170,91 @@ reloop: | |||
1173 | * packets; only ipathhdrerr should be set. | 1170 | * packets; only ipathhdrerr should be set. |
1174 | */ | 1171 | */ |
1175 | 1172 | ||
1176 | if (etype != RCVHQ_RCV_TYPE_NON_KD && etype != | 1173 | if (etype != RCVHQ_RCV_TYPE_NON_KD && |
1177 | RCVHQ_RCV_TYPE_ERROR && ipath_hdrget_ipath_ver( | 1174 | etype != RCVHQ_RCV_TYPE_ERROR && |
1178 | hdr->iph.ver_port_tid_offset) != | 1175 | ipath_hdrget_ipath_ver(hdr->iph.ver_port_tid_offset) != |
1179 | IPS_PROTO_VERSION) { | 1176 | IPS_PROTO_VERSION) |
1180 | ipath_cdbg(PKT, "Bad InfiniPath protocol version " | 1177 | ipath_cdbg(PKT, "Bad InfiniPath protocol version " |
1181 | "%x\n", etype); | 1178 | "%x\n", etype); |
1182 | } | ||
1183 | 1179 | ||
1184 | if (unlikely(eflags)) | 1180 | if (unlikely(eflags)) |
1185 | ipath_rcv_hdrerr(dd, eflags, l, etail, rc); | 1181 | ipath_rcv_hdrerr(dd, eflags, l, etail, rhf_addr, hdr); |
1186 | else if (etype == RCVHQ_RCV_TYPE_NON_KD) { | 1182 | else if (etype == RCVHQ_RCV_TYPE_NON_KD) { |
1187 | ipath_ib_rcv(dd->verbs_dev, rc + 1, ebuf, tlen); | 1183 | ipath_ib_rcv(dd->verbs_dev, (u32 *)hdr, ebuf, tlen); |
1188 | if (dd->ipath_lli_counter) | 1184 | if (dd->ipath_lli_counter) |
1189 | dd->ipath_lli_counter--; | 1185 | dd->ipath_lli_counter--; |
1186 | } else if (etype == RCVHQ_RCV_TYPE_EAGER) { | ||
1187 | u8 opcode = be32_to_cpu(hdr->bth[0]) >> 24; | ||
1188 | u32 qp = be32_to_cpu(hdr->bth[1]) & 0xffffff; | ||
1190 | ipath_cdbg(PKT, "typ %x, opcode %x (eager, " | 1189 | ipath_cdbg(PKT, "typ %x, opcode %x (eager, " |
1191 | "qp=%x), len %x; ignored\n", | 1190 | "qp=%x), len %x; ignored\n", |
1192 | etype, bthbytes[0], qp, tlen); | 1191 | etype, opcode, qp, tlen); |
1193 | } | 1192 | } |
1194 | else if (etype == RCVHQ_RCV_TYPE_EAGER) | ||
1195 | ipath_cdbg(PKT, "typ %x, opcode %x (eager, " | ||
1196 | "qp=%x), len %x; ignored\n", | ||
1197 | etype, bthbytes[0], qp, tlen); | ||
1198 | else if (etype == RCVHQ_RCV_TYPE_EXPECTED) | 1193 | else if (etype == RCVHQ_RCV_TYPE_EXPECTED) |
1199 | ipath_dbg("Bug: Expected TID, opcode %x; ignored\n", | 1194 | ipath_dbg("Bug: Expected TID, opcode %x; ignored\n", |
1200 | be32_to_cpu(hdr->bth[0]) & 0xff); | 1195 | be32_to_cpu(hdr->bth[0]) >> 24); |
1201 | else { | 1196 | else { |
1202 | /* | 1197 | /* |
1203 | * error packet, type of error unknown. | 1198 | * error packet, type of error unknown. |
1204 | * Probably type 3, but we don't know, so don't | 1199 | * Probably type 3, but we don't know, so don't |
1205 | * even try to print the opcode, etc. | 1200 | * even try to print the opcode, etc. |
1201 | * Usually caused by a "bad packet", that has no | ||
1202 | * BTH, when the LRH says it should. | ||
1206 | */ | 1203 | */ |
1207 | ipath_dbg("Error Pkt, but no eflags! egrbuf %x, " | 1204 | ipath_cdbg(ERRPKT, "Error Pkt, but no eflags! egrbuf" |
1208 | "len %x\nhdrq@%lx;hdrq+%x rhf: %llx; " | 1205 | " %x, len %x hdrq+%x rhf: %Lx\n", |
1209 | "hdr %llx %llx %llx %llx %llx\n", | 1206 | etail, tlen, l, |
1210 | etail, tlen, (unsigned long) rc, l, | 1207 | le64_to_cpu(*(__le64 *) rhf_addr)); |
1211 | (unsigned long long) rc[0], | 1208 | if (ipath_debug & __IPATH_ERRPKTDBG) { |
1212 | (unsigned long long) rc[1], | 1209 | u32 j, *d, dw = rsize-2; |
1213 | (unsigned long long) rc[2], | 1210 | if (rsize > (tlen>>2)) |
1214 | (unsigned long long) rc[3], | 1211 | dw = tlen>>2; |
1215 | (unsigned long long) rc[4], | 1212 | d = (u32 *)hdr; |
1216 | (unsigned long long) rc[5]); | 1213 | printk(KERN_DEBUG "EPkt rcvhdr(%x dw):\n", |
1214 | dw); | ||
1215 | for (j = 0; j < dw; j++) | ||
1216 | printk(KERN_DEBUG "%8x%s", d[j], | ||
1217 | (j%8) == 7 ? "\n" : " "); | ||
1218 | printk(KERN_DEBUG ".\n"); | ||
1219 | } | ||
1217 | } | 1220 | } |
1218 | l += rsize; | 1221 | l += rsize; |
1219 | if (l >= maxcnt) | 1222 | if (l >= maxcnt) |
1220 | l = 0; | 1223 | l = 0; |
1221 | if (etype != RCVHQ_RCV_TYPE_EXPECTED) | 1224 | rhf_addr = (__le32 *) pd->port_rcvhdrq + |
1222 | updegr = 1; | 1225 | l + dd->ipath_rhf_offset; |
1226 | if (dd->ipath_flags & IPATH_NODMA_RTAIL) { | ||
1227 | u32 seq = ipath_hdrget_seq(rhf_addr); | ||
1228 | |||
1229 | if (++pd->port_seq_cnt > 13) | ||
1230 | pd->port_seq_cnt = 1; | ||
1231 | if (seq != pd->port_seq_cnt) | ||
1232 | last = 1; | ||
1233 | } else if (l == hdrqtail) | ||
1234 | last = 1; | ||
1223 | /* | 1235 | /* |
1224 | * update head regs on last packet, and every 16 packets. | 1236 | * update head regs on last packet, and every 16 packets. |
1225 | * Reduce bus traffic, while still trying to prevent | 1237 | * Reduce bus traffic, while still trying to prevent |
1226 | * rcvhdrq overflows, for when the queue is nearly full | 1238 | * rcvhdrq overflows, for when the queue is nearly full |
1227 | */ | 1239 | */ |
1228 | if (l == hdrqtail || (i && !(i&0xf))) { | 1240 | if (last || !(i & 0xf)) { |
1229 | u64 lval; | 1241 | u64 lval = l; |
1230 | if (l == hdrqtail) | 1242 | |
1231 | /* request IBA6120 interrupt only on last */ | 1243 | /* request IBA6120 and 7220 interrupt only on last */ |
1232 | lval = dd->ipath_rhdrhead_intr_off | l; | 1244 | if (last) |
1233 | else | 1245 | lval |= dd->ipath_rhdrhead_intr_off; |
1234 | lval = l; | 1246 | ipath_write_ureg(dd, ur_rcvhdrhead, lval, |
1235 | ipath_write_ureg(dd, ur_rcvhdrhead, lval, 0); | 1247 | pd->port_port); |
1236 | if (updegr) { | 1248 | if (updegr) { |
1237 | ipath_write_ureg(dd, ur_rcvegrindexhead, | 1249 | ipath_write_ureg(dd, ur_rcvegrindexhead, |
1238 | etail, 0); | 1250 | etail, pd->port_port); |
1239 | updegr = 0; | 1251 | updegr = 0; |
1240 | } | 1252 | } |
1241 | } | 1253 | } |
1242 | } | 1254 | } |
1243 | 1255 | ||
1244 | if (!dd->ipath_rhdrhead_intr_off && !reloop) { | 1256 | if (!dd->ipath_rhdrhead_intr_off && !reloop && |
1257 | !(dd->ipath_flags & IPATH_NODMA_RTAIL)) { | ||
1245 | /* IBA6110 workaround; we can have a race clearing chip | 1258 | /* IBA6110 workaround; we can have a race clearing chip |
1246 | * interrupt with another interrupt about to be delivered, | 1259 | * interrupt with another interrupt about to be delivered, |
1247 | * and can clear it before it is delivered on the GPIO | 1260 | * and can clear it before it is delivered on the GPIO |
@@ -1638,19 +1651,27 @@ int ipath_create_rcvhdrq(struct ipath_devdata *dd, | |||
1638 | ret = -ENOMEM; | 1651 | ret = -ENOMEM; |
1639 | goto bail; | 1652 | goto bail; |
1640 | } | 1653 | } |
1641 | pd->port_rcvhdrtail_kvaddr = dma_alloc_coherent( | 1654 | |
1642 | &dd->pcidev->dev, PAGE_SIZE, &phys_hdrqtail, GFP_KERNEL); | 1655 | if (!(dd->ipath_flags & IPATH_NODMA_RTAIL)) { |
1643 | if (!pd->port_rcvhdrtail_kvaddr) { | 1656 | pd->port_rcvhdrtail_kvaddr = dma_alloc_coherent( |
1644 | ipath_dev_err(dd, "attempt to allocate 1 page " | 1657 | &dd->pcidev->dev, PAGE_SIZE, &phys_hdrqtail, |
1645 | "for port %u rcvhdrqtailaddr failed\n", | 1658 | GFP_KERNEL); |
1646 | pd->port_port); | 1659 | if (!pd->port_rcvhdrtail_kvaddr) { |
1647 | ret = -ENOMEM; | 1660 | ipath_dev_err(dd, "attempt to allocate 1 page " |
1648 | dma_free_coherent(&dd->pcidev->dev, amt, | 1661 | "for port %u rcvhdrqtailaddr " |
1649 | pd->port_rcvhdrq, pd->port_rcvhdrq_phys); | 1662 | "failed\n", pd->port_port); |
1650 | pd->port_rcvhdrq = NULL; | 1663 | ret = -ENOMEM; |
1651 | goto bail; | 1664 | dma_free_coherent(&dd->pcidev->dev, amt, |
1665 | pd->port_rcvhdrq, | ||
1666 | pd->port_rcvhdrq_phys); | ||
1667 | pd->port_rcvhdrq = NULL; | ||
1668 | goto bail; | ||
1669 | } | ||
1670 | pd->port_rcvhdrqtailaddr_phys = phys_hdrqtail; | ||
1671 | ipath_cdbg(VERBOSE, "port %d hdrtailaddr, %llx " | ||
1672 | "physical\n", pd->port_port, | ||
1673 | (unsigned long long) phys_hdrqtail); | ||
1652 | } | 1674 | } |
1653 | pd->port_rcvhdrqtailaddr_phys = phys_hdrqtail; | ||
1654 | 1675 | ||
1655 | pd->port_rcvhdrq_size = amt; | 1676 | pd->port_rcvhdrq_size = amt; |
1656 | 1677 | ||
@@ -1660,10 +1681,6 @@ int ipath_create_rcvhdrq(struct ipath_devdata *dd, | |||
1660 | (unsigned long) pd->port_rcvhdrq_phys, | 1681 | (unsigned long) pd->port_rcvhdrq_phys, |
1661 | (unsigned long) pd->port_rcvhdrq_size, | 1682 | (unsigned long) pd->port_rcvhdrq_size, |
1662 | pd->port_port); | 1683 | pd->port_port); |
1663 | |||
1664 | ipath_cdbg(VERBOSE, "port %d hdrtailaddr, %llx physical\n", | ||
1665 | pd->port_port, | ||
1666 | (unsigned long long) phys_hdrqtail); | ||
1667 | } | 1684 | } |
1668 | else | 1685 | else |
1669 | ipath_cdbg(VERBOSE, "reuse port %d rcvhdrq @%p %llx phys; " | 1686 | ipath_cdbg(VERBOSE, "reuse port %d rcvhdrq @%p %llx phys; " |
@@ -1687,7 +1704,6 @@ int ipath_create_rcvhdrq(struct ipath_devdata *dd, | |||
1687 | ipath_write_kreg_port(dd, dd->ipath_kregs->kr_rcvhdraddr, | 1704 | ipath_write_kreg_port(dd, dd->ipath_kregs->kr_rcvhdraddr, |
1688 | pd->port_port, pd->port_rcvhdrq_phys); | 1705 | pd->port_port, pd->port_rcvhdrq_phys); |
1689 | 1706 | ||
1690 | ret = 0; | ||
1691 | bail: | 1707 | bail: |
1692 | return ret; | 1708 | return ret; |
1693 | } | 1709 | } |
@@ -2222,7 +2238,7 @@ void ipath_free_pddata(struct ipath_devdata *dd, struct ipath_portdata *pd) | |||
2222 | ipath_cdbg(VERBOSE, "free closed port %d " | 2238 | ipath_cdbg(VERBOSE, "free closed port %d " |
2223 | "ipath_port0_skbinfo @ %p\n", pd->port_port, | 2239 | "ipath_port0_skbinfo @ %p\n", pd->port_port, |
2224 | skbinfo); | 2240 | skbinfo); |
2225 | for (e = 0; e < dd->ipath_rcvegrcnt; e++) | 2241 | for (e = 0; e < dd->ipath_p0_rcvegrcnt; e++) |
2226 | if (skbinfo[e].skb) { | 2242 | if (skbinfo[e].skb) { |
2227 | pci_unmap_single(dd->pcidev, skbinfo[e].phys, | 2243 | pci_unmap_single(dd->pcidev, skbinfo[e].phys, |
2228 | dd->ipath_ibmaxlen, | 2244 | dd->ipath_ibmaxlen, |
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c index 1b232b23dbfc..17d4e970abd9 100644 --- a/drivers/infiniband/hw/ipath/ipath_file_ops.c +++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c | |||
@@ -1930,22 +1930,25 @@ static int ipath_do_user_init(struct file *fp, | |||
1930 | pd->port_hdrqfull_poll = pd->port_hdrqfull; | 1930 | pd->port_hdrqfull_poll = pd->port_hdrqfull; |
1931 | 1931 | ||
1932 | /* | 1932 | /* |
1933 | * now enable the port; the tail registers will be written to memory | 1933 | * Now enable the port for receive. |
1934 | * by the chip as soon as it sees the write to | 1934 | * For chips that are set to DMA the tail register to memory |
1935 | * dd->ipath_kregs->kr_rcvctrl. The update only happens on | 1935 | * when they change (and when the update bit transitions from |
1936 | * transition from 0 to 1, so clear it first, then set it as part of | 1936 | * 0 to 1. So for those chips, we turn it off and then back on. |
1937 | * enabling the port. This will (very briefly) affect any other | 1937 | * This will (very briefly) affect any other open ports, but the |
1938 | * open ports, but it shouldn't be long enough to be an issue. | 1938 | * duration is very short, and therefore isn't an issue. We |
1939 | * We explictly set the in-memory copy to 0 beforehand, so we don't | 1939 | * explictly set the in-memory tail copy to 0 beforehand, so we |
1940 | * have to wait to be sure the DMA update has happened. | 1940 | * don't have to wait to be sure the DMA update has happened |
1941 | * (chip resets head/tail to 0 on transition to enable). | ||
1941 | */ | 1942 | */ |
1942 | if (pd->port_rcvhdrtail_kvaddr) | ||
1943 | ipath_clear_rcvhdrtail(pd); | ||
1944 | set_bit(dd->ipath_r_portenable_shift + pd->port_port, | 1943 | set_bit(dd->ipath_r_portenable_shift + pd->port_port, |
1945 | &dd->ipath_rcvctrl); | 1944 | &dd->ipath_rcvctrl); |
1946 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | 1945 | if (!(dd->ipath_flags & IPATH_NODMA_RTAIL)) { |
1946 | if (pd->port_rcvhdrtail_kvaddr) | ||
1947 | ipath_clear_rcvhdrtail(pd); | ||
1948 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | ||
1947 | dd->ipath_rcvctrl & | 1949 | dd->ipath_rcvctrl & |
1948 | ~(1ULL << dd->ipath_r_tailupd_shift)); | 1950 | ~(1ULL << dd->ipath_r_tailupd_shift)); |
1951 | } | ||
1949 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | 1952 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, |
1950 | dd->ipath_rcvctrl); | 1953 | dd->ipath_rcvctrl); |
1951 | /* Notify any waiting slaves */ | 1954 | /* Notify any waiting slaves */ |
@@ -1973,14 +1976,15 @@ static void unlock_expected_tids(struct ipath_portdata *pd) | |||
1973 | ipath_cdbg(VERBOSE, "Port %u unlocking any locked expTID pages\n", | 1976 | ipath_cdbg(VERBOSE, "Port %u unlocking any locked expTID pages\n", |
1974 | pd->port_port); | 1977 | pd->port_port); |
1975 | for (i = port_tidbase; i < maxtid; i++) { | 1978 | for (i = port_tidbase; i < maxtid; i++) { |
1976 | if (!dd->ipath_pageshadow[i]) | 1979 | struct page *ps = dd->ipath_pageshadow[i]; |
1980 | |||
1981 | if (!ps) | ||
1977 | continue; | 1982 | continue; |
1978 | 1983 | ||
1984 | dd->ipath_pageshadow[i] = NULL; | ||
1979 | pci_unmap_page(dd->pcidev, dd->ipath_physshadow[i], | 1985 | pci_unmap_page(dd->pcidev, dd->ipath_physshadow[i], |
1980 | PAGE_SIZE, PCI_DMA_FROMDEVICE); | 1986 | PAGE_SIZE, PCI_DMA_FROMDEVICE); |
1981 | ipath_release_user_pages_on_close(&dd->ipath_pageshadow[i], | 1987 | ipath_release_user_pages_on_close(&ps, 1); |
1982 | 1); | ||
1983 | dd->ipath_pageshadow[i] = NULL; | ||
1984 | cnt++; | 1988 | cnt++; |
1985 | ipath_stats.sps_pageunlocks++; | 1989 | ipath_stats.sps_pageunlocks++; |
1986 | } | 1990 | } |
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6110.c b/drivers/infiniband/hw/ipath/ipath_iba6110.c index d241f1c7c93e..02831ad070b8 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba6110.c +++ b/drivers/infiniband/hw/ipath/ipath_iba6110.c | |||
@@ -306,7 +306,9 @@ static const struct ipath_cregs ipath_ht_cregs = { | |||
306 | 306 | ||
307 | /* kr_intstatus, kr_intclear, kr_intmask bits */ | 307 | /* kr_intstatus, kr_intclear, kr_intmask bits */ |
308 | #define INFINIPATH_I_RCVURG_MASK ((1U<<9)-1) | 308 | #define INFINIPATH_I_RCVURG_MASK ((1U<<9)-1) |
309 | #define INFINIPATH_I_RCVURG_SHIFT 0 | ||
309 | #define INFINIPATH_I_RCVAVAIL_MASK ((1U<<9)-1) | 310 | #define INFINIPATH_I_RCVAVAIL_MASK ((1U<<9)-1) |
311 | #define INFINIPATH_I_RCVAVAIL_SHIFT 12 | ||
310 | 312 | ||
311 | /* kr_hwerrclear, kr_hwerrmask, kr_hwerrstatus, bits */ | 313 | /* kr_hwerrclear, kr_hwerrmask, kr_hwerrstatus, bits */ |
312 | #define INFINIPATH_HWE_HTCMEMPARITYERR_SHIFT 0 | 314 | #define INFINIPATH_HWE_HTCMEMPARITYERR_SHIFT 0 |
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c index ce0f40fbb4f2..907b61b5975a 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba6120.c +++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c | |||
@@ -316,7 +316,9 @@ static const struct ipath_cregs ipath_pe_cregs = { | |||
316 | 316 | ||
317 | /* kr_intstatus, kr_intclear, kr_intmask bits */ | 317 | /* kr_intstatus, kr_intclear, kr_intmask bits */ |
318 | #define INFINIPATH_I_RCVURG_MASK ((1U<<5)-1) | 318 | #define INFINIPATH_I_RCVURG_MASK ((1U<<5)-1) |
319 | #define INFINIPATH_I_RCVURG_SHIFT 0 | ||
319 | #define INFINIPATH_I_RCVAVAIL_MASK ((1U<<5)-1) | 320 | #define INFINIPATH_I_RCVAVAIL_MASK ((1U<<5)-1) |
321 | #define INFINIPATH_I_RCVAVAIL_SHIFT 12 | ||
320 | 322 | ||
321 | /* kr_hwerrclear, kr_hwerrmask, kr_hwerrstatus, bits */ | 323 | /* kr_hwerrclear, kr_hwerrmask, kr_hwerrstatus, bits */ |
322 | #define INFINIPATH_HWE_PCIEMEMPARITYERR_MASK 0x000000000000003fULL | 324 | #define INFINIPATH_HWE_PCIEMEMPARITYERR_MASK 0x000000000000003fULL |
diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c index 94f938f5d5c3..720ff4df84eb 100644 --- a/drivers/infiniband/hw/ipath/ipath_init_chip.c +++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c | |||
@@ -219,14 +219,14 @@ static struct ipath_portdata *create_portdata0(struct ipath_devdata *dd) | |||
219 | pd->port_cnt = 1; | 219 | pd->port_cnt = 1; |
220 | /* The port 0 pkey table is used by the layer interface. */ | 220 | /* The port 0 pkey table is used by the layer interface. */ |
221 | pd->port_pkeys[0] = IPATH_DEFAULT_P_KEY; | 221 | pd->port_pkeys[0] = IPATH_DEFAULT_P_KEY; |
222 | pd->port_seq_cnt = 1; | ||
222 | } | 223 | } |
223 | return pd; | 224 | return pd; |
224 | } | 225 | } |
225 | 226 | ||
226 | static int init_chip_first(struct ipath_devdata *dd, | 227 | static int init_chip_first(struct ipath_devdata *dd) |
227 | struct ipath_portdata **pdp) | ||
228 | { | 228 | { |
229 | struct ipath_portdata *pd = NULL; | 229 | struct ipath_portdata *pd; |
230 | int ret = 0; | 230 | int ret = 0; |
231 | u64 val; | 231 | u64 val; |
232 | 232 | ||
@@ -242,12 +242,14 @@ static int init_chip_first(struct ipath_devdata *dd, | |||
242 | else if (ipath_cfgports <= dd->ipath_portcnt) { | 242 | else if (ipath_cfgports <= dd->ipath_portcnt) { |
243 | dd->ipath_cfgports = ipath_cfgports; | 243 | dd->ipath_cfgports = ipath_cfgports; |
244 | ipath_dbg("Configured to use %u ports out of %u in chip\n", | 244 | ipath_dbg("Configured to use %u ports out of %u in chip\n", |
245 | dd->ipath_cfgports, dd->ipath_portcnt); | 245 | dd->ipath_cfgports, ipath_read_kreg32(dd, |
246 | dd->ipath_kregs->kr_portcnt)); | ||
246 | } else { | 247 | } else { |
247 | dd->ipath_cfgports = dd->ipath_portcnt; | 248 | dd->ipath_cfgports = dd->ipath_portcnt; |
248 | ipath_dbg("Tried to configured to use %u ports; chip " | 249 | ipath_dbg("Tried to configured to use %u ports; chip " |
249 | "only supports %u\n", ipath_cfgports, | 250 | "only supports %u\n", ipath_cfgports, |
250 | dd->ipath_portcnt); | 251 | ipath_read_kreg32(dd, |
252 | dd->ipath_kregs->kr_portcnt)); | ||
251 | } | 253 | } |
252 | /* | 254 | /* |
253 | * Allocate full portcnt array, rather than just cfgports, because | 255 | * Allocate full portcnt array, rather than just cfgports, because |
@@ -324,36 +326,39 @@ static int init_chip_first(struct ipath_devdata *dd, | |||
324 | mutex_init(&dd->ipath_eep_lock); | 326 | mutex_init(&dd->ipath_eep_lock); |
325 | 327 | ||
326 | done: | 328 | done: |
327 | *pdp = pd; | ||
328 | return ret; | 329 | return ret; |
329 | } | 330 | } |
330 | 331 | ||
331 | /** | 332 | /** |
332 | * init_chip_reset - re-initialize after a reset, or enable | 333 | * init_chip_reset - re-initialize after a reset, or enable |
333 | * @dd: the infinipath device | 334 | * @dd: the infinipath device |
334 | * @pdp: output for port data | ||
335 | * | 335 | * |
336 | * sanity check at least some of the values after reset, and | 336 | * sanity check at least some of the values after reset, and |
337 | * ensure no receive or transmit (explictly, in case reset | 337 | * ensure no receive or transmit (explictly, in case reset |
338 | * failed | 338 | * failed |
339 | */ | 339 | */ |
340 | static int init_chip_reset(struct ipath_devdata *dd, | 340 | static int init_chip_reset(struct ipath_devdata *dd) |
341 | struct ipath_portdata **pdp) | ||
342 | { | 341 | { |
343 | u32 rtmp; | 342 | u32 rtmp; |
343 | int i; | ||
344 | |||
345 | /* | ||
346 | * ensure chip does no sends or receives, tail updates, or | ||
347 | * pioavail updates while we re-initialize | ||
348 | */ | ||
349 | dd->ipath_rcvctrl &= ~(1ULL << dd->ipath_r_tailupd_shift); | ||
350 | for (i = 0; i < dd->ipath_portcnt; i++) { | ||
351 | clear_bit(dd->ipath_r_portenable_shift + i, | ||
352 | &dd->ipath_rcvctrl); | ||
353 | clear_bit(dd->ipath_r_intravail_shift + i, | ||
354 | &dd->ipath_rcvctrl); | ||
355 | } | ||
356 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | ||
357 | dd->ipath_rcvctrl); | ||
344 | 358 | ||
345 | *pdp = dd->ipath_pd[0]; | ||
346 | /* ensure chip does no sends or receives while we re-initialize */ | ||
347 | dd->ipath_control = dd->ipath_sendctrl = dd->ipath_rcvctrl = 0U; | ||
348 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, dd->ipath_rcvctrl); | ||
349 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl); | 359 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl); |
350 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, dd->ipath_control); | 360 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, dd->ipath_control); |
351 | 361 | ||
352 | rtmp = ipath_read_kreg32(dd, dd->ipath_kregs->kr_portcnt); | ||
353 | if (dd->ipath_portcnt != rtmp) | ||
354 | dev_info(&dd->pcidev->dev, "portcnt was %u before " | ||
355 | "reset, now %u, using original\n", | ||
356 | dd->ipath_portcnt, rtmp); | ||
357 | rtmp = ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvtidcnt); | 362 | rtmp = ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvtidcnt); |
358 | if (rtmp != dd->ipath_rcvtidcnt) | 363 | if (rtmp != dd->ipath_rcvtidcnt) |
359 | dev_info(&dd->pcidev->dev, "tidcnt was %u before " | 364 | dev_info(&dd->pcidev->dev, "tidcnt was %u before " |
@@ -456,10 +461,10 @@ static void init_shadow_tids(struct ipath_devdata *dd) | |||
456 | dd->ipath_physshadow = addrs; | 461 | dd->ipath_physshadow = addrs; |
457 | } | 462 | } |
458 | 463 | ||
459 | static void enable_chip(struct ipath_devdata *dd, | 464 | static void enable_chip(struct ipath_devdata *dd, int reinit) |
460 | struct ipath_portdata *pd, int reinit) | ||
461 | { | 465 | { |
462 | u32 val; | 466 | u32 val; |
467 | u64 rcvmask; | ||
463 | unsigned long flags; | 468 | unsigned long flags; |
464 | int i; | 469 | int i; |
465 | 470 | ||
@@ -478,12 +483,15 @@ static void enable_chip(struct ipath_devdata *dd, | |||
478 | spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); | 483 | spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); |
479 | 484 | ||
480 | /* | 485 | /* |
481 | * enable port 0 receive, and receive interrupt. other ports | 486 | * Enable kernel ports' receive and receive interrupt. |
482 | * done as user opens and inits them. | 487 | * Other ports done as user opens and inits them. |
483 | */ | 488 | */ |
484 | dd->ipath_rcvctrl = (1ULL << dd->ipath_r_tailupd_shift) | | 489 | rcvmask = 1ULL; |
485 | (1ULL << dd->ipath_r_portenable_shift) | | 490 | dd->ipath_rcvctrl |= (rcvmask << dd->ipath_r_portenable_shift) | |
486 | (1ULL << dd->ipath_r_intravail_shift); | 491 | (rcvmask << dd->ipath_r_intravail_shift); |
492 | if (!(dd->ipath_flags & IPATH_NODMA_RTAIL)) | ||
493 | dd->ipath_rcvctrl |= (1ULL << dd->ipath_r_tailupd_shift); | ||
494 | |||
487 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | 495 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, |
488 | dd->ipath_rcvctrl); | 496 | dd->ipath_rcvctrl); |
489 | 497 | ||
@@ -494,8 +502,8 @@ static void enable_chip(struct ipath_devdata *dd, | |||
494 | dd->ipath_flags |= IPATH_INITTED; | 502 | dd->ipath_flags |= IPATH_INITTED; |
495 | 503 | ||
496 | /* | 504 | /* |
497 | * init our shadow copies of head from tail values, and write | 505 | * Init our shadow copies of head from tail values, |
498 | * head values to match. | 506 | * and write head values to match. |
499 | */ | 507 | */ |
500 | val = ipath_read_ureg32(dd, ur_rcvegrindextail, 0); | 508 | val = ipath_read_ureg32(dd, ur_rcvegrindextail, 0); |
501 | ipath_write_ureg(dd, ur_rcvegrindexhead, val, 0); | 509 | ipath_write_ureg(dd, ur_rcvegrindexhead, val, 0); |
@@ -529,8 +537,7 @@ static void enable_chip(struct ipath_devdata *dd, | |||
529 | dd->ipath_flags |= IPATH_PRESENT; | 537 | dd->ipath_flags |= IPATH_PRESENT; |
530 | } | 538 | } |
531 | 539 | ||
532 | static int init_housekeeping(struct ipath_devdata *dd, | 540 | static int init_housekeeping(struct ipath_devdata *dd, int reinit) |
533 | struct ipath_portdata **pdp, int reinit) | ||
534 | { | 541 | { |
535 | char boardn[32]; | 542 | char boardn[32]; |
536 | int ret = 0; | 543 | int ret = 0; |
@@ -591,18 +598,9 @@ static int init_housekeeping(struct ipath_devdata *dd, | |||
591 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, | 598 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, |
592 | INFINIPATH_E_RESET); | 599 | INFINIPATH_E_RESET); |
593 | 600 | ||
594 | if (reinit) | 601 | ipath_cdbg(VERBOSE, "Revision %llx (PCI %x)\n", |
595 | ret = init_chip_reset(dd, pdp); | 602 | (unsigned long long) dd->ipath_revision, |
596 | else | 603 | dd->ipath_pcirev); |
597 | ret = init_chip_first(dd, pdp); | ||
598 | |||
599 | if (ret) | ||
600 | goto done; | ||
601 | |||
602 | ipath_cdbg(VERBOSE, "Revision %llx (PCI %x), %u ports, %u tids, " | ||
603 | "%u egrtids\n", (unsigned long long) dd->ipath_revision, | ||
604 | dd->ipath_pcirev, dd->ipath_portcnt, dd->ipath_rcvtidcnt, | ||
605 | dd->ipath_rcvegrcnt); | ||
606 | 604 | ||
607 | if (((dd->ipath_revision >> INFINIPATH_R_SOFTWARE_SHIFT) & | 605 | if (((dd->ipath_revision >> INFINIPATH_R_SOFTWARE_SHIFT) & |
608 | INFINIPATH_R_SOFTWARE_MASK) != IPATH_CHIP_SWVERSION) { | 606 | INFINIPATH_R_SOFTWARE_MASK) != IPATH_CHIP_SWVERSION) { |
@@ -641,6 +639,14 @@ static int init_housekeeping(struct ipath_devdata *dd, | |||
641 | 639 | ||
642 | ipath_dbg("%s", dd->ipath_boardversion); | 640 | ipath_dbg("%s", dd->ipath_boardversion); |
643 | 641 | ||
642 | if (ret) | ||
643 | goto done; | ||
644 | |||
645 | if (reinit) | ||
646 | ret = init_chip_reset(dd); | ||
647 | else | ||
648 | ret = init_chip_first(dd); | ||
649 | |||
644 | done: | 650 | done: |
645 | return ret; | 651 | return ret; |
646 | } | 652 | } |
@@ -666,11 +672,11 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) | |||
666 | u32 val32, kpiobufs; | 672 | u32 val32, kpiobufs; |
667 | u32 piobufs, uports; | 673 | u32 piobufs, uports; |
668 | u64 val; | 674 | u64 val; |
669 | struct ipath_portdata *pd = NULL; /* keep gcc4 happy */ | 675 | struct ipath_portdata *pd; |
670 | gfp_t gfp_flags = GFP_USER | __GFP_COMP; | 676 | gfp_t gfp_flags = GFP_USER | __GFP_COMP; |
671 | unsigned long flags; | 677 | unsigned long flags; |
672 | 678 | ||
673 | ret = init_housekeeping(dd, &pd, reinit); | 679 | ret = init_housekeeping(dd, reinit); |
674 | if (ret) | 680 | if (ret) |
675 | goto done; | 681 | goto done; |
676 | 682 | ||
@@ -690,7 +696,7 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) | |||
690 | * we now use routines that backend onto __get_free_pages, the | 696 | * we now use routines that backend onto __get_free_pages, the |
691 | * rest would be wasted. | 697 | * rest would be wasted. |
692 | */ | 698 | */ |
693 | dd->ipath_rcvhdrcnt = dd->ipath_rcvegrcnt; | 699 | dd->ipath_rcvhdrcnt = max(dd->ipath_p0_rcvegrcnt, dd->ipath_rcvegrcnt); |
694 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvhdrcnt, | 700 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvhdrcnt, |
695 | dd->ipath_rcvhdrcnt); | 701 | dd->ipath_rcvhdrcnt); |
696 | 702 | ||
@@ -721,8 +727,8 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) | |||
721 | if (kpiobufs + (uports * IPATH_MIN_USER_PORT_BUFCNT) > piobufs) { | 727 | if (kpiobufs + (uports * IPATH_MIN_USER_PORT_BUFCNT) > piobufs) { |
722 | int i = (int) piobufs - | 728 | int i = (int) piobufs - |
723 | (int) (uports * IPATH_MIN_USER_PORT_BUFCNT); | 729 | (int) (uports * IPATH_MIN_USER_PORT_BUFCNT); |
724 | if (i < 0) | 730 | if (i < 1) |
725 | i = 0; | 731 | i = 1; |
726 | dev_info(&dd->pcidev->dev, "Allocating %d PIO bufs of " | 732 | dev_info(&dd->pcidev->dev, "Allocating %d PIO bufs of " |
727 | "%d for kernel leaves too few for %d user ports " | 733 | "%d for kernel leaves too few for %d user ports " |
728 | "(%d each); using %u\n", kpiobufs, | 734 | "(%d each); using %u\n", kpiobufs, |
@@ -741,6 +747,7 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) | |||
741 | ipath_dbg("allocating %u pbufs/port leaves %u unused, " | 747 | ipath_dbg("allocating %u pbufs/port leaves %u unused, " |
742 | "add to kernel\n", dd->ipath_pbufsport, val32); | 748 | "add to kernel\n", dd->ipath_pbufsport, val32); |
743 | dd->ipath_lastport_piobuf -= val32; | 749 | dd->ipath_lastport_piobuf -= val32; |
750 | kpiobufs += val32; | ||
744 | ipath_dbg("%u pbufs/port leaves %u unused, add to kernel\n", | 751 | ipath_dbg("%u pbufs/port leaves %u unused, add to kernel\n", |
745 | dd->ipath_pbufsport, val32); | 752 | dd->ipath_pbufsport, val32); |
746 | } | 753 | } |
@@ -759,8 +766,10 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) | |||
759 | */ | 766 | */ |
760 | ipath_cancel_sends(dd, 0); | 767 | ipath_cancel_sends(dd, 0); |
761 | 768 | ||
762 | /* early_init sets rcvhdrentsize and rcvhdrsize, so this must be | 769 | /* |
763 | * done after early_init */ | 770 | * Early_init sets rcvhdrentsize and rcvhdrsize, so this must be |
771 | * done after early_init. | ||
772 | */ | ||
764 | dd->ipath_hdrqlast = | 773 | dd->ipath_hdrqlast = |
765 | dd->ipath_rcvhdrentsize * (dd->ipath_rcvhdrcnt - 1); | 774 | dd->ipath_rcvhdrentsize * (dd->ipath_rcvhdrcnt - 1); |
766 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvhdrentsize, | 775 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvhdrentsize, |
@@ -835,58 +844,65 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) | |||
835 | /* enable errors that are masked, at least this first time. */ | 844 | /* enable errors that are masked, at least this first time. */ |
836 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, | 845 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, |
837 | ~dd->ipath_maskederrs); | 846 | ~dd->ipath_maskederrs); |
838 | dd->ipath_errormask = ipath_read_kreg64(dd, | 847 | dd->ipath_maskederrs = 0; /* don't re-enable ignored in timer */ |
839 | dd->ipath_kregs->kr_errormask); | 848 | dd->ipath_errormask = |
849 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_errormask); | ||
840 | /* clear any interrupts up to this point (ints still not enabled) */ | 850 | /* clear any interrupts up to this point (ints still not enabled) */ |
841 | ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, -1LL); | 851 | ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, -1LL); |
842 | 852 | ||
853 | dd->ipath_f_tidtemplate(dd); | ||
854 | |||
843 | /* | 855 | /* |
844 | * Set up the port 0 (kernel) rcvhdr q and egr TIDs. If doing | 856 | * Set up the port 0 (kernel) rcvhdr q and egr TIDs. If doing |
845 | * re-init, the simplest way to handle this is to free | 857 | * re-init, the simplest way to handle this is to free |
846 | * existing, and re-allocate. | 858 | * existing, and re-allocate. |
847 | * Need to re-create rest of port 0 portdata as well. | 859 | * Need to re-create rest of port 0 portdata as well. |
848 | */ | 860 | */ |
861 | pd = dd->ipath_pd[0]; | ||
849 | if (reinit) { | 862 | if (reinit) { |
850 | /* Alloc and init new ipath_portdata for port0, | 863 | struct ipath_portdata *npd; |
864 | |||
865 | /* | ||
866 | * Alloc and init new ipath_portdata for port0, | ||
851 | * Then free old pd. Could lead to fragmentation, but also | 867 | * Then free old pd. Could lead to fragmentation, but also |
852 | * makes later support for hot-swap easier. | 868 | * makes later support for hot-swap easier. |
853 | */ | 869 | */ |
854 | struct ipath_portdata *npd; | ||
855 | npd = create_portdata0(dd); | 870 | npd = create_portdata0(dd); |
856 | if (npd) { | 871 | if (npd) { |
857 | ipath_free_pddata(dd, pd); | 872 | ipath_free_pddata(dd, pd); |
858 | dd->ipath_pd[0] = pd = npd; | 873 | dd->ipath_pd[0] = npd; |
874 | pd = npd; | ||
859 | } else { | 875 | } else { |
860 | ipath_dev_err(dd, "Unable to allocate portdata for" | 876 | ipath_dev_err(dd, "Unable to allocate portdata" |
861 | " port 0, failing\n"); | 877 | " for port 0, failing\n"); |
862 | ret = -ENOMEM; | 878 | ret = -ENOMEM; |
863 | goto done; | 879 | goto done; |
864 | } | 880 | } |
865 | } | 881 | } |
866 | dd->ipath_f_tidtemplate(dd); | ||
867 | ret = ipath_create_rcvhdrq(dd, pd); | 882 | ret = ipath_create_rcvhdrq(dd, pd); |
868 | if (!ret) { | 883 | if (!ret) |
869 | dd->ipath_hdrqtailptr = | ||
870 | (volatile __le64 *)pd->port_rcvhdrtail_kvaddr; | ||
871 | ret = create_port0_egr(dd); | 884 | ret = create_port0_egr(dd); |
872 | } | 885 | if (ret) { |
873 | if (ret) | 886 | ipath_dev_err(dd, "failed to allocate kernel port's " |
874 | ipath_dev_err(dd, "failed to allocate port 0 (kernel) " | ||
875 | "rcvhdrq and/or egr bufs\n"); | 887 | "rcvhdrq and/or egr bufs\n"); |
888 | goto done; | ||
889 | } | ||
876 | else | 890 | else |
877 | enable_chip(dd, pd, reinit); | 891 | enable_chip(dd, reinit); |
878 | 892 | ||
879 | 893 | if (!reinit) { | |
880 | if (!ret && !reinit) { | 894 | /* |
881 | /* used when we close a port, for DMA already in flight at close */ | 895 | * Used when we close a port, for DMA already in flight |
896 | * at close. | ||
897 | */ | ||
882 | dd->ipath_dummy_hdrq = dma_alloc_coherent( | 898 | dd->ipath_dummy_hdrq = dma_alloc_coherent( |
883 | &dd->pcidev->dev, pd->port_rcvhdrq_size, | 899 | &dd->pcidev->dev, dd->ipath_pd[0]->port_rcvhdrq_size, |
884 | &dd->ipath_dummy_hdrq_phys, | 900 | &dd->ipath_dummy_hdrq_phys, |
885 | gfp_flags); | 901 | gfp_flags); |
886 | if (!dd->ipath_dummy_hdrq) { | 902 | if (!dd->ipath_dummy_hdrq) { |
887 | dev_info(&dd->pcidev->dev, | 903 | dev_info(&dd->pcidev->dev, |
888 | "Couldn't allocate 0x%lx bytes for dummy hdrq\n", | 904 | "Couldn't allocate 0x%lx bytes for dummy hdrq\n", |
889 | pd->port_rcvhdrq_size); | 905 | dd->ipath_pd[0]->port_rcvhdrq_size); |
890 | /* fallback to just 0'ing */ | 906 | /* fallback to just 0'ing */ |
891 | dd->ipath_dummy_hdrq_phys = 0UL; | 907 | dd->ipath_dummy_hdrq_phys = 0UL; |
892 | } | 908 | } |
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c index 41329e72392d..826b96b39952 100644 --- a/drivers/infiniband/hw/ipath/ipath_intr.c +++ b/drivers/infiniband/hw/ipath/ipath_intr.c | |||
@@ -695,8 +695,7 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs) | |||
695 | struct ipath_portdata *pd = dd->ipath_pd[i]; | 695 | struct ipath_portdata *pd = dd->ipath_pd[i]; |
696 | if (i == 0) { | 696 | if (i == 0) { |
697 | hd = pd->port_head; | 697 | hd = pd->port_head; |
698 | tl = (u32) le64_to_cpu( | 698 | tl = ipath_get_hdrqtail(pd); |
699 | *dd->ipath_hdrqtailptr); | ||
700 | } else if (pd && pd->port_cnt && | 699 | } else if (pd && pd->port_cnt && |
701 | pd->port_rcvhdrtail_kvaddr) { | 700 | pd->port_rcvhdrtail_kvaddr) { |
702 | /* | 701 | /* |
@@ -732,8 +731,7 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs) | |||
732 | * vs user) | 731 | * vs user) |
733 | */ | 732 | */ |
734 | ipath_stats.sps_etidfull++; | 733 | ipath_stats.sps_etidfull++; |
735 | if (pd->port_head != | 734 | if (pd->port_head != ipath_get_hdrqtail(pd)) |
736 | (u32) le64_to_cpu(*dd->ipath_hdrqtailptr)) | ||
737 | chkerrpkts = 1; | 735 | chkerrpkts = 1; |
738 | } | 736 | } |
739 | 737 | ||
@@ -952,7 +950,7 @@ set: | |||
952 | * process was waiting for a packet to arrive, and didn't want | 950 | * process was waiting for a packet to arrive, and didn't want |
953 | * to poll | 951 | * to poll |
954 | */ | 952 | */ |
955 | static void handle_urcv(struct ipath_devdata *dd, u32 istat) | 953 | static void handle_urcv(struct ipath_devdata *dd, u64 istat) |
956 | { | 954 | { |
957 | u64 portr; | 955 | u64 portr; |
958 | int i; | 956 | int i; |
@@ -968,10 +966,10 @@ static void handle_urcv(struct ipath_devdata *dd, u32 istat) | |||
968 | * and ipath_poll_next()... | 966 | * and ipath_poll_next()... |
969 | */ | 967 | */ |
970 | rmb(); | 968 | rmb(); |
971 | portr = ((istat >> INFINIPATH_I_RCVAVAIL_SHIFT) & | 969 | portr = ((istat >> dd->ipath_i_rcvavail_shift) & |
972 | dd->ipath_i_rcvavail_mask) | 970 | dd->ipath_i_rcvavail_mask) | |
973 | | ((istat >> INFINIPATH_I_RCVURG_SHIFT) & | 971 | ((istat >> dd->ipath_i_rcvurg_shift) & |
974 | dd->ipath_i_rcvurg_mask); | 972 | dd->ipath_i_rcvurg_mask); |
975 | for (i = 1; i < dd->ipath_cfgports; i++) { | 973 | for (i = 1; i < dd->ipath_cfgports; i++) { |
976 | struct ipath_portdata *pd = dd->ipath_pd[i]; | 974 | struct ipath_portdata *pd = dd->ipath_pd[i]; |
977 | 975 | ||
@@ -991,7 +989,7 @@ static void handle_urcv(struct ipath_devdata *dd, u32 istat) | |||
991 | } | 989 | } |
992 | if (rcvdint) { | 990 | if (rcvdint) { |
993 | /* only want to take one interrupt, so turn off the rcv | 991 | /* only want to take one interrupt, so turn off the rcv |
994 | * interrupt for all the ports that we did the wakeup on | 992 | * interrupt for all the ports that we set the rcv_waiting |
995 | * (but never for kernel port) | 993 | * (but never for kernel port) |
996 | */ | 994 | */ |
997 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | 995 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, |
@@ -1006,8 +1004,7 @@ irqreturn_t ipath_intr(int irq, void *data) | |||
1006 | ipath_err_t estat = 0; | 1004 | ipath_err_t estat = 0; |
1007 | irqreturn_t ret; | 1005 | irqreturn_t ret; |
1008 | static unsigned unexpected = 0; | 1006 | static unsigned unexpected = 0; |
1009 | static const u32 port0rbits = (1U<<INFINIPATH_I_RCVAVAIL_SHIFT) | | 1007 | u64 kportrbits; |
1010 | (1U<<INFINIPATH_I_RCVURG_SHIFT); | ||
1011 | 1008 | ||
1012 | ipath_stats.sps_ints++; | 1009 | ipath_stats.sps_ints++; |
1013 | 1010 | ||
@@ -1076,9 +1073,7 @@ irqreturn_t ipath_intr(int irq, void *data) | |||
1076 | ipath_dev_err(dd, "Read of error status failed " | 1073 | ipath_dev_err(dd, "Read of error status failed " |
1077 | "(all bits set); ignoring\n"); | 1074 | "(all bits set); ignoring\n"); |
1078 | else | 1075 | else |
1079 | if (handle_errors(dd, estat)) | 1076 | chk0rcv |= handle_errors(dd, estat); |
1080 | /* force calling ipath_kreceive() */ | ||
1081 | chk0rcv = 1; | ||
1082 | } | 1077 | } |
1083 | 1078 | ||
1084 | if (istat & INFINIPATH_I_GPIO) { | 1079 | if (istat & INFINIPATH_I_GPIO) { |
@@ -1158,7 +1153,6 @@ irqreturn_t ipath_intr(int irq, void *data) | |||
1158 | (u64) to_clear); | 1153 | (u64) to_clear); |
1159 | } | 1154 | } |
1160 | } | 1155 | } |
1161 | chk0rcv |= istat & port0rbits; | ||
1162 | 1156 | ||
1163 | /* | 1157 | /* |
1164 | * Clear the interrupt bits we found set, unless they are receive | 1158 | * Clear the interrupt bits we found set, unless they are receive |
@@ -1171,20 +1165,20 @@ irqreturn_t ipath_intr(int irq, void *data) | |||
1171 | ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, istat); | 1165 | ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, istat); |
1172 | 1166 | ||
1173 | /* | 1167 | /* |
1174 | * handle port0 receive before checking for pio buffers available, | 1168 | * Handle kernel receive queues before checking for pio buffers |
1175 | * since receives can overflow; piobuf waiters can afford a few | 1169 | * available since receives can overflow; piobuf waiters can afford |
1176 | * extra cycles, since they were waiting anyway, and user's waiting | 1170 | * a few extra cycles, since they were waiting anyway, and user's |
1177 | * for receive are at the bottom. | 1171 | * waiting for receive are at the bottom. |
1178 | */ | 1172 | */ |
1179 | if (chk0rcv) { | 1173 | kportrbits = (1ULL << dd->ipath_i_rcvavail_shift) | |
1174 | (1ULL << dd->ipath_i_rcvurg_shift); | ||
1175 | if (chk0rcv || (istat & kportrbits)) { | ||
1176 | istat &= ~kportrbits; | ||
1180 | ipath_kreceive(dd->ipath_pd[0]); | 1177 | ipath_kreceive(dd->ipath_pd[0]); |
1181 | istat &= ~port0rbits; | ||
1182 | } | 1178 | } |
1183 | 1179 | ||
1184 | if (istat & ((dd->ipath_i_rcvavail_mask << | 1180 | if (istat & ((dd->ipath_i_rcvavail_mask << dd->ipath_i_rcvavail_shift) | |
1185 | INFINIPATH_I_RCVAVAIL_SHIFT) | 1181 | (dd->ipath_i_rcvurg_mask << dd->ipath_i_rcvurg_shift))) |
1186 | | (dd->ipath_i_rcvurg_mask << | ||
1187 | INFINIPATH_I_RCVURG_SHIFT))) | ||
1188 | handle_urcv(dd, istat); | 1182 | handle_urcv(dd, istat); |
1189 | 1183 | ||
1190 | if (istat & INFINIPATH_I_SPIOBUFAVAIL) { | 1184 | if (istat & INFINIPATH_I_SPIOBUFAVAIL) { |
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h index 9867c3f80ec2..2447e85bf4f8 100644 --- a/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/drivers/infiniband/hw/ipath/ipath_kernel.h | |||
@@ -175,6 +175,8 @@ struct ipath_portdata { | |||
175 | u16 poll_type; | 175 | u16 poll_type; |
176 | /* port rcvhdrq head offset */ | 176 | /* port rcvhdrq head offset */ |
177 | u32 port_head; | 177 | u32 port_head; |
178 | /* receive packet sequence counter */ | ||
179 | u32 port_seq_cnt; | ||
178 | }; | 180 | }; |
179 | 181 | ||
180 | struct sk_buff; | 182 | struct sk_buff; |
@@ -224,11 +226,6 @@ struct ipath_devdata { | |||
224 | unsigned long ipath_physaddr; | 226 | unsigned long ipath_physaddr; |
225 | /* base of memory alloced for ipath_kregbase, for free */ | 227 | /* base of memory alloced for ipath_kregbase, for free */ |
226 | u64 *ipath_kregalloc; | 228 | u64 *ipath_kregalloc; |
227 | /* | ||
228 | * virtual address where port0 rcvhdrqtail updated for this unit. | ||
229 | * only written to by the chip, not the driver. | ||
230 | */ | ||
231 | volatile __le64 *ipath_hdrqtailptr; | ||
232 | /* ipath_cfgports pointers */ | 229 | /* ipath_cfgports pointers */ |
233 | struct ipath_portdata **ipath_pd; | 230 | struct ipath_portdata **ipath_pd; |
234 | /* sk_buffs used by port 0 eager receive queue */ | 231 | /* sk_buffs used by port 0 eager receive queue */ |
@@ -286,6 +283,7 @@ struct ipath_devdata { | |||
286 | /* per chip actions needed for IB Link up/down changes */ | 283 | /* per chip actions needed for IB Link up/down changes */ |
287 | int (*ipath_f_ib_updown)(struct ipath_devdata *, int, u64); | 284 | int (*ipath_f_ib_updown)(struct ipath_devdata *, int, u64); |
288 | 285 | ||
286 | unsigned ipath_lastegr_idx; | ||
289 | struct ipath_ibdev *verbs_dev; | 287 | struct ipath_ibdev *verbs_dev; |
290 | struct timer_list verbs_timer; | 288 | struct timer_list verbs_timer; |
291 | /* total dwords sent (summed from counter) */ | 289 | /* total dwords sent (summed from counter) */ |
@@ -593,14 +591,6 @@ struct ipath_devdata { | |||
593 | u8 ipath_minrev; | 591 | u8 ipath_minrev; |
594 | /* board rev, from ipath_revision */ | 592 | /* board rev, from ipath_revision */ |
595 | u8 ipath_boardrev; | 593 | u8 ipath_boardrev; |
596 | |||
597 | u8 ipath_r_portenable_shift; | ||
598 | u8 ipath_r_intravail_shift; | ||
599 | u8 ipath_r_tailupd_shift; | ||
600 | u8 ipath_r_portcfg_shift; | ||
601 | |||
602 | /* unit # of this chip, if present */ | ||
603 | int ipath_unit; | ||
604 | /* saved for restore after reset */ | 594 | /* saved for restore after reset */ |
605 | u8 ipath_pci_cacheline; | 595 | u8 ipath_pci_cacheline; |
606 | /* LID mask control */ | 596 | /* LID mask control */ |
@@ -616,6 +606,14 @@ struct ipath_devdata { | |||
616 | /* Rx Polarity inversion (compensate for ~tx on partner) */ | 606 | /* Rx Polarity inversion (compensate for ~tx on partner) */ |
617 | u8 ipath_rx_pol_inv; | 607 | u8 ipath_rx_pol_inv; |
618 | 608 | ||
609 | u8 ipath_r_portenable_shift; | ||
610 | u8 ipath_r_intravail_shift; | ||
611 | u8 ipath_r_tailupd_shift; | ||
612 | u8 ipath_r_portcfg_shift; | ||
613 | |||
614 | /* unit # of this chip, if present */ | ||
615 | int ipath_unit; | ||
616 | |||
619 | /* local link integrity counter */ | 617 | /* local link integrity counter */ |
620 | u32 ipath_lli_counter; | 618 | u32 ipath_lli_counter; |
621 | /* local link integrity errors */ | 619 | /* local link integrity errors */ |
@@ -645,8 +643,8 @@ struct ipath_devdata { | |||
645 | * Below should be computable from number of ports, | 643 | * Below should be computable from number of ports, |
646 | * since they are never modified. | 644 | * since they are never modified. |
647 | */ | 645 | */ |
648 | u32 ipath_i_rcvavail_mask; | 646 | u64 ipath_i_rcvavail_mask; |
649 | u32 ipath_i_rcvurg_mask; | 647 | u64 ipath_i_rcvurg_mask; |
650 | u16 ipath_i_rcvurg_shift; | 648 | u16 ipath_i_rcvurg_shift; |
651 | u16 ipath_i_rcvavail_shift; | 649 | u16 ipath_i_rcvavail_shift; |
652 | 650 | ||
@@ -835,6 +833,8 @@ void ipath_hol_event(unsigned long); | |||
835 | #define IPATH_LINKUNK 0x400 | 833 | #define IPATH_LINKUNK 0x400 |
836 | /* Write combining flush needed for PIO */ | 834 | /* Write combining flush needed for PIO */ |
837 | #define IPATH_PIO_FLUSH_WC 0x1000 | 835 | #define IPATH_PIO_FLUSH_WC 0x1000 |
836 | /* DMA Receive tail pointer */ | ||
837 | #define IPATH_NODMA_RTAIL 0x2000 | ||
838 | /* no IB cable, or no device on IB cable */ | 838 | /* no IB cable, or no device on IB cable */ |
839 | #define IPATH_NOCABLE 0x4000 | 839 | #define IPATH_NOCABLE 0x4000 |
840 | /* Supports port zero per packet receive interrupts via | 840 | /* Supports port zero per packet receive interrupts via |
@@ -845,9 +845,9 @@ void ipath_hol_event(unsigned long); | |||
845 | /* packet/word counters are 32 bit, else those 4 counters | 845 | /* packet/word counters are 32 bit, else those 4 counters |
846 | * are 64bit */ | 846 | * are 64bit */ |
847 | #define IPATH_32BITCOUNTERS 0x20000 | 847 | #define IPATH_32BITCOUNTERS 0x20000 |
848 | /* can miss port0 rx interrupts */ | ||
849 | /* Interrupt register is 64 bits */ | 848 | /* Interrupt register is 64 bits */ |
850 | #define IPATH_INTREG_64 0x40000 | 849 | #define IPATH_INTREG_64 0x40000 |
850 | /* can miss port0 rx interrupts */ | ||
851 | #define IPATH_DISABLED 0x80000 /* administratively disabled */ | 851 | #define IPATH_DISABLED 0x80000 /* administratively disabled */ |
852 | /* Use GPIO interrupts for new counters */ | 852 | /* Use GPIO interrupts for new counters */ |
853 | #define IPATH_GPIO_ERRINTRS 0x100000 | 853 | #define IPATH_GPIO_ERRINTRS 0x100000 |
@@ -1035,6 +1035,27 @@ static inline u32 ipath_get_rcvhdrtail(const struct ipath_portdata *pd) | |||
1035 | pd->port_rcvhdrtail_kvaddr)); | 1035 | pd->port_rcvhdrtail_kvaddr)); |
1036 | } | 1036 | } |
1037 | 1037 | ||
1038 | static inline u32 ipath_get_hdrqtail(const struct ipath_portdata *pd) | ||
1039 | { | ||
1040 | const struct ipath_devdata *dd = pd->port_dd; | ||
1041 | u32 hdrqtail; | ||
1042 | |||
1043 | if (dd->ipath_flags & IPATH_NODMA_RTAIL) { | ||
1044 | __le32 *rhf_addr; | ||
1045 | u32 seq; | ||
1046 | |||
1047 | rhf_addr = (__le32 *) pd->port_rcvhdrq + | ||
1048 | pd->port_head + dd->ipath_rhf_offset; | ||
1049 | seq = ipath_hdrget_seq(rhf_addr); | ||
1050 | hdrqtail = pd->port_head; | ||
1051 | if (seq == pd->port_seq_cnt) | ||
1052 | hdrqtail++; | ||
1053 | } else | ||
1054 | hdrqtail = ipath_get_rcvhdrtail(pd); | ||
1055 | |||
1056 | return hdrqtail; | ||
1057 | } | ||
1058 | |||
1038 | static inline u64 ipath_read_ireg(const struct ipath_devdata *dd, ipath_kreg r) | 1059 | static inline u64 ipath_read_ireg(const struct ipath_devdata *dd, ipath_kreg r) |
1039 | { | 1060 | { |
1040 | return (dd->ipath_flags & IPATH_INTREG_64) ? | 1061 | return (dd->ipath_flags & IPATH_INTREG_64) ? |
diff --git a/drivers/infiniband/hw/ipath/ipath_registers.h b/drivers/infiniband/hw/ipath/ipath_registers.h index f49f1847d071..b7d87d3252e2 100644 --- a/drivers/infiniband/hw/ipath/ipath_registers.h +++ b/drivers/infiniband/hw/ipath/ipath_registers.h | |||
@@ -86,8 +86,6 @@ | |||
86 | #define INFINIPATH_R_QPMAP_ENABLE (1ULL << 38) | 86 | #define INFINIPATH_R_QPMAP_ENABLE (1ULL << 38) |
87 | 87 | ||
88 | /* kr_intstatus, kr_intclear, kr_intmask bits */ | 88 | /* kr_intstatus, kr_intclear, kr_intmask bits */ |
89 | #define INFINIPATH_I_RCVURG_SHIFT 0 | ||
90 | #define INFINIPATH_I_RCVAVAIL_SHIFT 12 | ||
91 | #define INFINIPATH_I_ERROR 0x80000000 | 89 | #define INFINIPATH_I_ERROR 0x80000000 |
92 | #define INFINIPATH_I_SPIOSENT 0x40000000 | 90 | #define INFINIPATH_I_SPIOSENT 0x40000000 |
93 | #define INFINIPATH_I_SPIOBUFAVAIL 0x20000000 | 91 | #define INFINIPATH_I_SPIOBUFAVAIL 0x20000000 |
diff --git a/drivers/infiniband/hw/ipath/ipath_stats.c b/drivers/infiniband/hw/ipath/ipath_stats.c index 57eb1d549785..adff2f10dc0e 100644 --- a/drivers/infiniband/hw/ipath/ipath_stats.c +++ b/drivers/infiniband/hw/ipath/ipath_stats.c | |||
@@ -136,6 +136,7 @@ static void ipath_qcheck(struct ipath_devdata *dd) | |||
136 | struct ipath_portdata *pd = dd->ipath_pd[0]; | 136 | struct ipath_portdata *pd = dd->ipath_pd[0]; |
137 | size_t blen = 0; | 137 | size_t blen = 0; |
138 | char buf[128]; | 138 | char buf[128]; |
139 | u32 hdrqtail; | ||
139 | 140 | ||
140 | *buf = 0; | 141 | *buf = 0; |
141 | if (pd->port_hdrqfull != dd->ipath_p0_hdrqfull) { | 142 | if (pd->port_hdrqfull != dd->ipath_p0_hdrqfull) { |
@@ -174,17 +175,18 @@ static void ipath_qcheck(struct ipath_devdata *dd) | |||
174 | if (blen) | 175 | if (blen) |
175 | ipath_dbg("%s\n", buf); | 176 | ipath_dbg("%s\n", buf); |
176 | 177 | ||
177 | if (pd->port_head != (u32) | 178 | hdrqtail = ipath_get_hdrqtail(pd); |
178 | le64_to_cpu(*dd->ipath_hdrqtailptr)) { | 179 | if (pd->port_head != hdrqtail) { |
179 | if (dd->ipath_lastport0rcv_cnt == | 180 | if (dd->ipath_lastport0rcv_cnt == |
180 | ipath_stats.sps_port0pkts) { | 181 | ipath_stats.sps_port0pkts) { |
181 | ipath_cdbg(PKT, "missing rcv interrupts? " | 182 | ipath_cdbg(PKT, "missing rcv interrupts? " |
182 | "port0 hd=%llx tl=%x; port0pkts %llx\n", | 183 | "port0 hd=%x tl=%x; port0pkts %llx; write" |
183 | (unsigned long long) | 184 | " hd (w/intr)\n", |
184 | le64_to_cpu(*dd->ipath_hdrqtailptr), | 185 | pd->port_head, hdrqtail, |
185 | pd->port_head, | ||
186 | (unsigned long long) | 186 | (unsigned long long) |
187 | ipath_stats.sps_port0pkts); | 187 | ipath_stats.sps_port0pkts); |
188 | ipath_write_ureg(dd, ur_rcvhdrhead, hdrqtail | | ||
189 | dd->ipath_rhdrhead_intr_off, pd->port_port); | ||
188 | } | 190 | } |
189 | dd->ipath_lastport0rcv_cnt = ipath_stats.sps_port0pkts; | 191 | dd->ipath_lastport0rcv_cnt = ipath_stats.sps_port0pkts; |
190 | } | 192 | } |