IB/mthca: fix posting of send lists of length >= 255 on mem-free HCAs
authorMichael S. Tsirkin <mst@mellanox.co.il>
Tue, 29 Nov 2005 19:33:46 +0000 (11:33 -0800)
committerRoland Dreier <rolandd@cisco.com>
Tue, 29 Nov 2005 19:33:46 +0000 (11:33 -0800)
On mem-free HCAs, when posting a long list of send requests, a
doorbell must be rung every 255 requests.  Add code to handle this.

Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/hw/mthca/mthca_qp.c
drivers/infiniband/hw/mthca/mthca_wqe.h

index f9c8eb9845c908660429cb03c296f417ad89c94d..7450550db736260bdd06228e66348b26a6eb8b19 100644 (file)
@@ -1822,6 +1822,7 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 {
        struct mthca_dev *dev = to_mdev(ibqp->device);
        struct mthca_qp *qp = to_mqp(ibqp);
+       __be32 doorbell[2];
        void *wqe;
        void *prev_wqe;
        unsigned long flags;
@@ -1841,6 +1842,34 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
        ind = qp->sq.head & (qp->sq.max - 1);
 
        for (nreq = 0; wr; ++nreq, wr = wr->next) {
+               if (unlikely(nreq == MTHCA_ARBEL_MAX_WQES_PER_SEND_DB)) {
+                       nreq = 0;
+
+                       doorbell[0] = cpu_to_be32((MTHCA_ARBEL_MAX_WQES_PER_SEND_DB << 24) |
+                                                 ((qp->sq.head & 0xffff) << 8) |
+                                                 f0 | op0);
+                       doorbell[1] = cpu_to_be32((qp->qpn << 8) | size0);
+
+                       qp->sq.head += MTHCA_ARBEL_MAX_WQES_PER_SEND_DB;
+                       size0 = 0;
+
+                       /*
+                        * Make sure that descriptors are written before
+                        * doorbell record.
+                        */
+                       wmb();
+                       *qp->sq.db = cpu_to_be32(qp->sq.head & 0xffff);
+
+                       /*
+                        * Make sure doorbell record is written before we
+                        * write MMIO send doorbell.
+                        */
+                       wmb();
+                       mthca_write64(doorbell,
+                                     dev->kar + MTHCA_SEND_DOORBELL,
+                                     MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
+               }
+
                if (mthca_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq)) {
                        mthca_err(dev, "SQ %06x full (%u head, %u tail,"
                                        " %d max, %d nreq)\n", qp->qpn,
@@ -2017,8 +2046,6 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 
 out:
        if (likely(nreq)) {
-               __be32 doorbell[2];
-
                doorbell[0] = cpu_to_be32((nreq << 24)                  |
                                          ((qp->sq.head & 0xffff) << 8) |
                                          f0 | op0);
index 73f1c0b9021e65b5f05bf9ee4cdd821bc6d6daee..e7d2c1e86199598a6762adcdc57d6a6858bcca77 100644 (file)
@@ -50,7 +50,8 @@ enum {
 
 enum {
        MTHCA_INVAL_LKEY                        = 0x100,
-       MTHCA_TAVOR_MAX_WQES_PER_RECV_DB        = 256
+       MTHCA_TAVOR_MAX_WQES_PER_RECV_DB        = 256,
+       MTHCA_ARBEL_MAX_WQES_PER_SEND_DB        = 255
 };
 
 struct mthca_next_seg {