xref: /OK3568_Linux_fs/kernel/drivers/infiniband/hw/hfi1/opfn.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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