i40iw: add connection management code
[cascardo/linux.git] / drivers / infiniband / hw / i40iw / i40iw_cm.h
1 /*******************************************************************************
2 *
3 * Copyright (c) 2015 Intel Corporation.  All rights reserved.
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;
294         u32 map_loc_addr[4];
295         u16 map_loc_port;
296         struct iw_cm_id *cm_id;
297         atomic_t ref_count;
298         struct i40iw_device *iwdev;
299         atomic_t pend_accepts_cnt;
300         int backlog;
301         enum i40iw_cm_listener_state listener_state;
302         u32 reused_node;
303         u8 user_pri;
304         u16 vlan_id;
305         bool qhash_set;
306         bool ipv4;
307         struct list_head child_listen_list;
308
309 };
310
311 struct i40iw_kmem_info {
312         void *addr;
313         u32 size;
314 };
315
316 /* per connection node and node state information */
317 struct i40iw_cm_node {
318         u32 loc_addr[4], rem_addr[4];
319         u16 loc_port, rem_port;
320         u32 map_loc_addr[4], map_rem_addr[4];
321         u16 map_loc_port, map_rem_port;
322         u16 vlan_id;
323         enum i40iw_cm_node_state state;
324         u8 loc_mac[ETH_ALEN];
325         u8 rem_mac[ETH_ALEN];
326         atomic_t ref_count;
327         struct i40iw_qp *iwqp;
328         struct i40iw_device *iwdev;
329         struct i40iw_sc_dev *dev;
330         struct i40iw_cm_tcp_context tcp_cntxt;
331         struct i40iw_cm_core *cm_core;
332         struct i40iw_cm_node *loopbackpartner;
333         struct i40iw_timer_entry *send_entry;
334         struct i40iw_timer_entry *close_entry;
335         spinlock_t retrans_list_lock; /* cm transmit packet */
336         enum send_rdma0 send_rdma0_op;
337         u16 ird_size;
338         u16 ord_size;
339         u16     mpav2_ird_ord;
340         struct iw_cm_id *cm_id;
341         struct list_head list;
342         int accelerated;
343         struct i40iw_cm_listener *listener;
344         int apbvt_set;
345         int accept_pend;
346         struct list_head timer_entry;
347         struct list_head reset_entry;
348         atomic_t passive_state;
349         bool qhash_set;
350         u8 user_pri;
351         bool ipv4;
352         bool snd_mark_en;
353         u16 lsmm_size;
354         enum mpa_frame_version mpa_frame_rev;
355         struct i40iw_kmem_info pdata;
356         union {
357                 struct ietf_mpa_v1 mpa_frame;
358                 struct ietf_mpa_v2 mpa_v2_frame;
359         };
360
361         u8 pdata_buf[IETF_MAX_PRIV_DATA_LEN];
362         struct i40iw_kmem_info mpa_hdr;
363 };
364
365 /* structure for client or CM to fill when making CM api calls. */
366 /*      - only need to set relevant data, based on op. */
367 struct i40iw_cm_info {
368         struct iw_cm_id *cm_id;
369         u16 loc_port;
370         u16 rem_port;
371         u32 loc_addr[4];
372         u32 rem_addr[4];
373         u16 map_loc_port;
374         u16 map_rem_port;
375         u32 map_loc_addr[4];
376         u32 map_rem_addr[4];
377         u16 vlan_id;
378         int backlog;
379         u16 user_pri;
380         bool ipv4;
381 };
382
383 /* CM event codes */
384 enum i40iw_cm_event_type {
385         I40IW_CM_EVENT_UNKNOWN,
386         I40IW_CM_EVENT_ESTABLISHED,
387         I40IW_CM_EVENT_MPA_REQ,
388         I40IW_CM_EVENT_MPA_CONNECT,
389         I40IW_CM_EVENT_MPA_ACCEPT,
390         I40IW_CM_EVENT_MPA_REJECT,
391         I40IW_CM_EVENT_MPA_ESTABLISHED,
392         I40IW_CM_EVENT_CONNECTED,
393         I40IW_CM_EVENT_RESET,
394         I40IW_CM_EVENT_ABORTED
395 };
396
397 /* event to post to CM event handler */
398 struct i40iw_cm_event {
399         enum i40iw_cm_event_type type;
400         struct i40iw_cm_info cm_info;
401         struct work_struct event_work;
402         struct i40iw_cm_node *cm_node;
403 };
404
405 struct i40iw_cm_core {
406         struct i40iw_device *iwdev;
407         struct i40iw_sc_dev *dev;
408
409         struct list_head listen_nodes;
410         struct list_head connected_nodes;
411
412         struct timer_list tcp_timer;
413
414         struct workqueue_struct *event_wq;
415         struct workqueue_struct *disconn_wq;
416
417         spinlock_t ht_lock; /* manage hash table */
418         spinlock_t listen_list_lock; /* listen list */
419
420         u64     stats_nodes_created;
421         u64     stats_nodes_destroyed;
422         u64     stats_listen_created;
423         u64     stats_listen_destroyed;
424         u64     stats_listen_nodes_created;
425         u64     stats_listen_nodes_destroyed;
426         u64     stats_loopbacks;
427         u64     stats_accepts;
428         u64     stats_rejects;
429         u64     stats_connect_errs;
430         u64     stats_passive_errs;
431         u64     stats_pkt_retrans;
432         u64     stats_backlog_drops;
433 };
434
435 int i40iw_schedule_cm_timer(struct i40iw_cm_node *cm_node,
436                             struct i40iw_puda_buf *sqbuf,
437                             enum i40iw_timer_type type,
438                             int send_retrans,
439                             int close_when_complete);
440
441 int i40iw_accept(struct iw_cm_id *, struct iw_cm_conn_param *);
442 int i40iw_reject(struct iw_cm_id *, const void *, u8);
443 int i40iw_connect(struct iw_cm_id *, struct iw_cm_conn_param *);
444 int i40iw_create_listen(struct iw_cm_id *, int);
445 int i40iw_destroy_listen(struct iw_cm_id *);
446
447 int i40iw_cm_start(struct i40iw_device *);
448 int i40iw_cm_stop(struct i40iw_device *);
449
450 int i40iw_arp_table(struct i40iw_device *iwdev,
451                     u32 *ip_addr,
452                     bool ipv4,
453                     u8 *mac_addr,
454                     u32 action);
455
456 #endif /* I40IW_CM_H */