]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
IB/hfi1: Add a function to build TID RDMA READ response
authorKaike Wan <kaike.wan@intel.com>
Thu, 24 Jan 2019 03:31:12 +0000 (19:31 -0800)
committerDoug Ledford <dledford@redhat.com>
Tue, 5 Feb 2019 22:53:55 +0000 (17:53 -0500)
This patch adds the function to build TID RDMA READ response packet.
The previously received TID resource information will be used to
build the KDETH packet, which will direct the delivery of packet payload
by hardware.

Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: Kaike Wan <kaike.wan@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/hw/hfi1/tid_rdma.c
drivers/infiniband/hw/hfi1/tid_rdma.h

index d8a46b7ddca02f90228bec36448242924848e71d..888954a79dac62ff29452404658e303a511b34e5 100644 (file)
@@ -2126,3 +2126,70 @@ void hfi1_rc_rcv_tid_rdma_read_req(struct hfi1_packet *packet)
 send_ack:
        hfi1_send_rc_ack(packet, is_fecn);
 }
+
+u32 hfi1_build_tid_rdma_read_resp(struct rvt_qp *qp, struct rvt_ack_entry *e,
+                                 struct ib_other_headers *ohdr, u32 *bth0,
+                                 u32 *bth1, u32 *bth2, u32 *len, bool *last)
+{
+       struct hfi1_ack_priv *epriv = e->priv;
+       struct tid_rdma_request *req = &epriv->tid_req;
+       struct hfi1_qp_priv *qpriv = qp->priv;
+       struct tid_rdma_flow *flow = &req->flows[req->clear_tail];
+       u32 tidentry = flow->tid_entry[flow->tid_idx];
+       u32 tidlen = EXP_TID_GET(tidentry, LEN) << PAGE_SHIFT;
+       struct tid_rdma_read_resp *resp = &ohdr->u.tid_rdma.r_rsp;
+       u32 next_offset, om = KDETH_OM_LARGE;
+       bool last_pkt;
+       u32 hdwords = 0;
+       struct tid_rdma_params *remote;
+
+       *len = min_t(u32, qp->pmtu, tidlen - flow->tid_offset);
+       flow->sent += *len;
+       next_offset = flow->tid_offset + *len;
+       last_pkt = (flow->sent >= flow->length);
+
+       rcu_read_lock();
+       remote = rcu_dereference(qpriv->tid_rdma.remote);
+       if (!remote) {
+               rcu_read_unlock();
+               goto done;
+       }
+       KDETH_RESET(resp->kdeth0, KVER, 0x1);
+       KDETH_SET(resp->kdeth0, SH, !last_pkt);
+       KDETH_SET(resp->kdeth0, INTR, !!(!last_pkt && remote->urg));
+       KDETH_SET(resp->kdeth0, TIDCTRL, EXP_TID_GET(tidentry, CTRL));
+       KDETH_SET(resp->kdeth0, TID, EXP_TID_GET(tidentry, IDX));
+       KDETH_SET(resp->kdeth0, OM, om == KDETH_OM_LARGE);
+       KDETH_SET(resp->kdeth0, OFFSET, flow->tid_offset / om);
+       KDETH_RESET(resp->kdeth1, JKEY, remote->jkey);
+       resp->verbs_qp = cpu_to_be32(qp->remote_qpn);
+       rcu_read_unlock();
+
+       resp->aeth = rvt_compute_aeth(qp);
+       resp->verbs_psn = cpu_to_be32(mask_psn(flow->flow_state.ib_spsn +
+                                              flow->pkt));
+
+       *bth0 = TID_OP(READ_RESP) << 24;
+       *bth1 = flow->tid_qpn;
+       *bth2 = mask_psn(((flow->flow_state.spsn + flow->pkt++) &
+                         HFI1_KDETH_BTH_SEQ_MASK) |
+                        (flow->flow_state.generation <<
+                         HFI1_KDETH_BTH_SEQ_SHIFT));
+       *last = last_pkt;
+       if (last_pkt)
+               /* Advance to next flow */
+               req->clear_tail = (req->clear_tail + 1) &
+                                 (MAX_FLOWS - 1);
+
+       if (next_offset >= tidlen) {
+               flow->tid_offset = 0;
+               flow->tid_idx++;
+       } else {
+               flow->tid_offset = next_offset;
+       }
+
+       hdwords = sizeof(ohdr->u.tid_rdma.r_rsp) / sizeof(u32);
+
+done:
+       return hdwords;
+}
index 439329398ccc7832fa68086ffd208f60cf66585f..01ded7c0c3026e059ce3076d77d7d6be7b205379 100644 (file)
@@ -198,5 +198,8 @@ u32 hfi1_build_tid_rdma_read_req(struct rvt_qp *qp, struct rvt_swqe *wqe,
                                 struct ib_other_headers *ohdr, u32 *bth1,
                                 u32 *bth2, u32 *len);
 void hfi1_rc_rcv_tid_rdma_read_req(struct hfi1_packet *packet);
+u32 hfi1_build_tid_rdma_read_resp(struct rvt_qp *qp, struct rvt_ack_entry *e,
+                                 struct ib_other_headers *ohdr, u32 *bth0,
+                                 u32 *bth1, u32 *bth2, u32 *len, bool *last);
 
 #endif /* HFI1_TID_RDMA_H */