1*4882a593Smuzhiyun /* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright(c) 2018 Intel Corporation. 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun */ 6*4882a593Smuzhiyun #ifndef _HFI1_OPFN_H 7*4882a593Smuzhiyun #define _HFI1_OPFN_H 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun /** 10*4882a593Smuzhiyun * DOC: Omni Path Feature Negotion (OPFN) 11*4882a593Smuzhiyun * 12*4882a593Smuzhiyun * OPFN is a discovery protocol for Intel Omni-Path fabric that 13*4882a593Smuzhiyun * allows two RC QPs to negotiate a common feature that both QPs 14*4882a593Smuzhiyun * can support. Currently, the only OPA feature that OPFN 15*4882a593Smuzhiyun * supports is TID RDMA. 16*4882a593Smuzhiyun * 17*4882a593Smuzhiyun * Architecture 18*4882a593Smuzhiyun * 19*4882a593Smuzhiyun * OPFN involves the communication between two QPs on the HFI 20*4882a593Smuzhiyun * level on an Omni-Path fabric, and ULPs have no knowledge of 21*4882a593Smuzhiyun * OPFN at all. 22*4882a593Smuzhiyun * 23*4882a593Smuzhiyun * Implementation 24*4882a593Smuzhiyun * 25*4882a593Smuzhiyun * OPFN extends the existing IB RC protocol with the following 26*4882a593Smuzhiyun * changes: 27*4882a593Smuzhiyun * -- Uses Bit 24 (reserved) of DWORD 1 of Base Transport 28*4882a593Smuzhiyun * Header (BTH1) to indicate that the RC QP supports OPFN; 29*4882a593Smuzhiyun * -- Uses a combination of RC COMPARE_SWAP opcode (0x13) and 30*4882a593Smuzhiyun * the address U64_MAX (0xFFFFFFFFFFFFFFFF) as an OPFN 31*4882a593Smuzhiyun * request; The 64-bit data carried with the request/response 32*4882a593Smuzhiyun * contains the parameters for negotiation and will be 33*4882a593Smuzhiyun * defined in tid_rdma.c file; 34*4882a593Smuzhiyun * -- Defines IB_WR_RESERVED3 as IB_WR_OPFN. 35*4882a593Smuzhiyun * 36*4882a593Smuzhiyun * The OPFN communication will be triggered when an RC QP 37*4882a593Smuzhiyun * receives a request with Bit 24 of BTH1 set. The responder QP 38*4882a593Smuzhiyun * will then post send an OPFN request with its local 39*4882a593Smuzhiyun * parameters, which will be sent to the requester QP once all 40*4882a593Smuzhiyun * existing requests on the responder QP side have been sent. 41*4882a593Smuzhiyun * Once the requester QP receives the OPFN request, it will 42*4882a593Smuzhiyun * keep a copy of the responder QP's parameters, and return a 43*4882a593Smuzhiyun * response packet with its own local parameters. The responder 44*4882a593Smuzhiyun * QP receives the response packet and keeps a copy of the requester 45*4882a593Smuzhiyun * QP's parameters. After this exchange, each side has the parameters 46*4882a593Smuzhiyun * for both sides and therefore can select the right parameters 47*4882a593Smuzhiyun * for future transactions 48*4882a593Smuzhiyun */ 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun #include <linux/workqueue.h> 51*4882a593Smuzhiyun #include <rdma/ib_verbs.h> 52*4882a593Smuzhiyun #include <rdma/rdmavt_qp.h> 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun /* STL Verbs Extended */ 55*4882a593Smuzhiyun #define IB_BTHE_E_SHIFT 24 56*4882a593Smuzhiyun #define HFI1_VERBS_E_ATOMIC_VADDR U64_MAX 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun enum hfi1_opfn_codes { 59*4882a593Smuzhiyun STL_VERBS_EXTD_NONE = 0, 60*4882a593Smuzhiyun STL_VERBS_EXTD_TID_RDMA, 61*4882a593Smuzhiyun STL_VERBS_EXTD_MAX 62*4882a593Smuzhiyun }; 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun struct hfi1_opfn_data { 65*4882a593Smuzhiyun u8 extended; 66*4882a593Smuzhiyun u16 requested; 67*4882a593Smuzhiyun u16 completed; 68*4882a593Smuzhiyun enum hfi1_opfn_codes curr; 69*4882a593Smuzhiyun /* serialize opfn function calls */ 70*4882a593Smuzhiyun spinlock_t lock; 71*4882a593Smuzhiyun struct work_struct opfn_work; 72*4882a593Smuzhiyun }; 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun /* WR opcode for OPFN */ 75*4882a593Smuzhiyun #define IB_WR_OPFN IB_WR_RESERVED3 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun void opfn_send_conn_request(struct work_struct *work); 78*4882a593Smuzhiyun void opfn_conn_response(struct rvt_qp *qp, struct rvt_ack_entry *e, 79*4882a593Smuzhiyun struct ib_atomic_eth *ateth); 80*4882a593Smuzhiyun void opfn_conn_reply(struct rvt_qp *qp, u64 data); 81*4882a593Smuzhiyun void opfn_conn_error(struct rvt_qp *qp); 82*4882a593Smuzhiyun void opfn_qp_init(struct rvt_qp *qp, struct ib_qp_attr *attr, int attr_mask); 83*4882a593Smuzhiyun void opfn_trigger_conn_request(struct rvt_qp *qp, u32 bth1); 84*4882a593Smuzhiyun int opfn_init(void); 85*4882a593Smuzhiyun void opfn_exit(void); 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun #endif /* _HFI1_OPFN_H */ 88