]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/infiniband/hw/i40iw/i40iw_cm.h
i40iw: Add missing cleanup on device close
[karo-tx-linux.git] / drivers / infiniband / hw / i40iw / i40iw_cm.h
1 /*******************************************************************************
2 *
3 * Copyright (c) 2015-2016 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 /* IETF RTR MSG Fields               */
60 #define IETF_PEER_TO_PEER       0x8000
61 #define IETF_FLPDU_ZERO_LEN     0x4000
62 #define IETF_RDMA0_WRITE        0x8000
63 #define IETF_RDMA0_READ         0x4000
64 #define IETF_NO_IRD_ORD         0x3FFF
65
66 /* HW-supported IRD sizes*/
67 #define I40IW_HW_IRD_SETTING_2  2
68 #define I40IW_HW_IRD_SETTING_4  4
69 #define I40IW_HW_IRD_SETTING_8  8
70 #define I40IW_HW_IRD_SETTING_16 16
71 #define I40IW_HW_IRD_SETTING_32 32
72 #define I40IW_HW_IRD_SETTING_64 64
73
74 enum ietf_mpa_flags {
75         IETF_MPA_FLAGS_MARKERS = 0x80,  /* receive Markers */
76         IETF_MPA_FLAGS_CRC = 0x40,      /* receive Markers */
77         IETF_MPA_FLAGS_REJECT = 0x20,   /* Reject */
78 };
79
80 struct ietf_mpa_v1 {
81         u8 key[IETF_MPA_KEY_SIZE];
82         u8 flags;
83         u8 rev;
84         __be16 priv_data_len;
85         u8 priv_data[0];
86 };
87
88 #define ietf_mpa_req_resp_frame ietf_mpa_frame
89
90 struct ietf_rtr_msg {
91         __be16 ctrl_ird;
92         __be16 ctrl_ord;
93 };
94
95 struct ietf_mpa_v2 {
96         u8 key[IETF_MPA_KEY_SIZE];
97         u8 flags;
98         u8 rev;
99         __be16 priv_data_len;
100         struct ietf_rtr_msg rtr_msg;
101         u8 priv_data[0];
102 };
103
104 struct i40iw_cm_node;
105 enum i40iw_timer_type {
106         I40IW_TIMER_TYPE_SEND,
107         I40IW_TIMER_TYPE_RECV,
108         I40IW_TIMER_NODE_CLEANUP,
109         I40IW_TIMER_TYPE_CLOSE,
110 };
111
112 #define I40IW_PASSIVE_STATE_INDICATED    0
113 #define I40IW_DO_NOT_SEND_RESET_EVENT    1
114 #define I40IW_SEND_RESET_EVENT           2
115
116 #define MAX_I40IW_IFS 4
117
118 #define SET_ACK 0x1
119 #define SET_SYN 0x2
120 #define SET_FIN 0x4
121 #define SET_RST 0x8
122
123 #define TCP_OPTIONS_PADDING     3
124
125 struct option_base {
126         u8 optionnum;
127         u8 length;
128 };
129
130 enum option_numbers {
131         OPTION_NUMBER_END,
132         OPTION_NUMBER_NONE,
133         OPTION_NUMBER_MSS,
134         OPTION_NUMBER_WINDOW_SCALE,
135         OPTION_NUMBER_SACK_PERM,
136         OPTION_NUMBER_SACK,
137         OPTION_NUMBER_WRITE0 = 0xbc
138 };
139
140 struct option_mss {
141         u8 optionnum;
142         u8 length;
143         __be16 mss;
144 };
145
146 struct option_windowscale {
147         u8 optionnum;
148         u8 length;
149         u8 shiftcount;
150 };
151
152 union all_known_options {
153         char as_end;
154         struct option_base as_base;
155         struct option_mss as_mss;
156         struct option_windowscale as_windowscale;
157 };
158
159 struct i40iw_timer_entry {
160         struct list_head list;
161         unsigned long timetosend;       /* jiffies */
162         struct i40iw_puda_buf *sqbuf;
163         u32 type;
164         u32 retrycount;
165         u32 retranscount;
166         u32 context;
167         u32 send_retrans;
168         int close_when_complete;
169 };
170
171 #define I40IW_DEFAULT_RETRYS    64
172 #define I40IW_DEFAULT_RETRANS   8
173 #define I40IW_DEFAULT_TTL       0x40
174 #define I40IW_DEFAULT_RTT_VAR   0x6
175 #define I40IW_DEFAULT_SS_THRESH 0x3FFFFFFF
176 #define I40IW_DEFAULT_REXMIT_THRESH 8
177
178 #define I40IW_RETRY_TIMEOUT   HZ
179 #define I40IW_SHORT_TIME      10
180 #define I40IW_LONG_TIME       (2 * HZ)
181 #define I40IW_MAX_TIMEOUT     ((unsigned long)(12 * HZ))
182
183 #define I40IW_CM_HASHTABLE_SIZE         1024
184 #define I40IW_CM_TCP_TIMER_INTERVAL     3000
185 #define I40IW_CM_DEFAULT_MTU            1540
186 #define I40IW_CM_DEFAULT_FRAME_CNT      10
187 #define I40IW_CM_THREAD_STACK_SIZE      256
188 #define I40IW_CM_DEFAULT_RCV_WND        64240
189 #define I40IW_CM_DEFAULT_RCV_WND_SCALED 0x3fffc
190 #define I40IW_CM_DEFAULT_RCV_WND_SCALE  2
191 #define I40IW_CM_DEFAULT_FREE_PKTS      0x000A
192 #define I40IW_CM_FREE_PKT_LO_WATERMARK  2
193
194 #define I40IW_CM_DEFAULT_MSS   536
195
196 #define I40IW_CM_DEF_SEQ       0x159bf75f
197 #define I40IW_CM_DEF_LOCAL_ID  0x3b47
198
199 #define I40IW_CM_DEF_SEQ2      0x18ed5740
200 #define I40IW_CM_DEF_LOCAL_ID2 0xb807
201 #define MAX_CM_BUFFER   (I40IW_MAX_IETF_SIZE + IETF_MAX_PRIV_DATA_LEN)
202
203 typedef u32 i40iw_addr_t;
204
205 #define i40iw_cm_tsa_context i40iw_qp_context
206
207 struct i40iw_qp;
208
209 /* cm node transition states */
210 enum i40iw_cm_node_state {
211         I40IW_CM_STATE_UNKNOWN,
212         I40IW_CM_STATE_INITED,
213         I40IW_CM_STATE_LISTENING,
214         I40IW_CM_STATE_SYN_RCVD,
215         I40IW_CM_STATE_SYN_SENT,
216         I40IW_CM_STATE_ONE_SIDE_ESTABLISHED,
217         I40IW_CM_STATE_ESTABLISHED,
218         I40IW_CM_STATE_ACCEPTING,
219         I40IW_CM_STATE_MPAREQ_SENT,
220         I40IW_CM_STATE_MPAREQ_RCVD,
221         I40IW_CM_STATE_MPAREJ_RCVD,
222         I40IW_CM_STATE_OFFLOADED,
223         I40IW_CM_STATE_FIN_WAIT1,
224         I40IW_CM_STATE_FIN_WAIT2,
225         I40IW_CM_STATE_CLOSE_WAIT,
226         I40IW_CM_STATE_TIME_WAIT,
227         I40IW_CM_STATE_LAST_ACK,
228         I40IW_CM_STATE_CLOSING,
229         I40IW_CM_STATE_LISTENER_DESTROYED,
230         I40IW_CM_STATE_CLOSED
231 };
232
233 enum mpa_frame_version {
234         IETF_MPA_V1 = 1,
235         IETF_MPA_V2 = 2
236 };
237
238 enum mpa_frame_key {
239         MPA_KEY_REQUEST,
240         MPA_KEY_REPLY
241 };
242
243 enum send_rdma0 {
244         SEND_RDMA_READ_ZERO = 1,
245         SEND_RDMA_WRITE_ZERO = 2
246 };
247
248 enum i40iw_tcpip_pkt_type {
249         I40IW_PKT_TYPE_UNKNOWN,
250         I40IW_PKT_TYPE_SYN,
251         I40IW_PKT_TYPE_SYNACK,
252         I40IW_PKT_TYPE_ACK,
253         I40IW_PKT_TYPE_FIN,
254         I40IW_PKT_TYPE_RST
255 };
256
257 /* CM context params */
258 struct i40iw_cm_tcp_context {
259         u8 client;
260
261         u32 loc_seq_num;
262         u32 loc_ack_num;
263         u32 rem_ack_num;
264         u32 rcv_nxt;
265
266         u32 loc_id;
267         u32 rem_id;
268
269         u32 snd_wnd;
270         u32 max_snd_wnd;
271
272         u32 rcv_wnd;
273         u32 mss;
274         u8 snd_wscale;
275         u8 rcv_wscale;
276
277         struct timeval sent_ts;
278 };
279
280 enum i40iw_cm_listener_state {
281         I40IW_CM_LISTENER_PASSIVE_STATE = 1,
282         I40IW_CM_LISTENER_ACTIVE_STATE = 2,
283         I40IW_CM_LISTENER_EITHER_STATE = 3
284 };
285
286 struct i40iw_cm_listener {
287         struct list_head list;
288         struct i40iw_cm_core *cm_core;
289         u8 loc_mac[ETH_ALEN];
290         u32 loc_addr[4];
291         u16 loc_port;
292         struct iw_cm_id *cm_id;
293         atomic_t ref_count;
294         struct i40iw_device *iwdev;
295         atomic_t pend_accepts_cnt;
296         int backlog;
297         enum i40iw_cm_listener_state listener_state;
298         u32 reused_node;
299         u8 user_pri;
300         u16 vlan_id;
301         bool qhash_set;
302         bool ipv4;
303         struct list_head child_listen_list;
304
305 };
306
307 struct i40iw_kmem_info {
308         void *addr;
309         u32 size;
310 };
311
312 /* per connection node and node state information */
313 struct i40iw_cm_node {
314         u32 loc_addr[4], rem_addr[4];
315         u16 loc_port, rem_port;
316         u16 vlan_id;
317         enum i40iw_cm_node_state state;
318         u8 loc_mac[ETH_ALEN];
319         u8 rem_mac[ETH_ALEN];
320         atomic_t ref_count;
321         struct i40iw_qp *iwqp;
322         struct i40iw_device *iwdev;
323         struct i40iw_sc_dev *dev;
324         struct i40iw_cm_tcp_context tcp_cntxt;
325         struct i40iw_cm_core *cm_core;
326         struct i40iw_cm_node *loopbackpartner;
327         struct i40iw_timer_entry *send_entry;
328         struct i40iw_timer_entry *close_entry;
329         spinlock_t retrans_list_lock; /* cm transmit packet */
330         enum send_rdma0 send_rdma0_op;
331         u16 ird_size;
332         u16 ord_size;
333         u16     mpav2_ird_ord;
334         struct iw_cm_id *cm_id;
335         struct list_head list;
336         int accelerated;
337         struct i40iw_cm_listener *listener;
338         int apbvt_set;
339         int accept_pend;
340         struct list_head timer_entry;
341         struct list_head reset_entry;
342         struct list_head connected_entry;
343         atomic_t passive_state;
344         bool qhash_set;
345         u8 user_pri;
346         bool ipv4;
347         bool snd_mark_en;
348         u16 lsmm_size;
349         enum mpa_frame_version mpa_frame_rev;
350         struct i40iw_kmem_info pdata;
351         union {
352                 struct ietf_mpa_v1 mpa_frame;
353                 struct ietf_mpa_v2 mpa_v2_frame;
354         };
355
356         u8 pdata_buf[IETF_MAX_PRIV_DATA_LEN];
357         struct i40iw_kmem_info mpa_hdr;
358 };
359
360 /* structure for client or CM to fill when making CM api calls. */
361 /*      - only need to set relevant data, based on op. */
362 struct i40iw_cm_info {
363         struct iw_cm_id *cm_id;
364         u16 loc_port;
365         u16 rem_port;
366         u32 loc_addr[4];
367         u32 rem_addr[4];
368         u16 vlan_id;
369         int backlog;
370         u8 user_pri;
371         bool ipv4;
372 };
373
374 /* CM event codes */
375 enum i40iw_cm_event_type {
376         I40IW_CM_EVENT_UNKNOWN,
377         I40IW_CM_EVENT_ESTABLISHED,
378         I40IW_CM_EVENT_MPA_REQ,
379         I40IW_CM_EVENT_MPA_CONNECT,
380         I40IW_CM_EVENT_MPA_ACCEPT,
381         I40IW_CM_EVENT_MPA_REJECT,
382         I40IW_CM_EVENT_MPA_ESTABLISHED,
383         I40IW_CM_EVENT_CONNECTED,
384         I40IW_CM_EVENT_RESET,
385         I40IW_CM_EVENT_ABORTED
386 };
387
388 /* event to post to CM event handler */
389 struct i40iw_cm_event {
390         enum i40iw_cm_event_type type;
391         struct i40iw_cm_info cm_info;
392         struct work_struct event_work;
393         struct i40iw_cm_node *cm_node;
394 };
395
396 struct i40iw_cm_core {
397         struct i40iw_device *iwdev;
398         struct i40iw_sc_dev *dev;
399
400         struct list_head listen_nodes;
401         struct list_head connected_nodes;
402
403         struct timer_list tcp_timer;
404
405         struct workqueue_struct *event_wq;
406         struct workqueue_struct *disconn_wq;
407
408         spinlock_t ht_lock; /* manage hash table */
409         spinlock_t listen_list_lock; /* listen list */
410
411         u64     stats_nodes_created;
412         u64     stats_nodes_destroyed;
413         u64     stats_listen_created;
414         u64     stats_listen_destroyed;
415         u64     stats_listen_nodes_created;
416         u64     stats_listen_nodes_destroyed;
417         u64     stats_loopbacks;
418         u64     stats_accepts;
419         u64     stats_rejects;
420         u64     stats_connect_errs;
421         u64     stats_passive_errs;
422         u64     stats_pkt_retrans;
423         u64     stats_backlog_drops;
424 };
425
426 int i40iw_schedule_cm_timer(struct i40iw_cm_node *cm_node,
427                             struct i40iw_puda_buf *sqbuf,
428                             enum i40iw_timer_type type,
429                             int send_retrans,
430                             int close_when_complete);
431
432 int i40iw_accept(struct iw_cm_id *, struct iw_cm_conn_param *);
433 int i40iw_reject(struct iw_cm_id *, const void *, u8);
434 int i40iw_connect(struct iw_cm_id *, struct iw_cm_conn_param *);
435 int i40iw_create_listen(struct iw_cm_id *, int);
436 int i40iw_destroy_listen(struct iw_cm_id *);
437
438 int i40iw_cm_start(struct i40iw_device *);
439 int i40iw_cm_stop(struct i40iw_device *);
440
441 int i40iw_arp_table(struct i40iw_device *iwdev,
442                     u32 *ip_addr,
443                     bool ipv4,
444                     u8 *mac_addr,
445                     u32 action);
446
447 void i40iw_cm_disconnect_all(struct i40iw_device *iwdev);
448 #endif /* I40IW_CM_H */