1178786Skmacy/**************************************************************************
2178786Skmacy
3178786SkmacyCopyright (c) 2007, 2008 Chelsio Inc.
4178786SkmacyAll rights reserved.
5178786Skmacy
6178786SkmacyRedistribution and use in source and binary forms, with or without
7178786Skmacymodification, are permitted provided that the following conditions are met:
8178786Skmacy
9178786Skmacy 1. Redistributions of source code must retain the above copyright notice,
10178786Skmacy    this list of conditions and the following disclaimer.
11178786Skmacy
12178786Skmacy 2. Neither the name of the Chelsio Corporation nor the names of its
13178786Skmacy    contributors may be used to endorse or promote products derived from
14178786Skmacy    this software without specific prior written permission.
15178786Skmacy
16178786SkmacyTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17178786SkmacyAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18178786SkmacyIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19178786SkmacyARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20178786SkmacyLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21178786SkmacyCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22178786SkmacySUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23178786SkmacyINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24178786SkmacyCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25178786SkmacyARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26178786SkmacyPOSSIBILITY OF SUCH DAMAGE.
27178786Skmacy
28178786Skmacy$FreeBSD$
29178786Skmacy
30178786Skmacy***************************************************************************/
31178786Skmacy
32178786Skmacy#ifndef _IWCH_CM_H_
33178786Skmacy#define _IWCH_CM_H_
34237263Snp#include <rdma/ib_verbs.h>
35237263Snp#include <rdma/iw_cm.h>
36178786Skmacy#include <sys/refcount.h>
37178786Skmacy#include <sys/condvar.h>
38178786Skmacy#include <sys/proc.h>
39178786Skmacy
40178786Skmacy
41178786Skmacy#define MPA_KEY_REQ "MPA ID Req Frame"
42178786Skmacy#define MPA_KEY_REP "MPA ID Rep Frame"
43178786Skmacy
44178786Skmacy#define MPA_MAX_PRIVATE_DATA	256
45237263Snp#define MPA_REV			0	/* XXX - amso1100 uses rev 0 ! */
46178786Skmacy#define MPA_REJECT		0x20
47178786Skmacy#define MPA_CRC			0x40
48178786Skmacy#define MPA_MARKERS		0x80
49178786Skmacy#define MPA_FLAGS_MASK		0xE0
50178786Skmacy
51178786Skmacy#define put_ep(ep) { \
52237263Snp	CTR4(KTR_IW_CXGB, "put_ep (via %s:%u) ep %p refcnt %d", __FUNCTION__, __LINE__,  \
53178786Skmacy	     ep, atomic_load_acq_int(&((ep)->refcount))); \
54178786Skmacy	if (refcount_release(&((ep)->refcount)))  \
55178786Skmacy		__free_ep(ep); \
56178786Skmacy}
57178786Skmacy
58178786Skmacy#define get_ep(ep) { \
59237263Snp	CTR4(KTR_IW_CXGB, "get_ep (via %s:%u) ep %p, refcnt %d", __FUNCTION__, __LINE__, \
60178786Skmacy	     ep, atomic_load_acq_int(&((ep)->refcount))); \
61178786Skmacy	refcount_acquire(&((ep)->refcount));	  \
62178786Skmacy}
63178786Skmacy
64178786Skmacystruct mpa_message {
65178786Skmacy	u8 key[16];
66178786Skmacy	u8 flags;
67178786Skmacy	u8 revision;
68178786Skmacy	__be16 private_data_size;
69178786Skmacy	u8 private_data[0];
70178786Skmacy};
71178786Skmacy
72178786Skmacystruct terminate_message {
73178786Skmacy	u8 layer_etype;
74178786Skmacy	u8 ecode;
75178786Skmacy	__be16 hdrct_rsvd;
76178786Skmacy	u8 len_hdrs[0];
77178786Skmacy};
78178786Skmacy
79178786Skmacy#define TERM_MAX_LENGTH (sizeof(struct terminate_message) + 2 + 18 + 28)
80178786Skmacy
81178786Skmacyenum iwch_layers_types {
82178786Skmacy	LAYER_RDMAP		= 0x00,
83178786Skmacy	LAYER_DDP		= 0x10,
84178786Skmacy	LAYER_MPA		= 0x20,
85178786Skmacy	RDMAP_LOCAL_CATA	= 0x00,
86178786Skmacy	RDMAP_REMOTE_PROT	= 0x01,
87178786Skmacy	RDMAP_REMOTE_OP		= 0x02,
88178786Skmacy	DDP_LOCAL_CATA		= 0x00,
89178786Skmacy	DDP_TAGGED_ERR		= 0x01,
90178786Skmacy	DDP_UNTAGGED_ERR	= 0x02,
91178786Skmacy	DDP_LLP			= 0x03
92178786Skmacy};
93178786Skmacy
94178786Skmacyenum iwch_rdma_ecodes {
95178786Skmacy	RDMAP_INV_STAG		= 0x00,
96178786Skmacy	RDMAP_BASE_BOUNDS	= 0x01,
97178786Skmacy	RDMAP_ACC_VIOL		= 0x02,
98178786Skmacy	RDMAP_STAG_NOT_ASSOC	= 0x03,
99178786Skmacy	RDMAP_TO_WRAP		= 0x04,
100178786Skmacy	RDMAP_INV_VERS		= 0x05,
101178786Skmacy	RDMAP_INV_OPCODE	= 0x06,
102178786Skmacy	RDMAP_STREAM_CATA	= 0x07,
103178786Skmacy	RDMAP_GLOBAL_CATA	= 0x08,
104178786Skmacy	RDMAP_CANT_INV_STAG	= 0x09,
105178786Skmacy	RDMAP_UNSPECIFIED	= 0xff
106178786Skmacy};
107178786Skmacy
108178786Skmacyenum iwch_ddp_ecodes {
109178786Skmacy	DDPT_INV_STAG		= 0x00,
110178786Skmacy	DDPT_BASE_BOUNDS	= 0x01,
111178786Skmacy	DDPT_STAG_NOT_ASSOC	= 0x02,
112178786Skmacy	DDPT_TO_WRAP		= 0x03,
113178786Skmacy	DDPT_INV_VERS		= 0x04,
114178786Skmacy	DDPU_INV_QN		= 0x01,
115178786Skmacy	DDPU_INV_MSN_NOBUF	= 0x02,
116178786Skmacy	DDPU_INV_MSN_RANGE	= 0x03,
117178786Skmacy	DDPU_INV_MO		= 0x04,
118178786Skmacy	DDPU_MSG_TOOBIG		= 0x05,
119178786Skmacy	DDPU_INV_VERS		= 0x06
120178786Skmacy};
121178786Skmacy
122178786Skmacyenum iwch_mpa_ecodes {
123178786Skmacy	MPA_CRC_ERR		= 0x02,
124178786Skmacy	MPA_MARKER_ERR		= 0x03
125178786Skmacy};
126178786Skmacy
127178786Skmacyenum iwch_ep_state {
128178786Skmacy	IDLE = 0,
129178786Skmacy	LISTEN,
130178786Skmacy	CONNECTING,
131178786Skmacy	MPA_REQ_WAIT,
132178786Skmacy	MPA_REQ_SENT,
133178786Skmacy	MPA_REQ_RCVD,
134178786Skmacy	MPA_REP_SENT,
135178786Skmacy	FPDU_MODE,
136178786Skmacy	ABORTING,
137178786Skmacy	CLOSING,
138178786Skmacy	MORIBUND,
139178786Skmacy	DEAD,
140178786Skmacy};
141178786Skmacy
142178786Skmacyenum iwch_ep_flags {
143178786Skmacy	PEER_ABORT_IN_PROGRESS	= (1 << 0),
144178786Skmacy	ABORT_REQ_IN_PROGRESS	= (1 << 1),
145178786Skmacy};
146178786Skmacy
147178786Skmacystruct iwch_ep_common {
148178786Skmacy	TAILQ_ENTRY(iwch_ep_common) entry;
149178786Skmacy	struct iw_cm_id *cm_id;
150178786Skmacy	struct iwch_qp *qp;
151237263Snp	struct toedev *tdev;
152178786Skmacy	enum iwch_ep_state state;
153178786Skmacy	u_int refcount;
154178786Skmacy	struct cv waitq;
155178786Skmacy	struct mtx lock;
156178786Skmacy	struct sockaddr_in local_addr;
157178786Skmacy	struct sockaddr_in remote_addr;
158178786Skmacy	int rpl_err;
159178786Skmacy	int rpl_done;
160178786Skmacy	struct thread *thread;
161178786Skmacy	struct socket *so;
162178786Skmacy};
163178786Skmacy
164178786Skmacystruct iwch_listen_ep {
165178786Skmacy	struct iwch_ep_common com;
166178786Skmacy	unsigned int stid;
167178786Skmacy	int backlog;
168178786Skmacy};
169178786Skmacy
170178786Skmacystruct iwch_ep {
171178786Skmacy	struct iwch_ep_common com;
172178786Skmacy	struct iwch_ep *parent_ep;
173178786Skmacy	struct callout timer;
174178786Skmacy	unsigned int atid;
175178786Skmacy	u32 hwtid;
176178786Skmacy	u32 snd_seq;
177178786Skmacy	u32 rcv_seq;
178178786Skmacy	struct l2t_entry *l2t;
179178786Skmacy	struct mbuf *mpa_mbuf;
180178786Skmacy	struct iwch_mpa_attributes mpa_attr;
181178786Skmacy	unsigned int mpa_pkt_len;
182178786Skmacy	u8 mpa_pkt[sizeof(struct mpa_message) + MPA_MAX_PRIVATE_DATA];
183178786Skmacy	u8 tos;
184178786Skmacy	u16 emss;
185178786Skmacy	u16 plen;
186178786Skmacy	u32 ird;
187178786Skmacy	u32 ord;
188178786Skmacy	u32 flags;
189178786Skmacy};
190178786Skmacy
191178786Skmacystatic inline struct iwch_ep *to_ep(struct iw_cm_id *cm_id)
192178786Skmacy{
193178786Skmacy	return cm_id->provider_data;
194178786Skmacy}
195178786Skmacy
196178786Skmacystatic inline struct iwch_listen_ep *to_listen_ep(struct iw_cm_id *cm_id)
197178786Skmacy{
198178786Skmacy	return cm_id->provider_data;
199178786Skmacy}
200178786Skmacy
201178786Skmacystatic inline int compute_wscale(int win)
202178786Skmacy{
203178786Skmacy	int wscale = 0;
204178786Skmacy
205178786Skmacy	while (wscale < 14 && (65535<<wscale) < win)
206178786Skmacy		wscale++;
207178786Skmacy	return wscale;
208178786Skmacy}
209178786Skmacy
210178786Skmacystatic __inline void
211178786Skmacyiwch_wait(struct cv *cv, struct mtx *lock, int *rpl_done)
212178786Skmacy{
213178786Skmacy	mtx_lock(lock);
214178786Skmacy	if (!*rpl_done) {
215178786Skmacy		CTR0(KTR_IW_CXGB, "sleeping for rpl_done\n");
216178786Skmacy		cv_wait_unlock(cv, lock);
217178786Skmacy	}
218178786Skmacy	CTR1(KTR_IW_CXGB, "*rpl_done=%d\n", *rpl_done);
219178786Skmacy}
220178786Skmacy
221178786Skmacystatic __inline void
222178786Skmacyiwch_wakeup(struct cv *cv, struct mtx *lock, int *rpl_done)
223178786Skmacy{
224178786Skmacy	mtx_lock(lock);
225178786Skmacy	*rpl_done=1;
226178786Skmacy	CTR0(KTR_IW_CXGB, "wakeup for rpl_done\n");
227178786Skmacy	cv_broadcast(cv);
228178786Skmacy	mtx_unlock(lock);
229178786Skmacy}
230178786Skmacy
231178786Skmacy/* CM prototypes */
232178786Skmacy
233178786Skmacyint iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param);
234178786Skmacyint iwch_create_listen(struct iw_cm_id *cm_id, int backlog);
235178786Skmacyint iwch_destroy_listen(struct iw_cm_id *cm_id);
236178786Skmacyint iwch_reject_cr(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len);
237178786Skmacyint iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param);
238178786Skmacyint iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, int flags);
239178786Skmacyvoid __free_ep(struct iwch_ep_common *ep);
240178786Skmacyvoid iwch_rearp(struct iwch_ep *ep);
241178786Skmacyint iwch_ep_redirect(void *ctx, struct rtentry *old, struct rtentry *new, struct l2t_entry *l2t);
242178786Skmacy
243178786Skmacyint iwch_cm_init(void);
244178786Skmacyvoid iwch_cm_term(void);
245237263Snpvoid iwch_cm_init_cpl(struct adapter *);
246237263Snpvoid iwch_cm_term_cpl(struct adapter *);
247178786Skmacy
248178786Skmacy#endif				/* _IWCH_CM_H_ */
249