Commit | Line | Data |
---|---|---|
f27b4746 FL |
1 | /******************************************************************************* |
2 | * | |
f606d893 | 3 | * Copyright (c) 2015-2016 Intel Corporation. All rights reserved. |
f27b4746 FL |
4 | * |
5 | * This software is available to you under a choice of one of two | |
6 | * licenses. You may choose to be licensed under the terms of the GNU | |
7 | * General Public License (GPL) Version 2, available from the file | |
8 | * COPYING in the main directory of this source tree, or the | |
9 | * OpenFabrics.org BSD license below: | |
10 | * | |
11 | * Redistribution and use in source and binary forms, with or | |
12 | * without modification, are permitted provided that the following | |
13 | * conditions are met: | |
14 | * | |
15 | * - Redistributions of source code must retain the above | |
16 | * copyright notice, this list of conditions and the following | |
17 | * disclaimer. | |
18 | * | |
19 | * - Redistributions in binary form must reproduce the above | |
20 | * copyright notice, this list of conditions and the following | |
21 | * disclaimer in the documentation and/or other materials | |
22 | * provided with the distribution. | |
23 | * | |
24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
25 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
26 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
27 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
28 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
29 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
30 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
31 | * SOFTWARE. | |
32 | * | |
33 | *******************************************************************************/ | |
34 | ||
35 | #ifndef I40IW_CM_H | |
36 | #define I40IW_CM_H | |
37 | ||
38 | #define QUEUE_EVENTS | |
39 | ||
40 | #define I40IW_MANAGE_APBVT_DEL 0 | |
41 | #define I40IW_MANAGE_APBVT_ADD 1 | |
42 | ||
43 | #define I40IW_MPA_REQUEST_ACCEPT 1 | |
44 | #define I40IW_MPA_REQUEST_REJECT 2 | |
45 | ||
46 | /* IETF MPA -- defines, enums, structs */ | |
47 | #define IEFT_MPA_KEY_REQ "MPA ID Req Frame" | |
48 | #define IEFT_MPA_KEY_REP "MPA ID Rep Frame" | |
49 | #define IETF_MPA_KEY_SIZE 16 | |
50 | #define IETF_MPA_VERSION 1 | |
51 | #define IETF_MAX_PRIV_DATA_LEN 512 | |
52 | #define IETF_MPA_FRAME_SIZE 20 | |
53 | #define IETF_RTR_MSG_SIZE 4 | |
54 | #define IETF_MPA_V2_FLAG 0x10 | |
55 | #define SNDMARKER_SEQNMASK 0x000001FF | |
56 | ||
57 | #define I40IW_MAX_IETF_SIZE 32 | |
58 | ||
59 | #define MPA_ZERO_PAD_LEN 4 | |
60 | ||
61 | /* IETF RTR MSG Fields */ | |
62 | #define IETF_PEER_TO_PEER 0x8000 | |
63 | #define IETF_FLPDU_ZERO_LEN 0x4000 | |
64 | #define IETF_RDMA0_WRITE 0x8000 | |
65 | #define IETF_RDMA0_READ 0x4000 | |
66 | #define IETF_NO_IRD_ORD 0x3FFF | |
67 | ||
68 | /* HW-supported IRD sizes*/ | |
69 | #define I40IW_HW_IRD_SETTING_2 2 | |
70 | #define I40IW_HW_IRD_SETTING_4 4 | |
71 | #define I40IW_HW_IRD_SETTING_8 8 | |
72 | #define I40IW_HW_IRD_SETTING_16 16 | |
73 | #define I40IW_HW_IRD_SETTING_32 32 | |
74 | #define I40IW_HW_IRD_SETTING_64 64 | |
75 | ||
76 | enum ietf_mpa_flags { | |
77 | IETF_MPA_FLAGS_MARKERS = 0x80, /* receive Markers */ | |
78 | IETF_MPA_FLAGS_CRC = 0x40, /* receive Markers */ | |
79 | IETF_MPA_FLAGS_REJECT = 0x20, /* Reject */ | |
80 | }; | |
81 | ||
82 | struct ietf_mpa_v1 { | |
83 | u8 key[IETF_MPA_KEY_SIZE]; | |
84 | u8 flags; | |
85 | u8 rev; | |
86 | __be16 priv_data_len; | |
87 | u8 priv_data[0]; | |
88 | }; | |
89 | ||
90 | #define ietf_mpa_req_resp_frame ietf_mpa_frame | |
91 | ||
92 | struct ietf_rtr_msg { | |
93 | __be16 ctrl_ird; | |
94 | __be16 ctrl_ord; | |
95 | }; | |
96 | ||
97 | struct ietf_mpa_v2 { | |
98 | u8 key[IETF_MPA_KEY_SIZE]; | |
99 | u8 flags; | |
100 | u8 rev; | |
101 | __be16 priv_data_len; | |
102 | struct ietf_rtr_msg rtr_msg; | |
103 | u8 priv_data[0]; | |
104 | }; | |
105 | ||
106 | struct i40iw_cm_node; | |
107 | enum i40iw_timer_type { | |
108 | I40IW_TIMER_TYPE_SEND, | |
109 | I40IW_TIMER_TYPE_RECV, | |
110 | I40IW_TIMER_NODE_CLEANUP, | |
111 | I40IW_TIMER_TYPE_CLOSE, | |
112 | }; | |
113 | ||
114 | #define I40IW_PASSIVE_STATE_INDICATED 0 | |
115 | #define I40IW_DO_NOT_SEND_RESET_EVENT 1 | |
116 | #define I40IW_SEND_RESET_EVENT 2 | |
117 | ||
118 | #define MAX_I40IW_IFS 4 | |
119 | ||
120 | #define SET_ACK 0x1 | |
121 | #define SET_SYN 0x2 | |
122 | #define SET_FIN 0x4 | |
123 | #define SET_RST 0x8 | |
124 | ||
125 | #define TCP_OPTIONS_PADDING 3 | |
126 | ||
127 | struct option_base { | |
128 | u8 optionnum; | |
129 | u8 length; | |
130 | }; | |
131 | ||
132 | enum option_numbers { | |
133 | OPTION_NUMBER_END, | |
134 | OPTION_NUMBER_NONE, | |
135 | OPTION_NUMBER_MSS, | |
136 | OPTION_NUMBER_WINDOW_SCALE, | |
137 | OPTION_NUMBER_SACK_PERM, | |
138 | OPTION_NUMBER_SACK, | |
139 | OPTION_NUMBER_WRITE0 = 0xbc | |
140 | }; | |
141 | ||
142 | struct option_mss { | |
143 | u8 optionnum; | |
144 | u8 length; | |
145 | __be16 mss; | |
146 | }; | |
147 | ||
148 | struct option_windowscale { | |
149 | u8 optionnum; | |
150 | u8 length; | |
151 | u8 shiftcount; | |
152 | }; | |
153 | ||
154 | union all_known_options { | |
155 | char as_end; | |
156 | struct option_base as_base; | |
157 | struct option_mss as_mss; | |
158 | struct option_windowscale as_windowscale; | |
159 | }; | |
160 | ||
161 | struct i40iw_timer_entry { | |
162 | struct list_head list; | |
163 | unsigned long timetosend; /* jiffies */ | |
164 | struct i40iw_puda_buf *sqbuf; | |
165 | u32 type; | |
166 | u32 retrycount; | |
167 | u32 retranscount; | |
168 | u32 context; | |
169 | u32 send_retrans; | |
170 | int close_when_complete; | |
171 | }; | |
172 | ||
173 | #define I40IW_DEFAULT_RETRYS 64 | |
174 | #define I40IW_DEFAULT_RETRANS 8 | |
175 | #define I40IW_DEFAULT_TTL 0x40 | |
176 | #define I40IW_DEFAULT_RTT_VAR 0x6 | |
177 | #define I40IW_DEFAULT_SS_THRESH 0x3FFFFFFF | |
178 | #define I40IW_DEFAULT_REXMIT_THRESH 8 | |
179 | ||
180 | #define I40IW_RETRY_TIMEOUT HZ | |
181 | #define I40IW_SHORT_TIME 10 | |
182 | #define I40IW_LONG_TIME (2 * HZ) | |
183 | #define I40IW_MAX_TIMEOUT ((unsigned long)(12 * HZ)) | |
184 | ||
185 | #define I40IW_CM_HASHTABLE_SIZE 1024 | |
186 | #define I40IW_CM_TCP_TIMER_INTERVAL 3000 | |
187 | #define I40IW_CM_DEFAULT_MTU 1540 | |
188 | #define I40IW_CM_DEFAULT_FRAME_CNT 10 | |
189 | #define I40IW_CM_THREAD_STACK_SIZE 256 | |
190 | #define I40IW_CM_DEFAULT_RCV_WND 64240 | |
191 | #define I40IW_CM_DEFAULT_RCV_WND_SCALED 0x3fffc | |
192 | #define I40IW_CM_DEFAULT_RCV_WND_SCALE 2 | |
193 | #define I40IW_CM_DEFAULT_FREE_PKTS 0x000A | |
194 | #define I40IW_CM_FREE_PKT_LO_WATERMARK 2 | |
195 | ||
196 | #define I40IW_CM_DEFAULT_MSS 536 | |
197 | ||
198 | #define I40IW_CM_DEF_SEQ 0x159bf75f | |
199 | #define I40IW_CM_DEF_LOCAL_ID 0x3b47 | |
200 | ||
201 | #define I40IW_CM_DEF_SEQ2 0x18ed5740 | |
202 | #define I40IW_CM_DEF_LOCAL_ID2 0xb807 | |
203 | #define MAX_CM_BUFFER (I40IW_MAX_IETF_SIZE + IETF_MAX_PRIV_DATA_LEN) | |
204 | ||
205 | typedef u32 i40iw_addr_t; | |
206 | ||
207 | #define i40iw_cm_tsa_context i40iw_qp_context | |
208 | ||
209 | struct i40iw_qp; | |
210 | ||
211 | /* cm node transition states */ | |
212 | enum i40iw_cm_node_state { | |
213 | I40IW_CM_STATE_UNKNOWN, | |
214 | I40IW_CM_STATE_INITED, | |
215 | I40IW_CM_STATE_LISTENING, | |
216 | I40IW_CM_STATE_SYN_RCVD, | |
217 | I40IW_CM_STATE_SYN_SENT, | |
218 | I40IW_CM_STATE_ONE_SIDE_ESTABLISHED, | |
219 | I40IW_CM_STATE_ESTABLISHED, | |
220 | I40IW_CM_STATE_ACCEPTING, | |
221 | I40IW_CM_STATE_MPAREQ_SENT, | |
222 | I40IW_CM_STATE_MPAREQ_RCVD, | |
223 | I40IW_CM_STATE_MPAREJ_RCVD, | |
224 | I40IW_CM_STATE_OFFLOADED, | |
225 | I40IW_CM_STATE_FIN_WAIT1, | |
226 | I40IW_CM_STATE_FIN_WAIT2, | |
227 | I40IW_CM_STATE_CLOSE_WAIT, | |
228 | I40IW_CM_STATE_TIME_WAIT, | |
229 | I40IW_CM_STATE_LAST_ACK, | |
230 | I40IW_CM_STATE_CLOSING, | |
231 | I40IW_CM_STATE_LISTENER_DESTROYED, | |
232 | I40IW_CM_STATE_CLOSED | |
233 | }; | |
234 | ||
235 | enum mpa_frame_version { | |
236 | IETF_MPA_V1 = 1, | |
237 | IETF_MPA_V2 = 2 | |
238 | }; | |
239 | ||
240 | enum mpa_frame_key { | |
241 | MPA_KEY_REQUEST, | |
242 | MPA_KEY_REPLY | |
243 | }; | |
244 | ||
245 | enum send_rdma0 { | |
246 | SEND_RDMA_READ_ZERO = 1, | |
247 | SEND_RDMA_WRITE_ZERO = 2 | |
248 | }; | |
249 | ||
250 | enum i40iw_tcpip_pkt_type { | |
251 | I40IW_PKT_TYPE_UNKNOWN, | |
252 | I40IW_PKT_TYPE_SYN, | |
253 | I40IW_PKT_TYPE_SYNACK, | |
254 | I40IW_PKT_TYPE_ACK, | |
255 | I40IW_PKT_TYPE_FIN, | |
256 | I40IW_PKT_TYPE_RST | |
257 | }; | |
258 | ||
259 | /* CM context params */ | |
260 | struct i40iw_cm_tcp_context { | |
261 | u8 client; | |
262 | ||
263 | u32 loc_seq_num; | |
264 | u32 loc_ack_num; | |
265 | u32 rem_ack_num; | |
266 | u32 rcv_nxt; | |
267 | ||
268 | u32 loc_id; | |
269 | u32 rem_id; | |
270 | ||
271 | u32 snd_wnd; | |
272 | u32 max_snd_wnd; | |
273 | ||
274 | u32 rcv_wnd; | |
275 | u32 mss; | |
276 | u8 snd_wscale; | |
277 | u8 rcv_wscale; | |
278 | ||
279 | struct timeval sent_ts; | |
280 | }; | |
281 | ||
282 | enum i40iw_cm_listener_state { | |
283 | I40IW_CM_LISTENER_PASSIVE_STATE = 1, | |
284 | I40IW_CM_LISTENER_ACTIVE_STATE = 2, | |
285 | I40IW_CM_LISTENER_EITHER_STATE = 3 | |
286 | }; | |
287 | ||
288 | struct i40iw_cm_listener { | |
289 | struct list_head list; | |
290 | struct i40iw_cm_core *cm_core; | |
291 | u8 loc_mac[ETH_ALEN]; | |
292 | u32 loc_addr[4]; | |
293 | u16 loc_port; | |
f27b4746 FL |
294 | struct iw_cm_id *cm_id; |
295 | atomic_t ref_count; | |
296 | struct i40iw_device *iwdev; | |
297 | atomic_t pend_accepts_cnt; | |
298 | int backlog; | |
299 | enum i40iw_cm_listener_state listener_state; | |
300 | u32 reused_node; | |
301 | u8 user_pri; | |
302 | u16 vlan_id; | |
303 | bool qhash_set; | |
304 | bool ipv4; | |
305 | struct list_head child_listen_list; | |
306 | ||
307 | }; | |
308 | ||
309 | struct i40iw_kmem_info { | |
310 | void *addr; | |
311 | u32 size; | |
312 | }; | |
313 | ||
314 | /* per connection node and node state information */ | |
315 | struct i40iw_cm_node { | |
316 | u32 loc_addr[4], rem_addr[4]; | |
317 | u16 loc_port, rem_port; | |
f27b4746 FL |
318 | u16 vlan_id; |
319 | enum i40iw_cm_node_state state; | |
320 | u8 loc_mac[ETH_ALEN]; | |
321 | u8 rem_mac[ETH_ALEN]; | |
322 | atomic_t ref_count; | |
323 | struct i40iw_qp *iwqp; | |
324 | struct i40iw_device *iwdev; | |
325 | struct i40iw_sc_dev *dev; | |
326 | struct i40iw_cm_tcp_context tcp_cntxt; | |
327 | struct i40iw_cm_core *cm_core; | |
328 | struct i40iw_cm_node *loopbackpartner; | |
329 | struct i40iw_timer_entry *send_entry; | |
330 | struct i40iw_timer_entry *close_entry; | |
331 | spinlock_t retrans_list_lock; /* cm transmit packet */ | |
332 | enum send_rdma0 send_rdma0_op; | |
333 | u16 ird_size; | |
334 | u16 ord_size; | |
335 | u16 mpav2_ird_ord; | |
336 | struct iw_cm_id *cm_id; | |
337 | struct list_head list; | |
338 | int accelerated; | |
339 | struct i40iw_cm_listener *listener; | |
340 | int apbvt_set; | |
341 | int accept_pend; | |
342 | struct list_head timer_entry; | |
343 | struct list_head reset_entry; | |
344 | atomic_t passive_state; | |
345 | bool qhash_set; | |
346 | u8 user_pri; | |
347 | bool ipv4; | |
348 | bool snd_mark_en; | |
349 | u16 lsmm_size; | |
350 | enum mpa_frame_version mpa_frame_rev; | |
351 | struct i40iw_kmem_info pdata; | |
352 | union { | |
353 | struct ietf_mpa_v1 mpa_frame; | |
354 | struct ietf_mpa_v2 mpa_v2_frame; | |
355 | }; | |
356 | ||
357 | u8 pdata_buf[IETF_MAX_PRIV_DATA_LEN]; | |
358 | struct i40iw_kmem_info mpa_hdr; | |
359 | }; | |
360 | ||
361 | /* structure for client or CM to fill when making CM api calls. */ | |
362 | /* - only need to set relevant data, based on op. */ | |
363 | struct i40iw_cm_info { | |
364 | struct iw_cm_id *cm_id; | |
365 | u16 loc_port; | |
366 | u16 rem_port; | |
367 | u32 loc_addr[4]; | |
368 | u32 rem_addr[4]; | |
f27b4746 FL |
369 | u16 vlan_id; |
370 | int backlog; | |
371 | u16 user_pri; | |
372 | bool ipv4; | |
373 | }; | |
374 | ||
375 | /* CM event codes */ | |
376 | enum i40iw_cm_event_type { | |
377 | I40IW_CM_EVENT_UNKNOWN, | |
378 | I40IW_CM_EVENT_ESTABLISHED, | |
379 | I40IW_CM_EVENT_MPA_REQ, | |
380 | I40IW_CM_EVENT_MPA_CONNECT, | |
381 | I40IW_CM_EVENT_MPA_ACCEPT, | |
382 | I40IW_CM_EVENT_MPA_REJECT, | |
383 | I40IW_CM_EVENT_MPA_ESTABLISHED, | |
384 | I40IW_CM_EVENT_CONNECTED, | |
385 | I40IW_CM_EVENT_RESET, | |
386 | I40IW_CM_EVENT_ABORTED | |
387 | }; | |
388 | ||
389 | /* event to post to CM event handler */ | |
390 | struct i40iw_cm_event { | |
391 | enum i40iw_cm_event_type type; | |
392 | struct i40iw_cm_info cm_info; | |
393 | struct work_struct event_work; | |
394 | struct i40iw_cm_node *cm_node; | |
395 | }; | |
396 | ||
397 | struct i40iw_cm_core { | |
398 | struct i40iw_device *iwdev; | |
399 | struct i40iw_sc_dev *dev; | |
400 | ||
401 | struct list_head listen_nodes; | |
402 | struct list_head connected_nodes; | |
403 | ||
404 | struct timer_list tcp_timer; | |
405 | ||
406 | struct workqueue_struct *event_wq; | |
407 | struct workqueue_struct *disconn_wq; | |
408 | ||
409 | spinlock_t ht_lock; /* manage hash table */ | |
410 | spinlock_t listen_list_lock; /* listen list */ | |
411 | ||
412 | u64 stats_nodes_created; | |
413 | u64 stats_nodes_destroyed; | |
414 | u64 stats_listen_created; | |
415 | u64 stats_listen_destroyed; | |
416 | u64 stats_listen_nodes_created; | |
417 | u64 stats_listen_nodes_destroyed; | |
418 | u64 stats_loopbacks; | |
419 | u64 stats_accepts; | |
420 | u64 stats_rejects; | |
421 | u64 stats_connect_errs; | |
422 | u64 stats_passive_errs; | |
423 | u64 stats_pkt_retrans; | |
424 | u64 stats_backlog_drops; | |
425 | }; | |
426 | ||
427 | int i40iw_schedule_cm_timer(struct i40iw_cm_node *cm_node, | |
428 | struct i40iw_puda_buf *sqbuf, | |
429 | enum i40iw_timer_type type, | |
430 | int send_retrans, | |
431 | int close_when_complete); | |
432 | ||
433 | int i40iw_accept(struct iw_cm_id *, struct iw_cm_conn_param *); | |
434 | int i40iw_reject(struct iw_cm_id *, const void *, u8); | |
435 | int i40iw_connect(struct iw_cm_id *, struct iw_cm_conn_param *); | |
436 | int i40iw_create_listen(struct iw_cm_id *, int); | |
437 | int i40iw_destroy_listen(struct iw_cm_id *); | |
438 | ||
439 | int i40iw_cm_start(struct i40iw_device *); | |
440 | int i40iw_cm_stop(struct i40iw_device *); | |
441 | ||
442 | int i40iw_arp_table(struct i40iw_device *iwdev, | |
443 | u32 *ip_addr, | |
444 | bool ipv4, | |
445 | u8 *mac_addr, | |
446 | u32 action); | |
447 | ||
448 | #endif /* I40IW_CM_H */ |