xref: /NextBSD/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.h (revision eb1a5f8de9f7ea602c373a710f531abbf81141c4)
1 /**************************************************************************
2 
3 Copyright (c) 2007, 2008 Chelsio Inc.
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without
7 modification, 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 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 POSSIBILITY OF SUCH DAMAGE.
27 
28 $FreeBSD$
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 
64 struct mpa_message {
65 	u8 key[16];
66 	u8 flags;
67 	u8 revision;
68 	__be16 private_data_size;
69 	u8 private_data[0];
70 };
71 
72 struct 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 
81 enum 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 
94 enum 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 
108 enum 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 
122 enum iwch_mpa_ecodes {
123 	MPA_CRC_ERR		= 0x02,
124 	MPA_MARKER_ERR		= 0x03
125 };
126 
127 enum 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 
142 enum iwch_ep_flags {
143 	PEER_ABORT_IN_PROGRESS	= (1 << 0),
144 	ABORT_REQ_IN_PROGRESS	= (1 << 1),
145 };
146 
147 struct 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 
164 struct iwch_listen_ep {
165 	struct iwch_ep_common com;
166 	unsigned int stid;
167 	int backlog;
168 };
169 
170 struct 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 
to_ep(struct iw_cm_id * cm_id)191 static inline struct iwch_ep *to_ep(struct iw_cm_id *cm_id)
192 {
193 	return cm_id->provider_data;
194 }
195 
to_listen_ep(struct iw_cm_id * cm_id)196 static inline struct iwch_listen_ep *to_listen_ep(struct iw_cm_id *cm_id)
197 {
198 	return cm_id->provider_data;
199 }
200 
compute_wscale(int win)201 static 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 
210 static __inline void
iwch_wait(struct cv * cv,struct mtx * lock,int * rpl_done)211 iwch_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 
221 static __inline void
iwch_wakeup(struct cv * cv,struct mtx * lock,int * rpl_done)222 iwch_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 
233 int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param);
234 int iwch_create_listen(struct iw_cm_id *cm_id, int backlog);
235 int iwch_destroy_listen(struct iw_cm_id *cm_id);
236 int iwch_reject_cr(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len);
237 int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param);
238 int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, int flags);
239 void __free_ep(struct iwch_ep_common *ep);
240 void iwch_rearp(struct iwch_ep *ep);
241 int iwch_ep_redirect(void *ctx, struct rtentry *old, struct rtentry *new, struct l2t_entry *l2t);
242 
243 int iwch_cm_init(void);
244 void iwch_cm_term(void);
245 void iwch_cm_init_cpl(struct adapter *);
246 void iwch_cm_term_cpl(struct adapter *);
247 
248 #endif				/* _IWCH_CM_H_ */
249