1/**************************************************************************
2
3Copyright (c) 2007, 2008 Chelsio Inc.
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without
7modification, are permitted provided that the following conditions are met:
8
9 1. Redistributions of source code must retain the above copyright notice,
10    this list of conditions and the following disclaimer.
11
12 2. Neither the name of the Chelsio Corporation nor the names of its
13    contributors may be used to endorse or promote products derived from
14    this software without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26POSSIBILITY OF SUCH DAMAGE.
27
28$FreeBSD: stable/10/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.h 309378 2016-12-01 23:38:52Z jhb $
29
30***************************************************************************/
31
32#ifndef _IWCH_CM_H_
33#define _IWCH_CM_H_
34#include <rdma/ib_verbs.h>
35#include <rdma/iw_cm.h>
36#include <sys/refcount.h>
37#include <sys/condvar.h>
38#include <sys/proc.h>
39
40
41#define MPA_KEY_REQ "MPA ID Req Frame"
42#define MPA_KEY_REP "MPA ID Rep Frame"
43
44#define MPA_MAX_PRIVATE_DATA	256
45#define MPA_REV			0	/* XXX - amso1100 uses rev 0 ! */
46#define MPA_REJECT		0x20
47#define MPA_CRC			0x40
48#define MPA_MARKERS		0x80
49#define MPA_FLAGS_MASK		0xE0
50
51#define put_ep(ep) { \
52	CTR4(KTR_IW_CXGB, "put_ep (via %s:%u) ep %p refcnt %d", __FUNCTION__, __LINE__,  \
53	     ep, atomic_load_acq_int(&((ep)->refcount))); \
54	if (refcount_release(&((ep)->refcount)))  \
55		__free_ep(ep); \
56}
57
58#define get_ep(ep) { \
59	CTR4(KTR_IW_CXGB, "get_ep (via %s:%u) ep %p, refcnt %d", __FUNCTION__, __LINE__, \
60	     ep, atomic_load_acq_int(&((ep)->refcount))); \
61	refcount_acquire(&((ep)->refcount));	  \
62}
63
64struct mpa_message {
65	u8 key[16];
66	u8 flags;
67	u8 revision;
68	__be16 private_data_size;
69	u8 private_data[0];
70};
71
72struct terminate_message {
73	u8 layer_etype;
74	u8 ecode;
75	__be16 hdrct_rsvd;
76	u8 len_hdrs[0];
77};
78
79#define TERM_MAX_LENGTH (sizeof(struct terminate_message) + 2 + 18 + 28)
80
81enum iwch_layers_types {
82	LAYER_RDMAP		= 0x00,
83	LAYER_DDP		= 0x10,
84	LAYER_MPA		= 0x20,
85	RDMAP_LOCAL_CATA	= 0x00,
86	RDMAP_REMOTE_PROT	= 0x01,
87	RDMAP_REMOTE_OP		= 0x02,
88	DDP_LOCAL_CATA		= 0x00,
89	DDP_TAGGED_ERR		= 0x01,
90	DDP_UNTAGGED_ERR	= 0x02,
91	DDP_LLP			= 0x03
92};
93
94enum iwch_rdma_ecodes {
95	RDMAP_INV_STAG		= 0x00,
96	RDMAP_BASE_BOUNDS	= 0x01,
97	RDMAP_ACC_VIOL		= 0x02,
98	RDMAP_STAG_NOT_ASSOC	= 0x03,
99	RDMAP_TO_WRAP		= 0x04,
100	RDMAP_INV_VERS		= 0x05,
101	RDMAP_INV_OPCODE	= 0x06,
102	RDMAP_STREAM_CATA	= 0x07,
103	RDMAP_GLOBAL_CATA	= 0x08,
104	RDMAP_CANT_INV_STAG	= 0x09,
105	RDMAP_UNSPECIFIED	= 0xff
106};
107
108enum iwch_ddp_ecodes {
109	DDPT_INV_STAG		= 0x00,
110	DDPT_BASE_BOUNDS	= 0x01,
111	DDPT_STAG_NOT_ASSOC	= 0x02,
112	DDPT_TO_WRAP		= 0x03,
113	DDPT_INV_VERS		= 0x04,
114	DDPU_INV_QN		= 0x01,
115	DDPU_INV_MSN_NOBUF	= 0x02,
116	DDPU_INV_MSN_RANGE	= 0x03,
117	DDPU_INV_MO		= 0x04,
118	DDPU_MSG_TOOBIG		= 0x05,
119	DDPU_INV_VERS		= 0x06
120};
121
122enum iwch_mpa_ecodes {
123	MPA_CRC_ERR		= 0x02,
124	MPA_MARKER_ERR		= 0x03
125};
126
127enum iwch_ep_state {
128	IDLE = 0,
129	LISTEN,
130	CONNECTING,
131	MPA_REQ_WAIT,
132	MPA_REQ_SENT,
133	MPA_REQ_RCVD,
134	MPA_REP_SENT,
135	FPDU_MODE,
136	ABORTING,
137	CLOSING,
138	MORIBUND,
139	DEAD,
140};
141
142enum iwch_ep_flags {
143	PEER_ABORT_IN_PROGRESS	= (1 << 0),
144	ABORT_REQ_IN_PROGRESS	= (1 << 1),
145};
146
147struct iwch_ep_common {
148	TAILQ_ENTRY(iwch_ep_common) entry;
149	struct iw_cm_id *cm_id;
150	struct iwch_qp *qp;
151	struct toedev *tdev;
152	enum iwch_ep_state state;
153	u_int refcount;
154	struct cv waitq;
155	struct mtx lock;
156	struct sockaddr_in local_addr;
157	struct sockaddr_in remote_addr;
158	int rpl_err;
159	int rpl_done;
160	struct thread *thread;
161	struct socket *so;
162};
163
164struct iwch_listen_ep {
165	struct iwch_ep_common com;
166	unsigned int stid;
167	int backlog;
168};
169
170struct iwch_ep {
171	struct iwch_ep_common com;
172	struct iwch_ep *parent_ep;
173	struct callout timer;
174	unsigned int atid;
175	u32 hwtid;
176	u32 snd_seq;
177	u32 rcv_seq;
178	struct l2t_entry *l2t;
179	struct mbuf *mpa_mbuf;
180	struct iwch_mpa_attributes mpa_attr;
181	unsigned int mpa_pkt_len;
182	u8 mpa_pkt[sizeof(struct mpa_message) + MPA_MAX_PRIVATE_DATA];
183	u8 tos;
184	u16 emss;
185	u16 plen;
186	u32 ird;
187	u32 ord;
188	u32 flags;
189};
190
191static inline struct iwch_ep *to_ep(struct iw_cm_id *cm_id)
192{
193	return cm_id->provider_data;
194}
195
196static inline struct iwch_listen_ep *to_listen_ep(struct iw_cm_id *cm_id)
197{
198	return cm_id->provider_data;
199}
200
201static inline int compute_wscale(int win)
202{
203	int wscale = 0;
204
205	while (wscale < 14 && (65535<<wscale) < win)
206		wscale++;
207	return wscale;
208}
209
210static __inline void
211iwch_wait(struct cv *cv, struct mtx *lock, int *rpl_done)
212{
213	mtx_lock(lock);
214	if (!*rpl_done) {
215		CTR0(KTR_IW_CXGB, "sleeping for rpl_done\n");
216		cv_wait_unlock(cv, lock);
217	}
218	CTR1(KTR_IW_CXGB, "*rpl_done=%d\n", *rpl_done);
219}
220
221static __inline void
222iwch_wakeup(struct cv *cv, struct mtx *lock, int *rpl_done)
223{
224	mtx_lock(lock);
225	*rpl_done=1;
226	CTR0(KTR_IW_CXGB, "wakeup for rpl_done\n");
227	cv_broadcast(cv);
228	mtx_unlock(lock);
229}
230
231/* CM prototypes */
232
233int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param);
234int iwch_create_listen_ep(struct iw_cm_id *cm_id, int backlog);
235void iwch_destroy_listen_ep(struct iw_cm_id *cm_id);
236int iwch_reject_cr(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len);
237int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param);
238int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, int flags);
239void __free_ep(struct iwch_ep_common *ep);
240void iwch_rearp(struct iwch_ep *ep);
241int iwch_ep_redirect(void *ctx, struct rtentry *old, struct rtentry *new, struct l2t_entry *l2t);
242
243int iwch_cm_init(void);
244void iwch_cm_term(void);
245void iwch_cm_init_cpl(struct adapter *);
246void iwch_cm_term_cpl(struct adapter *);
247
248#endif				/* _IWCH_CM_H_ */
249