aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ipath/ipath_driver.c
diff options
context:
space:
mode:
authorRalph Campbell <ralph.campbell@qlogic.com>2008-04-17 00:09:29 -0400
committerRoland Dreier <rolandd@cisco.com>2008-04-17 00:09:29 -0400
commit9355fb6a064723c71e80e9c78de3140b43bfb52d (patch)
treedd0fffeb6633aed6cb2c946a05bf33e05f2e9436 /drivers/infiniband/hw/ipath/ipath_driver.c
parent2ba3f56eb402672ff83601b5990b219d39577636 (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/infiniband/hw/ipath/ipath_driver.c')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c194
1 files changed, 105 insertions, 89 deletions
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
46static void ipath_update_pio_bufs(struct ipath_devdata *); 45static 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 */
1115void ipath_kreceive(struct ipath_portdata *pd) 1115void 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
1138reloop: 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); 1143reloop:
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;
1691bail: 1707bail:
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,