162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright(c) 2015 - 2018 Intel Corporation. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include <linux/io.h> 762306a36Sopenharmony_ci#include <rdma/rdma_vt.h> 862306a36Sopenharmony_ci#include <rdma/rdmavt_qp.h> 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include "hfi.h" 1162306a36Sopenharmony_ci#include "qp.h" 1262306a36Sopenharmony_ci#include "rc.h" 1362306a36Sopenharmony_ci#include "verbs_txreq.h" 1462306a36Sopenharmony_ci#include "trace.h" 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_cistruct rvt_ack_entry *find_prev_entry(struct rvt_qp *qp, u32 psn, u8 *prev, 1762306a36Sopenharmony_ci u8 *prev_ack, bool *scheduled) 1862306a36Sopenharmony_ci __must_hold(&qp->s_lock) 1962306a36Sopenharmony_ci{ 2062306a36Sopenharmony_ci struct rvt_ack_entry *e = NULL; 2162306a36Sopenharmony_ci u8 i, p; 2262306a36Sopenharmony_ci bool s = true; 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci for (i = qp->r_head_ack_queue; ; i = p) { 2562306a36Sopenharmony_ci if (i == qp->s_tail_ack_queue) 2662306a36Sopenharmony_ci s = false; 2762306a36Sopenharmony_ci if (i) 2862306a36Sopenharmony_ci p = i - 1; 2962306a36Sopenharmony_ci else 3062306a36Sopenharmony_ci p = rvt_size_atomic(ib_to_rvt(qp->ibqp.device)); 3162306a36Sopenharmony_ci if (p == qp->r_head_ack_queue) { 3262306a36Sopenharmony_ci e = NULL; 3362306a36Sopenharmony_ci break; 3462306a36Sopenharmony_ci } 3562306a36Sopenharmony_ci e = &qp->s_ack_queue[p]; 3662306a36Sopenharmony_ci if (!e->opcode) { 3762306a36Sopenharmony_ci e = NULL; 3862306a36Sopenharmony_ci break; 3962306a36Sopenharmony_ci } 4062306a36Sopenharmony_ci if (cmp_psn(psn, e->psn) >= 0) { 4162306a36Sopenharmony_ci if (p == qp->s_tail_ack_queue && 4262306a36Sopenharmony_ci cmp_psn(psn, e->lpsn) <= 0) 4362306a36Sopenharmony_ci s = false; 4462306a36Sopenharmony_ci break; 4562306a36Sopenharmony_ci } 4662306a36Sopenharmony_ci } 4762306a36Sopenharmony_ci if (prev) 4862306a36Sopenharmony_ci *prev = p; 4962306a36Sopenharmony_ci if (prev_ack) 5062306a36Sopenharmony_ci *prev_ack = i; 5162306a36Sopenharmony_ci if (scheduled) 5262306a36Sopenharmony_ci *scheduled = s; 5362306a36Sopenharmony_ci return e; 5462306a36Sopenharmony_ci} 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci/** 5762306a36Sopenharmony_ci * make_rc_ack - construct a response packet (ACK, NAK, or RDMA read) 5862306a36Sopenharmony_ci * @dev: the device for this QP 5962306a36Sopenharmony_ci * @qp: a pointer to the QP 6062306a36Sopenharmony_ci * @ohdr: a pointer to the IB header being constructed 6162306a36Sopenharmony_ci * @ps: the xmit packet state 6262306a36Sopenharmony_ci * 6362306a36Sopenharmony_ci * Return 1 if constructed; otherwise, return 0. 6462306a36Sopenharmony_ci * Note that we are in the responder's side of the QP context. 6562306a36Sopenharmony_ci * Note the QP s_lock must be held. 6662306a36Sopenharmony_ci */ 6762306a36Sopenharmony_cistatic int make_rc_ack(struct hfi1_ibdev *dev, struct rvt_qp *qp, 6862306a36Sopenharmony_ci struct ib_other_headers *ohdr, 6962306a36Sopenharmony_ci struct hfi1_pkt_state *ps) 7062306a36Sopenharmony_ci{ 7162306a36Sopenharmony_ci struct rvt_ack_entry *e; 7262306a36Sopenharmony_ci u32 hwords, hdrlen; 7362306a36Sopenharmony_ci u32 len = 0; 7462306a36Sopenharmony_ci u32 bth0 = 0, bth2 = 0; 7562306a36Sopenharmony_ci u32 bth1 = qp->remote_qpn | (HFI1_CAP_IS_KSET(OPFN) << IB_BTHE_E_SHIFT); 7662306a36Sopenharmony_ci int middle = 0; 7762306a36Sopenharmony_ci u32 pmtu = qp->pmtu; 7862306a36Sopenharmony_ci struct hfi1_qp_priv *qpriv = qp->priv; 7962306a36Sopenharmony_ci bool last_pkt; 8062306a36Sopenharmony_ci u32 delta; 8162306a36Sopenharmony_ci u8 next = qp->s_tail_ack_queue; 8262306a36Sopenharmony_ci struct tid_rdma_request *req; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci trace_hfi1_rsp_make_rc_ack(qp, 0); 8562306a36Sopenharmony_ci lockdep_assert_held(&qp->s_lock); 8662306a36Sopenharmony_ci /* Don't send an ACK if we aren't supposed to. */ 8762306a36Sopenharmony_ci if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK)) 8862306a36Sopenharmony_ci goto bail; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci if (qpriv->hdr_type == HFI1_PKT_TYPE_9B) 9162306a36Sopenharmony_ci /* header size in 32-bit words LRH+BTH = (8+12)/4. */ 9262306a36Sopenharmony_ci hwords = 5; 9362306a36Sopenharmony_ci else 9462306a36Sopenharmony_ci /* header size in 32-bit words 16B LRH+BTH = (16+12)/4. */ 9562306a36Sopenharmony_ci hwords = 7; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci switch (qp->s_ack_state) { 9862306a36Sopenharmony_ci case OP(RDMA_READ_RESPONSE_LAST): 9962306a36Sopenharmony_ci case OP(RDMA_READ_RESPONSE_ONLY): 10062306a36Sopenharmony_ci e = &qp->s_ack_queue[qp->s_tail_ack_queue]; 10162306a36Sopenharmony_ci release_rdma_sge_mr(e); 10262306a36Sopenharmony_ci fallthrough; 10362306a36Sopenharmony_ci case OP(ATOMIC_ACKNOWLEDGE): 10462306a36Sopenharmony_ci /* 10562306a36Sopenharmony_ci * We can increment the tail pointer now that the last 10662306a36Sopenharmony_ci * response has been sent instead of only being 10762306a36Sopenharmony_ci * constructed. 10862306a36Sopenharmony_ci */ 10962306a36Sopenharmony_ci if (++next > rvt_size_atomic(&dev->rdi)) 11062306a36Sopenharmony_ci next = 0; 11162306a36Sopenharmony_ci /* 11262306a36Sopenharmony_ci * Only advance the s_acked_ack_queue pointer if there 11362306a36Sopenharmony_ci * have been no TID RDMA requests. 11462306a36Sopenharmony_ci */ 11562306a36Sopenharmony_ci e = &qp->s_ack_queue[qp->s_tail_ack_queue]; 11662306a36Sopenharmony_ci if (e->opcode != TID_OP(WRITE_REQ) && 11762306a36Sopenharmony_ci qp->s_acked_ack_queue == qp->s_tail_ack_queue) 11862306a36Sopenharmony_ci qp->s_acked_ack_queue = next; 11962306a36Sopenharmony_ci qp->s_tail_ack_queue = next; 12062306a36Sopenharmony_ci trace_hfi1_rsp_make_rc_ack(qp, e->psn); 12162306a36Sopenharmony_ci fallthrough; 12262306a36Sopenharmony_ci case OP(SEND_ONLY): 12362306a36Sopenharmony_ci case OP(ACKNOWLEDGE): 12462306a36Sopenharmony_ci /* Check for no next entry in the queue. */ 12562306a36Sopenharmony_ci if (qp->r_head_ack_queue == qp->s_tail_ack_queue) { 12662306a36Sopenharmony_ci if (qp->s_flags & RVT_S_ACK_PENDING) 12762306a36Sopenharmony_ci goto normal; 12862306a36Sopenharmony_ci goto bail; 12962306a36Sopenharmony_ci } 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci e = &qp->s_ack_queue[qp->s_tail_ack_queue]; 13262306a36Sopenharmony_ci /* Check for tid write fence */ 13362306a36Sopenharmony_ci if ((qpriv->s_flags & HFI1_R_TID_WAIT_INTERLCK) || 13462306a36Sopenharmony_ci hfi1_tid_rdma_ack_interlock(qp, e)) { 13562306a36Sopenharmony_ci iowait_set_flag(&qpriv->s_iowait, IOWAIT_PENDING_IB); 13662306a36Sopenharmony_ci goto bail; 13762306a36Sopenharmony_ci } 13862306a36Sopenharmony_ci if (e->opcode == OP(RDMA_READ_REQUEST)) { 13962306a36Sopenharmony_ci /* 14062306a36Sopenharmony_ci * If a RDMA read response is being resent and 14162306a36Sopenharmony_ci * we haven't seen the duplicate request yet, 14262306a36Sopenharmony_ci * then stop sending the remaining responses the 14362306a36Sopenharmony_ci * responder has seen until the requester re-sends it. 14462306a36Sopenharmony_ci */ 14562306a36Sopenharmony_ci len = e->rdma_sge.sge_length; 14662306a36Sopenharmony_ci if (len && !e->rdma_sge.mr) { 14762306a36Sopenharmony_ci if (qp->s_acked_ack_queue == 14862306a36Sopenharmony_ci qp->s_tail_ack_queue) 14962306a36Sopenharmony_ci qp->s_acked_ack_queue = 15062306a36Sopenharmony_ci qp->r_head_ack_queue; 15162306a36Sopenharmony_ci qp->s_tail_ack_queue = qp->r_head_ack_queue; 15262306a36Sopenharmony_ci goto bail; 15362306a36Sopenharmony_ci } 15462306a36Sopenharmony_ci /* Copy SGE state in case we need to resend */ 15562306a36Sopenharmony_ci ps->s_txreq->mr = e->rdma_sge.mr; 15662306a36Sopenharmony_ci if (ps->s_txreq->mr) 15762306a36Sopenharmony_ci rvt_get_mr(ps->s_txreq->mr); 15862306a36Sopenharmony_ci qp->s_ack_rdma_sge.sge = e->rdma_sge; 15962306a36Sopenharmony_ci qp->s_ack_rdma_sge.num_sge = 1; 16062306a36Sopenharmony_ci ps->s_txreq->ss = &qp->s_ack_rdma_sge; 16162306a36Sopenharmony_ci if (len > pmtu) { 16262306a36Sopenharmony_ci len = pmtu; 16362306a36Sopenharmony_ci qp->s_ack_state = OP(RDMA_READ_RESPONSE_FIRST); 16462306a36Sopenharmony_ci } else { 16562306a36Sopenharmony_ci qp->s_ack_state = OP(RDMA_READ_RESPONSE_ONLY); 16662306a36Sopenharmony_ci e->sent = 1; 16762306a36Sopenharmony_ci } 16862306a36Sopenharmony_ci ohdr->u.aeth = rvt_compute_aeth(qp); 16962306a36Sopenharmony_ci hwords++; 17062306a36Sopenharmony_ci qp->s_ack_rdma_psn = e->psn; 17162306a36Sopenharmony_ci bth2 = mask_psn(qp->s_ack_rdma_psn++); 17262306a36Sopenharmony_ci } else if (e->opcode == TID_OP(WRITE_REQ)) { 17362306a36Sopenharmony_ci /* 17462306a36Sopenharmony_ci * If a TID RDMA WRITE RESP is being resent, we have to 17562306a36Sopenharmony_ci * wait for the actual request. All requests that are to 17662306a36Sopenharmony_ci * be resent will have their state set to 17762306a36Sopenharmony_ci * TID_REQUEST_RESEND. When the new request arrives, the 17862306a36Sopenharmony_ci * state will be changed to TID_REQUEST_RESEND_ACTIVE. 17962306a36Sopenharmony_ci */ 18062306a36Sopenharmony_ci req = ack_to_tid_req(e); 18162306a36Sopenharmony_ci if (req->state == TID_REQUEST_RESEND || 18262306a36Sopenharmony_ci req->state == TID_REQUEST_INIT_RESEND) 18362306a36Sopenharmony_ci goto bail; 18462306a36Sopenharmony_ci qp->s_ack_state = TID_OP(WRITE_RESP); 18562306a36Sopenharmony_ci qp->s_ack_rdma_psn = mask_psn(e->psn + req->cur_seg); 18662306a36Sopenharmony_ci goto write_resp; 18762306a36Sopenharmony_ci } else if (e->opcode == TID_OP(READ_REQ)) { 18862306a36Sopenharmony_ci /* 18962306a36Sopenharmony_ci * If a TID RDMA read response is being resent and 19062306a36Sopenharmony_ci * we haven't seen the duplicate request yet, 19162306a36Sopenharmony_ci * then stop sending the remaining responses the 19262306a36Sopenharmony_ci * responder has seen until the requester re-sends it. 19362306a36Sopenharmony_ci */ 19462306a36Sopenharmony_ci len = e->rdma_sge.sge_length; 19562306a36Sopenharmony_ci if (len && !e->rdma_sge.mr) { 19662306a36Sopenharmony_ci if (qp->s_acked_ack_queue == 19762306a36Sopenharmony_ci qp->s_tail_ack_queue) 19862306a36Sopenharmony_ci qp->s_acked_ack_queue = 19962306a36Sopenharmony_ci qp->r_head_ack_queue; 20062306a36Sopenharmony_ci qp->s_tail_ack_queue = qp->r_head_ack_queue; 20162306a36Sopenharmony_ci goto bail; 20262306a36Sopenharmony_ci } 20362306a36Sopenharmony_ci /* Copy SGE state in case we need to resend */ 20462306a36Sopenharmony_ci ps->s_txreq->mr = e->rdma_sge.mr; 20562306a36Sopenharmony_ci if (ps->s_txreq->mr) 20662306a36Sopenharmony_ci rvt_get_mr(ps->s_txreq->mr); 20762306a36Sopenharmony_ci qp->s_ack_rdma_sge.sge = e->rdma_sge; 20862306a36Sopenharmony_ci qp->s_ack_rdma_sge.num_sge = 1; 20962306a36Sopenharmony_ci qp->s_ack_state = TID_OP(READ_RESP); 21062306a36Sopenharmony_ci goto read_resp; 21162306a36Sopenharmony_ci } else { 21262306a36Sopenharmony_ci /* COMPARE_SWAP or FETCH_ADD */ 21362306a36Sopenharmony_ci ps->s_txreq->ss = NULL; 21462306a36Sopenharmony_ci len = 0; 21562306a36Sopenharmony_ci qp->s_ack_state = OP(ATOMIC_ACKNOWLEDGE); 21662306a36Sopenharmony_ci ohdr->u.at.aeth = rvt_compute_aeth(qp); 21762306a36Sopenharmony_ci ib_u64_put(e->atomic_data, &ohdr->u.at.atomic_ack_eth); 21862306a36Sopenharmony_ci hwords += sizeof(ohdr->u.at) / sizeof(u32); 21962306a36Sopenharmony_ci bth2 = mask_psn(e->psn); 22062306a36Sopenharmony_ci e->sent = 1; 22162306a36Sopenharmony_ci } 22262306a36Sopenharmony_ci trace_hfi1_tid_write_rsp_make_rc_ack(qp); 22362306a36Sopenharmony_ci bth0 = qp->s_ack_state << 24; 22462306a36Sopenharmony_ci break; 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci case OP(RDMA_READ_RESPONSE_FIRST): 22762306a36Sopenharmony_ci qp->s_ack_state = OP(RDMA_READ_RESPONSE_MIDDLE); 22862306a36Sopenharmony_ci fallthrough; 22962306a36Sopenharmony_ci case OP(RDMA_READ_RESPONSE_MIDDLE): 23062306a36Sopenharmony_ci ps->s_txreq->ss = &qp->s_ack_rdma_sge; 23162306a36Sopenharmony_ci ps->s_txreq->mr = qp->s_ack_rdma_sge.sge.mr; 23262306a36Sopenharmony_ci if (ps->s_txreq->mr) 23362306a36Sopenharmony_ci rvt_get_mr(ps->s_txreq->mr); 23462306a36Sopenharmony_ci len = qp->s_ack_rdma_sge.sge.sge_length; 23562306a36Sopenharmony_ci if (len > pmtu) { 23662306a36Sopenharmony_ci len = pmtu; 23762306a36Sopenharmony_ci middle = HFI1_CAP_IS_KSET(SDMA_AHG); 23862306a36Sopenharmony_ci } else { 23962306a36Sopenharmony_ci ohdr->u.aeth = rvt_compute_aeth(qp); 24062306a36Sopenharmony_ci hwords++; 24162306a36Sopenharmony_ci qp->s_ack_state = OP(RDMA_READ_RESPONSE_LAST); 24262306a36Sopenharmony_ci e = &qp->s_ack_queue[qp->s_tail_ack_queue]; 24362306a36Sopenharmony_ci e->sent = 1; 24462306a36Sopenharmony_ci } 24562306a36Sopenharmony_ci bth0 = qp->s_ack_state << 24; 24662306a36Sopenharmony_ci bth2 = mask_psn(qp->s_ack_rdma_psn++); 24762306a36Sopenharmony_ci break; 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci case TID_OP(WRITE_RESP): 25062306a36Sopenharmony_ciwrite_resp: 25162306a36Sopenharmony_ci /* 25262306a36Sopenharmony_ci * 1. Check if RVT_S_ACK_PENDING is set. If yes, 25362306a36Sopenharmony_ci * goto normal. 25462306a36Sopenharmony_ci * 2. Attempt to allocate TID resources. 25562306a36Sopenharmony_ci * 3. Remove RVT_S_RESP_PENDING flags from s_flags 25662306a36Sopenharmony_ci * 4. If resources not available: 25762306a36Sopenharmony_ci * 4.1 Set RVT_S_WAIT_TID_SPACE 25862306a36Sopenharmony_ci * 4.2 Queue QP on RCD TID queue 25962306a36Sopenharmony_ci * 4.3 Put QP on iowait list. 26062306a36Sopenharmony_ci * 4.4 Build IB RNR NAK with appropriate timeout value 26162306a36Sopenharmony_ci * 4.5 Return indication progress made. 26262306a36Sopenharmony_ci * 5. If resources are available: 26362306a36Sopenharmony_ci * 5.1 Program HW flow CSRs 26462306a36Sopenharmony_ci * 5.2 Build TID RDMA WRITE RESP packet 26562306a36Sopenharmony_ci * 5.3 If more resources needed, do 2.1 - 2.3. 26662306a36Sopenharmony_ci * 5.4 Wake up next QP on RCD TID queue. 26762306a36Sopenharmony_ci * 5.5 Return indication progress made. 26862306a36Sopenharmony_ci */ 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci e = &qp->s_ack_queue[qp->s_tail_ack_queue]; 27162306a36Sopenharmony_ci req = ack_to_tid_req(e); 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci /* 27462306a36Sopenharmony_ci * Send scheduled RNR NAK's. RNR NAK's need to be sent at 27562306a36Sopenharmony_ci * segment boundaries, not at request boundaries. Don't change 27662306a36Sopenharmony_ci * s_ack_state because we are still in the middle of a request 27762306a36Sopenharmony_ci */ 27862306a36Sopenharmony_ci if (qpriv->rnr_nak_state == TID_RNR_NAK_SEND && 27962306a36Sopenharmony_ci qp->s_tail_ack_queue == qpriv->r_tid_alloc && 28062306a36Sopenharmony_ci req->cur_seg == req->alloc_seg) { 28162306a36Sopenharmony_ci qpriv->rnr_nak_state = TID_RNR_NAK_SENT; 28262306a36Sopenharmony_ci goto normal_no_state; 28362306a36Sopenharmony_ci } 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci bth2 = mask_psn(qp->s_ack_rdma_psn); 28662306a36Sopenharmony_ci hdrlen = hfi1_build_tid_rdma_write_resp(qp, e, ohdr, &bth1, 28762306a36Sopenharmony_ci bth2, &len, 28862306a36Sopenharmony_ci &ps->s_txreq->ss); 28962306a36Sopenharmony_ci if (!hdrlen) 29062306a36Sopenharmony_ci return 0; 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci hwords += hdrlen; 29362306a36Sopenharmony_ci bth0 = qp->s_ack_state << 24; 29462306a36Sopenharmony_ci qp->s_ack_rdma_psn++; 29562306a36Sopenharmony_ci trace_hfi1_tid_req_make_rc_ack_write(qp, 0, e->opcode, e->psn, 29662306a36Sopenharmony_ci e->lpsn, req); 29762306a36Sopenharmony_ci if (req->cur_seg != req->total_segs) 29862306a36Sopenharmony_ci break; 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci e->sent = 1; 30162306a36Sopenharmony_ci /* Do not free e->rdma_sge until all data are received */ 30262306a36Sopenharmony_ci qp->s_ack_state = OP(ATOMIC_ACKNOWLEDGE); 30362306a36Sopenharmony_ci break; 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci case TID_OP(READ_RESP): 30662306a36Sopenharmony_ciread_resp: 30762306a36Sopenharmony_ci e = &qp->s_ack_queue[qp->s_tail_ack_queue]; 30862306a36Sopenharmony_ci ps->s_txreq->ss = &qp->s_ack_rdma_sge; 30962306a36Sopenharmony_ci delta = hfi1_build_tid_rdma_read_resp(qp, e, ohdr, &bth0, 31062306a36Sopenharmony_ci &bth1, &bth2, &len, 31162306a36Sopenharmony_ci &last_pkt); 31262306a36Sopenharmony_ci if (delta == 0) 31362306a36Sopenharmony_ci goto error_qp; 31462306a36Sopenharmony_ci hwords += delta; 31562306a36Sopenharmony_ci if (last_pkt) { 31662306a36Sopenharmony_ci e->sent = 1; 31762306a36Sopenharmony_ci /* 31862306a36Sopenharmony_ci * Increment qp->s_tail_ack_queue through s_ack_state 31962306a36Sopenharmony_ci * transition. 32062306a36Sopenharmony_ci */ 32162306a36Sopenharmony_ci qp->s_ack_state = OP(RDMA_READ_RESPONSE_LAST); 32262306a36Sopenharmony_ci } 32362306a36Sopenharmony_ci break; 32462306a36Sopenharmony_ci case TID_OP(READ_REQ): 32562306a36Sopenharmony_ci goto bail; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci default: 32862306a36Sopenharmony_cinormal: 32962306a36Sopenharmony_ci /* 33062306a36Sopenharmony_ci * Send a regular ACK. 33162306a36Sopenharmony_ci * Set the s_ack_state so we wait until after sending 33262306a36Sopenharmony_ci * the ACK before setting s_ack_state to ACKNOWLEDGE 33362306a36Sopenharmony_ci * (see above). 33462306a36Sopenharmony_ci */ 33562306a36Sopenharmony_ci qp->s_ack_state = OP(SEND_ONLY); 33662306a36Sopenharmony_cinormal_no_state: 33762306a36Sopenharmony_ci if (qp->s_nak_state) 33862306a36Sopenharmony_ci ohdr->u.aeth = 33962306a36Sopenharmony_ci cpu_to_be32((qp->r_msn & IB_MSN_MASK) | 34062306a36Sopenharmony_ci (qp->s_nak_state << 34162306a36Sopenharmony_ci IB_AETH_CREDIT_SHIFT)); 34262306a36Sopenharmony_ci else 34362306a36Sopenharmony_ci ohdr->u.aeth = rvt_compute_aeth(qp); 34462306a36Sopenharmony_ci hwords++; 34562306a36Sopenharmony_ci len = 0; 34662306a36Sopenharmony_ci bth0 = OP(ACKNOWLEDGE) << 24; 34762306a36Sopenharmony_ci bth2 = mask_psn(qp->s_ack_psn); 34862306a36Sopenharmony_ci qp->s_flags &= ~RVT_S_ACK_PENDING; 34962306a36Sopenharmony_ci ps->s_txreq->txreq.flags |= SDMA_TXREQ_F_VIP; 35062306a36Sopenharmony_ci ps->s_txreq->ss = NULL; 35162306a36Sopenharmony_ci } 35262306a36Sopenharmony_ci qp->s_rdma_ack_cnt++; 35362306a36Sopenharmony_ci ps->s_txreq->sde = qpriv->s_sde; 35462306a36Sopenharmony_ci ps->s_txreq->s_cur_size = len; 35562306a36Sopenharmony_ci ps->s_txreq->hdr_dwords = hwords; 35662306a36Sopenharmony_ci hfi1_make_ruc_header(qp, ohdr, bth0, bth1, bth2, middle, ps); 35762306a36Sopenharmony_ci return 1; 35862306a36Sopenharmony_cierror_qp: 35962306a36Sopenharmony_ci spin_unlock_irqrestore(&qp->s_lock, ps->flags); 36062306a36Sopenharmony_ci spin_lock_irqsave(&qp->r_lock, ps->flags); 36162306a36Sopenharmony_ci spin_lock(&qp->s_lock); 36262306a36Sopenharmony_ci rvt_error_qp(qp, IB_WC_WR_FLUSH_ERR); 36362306a36Sopenharmony_ci spin_unlock(&qp->s_lock); 36462306a36Sopenharmony_ci spin_unlock_irqrestore(&qp->r_lock, ps->flags); 36562306a36Sopenharmony_ci spin_lock_irqsave(&qp->s_lock, ps->flags); 36662306a36Sopenharmony_cibail: 36762306a36Sopenharmony_ci qp->s_ack_state = OP(ACKNOWLEDGE); 36862306a36Sopenharmony_ci /* 36962306a36Sopenharmony_ci * Ensure s_rdma_ack_cnt changes are committed prior to resetting 37062306a36Sopenharmony_ci * RVT_S_RESP_PENDING 37162306a36Sopenharmony_ci */ 37262306a36Sopenharmony_ci smp_wmb(); 37362306a36Sopenharmony_ci qp->s_flags &= ~(RVT_S_RESP_PENDING 37462306a36Sopenharmony_ci | RVT_S_ACK_PENDING 37562306a36Sopenharmony_ci | HFI1_S_AHG_VALID); 37662306a36Sopenharmony_ci return 0; 37762306a36Sopenharmony_ci} 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci/** 38062306a36Sopenharmony_ci * hfi1_make_rc_req - construct a request packet (SEND, RDMA r/w, ATOMIC) 38162306a36Sopenharmony_ci * @qp: a pointer to the QP 38262306a36Sopenharmony_ci * @ps: the current packet state 38362306a36Sopenharmony_ci * 38462306a36Sopenharmony_ci * Assumes s_lock is held. 38562306a36Sopenharmony_ci * 38662306a36Sopenharmony_ci * Return 1 if constructed; otherwise, return 0. 38762306a36Sopenharmony_ci */ 38862306a36Sopenharmony_ciint hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps) 38962306a36Sopenharmony_ci{ 39062306a36Sopenharmony_ci struct hfi1_qp_priv *priv = qp->priv; 39162306a36Sopenharmony_ci struct hfi1_ibdev *dev = to_idev(qp->ibqp.device); 39262306a36Sopenharmony_ci struct ib_other_headers *ohdr; 39362306a36Sopenharmony_ci struct rvt_sge_state *ss = NULL; 39462306a36Sopenharmony_ci struct rvt_swqe *wqe; 39562306a36Sopenharmony_ci struct hfi1_swqe_priv *wpriv; 39662306a36Sopenharmony_ci struct tid_rdma_request *req = NULL; 39762306a36Sopenharmony_ci /* header size in 32-bit words LRH+BTH = (8+12)/4. */ 39862306a36Sopenharmony_ci u32 hwords = 5; 39962306a36Sopenharmony_ci u32 len = 0; 40062306a36Sopenharmony_ci u32 bth0 = 0, bth2 = 0; 40162306a36Sopenharmony_ci u32 bth1 = qp->remote_qpn | (HFI1_CAP_IS_KSET(OPFN) << IB_BTHE_E_SHIFT); 40262306a36Sopenharmony_ci u32 pmtu = qp->pmtu; 40362306a36Sopenharmony_ci char newreq; 40462306a36Sopenharmony_ci int middle = 0; 40562306a36Sopenharmony_ci int delta; 40662306a36Sopenharmony_ci struct tid_rdma_flow *flow = NULL; 40762306a36Sopenharmony_ci struct tid_rdma_params *remote; 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci trace_hfi1_sender_make_rc_req(qp); 41062306a36Sopenharmony_ci lockdep_assert_held(&qp->s_lock); 41162306a36Sopenharmony_ci ps->s_txreq = get_txreq(ps->dev, qp); 41262306a36Sopenharmony_ci if (!ps->s_txreq) 41362306a36Sopenharmony_ci goto bail_no_tx; 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_ci if (priv->hdr_type == HFI1_PKT_TYPE_9B) { 41662306a36Sopenharmony_ci /* header size in 32-bit words LRH+BTH = (8+12)/4. */ 41762306a36Sopenharmony_ci hwords = 5; 41862306a36Sopenharmony_ci if (rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH) 41962306a36Sopenharmony_ci ohdr = &ps->s_txreq->phdr.hdr.ibh.u.l.oth; 42062306a36Sopenharmony_ci else 42162306a36Sopenharmony_ci ohdr = &ps->s_txreq->phdr.hdr.ibh.u.oth; 42262306a36Sopenharmony_ci } else { 42362306a36Sopenharmony_ci /* header size in 32-bit words 16B LRH+BTH = (16+12)/4. */ 42462306a36Sopenharmony_ci hwords = 7; 42562306a36Sopenharmony_ci if ((rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH) && 42662306a36Sopenharmony_ci (hfi1_check_mcast(rdma_ah_get_dlid(&qp->remote_ah_attr)))) 42762306a36Sopenharmony_ci ohdr = &ps->s_txreq->phdr.hdr.opah.u.l.oth; 42862306a36Sopenharmony_ci else 42962306a36Sopenharmony_ci ohdr = &ps->s_txreq->phdr.hdr.opah.u.oth; 43062306a36Sopenharmony_ci } 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ci /* Sending responses has higher priority over sending requests. */ 43362306a36Sopenharmony_ci if ((qp->s_flags & RVT_S_RESP_PENDING) && 43462306a36Sopenharmony_ci make_rc_ack(dev, qp, ohdr, ps)) 43562306a36Sopenharmony_ci return 1; 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_ci if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_SEND_OK)) { 43862306a36Sopenharmony_ci if (!(ib_rvt_state_ops[qp->state] & RVT_FLUSH_SEND)) 43962306a36Sopenharmony_ci goto bail; 44062306a36Sopenharmony_ci /* We are in the error state, flush the work request. */ 44162306a36Sopenharmony_ci if (qp->s_last == READ_ONCE(qp->s_head)) 44262306a36Sopenharmony_ci goto bail; 44362306a36Sopenharmony_ci /* If DMAs are in progress, we can't flush immediately. */ 44462306a36Sopenharmony_ci if (iowait_sdma_pending(&priv->s_iowait)) { 44562306a36Sopenharmony_ci qp->s_flags |= RVT_S_WAIT_DMA; 44662306a36Sopenharmony_ci goto bail; 44762306a36Sopenharmony_ci } 44862306a36Sopenharmony_ci clear_ahg(qp); 44962306a36Sopenharmony_ci wqe = rvt_get_swqe_ptr(qp, qp->s_last); 45062306a36Sopenharmony_ci hfi1_trdma_send_complete(qp, wqe, qp->s_last != qp->s_acked ? 45162306a36Sopenharmony_ci IB_WC_SUCCESS : IB_WC_WR_FLUSH_ERR); 45262306a36Sopenharmony_ci /* will get called again */ 45362306a36Sopenharmony_ci goto done_free_tx; 45462306a36Sopenharmony_ci } 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ci if (qp->s_flags & (RVT_S_WAIT_RNR | RVT_S_WAIT_ACK | HFI1_S_WAIT_HALT)) 45762306a36Sopenharmony_ci goto bail; 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci if (cmp_psn(qp->s_psn, qp->s_sending_hpsn) <= 0) { 46062306a36Sopenharmony_ci if (cmp_psn(qp->s_sending_psn, qp->s_sending_hpsn) <= 0) { 46162306a36Sopenharmony_ci qp->s_flags |= RVT_S_WAIT_PSN; 46262306a36Sopenharmony_ci goto bail; 46362306a36Sopenharmony_ci } 46462306a36Sopenharmony_ci qp->s_sending_psn = qp->s_psn; 46562306a36Sopenharmony_ci qp->s_sending_hpsn = qp->s_psn - 1; 46662306a36Sopenharmony_ci } 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ci /* Send a request. */ 46962306a36Sopenharmony_ci wqe = rvt_get_swqe_ptr(qp, qp->s_cur); 47062306a36Sopenharmony_cicheck_s_state: 47162306a36Sopenharmony_ci switch (qp->s_state) { 47262306a36Sopenharmony_ci default: 47362306a36Sopenharmony_ci if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_NEXT_SEND_OK)) 47462306a36Sopenharmony_ci goto bail; 47562306a36Sopenharmony_ci /* 47662306a36Sopenharmony_ci * Resend an old request or start a new one. 47762306a36Sopenharmony_ci * 47862306a36Sopenharmony_ci * We keep track of the current SWQE so that 47962306a36Sopenharmony_ci * we don't reset the "furthest progress" state 48062306a36Sopenharmony_ci * if we need to back up. 48162306a36Sopenharmony_ci */ 48262306a36Sopenharmony_ci newreq = 0; 48362306a36Sopenharmony_ci if (qp->s_cur == qp->s_tail) { 48462306a36Sopenharmony_ci /* Check if send work queue is empty. */ 48562306a36Sopenharmony_ci if (qp->s_tail == READ_ONCE(qp->s_head)) { 48662306a36Sopenharmony_ci clear_ahg(qp); 48762306a36Sopenharmony_ci goto bail; 48862306a36Sopenharmony_ci } 48962306a36Sopenharmony_ci /* 49062306a36Sopenharmony_ci * If a fence is requested, wait for previous 49162306a36Sopenharmony_ci * RDMA read and atomic operations to finish. 49262306a36Sopenharmony_ci * However, there is no need to guard against 49362306a36Sopenharmony_ci * TID RDMA READ after TID RDMA READ. 49462306a36Sopenharmony_ci */ 49562306a36Sopenharmony_ci if ((wqe->wr.send_flags & IB_SEND_FENCE) && 49662306a36Sopenharmony_ci qp->s_num_rd_atomic && 49762306a36Sopenharmony_ci (wqe->wr.opcode != IB_WR_TID_RDMA_READ || 49862306a36Sopenharmony_ci priv->pending_tid_r_segs < qp->s_num_rd_atomic)) { 49962306a36Sopenharmony_ci qp->s_flags |= RVT_S_WAIT_FENCE; 50062306a36Sopenharmony_ci goto bail; 50162306a36Sopenharmony_ci } 50262306a36Sopenharmony_ci /* 50362306a36Sopenharmony_ci * Local operations are processed immediately 50462306a36Sopenharmony_ci * after all prior requests have completed 50562306a36Sopenharmony_ci */ 50662306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_REG_MR || 50762306a36Sopenharmony_ci wqe->wr.opcode == IB_WR_LOCAL_INV) { 50862306a36Sopenharmony_ci int local_ops = 0; 50962306a36Sopenharmony_ci int err = 0; 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci if (qp->s_last != qp->s_cur) 51262306a36Sopenharmony_ci goto bail; 51362306a36Sopenharmony_ci if (++qp->s_cur == qp->s_size) 51462306a36Sopenharmony_ci qp->s_cur = 0; 51562306a36Sopenharmony_ci if (++qp->s_tail == qp->s_size) 51662306a36Sopenharmony_ci qp->s_tail = 0; 51762306a36Sopenharmony_ci if (!(wqe->wr.send_flags & 51862306a36Sopenharmony_ci RVT_SEND_COMPLETION_ONLY)) { 51962306a36Sopenharmony_ci err = rvt_invalidate_rkey( 52062306a36Sopenharmony_ci qp, 52162306a36Sopenharmony_ci wqe->wr.ex.invalidate_rkey); 52262306a36Sopenharmony_ci local_ops = 1; 52362306a36Sopenharmony_ci } 52462306a36Sopenharmony_ci rvt_send_complete(qp, wqe, 52562306a36Sopenharmony_ci err ? IB_WC_LOC_PROT_ERR 52662306a36Sopenharmony_ci : IB_WC_SUCCESS); 52762306a36Sopenharmony_ci if (local_ops) 52862306a36Sopenharmony_ci atomic_dec(&qp->local_ops_pending); 52962306a36Sopenharmony_ci goto done_free_tx; 53062306a36Sopenharmony_ci } 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci newreq = 1; 53362306a36Sopenharmony_ci qp->s_psn = wqe->psn; 53462306a36Sopenharmony_ci } 53562306a36Sopenharmony_ci /* 53662306a36Sopenharmony_ci * Note that we have to be careful not to modify the 53762306a36Sopenharmony_ci * original work request since we may need to resend 53862306a36Sopenharmony_ci * it. 53962306a36Sopenharmony_ci */ 54062306a36Sopenharmony_ci len = wqe->length; 54162306a36Sopenharmony_ci ss = &qp->s_sge; 54262306a36Sopenharmony_ci bth2 = mask_psn(qp->s_psn); 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_ci /* 54562306a36Sopenharmony_ci * Interlock between various IB requests and TID RDMA 54662306a36Sopenharmony_ci * if necessary. 54762306a36Sopenharmony_ci */ 54862306a36Sopenharmony_ci if ((priv->s_flags & HFI1_S_TID_WAIT_INTERLCK) || 54962306a36Sopenharmony_ci hfi1_tid_rdma_wqe_interlock(qp, wqe)) 55062306a36Sopenharmony_ci goto bail; 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci switch (wqe->wr.opcode) { 55362306a36Sopenharmony_ci case IB_WR_SEND: 55462306a36Sopenharmony_ci case IB_WR_SEND_WITH_IMM: 55562306a36Sopenharmony_ci case IB_WR_SEND_WITH_INV: 55662306a36Sopenharmony_ci /* If no credit, return. */ 55762306a36Sopenharmony_ci if (!rvt_rc_credit_avail(qp, wqe)) 55862306a36Sopenharmony_ci goto bail; 55962306a36Sopenharmony_ci if (len > pmtu) { 56062306a36Sopenharmony_ci qp->s_state = OP(SEND_FIRST); 56162306a36Sopenharmony_ci len = pmtu; 56262306a36Sopenharmony_ci break; 56362306a36Sopenharmony_ci } 56462306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_SEND) { 56562306a36Sopenharmony_ci qp->s_state = OP(SEND_ONLY); 56662306a36Sopenharmony_ci } else if (wqe->wr.opcode == IB_WR_SEND_WITH_IMM) { 56762306a36Sopenharmony_ci qp->s_state = OP(SEND_ONLY_WITH_IMMEDIATE); 56862306a36Sopenharmony_ci /* Immediate data comes after the BTH */ 56962306a36Sopenharmony_ci ohdr->u.imm_data = wqe->wr.ex.imm_data; 57062306a36Sopenharmony_ci hwords += 1; 57162306a36Sopenharmony_ci } else { 57262306a36Sopenharmony_ci qp->s_state = OP(SEND_ONLY_WITH_INVALIDATE); 57362306a36Sopenharmony_ci /* Invalidate rkey comes after the BTH */ 57462306a36Sopenharmony_ci ohdr->u.ieth = cpu_to_be32( 57562306a36Sopenharmony_ci wqe->wr.ex.invalidate_rkey); 57662306a36Sopenharmony_ci hwords += 1; 57762306a36Sopenharmony_ci } 57862306a36Sopenharmony_ci if (wqe->wr.send_flags & IB_SEND_SOLICITED) 57962306a36Sopenharmony_ci bth0 |= IB_BTH_SOLICITED; 58062306a36Sopenharmony_ci bth2 |= IB_BTH_REQ_ACK; 58162306a36Sopenharmony_ci if (++qp->s_cur == qp->s_size) 58262306a36Sopenharmony_ci qp->s_cur = 0; 58362306a36Sopenharmony_ci break; 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_ci case IB_WR_RDMA_WRITE: 58662306a36Sopenharmony_ci if (newreq && !(qp->s_flags & RVT_S_UNLIMITED_CREDIT)) 58762306a36Sopenharmony_ci qp->s_lsn++; 58862306a36Sopenharmony_ci goto no_flow_control; 58962306a36Sopenharmony_ci case IB_WR_RDMA_WRITE_WITH_IMM: 59062306a36Sopenharmony_ci /* If no credit, return. */ 59162306a36Sopenharmony_ci if (!rvt_rc_credit_avail(qp, wqe)) 59262306a36Sopenharmony_ci goto bail; 59362306a36Sopenharmony_cino_flow_control: 59462306a36Sopenharmony_ci put_ib_reth_vaddr( 59562306a36Sopenharmony_ci wqe->rdma_wr.remote_addr, 59662306a36Sopenharmony_ci &ohdr->u.rc.reth); 59762306a36Sopenharmony_ci ohdr->u.rc.reth.rkey = 59862306a36Sopenharmony_ci cpu_to_be32(wqe->rdma_wr.rkey); 59962306a36Sopenharmony_ci ohdr->u.rc.reth.length = cpu_to_be32(len); 60062306a36Sopenharmony_ci hwords += sizeof(struct ib_reth) / sizeof(u32); 60162306a36Sopenharmony_ci if (len > pmtu) { 60262306a36Sopenharmony_ci qp->s_state = OP(RDMA_WRITE_FIRST); 60362306a36Sopenharmony_ci len = pmtu; 60462306a36Sopenharmony_ci break; 60562306a36Sopenharmony_ci } 60662306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_RDMA_WRITE) { 60762306a36Sopenharmony_ci qp->s_state = OP(RDMA_WRITE_ONLY); 60862306a36Sopenharmony_ci } else { 60962306a36Sopenharmony_ci qp->s_state = 61062306a36Sopenharmony_ci OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE); 61162306a36Sopenharmony_ci /* Immediate data comes after RETH */ 61262306a36Sopenharmony_ci ohdr->u.rc.imm_data = wqe->wr.ex.imm_data; 61362306a36Sopenharmony_ci hwords += 1; 61462306a36Sopenharmony_ci if (wqe->wr.send_flags & IB_SEND_SOLICITED) 61562306a36Sopenharmony_ci bth0 |= IB_BTH_SOLICITED; 61662306a36Sopenharmony_ci } 61762306a36Sopenharmony_ci bth2 |= IB_BTH_REQ_ACK; 61862306a36Sopenharmony_ci if (++qp->s_cur == qp->s_size) 61962306a36Sopenharmony_ci qp->s_cur = 0; 62062306a36Sopenharmony_ci break; 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_ci case IB_WR_TID_RDMA_WRITE: 62362306a36Sopenharmony_ci if (newreq) { 62462306a36Sopenharmony_ci /* 62562306a36Sopenharmony_ci * Limit the number of TID RDMA WRITE requests. 62662306a36Sopenharmony_ci */ 62762306a36Sopenharmony_ci if (atomic_read(&priv->n_tid_requests) >= 62862306a36Sopenharmony_ci HFI1_TID_RDMA_WRITE_CNT) 62962306a36Sopenharmony_ci goto bail; 63062306a36Sopenharmony_ci 63162306a36Sopenharmony_ci if (!(qp->s_flags & RVT_S_UNLIMITED_CREDIT)) 63262306a36Sopenharmony_ci qp->s_lsn++; 63362306a36Sopenharmony_ci } 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci hwords += hfi1_build_tid_rdma_write_req(qp, wqe, ohdr, 63662306a36Sopenharmony_ci &bth1, &bth2, 63762306a36Sopenharmony_ci &len); 63862306a36Sopenharmony_ci ss = NULL; 63962306a36Sopenharmony_ci if (priv->s_tid_cur == HFI1_QP_WQE_INVALID) { 64062306a36Sopenharmony_ci priv->s_tid_cur = qp->s_cur; 64162306a36Sopenharmony_ci if (priv->s_tid_tail == HFI1_QP_WQE_INVALID) { 64262306a36Sopenharmony_ci priv->s_tid_tail = qp->s_cur; 64362306a36Sopenharmony_ci priv->s_state = TID_OP(WRITE_RESP); 64462306a36Sopenharmony_ci } 64562306a36Sopenharmony_ci } else if (priv->s_tid_cur == priv->s_tid_head) { 64662306a36Sopenharmony_ci struct rvt_swqe *__w; 64762306a36Sopenharmony_ci struct tid_rdma_request *__r; 64862306a36Sopenharmony_ci 64962306a36Sopenharmony_ci __w = rvt_get_swqe_ptr(qp, priv->s_tid_cur); 65062306a36Sopenharmony_ci __r = wqe_to_tid_req(__w); 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_ci /* 65362306a36Sopenharmony_ci * The s_tid_cur pointer is advanced to s_cur if 65462306a36Sopenharmony_ci * any of the following conditions about the WQE 65562306a36Sopenharmony_ci * to which s_ti_cur currently points to are 65662306a36Sopenharmony_ci * satisfied: 65762306a36Sopenharmony_ci * 1. The request is not a TID RDMA WRITE 65862306a36Sopenharmony_ci * request, 65962306a36Sopenharmony_ci * 2. The request is in the INACTIVE or 66062306a36Sopenharmony_ci * COMPLETE states (TID RDMA READ requests 66162306a36Sopenharmony_ci * stay at INACTIVE and TID RDMA WRITE 66262306a36Sopenharmony_ci * transition to COMPLETE when done), 66362306a36Sopenharmony_ci * 3. The request is in the ACTIVE or SYNC 66462306a36Sopenharmony_ci * state and the number of completed 66562306a36Sopenharmony_ci * segments is equal to the total segment 66662306a36Sopenharmony_ci * count. 66762306a36Sopenharmony_ci * (If ACTIVE, the request is waiting for 66862306a36Sopenharmony_ci * ACKs. If SYNC, the request has not 66962306a36Sopenharmony_ci * received any responses because it's 67062306a36Sopenharmony_ci * waiting on a sync point.) 67162306a36Sopenharmony_ci */ 67262306a36Sopenharmony_ci if (__w->wr.opcode != IB_WR_TID_RDMA_WRITE || 67362306a36Sopenharmony_ci __r->state == TID_REQUEST_INACTIVE || 67462306a36Sopenharmony_ci __r->state == TID_REQUEST_COMPLETE || 67562306a36Sopenharmony_ci ((__r->state == TID_REQUEST_ACTIVE || 67662306a36Sopenharmony_ci __r->state == TID_REQUEST_SYNC) && 67762306a36Sopenharmony_ci __r->comp_seg == __r->total_segs)) { 67862306a36Sopenharmony_ci if (priv->s_tid_tail == 67962306a36Sopenharmony_ci priv->s_tid_cur && 68062306a36Sopenharmony_ci priv->s_state == 68162306a36Sopenharmony_ci TID_OP(WRITE_DATA_LAST)) { 68262306a36Sopenharmony_ci priv->s_tid_tail = qp->s_cur; 68362306a36Sopenharmony_ci priv->s_state = 68462306a36Sopenharmony_ci TID_OP(WRITE_RESP); 68562306a36Sopenharmony_ci } 68662306a36Sopenharmony_ci priv->s_tid_cur = qp->s_cur; 68762306a36Sopenharmony_ci } 68862306a36Sopenharmony_ci /* 68962306a36Sopenharmony_ci * A corner case: when the last TID RDMA WRITE 69062306a36Sopenharmony_ci * request was completed, s_tid_head, 69162306a36Sopenharmony_ci * s_tid_cur, and s_tid_tail all point to the 69262306a36Sopenharmony_ci * same location. Other requests are posted and 69362306a36Sopenharmony_ci * s_cur wraps around to the same location, 69462306a36Sopenharmony_ci * where a new TID RDMA WRITE is posted. In 69562306a36Sopenharmony_ci * this case, none of the indices need to be 69662306a36Sopenharmony_ci * updated. However, the priv->s_state should. 69762306a36Sopenharmony_ci */ 69862306a36Sopenharmony_ci if (priv->s_tid_tail == qp->s_cur && 69962306a36Sopenharmony_ci priv->s_state == TID_OP(WRITE_DATA_LAST)) 70062306a36Sopenharmony_ci priv->s_state = TID_OP(WRITE_RESP); 70162306a36Sopenharmony_ci } 70262306a36Sopenharmony_ci req = wqe_to_tid_req(wqe); 70362306a36Sopenharmony_ci if (newreq) { 70462306a36Sopenharmony_ci priv->s_tid_head = qp->s_cur; 70562306a36Sopenharmony_ci priv->pending_tid_w_resp += req->total_segs; 70662306a36Sopenharmony_ci atomic_inc(&priv->n_tid_requests); 70762306a36Sopenharmony_ci atomic_dec(&priv->n_requests); 70862306a36Sopenharmony_ci } else { 70962306a36Sopenharmony_ci req->state = TID_REQUEST_RESEND; 71062306a36Sopenharmony_ci req->comp_seg = delta_psn(bth2, wqe->psn); 71162306a36Sopenharmony_ci /* 71262306a36Sopenharmony_ci * Pull back any segments since we are going 71362306a36Sopenharmony_ci * to re-receive them. 71462306a36Sopenharmony_ci */ 71562306a36Sopenharmony_ci req->setup_head = req->clear_tail; 71662306a36Sopenharmony_ci priv->pending_tid_w_resp += 71762306a36Sopenharmony_ci delta_psn(wqe->lpsn, bth2) + 1; 71862306a36Sopenharmony_ci } 71962306a36Sopenharmony_ci 72062306a36Sopenharmony_ci trace_hfi1_tid_write_sender_make_req(qp, newreq); 72162306a36Sopenharmony_ci trace_hfi1_tid_req_make_req_write(qp, newreq, 72262306a36Sopenharmony_ci wqe->wr.opcode, 72362306a36Sopenharmony_ci wqe->psn, wqe->lpsn, 72462306a36Sopenharmony_ci req); 72562306a36Sopenharmony_ci if (++qp->s_cur == qp->s_size) 72662306a36Sopenharmony_ci qp->s_cur = 0; 72762306a36Sopenharmony_ci break; 72862306a36Sopenharmony_ci 72962306a36Sopenharmony_ci case IB_WR_RDMA_READ: 73062306a36Sopenharmony_ci /* 73162306a36Sopenharmony_ci * Don't allow more operations to be started 73262306a36Sopenharmony_ci * than the QP limits allow. 73362306a36Sopenharmony_ci */ 73462306a36Sopenharmony_ci if (qp->s_num_rd_atomic >= 73562306a36Sopenharmony_ci qp->s_max_rd_atomic) { 73662306a36Sopenharmony_ci qp->s_flags |= RVT_S_WAIT_RDMAR; 73762306a36Sopenharmony_ci goto bail; 73862306a36Sopenharmony_ci } 73962306a36Sopenharmony_ci qp->s_num_rd_atomic++; 74062306a36Sopenharmony_ci if (newreq && !(qp->s_flags & RVT_S_UNLIMITED_CREDIT)) 74162306a36Sopenharmony_ci qp->s_lsn++; 74262306a36Sopenharmony_ci put_ib_reth_vaddr( 74362306a36Sopenharmony_ci wqe->rdma_wr.remote_addr, 74462306a36Sopenharmony_ci &ohdr->u.rc.reth); 74562306a36Sopenharmony_ci ohdr->u.rc.reth.rkey = 74662306a36Sopenharmony_ci cpu_to_be32(wqe->rdma_wr.rkey); 74762306a36Sopenharmony_ci ohdr->u.rc.reth.length = cpu_to_be32(len); 74862306a36Sopenharmony_ci qp->s_state = OP(RDMA_READ_REQUEST); 74962306a36Sopenharmony_ci hwords += sizeof(ohdr->u.rc.reth) / sizeof(u32); 75062306a36Sopenharmony_ci ss = NULL; 75162306a36Sopenharmony_ci len = 0; 75262306a36Sopenharmony_ci bth2 |= IB_BTH_REQ_ACK; 75362306a36Sopenharmony_ci if (++qp->s_cur == qp->s_size) 75462306a36Sopenharmony_ci qp->s_cur = 0; 75562306a36Sopenharmony_ci break; 75662306a36Sopenharmony_ci 75762306a36Sopenharmony_ci case IB_WR_TID_RDMA_READ: 75862306a36Sopenharmony_ci trace_hfi1_tid_read_sender_make_req(qp, newreq); 75962306a36Sopenharmony_ci wpriv = wqe->priv; 76062306a36Sopenharmony_ci req = wqe_to_tid_req(wqe); 76162306a36Sopenharmony_ci trace_hfi1_tid_req_make_req_read(qp, newreq, 76262306a36Sopenharmony_ci wqe->wr.opcode, 76362306a36Sopenharmony_ci wqe->psn, wqe->lpsn, 76462306a36Sopenharmony_ci req); 76562306a36Sopenharmony_ci delta = cmp_psn(qp->s_psn, wqe->psn); 76662306a36Sopenharmony_ci 76762306a36Sopenharmony_ci /* 76862306a36Sopenharmony_ci * Don't allow more operations to be started 76962306a36Sopenharmony_ci * than the QP limits allow. We could get here under 77062306a36Sopenharmony_ci * three conditions; (1) It's a new request; (2) We are 77162306a36Sopenharmony_ci * sending the second or later segment of a request, 77262306a36Sopenharmony_ci * but the qp->s_state is set to OP(RDMA_READ_REQUEST) 77362306a36Sopenharmony_ci * when the last segment of a previous request is 77462306a36Sopenharmony_ci * received just before this; (3) We are re-sending a 77562306a36Sopenharmony_ci * request. 77662306a36Sopenharmony_ci */ 77762306a36Sopenharmony_ci if (qp->s_num_rd_atomic >= qp->s_max_rd_atomic) { 77862306a36Sopenharmony_ci qp->s_flags |= RVT_S_WAIT_RDMAR; 77962306a36Sopenharmony_ci goto bail; 78062306a36Sopenharmony_ci } 78162306a36Sopenharmony_ci if (newreq) { 78262306a36Sopenharmony_ci struct tid_rdma_flow *flow = 78362306a36Sopenharmony_ci &req->flows[req->setup_head]; 78462306a36Sopenharmony_ci 78562306a36Sopenharmony_ci /* 78662306a36Sopenharmony_ci * Set up s_sge as it is needed for TID 78762306a36Sopenharmony_ci * allocation. However, if the pages have been 78862306a36Sopenharmony_ci * walked and mapped, skip it. An earlier try 78962306a36Sopenharmony_ci * has failed to allocate the TID entries. 79062306a36Sopenharmony_ci */ 79162306a36Sopenharmony_ci if (!flow->npagesets) { 79262306a36Sopenharmony_ci qp->s_sge.sge = wqe->sg_list[0]; 79362306a36Sopenharmony_ci qp->s_sge.sg_list = wqe->sg_list + 1; 79462306a36Sopenharmony_ci qp->s_sge.num_sge = wqe->wr.num_sge; 79562306a36Sopenharmony_ci qp->s_sge.total_len = wqe->length; 79662306a36Sopenharmony_ci qp->s_len = wqe->length; 79762306a36Sopenharmony_ci req->isge = 0; 79862306a36Sopenharmony_ci req->clear_tail = req->setup_head; 79962306a36Sopenharmony_ci req->flow_idx = req->setup_head; 80062306a36Sopenharmony_ci req->state = TID_REQUEST_ACTIVE; 80162306a36Sopenharmony_ci } 80262306a36Sopenharmony_ci } else if (delta == 0) { 80362306a36Sopenharmony_ci /* Re-send a request */ 80462306a36Sopenharmony_ci req->cur_seg = 0; 80562306a36Sopenharmony_ci req->comp_seg = 0; 80662306a36Sopenharmony_ci req->ack_pending = 0; 80762306a36Sopenharmony_ci req->flow_idx = req->clear_tail; 80862306a36Sopenharmony_ci req->state = TID_REQUEST_RESEND; 80962306a36Sopenharmony_ci } 81062306a36Sopenharmony_ci req->s_next_psn = qp->s_psn; 81162306a36Sopenharmony_ci /* Read one segment at a time */ 81262306a36Sopenharmony_ci len = min_t(u32, req->seg_len, 81362306a36Sopenharmony_ci wqe->length - req->seg_len * req->cur_seg); 81462306a36Sopenharmony_ci delta = hfi1_build_tid_rdma_read_req(qp, wqe, ohdr, 81562306a36Sopenharmony_ci &bth1, &bth2, 81662306a36Sopenharmony_ci &len); 81762306a36Sopenharmony_ci if (delta <= 0) { 81862306a36Sopenharmony_ci /* Wait for TID space */ 81962306a36Sopenharmony_ci goto bail; 82062306a36Sopenharmony_ci } 82162306a36Sopenharmony_ci if (newreq && !(qp->s_flags & RVT_S_UNLIMITED_CREDIT)) 82262306a36Sopenharmony_ci qp->s_lsn++; 82362306a36Sopenharmony_ci hwords += delta; 82462306a36Sopenharmony_ci ss = &wpriv->ss; 82562306a36Sopenharmony_ci /* Check if this is the last segment */ 82662306a36Sopenharmony_ci if (req->cur_seg >= req->total_segs && 82762306a36Sopenharmony_ci ++qp->s_cur == qp->s_size) 82862306a36Sopenharmony_ci qp->s_cur = 0; 82962306a36Sopenharmony_ci break; 83062306a36Sopenharmony_ci 83162306a36Sopenharmony_ci case IB_WR_ATOMIC_CMP_AND_SWP: 83262306a36Sopenharmony_ci case IB_WR_ATOMIC_FETCH_AND_ADD: 83362306a36Sopenharmony_ci /* 83462306a36Sopenharmony_ci * Don't allow more operations to be started 83562306a36Sopenharmony_ci * than the QP limits allow. 83662306a36Sopenharmony_ci */ 83762306a36Sopenharmony_ci if (qp->s_num_rd_atomic >= 83862306a36Sopenharmony_ci qp->s_max_rd_atomic) { 83962306a36Sopenharmony_ci qp->s_flags |= RVT_S_WAIT_RDMAR; 84062306a36Sopenharmony_ci goto bail; 84162306a36Sopenharmony_ci } 84262306a36Sopenharmony_ci qp->s_num_rd_atomic++; 84362306a36Sopenharmony_ci fallthrough; 84462306a36Sopenharmony_ci case IB_WR_OPFN: 84562306a36Sopenharmony_ci if (newreq && !(qp->s_flags & RVT_S_UNLIMITED_CREDIT)) 84662306a36Sopenharmony_ci qp->s_lsn++; 84762306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP || 84862306a36Sopenharmony_ci wqe->wr.opcode == IB_WR_OPFN) { 84962306a36Sopenharmony_ci qp->s_state = OP(COMPARE_SWAP); 85062306a36Sopenharmony_ci put_ib_ateth_swap(wqe->atomic_wr.swap, 85162306a36Sopenharmony_ci &ohdr->u.atomic_eth); 85262306a36Sopenharmony_ci put_ib_ateth_compare(wqe->atomic_wr.compare_add, 85362306a36Sopenharmony_ci &ohdr->u.atomic_eth); 85462306a36Sopenharmony_ci } else { 85562306a36Sopenharmony_ci qp->s_state = OP(FETCH_ADD); 85662306a36Sopenharmony_ci put_ib_ateth_swap(wqe->atomic_wr.compare_add, 85762306a36Sopenharmony_ci &ohdr->u.atomic_eth); 85862306a36Sopenharmony_ci put_ib_ateth_compare(0, &ohdr->u.atomic_eth); 85962306a36Sopenharmony_ci } 86062306a36Sopenharmony_ci put_ib_ateth_vaddr(wqe->atomic_wr.remote_addr, 86162306a36Sopenharmony_ci &ohdr->u.atomic_eth); 86262306a36Sopenharmony_ci ohdr->u.atomic_eth.rkey = cpu_to_be32( 86362306a36Sopenharmony_ci wqe->atomic_wr.rkey); 86462306a36Sopenharmony_ci hwords += sizeof(struct ib_atomic_eth) / sizeof(u32); 86562306a36Sopenharmony_ci ss = NULL; 86662306a36Sopenharmony_ci len = 0; 86762306a36Sopenharmony_ci bth2 |= IB_BTH_REQ_ACK; 86862306a36Sopenharmony_ci if (++qp->s_cur == qp->s_size) 86962306a36Sopenharmony_ci qp->s_cur = 0; 87062306a36Sopenharmony_ci break; 87162306a36Sopenharmony_ci 87262306a36Sopenharmony_ci default: 87362306a36Sopenharmony_ci goto bail; 87462306a36Sopenharmony_ci } 87562306a36Sopenharmony_ci if (wqe->wr.opcode != IB_WR_TID_RDMA_READ) { 87662306a36Sopenharmony_ci qp->s_sge.sge = wqe->sg_list[0]; 87762306a36Sopenharmony_ci qp->s_sge.sg_list = wqe->sg_list + 1; 87862306a36Sopenharmony_ci qp->s_sge.num_sge = wqe->wr.num_sge; 87962306a36Sopenharmony_ci qp->s_sge.total_len = wqe->length; 88062306a36Sopenharmony_ci qp->s_len = wqe->length; 88162306a36Sopenharmony_ci } 88262306a36Sopenharmony_ci if (newreq) { 88362306a36Sopenharmony_ci qp->s_tail++; 88462306a36Sopenharmony_ci if (qp->s_tail >= qp->s_size) 88562306a36Sopenharmony_ci qp->s_tail = 0; 88662306a36Sopenharmony_ci } 88762306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_RDMA_READ || 88862306a36Sopenharmony_ci wqe->wr.opcode == IB_WR_TID_RDMA_WRITE) 88962306a36Sopenharmony_ci qp->s_psn = wqe->lpsn + 1; 89062306a36Sopenharmony_ci else if (wqe->wr.opcode == IB_WR_TID_RDMA_READ) 89162306a36Sopenharmony_ci qp->s_psn = req->s_next_psn; 89262306a36Sopenharmony_ci else 89362306a36Sopenharmony_ci qp->s_psn++; 89462306a36Sopenharmony_ci break; 89562306a36Sopenharmony_ci 89662306a36Sopenharmony_ci case OP(RDMA_READ_RESPONSE_FIRST): 89762306a36Sopenharmony_ci /* 89862306a36Sopenharmony_ci * qp->s_state is normally set to the opcode of the 89962306a36Sopenharmony_ci * last packet constructed for new requests and therefore 90062306a36Sopenharmony_ci * is never set to RDMA read response. 90162306a36Sopenharmony_ci * RDMA_READ_RESPONSE_FIRST is used by the ACK processing 90262306a36Sopenharmony_ci * thread to indicate a SEND needs to be restarted from an 90362306a36Sopenharmony_ci * earlier PSN without interfering with the sending thread. 90462306a36Sopenharmony_ci * See restart_rc(). 90562306a36Sopenharmony_ci */ 90662306a36Sopenharmony_ci qp->s_len = restart_sge(&qp->s_sge, wqe, qp->s_psn, pmtu); 90762306a36Sopenharmony_ci fallthrough; 90862306a36Sopenharmony_ci case OP(SEND_FIRST): 90962306a36Sopenharmony_ci qp->s_state = OP(SEND_MIDDLE); 91062306a36Sopenharmony_ci fallthrough; 91162306a36Sopenharmony_ci case OP(SEND_MIDDLE): 91262306a36Sopenharmony_ci bth2 = mask_psn(qp->s_psn++); 91362306a36Sopenharmony_ci ss = &qp->s_sge; 91462306a36Sopenharmony_ci len = qp->s_len; 91562306a36Sopenharmony_ci if (len > pmtu) { 91662306a36Sopenharmony_ci len = pmtu; 91762306a36Sopenharmony_ci middle = HFI1_CAP_IS_KSET(SDMA_AHG); 91862306a36Sopenharmony_ci break; 91962306a36Sopenharmony_ci } 92062306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_SEND) { 92162306a36Sopenharmony_ci qp->s_state = OP(SEND_LAST); 92262306a36Sopenharmony_ci } else if (wqe->wr.opcode == IB_WR_SEND_WITH_IMM) { 92362306a36Sopenharmony_ci qp->s_state = OP(SEND_LAST_WITH_IMMEDIATE); 92462306a36Sopenharmony_ci /* Immediate data comes after the BTH */ 92562306a36Sopenharmony_ci ohdr->u.imm_data = wqe->wr.ex.imm_data; 92662306a36Sopenharmony_ci hwords += 1; 92762306a36Sopenharmony_ci } else { 92862306a36Sopenharmony_ci qp->s_state = OP(SEND_LAST_WITH_INVALIDATE); 92962306a36Sopenharmony_ci /* invalidate data comes after the BTH */ 93062306a36Sopenharmony_ci ohdr->u.ieth = cpu_to_be32(wqe->wr.ex.invalidate_rkey); 93162306a36Sopenharmony_ci hwords += 1; 93262306a36Sopenharmony_ci } 93362306a36Sopenharmony_ci if (wqe->wr.send_flags & IB_SEND_SOLICITED) 93462306a36Sopenharmony_ci bth0 |= IB_BTH_SOLICITED; 93562306a36Sopenharmony_ci bth2 |= IB_BTH_REQ_ACK; 93662306a36Sopenharmony_ci qp->s_cur++; 93762306a36Sopenharmony_ci if (qp->s_cur >= qp->s_size) 93862306a36Sopenharmony_ci qp->s_cur = 0; 93962306a36Sopenharmony_ci break; 94062306a36Sopenharmony_ci 94162306a36Sopenharmony_ci case OP(RDMA_READ_RESPONSE_LAST): 94262306a36Sopenharmony_ci /* 94362306a36Sopenharmony_ci * qp->s_state is normally set to the opcode of the 94462306a36Sopenharmony_ci * last packet constructed for new requests and therefore 94562306a36Sopenharmony_ci * is never set to RDMA read response. 94662306a36Sopenharmony_ci * RDMA_READ_RESPONSE_LAST is used by the ACK processing 94762306a36Sopenharmony_ci * thread to indicate a RDMA write needs to be restarted from 94862306a36Sopenharmony_ci * an earlier PSN without interfering with the sending thread. 94962306a36Sopenharmony_ci * See restart_rc(). 95062306a36Sopenharmony_ci */ 95162306a36Sopenharmony_ci qp->s_len = restart_sge(&qp->s_sge, wqe, qp->s_psn, pmtu); 95262306a36Sopenharmony_ci fallthrough; 95362306a36Sopenharmony_ci case OP(RDMA_WRITE_FIRST): 95462306a36Sopenharmony_ci qp->s_state = OP(RDMA_WRITE_MIDDLE); 95562306a36Sopenharmony_ci fallthrough; 95662306a36Sopenharmony_ci case OP(RDMA_WRITE_MIDDLE): 95762306a36Sopenharmony_ci bth2 = mask_psn(qp->s_psn++); 95862306a36Sopenharmony_ci ss = &qp->s_sge; 95962306a36Sopenharmony_ci len = qp->s_len; 96062306a36Sopenharmony_ci if (len > pmtu) { 96162306a36Sopenharmony_ci len = pmtu; 96262306a36Sopenharmony_ci middle = HFI1_CAP_IS_KSET(SDMA_AHG); 96362306a36Sopenharmony_ci break; 96462306a36Sopenharmony_ci } 96562306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_RDMA_WRITE) { 96662306a36Sopenharmony_ci qp->s_state = OP(RDMA_WRITE_LAST); 96762306a36Sopenharmony_ci } else { 96862306a36Sopenharmony_ci qp->s_state = OP(RDMA_WRITE_LAST_WITH_IMMEDIATE); 96962306a36Sopenharmony_ci /* Immediate data comes after the BTH */ 97062306a36Sopenharmony_ci ohdr->u.imm_data = wqe->wr.ex.imm_data; 97162306a36Sopenharmony_ci hwords += 1; 97262306a36Sopenharmony_ci if (wqe->wr.send_flags & IB_SEND_SOLICITED) 97362306a36Sopenharmony_ci bth0 |= IB_BTH_SOLICITED; 97462306a36Sopenharmony_ci } 97562306a36Sopenharmony_ci bth2 |= IB_BTH_REQ_ACK; 97662306a36Sopenharmony_ci qp->s_cur++; 97762306a36Sopenharmony_ci if (qp->s_cur >= qp->s_size) 97862306a36Sopenharmony_ci qp->s_cur = 0; 97962306a36Sopenharmony_ci break; 98062306a36Sopenharmony_ci 98162306a36Sopenharmony_ci case OP(RDMA_READ_RESPONSE_MIDDLE): 98262306a36Sopenharmony_ci /* 98362306a36Sopenharmony_ci * qp->s_state is normally set to the opcode of the 98462306a36Sopenharmony_ci * last packet constructed for new requests and therefore 98562306a36Sopenharmony_ci * is never set to RDMA read response. 98662306a36Sopenharmony_ci * RDMA_READ_RESPONSE_MIDDLE is used by the ACK processing 98762306a36Sopenharmony_ci * thread to indicate a RDMA read needs to be restarted from 98862306a36Sopenharmony_ci * an earlier PSN without interfering with the sending thread. 98962306a36Sopenharmony_ci * See restart_rc(). 99062306a36Sopenharmony_ci */ 99162306a36Sopenharmony_ci len = (delta_psn(qp->s_psn, wqe->psn)) * pmtu; 99262306a36Sopenharmony_ci put_ib_reth_vaddr( 99362306a36Sopenharmony_ci wqe->rdma_wr.remote_addr + len, 99462306a36Sopenharmony_ci &ohdr->u.rc.reth); 99562306a36Sopenharmony_ci ohdr->u.rc.reth.rkey = 99662306a36Sopenharmony_ci cpu_to_be32(wqe->rdma_wr.rkey); 99762306a36Sopenharmony_ci ohdr->u.rc.reth.length = cpu_to_be32(wqe->length - len); 99862306a36Sopenharmony_ci qp->s_state = OP(RDMA_READ_REQUEST); 99962306a36Sopenharmony_ci hwords += sizeof(ohdr->u.rc.reth) / sizeof(u32); 100062306a36Sopenharmony_ci bth2 = mask_psn(qp->s_psn) | IB_BTH_REQ_ACK; 100162306a36Sopenharmony_ci qp->s_psn = wqe->lpsn + 1; 100262306a36Sopenharmony_ci ss = NULL; 100362306a36Sopenharmony_ci len = 0; 100462306a36Sopenharmony_ci qp->s_cur++; 100562306a36Sopenharmony_ci if (qp->s_cur == qp->s_size) 100662306a36Sopenharmony_ci qp->s_cur = 0; 100762306a36Sopenharmony_ci break; 100862306a36Sopenharmony_ci 100962306a36Sopenharmony_ci case TID_OP(WRITE_RESP): 101062306a36Sopenharmony_ci /* 101162306a36Sopenharmony_ci * This value for s_state is used for restarting a TID RDMA 101262306a36Sopenharmony_ci * WRITE request. See comment in OP(RDMA_READ_RESPONSE_MIDDLE 101362306a36Sopenharmony_ci * for more). 101462306a36Sopenharmony_ci */ 101562306a36Sopenharmony_ci req = wqe_to_tid_req(wqe); 101662306a36Sopenharmony_ci req->state = TID_REQUEST_RESEND; 101762306a36Sopenharmony_ci rcu_read_lock(); 101862306a36Sopenharmony_ci remote = rcu_dereference(priv->tid_rdma.remote); 101962306a36Sopenharmony_ci req->comp_seg = delta_psn(qp->s_psn, wqe->psn); 102062306a36Sopenharmony_ci len = wqe->length - (req->comp_seg * remote->max_len); 102162306a36Sopenharmony_ci rcu_read_unlock(); 102262306a36Sopenharmony_ci 102362306a36Sopenharmony_ci bth2 = mask_psn(qp->s_psn); 102462306a36Sopenharmony_ci hwords += hfi1_build_tid_rdma_write_req(qp, wqe, ohdr, &bth1, 102562306a36Sopenharmony_ci &bth2, &len); 102662306a36Sopenharmony_ci qp->s_psn = wqe->lpsn + 1; 102762306a36Sopenharmony_ci ss = NULL; 102862306a36Sopenharmony_ci qp->s_state = TID_OP(WRITE_REQ); 102962306a36Sopenharmony_ci priv->pending_tid_w_resp += delta_psn(wqe->lpsn, bth2) + 1; 103062306a36Sopenharmony_ci priv->s_tid_cur = qp->s_cur; 103162306a36Sopenharmony_ci if (++qp->s_cur == qp->s_size) 103262306a36Sopenharmony_ci qp->s_cur = 0; 103362306a36Sopenharmony_ci trace_hfi1_tid_req_make_req_write(qp, 0, wqe->wr.opcode, 103462306a36Sopenharmony_ci wqe->psn, wqe->lpsn, req); 103562306a36Sopenharmony_ci break; 103662306a36Sopenharmony_ci 103762306a36Sopenharmony_ci case TID_OP(READ_RESP): 103862306a36Sopenharmony_ci if (wqe->wr.opcode != IB_WR_TID_RDMA_READ) 103962306a36Sopenharmony_ci goto bail; 104062306a36Sopenharmony_ci /* This is used to restart a TID read request */ 104162306a36Sopenharmony_ci req = wqe_to_tid_req(wqe); 104262306a36Sopenharmony_ci wpriv = wqe->priv; 104362306a36Sopenharmony_ci /* 104462306a36Sopenharmony_ci * Back down. The field qp->s_psn has been set to the psn with 104562306a36Sopenharmony_ci * which the request should be restart. It's OK to use division 104662306a36Sopenharmony_ci * as this is on the retry path. 104762306a36Sopenharmony_ci */ 104862306a36Sopenharmony_ci req->cur_seg = delta_psn(qp->s_psn, wqe->psn) / priv->pkts_ps; 104962306a36Sopenharmony_ci 105062306a36Sopenharmony_ci /* 105162306a36Sopenharmony_ci * The following function need to be redefined to return the 105262306a36Sopenharmony_ci * status to make sure that we find the flow. At the same 105362306a36Sopenharmony_ci * time, we can use the req->state change to check if the 105462306a36Sopenharmony_ci * call succeeds or not. 105562306a36Sopenharmony_ci */ 105662306a36Sopenharmony_ci req->state = TID_REQUEST_RESEND; 105762306a36Sopenharmony_ci hfi1_tid_rdma_restart_req(qp, wqe, &bth2); 105862306a36Sopenharmony_ci if (req->state != TID_REQUEST_ACTIVE) { 105962306a36Sopenharmony_ci /* 106062306a36Sopenharmony_ci * Failed to find the flow. Release all allocated tid 106162306a36Sopenharmony_ci * resources. 106262306a36Sopenharmony_ci */ 106362306a36Sopenharmony_ci hfi1_kern_exp_rcv_clear_all(req); 106462306a36Sopenharmony_ci hfi1_kern_clear_hw_flow(priv->rcd, qp); 106562306a36Sopenharmony_ci 106662306a36Sopenharmony_ci hfi1_trdma_send_complete(qp, wqe, IB_WC_LOC_QP_OP_ERR); 106762306a36Sopenharmony_ci goto bail; 106862306a36Sopenharmony_ci } 106962306a36Sopenharmony_ci req->state = TID_REQUEST_RESEND; 107062306a36Sopenharmony_ci len = min_t(u32, req->seg_len, 107162306a36Sopenharmony_ci wqe->length - req->seg_len * req->cur_seg); 107262306a36Sopenharmony_ci flow = &req->flows[req->flow_idx]; 107362306a36Sopenharmony_ci len -= flow->sent; 107462306a36Sopenharmony_ci req->s_next_psn = flow->flow_state.ib_lpsn + 1; 107562306a36Sopenharmony_ci delta = hfi1_build_tid_rdma_read_packet(wqe, ohdr, &bth1, 107662306a36Sopenharmony_ci &bth2, &len); 107762306a36Sopenharmony_ci if (delta <= 0) { 107862306a36Sopenharmony_ci /* Wait for TID space */ 107962306a36Sopenharmony_ci goto bail; 108062306a36Sopenharmony_ci } 108162306a36Sopenharmony_ci hwords += delta; 108262306a36Sopenharmony_ci ss = &wpriv->ss; 108362306a36Sopenharmony_ci /* Check if this is the last segment */ 108462306a36Sopenharmony_ci if (req->cur_seg >= req->total_segs && 108562306a36Sopenharmony_ci ++qp->s_cur == qp->s_size) 108662306a36Sopenharmony_ci qp->s_cur = 0; 108762306a36Sopenharmony_ci qp->s_psn = req->s_next_psn; 108862306a36Sopenharmony_ci trace_hfi1_tid_req_make_req_read(qp, 0, wqe->wr.opcode, 108962306a36Sopenharmony_ci wqe->psn, wqe->lpsn, req); 109062306a36Sopenharmony_ci break; 109162306a36Sopenharmony_ci case TID_OP(READ_REQ): 109262306a36Sopenharmony_ci req = wqe_to_tid_req(wqe); 109362306a36Sopenharmony_ci delta = cmp_psn(qp->s_psn, wqe->psn); 109462306a36Sopenharmony_ci /* 109562306a36Sopenharmony_ci * If the current WR is not TID RDMA READ, or this is the start 109662306a36Sopenharmony_ci * of a new request, we need to change the qp->s_state so that 109762306a36Sopenharmony_ci * the request can be set up properly. 109862306a36Sopenharmony_ci */ 109962306a36Sopenharmony_ci if (wqe->wr.opcode != IB_WR_TID_RDMA_READ || delta == 0 || 110062306a36Sopenharmony_ci qp->s_cur == qp->s_tail) { 110162306a36Sopenharmony_ci qp->s_state = OP(RDMA_READ_REQUEST); 110262306a36Sopenharmony_ci if (delta == 0 || qp->s_cur == qp->s_tail) 110362306a36Sopenharmony_ci goto check_s_state; 110462306a36Sopenharmony_ci else 110562306a36Sopenharmony_ci goto bail; 110662306a36Sopenharmony_ci } 110762306a36Sopenharmony_ci 110862306a36Sopenharmony_ci /* Rate limiting */ 110962306a36Sopenharmony_ci if (qp->s_num_rd_atomic >= qp->s_max_rd_atomic) { 111062306a36Sopenharmony_ci qp->s_flags |= RVT_S_WAIT_RDMAR; 111162306a36Sopenharmony_ci goto bail; 111262306a36Sopenharmony_ci } 111362306a36Sopenharmony_ci 111462306a36Sopenharmony_ci wpriv = wqe->priv; 111562306a36Sopenharmony_ci /* Read one segment at a time */ 111662306a36Sopenharmony_ci len = min_t(u32, req->seg_len, 111762306a36Sopenharmony_ci wqe->length - req->seg_len * req->cur_seg); 111862306a36Sopenharmony_ci delta = hfi1_build_tid_rdma_read_req(qp, wqe, ohdr, &bth1, 111962306a36Sopenharmony_ci &bth2, &len); 112062306a36Sopenharmony_ci if (delta <= 0) { 112162306a36Sopenharmony_ci /* Wait for TID space */ 112262306a36Sopenharmony_ci goto bail; 112362306a36Sopenharmony_ci } 112462306a36Sopenharmony_ci hwords += delta; 112562306a36Sopenharmony_ci ss = &wpriv->ss; 112662306a36Sopenharmony_ci /* Check if this is the last segment */ 112762306a36Sopenharmony_ci if (req->cur_seg >= req->total_segs && 112862306a36Sopenharmony_ci ++qp->s_cur == qp->s_size) 112962306a36Sopenharmony_ci qp->s_cur = 0; 113062306a36Sopenharmony_ci qp->s_psn = req->s_next_psn; 113162306a36Sopenharmony_ci trace_hfi1_tid_req_make_req_read(qp, 0, wqe->wr.opcode, 113262306a36Sopenharmony_ci wqe->psn, wqe->lpsn, req); 113362306a36Sopenharmony_ci break; 113462306a36Sopenharmony_ci } 113562306a36Sopenharmony_ci qp->s_sending_hpsn = bth2; 113662306a36Sopenharmony_ci delta = delta_psn(bth2, wqe->psn); 113762306a36Sopenharmony_ci if (delta && delta % HFI1_PSN_CREDIT == 0 && 113862306a36Sopenharmony_ci wqe->wr.opcode != IB_WR_TID_RDMA_WRITE) 113962306a36Sopenharmony_ci bth2 |= IB_BTH_REQ_ACK; 114062306a36Sopenharmony_ci if (qp->s_flags & RVT_S_SEND_ONE) { 114162306a36Sopenharmony_ci qp->s_flags &= ~RVT_S_SEND_ONE; 114262306a36Sopenharmony_ci qp->s_flags |= RVT_S_WAIT_ACK; 114362306a36Sopenharmony_ci bth2 |= IB_BTH_REQ_ACK; 114462306a36Sopenharmony_ci } 114562306a36Sopenharmony_ci qp->s_len -= len; 114662306a36Sopenharmony_ci ps->s_txreq->hdr_dwords = hwords; 114762306a36Sopenharmony_ci ps->s_txreq->sde = priv->s_sde; 114862306a36Sopenharmony_ci ps->s_txreq->ss = ss; 114962306a36Sopenharmony_ci ps->s_txreq->s_cur_size = len; 115062306a36Sopenharmony_ci hfi1_make_ruc_header( 115162306a36Sopenharmony_ci qp, 115262306a36Sopenharmony_ci ohdr, 115362306a36Sopenharmony_ci bth0 | (qp->s_state << 24), 115462306a36Sopenharmony_ci bth1, 115562306a36Sopenharmony_ci bth2, 115662306a36Sopenharmony_ci middle, 115762306a36Sopenharmony_ci ps); 115862306a36Sopenharmony_ci return 1; 115962306a36Sopenharmony_ci 116062306a36Sopenharmony_cidone_free_tx: 116162306a36Sopenharmony_ci hfi1_put_txreq(ps->s_txreq); 116262306a36Sopenharmony_ci ps->s_txreq = NULL; 116362306a36Sopenharmony_ci return 1; 116462306a36Sopenharmony_ci 116562306a36Sopenharmony_cibail: 116662306a36Sopenharmony_ci hfi1_put_txreq(ps->s_txreq); 116762306a36Sopenharmony_ci 116862306a36Sopenharmony_cibail_no_tx: 116962306a36Sopenharmony_ci ps->s_txreq = NULL; 117062306a36Sopenharmony_ci qp->s_flags &= ~RVT_S_BUSY; 117162306a36Sopenharmony_ci /* 117262306a36Sopenharmony_ci * If we didn't get a txreq, the QP will be woken up later to try 117362306a36Sopenharmony_ci * again. Set the flags to indicate which work item to wake 117462306a36Sopenharmony_ci * up. 117562306a36Sopenharmony_ci */ 117662306a36Sopenharmony_ci iowait_set_flag(&priv->s_iowait, IOWAIT_PENDING_IB); 117762306a36Sopenharmony_ci return 0; 117862306a36Sopenharmony_ci} 117962306a36Sopenharmony_ci 118062306a36Sopenharmony_cistatic inline void hfi1_make_bth_aeth(struct rvt_qp *qp, 118162306a36Sopenharmony_ci struct ib_other_headers *ohdr, 118262306a36Sopenharmony_ci u32 bth0, u32 bth1) 118362306a36Sopenharmony_ci{ 118462306a36Sopenharmony_ci if (qp->r_nak_state) 118562306a36Sopenharmony_ci ohdr->u.aeth = cpu_to_be32((qp->r_msn & IB_MSN_MASK) | 118662306a36Sopenharmony_ci (qp->r_nak_state << 118762306a36Sopenharmony_ci IB_AETH_CREDIT_SHIFT)); 118862306a36Sopenharmony_ci else 118962306a36Sopenharmony_ci ohdr->u.aeth = rvt_compute_aeth(qp); 119062306a36Sopenharmony_ci 119162306a36Sopenharmony_ci ohdr->bth[0] = cpu_to_be32(bth0); 119262306a36Sopenharmony_ci ohdr->bth[1] = cpu_to_be32(bth1 | qp->remote_qpn); 119362306a36Sopenharmony_ci ohdr->bth[2] = cpu_to_be32(mask_psn(qp->r_ack_psn)); 119462306a36Sopenharmony_ci} 119562306a36Sopenharmony_ci 119662306a36Sopenharmony_cistatic inline void hfi1_queue_rc_ack(struct hfi1_packet *packet, bool is_fecn) 119762306a36Sopenharmony_ci{ 119862306a36Sopenharmony_ci struct rvt_qp *qp = packet->qp; 119962306a36Sopenharmony_ci struct hfi1_ibport *ibp; 120062306a36Sopenharmony_ci unsigned long flags; 120162306a36Sopenharmony_ci 120262306a36Sopenharmony_ci spin_lock_irqsave(&qp->s_lock, flags); 120362306a36Sopenharmony_ci if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK)) 120462306a36Sopenharmony_ci goto unlock; 120562306a36Sopenharmony_ci ibp = rcd_to_iport(packet->rcd); 120662306a36Sopenharmony_ci this_cpu_inc(*ibp->rvp.rc_qacks); 120762306a36Sopenharmony_ci qp->s_flags |= RVT_S_ACK_PENDING | RVT_S_RESP_PENDING; 120862306a36Sopenharmony_ci qp->s_nak_state = qp->r_nak_state; 120962306a36Sopenharmony_ci qp->s_ack_psn = qp->r_ack_psn; 121062306a36Sopenharmony_ci if (is_fecn) 121162306a36Sopenharmony_ci qp->s_flags |= RVT_S_ECN; 121262306a36Sopenharmony_ci 121362306a36Sopenharmony_ci /* Schedule the send tasklet. */ 121462306a36Sopenharmony_ci hfi1_schedule_send(qp); 121562306a36Sopenharmony_ciunlock: 121662306a36Sopenharmony_ci spin_unlock_irqrestore(&qp->s_lock, flags); 121762306a36Sopenharmony_ci} 121862306a36Sopenharmony_ci 121962306a36Sopenharmony_cistatic inline void hfi1_make_rc_ack_9B(struct hfi1_packet *packet, 122062306a36Sopenharmony_ci struct hfi1_opa_header *opa_hdr, 122162306a36Sopenharmony_ci u8 sc5, bool is_fecn, 122262306a36Sopenharmony_ci u64 *pbc_flags, u32 *hwords, 122362306a36Sopenharmony_ci u32 *nwords) 122462306a36Sopenharmony_ci{ 122562306a36Sopenharmony_ci struct rvt_qp *qp = packet->qp; 122662306a36Sopenharmony_ci struct hfi1_ibport *ibp = rcd_to_iport(packet->rcd); 122762306a36Sopenharmony_ci struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); 122862306a36Sopenharmony_ci struct ib_header *hdr = &opa_hdr->ibh; 122962306a36Sopenharmony_ci struct ib_other_headers *ohdr; 123062306a36Sopenharmony_ci u16 lrh0 = HFI1_LRH_BTH; 123162306a36Sopenharmony_ci u16 pkey; 123262306a36Sopenharmony_ci u32 bth0, bth1; 123362306a36Sopenharmony_ci 123462306a36Sopenharmony_ci opa_hdr->hdr_type = HFI1_PKT_TYPE_9B; 123562306a36Sopenharmony_ci ohdr = &hdr->u.oth; 123662306a36Sopenharmony_ci /* header size in 32-bit words LRH+BTH+AETH = (8+12+4)/4 */ 123762306a36Sopenharmony_ci *hwords = 6; 123862306a36Sopenharmony_ci 123962306a36Sopenharmony_ci if (unlikely(rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH)) { 124062306a36Sopenharmony_ci *hwords += hfi1_make_grh(ibp, &hdr->u.l.grh, 124162306a36Sopenharmony_ci rdma_ah_read_grh(&qp->remote_ah_attr), 124262306a36Sopenharmony_ci *hwords - 2, SIZE_OF_CRC); 124362306a36Sopenharmony_ci ohdr = &hdr->u.l.oth; 124462306a36Sopenharmony_ci lrh0 = HFI1_LRH_GRH; 124562306a36Sopenharmony_ci } 124662306a36Sopenharmony_ci /* set PBC_DC_INFO bit (aka SC[4]) in pbc_flags */ 124762306a36Sopenharmony_ci *pbc_flags |= ((!!(sc5 & 0x10)) << PBC_DC_INFO_SHIFT); 124862306a36Sopenharmony_ci 124962306a36Sopenharmony_ci /* read pkey_index w/o lock (its atomic) */ 125062306a36Sopenharmony_ci pkey = hfi1_get_pkey(ibp, qp->s_pkey_index); 125162306a36Sopenharmony_ci 125262306a36Sopenharmony_ci lrh0 |= (sc5 & IB_SC_MASK) << IB_SC_SHIFT | 125362306a36Sopenharmony_ci (rdma_ah_get_sl(&qp->remote_ah_attr) & IB_SL_MASK) << 125462306a36Sopenharmony_ci IB_SL_SHIFT; 125562306a36Sopenharmony_ci 125662306a36Sopenharmony_ci hfi1_make_ib_hdr(hdr, lrh0, *hwords + SIZE_OF_CRC, 125762306a36Sopenharmony_ci opa_get_lid(rdma_ah_get_dlid(&qp->remote_ah_attr), 9B), 125862306a36Sopenharmony_ci ppd->lid | rdma_ah_get_path_bits(&qp->remote_ah_attr)); 125962306a36Sopenharmony_ci 126062306a36Sopenharmony_ci bth0 = pkey | (OP(ACKNOWLEDGE) << 24); 126162306a36Sopenharmony_ci if (qp->s_mig_state == IB_MIG_MIGRATED) 126262306a36Sopenharmony_ci bth0 |= IB_BTH_MIG_REQ; 126362306a36Sopenharmony_ci bth1 = (!!is_fecn) << IB_BECN_SHIFT; 126462306a36Sopenharmony_ci /* 126562306a36Sopenharmony_ci * Inline ACKs go out without the use of the Verbs send engine, so 126662306a36Sopenharmony_ci * we need to set the STL Verbs Extended bit here 126762306a36Sopenharmony_ci */ 126862306a36Sopenharmony_ci bth1 |= HFI1_CAP_IS_KSET(OPFN) << IB_BTHE_E_SHIFT; 126962306a36Sopenharmony_ci hfi1_make_bth_aeth(qp, ohdr, bth0, bth1); 127062306a36Sopenharmony_ci} 127162306a36Sopenharmony_ci 127262306a36Sopenharmony_cistatic inline void hfi1_make_rc_ack_16B(struct hfi1_packet *packet, 127362306a36Sopenharmony_ci struct hfi1_opa_header *opa_hdr, 127462306a36Sopenharmony_ci u8 sc5, bool is_fecn, 127562306a36Sopenharmony_ci u64 *pbc_flags, u32 *hwords, 127662306a36Sopenharmony_ci u32 *nwords) 127762306a36Sopenharmony_ci{ 127862306a36Sopenharmony_ci struct rvt_qp *qp = packet->qp; 127962306a36Sopenharmony_ci struct hfi1_ibport *ibp = rcd_to_iport(packet->rcd); 128062306a36Sopenharmony_ci struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); 128162306a36Sopenharmony_ci struct hfi1_16b_header *hdr = &opa_hdr->opah; 128262306a36Sopenharmony_ci struct ib_other_headers *ohdr; 128362306a36Sopenharmony_ci u32 bth0, bth1 = 0; 128462306a36Sopenharmony_ci u16 len, pkey; 128562306a36Sopenharmony_ci bool becn = is_fecn; 128662306a36Sopenharmony_ci u8 l4 = OPA_16B_L4_IB_LOCAL; 128762306a36Sopenharmony_ci u8 extra_bytes; 128862306a36Sopenharmony_ci 128962306a36Sopenharmony_ci opa_hdr->hdr_type = HFI1_PKT_TYPE_16B; 129062306a36Sopenharmony_ci ohdr = &hdr->u.oth; 129162306a36Sopenharmony_ci /* header size in 32-bit words 16B LRH+BTH+AETH = (16+12+4)/4 */ 129262306a36Sopenharmony_ci *hwords = 8; 129362306a36Sopenharmony_ci extra_bytes = hfi1_get_16b_padding(*hwords << 2, 0); 129462306a36Sopenharmony_ci *nwords = SIZE_OF_CRC + ((extra_bytes + SIZE_OF_LT) >> 2); 129562306a36Sopenharmony_ci 129662306a36Sopenharmony_ci if (unlikely(rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH) && 129762306a36Sopenharmony_ci hfi1_check_mcast(rdma_ah_get_dlid(&qp->remote_ah_attr))) { 129862306a36Sopenharmony_ci *hwords += hfi1_make_grh(ibp, &hdr->u.l.grh, 129962306a36Sopenharmony_ci rdma_ah_read_grh(&qp->remote_ah_attr), 130062306a36Sopenharmony_ci *hwords - 4, *nwords); 130162306a36Sopenharmony_ci ohdr = &hdr->u.l.oth; 130262306a36Sopenharmony_ci l4 = OPA_16B_L4_IB_GLOBAL; 130362306a36Sopenharmony_ci } 130462306a36Sopenharmony_ci *pbc_flags |= PBC_PACKET_BYPASS | PBC_INSERT_BYPASS_ICRC; 130562306a36Sopenharmony_ci 130662306a36Sopenharmony_ci /* read pkey_index w/o lock (its atomic) */ 130762306a36Sopenharmony_ci pkey = hfi1_get_pkey(ibp, qp->s_pkey_index); 130862306a36Sopenharmony_ci 130962306a36Sopenharmony_ci /* Convert dwords to flits */ 131062306a36Sopenharmony_ci len = (*hwords + *nwords) >> 1; 131162306a36Sopenharmony_ci 131262306a36Sopenharmony_ci hfi1_make_16b_hdr(hdr, ppd->lid | 131362306a36Sopenharmony_ci (rdma_ah_get_path_bits(&qp->remote_ah_attr) & 131462306a36Sopenharmony_ci ((1 << ppd->lmc) - 1)), 131562306a36Sopenharmony_ci opa_get_lid(rdma_ah_get_dlid(&qp->remote_ah_attr), 131662306a36Sopenharmony_ci 16B), len, pkey, becn, 0, l4, sc5); 131762306a36Sopenharmony_ci 131862306a36Sopenharmony_ci bth0 = pkey | (OP(ACKNOWLEDGE) << 24); 131962306a36Sopenharmony_ci bth0 |= extra_bytes << 20; 132062306a36Sopenharmony_ci if (qp->s_mig_state == IB_MIG_MIGRATED) 132162306a36Sopenharmony_ci bth1 = OPA_BTH_MIG_REQ; 132262306a36Sopenharmony_ci hfi1_make_bth_aeth(qp, ohdr, bth0, bth1); 132362306a36Sopenharmony_ci} 132462306a36Sopenharmony_ci 132562306a36Sopenharmony_citypedef void (*hfi1_make_rc_ack)(struct hfi1_packet *packet, 132662306a36Sopenharmony_ci struct hfi1_opa_header *opa_hdr, 132762306a36Sopenharmony_ci u8 sc5, bool is_fecn, 132862306a36Sopenharmony_ci u64 *pbc_flags, u32 *hwords, 132962306a36Sopenharmony_ci u32 *nwords); 133062306a36Sopenharmony_ci 133162306a36Sopenharmony_ci/* We support only two types - 9B and 16B for now */ 133262306a36Sopenharmony_cistatic const hfi1_make_rc_ack hfi1_make_rc_ack_tbl[2] = { 133362306a36Sopenharmony_ci [HFI1_PKT_TYPE_9B] = &hfi1_make_rc_ack_9B, 133462306a36Sopenharmony_ci [HFI1_PKT_TYPE_16B] = &hfi1_make_rc_ack_16B 133562306a36Sopenharmony_ci}; 133662306a36Sopenharmony_ci 133762306a36Sopenharmony_ci/* 133862306a36Sopenharmony_ci * hfi1_send_rc_ack - Construct an ACK packet and send it 133962306a36Sopenharmony_ci * 134062306a36Sopenharmony_ci * This is called from hfi1_rc_rcv() and handle_receive_interrupt(). 134162306a36Sopenharmony_ci * Note that RDMA reads and atomics are handled in the 134262306a36Sopenharmony_ci * send side QP state and send engine. 134362306a36Sopenharmony_ci */ 134462306a36Sopenharmony_civoid hfi1_send_rc_ack(struct hfi1_packet *packet, bool is_fecn) 134562306a36Sopenharmony_ci{ 134662306a36Sopenharmony_ci struct hfi1_ctxtdata *rcd = packet->rcd; 134762306a36Sopenharmony_ci struct rvt_qp *qp = packet->qp; 134862306a36Sopenharmony_ci struct hfi1_ibport *ibp = rcd_to_iport(rcd); 134962306a36Sopenharmony_ci struct hfi1_qp_priv *priv = qp->priv; 135062306a36Sopenharmony_ci struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); 135162306a36Sopenharmony_ci u8 sc5 = ibp->sl_to_sc[rdma_ah_get_sl(&qp->remote_ah_attr)]; 135262306a36Sopenharmony_ci u64 pbc, pbc_flags = 0; 135362306a36Sopenharmony_ci u32 hwords = 0; 135462306a36Sopenharmony_ci u32 nwords = 0; 135562306a36Sopenharmony_ci u32 plen; 135662306a36Sopenharmony_ci struct pio_buf *pbuf; 135762306a36Sopenharmony_ci struct hfi1_opa_header opa_hdr; 135862306a36Sopenharmony_ci 135962306a36Sopenharmony_ci /* clear the defer count */ 136062306a36Sopenharmony_ci qp->r_adefered = 0; 136162306a36Sopenharmony_ci 136262306a36Sopenharmony_ci /* Don't send ACK or NAK if a RDMA read or atomic is pending. */ 136362306a36Sopenharmony_ci if (qp->s_flags & RVT_S_RESP_PENDING) { 136462306a36Sopenharmony_ci hfi1_queue_rc_ack(packet, is_fecn); 136562306a36Sopenharmony_ci return; 136662306a36Sopenharmony_ci } 136762306a36Sopenharmony_ci 136862306a36Sopenharmony_ci /* Ensure s_rdma_ack_cnt changes are committed */ 136962306a36Sopenharmony_ci if (qp->s_rdma_ack_cnt) { 137062306a36Sopenharmony_ci hfi1_queue_rc_ack(packet, is_fecn); 137162306a36Sopenharmony_ci return; 137262306a36Sopenharmony_ci } 137362306a36Sopenharmony_ci 137462306a36Sopenharmony_ci /* Don't try to send ACKs if the link isn't ACTIVE */ 137562306a36Sopenharmony_ci if (driver_lstate(ppd) != IB_PORT_ACTIVE) 137662306a36Sopenharmony_ci return; 137762306a36Sopenharmony_ci 137862306a36Sopenharmony_ci /* Make the appropriate header */ 137962306a36Sopenharmony_ci hfi1_make_rc_ack_tbl[priv->hdr_type](packet, &opa_hdr, sc5, is_fecn, 138062306a36Sopenharmony_ci &pbc_flags, &hwords, &nwords); 138162306a36Sopenharmony_ci 138262306a36Sopenharmony_ci plen = 2 /* PBC */ + hwords + nwords; 138362306a36Sopenharmony_ci pbc = create_pbc(ppd, pbc_flags, qp->srate_mbps, 138462306a36Sopenharmony_ci sc_to_vlt(ppd->dd, sc5), plen); 138562306a36Sopenharmony_ci pbuf = sc_buffer_alloc(rcd->sc, plen, NULL, NULL); 138662306a36Sopenharmony_ci if (IS_ERR_OR_NULL(pbuf)) { 138762306a36Sopenharmony_ci /* 138862306a36Sopenharmony_ci * We have no room to send at the moment. Pass 138962306a36Sopenharmony_ci * responsibility for sending the ACK to the send engine 139062306a36Sopenharmony_ci * so that when enough buffer space becomes available, 139162306a36Sopenharmony_ci * the ACK is sent ahead of other outgoing packets. 139262306a36Sopenharmony_ci */ 139362306a36Sopenharmony_ci hfi1_queue_rc_ack(packet, is_fecn); 139462306a36Sopenharmony_ci return; 139562306a36Sopenharmony_ci } 139662306a36Sopenharmony_ci trace_ack_output_ibhdr(dd_from_ibdev(qp->ibqp.device), 139762306a36Sopenharmony_ci &opa_hdr, ib_is_sc5(sc5)); 139862306a36Sopenharmony_ci 139962306a36Sopenharmony_ci /* write the pbc and data */ 140062306a36Sopenharmony_ci ppd->dd->pio_inline_send(ppd->dd, pbuf, pbc, 140162306a36Sopenharmony_ci (priv->hdr_type == HFI1_PKT_TYPE_9B ? 140262306a36Sopenharmony_ci (void *)&opa_hdr.ibh : 140362306a36Sopenharmony_ci (void *)&opa_hdr.opah), hwords); 140462306a36Sopenharmony_ci return; 140562306a36Sopenharmony_ci} 140662306a36Sopenharmony_ci 140762306a36Sopenharmony_ci/** 140862306a36Sopenharmony_ci * update_num_rd_atomic - update the qp->s_num_rd_atomic 140962306a36Sopenharmony_ci * @qp: the QP 141062306a36Sopenharmony_ci * @psn: the packet sequence number to restart at 141162306a36Sopenharmony_ci * @wqe: the wqe 141262306a36Sopenharmony_ci * 141362306a36Sopenharmony_ci * This is called from reset_psn() to update qp->s_num_rd_atomic 141462306a36Sopenharmony_ci * for the current wqe. 141562306a36Sopenharmony_ci * Called at interrupt level with the QP s_lock held. 141662306a36Sopenharmony_ci */ 141762306a36Sopenharmony_cistatic void update_num_rd_atomic(struct rvt_qp *qp, u32 psn, 141862306a36Sopenharmony_ci struct rvt_swqe *wqe) 141962306a36Sopenharmony_ci{ 142062306a36Sopenharmony_ci u32 opcode = wqe->wr.opcode; 142162306a36Sopenharmony_ci 142262306a36Sopenharmony_ci if (opcode == IB_WR_RDMA_READ || 142362306a36Sopenharmony_ci opcode == IB_WR_ATOMIC_CMP_AND_SWP || 142462306a36Sopenharmony_ci opcode == IB_WR_ATOMIC_FETCH_AND_ADD) { 142562306a36Sopenharmony_ci qp->s_num_rd_atomic++; 142662306a36Sopenharmony_ci } else if (opcode == IB_WR_TID_RDMA_READ) { 142762306a36Sopenharmony_ci struct tid_rdma_request *req = wqe_to_tid_req(wqe); 142862306a36Sopenharmony_ci struct hfi1_qp_priv *priv = qp->priv; 142962306a36Sopenharmony_ci 143062306a36Sopenharmony_ci if (cmp_psn(psn, wqe->lpsn) <= 0) { 143162306a36Sopenharmony_ci u32 cur_seg; 143262306a36Sopenharmony_ci 143362306a36Sopenharmony_ci cur_seg = (psn - wqe->psn) / priv->pkts_ps; 143462306a36Sopenharmony_ci req->ack_pending = cur_seg - req->comp_seg; 143562306a36Sopenharmony_ci priv->pending_tid_r_segs += req->ack_pending; 143662306a36Sopenharmony_ci qp->s_num_rd_atomic += req->ack_pending; 143762306a36Sopenharmony_ci trace_hfi1_tid_req_update_num_rd_atomic(qp, 0, 143862306a36Sopenharmony_ci wqe->wr.opcode, 143962306a36Sopenharmony_ci wqe->psn, 144062306a36Sopenharmony_ci wqe->lpsn, 144162306a36Sopenharmony_ci req); 144262306a36Sopenharmony_ci } else { 144362306a36Sopenharmony_ci priv->pending_tid_r_segs += req->total_segs; 144462306a36Sopenharmony_ci qp->s_num_rd_atomic += req->total_segs; 144562306a36Sopenharmony_ci } 144662306a36Sopenharmony_ci } 144762306a36Sopenharmony_ci} 144862306a36Sopenharmony_ci 144962306a36Sopenharmony_ci/** 145062306a36Sopenharmony_ci * reset_psn - reset the QP state to send starting from PSN 145162306a36Sopenharmony_ci * @qp: the QP 145262306a36Sopenharmony_ci * @psn: the packet sequence number to restart at 145362306a36Sopenharmony_ci * 145462306a36Sopenharmony_ci * This is called from hfi1_rc_rcv() to process an incoming RC ACK 145562306a36Sopenharmony_ci * for the given QP. 145662306a36Sopenharmony_ci * Called at interrupt level with the QP s_lock held. 145762306a36Sopenharmony_ci */ 145862306a36Sopenharmony_cistatic void reset_psn(struct rvt_qp *qp, u32 psn) 145962306a36Sopenharmony_ci{ 146062306a36Sopenharmony_ci u32 n = qp->s_acked; 146162306a36Sopenharmony_ci struct rvt_swqe *wqe = rvt_get_swqe_ptr(qp, n); 146262306a36Sopenharmony_ci u32 opcode; 146362306a36Sopenharmony_ci struct hfi1_qp_priv *priv = qp->priv; 146462306a36Sopenharmony_ci 146562306a36Sopenharmony_ci lockdep_assert_held(&qp->s_lock); 146662306a36Sopenharmony_ci qp->s_cur = n; 146762306a36Sopenharmony_ci priv->pending_tid_r_segs = 0; 146862306a36Sopenharmony_ci priv->pending_tid_w_resp = 0; 146962306a36Sopenharmony_ci qp->s_num_rd_atomic = 0; 147062306a36Sopenharmony_ci 147162306a36Sopenharmony_ci /* 147262306a36Sopenharmony_ci * If we are starting the request from the beginning, 147362306a36Sopenharmony_ci * let the normal send code handle initialization. 147462306a36Sopenharmony_ci */ 147562306a36Sopenharmony_ci if (cmp_psn(psn, wqe->psn) <= 0) { 147662306a36Sopenharmony_ci qp->s_state = OP(SEND_LAST); 147762306a36Sopenharmony_ci goto done; 147862306a36Sopenharmony_ci } 147962306a36Sopenharmony_ci update_num_rd_atomic(qp, psn, wqe); 148062306a36Sopenharmony_ci 148162306a36Sopenharmony_ci /* Find the work request opcode corresponding to the given PSN. */ 148262306a36Sopenharmony_ci for (;;) { 148362306a36Sopenharmony_ci int diff; 148462306a36Sopenharmony_ci 148562306a36Sopenharmony_ci if (++n == qp->s_size) 148662306a36Sopenharmony_ci n = 0; 148762306a36Sopenharmony_ci if (n == qp->s_tail) 148862306a36Sopenharmony_ci break; 148962306a36Sopenharmony_ci wqe = rvt_get_swqe_ptr(qp, n); 149062306a36Sopenharmony_ci diff = cmp_psn(psn, wqe->psn); 149162306a36Sopenharmony_ci if (diff < 0) { 149262306a36Sopenharmony_ci /* Point wqe back to the previous one*/ 149362306a36Sopenharmony_ci wqe = rvt_get_swqe_ptr(qp, qp->s_cur); 149462306a36Sopenharmony_ci break; 149562306a36Sopenharmony_ci } 149662306a36Sopenharmony_ci qp->s_cur = n; 149762306a36Sopenharmony_ci /* 149862306a36Sopenharmony_ci * If we are starting the request from the beginning, 149962306a36Sopenharmony_ci * let the normal send code handle initialization. 150062306a36Sopenharmony_ci */ 150162306a36Sopenharmony_ci if (diff == 0) { 150262306a36Sopenharmony_ci qp->s_state = OP(SEND_LAST); 150362306a36Sopenharmony_ci goto done; 150462306a36Sopenharmony_ci } 150562306a36Sopenharmony_ci 150662306a36Sopenharmony_ci update_num_rd_atomic(qp, psn, wqe); 150762306a36Sopenharmony_ci } 150862306a36Sopenharmony_ci opcode = wqe->wr.opcode; 150962306a36Sopenharmony_ci 151062306a36Sopenharmony_ci /* 151162306a36Sopenharmony_ci * Set the state to restart in the middle of a request. 151262306a36Sopenharmony_ci * Don't change the s_sge, s_cur_sge, or s_cur_size. 151362306a36Sopenharmony_ci * See hfi1_make_rc_req(). 151462306a36Sopenharmony_ci */ 151562306a36Sopenharmony_ci switch (opcode) { 151662306a36Sopenharmony_ci case IB_WR_SEND: 151762306a36Sopenharmony_ci case IB_WR_SEND_WITH_IMM: 151862306a36Sopenharmony_ci qp->s_state = OP(RDMA_READ_RESPONSE_FIRST); 151962306a36Sopenharmony_ci break; 152062306a36Sopenharmony_ci 152162306a36Sopenharmony_ci case IB_WR_RDMA_WRITE: 152262306a36Sopenharmony_ci case IB_WR_RDMA_WRITE_WITH_IMM: 152362306a36Sopenharmony_ci qp->s_state = OP(RDMA_READ_RESPONSE_LAST); 152462306a36Sopenharmony_ci break; 152562306a36Sopenharmony_ci 152662306a36Sopenharmony_ci case IB_WR_TID_RDMA_WRITE: 152762306a36Sopenharmony_ci qp->s_state = TID_OP(WRITE_RESP); 152862306a36Sopenharmony_ci break; 152962306a36Sopenharmony_ci 153062306a36Sopenharmony_ci case IB_WR_RDMA_READ: 153162306a36Sopenharmony_ci qp->s_state = OP(RDMA_READ_RESPONSE_MIDDLE); 153262306a36Sopenharmony_ci break; 153362306a36Sopenharmony_ci 153462306a36Sopenharmony_ci case IB_WR_TID_RDMA_READ: 153562306a36Sopenharmony_ci qp->s_state = TID_OP(READ_RESP); 153662306a36Sopenharmony_ci break; 153762306a36Sopenharmony_ci 153862306a36Sopenharmony_ci default: 153962306a36Sopenharmony_ci /* 154062306a36Sopenharmony_ci * This case shouldn't happen since its only 154162306a36Sopenharmony_ci * one PSN per req. 154262306a36Sopenharmony_ci */ 154362306a36Sopenharmony_ci qp->s_state = OP(SEND_LAST); 154462306a36Sopenharmony_ci } 154562306a36Sopenharmony_cidone: 154662306a36Sopenharmony_ci priv->s_flags &= ~HFI1_S_TID_WAIT_INTERLCK; 154762306a36Sopenharmony_ci qp->s_psn = psn; 154862306a36Sopenharmony_ci /* 154962306a36Sopenharmony_ci * Set RVT_S_WAIT_PSN as rc_complete() may start the timer 155062306a36Sopenharmony_ci * asynchronously before the send engine can get scheduled. 155162306a36Sopenharmony_ci * Doing it in hfi1_make_rc_req() is too late. 155262306a36Sopenharmony_ci */ 155362306a36Sopenharmony_ci if ((cmp_psn(qp->s_psn, qp->s_sending_hpsn) <= 0) && 155462306a36Sopenharmony_ci (cmp_psn(qp->s_sending_psn, qp->s_sending_hpsn) <= 0)) 155562306a36Sopenharmony_ci qp->s_flags |= RVT_S_WAIT_PSN; 155662306a36Sopenharmony_ci qp->s_flags &= ~HFI1_S_AHG_VALID; 155762306a36Sopenharmony_ci trace_hfi1_sender_reset_psn(qp); 155862306a36Sopenharmony_ci} 155962306a36Sopenharmony_ci 156062306a36Sopenharmony_ci/* 156162306a36Sopenharmony_ci * Back up requester to resend the last un-ACKed request. 156262306a36Sopenharmony_ci * The QP r_lock and s_lock should be held and interrupts disabled. 156362306a36Sopenharmony_ci */ 156462306a36Sopenharmony_civoid hfi1_restart_rc(struct rvt_qp *qp, u32 psn, int wait) 156562306a36Sopenharmony_ci{ 156662306a36Sopenharmony_ci struct hfi1_qp_priv *priv = qp->priv; 156762306a36Sopenharmony_ci struct rvt_swqe *wqe = rvt_get_swqe_ptr(qp, qp->s_acked); 156862306a36Sopenharmony_ci struct hfi1_ibport *ibp; 156962306a36Sopenharmony_ci 157062306a36Sopenharmony_ci lockdep_assert_held(&qp->r_lock); 157162306a36Sopenharmony_ci lockdep_assert_held(&qp->s_lock); 157262306a36Sopenharmony_ci trace_hfi1_sender_restart_rc(qp); 157362306a36Sopenharmony_ci if (qp->s_retry == 0) { 157462306a36Sopenharmony_ci if (qp->s_mig_state == IB_MIG_ARMED) { 157562306a36Sopenharmony_ci hfi1_migrate_qp(qp); 157662306a36Sopenharmony_ci qp->s_retry = qp->s_retry_cnt; 157762306a36Sopenharmony_ci } else if (qp->s_last == qp->s_acked) { 157862306a36Sopenharmony_ci /* 157962306a36Sopenharmony_ci * We need special handling for the OPFN request WQEs as 158062306a36Sopenharmony_ci * they are not allowed to generate real user errors 158162306a36Sopenharmony_ci */ 158262306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_OPFN) { 158362306a36Sopenharmony_ci struct hfi1_ibport *ibp = 158462306a36Sopenharmony_ci to_iport(qp->ibqp.device, qp->port_num); 158562306a36Sopenharmony_ci /* 158662306a36Sopenharmony_ci * Call opfn_conn_reply() with capcode and 158762306a36Sopenharmony_ci * remaining data as 0 to close out the 158862306a36Sopenharmony_ci * current request 158962306a36Sopenharmony_ci */ 159062306a36Sopenharmony_ci opfn_conn_reply(qp, priv->opfn.curr); 159162306a36Sopenharmony_ci wqe = do_rc_completion(qp, wqe, ibp); 159262306a36Sopenharmony_ci qp->s_flags &= ~RVT_S_WAIT_ACK; 159362306a36Sopenharmony_ci } else { 159462306a36Sopenharmony_ci trace_hfi1_tid_write_sender_restart_rc(qp, 0); 159562306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_TID_RDMA_READ) { 159662306a36Sopenharmony_ci struct tid_rdma_request *req; 159762306a36Sopenharmony_ci 159862306a36Sopenharmony_ci req = wqe_to_tid_req(wqe); 159962306a36Sopenharmony_ci hfi1_kern_exp_rcv_clear_all(req); 160062306a36Sopenharmony_ci hfi1_kern_clear_hw_flow(priv->rcd, qp); 160162306a36Sopenharmony_ci } 160262306a36Sopenharmony_ci 160362306a36Sopenharmony_ci hfi1_trdma_send_complete(qp, wqe, 160462306a36Sopenharmony_ci IB_WC_RETRY_EXC_ERR); 160562306a36Sopenharmony_ci rvt_error_qp(qp, IB_WC_WR_FLUSH_ERR); 160662306a36Sopenharmony_ci } 160762306a36Sopenharmony_ci return; 160862306a36Sopenharmony_ci } else { /* need to handle delayed completion */ 160962306a36Sopenharmony_ci return; 161062306a36Sopenharmony_ci } 161162306a36Sopenharmony_ci } else { 161262306a36Sopenharmony_ci qp->s_retry--; 161362306a36Sopenharmony_ci } 161462306a36Sopenharmony_ci 161562306a36Sopenharmony_ci ibp = to_iport(qp->ibqp.device, qp->port_num); 161662306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_RDMA_READ || 161762306a36Sopenharmony_ci wqe->wr.opcode == IB_WR_TID_RDMA_READ) 161862306a36Sopenharmony_ci ibp->rvp.n_rc_resends++; 161962306a36Sopenharmony_ci else 162062306a36Sopenharmony_ci ibp->rvp.n_rc_resends += delta_psn(qp->s_psn, psn); 162162306a36Sopenharmony_ci 162262306a36Sopenharmony_ci qp->s_flags &= ~(RVT_S_WAIT_FENCE | RVT_S_WAIT_RDMAR | 162362306a36Sopenharmony_ci RVT_S_WAIT_SSN_CREDIT | RVT_S_WAIT_PSN | 162462306a36Sopenharmony_ci RVT_S_WAIT_ACK | HFI1_S_WAIT_TID_RESP); 162562306a36Sopenharmony_ci if (wait) 162662306a36Sopenharmony_ci qp->s_flags |= RVT_S_SEND_ONE; 162762306a36Sopenharmony_ci reset_psn(qp, psn); 162862306a36Sopenharmony_ci} 162962306a36Sopenharmony_ci 163062306a36Sopenharmony_ci/* 163162306a36Sopenharmony_ci * Set qp->s_sending_psn to the next PSN after the given one. 163262306a36Sopenharmony_ci * This would be psn+1 except when RDMA reads or TID RDMA ops 163362306a36Sopenharmony_ci * are present. 163462306a36Sopenharmony_ci */ 163562306a36Sopenharmony_cistatic void reset_sending_psn(struct rvt_qp *qp, u32 psn) 163662306a36Sopenharmony_ci{ 163762306a36Sopenharmony_ci struct rvt_swqe *wqe; 163862306a36Sopenharmony_ci u32 n = qp->s_last; 163962306a36Sopenharmony_ci 164062306a36Sopenharmony_ci lockdep_assert_held(&qp->s_lock); 164162306a36Sopenharmony_ci /* Find the work request corresponding to the given PSN. */ 164262306a36Sopenharmony_ci for (;;) { 164362306a36Sopenharmony_ci wqe = rvt_get_swqe_ptr(qp, n); 164462306a36Sopenharmony_ci if (cmp_psn(psn, wqe->lpsn) <= 0) { 164562306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_RDMA_READ || 164662306a36Sopenharmony_ci wqe->wr.opcode == IB_WR_TID_RDMA_READ || 164762306a36Sopenharmony_ci wqe->wr.opcode == IB_WR_TID_RDMA_WRITE) 164862306a36Sopenharmony_ci qp->s_sending_psn = wqe->lpsn + 1; 164962306a36Sopenharmony_ci else 165062306a36Sopenharmony_ci qp->s_sending_psn = psn + 1; 165162306a36Sopenharmony_ci break; 165262306a36Sopenharmony_ci } 165362306a36Sopenharmony_ci if (++n == qp->s_size) 165462306a36Sopenharmony_ci n = 0; 165562306a36Sopenharmony_ci if (n == qp->s_tail) 165662306a36Sopenharmony_ci break; 165762306a36Sopenharmony_ci } 165862306a36Sopenharmony_ci} 165962306a36Sopenharmony_ci 166062306a36Sopenharmony_ci/** 166162306a36Sopenharmony_ci * hfi1_rc_verbs_aborted - handle abort status 166262306a36Sopenharmony_ci * @qp: the QP 166362306a36Sopenharmony_ci * @opah: the opa header 166462306a36Sopenharmony_ci * 166562306a36Sopenharmony_ci * This code modifies both ACK bit in BTH[2] 166662306a36Sopenharmony_ci * and the s_flags to go into send one mode. 166762306a36Sopenharmony_ci * 166862306a36Sopenharmony_ci * This serves to throttle the send engine to only 166962306a36Sopenharmony_ci * send a single packet in the likely case the 167062306a36Sopenharmony_ci * a link has gone down. 167162306a36Sopenharmony_ci */ 167262306a36Sopenharmony_civoid hfi1_rc_verbs_aborted(struct rvt_qp *qp, struct hfi1_opa_header *opah) 167362306a36Sopenharmony_ci{ 167462306a36Sopenharmony_ci struct ib_other_headers *ohdr = hfi1_get_rc_ohdr(opah); 167562306a36Sopenharmony_ci u8 opcode = ib_bth_get_opcode(ohdr); 167662306a36Sopenharmony_ci u32 psn; 167762306a36Sopenharmony_ci 167862306a36Sopenharmony_ci /* ignore responses */ 167962306a36Sopenharmony_ci if ((opcode >= OP(RDMA_READ_RESPONSE_FIRST) && 168062306a36Sopenharmony_ci opcode <= OP(ATOMIC_ACKNOWLEDGE)) || 168162306a36Sopenharmony_ci opcode == TID_OP(READ_RESP) || 168262306a36Sopenharmony_ci opcode == TID_OP(WRITE_RESP)) 168362306a36Sopenharmony_ci return; 168462306a36Sopenharmony_ci 168562306a36Sopenharmony_ci psn = ib_bth_get_psn(ohdr) | IB_BTH_REQ_ACK; 168662306a36Sopenharmony_ci ohdr->bth[2] = cpu_to_be32(psn); 168762306a36Sopenharmony_ci qp->s_flags |= RVT_S_SEND_ONE; 168862306a36Sopenharmony_ci} 168962306a36Sopenharmony_ci 169062306a36Sopenharmony_ci/* 169162306a36Sopenharmony_ci * This should be called with the QP s_lock held and interrupts disabled. 169262306a36Sopenharmony_ci */ 169362306a36Sopenharmony_civoid hfi1_rc_send_complete(struct rvt_qp *qp, struct hfi1_opa_header *opah) 169462306a36Sopenharmony_ci{ 169562306a36Sopenharmony_ci struct ib_other_headers *ohdr; 169662306a36Sopenharmony_ci struct hfi1_qp_priv *priv = qp->priv; 169762306a36Sopenharmony_ci struct rvt_swqe *wqe; 169862306a36Sopenharmony_ci u32 opcode, head, tail; 169962306a36Sopenharmony_ci u32 psn; 170062306a36Sopenharmony_ci struct tid_rdma_request *req; 170162306a36Sopenharmony_ci 170262306a36Sopenharmony_ci lockdep_assert_held(&qp->s_lock); 170362306a36Sopenharmony_ci if (!(ib_rvt_state_ops[qp->state] & RVT_SEND_OR_FLUSH_OR_RECV_OK)) 170462306a36Sopenharmony_ci return; 170562306a36Sopenharmony_ci 170662306a36Sopenharmony_ci ohdr = hfi1_get_rc_ohdr(opah); 170762306a36Sopenharmony_ci opcode = ib_bth_get_opcode(ohdr); 170862306a36Sopenharmony_ci if ((opcode >= OP(RDMA_READ_RESPONSE_FIRST) && 170962306a36Sopenharmony_ci opcode <= OP(ATOMIC_ACKNOWLEDGE)) || 171062306a36Sopenharmony_ci opcode == TID_OP(READ_RESP) || 171162306a36Sopenharmony_ci opcode == TID_OP(WRITE_RESP)) { 171262306a36Sopenharmony_ci WARN_ON(!qp->s_rdma_ack_cnt); 171362306a36Sopenharmony_ci qp->s_rdma_ack_cnt--; 171462306a36Sopenharmony_ci return; 171562306a36Sopenharmony_ci } 171662306a36Sopenharmony_ci 171762306a36Sopenharmony_ci psn = ib_bth_get_psn(ohdr); 171862306a36Sopenharmony_ci /* 171962306a36Sopenharmony_ci * Don't attempt to reset the sending PSN for packets in the 172062306a36Sopenharmony_ci * KDETH PSN space since the PSN does not match anything. 172162306a36Sopenharmony_ci */ 172262306a36Sopenharmony_ci if (opcode != TID_OP(WRITE_DATA) && 172362306a36Sopenharmony_ci opcode != TID_OP(WRITE_DATA_LAST) && 172462306a36Sopenharmony_ci opcode != TID_OP(ACK) && opcode != TID_OP(RESYNC)) 172562306a36Sopenharmony_ci reset_sending_psn(qp, psn); 172662306a36Sopenharmony_ci 172762306a36Sopenharmony_ci /* Handle TID RDMA WRITE packets differently */ 172862306a36Sopenharmony_ci if (opcode >= TID_OP(WRITE_REQ) && 172962306a36Sopenharmony_ci opcode <= TID_OP(WRITE_DATA_LAST)) { 173062306a36Sopenharmony_ci head = priv->s_tid_head; 173162306a36Sopenharmony_ci tail = priv->s_tid_cur; 173262306a36Sopenharmony_ci /* 173362306a36Sopenharmony_ci * s_tid_cur is set to s_tid_head in the case, where 173462306a36Sopenharmony_ci * a new TID RDMA request is being started and all 173562306a36Sopenharmony_ci * previous ones have been completed. 173662306a36Sopenharmony_ci * Therefore, we need to do a secondary check in order 173762306a36Sopenharmony_ci * to properly determine whether we should start the 173862306a36Sopenharmony_ci * RC timer. 173962306a36Sopenharmony_ci */ 174062306a36Sopenharmony_ci wqe = rvt_get_swqe_ptr(qp, tail); 174162306a36Sopenharmony_ci req = wqe_to_tid_req(wqe); 174262306a36Sopenharmony_ci if (head == tail && req->comp_seg < req->total_segs) { 174362306a36Sopenharmony_ci if (tail == 0) 174462306a36Sopenharmony_ci tail = qp->s_size - 1; 174562306a36Sopenharmony_ci else 174662306a36Sopenharmony_ci tail -= 1; 174762306a36Sopenharmony_ci } 174862306a36Sopenharmony_ci } else { 174962306a36Sopenharmony_ci head = qp->s_tail; 175062306a36Sopenharmony_ci tail = qp->s_acked; 175162306a36Sopenharmony_ci } 175262306a36Sopenharmony_ci 175362306a36Sopenharmony_ci /* 175462306a36Sopenharmony_ci * Start timer after a packet requesting an ACK has been sent and 175562306a36Sopenharmony_ci * there are still requests that haven't been acked. 175662306a36Sopenharmony_ci */ 175762306a36Sopenharmony_ci if ((psn & IB_BTH_REQ_ACK) && tail != head && 175862306a36Sopenharmony_ci opcode != TID_OP(WRITE_DATA) && opcode != TID_OP(WRITE_DATA_LAST) && 175962306a36Sopenharmony_ci opcode != TID_OP(RESYNC) && 176062306a36Sopenharmony_ci !(qp->s_flags & 176162306a36Sopenharmony_ci (RVT_S_TIMER | RVT_S_WAIT_RNR | RVT_S_WAIT_PSN)) && 176262306a36Sopenharmony_ci (ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK)) { 176362306a36Sopenharmony_ci if (opcode == TID_OP(READ_REQ)) 176462306a36Sopenharmony_ci rvt_add_retry_timer_ext(qp, priv->timeout_shift); 176562306a36Sopenharmony_ci else 176662306a36Sopenharmony_ci rvt_add_retry_timer(qp); 176762306a36Sopenharmony_ci } 176862306a36Sopenharmony_ci 176962306a36Sopenharmony_ci /* Start TID RDMA ACK timer */ 177062306a36Sopenharmony_ci if ((opcode == TID_OP(WRITE_DATA) || 177162306a36Sopenharmony_ci opcode == TID_OP(WRITE_DATA_LAST) || 177262306a36Sopenharmony_ci opcode == TID_OP(RESYNC)) && 177362306a36Sopenharmony_ci (psn & IB_BTH_REQ_ACK) && 177462306a36Sopenharmony_ci !(priv->s_flags & HFI1_S_TID_RETRY_TIMER) && 177562306a36Sopenharmony_ci (ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK)) { 177662306a36Sopenharmony_ci /* 177762306a36Sopenharmony_ci * The TID RDMA ACK packet could be received before this 177862306a36Sopenharmony_ci * function is called. Therefore, add the timer only if TID 177962306a36Sopenharmony_ci * RDMA ACK packets are actually pending. 178062306a36Sopenharmony_ci */ 178162306a36Sopenharmony_ci wqe = rvt_get_swqe_ptr(qp, qp->s_acked); 178262306a36Sopenharmony_ci req = wqe_to_tid_req(wqe); 178362306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_TID_RDMA_WRITE && 178462306a36Sopenharmony_ci req->ack_seg < req->cur_seg) 178562306a36Sopenharmony_ci hfi1_add_tid_retry_timer(qp); 178662306a36Sopenharmony_ci } 178762306a36Sopenharmony_ci 178862306a36Sopenharmony_ci while (qp->s_last != qp->s_acked) { 178962306a36Sopenharmony_ci wqe = rvt_get_swqe_ptr(qp, qp->s_last); 179062306a36Sopenharmony_ci if (cmp_psn(wqe->lpsn, qp->s_sending_psn) >= 0 && 179162306a36Sopenharmony_ci cmp_psn(qp->s_sending_psn, qp->s_sending_hpsn) <= 0) 179262306a36Sopenharmony_ci break; 179362306a36Sopenharmony_ci trdma_clean_swqe(qp, wqe); 179462306a36Sopenharmony_ci trace_hfi1_qp_send_completion(qp, wqe, qp->s_last); 179562306a36Sopenharmony_ci rvt_qp_complete_swqe(qp, 179662306a36Sopenharmony_ci wqe, 179762306a36Sopenharmony_ci ib_hfi1_wc_opcode[wqe->wr.opcode], 179862306a36Sopenharmony_ci IB_WC_SUCCESS); 179962306a36Sopenharmony_ci } 180062306a36Sopenharmony_ci /* 180162306a36Sopenharmony_ci * If we were waiting for sends to complete before re-sending, 180262306a36Sopenharmony_ci * and they are now complete, restart sending. 180362306a36Sopenharmony_ci */ 180462306a36Sopenharmony_ci trace_hfi1_sendcomplete(qp, psn); 180562306a36Sopenharmony_ci if (qp->s_flags & RVT_S_WAIT_PSN && 180662306a36Sopenharmony_ci cmp_psn(qp->s_sending_psn, qp->s_sending_hpsn) > 0) { 180762306a36Sopenharmony_ci qp->s_flags &= ~RVT_S_WAIT_PSN; 180862306a36Sopenharmony_ci qp->s_sending_psn = qp->s_psn; 180962306a36Sopenharmony_ci qp->s_sending_hpsn = qp->s_psn - 1; 181062306a36Sopenharmony_ci hfi1_schedule_send(qp); 181162306a36Sopenharmony_ci } 181262306a36Sopenharmony_ci} 181362306a36Sopenharmony_ci 181462306a36Sopenharmony_cistatic inline void update_last_psn(struct rvt_qp *qp, u32 psn) 181562306a36Sopenharmony_ci{ 181662306a36Sopenharmony_ci qp->s_last_psn = psn; 181762306a36Sopenharmony_ci} 181862306a36Sopenharmony_ci 181962306a36Sopenharmony_ci/* 182062306a36Sopenharmony_ci * Generate a SWQE completion. 182162306a36Sopenharmony_ci * This is similar to hfi1_send_complete but has to check to be sure 182262306a36Sopenharmony_ci * that the SGEs are not being referenced if the SWQE is being resent. 182362306a36Sopenharmony_ci */ 182462306a36Sopenharmony_cistruct rvt_swqe *do_rc_completion(struct rvt_qp *qp, 182562306a36Sopenharmony_ci struct rvt_swqe *wqe, 182662306a36Sopenharmony_ci struct hfi1_ibport *ibp) 182762306a36Sopenharmony_ci{ 182862306a36Sopenharmony_ci struct hfi1_qp_priv *priv = qp->priv; 182962306a36Sopenharmony_ci 183062306a36Sopenharmony_ci lockdep_assert_held(&qp->s_lock); 183162306a36Sopenharmony_ci /* 183262306a36Sopenharmony_ci * Don't decrement refcount and don't generate a 183362306a36Sopenharmony_ci * completion if the SWQE is being resent until the send 183462306a36Sopenharmony_ci * is finished. 183562306a36Sopenharmony_ci */ 183662306a36Sopenharmony_ci trace_hfi1_rc_completion(qp, wqe->lpsn); 183762306a36Sopenharmony_ci if (cmp_psn(wqe->lpsn, qp->s_sending_psn) < 0 || 183862306a36Sopenharmony_ci cmp_psn(qp->s_sending_psn, qp->s_sending_hpsn) > 0) { 183962306a36Sopenharmony_ci trdma_clean_swqe(qp, wqe); 184062306a36Sopenharmony_ci trace_hfi1_qp_send_completion(qp, wqe, qp->s_last); 184162306a36Sopenharmony_ci rvt_qp_complete_swqe(qp, 184262306a36Sopenharmony_ci wqe, 184362306a36Sopenharmony_ci ib_hfi1_wc_opcode[wqe->wr.opcode], 184462306a36Sopenharmony_ci IB_WC_SUCCESS); 184562306a36Sopenharmony_ci } else { 184662306a36Sopenharmony_ci struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); 184762306a36Sopenharmony_ci 184862306a36Sopenharmony_ci this_cpu_inc(*ibp->rvp.rc_delayed_comp); 184962306a36Sopenharmony_ci /* 185062306a36Sopenharmony_ci * If send progress not running attempt to progress 185162306a36Sopenharmony_ci * SDMA queue. 185262306a36Sopenharmony_ci */ 185362306a36Sopenharmony_ci if (ppd->dd->flags & HFI1_HAS_SEND_DMA) { 185462306a36Sopenharmony_ci struct sdma_engine *engine; 185562306a36Sopenharmony_ci u8 sl = rdma_ah_get_sl(&qp->remote_ah_attr); 185662306a36Sopenharmony_ci u8 sc5; 185762306a36Sopenharmony_ci 185862306a36Sopenharmony_ci /* For now use sc to find engine */ 185962306a36Sopenharmony_ci sc5 = ibp->sl_to_sc[sl]; 186062306a36Sopenharmony_ci engine = qp_to_sdma_engine(qp, sc5); 186162306a36Sopenharmony_ci sdma_engine_progress_schedule(engine); 186262306a36Sopenharmony_ci } 186362306a36Sopenharmony_ci } 186462306a36Sopenharmony_ci 186562306a36Sopenharmony_ci qp->s_retry = qp->s_retry_cnt; 186662306a36Sopenharmony_ci /* 186762306a36Sopenharmony_ci * Don't update the last PSN if the request being completed is 186862306a36Sopenharmony_ci * a TID RDMA WRITE request. 186962306a36Sopenharmony_ci * Completion of the TID RDMA WRITE requests are done by the 187062306a36Sopenharmony_ci * TID RDMA ACKs and as such could be for a request that has 187162306a36Sopenharmony_ci * already been ACKed as far as the IB state machine is 187262306a36Sopenharmony_ci * concerned. 187362306a36Sopenharmony_ci */ 187462306a36Sopenharmony_ci if (wqe->wr.opcode != IB_WR_TID_RDMA_WRITE) 187562306a36Sopenharmony_ci update_last_psn(qp, wqe->lpsn); 187662306a36Sopenharmony_ci 187762306a36Sopenharmony_ci /* 187862306a36Sopenharmony_ci * If we are completing a request which is in the process of 187962306a36Sopenharmony_ci * being resent, we can stop re-sending it since we know the 188062306a36Sopenharmony_ci * responder has already seen it. 188162306a36Sopenharmony_ci */ 188262306a36Sopenharmony_ci if (qp->s_acked == qp->s_cur) { 188362306a36Sopenharmony_ci if (++qp->s_cur >= qp->s_size) 188462306a36Sopenharmony_ci qp->s_cur = 0; 188562306a36Sopenharmony_ci qp->s_acked = qp->s_cur; 188662306a36Sopenharmony_ci wqe = rvt_get_swqe_ptr(qp, qp->s_cur); 188762306a36Sopenharmony_ci if (qp->s_acked != qp->s_tail) { 188862306a36Sopenharmony_ci qp->s_state = OP(SEND_LAST); 188962306a36Sopenharmony_ci qp->s_psn = wqe->psn; 189062306a36Sopenharmony_ci } 189162306a36Sopenharmony_ci } else { 189262306a36Sopenharmony_ci if (++qp->s_acked >= qp->s_size) 189362306a36Sopenharmony_ci qp->s_acked = 0; 189462306a36Sopenharmony_ci if (qp->state == IB_QPS_SQD && qp->s_acked == qp->s_cur) 189562306a36Sopenharmony_ci qp->s_draining = 0; 189662306a36Sopenharmony_ci wqe = rvt_get_swqe_ptr(qp, qp->s_acked); 189762306a36Sopenharmony_ci } 189862306a36Sopenharmony_ci if (priv->s_flags & HFI1_S_TID_WAIT_INTERLCK) { 189962306a36Sopenharmony_ci priv->s_flags &= ~HFI1_S_TID_WAIT_INTERLCK; 190062306a36Sopenharmony_ci hfi1_schedule_send(qp); 190162306a36Sopenharmony_ci } 190262306a36Sopenharmony_ci return wqe; 190362306a36Sopenharmony_ci} 190462306a36Sopenharmony_ci 190562306a36Sopenharmony_cistatic void set_restart_qp(struct rvt_qp *qp, struct hfi1_ctxtdata *rcd) 190662306a36Sopenharmony_ci{ 190762306a36Sopenharmony_ci /* Retry this request. */ 190862306a36Sopenharmony_ci if (!(qp->r_flags & RVT_R_RDMAR_SEQ)) { 190962306a36Sopenharmony_ci qp->r_flags |= RVT_R_RDMAR_SEQ; 191062306a36Sopenharmony_ci hfi1_restart_rc(qp, qp->s_last_psn + 1, 0); 191162306a36Sopenharmony_ci if (list_empty(&qp->rspwait)) { 191262306a36Sopenharmony_ci qp->r_flags |= RVT_R_RSP_SEND; 191362306a36Sopenharmony_ci rvt_get_qp(qp); 191462306a36Sopenharmony_ci list_add_tail(&qp->rspwait, &rcd->qp_wait_list); 191562306a36Sopenharmony_ci } 191662306a36Sopenharmony_ci } 191762306a36Sopenharmony_ci} 191862306a36Sopenharmony_ci 191962306a36Sopenharmony_ci/** 192062306a36Sopenharmony_ci * update_qp_retry_state - Update qp retry state. 192162306a36Sopenharmony_ci * @qp: the QP 192262306a36Sopenharmony_ci * @psn: the packet sequence number of the TID RDMA WRITE RESP. 192362306a36Sopenharmony_ci * @spsn: The start psn for the given TID RDMA WRITE swqe. 192462306a36Sopenharmony_ci * @lpsn: The last psn for the given TID RDMA WRITE swqe. 192562306a36Sopenharmony_ci * 192662306a36Sopenharmony_ci * This function is called to update the qp retry state upon 192762306a36Sopenharmony_ci * receiving a TID WRITE RESP after the qp is scheduled to retry 192862306a36Sopenharmony_ci * a request. 192962306a36Sopenharmony_ci */ 193062306a36Sopenharmony_cistatic void update_qp_retry_state(struct rvt_qp *qp, u32 psn, u32 spsn, 193162306a36Sopenharmony_ci u32 lpsn) 193262306a36Sopenharmony_ci{ 193362306a36Sopenharmony_ci struct hfi1_qp_priv *qpriv = qp->priv; 193462306a36Sopenharmony_ci 193562306a36Sopenharmony_ci qp->s_psn = psn + 1; 193662306a36Sopenharmony_ci /* 193762306a36Sopenharmony_ci * If this is the first TID RDMA WRITE RESP packet for the current 193862306a36Sopenharmony_ci * request, change the s_state so that the retry will be processed 193962306a36Sopenharmony_ci * correctly. Similarly, if this is the last TID RDMA WRITE RESP 194062306a36Sopenharmony_ci * packet, change the s_state and advance the s_cur. 194162306a36Sopenharmony_ci */ 194262306a36Sopenharmony_ci if (cmp_psn(psn, lpsn) >= 0) { 194362306a36Sopenharmony_ci qp->s_cur = qpriv->s_tid_cur + 1; 194462306a36Sopenharmony_ci if (qp->s_cur >= qp->s_size) 194562306a36Sopenharmony_ci qp->s_cur = 0; 194662306a36Sopenharmony_ci qp->s_state = TID_OP(WRITE_REQ); 194762306a36Sopenharmony_ci } else if (!cmp_psn(psn, spsn)) { 194862306a36Sopenharmony_ci qp->s_cur = qpriv->s_tid_cur; 194962306a36Sopenharmony_ci qp->s_state = TID_OP(WRITE_RESP); 195062306a36Sopenharmony_ci } 195162306a36Sopenharmony_ci} 195262306a36Sopenharmony_ci 195362306a36Sopenharmony_ci/* 195462306a36Sopenharmony_ci * do_rc_ack - process an incoming RC ACK 195562306a36Sopenharmony_ci * @qp: the QP the ACK came in on 195662306a36Sopenharmony_ci * @psn: the packet sequence number of the ACK 195762306a36Sopenharmony_ci * @opcode: the opcode of the request that resulted in the ACK 195862306a36Sopenharmony_ci * 195962306a36Sopenharmony_ci * This is called from rc_rcv_resp() to process an incoming RC ACK 196062306a36Sopenharmony_ci * for the given QP. 196162306a36Sopenharmony_ci * May be called at interrupt level, with the QP s_lock held. 196262306a36Sopenharmony_ci * Returns 1 if OK, 0 if current operation should be aborted (NAK). 196362306a36Sopenharmony_ci */ 196462306a36Sopenharmony_ciint do_rc_ack(struct rvt_qp *qp, u32 aeth, u32 psn, int opcode, 196562306a36Sopenharmony_ci u64 val, struct hfi1_ctxtdata *rcd) 196662306a36Sopenharmony_ci{ 196762306a36Sopenharmony_ci struct hfi1_ibport *ibp; 196862306a36Sopenharmony_ci enum ib_wc_status status; 196962306a36Sopenharmony_ci struct hfi1_qp_priv *qpriv = qp->priv; 197062306a36Sopenharmony_ci struct rvt_swqe *wqe; 197162306a36Sopenharmony_ci int ret = 0; 197262306a36Sopenharmony_ci u32 ack_psn; 197362306a36Sopenharmony_ci int diff; 197462306a36Sopenharmony_ci struct rvt_dev_info *rdi; 197562306a36Sopenharmony_ci 197662306a36Sopenharmony_ci lockdep_assert_held(&qp->s_lock); 197762306a36Sopenharmony_ci /* 197862306a36Sopenharmony_ci * Note that NAKs implicitly ACK outstanding SEND and RDMA write 197962306a36Sopenharmony_ci * requests and implicitly NAK RDMA read and atomic requests issued 198062306a36Sopenharmony_ci * before the NAK'ed request. The MSN won't include the NAK'ed 198162306a36Sopenharmony_ci * request but will include an ACK'ed request(s). 198262306a36Sopenharmony_ci */ 198362306a36Sopenharmony_ci ack_psn = psn; 198462306a36Sopenharmony_ci if (aeth >> IB_AETH_NAK_SHIFT) 198562306a36Sopenharmony_ci ack_psn--; 198662306a36Sopenharmony_ci wqe = rvt_get_swqe_ptr(qp, qp->s_acked); 198762306a36Sopenharmony_ci ibp = rcd_to_iport(rcd); 198862306a36Sopenharmony_ci 198962306a36Sopenharmony_ci /* 199062306a36Sopenharmony_ci * The MSN might be for a later WQE than the PSN indicates so 199162306a36Sopenharmony_ci * only complete WQEs that the PSN finishes. 199262306a36Sopenharmony_ci */ 199362306a36Sopenharmony_ci while ((diff = delta_psn(ack_psn, wqe->lpsn)) >= 0) { 199462306a36Sopenharmony_ci /* 199562306a36Sopenharmony_ci * RDMA_READ_RESPONSE_ONLY is a special case since 199662306a36Sopenharmony_ci * we want to generate completion events for everything 199762306a36Sopenharmony_ci * before the RDMA read, copy the data, then generate 199862306a36Sopenharmony_ci * the completion for the read. 199962306a36Sopenharmony_ci */ 200062306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_RDMA_READ && 200162306a36Sopenharmony_ci opcode == OP(RDMA_READ_RESPONSE_ONLY) && 200262306a36Sopenharmony_ci diff == 0) { 200362306a36Sopenharmony_ci ret = 1; 200462306a36Sopenharmony_ci goto bail_stop; 200562306a36Sopenharmony_ci } 200662306a36Sopenharmony_ci /* 200762306a36Sopenharmony_ci * If this request is a RDMA read or atomic, and the ACK is 200862306a36Sopenharmony_ci * for a later operation, this ACK NAKs the RDMA read or 200962306a36Sopenharmony_ci * atomic. In other words, only a RDMA_READ_LAST or ONLY 201062306a36Sopenharmony_ci * can ACK a RDMA read and likewise for atomic ops. Note 201162306a36Sopenharmony_ci * that the NAK case can only happen if relaxed ordering is 201262306a36Sopenharmony_ci * used and requests are sent after an RDMA read or atomic 201362306a36Sopenharmony_ci * is sent but before the response is received. 201462306a36Sopenharmony_ci */ 201562306a36Sopenharmony_ci if ((wqe->wr.opcode == IB_WR_RDMA_READ && 201662306a36Sopenharmony_ci (opcode != OP(RDMA_READ_RESPONSE_LAST) || diff != 0)) || 201762306a36Sopenharmony_ci (wqe->wr.opcode == IB_WR_TID_RDMA_READ && 201862306a36Sopenharmony_ci (opcode != TID_OP(READ_RESP) || diff != 0)) || 201962306a36Sopenharmony_ci ((wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP || 202062306a36Sopenharmony_ci wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD) && 202162306a36Sopenharmony_ci (opcode != OP(ATOMIC_ACKNOWLEDGE) || diff != 0)) || 202262306a36Sopenharmony_ci (wqe->wr.opcode == IB_WR_TID_RDMA_WRITE && 202362306a36Sopenharmony_ci (delta_psn(psn, qp->s_last_psn) != 1))) { 202462306a36Sopenharmony_ci set_restart_qp(qp, rcd); 202562306a36Sopenharmony_ci /* 202662306a36Sopenharmony_ci * No need to process the ACK/NAK since we are 202762306a36Sopenharmony_ci * restarting an earlier request. 202862306a36Sopenharmony_ci */ 202962306a36Sopenharmony_ci goto bail_stop; 203062306a36Sopenharmony_ci } 203162306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP || 203262306a36Sopenharmony_ci wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD) { 203362306a36Sopenharmony_ci u64 *vaddr = wqe->sg_list[0].vaddr; 203462306a36Sopenharmony_ci *vaddr = val; 203562306a36Sopenharmony_ci } 203662306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_OPFN) 203762306a36Sopenharmony_ci opfn_conn_reply(qp, val); 203862306a36Sopenharmony_ci 203962306a36Sopenharmony_ci if (qp->s_num_rd_atomic && 204062306a36Sopenharmony_ci (wqe->wr.opcode == IB_WR_RDMA_READ || 204162306a36Sopenharmony_ci wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP || 204262306a36Sopenharmony_ci wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD)) { 204362306a36Sopenharmony_ci qp->s_num_rd_atomic--; 204462306a36Sopenharmony_ci /* Restart sending task if fence is complete */ 204562306a36Sopenharmony_ci if ((qp->s_flags & RVT_S_WAIT_FENCE) && 204662306a36Sopenharmony_ci !qp->s_num_rd_atomic) { 204762306a36Sopenharmony_ci qp->s_flags &= ~(RVT_S_WAIT_FENCE | 204862306a36Sopenharmony_ci RVT_S_WAIT_ACK); 204962306a36Sopenharmony_ci hfi1_schedule_send(qp); 205062306a36Sopenharmony_ci } else if (qp->s_flags & RVT_S_WAIT_RDMAR) { 205162306a36Sopenharmony_ci qp->s_flags &= ~(RVT_S_WAIT_RDMAR | 205262306a36Sopenharmony_ci RVT_S_WAIT_ACK); 205362306a36Sopenharmony_ci hfi1_schedule_send(qp); 205462306a36Sopenharmony_ci } 205562306a36Sopenharmony_ci } 205662306a36Sopenharmony_ci 205762306a36Sopenharmony_ci /* 205862306a36Sopenharmony_ci * TID RDMA WRITE requests will be completed by the TID RDMA 205962306a36Sopenharmony_ci * ACK packet handler (see tid_rdma.c). 206062306a36Sopenharmony_ci */ 206162306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_TID_RDMA_WRITE) 206262306a36Sopenharmony_ci break; 206362306a36Sopenharmony_ci 206462306a36Sopenharmony_ci wqe = do_rc_completion(qp, wqe, ibp); 206562306a36Sopenharmony_ci if (qp->s_acked == qp->s_tail) 206662306a36Sopenharmony_ci break; 206762306a36Sopenharmony_ci } 206862306a36Sopenharmony_ci 206962306a36Sopenharmony_ci trace_hfi1_rc_ack_do(qp, aeth, psn, wqe); 207062306a36Sopenharmony_ci trace_hfi1_sender_do_rc_ack(qp); 207162306a36Sopenharmony_ci switch (aeth >> IB_AETH_NAK_SHIFT) { 207262306a36Sopenharmony_ci case 0: /* ACK */ 207362306a36Sopenharmony_ci this_cpu_inc(*ibp->rvp.rc_acks); 207462306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_TID_RDMA_READ) { 207562306a36Sopenharmony_ci if (wqe_to_tid_req(wqe)->ack_pending) 207662306a36Sopenharmony_ci rvt_mod_retry_timer_ext(qp, 207762306a36Sopenharmony_ci qpriv->timeout_shift); 207862306a36Sopenharmony_ci else 207962306a36Sopenharmony_ci rvt_stop_rc_timers(qp); 208062306a36Sopenharmony_ci } else if (qp->s_acked != qp->s_tail) { 208162306a36Sopenharmony_ci struct rvt_swqe *__w = NULL; 208262306a36Sopenharmony_ci 208362306a36Sopenharmony_ci if (qpriv->s_tid_cur != HFI1_QP_WQE_INVALID) 208462306a36Sopenharmony_ci __w = rvt_get_swqe_ptr(qp, qpriv->s_tid_cur); 208562306a36Sopenharmony_ci 208662306a36Sopenharmony_ci /* 208762306a36Sopenharmony_ci * Stop timers if we've received all of the TID RDMA 208862306a36Sopenharmony_ci * WRITE * responses. 208962306a36Sopenharmony_ci */ 209062306a36Sopenharmony_ci if (__w && __w->wr.opcode == IB_WR_TID_RDMA_WRITE && 209162306a36Sopenharmony_ci opcode == TID_OP(WRITE_RESP)) { 209262306a36Sopenharmony_ci /* 209362306a36Sopenharmony_ci * Normally, the loop above would correctly 209462306a36Sopenharmony_ci * process all WQEs from s_acked onward and 209562306a36Sopenharmony_ci * either complete them or check for correct 209662306a36Sopenharmony_ci * PSN sequencing. 209762306a36Sopenharmony_ci * However, for TID RDMA, due to pipelining, 209862306a36Sopenharmony_ci * the response may not be for the request at 209962306a36Sopenharmony_ci * s_acked so the above look would just be 210062306a36Sopenharmony_ci * skipped. This does not allow for checking 210162306a36Sopenharmony_ci * the PSN sequencing. It has to be done 210262306a36Sopenharmony_ci * separately. 210362306a36Sopenharmony_ci */ 210462306a36Sopenharmony_ci if (cmp_psn(psn, qp->s_last_psn + 1)) { 210562306a36Sopenharmony_ci set_restart_qp(qp, rcd); 210662306a36Sopenharmony_ci goto bail_stop; 210762306a36Sopenharmony_ci } 210862306a36Sopenharmony_ci /* 210962306a36Sopenharmony_ci * If the psn is being resent, stop the 211062306a36Sopenharmony_ci * resending. 211162306a36Sopenharmony_ci */ 211262306a36Sopenharmony_ci if (qp->s_cur != qp->s_tail && 211362306a36Sopenharmony_ci cmp_psn(qp->s_psn, psn) <= 0) 211462306a36Sopenharmony_ci update_qp_retry_state(qp, psn, 211562306a36Sopenharmony_ci __w->psn, 211662306a36Sopenharmony_ci __w->lpsn); 211762306a36Sopenharmony_ci else if (--qpriv->pending_tid_w_resp) 211862306a36Sopenharmony_ci rvt_mod_retry_timer(qp); 211962306a36Sopenharmony_ci else 212062306a36Sopenharmony_ci rvt_stop_rc_timers(qp); 212162306a36Sopenharmony_ci } else { 212262306a36Sopenharmony_ci /* 212362306a36Sopenharmony_ci * We are expecting more ACKs so 212462306a36Sopenharmony_ci * mod the retry timer. 212562306a36Sopenharmony_ci */ 212662306a36Sopenharmony_ci rvt_mod_retry_timer(qp); 212762306a36Sopenharmony_ci /* 212862306a36Sopenharmony_ci * We can stop re-sending the earlier packets 212962306a36Sopenharmony_ci * and continue with the next packet the 213062306a36Sopenharmony_ci * receiver wants. 213162306a36Sopenharmony_ci */ 213262306a36Sopenharmony_ci if (cmp_psn(qp->s_psn, psn) <= 0) 213362306a36Sopenharmony_ci reset_psn(qp, psn + 1); 213462306a36Sopenharmony_ci } 213562306a36Sopenharmony_ci } else { 213662306a36Sopenharmony_ci /* No more acks - kill all timers */ 213762306a36Sopenharmony_ci rvt_stop_rc_timers(qp); 213862306a36Sopenharmony_ci if (cmp_psn(qp->s_psn, psn) <= 0) { 213962306a36Sopenharmony_ci qp->s_state = OP(SEND_LAST); 214062306a36Sopenharmony_ci qp->s_psn = psn + 1; 214162306a36Sopenharmony_ci } 214262306a36Sopenharmony_ci } 214362306a36Sopenharmony_ci if (qp->s_flags & RVT_S_WAIT_ACK) { 214462306a36Sopenharmony_ci qp->s_flags &= ~RVT_S_WAIT_ACK; 214562306a36Sopenharmony_ci hfi1_schedule_send(qp); 214662306a36Sopenharmony_ci } 214762306a36Sopenharmony_ci rvt_get_credit(qp, aeth); 214862306a36Sopenharmony_ci qp->s_rnr_retry = qp->s_rnr_retry_cnt; 214962306a36Sopenharmony_ci qp->s_retry = qp->s_retry_cnt; 215062306a36Sopenharmony_ci /* 215162306a36Sopenharmony_ci * If the current request is a TID RDMA WRITE request and the 215262306a36Sopenharmony_ci * response is not a TID RDMA WRITE RESP packet, s_last_psn 215362306a36Sopenharmony_ci * can't be advanced. 215462306a36Sopenharmony_ci */ 215562306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_TID_RDMA_WRITE && 215662306a36Sopenharmony_ci opcode != TID_OP(WRITE_RESP) && 215762306a36Sopenharmony_ci cmp_psn(psn, wqe->psn) >= 0) 215862306a36Sopenharmony_ci return 1; 215962306a36Sopenharmony_ci update_last_psn(qp, psn); 216062306a36Sopenharmony_ci return 1; 216162306a36Sopenharmony_ci 216262306a36Sopenharmony_ci case 1: /* RNR NAK */ 216362306a36Sopenharmony_ci ibp->rvp.n_rnr_naks++; 216462306a36Sopenharmony_ci if (qp->s_acked == qp->s_tail) 216562306a36Sopenharmony_ci goto bail_stop; 216662306a36Sopenharmony_ci if (qp->s_flags & RVT_S_WAIT_RNR) 216762306a36Sopenharmony_ci goto bail_stop; 216862306a36Sopenharmony_ci rdi = ib_to_rvt(qp->ibqp.device); 216962306a36Sopenharmony_ci if (!(rdi->post_parms[wqe->wr.opcode].flags & 217062306a36Sopenharmony_ci RVT_OPERATION_IGN_RNR_CNT)) { 217162306a36Sopenharmony_ci if (qp->s_rnr_retry == 0) { 217262306a36Sopenharmony_ci status = IB_WC_RNR_RETRY_EXC_ERR; 217362306a36Sopenharmony_ci goto class_b; 217462306a36Sopenharmony_ci } 217562306a36Sopenharmony_ci if (qp->s_rnr_retry_cnt < 7 && qp->s_rnr_retry_cnt > 0) 217662306a36Sopenharmony_ci qp->s_rnr_retry--; 217762306a36Sopenharmony_ci } 217862306a36Sopenharmony_ci 217962306a36Sopenharmony_ci /* 218062306a36Sopenharmony_ci * The last valid PSN is the previous PSN. For TID RDMA WRITE 218162306a36Sopenharmony_ci * request, s_last_psn should be incremented only when a TID 218262306a36Sopenharmony_ci * RDMA WRITE RESP is received to avoid skipping lost TID RDMA 218362306a36Sopenharmony_ci * WRITE RESP packets. 218462306a36Sopenharmony_ci */ 218562306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_TID_RDMA_WRITE) { 218662306a36Sopenharmony_ci reset_psn(qp, qp->s_last_psn + 1); 218762306a36Sopenharmony_ci } else { 218862306a36Sopenharmony_ci update_last_psn(qp, psn - 1); 218962306a36Sopenharmony_ci reset_psn(qp, psn); 219062306a36Sopenharmony_ci } 219162306a36Sopenharmony_ci 219262306a36Sopenharmony_ci ibp->rvp.n_rc_resends += delta_psn(qp->s_psn, psn); 219362306a36Sopenharmony_ci qp->s_flags &= ~(RVT_S_WAIT_SSN_CREDIT | RVT_S_WAIT_ACK); 219462306a36Sopenharmony_ci rvt_stop_rc_timers(qp); 219562306a36Sopenharmony_ci rvt_add_rnr_timer(qp, aeth); 219662306a36Sopenharmony_ci return 0; 219762306a36Sopenharmony_ci 219862306a36Sopenharmony_ci case 3: /* NAK */ 219962306a36Sopenharmony_ci if (qp->s_acked == qp->s_tail) 220062306a36Sopenharmony_ci goto bail_stop; 220162306a36Sopenharmony_ci /* The last valid PSN is the previous PSN. */ 220262306a36Sopenharmony_ci update_last_psn(qp, psn - 1); 220362306a36Sopenharmony_ci switch ((aeth >> IB_AETH_CREDIT_SHIFT) & 220462306a36Sopenharmony_ci IB_AETH_CREDIT_MASK) { 220562306a36Sopenharmony_ci case 0: /* PSN sequence error */ 220662306a36Sopenharmony_ci ibp->rvp.n_seq_naks++; 220762306a36Sopenharmony_ci /* 220862306a36Sopenharmony_ci * Back up to the responder's expected PSN. 220962306a36Sopenharmony_ci * Note that we might get a NAK in the middle of an 221062306a36Sopenharmony_ci * RDMA READ response which terminates the RDMA 221162306a36Sopenharmony_ci * READ. 221262306a36Sopenharmony_ci */ 221362306a36Sopenharmony_ci hfi1_restart_rc(qp, psn, 0); 221462306a36Sopenharmony_ci hfi1_schedule_send(qp); 221562306a36Sopenharmony_ci break; 221662306a36Sopenharmony_ci 221762306a36Sopenharmony_ci case 1: /* Invalid Request */ 221862306a36Sopenharmony_ci status = IB_WC_REM_INV_REQ_ERR; 221962306a36Sopenharmony_ci ibp->rvp.n_other_naks++; 222062306a36Sopenharmony_ci goto class_b; 222162306a36Sopenharmony_ci 222262306a36Sopenharmony_ci case 2: /* Remote Access Error */ 222362306a36Sopenharmony_ci status = IB_WC_REM_ACCESS_ERR; 222462306a36Sopenharmony_ci ibp->rvp.n_other_naks++; 222562306a36Sopenharmony_ci goto class_b; 222662306a36Sopenharmony_ci 222762306a36Sopenharmony_ci case 3: /* Remote Operation Error */ 222862306a36Sopenharmony_ci status = IB_WC_REM_OP_ERR; 222962306a36Sopenharmony_ci ibp->rvp.n_other_naks++; 223062306a36Sopenharmony_ciclass_b: 223162306a36Sopenharmony_ci if (qp->s_last == qp->s_acked) { 223262306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_TID_RDMA_READ) 223362306a36Sopenharmony_ci hfi1_kern_read_tid_flow_free(qp); 223462306a36Sopenharmony_ci 223562306a36Sopenharmony_ci hfi1_trdma_send_complete(qp, wqe, status); 223662306a36Sopenharmony_ci rvt_error_qp(qp, IB_WC_WR_FLUSH_ERR); 223762306a36Sopenharmony_ci } 223862306a36Sopenharmony_ci break; 223962306a36Sopenharmony_ci 224062306a36Sopenharmony_ci default: 224162306a36Sopenharmony_ci /* Ignore other reserved NAK error codes */ 224262306a36Sopenharmony_ci goto reserved; 224362306a36Sopenharmony_ci } 224462306a36Sopenharmony_ci qp->s_retry = qp->s_retry_cnt; 224562306a36Sopenharmony_ci qp->s_rnr_retry = qp->s_rnr_retry_cnt; 224662306a36Sopenharmony_ci goto bail_stop; 224762306a36Sopenharmony_ci 224862306a36Sopenharmony_ci default: /* 2: reserved */ 224962306a36Sopenharmony_cireserved: 225062306a36Sopenharmony_ci /* Ignore reserved NAK codes. */ 225162306a36Sopenharmony_ci goto bail_stop; 225262306a36Sopenharmony_ci } 225362306a36Sopenharmony_ci /* cannot be reached */ 225462306a36Sopenharmony_cibail_stop: 225562306a36Sopenharmony_ci rvt_stop_rc_timers(qp); 225662306a36Sopenharmony_ci return ret; 225762306a36Sopenharmony_ci} 225862306a36Sopenharmony_ci 225962306a36Sopenharmony_ci/* 226062306a36Sopenharmony_ci * We have seen an out of sequence RDMA read middle or last packet. 226162306a36Sopenharmony_ci * This ACKs SENDs and RDMA writes up to the first RDMA read or atomic SWQE. 226262306a36Sopenharmony_ci */ 226362306a36Sopenharmony_cistatic void rdma_seq_err(struct rvt_qp *qp, struct hfi1_ibport *ibp, u32 psn, 226462306a36Sopenharmony_ci struct hfi1_ctxtdata *rcd) 226562306a36Sopenharmony_ci{ 226662306a36Sopenharmony_ci struct rvt_swqe *wqe; 226762306a36Sopenharmony_ci 226862306a36Sopenharmony_ci lockdep_assert_held(&qp->s_lock); 226962306a36Sopenharmony_ci /* Remove QP from retry timer */ 227062306a36Sopenharmony_ci rvt_stop_rc_timers(qp); 227162306a36Sopenharmony_ci 227262306a36Sopenharmony_ci wqe = rvt_get_swqe_ptr(qp, qp->s_acked); 227362306a36Sopenharmony_ci 227462306a36Sopenharmony_ci while (cmp_psn(psn, wqe->lpsn) > 0) { 227562306a36Sopenharmony_ci if (wqe->wr.opcode == IB_WR_RDMA_READ || 227662306a36Sopenharmony_ci wqe->wr.opcode == IB_WR_TID_RDMA_READ || 227762306a36Sopenharmony_ci wqe->wr.opcode == IB_WR_TID_RDMA_WRITE || 227862306a36Sopenharmony_ci wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP || 227962306a36Sopenharmony_ci wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD) 228062306a36Sopenharmony_ci break; 228162306a36Sopenharmony_ci wqe = do_rc_completion(qp, wqe, ibp); 228262306a36Sopenharmony_ci } 228362306a36Sopenharmony_ci 228462306a36Sopenharmony_ci ibp->rvp.n_rdma_seq++; 228562306a36Sopenharmony_ci qp->r_flags |= RVT_R_RDMAR_SEQ; 228662306a36Sopenharmony_ci hfi1_restart_rc(qp, qp->s_last_psn + 1, 0); 228762306a36Sopenharmony_ci if (list_empty(&qp->rspwait)) { 228862306a36Sopenharmony_ci qp->r_flags |= RVT_R_RSP_SEND; 228962306a36Sopenharmony_ci rvt_get_qp(qp); 229062306a36Sopenharmony_ci list_add_tail(&qp->rspwait, &rcd->qp_wait_list); 229162306a36Sopenharmony_ci } 229262306a36Sopenharmony_ci} 229362306a36Sopenharmony_ci 229462306a36Sopenharmony_ci/** 229562306a36Sopenharmony_ci * rc_rcv_resp - process an incoming RC response packet 229662306a36Sopenharmony_ci * @packet: data packet information 229762306a36Sopenharmony_ci * 229862306a36Sopenharmony_ci * This is called from hfi1_rc_rcv() to process an incoming RC response 229962306a36Sopenharmony_ci * packet for the given QP. 230062306a36Sopenharmony_ci * Called at interrupt level. 230162306a36Sopenharmony_ci */ 230262306a36Sopenharmony_cistatic void rc_rcv_resp(struct hfi1_packet *packet) 230362306a36Sopenharmony_ci{ 230462306a36Sopenharmony_ci struct hfi1_ctxtdata *rcd = packet->rcd; 230562306a36Sopenharmony_ci void *data = packet->payload; 230662306a36Sopenharmony_ci u32 tlen = packet->tlen; 230762306a36Sopenharmony_ci struct rvt_qp *qp = packet->qp; 230862306a36Sopenharmony_ci struct hfi1_ibport *ibp; 230962306a36Sopenharmony_ci struct ib_other_headers *ohdr = packet->ohdr; 231062306a36Sopenharmony_ci struct rvt_swqe *wqe; 231162306a36Sopenharmony_ci enum ib_wc_status status; 231262306a36Sopenharmony_ci unsigned long flags; 231362306a36Sopenharmony_ci int diff; 231462306a36Sopenharmony_ci u64 val; 231562306a36Sopenharmony_ci u32 aeth; 231662306a36Sopenharmony_ci u32 psn = ib_bth_get_psn(packet->ohdr); 231762306a36Sopenharmony_ci u32 pmtu = qp->pmtu; 231862306a36Sopenharmony_ci u16 hdrsize = packet->hlen; 231962306a36Sopenharmony_ci u8 opcode = packet->opcode; 232062306a36Sopenharmony_ci u8 pad = packet->pad; 232162306a36Sopenharmony_ci u8 extra_bytes = pad + packet->extra_byte + (SIZE_OF_CRC << 2); 232262306a36Sopenharmony_ci 232362306a36Sopenharmony_ci spin_lock_irqsave(&qp->s_lock, flags); 232462306a36Sopenharmony_ci trace_hfi1_ack(qp, psn); 232562306a36Sopenharmony_ci 232662306a36Sopenharmony_ci /* Ignore invalid responses. */ 232762306a36Sopenharmony_ci if (cmp_psn(psn, READ_ONCE(qp->s_next_psn)) >= 0) 232862306a36Sopenharmony_ci goto ack_done; 232962306a36Sopenharmony_ci 233062306a36Sopenharmony_ci /* Ignore duplicate responses. */ 233162306a36Sopenharmony_ci diff = cmp_psn(psn, qp->s_last_psn); 233262306a36Sopenharmony_ci if (unlikely(diff <= 0)) { 233362306a36Sopenharmony_ci /* Update credits for "ghost" ACKs */ 233462306a36Sopenharmony_ci if (diff == 0 && opcode == OP(ACKNOWLEDGE)) { 233562306a36Sopenharmony_ci aeth = be32_to_cpu(ohdr->u.aeth); 233662306a36Sopenharmony_ci if ((aeth >> IB_AETH_NAK_SHIFT) == 0) 233762306a36Sopenharmony_ci rvt_get_credit(qp, aeth); 233862306a36Sopenharmony_ci } 233962306a36Sopenharmony_ci goto ack_done; 234062306a36Sopenharmony_ci } 234162306a36Sopenharmony_ci 234262306a36Sopenharmony_ci /* 234362306a36Sopenharmony_ci * Skip everything other than the PSN we expect, if we are waiting 234462306a36Sopenharmony_ci * for a reply to a restarted RDMA read or atomic op. 234562306a36Sopenharmony_ci */ 234662306a36Sopenharmony_ci if (qp->r_flags & RVT_R_RDMAR_SEQ) { 234762306a36Sopenharmony_ci if (cmp_psn(psn, qp->s_last_psn + 1) != 0) 234862306a36Sopenharmony_ci goto ack_done; 234962306a36Sopenharmony_ci qp->r_flags &= ~RVT_R_RDMAR_SEQ; 235062306a36Sopenharmony_ci } 235162306a36Sopenharmony_ci 235262306a36Sopenharmony_ci if (unlikely(qp->s_acked == qp->s_tail)) 235362306a36Sopenharmony_ci goto ack_done; 235462306a36Sopenharmony_ci wqe = rvt_get_swqe_ptr(qp, qp->s_acked); 235562306a36Sopenharmony_ci status = IB_WC_SUCCESS; 235662306a36Sopenharmony_ci 235762306a36Sopenharmony_ci switch (opcode) { 235862306a36Sopenharmony_ci case OP(ACKNOWLEDGE): 235962306a36Sopenharmony_ci case OP(ATOMIC_ACKNOWLEDGE): 236062306a36Sopenharmony_ci case OP(RDMA_READ_RESPONSE_FIRST): 236162306a36Sopenharmony_ci aeth = be32_to_cpu(ohdr->u.aeth); 236262306a36Sopenharmony_ci if (opcode == OP(ATOMIC_ACKNOWLEDGE)) 236362306a36Sopenharmony_ci val = ib_u64_get(&ohdr->u.at.atomic_ack_eth); 236462306a36Sopenharmony_ci else 236562306a36Sopenharmony_ci val = 0; 236662306a36Sopenharmony_ci if (!do_rc_ack(qp, aeth, psn, opcode, val, rcd) || 236762306a36Sopenharmony_ci opcode != OP(RDMA_READ_RESPONSE_FIRST)) 236862306a36Sopenharmony_ci goto ack_done; 236962306a36Sopenharmony_ci wqe = rvt_get_swqe_ptr(qp, qp->s_acked); 237062306a36Sopenharmony_ci if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ)) 237162306a36Sopenharmony_ci goto ack_op_err; 237262306a36Sopenharmony_ci /* 237362306a36Sopenharmony_ci * If this is a response to a resent RDMA read, we 237462306a36Sopenharmony_ci * have to be careful to copy the data to the right 237562306a36Sopenharmony_ci * location. 237662306a36Sopenharmony_ci */ 237762306a36Sopenharmony_ci qp->s_rdma_read_len = restart_sge(&qp->s_rdma_read_sge, 237862306a36Sopenharmony_ci wqe, psn, pmtu); 237962306a36Sopenharmony_ci goto read_middle; 238062306a36Sopenharmony_ci 238162306a36Sopenharmony_ci case OP(RDMA_READ_RESPONSE_MIDDLE): 238262306a36Sopenharmony_ci /* no AETH, no ACK */ 238362306a36Sopenharmony_ci if (unlikely(cmp_psn(psn, qp->s_last_psn + 1))) 238462306a36Sopenharmony_ci goto ack_seq_err; 238562306a36Sopenharmony_ci if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ)) 238662306a36Sopenharmony_ci goto ack_op_err; 238762306a36Sopenharmony_ciread_middle: 238862306a36Sopenharmony_ci if (unlikely(tlen != (hdrsize + pmtu + extra_bytes))) 238962306a36Sopenharmony_ci goto ack_len_err; 239062306a36Sopenharmony_ci if (unlikely(pmtu >= qp->s_rdma_read_len)) 239162306a36Sopenharmony_ci goto ack_len_err; 239262306a36Sopenharmony_ci 239362306a36Sopenharmony_ci /* 239462306a36Sopenharmony_ci * We got a response so update the timeout. 239562306a36Sopenharmony_ci * 4.096 usec. * (1 << qp->timeout) 239662306a36Sopenharmony_ci */ 239762306a36Sopenharmony_ci rvt_mod_retry_timer(qp); 239862306a36Sopenharmony_ci if (qp->s_flags & RVT_S_WAIT_ACK) { 239962306a36Sopenharmony_ci qp->s_flags &= ~RVT_S_WAIT_ACK; 240062306a36Sopenharmony_ci hfi1_schedule_send(qp); 240162306a36Sopenharmony_ci } 240262306a36Sopenharmony_ci 240362306a36Sopenharmony_ci if (opcode == OP(RDMA_READ_RESPONSE_MIDDLE)) 240462306a36Sopenharmony_ci qp->s_retry = qp->s_retry_cnt; 240562306a36Sopenharmony_ci 240662306a36Sopenharmony_ci /* 240762306a36Sopenharmony_ci * Update the RDMA receive state but do the copy w/o 240862306a36Sopenharmony_ci * holding the locks and blocking interrupts. 240962306a36Sopenharmony_ci */ 241062306a36Sopenharmony_ci qp->s_rdma_read_len -= pmtu; 241162306a36Sopenharmony_ci update_last_psn(qp, psn); 241262306a36Sopenharmony_ci spin_unlock_irqrestore(&qp->s_lock, flags); 241362306a36Sopenharmony_ci rvt_copy_sge(qp, &qp->s_rdma_read_sge, 241462306a36Sopenharmony_ci data, pmtu, false, false); 241562306a36Sopenharmony_ci goto bail; 241662306a36Sopenharmony_ci 241762306a36Sopenharmony_ci case OP(RDMA_READ_RESPONSE_ONLY): 241862306a36Sopenharmony_ci aeth = be32_to_cpu(ohdr->u.aeth); 241962306a36Sopenharmony_ci if (!do_rc_ack(qp, aeth, psn, opcode, 0, rcd)) 242062306a36Sopenharmony_ci goto ack_done; 242162306a36Sopenharmony_ci /* 242262306a36Sopenharmony_ci * Check that the data size is >= 0 && <= pmtu. 242362306a36Sopenharmony_ci * Remember to account for ICRC (4). 242462306a36Sopenharmony_ci */ 242562306a36Sopenharmony_ci if (unlikely(tlen < (hdrsize + extra_bytes))) 242662306a36Sopenharmony_ci goto ack_len_err; 242762306a36Sopenharmony_ci /* 242862306a36Sopenharmony_ci * If this is a response to a resent RDMA read, we 242962306a36Sopenharmony_ci * have to be careful to copy the data to the right 243062306a36Sopenharmony_ci * location. 243162306a36Sopenharmony_ci */ 243262306a36Sopenharmony_ci wqe = rvt_get_swqe_ptr(qp, qp->s_acked); 243362306a36Sopenharmony_ci qp->s_rdma_read_len = restart_sge(&qp->s_rdma_read_sge, 243462306a36Sopenharmony_ci wqe, psn, pmtu); 243562306a36Sopenharmony_ci goto read_last; 243662306a36Sopenharmony_ci 243762306a36Sopenharmony_ci case OP(RDMA_READ_RESPONSE_LAST): 243862306a36Sopenharmony_ci /* ACKs READ req. */ 243962306a36Sopenharmony_ci if (unlikely(cmp_psn(psn, qp->s_last_psn + 1))) 244062306a36Sopenharmony_ci goto ack_seq_err; 244162306a36Sopenharmony_ci if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ)) 244262306a36Sopenharmony_ci goto ack_op_err; 244362306a36Sopenharmony_ci /* 244462306a36Sopenharmony_ci * Check that the data size is >= 1 && <= pmtu. 244562306a36Sopenharmony_ci * Remember to account for ICRC (4). 244662306a36Sopenharmony_ci */ 244762306a36Sopenharmony_ci if (unlikely(tlen <= (hdrsize + extra_bytes))) 244862306a36Sopenharmony_ci goto ack_len_err; 244962306a36Sopenharmony_ciread_last: 245062306a36Sopenharmony_ci tlen -= hdrsize + extra_bytes; 245162306a36Sopenharmony_ci if (unlikely(tlen != qp->s_rdma_read_len)) 245262306a36Sopenharmony_ci goto ack_len_err; 245362306a36Sopenharmony_ci aeth = be32_to_cpu(ohdr->u.aeth); 245462306a36Sopenharmony_ci rvt_copy_sge(qp, &qp->s_rdma_read_sge, 245562306a36Sopenharmony_ci data, tlen, false, false); 245662306a36Sopenharmony_ci WARN_ON(qp->s_rdma_read_sge.num_sge); 245762306a36Sopenharmony_ci (void)do_rc_ack(qp, aeth, psn, 245862306a36Sopenharmony_ci OP(RDMA_READ_RESPONSE_LAST), 0, rcd); 245962306a36Sopenharmony_ci goto ack_done; 246062306a36Sopenharmony_ci } 246162306a36Sopenharmony_ci 246262306a36Sopenharmony_ciack_op_err: 246362306a36Sopenharmony_ci status = IB_WC_LOC_QP_OP_ERR; 246462306a36Sopenharmony_ci goto ack_err; 246562306a36Sopenharmony_ci 246662306a36Sopenharmony_ciack_seq_err: 246762306a36Sopenharmony_ci ibp = rcd_to_iport(rcd); 246862306a36Sopenharmony_ci rdma_seq_err(qp, ibp, psn, rcd); 246962306a36Sopenharmony_ci goto ack_done; 247062306a36Sopenharmony_ci 247162306a36Sopenharmony_ciack_len_err: 247262306a36Sopenharmony_ci status = IB_WC_LOC_LEN_ERR; 247362306a36Sopenharmony_ciack_err: 247462306a36Sopenharmony_ci if (qp->s_last == qp->s_acked) { 247562306a36Sopenharmony_ci rvt_send_complete(qp, wqe, status); 247662306a36Sopenharmony_ci rvt_error_qp(qp, IB_WC_WR_FLUSH_ERR); 247762306a36Sopenharmony_ci } 247862306a36Sopenharmony_ciack_done: 247962306a36Sopenharmony_ci spin_unlock_irqrestore(&qp->s_lock, flags); 248062306a36Sopenharmony_cibail: 248162306a36Sopenharmony_ci return; 248262306a36Sopenharmony_ci} 248362306a36Sopenharmony_ci 248462306a36Sopenharmony_cistatic inline void rc_cancel_ack(struct rvt_qp *qp) 248562306a36Sopenharmony_ci{ 248662306a36Sopenharmony_ci qp->r_adefered = 0; 248762306a36Sopenharmony_ci if (list_empty(&qp->rspwait)) 248862306a36Sopenharmony_ci return; 248962306a36Sopenharmony_ci list_del_init(&qp->rspwait); 249062306a36Sopenharmony_ci qp->r_flags &= ~RVT_R_RSP_NAK; 249162306a36Sopenharmony_ci rvt_put_qp(qp); 249262306a36Sopenharmony_ci} 249362306a36Sopenharmony_ci 249462306a36Sopenharmony_ci/** 249562306a36Sopenharmony_ci * rc_rcv_error - process an incoming duplicate or error RC packet 249662306a36Sopenharmony_ci * @ohdr: the other headers for this packet 249762306a36Sopenharmony_ci * @data: the packet data 249862306a36Sopenharmony_ci * @qp: the QP for this packet 249962306a36Sopenharmony_ci * @opcode: the opcode for this packet 250062306a36Sopenharmony_ci * @psn: the packet sequence number for this packet 250162306a36Sopenharmony_ci * @diff: the difference between the PSN and the expected PSN 250262306a36Sopenharmony_ci * @rcd: the receive context 250362306a36Sopenharmony_ci * 250462306a36Sopenharmony_ci * This is called from hfi1_rc_rcv() to process an unexpected 250562306a36Sopenharmony_ci * incoming RC packet for the given QP. 250662306a36Sopenharmony_ci * Called at interrupt level. 250762306a36Sopenharmony_ci * Return 1 if no more processing is needed; otherwise return 0 to 250862306a36Sopenharmony_ci * schedule a response to be sent. 250962306a36Sopenharmony_ci */ 251062306a36Sopenharmony_cistatic noinline int rc_rcv_error(struct ib_other_headers *ohdr, void *data, 251162306a36Sopenharmony_ci struct rvt_qp *qp, u32 opcode, u32 psn, 251262306a36Sopenharmony_ci int diff, struct hfi1_ctxtdata *rcd) 251362306a36Sopenharmony_ci{ 251462306a36Sopenharmony_ci struct hfi1_ibport *ibp = rcd_to_iport(rcd); 251562306a36Sopenharmony_ci struct rvt_ack_entry *e; 251662306a36Sopenharmony_ci unsigned long flags; 251762306a36Sopenharmony_ci u8 prev; 251862306a36Sopenharmony_ci u8 mra; /* most recent ACK */ 251962306a36Sopenharmony_ci bool old_req; 252062306a36Sopenharmony_ci 252162306a36Sopenharmony_ci trace_hfi1_rcv_error(qp, psn); 252262306a36Sopenharmony_ci if (diff > 0) { 252362306a36Sopenharmony_ci /* 252462306a36Sopenharmony_ci * Packet sequence error. 252562306a36Sopenharmony_ci * A NAK will ACK earlier sends and RDMA writes. 252662306a36Sopenharmony_ci * Don't queue the NAK if we already sent one. 252762306a36Sopenharmony_ci */ 252862306a36Sopenharmony_ci if (!qp->r_nak_state) { 252962306a36Sopenharmony_ci ibp->rvp.n_rc_seqnak++; 253062306a36Sopenharmony_ci qp->r_nak_state = IB_NAK_PSN_ERROR; 253162306a36Sopenharmony_ci /* Use the expected PSN. */ 253262306a36Sopenharmony_ci qp->r_ack_psn = qp->r_psn; 253362306a36Sopenharmony_ci /* 253462306a36Sopenharmony_ci * Wait to send the sequence NAK until all packets 253562306a36Sopenharmony_ci * in the receive queue have been processed. 253662306a36Sopenharmony_ci * Otherwise, we end up propagating congestion. 253762306a36Sopenharmony_ci */ 253862306a36Sopenharmony_ci rc_defered_ack(rcd, qp); 253962306a36Sopenharmony_ci } 254062306a36Sopenharmony_ci goto done; 254162306a36Sopenharmony_ci } 254262306a36Sopenharmony_ci 254362306a36Sopenharmony_ci /* 254462306a36Sopenharmony_ci * Handle a duplicate request. Don't re-execute SEND, RDMA 254562306a36Sopenharmony_ci * write or atomic op. Don't NAK errors, just silently drop 254662306a36Sopenharmony_ci * the duplicate request. Note that r_sge, r_len, and 254762306a36Sopenharmony_ci * r_rcv_len may be in use so don't modify them. 254862306a36Sopenharmony_ci * 254962306a36Sopenharmony_ci * We are supposed to ACK the earliest duplicate PSN but we 255062306a36Sopenharmony_ci * can coalesce an outstanding duplicate ACK. We have to 255162306a36Sopenharmony_ci * send the earliest so that RDMA reads can be restarted at 255262306a36Sopenharmony_ci * the requester's expected PSN. 255362306a36Sopenharmony_ci * 255462306a36Sopenharmony_ci * First, find where this duplicate PSN falls within the 255562306a36Sopenharmony_ci * ACKs previously sent. 255662306a36Sopenharmony_ci * old_req is true if there is an older response that is scheduled 255762306a36Sopenharmony_ci * to be sent before sending this one. 255862306a36Sopenharmony_ci */ 255962306a36Sopenharmony_ci e = NULL; 256062306a36Sopenharmony_ci old_req = true; 256162306a36Sopenharmony_ci ibp->rvp.n_rc_dupreq++; 256262306a36Sopenharmony_ci 256362306a36Sopenharmony_ci spin_lock_irqsave(&qp->s_lock, flags); 256462306a36Sopenharmony_ci 256562306a36Sopenharmony_ci e = find_prev_entry(qp, psn, &prev, &mra, &old_req); 256662306a36Sopenharmony_ci 256762306a36Sopenharmony_ci switch (opcode) { 256862306a36Sopenharmony_ci case OP(RDMA_READ_REQUEST): { 256962306a36Sopenharmony_ci struct ib_reth *reth; 257062306a36Sopenharmony_ci u32 offset; 257162306a36Sopenharmony_ci u32 len; 257262306a36Sopenharmony_ci 257362306a36Sopenharmony_ci /* 257462306a36Sopenharmony_ci * If we didn't find the RDMA read request in the ack queue, 257562306a36Sopenharmony_ci * we can ignore this request. 257662306a36Sopenharmony_ci */ 257762306a36Sopenharmony_ci if (!e || e->opcode != OP(RDMA_READ_REQUEST)) 257862306a36Sopenharmony_ci goto unlock_done; 257962306a36Sopenharmony_ci /* RETH comes after BTH */ 258062306a36Sopenharmony_ci reth = &ohdr->u.rc.reth; 258162306a36Sopenharmony_ci /* 258262306a36Sopenharmony_ci * Address range must be a subset of the original 258362306a36Sopenharmony_ci * request and start on pmtu boundaries. 258462306a36Sopenharmony_ci * We reuse the old ack_queue slot since the requester 258562306a36Sopenharmony_ci * should not back up and request an earlier PSN for the 258662306a36Sopenharmony_ci * same request. 258762306a36Sopenharmony_ci */ 258862306a36Sopenharmony_ci offset = delta_psn(psn, e->psn) * qp->pmtu; 258962306a36Sopenharmony_ci len = be32_to_cpu(reth->length); 259062306a36Sopenharmony_ci if (unlikely(offset + len != e->rdma_sge.sge_length)) 259162306a36Sopenharmony_ci goto unlock_done; 259262306a36Sopenharmony_ci release_rdma_sge_mr(e); 259362306a36Sopenharmony_ci if (len != 0) { 259462306a36Sopenharmony_ci u32 rkey = be32_to_cpu(reth->rkey); 259562306a36Sopenharmony_ci u64 vaddr = get_ib_reth_vaddr(reth); 259662306a36Sopenharmony_ci int ok; 259762306a36Sopenharmony_ci 259862306a36Sopenharmony_ci ok = rvt_rkey_ok(qp, &e->rdma_sge, len, vaddr, rkey, 259962306a36Sopenharmony_ci IB_ACCESS_REMOTE_READ); 260062306a36Sopenharmony_ci if (unlikely(!ok)) 260162306a36Sopenharmony_ci goto unlock_done; 260262306a36Sopenharmony_ci } else { 260362306a36Sopenharmony_ci e->rdma_sge.vaddr = NULL; 260462306a36Sopenharmony_ci e->rdma_sge.length = 0; 260562306a36Sopenharmony_ci e->rdma_sge.sge_length = 0; 260662306a36Sopenharmony_ci } 260762306a36Sopenharmony_ci e->psn = psn; 260862306a36Sopenharmony_ci if (old_req) 260962306a36Sopenharmony_ci goto unlock_done; 261062306a36Sopenharmony_ci if (qp->s_acked_ack_queue == qp->s_tail_ack_queue) 261162306a36Sopenharmony_ci qp->s_acked_ack_queue = prev; 261262306a36Sopenharmony_ci qp->s_tail_ack_queue = prev; 261362306a36Sopenharmony_ci break; 261462306a36Sopenharmony_ci } 261562306a36Sopenharmony_ci 261662306a36Sopenharmony_ci case OP(COMPARE_SWAP): 261762306a36Sopenharmony_ci case OP(FETCH_ADD): { 261862306a36Sopenharmony_ci /* 261962306a36Sopenharmony_ci * If we didn't find the atomic request in the ack queue 262062306a36Sopenharmony_ci * or the send engine is already backed up to send an 262162306a36Sopenharmony_ci * earlier entry, we can ignore this request. 262262306a36Sopenharmony_ci */ 262362306a36Sopenharmony_ci if (!e || e->opcode != (u8)opcode || old_req) 262462306a36Sopenharmony_ci goto unlock_done; 262562306a36Sopenharmony_ci if (qp->s_tail_ack_queue == qp->s_acked_ack_queue) 262662306a36Sopenharmony_ci qp->s_acked_ack_queue = prev; 262762306a36Sopenharmony_ci qp->s_tail_ack_queue = prev; 262862306a36Sopenharmony_ci break; 262962306a36Sopenharmony_ci } 263062306a36Sopenharmony_ci 263162306a36Sopenharmony_ci default: 263262306a36Sopenharmony_ci /* 263362306a36Sopenharmony_ci * Ignore this operation if it doesn't request an ACK 263462306a36Sopenharmony_ci * or an earlier RDMA read or atomic is going to be resent. 263562306a36Sopenharmony_ci */ 263662306a36Sopenharmony_ci if (!(psn & IB_BTH_REQ_ACK) || old_req) 263762306a36Sopenharmony_ci goto unlock_done; 263862306a36Sopenharmony_ci /* 263962306a36Sopenharmony_ci * Resend the most recent ACK if this request is 264062306a36Sopenharmony_ci * after all the previous RDMA reads and atomics. 264162306a36Sopenharmony_ci */ 264262306a36Sopenharmony_ci if (mra == qp->r_head_ack_queue) { 264362306a36Sopenharmony_ci spin_unlock_irqrestore(&qp->s_lock, flags); 264462306a36Sopenharmony_ci qp->r_nak_state = 0; 264562306a36Sopenharmony_ci qp->r_ack_psn = qp->r_psn - 1; 264662306a36Sopenharmony_ci goto send_ack; 264762306a36Sopenharmony_ci } 264862306a36Sopenharmony_ci 264962306a36Sopenharmony_ci /* 265062306a36Sopenharmony_ci * Resend the RDMA read or atomic op which 265162306a36Sopenharmony_ci * ACKs this duplicate request. 265262306a36Sopenharmony_ci */ 265362306a36Sopenharmony_ci if (qp->s_tail_ack_queue == qp->s_acked_ack_queue) 265462306a36Sopenharmony_ci qp->s_acked_ack_queue = mra; 265562306a36Sopenharmony_ci qp->s_tail_ack_queue = mra; 265662306a36Sopenharmony_ci break; 265762306a36Sopenharmony_ci } 265862306a36Sopenharmony_ci qp->s_ack_state = OP(ACKNOWLEDGE); 265962306a36Sopenharmony_ci qp->s_flags |= RVT_S_RESP_PENDING; 266062306a36Sopenharmony_ci qp->r_nak_state = 0; 266162306a36Sopenharmony_ci hfi1_schedule_send(qp); 266262306a36Sopenharmony_ci 266362306a36Sopenharmony_ciunlock_done: 266462306a36Sopenharmony_ci spin_unlock_irqrestore(&qp->s_lock, flags); 266562306a36Sopenharmony_cidone: 266662306a36Sopenharmony_ci return 1; 266762306a36Sopenharmony_ci 266862306a36Sopenharmony_cisend_ack: 266962306a36Sopenharmony_ci return 0; 267062306a36Sopenharmony_ci} 267162306a36Sopenharmony_ci 267262306a36Sopenharmony_cistatic void log_cca_event(struct hfi1_pportdata *ppd, u8 sl, u32 rlid, 267362306a36Sopenharmony_ci u32 lqpn, u32 rqpn, u8 svc_type) 267462306a36Sopenharmony_ci{ 267562306a36Sopenharmony_ci struct opa_hfi1_cong_log_event_internal *cc_event; 267662306a36Sopenharmony_ci unsigned long flags; 267762306a36Sopenharmony_ci 267862306a36Sopenharmony_ci if (sl >= OPA_MAX_SLS) 267962306a36Sopenharmony_ci return; 268062306a36Sopenharmony_ci 268162306a36Sopenharmony_ci spin_lock_irqsave(&ppd->cc_log_lock, flags); 268262306a36Sopenharmony_ci 268362306a36Sopenharmony_ci ppd->threshold_cong_event_map[sl / 8] |= 1 << (sl % 8); 268462306a36Sopenharmony_ci ppd->threshold_event_counter++; 268562306a36Sopenharmony_ci 268662306a36Sopenharmony_ci cc_event = &ppd->cc_events[ppd->cc_log_idx++]; 268762306a36Sopenharmony_ci if (ppd->cc_log_idx == OPA_CONG_LOG_ELEMS) 268862306a36Sopenharmony_ci ppd->cc_log_idx = 0; 268962306a36Sopenharmony_ci cc_event->lqpn = lqpn & RVT_QPN_MASK; 269062306a36Sopenharmony_ci cc_event->rqpn = rqpn & RVT_QPN_MASK; 269162306a36Sopenharmony_ci cc_event->sl = sl; 269262306a36Sopenharmony_ci cc_event->svc_type = svc_type; 269362306a36Sopenharmony_ci cc_event->rlid = rlid; 269462306a36Sopenharmony_ci /* keep timestamp in units of 1.024 usec */ 269562306a36Sopenharmony_ci cc_event->timestamp = ktime_get_ns() / 1024; 269662306a36Sopenharmony_ci 269762306a36Sopenharmony_ci spin_unlock_irqrestore(&ppd->cc_log_lock, flags); 269862306a36Sopenharmony_ci} 269962306a36Sopenharmony_ci 270062306a36Sopenharmony_civoid process_becn(struct hfi1_pportdata *ppd, u8 sl, u32 rlid, u32 lqpn, 270162306a36Sopenharmony_ci u32 rqpn, u8 svc_type) 270262306a36Sopenharmony_ci{ 270362306a36Sopenharmony_ci struct cca_timer *cca_timer; 270462306a36Sopenharmony_ci u16 ccti, ccti_incr, ccti_timer, ccti_limit; 270562306a36Sopenharmony_ci u8 trigger_threshold; 270662306a36Sopenharmony_ci struct cc_state *cc_state; 270762306a36Sopenharmony_ci unsigned long flags; 270862306a36Sopenharmony_ci 270962306a36Sopenharmony_ci if (sl >= OPA_MAX_SLS) 271062306a36Sopenharmony_ci return; 271162306a36Sopenharmony_ci 271262306a36Sopenharmony_ci cc_state = get_cc_state(ppd); 271362306a36Sopenharmony_ci 271462306a36Sopenharmony_ci if (!cc_state) 271562306a36Sopenharmony_ci return; 271662306a36Sopenharmony_ci 271762306a36Sopenharmony_ci /* 271862306a36Sopenharmony_ci * 1) increase CCTI (for this SL) 271962306a36Sopenharmony_ci * 2) select IPG (i.e., call set_link_ipg()) 272062306a36Sopenharmony_ci * 3) start timer 272162306a36Sopenharmony_ci */ 272262306a36Sopenharmony_ci ccti_limit = cc_state->cct.ccti_limit; 272362306a36Sopenharmony_ci ccti_incr = cc_state->cong_setting.entries[sl].ccti_increase; 272462306a36Sopenharmony_ci ccti_timer = cc_state->cong_setting.entries[sl].ccti_timer; 272562306a36Sopenharmony_ci trigger_threshold = 272662306a36Sopenharmony_ci cc_state->cong_setting.entries[sl].trigger_threshold; 272762306a36Sopenharmony_ci 272862306a36Sopenharmony_ci spin_lock_irqsave(&ppd->cca_timer_lock, flags); 272962306a36Sopenharmony_ci 273062306a36Sopenharmony_ci cca_timer = &ppd->cca_timer[sl]; 273162306a36Sopenharmony_ci if (cca_timer->ccti < ccti_limit) { 273262306a36Sopenharmony_ci if (cca_timer->ccti + ccti_incr <= ccti_limit) 273362306a36Sopenharmony_ci cca_timer->ccti += ccti_incr; 273462306a36Sopenharmony_ci else 273562306a36Sopenharmony_ci cca_timer->ccti = ccti_limit; 273662306a36Sopenharmony_ci set_link_ipg(ppd); 273762306a36Sopenharmony_ci } 273862306a36Sopenharmony_ci 273962306a36Sopenharmony_ci ccti = cca_timer->ccti; 274062306a36Sopenharmony_ci 274162306a36Sopenharmony_ci if (!hrtimer_active(&cca_timer->hrtimer)) { 274262306a36Sopenharmony_ci /* ccti_timer is in units of 1.024 usec */ 274362306a36Sopenharmony_ci unsigned long nsec = 1024 * ccti_timer; 274462306a36Sopenharmony_ci 274562306a36Sopenharmony_ci hrtimer_start(&cca_timer->hrtimer, ns_to_ktime(nsec), 274662306a36Sopenharmony_ci HRTIMER_MODE_REL_PINNED); 274762306a36Sopenharmony_ci } 274862306a36Sopenharmony_ci 274962306a36Sopenharmony_ci spin_unlock_irqrestore(&ppd->cca_timer_lock, flags); 275062306a36Sopenharmony_ci 275162306a36Sopenharmony_ci if ((trigger_threshold != 0) && (ccti >= trigger_threshold)) 275262306a36Sopenharmony_ci log_cca_event(ppd, sl, rlid, lqpn, rqpn, svc_type); 275362306a36Sopenharmony_ci} 275462306a36Sopenharmony_ci 275562306a36Sopenharmony_ci/** 275662306a36Sopenharmony_ci * hfi1_rc_rcv - process an incoming RC packet 275762306a36Sopenharmony_ci * @packet: data packet information 275862306a36Sopenharmony_ci * 275962306a36Sopenharmony_ci * This is called from qp_rcv() to process an incoming RC packet 276062306a36Sopenharmony_ci * for the given QP. 276162306a36Sopenharmony_ci * May be called at interrupt level. 276262306a36Sopenharmony_ci */ 276362306a36Sopenharmony_civoid hfi1_rc_rcv(struct hfi1_packet *packet) 276462306a36Sopenharmony_ci{ 276562306a36Sopenharmony_ci struct hfi1_ctxtdata *rcd = packet->rcd; 276662306a36Sopenharmony_ci void *data = packet->payload; 276762306a36Sopenharmony_ci u32 tlen = packet->tlen; 276862306a36Sopenharmony_ci struct rvt_qp *qp = packet->qp; 276962306a36Sopenharmony_ci struct hfi1_qp_priv *qpriv = qp->priv; 277062306a36Sopenharmony_ci struct hfi1_ibport *ibp = rcd_to_iport(rcd); 277162306a36Sopenharmony_ci struct ib_other_headers *ohdr = packet->ohdr; 277262306a36Sopenharmony_ci u32 opcode = packet->opcode; 277362306a36Sopenharmony_ci u32 hdrsize = packet->hlen; 277462306a36Sopenharmony_ci u32 psn = ib_bth_get_psn(packet->ohdr); 277562306a36Sopenharmony_ci u32 pad = packet->pad; 277662306a36Sopenharmony_ci struct ib_wc wc; 277762306a36Sopenharmony_ci u32 pmtu = qp->pmtu; 277862306a36Sopenharmony_ci int diff; 277962306a36Sopenharmony_ci struct ib_reth *reth; 278062306a36Sopenharmony_ci unsigned long flags; 278162306a36Sopenharmony_ci int ret; 278262306a36Sopenharmony_ci bool copy_last = false, fecn; 278362306a36Sopenharmony_ci u32 rkey; 278462306a36Sopenharmony_ci u8 extra_bytes = pad + packet->extra_byte + (SIZE_OF_CRC << 2); 278562306a36Sopenharmony_ci 278662306a36Sopenharmony_ci lockdep_assert_held(&qp->r_lock); 278762306a36Sopenharmony_ci 278862306a36Sopenharmony_ci if (hfi1_ruc_check_hdr(ibp, packet)) 278962306a36Sopenharmony_ci return; 279062306a36Sopenharmony_ci 279162306a36Sopenharmony_ci fecn = process_ecn(qp, packet); 279262306a36Sopenharmony_ci opfn_trigger_conn_request(qp, be32_to_cpu(ohdr->bth[1])); 279362306a36Sopenharmony_ci 279462306a36Sopenharmony_ci /* 279562306a36Sopenharmony_ci * Process responses (ACKs) before anything else. Note that the 279662306a36Sopenharmony_ci * packet sequence number will be for something in the send work 279762306a36Sopenharmony_ci * queue rather than the expected receive packet sequence number. 279862306a36Sopenharmony_ci * In other words, this QP is the requester. 279962306a36Sopenharmony_ci */ 280062306a36Sopenharmony_ci if (opcode >= OP(RDMA_READ_RESPONSE_FIRST) && 280162306a36Sopenharmony_ci opcode <= OP(ATOMIC_ACKNOWLEDGE)) { 280262306a36Sopenharmony_ci rc_rcv_resp(packet); 280362306a36Sopenharmony_ci return; 280462306a36Sopenharmony_ci } 280562306a36Sopenharmony_ci 280662306a36Sopenharmony_ci /* Compute 24 bits worth of difference. */ 280762306a36Sopenharmony_ci diff = delta_psn(psn, qp->r_psn); 280862306a36Sopenharmony_ci if (unlikely(diff)) { 280962306a36Sopenharmony_ci if (rc_rcv_error(ohdr, data, qp, opcode, psn, diff, rcd)) 281062306a36Sopenharmony_ci return; 281162306a36Sopenharmony_ci goto send_ack; 281262306a36Sopenharmony_ci } 281362306a36Sopenharmony_ci 281462306a36Sopenharmony_ci /* Check for opcode sequence errors. */ 281562306a36Sopenharmony_ci switch (qp->r_state) { 281662306a36Sopenharmony_ci case OP(SEND_FIRST): 281762306a36Sopenharmony_ci case OP(SEND_MIDDLE): 281862306a36Sopenharmony_ci if (opcode == OP(SEND_MIDDLE) || 281962306a36Sopenharmony_ci opcode == OP(SEND_LAST) || 282062306a36Sopenharmony_ci opcode == OP(SEND_LAST_WITH_IMMEDIATE) || 282162306a36Sopenharmony_ci opcode == OP(SEND_LAST_WITH_INVALIDATE)) 282262306a36Sopenharmony_ci break; 282362306a36Sopenharmony_ci goto nack_inv; 282462306a36Sopenharmony_ci 282562306a36Sopenharmony_ci case OP(RDMA_WRITE_FIRST): 282662306a36Sopenharmony_ci case OP(RDMA_WRITE_MIDDLE): 282762306a36Sopenharmony_ci if (opcode == OP(RDMA_WRITE_MIDDLE) || 282862306a36Sopenharmony_ci opcode == OP(RDMA_WRITE_LAST) || 282962306a36Sopenharmony_ci opcode == OP(RDMA_WRITE_LAST_WITH_IMMEDIATE)) 283062306a36Sopenharmony_ci break; 283162306a36Sopenharmony_ci goto nack_inv; 283262306a36Sopenharmony_ci 283362306a36Sopenharmony_ci default: 283462306a36Sopenharmony_ci if (opcode == OP(SEND_MIDDLE) || 283562306a36Sopenharmony_ci opcode == OP(SEND_LAST) || 283662306a36Sopenharmony_ci opcode == OP(SEND_LAST_WITH_IMMEDIATE) || 283762306a36Sopenharmony_ci opcode == OP(SEND_LAST_WITH_INVALIDATE) || 283862306a36Sopenharmony_ci opcode == OP(RDMA_WRITE_MIDDLE) || 283962306a36Sopenharmony_ci opcode == OP(RDMA_WRITE_LAST) || 284062306a36Sopenharmony_ci opcode == OP(RDMA_WRITE_LAST_WITH_IMMEDIATE)) 284162306a36Sopenharmony_ci goto nack_inv; 284262306a36Sopenharmony_ci /* 284362306a36Sopenharmony_ci * Note that it is up to the requester to not send a new 284462306a36Sopenharmony_ci * RDMA read or atomic operation before receiving an ACK 284562306a36Sopenharmony_ci * for the previous operation. 284662306a36Sopenharmony_ci */ 284762306a36Sopenharmony_ci break; 284862306a36Sopenharmony_ci } 284962306a36Sopenharmony_ci 285062306a36Sopenharmony_ci if (qp->state == IB_QPS_RTR && !(qp->r_flags & RVT_R_COMM_EST)) 285162306a36Sopenharmony_ci rvt_comm_est(qp); 285262306a36Sopenharmony_ci 285362306a36Sopenharmony_ci /* OK, process the packet. */ 285462306a36Sopenharmony_ci switch (opcode) { 285562306a36Sopenharmony_ci case OP(SEND_FIRST): 285662306a36Sopenharmony_ci ret = rvt_get_rwqe(qp, false); 285762306a36Sopenharmony_ci if (ret < 0) 285862306a36Sopenharmony_ci goto nack_op_err; 285962306a36Sopenharmony_ci if (!ret) 286062306a36Sopenharmony_ci goto rnr_nak; 286162306a36Sopenharmony_ci qp->r_rcv_len = 0; 286262306a36Sopenharmony_ci fallthrough; 286362306a36Sopenharmony_ci case OP(SEND_MIDDLE): 286462306a36Sopenharmony_ci case OP(RDMA_WRITE_MIDDLE): 286562306a36Sopenharmony_cisend_middle: 286662306a36Sopenharmony_ci /* Check for invalid length PMTU or posted rwqe len. */ 286762306a36Sopenharmony_ci /* 286862306a36Sopenharmony_ci * There will be no padding for 9B packet but 16B packets 286962306a36Sopenharmony_ci * will come in with some padding since we always add 287062306a36Sopenharmony_ci * CRC and LT bytes which will need to be flit aligned 287162306a36Sopenharmony_ci */ 287262306a36Sopenharmony_ci if (unlikely(tlen != (hdrsize + pmtu + extra_bytes))) 287362306a36Sopenharmony_ci goto nack_inv; 287462306a36Sopenharmony_ci qp->r_rcv_len += pmtu; 287562306a36Sopenharmony_ci if (unlikely(qp->r_rcv_len > qp->r_len)) 287662306a36Sopenharmony_ci goto nack_inv; 287762306a36Sopenharmony_ci rvt_copy_sge(qp, &qp->r_sge, data, pmtu, true, false); 287862306a36Sopenharmony_ci break; 287962306a36Sopenharmony_ci 288062306a36Sopenharmony_ci case OP(RDMA_WRITE_LAST_WITH_IMMEDIATE): 288162306a36Sopenharmony_ci /* consume RWQE */ 288262306a36Sopenharmony_ci ret = rvt_get_rwqe(qp, true); 288362306a36Sopenharmony_ci if (ret < 0) 288462306a36Sopenharmony_ci goto nack_op_err; 288562306a36Sopenharmony_ci if (!ret) 288662306a36Sopenharmony_ci goto rnr_nak; 288762306a36Sopenharmony_ci goto send_last_imm; 288862306a36Sopenharmony_ci 288962306a36Sopenharmony_ci case OP(SEND_ONLY): 289062306a36Sopenharmony_ci case OP(SEND_ONLY_WITH_IMMEDIATE): 289162306a36Sopenharmony_ci case OP(SEND_ONLY_WITH_INVALIDATE): 289262306a36Sopenharmony_ci ret = rvt_get_rwqe(qp, false); 289362306a36Sopenharmony_ci if (ret < 0) 289462306a36Sopenharmony_ci goto nack_op_err; 289562306a36Sopenharmony_ci if (!ret) 289662306a36Sopenharmony_ci goto rnr_nak; 289762306a36Sopenharmony_ci qp->r_rcv_len = 0; 289862306a36Sopenharmony_ci if (opcode == OP(SEND_ONLY)) 289962306a36Sopenharmony_ci goto no_immediate_data; 290062306a36Sopenharmony_ci if (opcode == OP(SEND_ONLY_WITH_INVALIDATE)) 290162306a36Sopenharmony_ci goto send_last_inv; 290262306a36Sopenharmony_ci fallthrough; /* for SEND_ONLY_WITH_IMMEDIATE */ 290362306a36Sopenharmony_ci case OP(SEND_LAST_WITH_IMMEDIATE): 290462306a36Sopenharmony_cisend_last_imm: 290562306a36Sopenharmony_ci wc.ex.imm_data = ohdr->u.imm_data; 290662306a36Sopenharmony_ci wc.wc_flags = IB_WC_WITH_IMM; 290762306a36Sopenharmony_ci goto send_last; 290862306a36Sopenharmony_ci case OP(SEND_LAST_WITH_INVALIDATE): 290962306a36Sopenharmony_cisend_last_inv: 291062306a36Sopenharmony_ci rkey = be32_to_cpu(ohdr->u.ieth); 291162306a36Sopenharmony_ci if (rvt_invalidate_rkey(qp, rkey)) 291262306a36Sopenharmony_ci goto no_immediate_data; 291362306a36Sopenharmony_ci wc.ex.invalidate_rkey = rkey; 291462306a36Sopenharmony_ci wc.wc_flags = IB_WC_WITH_INVALIDATE; 291562306a36Sopenharmony_ci goto send_last; 291662306a36Sopenharmony_ci case OP(RDMA_WRITE_LAST): 291762306a36Sopenharmony_ci copy_last = rvt_is_user_qp(qp); 291862306a36Sopenharmony_ci fallthrough; 291962306a36Sopenharmony_ci case OP(SEND_LAST): 292062306a36Sopenharmony_cino_immediate_data: 292162306a36Sopenharmony_ci wc.wc_flags = 0; 292262306a36Sopenharmony_ci wc.ex.imm_data = 0; 292362306a36Sopenharmony_cisend_last: 292462306a36Sopenharmony_ci /* Check for invalid length. */ 292562306a36Sopenharmony_ci /* LAST len should be >= 1 */ 292662306a36Sopenharmony_ci if (unlikely(tlen < (hdrsize + extra_bytes))) 292762306a36Sopenharmony_ci goto nack_inv; 292862306a36Sopenharmony_ci /* Don't count the CRC(and padding and LT byte for 16B). */ 292962306a36Sopenharmony_ci tlen -= (hdrsize + extra_bytes); 293062306a36Sopenharmony_ci wc.byte_len = tlen + qp->r_rcv_len; 293162306a36Sopenharmony_ci if (unlikely(wc.byte_len > qp->r_len)) 293262306a36Sopenharmony_ci goto nack_inv; 293362306a36Sopenharmony_ci rvt_copy_sge(qp, &qp->r_sge, data, tlen, true, copy_last); 293462306a36Sopenharmony_ci rvt_put_ss(&qp->r_sge); 293562306a36Sopenharmony_ci qp->r_msn++; 293662306a36Sopenharmony_ci if (!__test_and_clear_bit(RVT_R_WRID_VALID, &qp->r_aflags)) 293762306a36Sopenharmony_ci break; 293862306a36Sopenharmony_ci wc.wr_id = qp->r_wr_id; 293962306a36Sopenharmony_ci wc.status = IB_WC_SUCCESS; 294062306a36Sopenharmony_ci if (opcode == OP(RDMA_WRITE_LAST_WITH_IMMEDIATE) || 294162306a36Sopenharmony_ci opcode == OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE)) 294262306a36Sopenharmony_ci wc.opcode = IB_WC_RECV_RDMA_WITH_IMM; 294362306a36Sopenharmony_ci else 294462306a36Sopenharmony_ci wc.opcode = IB_WC_RECV; 294562306a36Sopenharmony_ci wc.qp = &qp->ibqp; 294662306a36Sopenharmony_ci wc.src_qp = qp->remote_qpn; 294762306a36Sopenharmony_ci wc.slid = rdma_ah_get_dlid(&qp->remote_ah_attr) & U16_MAX; 294862306a36Sopenharmony_ci /* 294962306a36Sopenharmony_ci * It seems that IB mandates the presence of an SL in a 295062306a36Sopenharmony_ci * work completion only for the UD transport (see section 295162306a36Sopenharmony_ci * 11.4.2 of IBTA Vol. 1). 295262306a36Sopenharmony_ci * 295362306a36Sopenharmony_ci * However, the way the SL is chosen below is consistent 295462306a36Sopenharmony_ci * with the way that IB/qib works and is trying avoid 295562306a36Sopenharmony_ci * introducing incompatibilities. 295662306a36Sopenharmony_ci * 295762306a36Sopenharmony_ci * See also OPA Vol. 1, section 9.7.6, and table 9-17. 295862306a36Sopenharmony_ci */ 295962306a36Sopenharmony_ci wc.sl = rdma_ah_get_sl(&qp->remote_ah_attr); 296062306a36Sopenharmony_ci /* zero fields that are N/A */ 296162306a36Sopenharmony_ci wc.vendor_err = 0; 296262306a36Sopenharmony_ci wc.pkey_index = 0; 296362306a36Sopenharmony_ci wc.dlid_path_bits = 0; 296462306a36Sopenharmony_ci wc.port_num = 0; 296562306a36Sopenharmony_ci /* Signal completion event if the solicited bit is set. */ 296662306a36Sopenharmony_ci rvt_recv_cq(qp, &wc, ib_bth_is_solicited(ohdr)); 296762306a36Sopenharmony_ci break; 296862306a36Sopenharmony_ci 296962306a36Sopenharmony_ci case OP(RDMA_WRITE_ONLY): 297062306a36Sopenharmony_ci copy_last = rvt_is_user_qp(qp); 297162306a36Sopenharmony_ci fallthrough; 297262306a36Sopenharmony_ci case OP(RDMA_WRITE_FIRST): 297362306a36Sopenharmony_ci case OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE): 297462306a36Sopenharmony_ci if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_WRITE))) 297562306a36Sopenharmony_ci goto nack_inv; 297662306a36Sopenharmony_ci /* consume RWQE */ 297762306a36Sopenharmony_ci reth = &ohdr->u.rc.reth; 297862306a36Sopenharmony_ci qp->r_len = be32_to_cpu(reth->length); 297962306a36Sopenharmony_ci qp->r_rcv_len = 0; 298062306a36Sopenharmony_ci qp->r_sge.sg_list = NULL; 298162306a36Sopenharmony_ci if (qp->r_len != 0) { 298262306a36Sopenharmony_ci u32 rkey = be32_to_cpu(reth->rkey); 298362306a36Sopenharmony_ci u64 vaddr = get_ib_reth_vaddr(reth); 298462306a36Sopenharmony_ci int ok; 298562306a36Sopenharmony_ci 298662306a36Sopenharmony_ci /* Check rkey & NAK */ 298762306a36Sopenharmony_ci ok = rvt_rkey_ok(qp, &qp->r_sge.sge, qp->r_len, vaddr, 298862306a36Sopenharmony_ci rkey, IB_ACCESS_REMOTE_WRITE); 298962306a36Sopenharmony_ci if (unlikely(!ok)) 299062306a36Sopenharmony_ci goto nack_acc; 299162306a36Sopenharmony_ci qp->r_sge.num_sge = 1; 299262306a36Sopenharmony_ci } else { 299362306a36Sopenharmony_ci qp->r_sge.num_sge = 0; 299462306a36Sopenharmony_ci qp->r_sge.sge.mr = NULL; 299562306a36Sopenharmony_ci qp->r_sge.sge.vaddr = NULL; 299662306a36Sopenharmony_ci qp->r_sge.sge.length = 0; 299762306a36Sopenharmony_ci qp->r_sge.sge.sge_length = 0; 299862306a36Sopenharmony_ci } 299962306a36Sopenharmony_ci if (opcode == OP(RDMA_WRITE_FIRST)) 300062306a36Sopenharmony_ci goto send_middle; 300162306a36Sopenharmony_ci else if (opcode == OP(RDMA_WRITE_ONLY)) 300262306a36Sopenharmony_ci goto no_immediate_data; 300362306a36Sopenharmony_ci ret = rvt_get_rwqe(qp, true); 300462306a36Sopenharmony_ci if (ret < 0) 300562306a36Sopenharmony_ci goto nack_op_err; 300662306a36Sopenharmony_ci if (!ret) { 300762306a36Sopenharmony_ci /* peer will send again */ 300862306a36Sopenharmony_ci rvt_put_ss(&qp->r_sge); 300962306a36Sopenharmony_ci goto rnr_nak; 301062306a36Sopenharmony_ci } 301162306a36Sopenharmony_ci wc.ex.imm_data = ohdr->u.rc.imm_data; 301262306a36Sopenharmony_ci wc.wc_flags = IB_WC_WITH_IMM; 301362306a36Sopenharmony_ci goto send_last; 301462306a36Sopenharmony_ci 301562306a36Sopenharmony_ci case OP(RDMA_READ_REQUEST): { 301662306a36Sopenharmony_ci struct rvt_ack_entry *e; 301762306a36Sopenharmony_ci u32 len; 301862306a36Sopenharmony_ci u8 next; 301962306a36Sopenharmony_ci 302062306a36Sopenharmony_ci if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_READ))) 302162306a36Sopenharmony_ci goto nack_inv; 302262306a36Sopenharmony_ci next = qp->r_head_ack_queue + 1; 302362306a36Sopenharmony_ci /* s_ack_queue is size rvt_size_atomic()+1 so use > not >= */ 302462306a36Sopenharmony_ci if (next > rvt_size_atomic(ib_to_rvt(qp->ibqp.device))) 302562306a36Sopenharmony_ci next = 0; 302662306a36Sopenharmony_ci spin_lock_irqsave(&qp->s_lock, flags); 302762306a36Sopenharmony_ci if (unlikely(next == qp->s_acked_ack_queue)) { 302862306a36Sopenharmony_ci if (!qp->s_ack_queue[next].sent) 302962306a36Sopenharmony_ci goto nack_inv_unlck; 303062306a36Sopenharmony_ci update_ack_queue(qp, next); 303162306a36Sopenharmony_ci } 303262306a36Sopenharmony_ci e = &qp->s_ack_queue[qp->r_head_ack_queue]; 303362306a36Sopenharmony_ci release_rdma_sge_mr(e); 303462306a36Sopenharmony_ci reth = &ohdr->u.rc.reth; 303562306a36Sopenharmony_ci len = be32_to_cpu(reth->length); 303662306a36Sopenharmony_ci if (len) { 303762306a36Sopenharmony_ci u32 rkey = be32_to_cpu(reth->rkey); 303862306a36Sopenharmony_ci u64 vaddr = get_ib_reth_vaddr(reth); 303962306a36Sopenharmony_ci int ok; 304062306a36Sopenharmony_ci 304162306a36Sopenharmony_ci /* Check rkey & NAK */ 304262306a36Sopenharmony_ci ok = rvt_rkey_ok(qp, &e->rdma_sge, len, vaddr, 304362306a36Sopenharmony_ci rkey, IB_ACCESS_REMOTE_READ); 304462306a36Sopenharmony_ci if (unlikely(!ok)) 304562306a36Sopenharmony_ci goto nack_acc_unlck; 304662306a36Sopenharmony_ci /* 304762306a36Sopenharmony_ci * Update the next expected PSN. We add 1 later 304862306a36Sopenharmony_ci * below, so only add the remainder here. 304962306a36Sopenharmony_ci */ 305062306a36Sopenharmony_ci qp->r_psn += rvt_div_mtu(qp, len - 1); 305162306a36Sopenharmony_ci } else { 305262306a36Sopenharmony_ci e->rdma_sge.mr = NULL; 305362306a36Sopenharmony_ci e->rdma_sge.vaddr = NULL; 305462306a36Sopenharmony_ci e->rdma_sge.length = 0; 305562306a36Sopenharmony_ci e->rdma_sge.sge_length = 0; 305662306a36Sopenharmony_ci } 305762306a36Sopenharmony_ci e->opcode = opcode; 305862306a36Sopenharmony_ci e->sent = 0; 305962306a36Sopenharmony_ci e->psn = psn; 306062306a36Sopenharmony_ci e->lpsn = qp->r_psn; 306162306a36Sopenharmony_ci /* 306262306a36Sopenharmony_ci * We need to increment the MSN here instead of when we 306362306a36Sopenharmony_ci * finish sending the result since a duplicate request would 306462306a36Sopenharmony_ci * increment it more than once. 306562306a36Sopenharmony_ci */ 306662306a36Sopenharmony_ci qp->r_msn++; 306762306a36Sopenharmony_ci qp->r_psn++; 306862306a36Sopenharmony_ci qp->r_state = opcode; 306962306a36Sopenharmony_ci qp->r_nak_state = 0; 307062306a36Sopenharmony_ci qp->r_head_ack_queue = next; 307162306a36Sopenharmony_ci qpriv->r_tid_alloc = qp->r_head_ack_queue; 307262306a36Sopenharmony_ci 307362306a36Sopenharmony_ci /* Schedule the send engine. */ 307462306a36Sopenharmony_ci qp->s_flags |= RVT_S_RESP_PENDING; 307562306a36Sopenharmony_ci if (fecn) 307662306a36Sopenharmony_ci qp->s_flags |= RVT_S_ECN; 307762306a36Sopenharmony_ci hfi1_schedule_send(qp); 307862306a36Sopenharmony_ci 307962306a36Sopenharmony_ci spin_unlock_irqrestore(&qp->s_lock, flags); 308062306a36Sopenharmony_ci return; 308162306a36Sopenharmony_ci } 308262306a36Sopenharmony_ci 308362306a36Sopenharmony_ci case OP(COMPARE_SWAP): 308462306a36Sopenharmony_ci case OP(FETCH_ADD): { 308562306a36Sopenharmony_ci struct ib_atomic_eth *ateth = &ohdr->u.atomic_eth; 308662306a36Sopenharmony_ci u64 vaddr = get_ib_ateth_vaddr(ateth); 308762306a36Sopenharmony_ci bool opfn = opcode == OP(COMPARE_SWAP) && 308862306a36Sopenharmony_ci vaddr == HFI1_VERBS_E_ATOMIC_VADDR; 308962306a36Sopenharmony_ci struct rvt_ack_entry *e; 309062306a36Sopenharmony_ci atomic64_t *maddr; 309162306a36Sopenharmony_ci u64 sdata; 309262306a36Sopenharmony_ci u32 rkey; 309362306a36Sopenharmony_ci u8 next; 309462306a36Sopenharmony_ci 309562306a36Sopenharmony_ci if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_ATOMIC) && 309662306a36Sopenharmony_ci !opfn)) 309762306a36Sopenharmony_ci goto nack_inv; 309862306a36Sopenharmony_ci next = qp->r_head_ack_queue + 1; 309962306a36Sopenharmony_ci if (next > rvt_size_atomic(ib_to_rvt(qp->ibqp.device))) 310062306a36Sopenharmony_ci next = 0; 310162306a36Sopenharmony_ci spin_lock_irqsave(&qp->s_lock, flags); 310262306a36Sopenharmony_ci if (unlikely(next == qp->s_acked_ack_queue)) { 310362306a36Sopenharmony_ci if (!qp->s_ack_queue[next].sent) 310462306a36Sopenharmony_ci goto nack_inv_unlck; 310562306a36Sopenharmony_ci update_ack_queue(qp, next); 310662306a36Sopenharmony_ci } 310762306a36Sopenharmony_ci e = &qp->s_ack_queue[qp->r_head_ack_queue]; 310862306a36Sopenharmony_ci release_rdma_sge_mr(e); 310962306a36Sopenharmony_ci /* Process OPFN special virtual address */ 311062306a36Sopenharmony_ci if (opfn) { 311162306a36Sopenharmony_ci opfn_conn_response(qp, e, ateth); 311262306a36Sopenharmony_ci goto ack; 311362306a36Sopenharmony_ci } 311462306a36Sopenharmony_ci if (unlikely(vaddr & (sizeof(u64) - 1))) 311562306a36Sopenharmony_ci goto nack_inv_unlck; 311662306a36Sopenharmony_ci rkey = be32_to_cpu(ateth->rkey); 311762306a36Sopenharmony_ci /* Check rkey & NAK */ 311862306a36Sopenharmony_ci if (unlikely(!rvt_rkey_ok(qp, &qp->r_sge.sge, sizeof(u64), 311962306a36Sopenharmony_ci vaddr, rkey, 312062306a36Sopenharmony_ci IB_ACCESS_REMOTE_ATOMIC))) 312162306a36Sopenharmony_ci goto nack_acc_unlck; 312262306a36Sopenharmony_ci /* Perform atomic OP and save result. */ 312362306a36Sopenharmony_ci maddr = (atomic64_t *)qp->r_sge.sge.vaddr; 312462306a36Sopenharmony_ci sdata = get_ib_ateth_swap(ateth); 312562306a36Sopenharmony_ci e->atomic_data = (opcode == OP(FETCH_ADD)) ? 312662306a36Sopenharmony_ci (u64)atomic64_add_return(sdata, maddr) - sdata : 312762306a36Sopenharmony_ci (u64)cmpxchg((u64 *)qp->r_sge.sge.vaddr, 312862306a36Sopenharmony_ci get_ib_ateth_compare(ateth), 312962306a36Sopenharmony_ci sdata); 313062306a36Sopenharmony_ci rvt_put_mr(qp->r_sge.sge.mr); 313162306a36Sopenharmony_ci qp->r_sge.num_sge = 0; 313262306a36Sopenharmony_ciack: 313362306a36Sopenharmony_ci e->opcode = opcode; 313462306a36Sopenharmony_ci e->sent = 0; 313562306a36Sopenharmony_ci e->psn = psn; 313662306a36Sopenharmony_ci e->lpsn = psn; 313762306a36Sopenharmony_ci qp->r_msn++; 313862306a36Sopenharmony_ci qp->r_psn++; 313962306a36Sopenharmony_ci qp->r_state = opcode; 314062306a36Sopenharmony_ci qp->r_nak_state = 0; 314162306a36Sopenharmony_ci qp->r_head_ack_queue = next; 314262306a36Sopenharmony_ci qpriv->r_tid_alloc = qp->r_head_ack_queue; 314362306a36Sopenharmony_ci 314462306a36Sopenharmony_ci /* Schedule the send engine. */ 314562306a36Sopenharmony_ci qp->s_flags |= RVT_S_RESP_PENDING; 314662306a36Sopenharmony_ci if (fecn) 314762306a36Sopenharmony_ci qp->s_flags |= RVT_S_ECN; 314862306a36Sopenharmony_ci hfi1_schedule_send(qp); 314962306a36Sopenharmony_ci 315062306a36Sopenharmony_ci spin_unlock_irqrestore(&qp->s_lock, flags); 315162306a36Sopenharmony_ci return; 315262306a36Sopenharmony_ci } 315362306a36Sopenharmony_ci 315462306a36Sopenharmony_ci default: 315562306a36Sopenharmony_ci /* NAK unknown opcodes. */ 315662306a36Sopenharmony_ci goto nack_inv; 315762306a36Sopenharmony_ci } 315862306a36Sopenharmony_ci qp->r_psn++; 315962306a36Sopenharmony_ci qp->r_state = opcode; 316062306a36Sopenharmony_ci qp->r_ack_psn = psn; 316162306a36Sopenharmony_ci qp->r_nak_state = 0; 316262306a36Sopenharmony_ci /* Send an ACK if requested or required. */ 316362306a36Sopenharmony_ci if (psn & IB_BTH_REQ_ACK || fecn) { 316462306a36Sopenharmony_ci if (packet->numpkt == 0 || fecn || 316562306a36Sopenharmony_ci qp->r_adefered >= HFI1_PSN_CREDIT) { 316662306a36Sopenharmony_ci rc_cancel_ack(qp); 316762306a36Sopenharmony_ci goto send_ack; 316862306a36Sopenharmony_ci } 316962306a36Sopenharmony_ci qp->r_adefered++; 317062306a36Sopenharmony_ci rc_defered_ack(rcd, qp); 317162306a36Sopenharmony_ci } 317262306a36Sopenharmony_ci return; 317362306a36Sopenharmony_ci 317462306a36Sopenharmony_cirnr_nak: 317562306a36Sopenharmony_ci qp->r_nak_state = qp->r_min_rnr_timer | IB_RNR_NAK; 317662306a36Sopenharmony_ci qp->r_ack_psn = qp->r_psn; 317762306a36Sopenharmony_ci /* Queue RNR NAK for later */ 317862306a36Sopenharmony_ci rc_defered_ack(rcd, qp); 317962306a36Sopenharmony_ci return; 318062306a36Sopenharmony_ci 318162306a36Sopenharmony_cinack_op_err: 318262306a36Sopenharmony_ci rvt_rc_error(qp, IB_WC_LOC_QP_OP_ERR); 318362306a36Sopenharmony_ci qp->r_nak_state = IB_NAK_REMOTE_OPERATIONAL_ERROR; 318462306a36Sopenharmony_ci qp->r_ack_psn = qp->r_psn; 318562306a36Sopenharmony_ci /* Queue NAK for later */ 318662306a36Sopenharmony_ci rc_defered_ack(rcd, qp); 318762306a36Sopenharmony_ci return; 318862306a36Sopenharmony_ci 318962306a36Sopenharmony_cinack_inv_unlck: 319062306a36Sopenharmony_ci spin_unlock_irqrestore(&qp->s_lock, flags); 319162306a36Sopenharmony_cinack_inv: 319262306a36Sopenharmony_ci rvt_rc_error(qp, IB_WC_LOC_QP_OP_ERR); 319362306a36Sopenharmony_ci qp->r_nak_state = IB_NAK_INVALID_REQUEST; 319462306a36Sopenharmony_ci qp->r_ack_psn = qp->r_psn; 319562306a36Sopenharmony_ci /* Queue NAK for later */ 319662306a36Sopenharmony_ci rc_defered_ack(rcd, qp); 319762306a36Sopenharmony_ci return; 319862306a36Sopenharmony_ci 319962306a36Sopenharmony_cinack_acc_unlck: 320062306a36Sopenharmony_ci spin_unlock_irqrestore(&qp->s_lock, flags); 320162306a36Sopenharmony_cinack_acc: 320262306a36Sopenharmony_ci rvt_rc_error(qp, IB_WC_LOC_PROT_ERR); 320362306a36Sopenharmony_ci qp->r_nak_state = IB_NAK_REMOTE_ACCESS_ERROR; 320462306a36Sopenharmony_ci qp->r_ack_psn = qp->r_psn; 320562306a36Sopenharmony_cisend_ack: 320662306a36Sopenharmony_ci hfi1_send_rc_ack(packet, fecn); 320762306a36Sopenharmony_ci} 320862306a36Sopenharmony_ci 320962306a36Sopenharmony_civoid hfi1_rc_hdrerr( 321062306a36Sopenharmony_ci struct hfi1_ctxtdata *rcd, 321162306a36Sopenharmony_ci struct hfi1_packet *packet, 321262306a36Sopenharmony_ci struct rvt_qp *qp) 321362306a36Sopenharmony_ci{ 321462306a36Sopenharmony_ci struct hfi1_ibport *ibp = rcd_to_iport(rcd); 321562306a36Sopenharmony_ci int diff; 321662306a36Sopenharmony_ci u32 opcode; 321762306a36Sopenharmony_ci u32 psn; 321862306a36Sopenharmony_ci 321962306a36Sopenharmony_ci if (hfi1_ruc_check_hdr(ibp, packet)) 322062306a36Sopenharmony_ci return; 322162306a36Sopenharmony_ci 322262306a36Sopenharmony_ci psn = ib_bth_get_psn(packet->ohdr); 322362306a36Sopenharmony_ci opcode = ib_bth_get_opcode(packet->ohdr); 322462306a36Sopenharmony_ci 322562306a36Sopenharmony_ci /* Only deal with RDMA Writes for now */ 322662306a36Sopenharmony_ci if (opcode < IB_OPCODE_RC_RDMA_READ_RESPONSE_FIRST) { 322762306a36Sopenharmony_ci diff = delta_psn(psn, qp->r_psn); 322862306a36Sopenharmony_ci if (!qp->r_nak_state && diff >= 0) { 322962306a36Sopenharmony_ci ibp->rvp.n_rc_seqnak++; 323062306a36Sopenharmony_ci qp->r_nak_state = IB_NAK_PSN_ERROR; 323162306a36Sopenharmony_ci /* Use the expected PSN. */ 323262306a36Sopenharmony_ci qp->r_ack_psn = qp->r_psn; 323362306a36Sopenharmony_ci /* 323462306a36Sopenharmony_ci * Wait to send the sequence 323562306a36Sopenharmony_ci * NAK until all packets 323662306a36Sopenharmony_ci * in the receive queue have 323762306a36Sopenharmony_ci * been processed. 323862306a36Sopenharmony_ci * Otherwise, we end up 323962306a36Sopenharmony_ci * propagating congestion. 324062306a36Sopenharmony_ci */ 324162306a36Sopenharmony_ci rc_defered_ack(rcd, qp); 324262306a36Sopenharmony_ci } /* Out of sequence NAK */ 324362306a36Sopenharmony_ci } /* QP Request NAKs */ 324462306a36Sopenharmony_ci} 3245