Commit | Line | Data |
---|---|---|
3c2d774c GS |
1 | /* |
2 | * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved. | |
3 | * | |
4 | * This software is available to you under a choice of one of two | |
5 | * licenses. You may choose to be licensed under the terms of the GNU | |
6 | * General Public License (GPL) Version 2, available from the file | |
7 | * COPYING in the main directory of this source tree, or the | |
8 | * OpenIB.org BSD license below: | |
9 | * | |
10 | * Redistribution and use in source and binary forms, with or | |
11 | * without modification, are permitted provided that the following | |
12 | * conditions are met: | |
13 | * | |
14 | * - Redistributions of source code must retain the above | |
15 | * copyright notice, this list of conditions and the following | |
16 | * disclaimer. | |
17 | * | |
18 | * - Redistributions in binary form must reproduce the above | |
19 | * copyright notice, this list of conditions and the following | |
20 | * disclaimer in the documentation and/or other materials | |
21 | * provided with the distribution. | |
22 | * | |
23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
30 | * SOFTWARE. | |
31 | * | |
32 | */ | |
33 | ||
34 | #ifndef NES_CM_H | |
35 | #define NES_CM_H | |
36 | ||
37 | #define QUEUE_EVENTS | |
38 | ||
39 | #define NES_MANAGE_APBVT_DEL 0 | |
40 | #define NES_MANAGE_APBVT_ADD 1 | |
41 | ||
42 | /* IETF MPA -- defines, enums, structs */ | |
43 | #define IEFT_MPA_KEY_REQ "MPA ID Req Frame" | |
44 | #define IEFT_MPA_KEY_REP "MPA ID Rep Frame" | |
45 | #define IETF_MPA_KEY_SIZE 16 | |
46 | #define IETF_MPA_VERSION 1 | |
47 | ||
48 | enum ietf_mpa_flags { | |
49 | IETF_MPA_FLAGS_MARKERS = 0x80, /* receive Markers */ | |
50 | IETF_MPA_FLAGS_CRC = 0x40, /* receive Markers */ | |
51 | IETF_MPA_FLAGS_REJECT = 0x20, /* Reject */ | |
52 | }; | |
53 | ||
54 | struct ietf_mpa_frame { | |
55 | u8 key[IETF_MPA_KEY_SIZE]; | |
56 | u8 flags; | |
57 | u8 rev; | |
58 | __be16 priv_data_len; | |
59 | u8 priv_data[0]; | |
60 | }; | |
61 | ||
62 | #define ietf_mpa_req_resp_frame ietf_mpa_frame | |
63 | ||
64 | struct nes_v4_quad { | |
65 | u32 rsvd0; | |
66 | __le32 DstIpAdrIndex; /* Only most significant 5 bits are valid */ | |
67 | __be32 SrcIpadr; | |
68 | __be16 TcpPorts[2]; /* src is low, dest is high */ | |
69 | }; | |
70 | ||
71 | struct nes_cm_node; | |
72 | enum nes_timer_type { | |
73 | NES_TIMER_TYPE_SEND, | |
74 | NES_TIMER_TYPE_RECV, | |
75 | NES_TIMER_NODE_CLEANUP, | |
76 | NES_TIMER_TYPE_CLOSE, | |
77 | }; | |
78 | ||
79 | #define MAX_NES_IFS 4 | |
80 | ||
81 | #define SET_ACK 1 | |
82 | #define SET_SYN 2 | |
83 | #define SET_FIN 4 | |
84 | #define SET_RST 8 | |
85 | ||
6492cdf3 FL |
86 | #define TCP_OPTIONS_PADDING 3 |
87 | ||
3c2d774c GS |
88 | struct option_base { |
89 | u8 optionnum; | |
90 | u8 length; | |
91 | }; | |
92 | ||
93 | enum option_numbers { | |
94 | OPTION_NUMBER_END, | |
95 | OPTION_NUMBER_NONE, | |
96 | OPTION_NUMBER_MSS, | |
97 | OPTION_NUMBER_WINDOW_SCALE, | |
98 | OPTION_NUMBER_SACK_PERM, | |
99 | OPTION_NUMBER_SACK, | |
100 | OPTION_NUMBER_WRITE0 = 0xbc | |
101 | }; | |
102 | ||
103 | struct option_mss { | |
104 | u8 optionnum; | |
105 | u8 length; | |
106 | __be16 mss; | |
107 | }; | |
108 | ||
109 | struct option_windowscale { | |
110 | u8 optionnum; | |
111 | u8 length; | |
112 | u8 shiftcount; | |
113 | }; | |
114 | ||
115 | union all_known_options { | |
116 | char as_end; | |
117 | struct option_base as_base; | |
118 | struct option_mss as_mss; | |
119 | struct option_windowscale as_windowscale; | |
120 | }; | |
121 | ||
122 | struct nes_timer_entry { | |
123 | struct list_head list; | |
124 | unsigned long timetosend; /* jiffies */ | |
125 | struct sk_buff *skb; | |
126 | u32 type; | |
127 | u32 retrycount; | |
128 | u32 retranscount; | |
129 | u32 context; | |
130 | u32 seq_num; | |
131 | u32 send_retrans; | |
132 | int close_when_complete; | |
133 | struct net_device *netdev; | |
134 | }; | |
135 | ||
136 | #define NES_DEFAULT_RETRYS 64 | |
137 | #define NES_DEFAULT_RETRANS 8 | |
138 | #ifdef CONFIG_INFINIBAND_NES_DEBUG | |
139 | #define NES_RETRY_TIMEOUT (1000*HZ/1000) | |
140 | #else | |
141 | #define NES_RETRY_TIMEOUT (3000*HZ/1000) | |
142 | #endif | |
143 | #define NES_SHORT_TIME (10) | |
144 | #define NES_LONG_TIME (2000*HZ/1000) | |
145 | ||
146 | #define NES_CM_HASHTABLE_SIZE 1024 | |
147 | #define NES_CM_TCP_TIMER_INTERVAL 3000 | |
148 | #define NES_CM_DEFAULT_MTU 1540 | |
149 | #define NES_CM_DEFAULT_FRAME_CNT 10 | |
150 | #define NES_CM_THREAD_STACK_SIZE 256 | |
151 | #define NES_CM_DEFAULT_RCV_WND 64240 // before we know that window scaling is allowed | |
152 | #define NES_CM_DEFAULT_RCV_WND_SCALED 256960 // after we know that window scaling is allowed | |
153 | #define NES_CM_DEFAULT_RCV_WND_SCALE 2 | |
154 | #define NES_CM_DEFAULT_FREE_PKTS 0x000A | |
155 | #define NES_CM_FREE_PKT_LO_WATERMARK 2 | |
156 | ||
157 | #define NES_CM_DEFAULT_MSS 536 | |
158 | ||
159 | #define NES_CM_DEF_SEQ 0x159bf75f | |
160 | #define NES_CM_DEF_LOCAL_ID 0x3b47 | |
161 | ||
162 | #define NES_CM_DEF_SEQ2 0x18ed5740 | |
163 | #define NES_CM_DEF_LOCAL_ID2 0xb807 | |
164 | ||
165 | typedef u32 nes_addr_t; | |
166 | ||
167 | #define nes_cm_tsa_context nes_qp_context | |
168 | ||
169 | struct nes_qp; | |
170 | ||
171 | /* cm node transition states */ | |
172 | enum nes_cm_node_state { | |
173 | NES_CM_STATE_UNKNOWN, | |
174 | NES_CM_STATE_INITED, | |
175 | NES_CM_STATE_LISTENING, | |
176 | NES_CM_STATE_SYN_RCVD, | |
177 | NES_CM_STATE_SYN_SENT, | |
178 | NES_CM_STATE_ONE_SIDE_ESTABLISHED, | |
179 | NES_CM_STATE_ESTABLISHED, | |
180 | NES_CM_STATE_ACCEPTING, | |
181 | NES_CM_STATE_MPAREQ_SENT, | |
6492cdf3 | 182 | NES_CM_STATE_MPAREQ_RCVD, |
3c2d774c GS |
183 | NES_CM_STATE_TSA, |
184 | NES_CM_STATE_FIN_WAIT1, | |
185 | NES_CM_STATE_FIN_WAIT2, | |
186 | NES_CM_STATE_CLOSE_WAIT, | |
187 | NES_CM_STATE_TIME_WAIT, | |
188 | NES_CM_STATE_LAST_ACK, | |
189 | NES_CM_STATE_CLOSING, | |
190 | NES_CM_STATE_CLOSED | |
191 | }; | |
192 | ||
6492cdf3 FL |
193 | enum nes_tcpip_pkt_type { |
194 | NES_PKT_TYPE_UNKNOWN, | |
195 | NES_PKT_TYPE_SYN, | |
196 | NES_PKT_TYPE_SYNACK, | |
197 | NES_PKT_TYPE_ACK, | |
198 | NES_PKT_TYPE_FIN, | |
199 | NES_PKT_TYPE_RST | |
200 | }; | |
201 | ||
202 | ||
3c2d774c GS |
203 | /* type of nes connection */ |
204 | enum nes_cm_conn_type { | |
205 | NES_CM_IWARP_CONN_TYPE, | |
206 | }; | |
207 | ||
208 | /* CM context params */ | |
209 | struct nes_cm_tcp_context { | |
210 | u8 client; | |
211 | ||
212 | u32 loc_seq_num; | |
213 | u32 loc_ack_num; | |
214 | u32 rem_ack_num; | |
215 | u32 rcv_nxt; | |
216 | ||
217 | u32 loc_id; | |
218 | u32 rem_id; | |
219 | ||
220 | u32 snd_wnd; | |
221 | u32 max_snd_wnd; | |
222 | ||
223 | u32 rcv_wnd; | |
224 | u32 mss; | |
225 | u8 snd_wscale; | |
226 | u8 rcv_wscale; | |
227 | ||
228 | struct nes_cm_tsa_context tsa_cntxt; | |
229 | struct timeval sent_ts; | |
230 | }; | |
231 | ||
232 | ||
233 | enum nes_cm_listener_state { | |
234 | NES_CM_LISTENER_PASSIVE_STATE=1, | |
235 | NES_CM_LISTENER_ACTIVE_STATE=2, | |
236 | NES_CM_LISTENER_EITHER_STATE=3 | |
237 | }; | |
238 | ||
239 | struct nes_cm_listener { | |
240 | struct list_head list; | |
3c2d774c GS |
241 | struct nes_cm_core *cm_core; |
242 | u8 loc_mac[ETH_ALEN]; | |
243 | nes_addr_t loc_addr; | |
244 | u16 loc_port; | |
245 | struct iw_cm_id *cm_id; | |
246 | enum nes_cm_conn_type conn_type; | |
247 | atomic_t ref_count; | |
248 | struct nes_vnic *nesvnic; | |
249 | atomic_t pend_accepts_cnt; | |
250 | int backlog; | |
251 | enum nes_cm_listener_state listener_state; | |
252 | u32 reused_node; | |
253 | }; | |
254 | ||
255 | /* per connection node and node state information */ | |
256 | struct nes_cm_node { | |
3c2d774c GS |
257 | u32 hashkey; |
258 | ||
259 | nes_addr_t loc_addr, rem_addr; | |
260 | u16 loc_port, rem_port; | |
261 | ||
262 | u8 loc_mac[ETH_ALEN]; | |
263 | u8 rem_mac[ETH_ALEN]; | |
264 | ||
265 | enum nes_cm_node_state state; | |
266 | struct nes_cm_tcp_context tcp_cntxt; | |
267 | struct nes_cm_core *cm_core; | |
268 | struct sk_buff_head resend_list; | |
269 | atomic_t ref_count; | |
270 | struct net_device *netdev; | |
271 | ||
272 | struct nes_cm_node *loopbackpartner; | |
6492cdf3 FL |
273 | |
274 | struct nes_timer_entry *send_entry; | |
275 | ||
3c2d774c GS |
276 | spinlock_t retrans_list_lock; |
277 | struct list_head recv_list; | |
278 | spinlock_t recv_list_lock; | |
279 | ||
280 | int send_write0; | |
281 | union { | |
282 | struct ietf_mpa_frame mpa_frame; | |
283 | u8 mpa_frame_buf[NES_CM_DEFAULT_MTU]; | |
284 | }; | |
285 | u16 mpa_frame_size; | |
286 | struct iw_cm_id *cm_id; | |
287 | struct list_head list; | |
288 | int accelerated; | |
289 | struct nes_cm_listener *listener; | |
290 | enum nes_cm_conn_type conn_type; | |
291 | struct nes_vnic *nesvnic; | |
292 | int apbvt_set; | |
293 | int accept_pend; | |
6492cdf3 FL |
294 | int freed; |
295 | struct nes_qp *nesqp; | |
3c2d774c GS |
296 | }; |
297 | ||
298 | /* structure for client or CM to fill when making CM api calls. */ | |
299 | /* - only need to set relevant data, based on op. */ | |
300 | struct nes_cm_info { | |
301 | union { | |
302 | struct iw_cm_id *cm_id; | |
303 | struct net_device *netdev; | |
304 | }; | |
305 | ||
306 | u16 loc_port; | |
307 | u16 rem_port; | |
308 | nes_addr_t loc_addr; | |
309 | nes_addr_t rem_addr; | |
310 | ||
311 | enum nes_cm_conn_type conn_type; | |
312 | int backlog; | |
313 | }; | |
314 | ||
315 | /* CM event codes */ | |
316 | enum nes_cm_event_type { | |
317 | NES_CM_EVENT_UNKNOWN, | |
318 | NES_CM_EVENT_ESTABLISHED, | |
319 | NES_CM_EVENT_MPA_REQ, | |
320 | NES_CM_EVENT_MPA_CONNECT, | |
321 | NES_CM_EVENT_MPA_ACCEPT, | |
322 | NES_CM_EVENT_MPA_ESTABLISHED, | |
323 | NES_CM_EVENT_CONNECTED, | |
324 | NES_CM_EVENT_CLOSED, | |
325 | NES_CM_EVENT_RESET, | |
326 | NES_CM_EVENT_DROPPED_PKT, | |
327 | NES_CM_EVENT_CLOSE_IMMED, | |
328 | NES_CM_EVENT_CLOSE_HARD, | |
329 | NES_CM_EVENT_CLOSE_CLEAN, | |
330 | NES_CM_EVENT_ABORTED, | |
331 | NES_CM_EVENT_SEND_FIRST | |
332 | }; | |
333 | ||
334 | /* event to post to CM event handler */ | |
335 | struct nes_cm_event { | |
336 | enum nes_cm_event_type type; | |
337 | ||
338 | struct nes_cm_info cm_info; | |
339 | struct work_struct event_work; | |
340 | struct nes_cm_node *cm_node; | |
341 | }; | |
342 | ||
343 | struct nes_cm_core { | |
344 | enum nes_cm_node_state state; | |
3c2d774c GS |
345 | |
346 | atomic_t listen_node_cnt; | |
347 | struct nes_cm_node listen_list; | |
348 | spinlock_t listen_list_lock; | |
349 | ||
350 | u32 mtu; | |
351 | u32 free_tx_pkt_max; | |
352 | u32 rx_pkt_posted; | |
353 | struct sk_buff_head tx_free_list; | |
354 | atomic_t ht_node_cnt; | |
355 | struct list_head connected_nodes; | |
356 | /* struct list_head hashtable[NES_CM_HASHTABLE_SIZE]; */ | |
357 | spinlock_t ht_lock; | |
358 | ||
359 | struct timer_list tcp_timer; | |
360 | ||
361 | struct nes_cm_ops *api; | |
362 | ||
363 | int (*post_event)(struct nes_cm_event *event); | |
364 | atomic_t events_posted; | |
365 | struct workqueue_struct *event_wq; | |
366 | struct workqueue_struct *disconn_wq; | |
367 | ||
368 | atomic_t node_cnt; | |
369 | u64 aborted_connects; | |
370 | u32 options; | |
371 | ||
372 | struct nes_cm_node *current_listen_node; | |
373 | }; | |
374 | ||
375 | ||
376 | #define NES_CM_SET_PKT_SIZE (1 << 1) | |
377 | #define NES_CM_SET_FREE_PKT_Q_SIZE (1 << 2) | |
378 | ||
379 | /* CM ops/API for client interface */ | |
380 | struct nes_cm_ops { | |
381 | int (*accelerated)(struct nes_cm_core *, struct nes_cm_node *); | |
382 | struct nes_cm_listener * (*listen)(struct nes_cm_core *, struct nes_vnic *, | |
383 | struct nes_cm_info *); | |
384 | int (*stop_listener)(struct nes_cm_core *, struct nes_cm_listener *); | |
385 | struct nes_cm_node * (*connect)(struct nes_cm_core *, | |
6492cdf3 | 386 | struct nes_vnic *, u16, void *, |
3c2d774c GS |
387 | struct nes_cm_info *); |
388 | int (*close)(struct nes_cm_core *, struct nes_cm_node *); | |
389 | int (*accept)(struct nes_cm_core *, struct ietf_mpa_frame *, | |
390 | struct nes_cm_node *); | |
391 | int (*reject)(struct nes_cm_core *, struct ietf_mpa_frame *, | |
392 | struct nes_cm_node *); | |
6492cdf3 | 393 | void (*recv_pkt)(struct nes_cm_core *, struct nes_vnic *, |
3c2d774c GS |
394 | struct sk_buff *); |
395 | int (*destroy_cm_core)(struct nes_cm_core *); | |
396 | int (*get)(struct nes_cm_core *); | |
397 | int (*set)(struct nes_cm_core *, u32, u32); | |
398 | }; | |
399 | ||
3c2d774c GS |
400 | int schedule_nes_timer(struct nes_cm_node *, struct sk_buff *, |
401 | enum nes_timer_type, int, int); | |
3c2d774c GS |
402 | |
403 | int nes_cm_disconn(struct nes_qp *); | |
3c2d774c GS |
404 | |
405 | int nes_accept(struct iw_cm_id *, struct iw_cm_conn_param *); | |
406 | int nes_reject(struct iw_cm_id *, const void *, u8); | |
407 | int nes_connect(struct iw_cm_id *, struct iw_cm_conn_param *); | |
408 | int nes_create_listen(struct iw_cm_id *, int); | |
409 | int nes_destroy_listen(struct iw_cm_id *); | |
410 | ||
411 | int nes_cm_recv(struct sk_buff *, struct net_device *); | |
412 | int nes_cm_start(void); | |
413 | int nes_cm_stop(void); | |
414 | ||
3c2d774c | 415 | #endif /* NES_CM_H */ |