Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/infiniband/hw/nes/nes_cm.c
15112 views
1
/*
2
* Copyright (c) 2006 - 2009 Intel Corporation. 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
35
#define TCPOPT_TIMESTAMP 8
36
37
#include <asm/atomic.h>
38
#include <linux/skbuff.h>
39
#include <linux/ip.h>
40
#include <linux/tcp.h>
41
#include <linux/init.h>
42
#include <linux/if_arp.h>
43
#include <linux/if_vlan.h>
44
#include <linux/notifier.h>
45
#include <linux/net.h>
46
#include <linux/types.h>
47
#include <linux/timer.h>
48
#include <linux/time.h>
49
#include <linux/delay.h>
50
#include <linux/etherdevice.h>
51
#include <linux/netdevice.h>
52
#include <linux/random.h>
53
#include <linux/list.h>
54
#include <linux/threads.h>
55
#include <linux/highmem.h>
56
#include <linux/slab.h>
57
#include <net/arp.h>
58
#include <net/neighbour.h>
59
#include <net/route.h>
60
#include <net/ip_fib.h>
61
#include <net/tcp.h>
62
63
#include "nes.h"
64
65
u32 cm_packets_sent;
66
u32 cm_packets_bounced;
67
u32 cm_packets_dropped;
68
u32 cm_packets_retrans;
69
u32 cm_packets_created;
70
u32 cm_packets_received;
71
atomic_t cm_listens_created;
72
atomic_t cm_listens_destroyed;
73
u32 cm_backlog_drops;
74
atomic_t cm_loopbacks;
75
atomic_t cm_nodes_created;
76
atomic_t cm_nodes_destroyed;
77
atomic_t cm_accel_dropped_pkts;
78
atomic_t cm_resets_recvd;
79
80
static inline int mini_cm_accelerated(struct nes_cm_core *,
81
struct nes_cm_node *);
82
static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *,
83
struct nes_vnic *, struct nes_cm_info *);
84
static int mini_cm_del_listen(struct nes_cm_core *, struct nes_cm_listener *);
85
static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *,
86
struct nes_vnic *, u16, void *, struct nes_cm_info *);
87
static int mini_cm_close(struct nes_cm_core *, struct nes_cm_node *);
88
static int mini_cm_accept(struct nes_cm_core *, struct ietf_mpa_frame *,
89
struct nes_cm_node *);
90
static int mini_cm_reject(struct nes_cm_core *, struct ietf_mpa_frame *,
91
struct nes_cm_node *);
92
static int mini_cm_recv_pkt(struct nes_cm_core *, struct nes_vnic *,
93
struct sk_buff *);
94
static int mini_cm_dealloc_core(struct nes_cm_core *);
95
static int mini_cm_get(struct nes_cm_core *);
96
static int mini_cm_set(struct nes_cm_core *, u32, u32);
97
98
static void form_cm_frame(struct sk_buff *, struct nes_cm_node *,
99
void *, u32, void *, u32, u8);
100
static int add_ref_cm_node(struct nes_cm_node *);
101
static int rem_ref_cm_node(struct nes_cm_core *, struct nes_cm_node *);
102
103
static int nes_cm_disconn_true(struct nes_qp *);
104
static int nes_cm_post_event(struct nes_cm_event *event);
105
static int nes_disconnect(struct nes_qp *nesqp, int abrupt);
106
static void nes_disconnect_worker(struct work_struct *work);
107
108
static int send_mpa_request(struct nes_cm_node *, struct sk_buff *);
109
static int send_mpa_reject(struct nes_cm_node *);
110
static int send_syn(struct nes_cm_node *, u32, struct sk_buff *);
111
static int send_reset(struct nes_cm_node *, struct sk_buff *);
112
static int send_ack(struct nes_cm_node *cm_node, struct sk_buff *skb);
113
static int send_fin(struct nes_cm_node *cm_node, struct sk_buff *skb);
114
static void process_packet(struct nes_cm_node *, struct sk_buff *,
115
struct nes_cm_core *);
116
117
static void active_open_err(struct nes_cm_node *, struct sk_buff *, int);
118
static void passive_open_err(struct nes_cm_node *, struct sk_buff *, int);
119
static void cleanup_retrans_entry(struct nes_cm_node *);
120
static void handle_rcv_mpa(struct nes_cm_node *, struct sk_buff *);
121
static void free_retrans_entry(struct nes_cm_node *cm_node);
122
static int handle_tcp_options(struct nes_cm_node *cm_node, struct tcphdr *tcph,
123
struct sk_buff *skb, int optionsize, int passive);
124
125
/* CM event handler functions */
126
static void cm_event_connected(struct nes_cm_event *);
127
static void cm_event_connect_error(struct nes_cm_event *);
128
static void cm_event_reset(struct nes_cm_event *);
129
static void cm_event_mpa_req(struct nes_cm_event *);
130
static void cm_event_mpa_reject(struct nes_cm_event *);
131
static void handle_recv_entry(struct nes_cm_node *cm_node, u32 rem_node);
132
133
static void print_core(struct nes_cm_core *core);
134
135
/* External CM API Interface */
136
/* instance of function pointers for client API */
137
/* set address of this instance to cm_core->cm_ops at cm_core alloc */
138
static struct nes_cm_ops nes_cm_api = {
139
mini_cm_accelerated,
140
mini_cm_listen,
141
mini_cm_del_listen,
142
mini_cm_connect,
143
mini_cm_close,
144
mini_cm_accept,
145
mini_cm_reject,
146
mini_cm_recv_pkt,
147
mini_cm_dealloc_core,
148
mini_cm_get,
149
mini_cm_set
150
};
151
152
static struct nes_cm_core *g_cm_core;
153
154
atomic_t cm_connects;
155
atomic_t cm_accepts;
156
atomic_t cm_disconnects;
157
atomic_t cm_closes;
158
atomic_t cm_connecteds;
159
atomic_t cm_connect_reqs;
160
atomic_t cm_rejects;
161
162
163
/**
164
* create_event
165
*/
166
static struct nes_cm_event *create_event(struct nes_cm_node *cm_node,
167
enum nes_cm_event_type type)
168
{
169
struct nes_cm_event *event;
170
171
if (!cm_node->cm_id)
172
return NULL;
173
174
/* allocate an empty event */
175
event = kzalloc(sizeof(*event), GFP_ATOMIC);
176
177
if (!event)
178
return NULL;
179
180
event->type = type;
181
event->cm_node = cm_node;
182
event->cm_info.rem_addr = cm_node->rem_addr;
183
event->cm_info.loc_addr = cm_node->loc_addr;
184
event->cm_info.rem_port = cm_node->rem_port;
185
event->cm_info.loc_port = cm_node->loc_port;
186
event->cm_info.cm_id = cm_node->cm_id;
187
188
nes_debug(NES_DBG_CM, "cm_node=%p Created event=%p, type=%u, "
189
"dst_addr=%08x[%x], src_addr=%08x[%x]\n",
190
cm_node, event, type, event->cm_info.loc_addr,
191
event->cm_info.loc_port, event->cm_info.rem_addr,
192
event->cm_info.rem_port);
193
194
nes_cm_post_event(event);
195
return event;
196
}
197
198
199
/**
200
* send_mpa_request
201
*/
202
static int send_mpa_request(struct nes_cm_node *cm_node, struct sk_buff *skb)
203
{
204
if (!skb) {
205
nes_debug(NES_DBG_CM, "skb set to NULL\n");
206
return -1;
207
}
208
209
/* send an MPA Request frame */
210
form_cm_frame(skb, cm_node, NULL, 0, &cm_node->mpa_frame,
211
cm_node->mpa_frame_size, SET_ACK);
212
213
return schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0);
214
}
215
216
217
218
static int send_mpa_reject(struct nes_cm_node *cm_node)
219
{
220
struct sk_buff *skb = NULL;
221
222
skb = dev_alloc_skb(MAX_CM_BUFFER);
223
if (!skb) {
224
nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
225
return -ENOMEM;
226
}
227
228
/* send an MPA reject frame */
229
form_cm_frame(skb, cm_node, NULL, 0, &cm_node->mpa_frame,
230
cm_node->mpa_frame_size, SET_ACK | SET_FIN);
231
232
cm_node->state = NES_CM_STATE_FIN_WAIT1;
233
return schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0);
234
}
235
236
237
/**
238
* recv_mpa - process a received TCP pkt, we are expecting an
239
* IETF MPA frame
240
*/
241
static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 *type,
242
u32 len)
243
{
244
struct ietf_mpa_frame *mpa_frame;
245
246
*type = NES_MPA_REQUEST_ACCEPT;
247
248
/* assume req frame is in tcp data payload */
249
if (len < sizeof(struct ietf_mpa_frame)) {
250
nes_debug(NES_DBG_CM, "The received ietf buffer was too small (%x)\n", len);
251
return -EINVAL;
252
}
253
254
mpa_frame = (struct ietf_mpa_frame *)buffer;
255
cm_node->mpa_frame_size = ntohs(mpa_frame->priv_data_len);
256
/* make sure mpa private data len is less than 512 bytes */
257
if (cm_node->mpa_frame_size > IETF_MAX_PRIV_DATA_LEN) {
258
nes_debug(NES_DBG_CM, "The received Length of Private"
259
" Data field exceeds 512 octets\n");
260
return -EINVAL;
261
}
262
/*
263
* make sure MPA receiver interoperate with the
264
* received MPA version and MPA key information
265
*
266
*/
267
if (mpa_frame->rev != mpa_version) {
268
nes_debug(NES_DBG_CM, "The received mpa version"
269
" can not be interoperated\n");
270
return -EINVAL;
271
}
272
if (cm_node->state != NES_CM_STATE_MPAREQ_SENT) {
273
if (memcmp(mpa_frame->key, IEFT_MPA_KEY_REQ, IETF_MPA_KEY_SIZE)) {
274
nes_debug(NES_DBG_CM, "Unexpected MPA Key received \n");
275
return -EINVAL;
276
}
277
} else {
278
if (memcmp(mpa_frame->key, IEFT_MPA_KEY_REP, IETF_MPA_KEY_SIZE)) {
279
nes_debug(NES_DBG_CM, "Unexpected MPA Key received \n");
280
return -EINVAL;
281
}
282
}
283
284
if (cm_node->mpa_frame_size + sizeof(struct ietf_mpa_frame) != len) {
285
nes_debug(NES_DBG_CM, "The received ietf buffer was not right"
286
" complete (%x + %x != %x)\n",
287
cm_node->mpa_frame_size,
288
(u32)sizeof(struct ietf_mpa_frame), len);
289
return -EINVAL;
290
}
291
/* make sure it does not exceed the max size */
292
if (len > MAX_CM_BUFFER) {
293
nes_debug(NES_DBG_CM, "The received ietf buffer was too large"
294
" (%x + %x != %x)\n",
295
cm_node->mpa_frame_size,
296
(u32)sizeof(struct ietf_mpa_frame), len);
297
return -EINVAL;
298
}
299
300
/* copy entire MPA frame to our cm_node's frame */
301
memcpy(cm_node->mpa_frame_buf, buffer + sizeof(struct ietf_mpa_frame),
302
cm_node->mpa_frame_size);
303
304
if (mpa_frame->flags & IETF_MPA_FLAGS_REJECT)
305
*type = NES_MPA_REQUEST_REJECT;
306
return 0;
307
}
308
309
310
/**
311
* form_cm_frame - get a free packet and build empty frame Use
312
* node info to build.
313
*/
314
static void form_cm_frame(struct sk_buff *skb,
315
struct nes_cm_node *cm_node, void *options, u32 optionsize,
316
void *data, u32 datasize, u8 flags)
317
{
318
struct tcphdr *tcph;
319
struct iphdr *iph;
320
struct ethhdr *ethh;
321
u8 *buf;
322
u16 packetsize = sizeof(*iph);
323
324
packetsize += sizeof(*tcph);
325
packetsize += optionsize + datasize;
326
327
memset(skb->data, 0x00, ETH_HLEN + sizeof(*iph) + sizeof(*tcph));
328
329
skb->len = 0;
330
buf = skb_put(skb, packetsize + ETH_HLEN);
331
332
ethh = (struct ethhdr *) buf;
333
buf += ETH_HLEN;
334
335
iph = (struct iphdr *)buf;
336
buf += sizeof(*iph);
337
tcph = (struct tcphdr *)buf;
338
skb_reset_mac_header(skb);
339
skb_set_network_header(skb, ETH_HLEN);
340
skb_set_transport_header(skb, ETH_HLEN+sizeof(*iph));
341
buf += sizeof(*tcph);
342
343
skb->ip_summed = CHECKSUM_PARTIAL;
344
skb->protocol = htons(0x800);
345
skb->data_len = 0;
346
skb->mac_len = ETH_HLEN;
347
348
memcpy(ethh->h_dest, cm_node->rem_mac, ETH_ALEN);
349
memcpy(ethh->h_source, cm_node->loc_mac, ETH_ALEN);
350
ethh->h_proto = htons(0x0800);
351
352
iph->version = IPVERSION;
353
iph->ihl = 5; /* 5 * 4Byte words, IP headr len */
354
iph->tos = 0;
355
iph->tot_len = htons(packetsize);
356
iph->id = htons(++cm_node->tcp_cntxt.loc_id);
357
358
iph->frag_off = htons(0x4000);
359
iph->ttl = 0x40;
360
iph->protocol = 0x06; /* IPPROTO_TCP */
361
362
iph->saddr = htonl(cm_node->loc_addr);
363
iph->daddr = htonl(cm_node->rem_addr);
364
365
tcph->source = htons(cm_node->loc_port);
366
tcph->dest = htons(cm_node->rem_port);
367
tcph->seq = htonl(cm_node->tcp_cntxt.loc_seq_num);
368
369
if (flags & SET_ACK) {
370
cm_node->tcp_cntxt.loc_ack_num = cm_node->tcp_cntxt.rcv_nxt;
371
tcph->ack_seq = htonl(cm_node->tcp_cntxt.loc_ack_num);
372
tcph->ack = 1;
373
} else
374
tcph->ack_seq = 0;
375
376
if (flags & SET_SYN) {
377
cm_node->tcp_cntxt.loc_seq_num++;
378
tcph->syn = 1;
379
} else
380
cm_node->tcp_cntxt.loc_seq_num += datasize;
381
382
if (flags & SET_FIN) {
383
cm_node->tcp_cntxt.loc_seq_num++;
384
tcph->fin = 1;
385
}
386
387
if (flags & SET_RST)
388
tcph->rst = 1;
389
390
tcph->doff = (u16)((sizeof(*tcph) + optionsize + 3) >> 2);
391
tcph->window = htons(cm_node->tcp_cntxt.rcv_wnd);
392
tcph->urg_ptr = 0;
393
if (optionsize)
394
memcpy(buf, options, optionsize);
395
buf += optionsize;
396
if (datasize)
397
memcpy(buf, data, datasize);
398
399
skb_shinfo(skb)->nr_frags = 0;
400
cm_packets_created++;
401
402
}
403
404
405
/**
406
* print_core - dump a cm core
407
*/
408
static void print_core(struct nes_cm_core *core)
409
{
410
nes_debug(NES_DBG_CM, "---------------------------------------------\n");
411
nes_debug(NES_DBG_CM, "CM Core -- (core = %p )\n", core);
412
if (!core)
413
return;
414
nes_debug(NES_DBG_CM, "---------------------------------------------\n");
415
416
nes_debug(NES_DBG_CM, "State : %u \n", core->state);
417
418
nes_debug(NES_DBG_CM, "Listen Nodes : %u \n", atomic_read(&core->listen_node_cnt));
419
nes_debug(NES_DBG_CM, "Active Nodes : %u \n", atomic_read(&core->node_cnt));
420
421
nes_debug(NES_DBG_CM, "core : %p \n", core);
422
423
nes_debug(NES_DBG_CM, "-------------- end core ---------------\n");
424
}
425
426
427
/**
428
* schedule_nes_timer
429
* note - cm_node needs to be protected before calling this. Encase in:
430
* rem_ref_cm_node(cm_core, cm_node);add_ref_cm_node(cm_node);
431
*/
432
int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
433
enum nes_timer_type type, int send_retrans,
434
int close_when_complete)
435
{
436
unsigned long flags;
437
struct nes_cm_core *cm_core = cm_node->cm_core;
438
struct nes_timer_entry *new_send;
439
int ret = 0;
440
u32 was_timer_set;
441
442
new_send = kzalloc(sizeof(*new_send), GFP_ATOMIC);
443
if (!new_send)
444
return -ENOMEM;
445
446
/* new_send->timetosend = currenttime */
447
new_send->retrycount = NES_DEFAULT_RETRYS;
448
new_send->retranscount = NES_DEFAULT_RETRANS;
449
new_send->skb = skb;
450
new_send->timetosend = jiffies;
451
new_send->type = type;
452
new_send->netdev = cm_node->netdev;
453
new_send->send_retrans = send_retrans;
454
new_send->close_when_complete = close_when_complete;
455
456
if (type == NES_TIMER_TYPE_CLOSE) {
457
new_send->timetosend += (HZ/10);
458
if (cm_node->recv_entry) {
459
kfree(new_send);
460
WARN_ON(1);
461
return -EINVAL;
462
}
463
cm_node->recv_entry = new_send;
464
}
465
466
if (type == NES_TIMER_TYPE_SEND) {
467
new_send->seq_num = ntohl(tcp_hdr(skb)->seq);
468
atomic_inc(&new_send->skb->users);
469
spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
470
cm_node->send_entry = new_send;
471
add_ref_cm_node(cm_node);
472
spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
473
new_send->timetosend = jiffies + NES_RETRY_TIMEOUT;
474
475
ret = nes_nic_cm_xmit(new_send->skb, cm_node->netdev);
476
if (ret != NETDEV_TX_OK) {
477
nes_debug(NES_DBG_CM, "Error sending packet %p "
478
"(jiffies = %lu)\n", new_send, jiffies);
479
new_send->timetosend = jiffies;
480
ret = NETDEV_TX_OK;
481
} else {
482
cm_packets_sent++;
483
if (!send_retrans) {
484
cleanup_retrans_entry(cm_node);
485
if (close_when_complete)
486
rem_ref_cm_node(cm_core, cm_node);
487
return ret;
488
}
489
}
490
}
491
492
was_timer_set = timer_pending(&cm_core->tcp_timer);
493
494
if (!was_timer_set) {
495
cm_core->tcp_timer.expires = new_send->timetosend;
496
add_timer(&cm_core->tcp_timer);
497
}
498
499
return ret;
500
}
501
502
static void nes_retrans_expired(struct nes_cm_node *cm_node)
503
{
504
struct iw_cm_id *cm_id = cm_node->cm_id;
505
enum nes_cm_node_state state = cm_node->state;
506
cm_node->state = NES_CM_STATE_CLOSED;
507
switch (state) {
508
case NES_CM_STATE_SYN_RCVD:
509
case NES_CM_STATE_CLOSING:
510
rem_ref_cm_node(cm_node->cm_core, cm_node);
511
break;
512
case NES_CM_STATE_LAST_ACK:
513
case NES_CM_STATE_FIN_WAIT1:
514
if (cm_node->cm_id)
515
cm_id->rem_ref(cm_id);
516
send_reset(cm_node, NULL);
517
break;
518
default:
519
add_ref_cm_node(cm_node);
520
send_reset(cm_node, NULL);
521
create_event(cm_node, NES_CM_EVENT_ABORTED);
522
}
523
}
524
525
static void handle_recv_entry(struct nes_cm_node *cm_node, u32 rem_node)
526
{
527
struct nes_timer_entry *recv_entry = cm_node->recv_entry;
528
struct iw_cm_id *cm_id = cm_node->cm_id;
529
struct nes_qp *nesqp;
530
unsigned long qplockflags;
531
532
if (!recv_entry)
533
return;
534
nesqp = (struct nes_qp *)recv_entry->skb;
535
if (nesqp) {
536
spin_lock_irqsave(&nesqp->lock, qplockflags);
537
if (nesqp->cm_id) {
538
nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
539
"refcount = %d: HIT A "
540
"NES_TIMER_TYPE_CLOSE with something "
541
"to do!!!\n", nesqp->hwqp.qp_id, cm_id,
542
atomic_read(&nesqp->refcount));
543
nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
544
nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT;
545
nesqp->ibqp_state = IB_QPS_ERR;
546
spin_unlock_irqrestore(&nesqp->lock, qplockflags);
547
nes_cm_disconn(nesqp);
548
} else {
549
spin_unlock_irqrestore(&nesqp->lock, qplockflags);
550
nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
551
"refcount = %d: HIT A "
552
"NES_TIMER_TYPE_CLOSE with nothing "
553
"to do!!!\n", nesqp->hwqp.qp_id, cm_id,
554
atomic_read(&nesqp->refcount));
555
}
556
} else if (rem_node) {
557
/* TIME_WAIT state */
558
rem_ref_cm_node(cm_node->cm_core, cm_node);
559
}
560
if (cm_node->cm_id)
561
cm_id->rem_ref(cm_id);
562
kfree(recv_entry);
563
cm_node->recv_entry = NULL;
564
}
565
566
/**
567
* nes_cm_timer_tick
568
*/
569
static void nes_cm_timer_tick(unsigned long pass)
570
{
571
unsigned long flags;
572
unsigned long nexttimeout = jiffies + NES_LONG_TIME;
573
struct nes_cm_node *cm_node;
574
struct nes_timer_entry *send_entry, *recv_entry;
575
struct list_head *list_core_temp;
576
struct list_head *list_node;
577
struct nes_cm_core *cm_core = g_cm_core;
578
u32 settimer = 0;
579
unsigned long timetosend;
580
int ret = NETDEV_TX_OK;
581
582
struct list_head timer_list;
583
INIT_LIST_HEAD(&timer_list);
584
spin_lock_irqsave(&cm_core->ht_lock, flags);
585
586
list_for_each_safe(list_node, list_core_temp,
587
&cm_core->connected_nodes) {
588
cm_node = container_of(list_node, struct nes_cm_node, list);
589
if ((cm_node->recv_entry) || (cm_node->send_entry)) {
590
add_ref_cm_node(cm_node);
591
list_add(&cm_node->timer_entry, &timer_list);
592
}
593
}
594
spin_unlock_irqrestore(&cm_core->ht_lock, flags);
595
596
list_for_each_safe(list_node, list_core_temp, &timer_list) {
597
cm_node = container_of(list_node, struct nes_cm_node,
598
timer_entry);
599
recv_entry = cm_node->recv_entry;
600
601
if (recv_entry) {
602
if (time_after(recv_entry->timetosend, jiffies)) {
603
if (nexttimeout > recv_entry->timetosend ||
604
!settimer) {
605
nexttimeout = recv_entry->timetosend;
606
settimer = 1;
607
}
608
} else
609
handle_recv_entry(cm_node, 1);
610
}
611
612
spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
613
do {
614
send_entry = cm_node->send_entry;
615
if (!send_entry)
616
break;
617
if (time_after(send_entry->timetosend, jiffies)) {
618
if (cm_node->state != NES_CM_STATE_TSA) {
619
if ((nexttimeout >
620
send_entry->timetosend) ||
621
!settimer) {
622
nexttimeout =
623
send_entry->timetosend;
624
settimer = 1;
625
}
626
} else {
627
free_retrans_entry(cm_node);
628
}
629
break;
630
}
631
632
if ((cm_node->state == NES_CM_STATE_TSA) ||
633
(cm_node->state == NES_CM_STATE_CLOSED)) {
634
free_retrans_entry(cm_node);
635
break;
636
}
637
638
if (!send_entry->retranscount ||
639
!send_entry->retrycount) {
640
cm_packets_dropped++;
641
free_retrans_entry(cm_node);
642
643
spin_unlock_irqrestore(
644
&cm_node->retrans_list_lock, flags);
645
nes_retrans_expired(cm_node);
646
cm_node->state = NES_CM_STATE_CLOSED;
647
spin_lock_irqsave(&cm_node->retrans_list_lock,
648
flags);
649
break;
650
}
651
atomic_inc(&send_entry->skb->users);
652
cm_packets_retrans++;
653
nes_debug(NES_DBG_CM, "Retransmitting send_entry %p "
654
"for node %p, jiffies = %lu, time to send = "
655
"%lu, retranscount = %u, send_entry->seq_num = "
656
"0x%08X, cm_node->tcp_cntxt.rem_ack_num = "
657
"0x%08X\n", send_entry, cm_node, jiffies,
658
send_entry->timetosend,
659
send_entry->retranscount,
660
send_entry->seq_num,
661
cm_node->tcp_cntxt.rem_ack_num);
662
663
spin_unlock_irqrestore(&cm_node->retrans_list_lock,
664
flags);
665
ret = nes_nic_cm_xmit(send_entry->skb, cm_node->netdev);
666
spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
667
if (ret != NETDEV_TX_OK) {
668
nes_debug(NES_DBG_CM, "rexmit failed for "
669
"node=%p\n", cm_node);
670
cm_packets_bounced++;
671
send_entry->retrycount--;
672
nexttimeout = jiffies + NES_SHORT_TIME;
673
settimer = 1;
674
break;
675
} else {
676
cm_packets_sent++;
677
}
678
nes_debug(NES_DBG_CM, "Packet Sent: retrans count = "
679
"%u, retry count = %u.\n",
680
send_entry->retranscount,
681
send_entry->retrycount);
682
if (send_entry->send_retrans) {
683
send_entry->retranscount--;
684
timetosend = (NES_RETRY_TIMEOUT <<
685
(NES_DEFAULT_RETRANS - send_entry->retranscount));
686
687
send_entry->timetosend = jiffies +
688
min(timetosend, NES_MAX_TIMEOUT);
689
if (nexttimeout > send_entry->timetosend ||
690
!settimer) {
691
nexttimeout = send_entry->timetosend;
692
settimer = 1;
693
}
694
} else {
695
int close_when_complete;
696
close_when_complete =
697
send_entry->close_when_complete;
698
nes_debug(NES_DBG_CM, "cm_node=%p state=%d\n",
699
cm_node, cm_node->state);
700
free_retrans_entry(cm_node);
701
if (close_when_complete)
702
rem_ref_cm_node(cm_node->cm_core,
703
cm_node);
704
}
705
} while (0);
706
707
spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
708
rem_ref_cm_node(cm_node->cm_core, cm_node);
709
}
710
711
if (settimer) {
712
if (!timer_pending(&cm_core->tcp_timer)) {
713
cm_core->tcp_timer.expires = nexttimeout;
714
add_timer(&cm_core->tcp_timer);
715
}
716
}
717
}
718
719
720
/**
721
* send_syn
722
*/
723
static int send_syn(struct nes_cm_node *cm_node, u32 sendack,
724
struct sk_buff *skb)
725
{
726
int ret;
727
int flags = SET_SYN;
728
char optionsbuffer[sizeof(struct option_mss) +
729
sizeof(struct option_windowscale) + sizeof(struct option_base) +
730
TCP_OPTIONS_PADDING];
731
732
int optionssize = 0;
733
/* Sending MSS option */
734
union all_known_options *options;
735
736
if (!cm_node)
737
return -EINVAL;
738
739
options = (union all_known_options *)&optionsbuffer[optionssize];
740
options->as_mss.optionnum = OPTION_NUMBER_MSS;
741
options->as_mss.length = sizeof(struct option_mss);
742
options->as_mss.mss = htons(cm_node->tcp_cntxt.mss);
743
optionssize += sizeof(struct option_mss);
744
745
options = (union all_known_options *)&optionsbuffer[optionssize];
746
options->as_windowscale.optionnum = OPTION_NUMBER_WINDOW_SCALE;
747
options->as_windowscale.length = sizeof(struct option_windowscale);
748
options->as_windowscale.shiftcount = cm_node->tcp_cntxt.rcv_wscale;
749
optionssize += sizeof(struct option_windowscale);
750
751
if (sendack && !(NES_DRV_OPT_SUPRESS_OPTION_BC & nes_drv_opt)) {
752
options = (union all_known_options *)&optionsbuffer[optionssize];
753
options->as_base.optionnum = OPTION_NUMBER_WRITE0;
754
options->as_base.length = sizeof(struct option_base);
755
optionssize += sizeof(struct option_base);
756
/* we need the size to be a multiple of 4 */
757
options = (union all_known_options *)&optionsbuffer[optionssize];
758
options->as_end = 1;
759
optionssize += 1;
760
options = (union all_known_options *)&optionsbuffer[optionssize];
761
options->as_end = 1;
762
optionssize += 1;
763
}
764
765
options = (union all_known_options *)&optionsbuffer[optionssize];
766
options->as_end = OPTION_NUMBER_END;
767
optionssize += 1;
768
769
if (!skb)
770
skb = dev_alloc_skb(MAX_CM_BUFFER);
771
if (!skb) {
772
nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
773
return -1;
774
}
775
776
if (sendack)
777
flags |= SET_ACK;
778
779
form_cm_frame(skb, cm_node, optionsbuffer, optionssize, NULL, 0, flags);
780
ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0);
781
782
return ret;
783
}
784
785
786
/**
787
* send_reset
788
*/
789
static int send_reset(struct nes_cm_node *cm_node, struct sk_buff *skb)
790
{
791
int ret;
792
int flags = SET_RST | SET_ACK;
793
794
if (!skb)
795
skb = dev_alloc_skb(MAX_CM_BUFFER);
796
if (!skb) {
797
nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
798
return -ENOMEM;
799
}
800
801
form_cm_frame(skb, cm_node, NULL, 0, NULL, 0, flags);
802
ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 0, 1);
803
804
return ret;
805
}
806
807
808
/**
809
* send_ack
810
*/
811
static int send_ack(struct nes_cm_node *cm_node, struct sk_buff *skb)
812
{
813
int ret;
814
815
if (!skb)
816
skb = dev_alloc_skb(MAX_CM_BUFFER);
817
818
if (!skb) {
819
nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
820
return -1;
821
}
822
823
form_cm_frame(skb, cm_node, NULL, 0, NULL, 0, SET_ACK);
824
ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 0, 0);
825
826
return ret;
827
}
828
829
830
/**
831
* send_fin
832
*/
833
static int send_fin(struct nes_cm_node *cm_node, struct sk_buff *skb)
834
{
835
int ret;
836
837
/* if we didn't get a frame get one */
838
if (!skb)
839
skb = dev_alloc_skb(MAX_CM_BUFFER);
840
841
if (!skb) {
842
nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
843
return -1;
844
}
845
846
form_cm_frame(skb, cm_node, NULL, 0, NULL, 0, SET_ACK | SET_FIN);
847
ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0);
848
849
return ret;
850
}
851
852
853
/**
854
* find_node - find a cm node that matches the reference cm node
855
*/
856
static struct nes_cm_node *find_node(struct nes_cm_core *cm_core,
857
u16 rem_port, nes_addr_t rem_addr, u16 loc_port, nes_addr_t loc_addr)
858
{
859
unsigned long flags;
860
struct list_head *hte;
861
struct nes_cm_node *cm_node;
862
863
/* get a handle on the hte */
864
hte = &cm_core->connected_nodes;
865
866
/* walk list and find cm_node associated with this session ID */
867
spin_lock_irqsave(&cm_core->ht_lock, flags);
868
list_for_each_entry(cm_node, hte, list) {
869
/* compare quad, return node handle if a match */
870
nes_debug(NES_DBG_CM, "finding node %x:%x =? %x:%x ^ %x:%x =? %x:%x\n",
871
cm_node->loc_addr, cm_node->loc_port,
872
loc_addr, loc_port,
873
cm_node->rem_addr, cm_node->rem_port,
874
rem_addr, rem_port);
875
if ((cm_node->loc_addr == loc_addr) && (cm_node->loc_port == loc_port) &&
876
(cm_node->rem_addr == rem_addr) && (cm_node->rem_port == rem_port)) {
877
add_ref_cm_node(cm_node);
878
spin_unlock_irqrestore(&cm_core->ht_lock, flags);
879
return cm_node;
880
}
881
}
882
spin_unlock_irqrestore(&cm_core->ht_lock, flags);
883
884
/* no owner node */
885
return NULL;
886
}
887
888
889
/**
890
* find_listener - find a cm node listening on this addr-port pair
891
*/
892
static struct nes_cm_listener *find_listener(struct nes_cm_core *cm_core,
893
nes_addr_t dst_addr, u16 dst_port, enum nes_cm_listener_state listener_state)
894
{
895
unsigned long flags;
896
struct nes_cm_listener *listen_node;
897
898
/* walk list and find cm_node associated with this session ID */
899
spin_lock_irqsave(&cm_core->listen_list_lock, flags);
900
list_for_each_entry(listen_node, &cm_core->listen_list.list, list) {
901
/* compare node pair, return node handle if a match */
902
if (((listen_node->loc_addr == dst_addr) ||
903
listen_node->loc_addr == 0x00000000) &&
904
(listen_node->loc_port == dst_port) &&
905
(listener_state & listen_node->listener_state)) {
906
atomic_inc(&listen_node->ref_count);
907
spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
908
return listen_node;
909
}
910
}
911
spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
912
913
/* no listener */
914
return NULL;
915
}
916
917
918
/**
919
* add_hte_node - add a cm node to the hash table
920
*/
921
static int add_hte_node(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node)
922
{
923
unsigned long flags;
924
struct list_head *hte;
925
926
if (!cm_node || !cm_core)
927
return -EINVAL;
928
929
nes_debug(NES_DBG_CM, "Adding Node %p to Active Connection HT\n",
930
cm_node);
931
932
spin_lock_irqsave(&cm_core->ht_lock, flags);
933
934
/* get a handle on the hash table element (list head for this slot) */
935
hte = &cm_core->connected_nodes;
936
list_add_tail(&cm_node->list, hte);
937
atomic_inc(&cm_core->ht_node_cnt);
938
939
spin_unlock_irqrestore(&cm_core->ht_lock, flags);
940
941
return 0;
942
}
943
944
945
/**
946
* mini_cm_dec_refcnt_listen
947
*/
948
static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
949
struct nes_cm_listener *listener, int free_hanging_nodes)
950
{
951
int ret = -EINVAL;
952
int err = 0;
953
unsigned long flags;
954
struct list_head *list_pos = NULL;
955
struct list_head *list_temp = NULL;
956
struct nes_cm_node *cm_node = NULL;
957
struct list_head reset_list;
958
959
nes_debug(NES_DBG_CM, "attempting listener= %p free_nodes= %d, "
960
"refcnt=%d\n", listener, free_hanging_nodes,
961
atomic_read(&listener->ref_count));
962
/* free non-accelerated child nodes for this listener */
963
INIT_LIST_HEAD(&reset_list);
964
if (free_hanging_nodes) {
965
spin_lock_irqsave(&cm_core->ht_lock, flags);
966
list_for_each_safe(list_pos, list_temp,
967
&g_cm_core->connected_nodes) {
968
cm_node = container_of(list_pos, struct nes_cm_node,
969
list);
970
if ((cm_node->listener == listener) &&
971
(!cm_node->accelerated)) {
972
add_ref_cm_node(cm_node);
973
list_add(&cm_node->reset_entry, &reset_list);
974
}
975
}
976
spin_unlock_irqrestore(&cm_core->ht_lock, flags);
977
}
978
979
list_for_each_safe(list_pos, list_temp, &reset_list) {
980
cm_node = container_of(list_pos, struct nes_cm_node,
981
reset_entry);
982
{
983
struct nes_cm_node *loopback = cm_node->loopbackpartner;
984
enum nes_cm_node_state old_state;
985
if (NES_CM_STATE_FIN_WAIT1 <= cm_node->state) {
986
rem_ref_cm_node(cm_node->cm_core, cm_node);
987
} else {
988
if (!loopback) {
989
cleanup_retrans_entry(cm_node);
990
err = send_reset(cm_node, NULL);
991
if (err) {
992
cm_node->state =
993
NES_CM_STATE_CLOSED;
994
WARN_ON(1);
995
} else {
996
old_state = cm_node->state;
997
cm_node->state = NES_CM_STATE_LISTENER_DESTROYED;
998
if (old_state != NES_CM_STATE_MPAREQ_RCVD)
999
rem_ref_cm_node(
1000
cm_node->cm_core,
1001
cm_node);
1002
}
1003
} else {
1004
struct nes_cm_event event;
1005
1006
event.cm_node = loopback;
1007
event.cm_info.rem_addr =
1008
loopback->rem_addr;
1009
event.cm_info.loc_addr =
1010
loopback->loc_addr;
1011
event.cm_info.rem_port =
1012
loopback->rem_port;
1013
event.cm_info.loc_port =
1014
loopback->loc_port;
1015
event.cm_info.cm_id = loopback->cm_id;
1016
add_ref_cm_node(loopback);
1017
loopback->state = NES_CM_STATE_CLOSED;
1018
cm_event_connect_error(&event);
1019
cm_node->state = NES_CM_STATE_LISTENER_DESTROYED;
1020
1021
rem_ref_cm_node(cm_node->cm_core,
1022
cm_node);
1023
1024
}
1025
}
1026
}
1027
}
1028
1029
spin_lock_irqsave(&cm_core->listen_list_lock, flags);
1030
if (!atomic_dec_return(&listener->ref_count)) {
1031
list_del(&listener->list);
1032
1033
/* decrement our listen node count */
1034
atomic_dec(&cm_core->listen_node_cnt);
1035
1036
spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
1037
1038
if (listener->nesvnic) {
1039
nes_manage_apbvt(listener->nesvnic, listener->loc_port,
1040
PCI_FUNC(listener->nesvnic->nesdev->pcidev->devfn), NES_MANAGE_APBVT_DEL);
1041
}
1042
1043
nes_debug(NES_DBG_CM, "destroying listener (%p)\n", listener);
1044
1045
kfree(listener);
1046
listener = NULL;
1047
ret = 0;
1048
atomic_inc(&cm_listens_destroyed);
1049
} else {
1050
spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
1051
}
1052
if (listener) {
1053
if (atomic_read(&listener->pend_accepts_cnt) > 0)
1054
nes_debug(NES_DBG_CM, "destroying listener (%p)"
1055
" with non-zero pending accepts=%u\n",
1056
listener, atomic_read(&listener->pend_accepts_cnt));
1057
}
1058
1059
return ret;
1060
}
1061
1062
1063
/**
1064
* mini_cm_del_listen
1065
*/
1066
static int mini_cm_del_listen(struct nes_cm_core *cm_core,
1067
struct nes_cm_listener *listener)
1068
{
1069
listener->listener_state = NES_CM_LISTENER_PASSIVE_STATE;
1070
listener->cm_id = NULL; /* going to be destroyed pretty soon */
1071
return mini_cm_dec_refcnt_listen(cm_core, listener, 1);
1072
}
1073
1074
1075
/**
1076
* mini_cm_accelerated
1077
*/
1078
static inline int mini_cm_accelerated(struct nes_cm_core *cm_core,
1079
struct nes_cm_node *cm_node)
1080
{
1081
u32 was_timer_set;
1082
cm_node->accelerated = 1;
1083
1084
if (cm_node->accept_pend) {
1085
BUG_ON(!cm_node->listener);
1086
atomic_dec(&cm_node->listener->pend_accepts_cnt);
1087
cm_node->accept_pend = 0;
1088
BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0);
1089
}
1090
1091
was_timer_set = timer_pending(&cm_core->tcp_timer);
1092
if (!was_timer_set) {
1093
cm_core->tcp_timer.expires = jiffies + NES_SHORT_TIME;
1094
add_timer(&cm_core->tcp_timer);
1095
}
1096
1097
return 0;
1098
}
1099
1100
1101
/**
1102
* nes_addr_resolve_neigh
1103
*/
1104
static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpindex)
1105
{
1106
struct rtable *rt;
1107
struct neighbour *neigh;
1108
int rc = arpindex;
1109
struct net_device *netdev;
1110
struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter;
1111
1112
rt = ip_route_output(&init_net, htonl(dst_ip), 0, 0, 0);
1113
if (IS_ERR(rt)) {
1114
printk(KERN_ERR "%s: ip_route_output_key failed for 0x%08X\n",
1115
__func__, dst_ip);
1116
return rc;
1117
}
1118
1119
if (netif_is_bond_slave(nesvnic->netdev))
1120
netdev = nesvnic->netdev->master;
1121
else
1122
netdev = nesvnic->netdev;
1123
1124
neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, netdev);
1125
if (neigh) {
1126
if (neigh->nud_state & NUD_VALID) {
1127
nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X"
1128
" is %pM, Gateway is 0x%08X \n", dst_ip,
1129
neigh->ha, ntohl(rt->rt_gateway));
1130
1131
if (arpindex >= 0) {
1132
if (!memcmp(nesadapter->arp_table[arpindex].mac_addr,
1133
neigh->ha, ETH_ALEN)){
1134
/* Mac address same as in nes_arp_table */
1135
neigh_release(neigh);
1136
ip_rt_put(rt);
1137
return rc;
1138
}
1139
1140
nes_manage_arp_cache(nesvnic->netdev,
1141
nesadapter->arp_table[arpindex].mac_addr,
1142
dst_ip, NES_ARP_DELETE);
1143
}
1144
1145
nes_manage_arp_cache(nesvnic->netdev, neigh->ha,
1146
dst_ip, NES_ARP_ADD);
1147
rc = nes_arp_table(nesvnic->nesdev, dst_ip, NULL,
1148
NES_ARP_RESOLVE);
1149
}
1150
neigh_release(neigh);
1151
}
1152
1153
if ((neigh == NULL) || (!(neigh->nud_state & NUD_VALID)))
1154
neigh_event_send(rt->dst.neighbour, NULL);
1155
1156
ip_rt_put(rt);
1157
return rc;
1158
}
1159
1160
/**
1161
* make_cm_node - create a new instance of a cm node
1162
*/
1163
static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
1164
struct nes_vnic *nesvnic, struct nes_cm_info *cm_info,
1165
struct nes_cm_listener *listener)
1166
{
1167
struct nes_cm_node *cm_node;
1168
struct timespec ts;
1169
int oldarpindex = 0;
1170
int arpindex = 0;
1171
struct nes_device *nesdev;
1172
struct nes_adapter *nesadapter;
1173
1174
/* create an hte and cm_node for this instance */
1175
cm_node = kzalloc(sizeof(*cm_node), GFP_ATOMIC);
1176
if (!cm_node)
1177
return NULL;
1178
1179
/* set our node specific transport info */
1180
cm_node->loc_addr = cm_info->loc_addr;
1181
cm_node->rem_addr = cm_info->rem_addr;
1182
cm_node->loc_port = cm_info->loc_port;
1183
cm_node->rem_port = cm_info->rem_port;
1184
cm_node->send_write0 = send_first;
1185
nes_debug(NES_DBG_CM, "Make node addresses : loc = %pI4:%x, rem = %pI4:%x\n",
1186
&cm_node->loc_addr, cm_node->loc_port,
1187
&cm_node->rem_addr, cm_node->rem_port);
1188
cm_node->listener = listener;
1189
cm_node->netdev = nesvnic->netdev;
1190
cm_node->cm_id = cm_info->cm_id;
1191
memcpy(cm_node->loc_mac, nesvnic->netdev->dev_addr, ETH_ALEN);
1192
1193
nes_debug(NES_DBG_CM, "listener=%p, cm_id=%p\n", cm_node->listener,
1194
cm_node->cm_id);
1195
1196
spin_lock_init(&cm_node->retrans_list_lock);
1197
1198
cm_node->loopbackpartner = NULL;
1199
atomic_set(&cm_node->ref_count, 1);
1200
/* associate our parent CM core */
1201
cm_node->cm_core = cm_core;
1202
cm_node->tcp_cntxt.loc_id = NES_CM_DEF_LOCAL_ID;
1203
cm_node->tcp_cntxt.rcv_wscale = NES_CM_DEFAULT_RCV_WND_SCALE;
1204
cm_node->tcp_cntxt.rcv_wnd = NES_CM_DEFAULT_RCV_WND_SCALED >>
1205
NES_CM_DEFAULT_RCV_WND_SCALE;
1206
ts = current_kernel_time();
1207
cm_node->tcp_cntxt.loc_seq_num = htonl(ts.tv_nsec);
1208
cm_node->tcp_cntxt.mss = nesvnic->max_frame_size - sizeof(struct iphdr) -
1209
sizeof(struct tcphdr) - ETH_HLEN - VLAN_HLEN;
1210
cm_node->tcp_cntxt.rcv_nxt = 0;
1211
/* get a unique session ID , add thread_id to an upcounter to handle race */
1212
atomic_inc(&cm_core->node_cnt);
1213
cm_node->conn_type = cm_info->conn_type;
1214
cm_node->apbvt_set = 0;
1215
cm_node->accept_pend = 0;
1216
1217
cm_node->nesvnic = nesvnic;
1218
/* get some device handles, for arp lookup */
1219
nesdev = nesvnic->nesdev;
1220
nesadapter = nesdev->nesadapter;
1221
1222
cm_node->loopbackpartner = NULL;
1223
1224
/* get the mac addr for the remote node */
1225
if (ipv4_is_loopback(htonl(cm_node->rem_addr)))
1226
arpindex = nes_arp_table(nesdev, ntohl(nesvnic->local_ipaddr), NULL, NES_ARP_RESOLVE);
1227
else {
1228
oldarpindex = nes_arp_table(nesdev, cm_node->rem_addr, NULL, NES_ARP_RESOLVE);
1229
arpindex = nes_addr_resolve_neigh(nesvnic, cm_info->rem_addr, oldarpindex);
1230
1231
}
1232
if (arpindex < 0) {
1233
kfree(cm_node);
1234
return NULL;
1235
}
1236
1237
/* copy the mac addr to node context */
1238
memcpy(cm_node->rem_mac, nesadapter->arp_table[arpindex].mac_addr, ETH_ALEN);
1239
nes_debug(NES_DBG_CM, "Remote mac addr from arp table: %pM\n",
1240
cm_node->rem_mac);
1241
1242
add_hte_node(cm_core, cm_node);
1243
atomic_inc(&cm_nodes_created);
1244
1245
return cm_node;
1246
}
1247
1248
1249
/**
1250
* add_ref_cm_node - destroy an instance of a cm node
1251
*/
1252
static int add_ref_cm_node(struct nes_cm_node *cm_node)
1253
{
1254
atomic_inc(&cm_node->ref_count);
1255
return 0;
1256
}
1257
1258
1259
/**
1260
* rem_ref_cm_node - destroy an instance of a cm node
1261
*/
1262
static int rem_ref_cm_node(struct nes_cm_core *cm_core,
1263
struct nes_cm_node *cm_node)
1264
{
1265
unsigned long flags;
1266
struct nes_qp *nesqp;
1267
1268
if (!cm_node)
1269
return -EINVAL;
1270
1271
spin_lock_irqsave(&cm_node->cm_core->ht_lock, flags);
1272
if (atomic_dec_return(&cm_node->ref_count)) {
1273
spin_unlock_irqrestore(&cm_node->cm_core->ht_lock, flags);
1274
return 0;
1275
}
1276
list_del(&cm_node->list);
1277
atomic_dec(&cm_core->ht_node_cnt);
1278
spin_unlock_irqrestore(&cm_node->cm_core->ht_lock, flags);
1279
1280
/* if the node is destroyed before connection was accelerated */
1281
if (!cm_node->accelerated && cm_node->accept_pend) {
1282
BUG_ON(!cm_node->listener);
1283
atomic_dec(&cm_node->listener->pend_accepts_cnt);
1284
BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0);
1285
}
1286
WARN_ON(cm_node->send_entry);
1287
if (cm_node->recv_entry)
1288
handle_recv_entry(cm_node, 0);
1289
if (cm_node->listener) {
1290
mini_cm_dec_refcnt_listen(cm_core, cm_node->listener, 0);
1291
} else {
1292
if (cm_node->apbvt_set && cm_node->nesvnic) {
1293
nes_manage_apbvt(cm_node->nesvnic, cm_node->loc_port,
1294
PCI_FUNC(
1295
cm_node->nesvnic->nesdev->pcidev->devfn),
1296
NES_MANAGE_APBVT_DEL);
1297
}
1298
}
1299
1300
atomic_dec(&cm_core->node_cnt);
1301
atomic_inc(&cm_nodes_destroyed);
1302
nesqp = cm_node->nesqp;
1303
if (nesqp) {
1304
nesqp->cm_node = NULL;
1305
nes_rem_ref(&nesqp->ibqp);
1306
cm_node->nesqp = NULL;
1307
}
1308
1309
kfree(cm_node);
1310
return 0;
1311
}
1312
1313
/**
1314
* process_options
1315
*/
1316
static int process_options(struct nes_cm_node *cm_node, u8 *optionsloc,
1317
u32 optionsize, u32 syn_packet)
1318
{
1319
u32 tmp;
1320
u32 offset = 0;
1321
union all_known_options *all_options;
1322
char got_mss_option = 0;
1323
1324
while (offset < optionsize) {
1325
all_options = (union all_known_options *)(optionsloc + offset);
1326
switch (all_options->as_base.optionnum) {
1327
case OPTION_NUMBER_END:
1328
offset = optionsize;
1329
break;
1330
case OPTION_NUMBER_NONE:
1331
offset += 1;
1332
continue;
1333
case OPTION_NUMBER_MSS:
1334
nes_debug(NES_DBG_CM, "%s: MSS Length: %d Offset: %d "
1335
"Size: %d\n", __func__,
1336
all_options->as_mss.length, offset, optionsize);
1337
got_mss_option = 1;
1338
if (all_options->as_mss.length != 4) {
1339
return 1;
1340
} else {
1341
tmp = ntohs(all_options->as_mss.mss);
1342
if (tmp > 0 && tmp <
1343
cm_node->tcp_cntxt.mss)
1344
cm_node->tcp_cntxt.mss = tmp;
1345
}
1346
break;
1347
case OPTION_NUMBER_WINDOW_SCALE:
1348
cm_node->tcp_cntxt.snd_wscale =
1349
all_options->as_windowscale.shiftcount;
1350
break;
1351
case OPTION_NUMBER_WRITE0:
1352
cm_node->send_write0 = 1;
1353
break;
1354
default:
1355
nes_debug(NES_DBG_CM, "TCP Option not understood: %x\n",
1356
all_options->as_base.optionnum);
1357
break;
1358
}
1359
offset += all_options->as_base.length;
1360
}
1361
if ((!got_mss_option) && (syn_packet))
1362
cm_node->tcp_cntxt.mss = NES_CM_DEFAULT_MSS;
1363
return 0;
1364
}
1365
1366
static void drop_packet(struct sk_buff *skb)
1367
{
1368
atomic_inc(&cm_accel_dropped_pkts);
1369
dev_kfree_skb_any(skb);
1370
}
1371
1372
static void handle_fin_pkt(struct nes_cm_node *cm_node)
1373
{
1374
nes_debug(NES_DBG_CM, "Received FIN, cm_node = %p, state = %u. "
1375
"refcnt=%d\n", cm_node, cm_node->state,
1376
atomic_read(&cm_node->ref_count));
1377
switch (cm_node->state) {
1378
case NES_CM_STATE_SYN_RCVD:
1379
case NES_CM_STATE_SYN_SENT:
1380
case NES_CM_STATE_ESTABLISHED:
1381
case NES_CM_STATE_MPAREJ_RCVD:
1382
cm_node->tcp_cntxt.rcv_nxt++;
1383
cleanup_retrans_entry(cm_node);
1384
cm_node->state = NES_CM_STATE_LAST_ACK;
1385
send_fin(cm_node, NULL);
1386
break;
1387
case NES_CM_STATE_MPAREQ_SENT:
1388
create_event(cm_node, NES_CM_EVENT_ABORTED);
1389
cm_node->tcp_cntxt.rcv_nxt++;
1390
cleanup_retrans_entry(cm_node);
1391
cm_node->state = NES_CM_STATE_CLOSED;
1392
add_ref_cm_node(cm_node);
1393
send_reset(cm_node, NULL);
1394
break;
1395
case NES_CM_STATE_FIN_WAIT1:
1396
cm_node->tcp_cntxt.rcv_nxt++;
1397
cleanup_retrans_entry(cm_node);
1398
cm_node->state = NES_CM_STATE_CLOSING;
1399
send_ack(cm_node, NULL);
1400
/* Wait for ACK as this is simultaneous close..
1401
* After we receive ACK, do not send anything..
1402
* Just rm the node.. Done.. */
1403
break;
1404
case NES_CM_STATE_FIN_WAIT2:
1405
cm_node->tcp_cntxt.rcv_nxt++;
1406
cleanup_retrans_entry(cm_node);
1407
cm_node->state = NES_CM_STATE_TIME_WAIT;
1408
send_ack(cm_node, NULL);
1409
schedule_nes_timer(cm_node, NULL, NES_TIMER_TYPE_CLOSE, 1, 0);
1410
break;
1411
case NES_CM_STATE_TIME_WAIT:
1412
cm_node->tcp_cntxt.rcv_nxt++;
1413
cleanup_retrans_entry(cm_node);
1414
cm_node->state = NES_CM_STATE_CLOSED;
1415
rem_ref_cm_node(cm_node->cm_core, cm_node);
1416
break;
1417
case NES_CM_STATE_TSA:
1418
default:
1419
nes_debug(NES_DBG_CM, "Error Rcvd FIN for node-%p state = %d\n",
1420
cm_node, cm_node->state);
1421
break;
1422
}
1423
}
1424
1425
1426
static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1427
struct tcphdr *tcph)
1428
{
1429
1430
int reset = 0; /* whether to send reset in case of err.. */
1431
atomic_inc(&cm_resets_recvd);
1432
nes_debug(NES_DBG_CM, "Received Reset, cm_node = %p, state = %u."
1433
" refcnt=%d\n", cm_node, cm_node->state,
1434
atomic_read(&cm_node->ref_count));
1435
cleanup_retrans_entry(cm_node);
1436
switch (cm_node->state) {
1437
case NES_CM_STATE_SYN_SENT:
1438
case NES_CM_STATE_MPAREQ_SENT:
1439
nes_debug(NES_DBG_CM, "%s[%u] create abort for cm_node=%p "
1440
"listener=%p state=%d\n", __func__, __LINE__, cm_node,
1441
cm_node->listener, cm_node->state);
1442
active_open_err(cm_node, skb, reset);
1443
break;
1444
case NES_CM_STATE_MPAREQ_RCVD:
1445
atomic_inc(&cm_node->passive_state);
1446
dev_kfree_skb_any(skb);
1447
break;
1448
case NES_CM_STATE_ESTABLISHED:
1449
case NES_CM_STATE_SYN_RCVD:
1450
case NES_CM_STATE_LISTENING:
1451
nes_debug(NES_DBG_CM, "Bad state %s[%u]\n", __func__, __LINE__);
1452
passive_open_err(cm_node, skb, reset);
1453
break;
1454
case NES_CM_STATE_TSA:
1455
active_open_err(cm_node, skb, reset);
1456
break;
1457
case NES_CM_STATE_CLOSED:
1458
drop_packet(skb);
1459
break;
1460
case NES_CM_STATE_FIN_WAIT2:
1461
case NES_CM_STATE_FIN_WAIT1:
1462
case NES_CM_STATE_LAST_ACK:
1463
cm_node->cm_id->rem_ref(cm_node->cm_id);
1464
case NES_CM_STATE_TIME_WAIT:
1465
cm_node->state = NES_CM_STATE_CLOSED;
1466
rem_ref_cm_node(cm_node->cm_core, cm_node);
1467
drop_packet(skb);
1468
break;
1469
default:
1470
drop_packet(skb);
1471
break;
1472
}
1473
}
1474
1475
1476
static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb)
1477
{
1478
1479
int ret = 0;
1480
int datasize = skb->len;
1481
u8 *dataloc = skb->data;
1482
1483
enum nes_cm_event_type type = NES_CM_EVENT_UNKNOWN;
1484
u32 res_type;
1485
ret = parse_mpa(cm_node, dataloc, &res_type, datasize);
1486
if (ret) {
1487
nes_debug(NES_DBG_CM, "didn't like MPA Request\n");
1488
if (cm_node->state == NES_CM_STATE_MPAREQ_SENT) {
1489
nes_debug(NES_DBG_CM, "%s[%u] create abort for "
1490
"cm_node=%p listener=%p state=%d\n", __func__,
1491
__LINE__, cm_node, cm_node->listener,
1492
cm_node->state);
1493
active_open_err(cm_node, skb, 1);
1494
} else {
1495
passive_open_err(cm_node, skb, 1);
1496
}
1497
return;
1498
}
1499
1500
switch (cm_node->state) {
1501
case NES_CM_STATE_ESTABLISHED:
1502
if (res_type == NES_MPA_REQUEST_REJECT) {
1503
/*BIG problem as we are receiving the MPA.. So should
1504
* not be REJECT.. This is Passive Open.. We can
1505
* only receive it Reject for Active Open...*/
1506
WARN_ON(1);
1507
}
1508
cm_node->state = NES_CM_STATE_MPAREQ_RCVD;
1509
type = NES_CM_EVENT_MPA_REQ;
1510
atomic_set(&cm_node->passive_state,
1511
NES_PASSIVE_STATE_INDICATED);
1512
break;
1513
case NES_CM_STATE_MPAREQ_SENT:
1514
cleanup_retrans_entry(cm_node);
1515
if (res_type == NES_MPA_REQUEST_REJECT) {
1516
type = NES_CM_EVENT_MPA_REJECT;
1517
cm_node->state = NES_CM_STATE_MPAREJ_RCVD;
1518
} else {
1519
type = NES_CM_EVENT_CONNECTED;
1520
cm_node->state = NES_CM_STATE_TSA;
1521
}
1522
1523
break;
1524
default:
1525
WARN_ON(1);
1526
break;
1527
}
1528
dev_kfree_skb_any(skb);
1529
create_event(cm_node, type);
1530
}
1531
1532
static void indicate_pkt_err(struct nes_cm_node *cm_node, struct sk_buff *skb)
1533
{
1534
switch (cm_node->state) {
1535
case NES_CM_STATE_SYN_SENT:
1536
case NES_CM_STATE_MPAREQ_SENT:
1537
nes_debug(NES_DBG_CM, "%s[%u] create abort for cm_node=%p "
1538
"listener=%p state=%d\n", __func__, __LINE__, cm_node,
1539
cm_node->listener, cm_node->state);
1540
active_open_err(cm_node, skb, 1);
1541
break;
1542
case NES_CM_STATE_ESTABLISHED:
1543
case NES_CM_STATE_SYN_RCVD:
1544
passive_open_err(cm_node, skb, 1);
1545
break;
1546
case NES_CM_STATE_TSA:
1547
default:
1548
drop_packet(skb);
1549
}
1550
}
1551
1552
static int check_syn(struct nes_cm_node *cm_node, struct tcphdr *tcph,
1553
struct sk_buff *skb)
1554
{
1555
int err;
1556
1557
err = ((ntohl(tcph->ack_seq) == cm_node->tcp_cntxt.loc_seq_num))? 0 : 1;
1558
if (err)
1559
active_open_err(cm_node, skb, 1);
1560
1561
return err;
1562
}
1563
1564
static int check_seq(struct nes_cm_node *cm_node, struct tcphdr *tcph,
1565
struct sk_buff *skb)
1566
{
1567
int err = 0;
1568
u32 seq;
1569
u32 ack_seq;
1570
u32 loc_seq_num = cm_node->tcp_cntxt.loc_seq_num;
1571
u32 rcv_nxt = cm_node->tcp_cntxt.rcv_nxt;
1572
u32 rcv_wnd;
1573
seq = ntohl(tcph->seq);
1574
ack_seq = ntohl(tcph->ack_seq);
1575
rcv_wnd = cm_node->tcp_cntxt.rcv_wnd;
1576
if (ack_seq != loc_seq_num)
1577
err = 1;
1578
else if (!between(seq, rcv_nxt, (rcv_nxt+rcv_wnd)))
1579
err = 1;
1580
if (err) {
1581
nes_debug(NES_DBG_CM, "%s[%u] create abort for cm_node=%p "
1582
"listener=%p state=%d\n", __func__, __LINE__, cm_node,
1583
cm_node->listener, cm_node->state);
1584
indicate_pkt_err(cm_node, skb);
1585
nes_debug(NES_DBG_CM, "seq ERROR cm_node =%p seq=0x%08X "
1586
"rcv_nxt=0x%08X rcv_wnd=0x%x\n", cm_node, seq, rcv_nxt,
1587
rcv_wnd);
1588
}
1589
return err;
1590
}
1591
1592
/*
1593
* handle_syn_pkt() is for Passive node. The syn packet is received when a node
1594
* is created with a listener or it may comein as rexmitted packet which in
1595
* that case will be just dropped.
1596
*/
1597
1598
static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1599
struct tcphdr *tcph)
1600
{
1601
int ret;
1602
u32 inc_sequence;
1603
int optionsize;
1604
1605
optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
1606
skb_trim(skb, 0);
1607
inc_sequence = ntohl(tcph->seq);
1608
1609
switch (cm_node->state) {
1610
case NES_CM_STATE_SYN_SENT:
1611
case NES_CM_STATE_MPAREQ_SENT:
1612
/* Rcvd syn on active open connection*/
1613
active_open_err(cm_node, skb, 1);
1614
break;
1615
case NES_CM_STATE_LISTENING:
1616
/* Passive OPEN */
1617
if (atomic_read(&cm_node->listener->pend_accepts_cnt) >
1618
cm_node->listener->backlog) {
1619
nes_debug(NES_DBG_CM, "drop syn due to backlog "
1620
"pressure \n");
1621
cm_backlog_drops++;
1622
passive_open_err(cm_node, skb, 0);
1623
break;
1624
}
1625
ret = handle_tcp_options(cm_node, tcph, skb, optionsize,
1626
1);
1627
if (ret) {
1628
passive_open_err(cm_node, skb, 0);
1629
/* drop pkt */
1630
break;
1631
}
1632
cm_node->tcp_cntxt.rcv_nxt = inc_sequence + 1;
1633
BUG_ON(cm_node->send_entry);
1634
cm_node->accept_pend = 1;
1635
atomic_inc(&cm_node->listener->pend_accepts_cnt);
1636
1637
cm_node->state = NES_CM_STATE_SYN_RCVD;
1638
send_syn(cm_node, 1, skb);
1639
break;
1640
case NES_CM_STATE_CLOSED:
1641
cleanup_retrans_entry(cm_node);
1642
add_ref_cm_node(cm_node);
1643
send_reset(cm_node, skb);
1644
break;
1645
case NES_CM_STATE_TSA:
1646
case NES_CM_STATE_ESTABLISHED:
1647
case NES_CM_STATE_FIN_WAIT1:
1648
case NES_CM_STATE_FIN_WAIT2:
1649
case NES_CM_STATE_MPAREQ_RCVD:
1650
case NES_CM_STATE_LAST_ACK:
1651
case NES_CM_STATE_CLOSING:
1652
case NES_CM_STATE_UNKNOWN:
1653
default:
1654
drop_packet(skb);
1655
break;
1656
}
1657
}
1658
1659
static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1660
struct tcphdr *tcph)
1661
{
1662
1663
int ret;
1664
u32 inc_sequence;
1665
int optionsize;
1666
1667
optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
1668
skb_trim(skb, 0);
1669
inc_sequence = ntohl(tcph->seq);
1670
switch (cm_node->state) {
1671
case NES_CM_STATE_SYN_SENT:
1672
cleanup_retrans_entry(cm_node);
1673
/* active open */
1674
if (check_syn(cm_node, tcph, skb))
1675
return;
1676
cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
1677
/* setup options */
1678
ret = handle_tcp_options(cm_node, tcph, skb, optionsize, 0);
1679
if (ret) {
1680
nes_debug(NES_DBG_CM, "cm_node=%p tcp_options failed\n",
1681
cm_node);
1682
break;
1683
}
1684
cleanup_retrans_entry(cm_node);
1685
cm_node->tcp_cntxt.rcv_nxt = inc_sequence + 1;
1686
send_mpa_request(cm_node, skb);
1687
cm_node->state = NES_CM_STATE_MPAREQ_SENT;
1688
break;
1689
case NES_CM_STATE_MPAREQ_RCVD:
1690
/* passive open, so should not be here */
1691
passive_open_err(cm_node, skb, 1);
1692
break;
1693
case NES_CM_STATE_LISTENING:
1694
cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
1695
cleanup_retrans_entry(cm_node);
1696
cm_node->state = NES_CM_STATE_CLOSED;
1697
send_reset(cm_node, skb);
1698
break;
1699
case NES_CM_STATE_CLOSED:
1700
cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
1701
cleanup_retrans_entry(cm_node);
1702
add_ref_cm_node(cm_node);
1703
send_reset(cm_node, skb);
1704
break;
1705
case NES_CM_STATE_ESTABLISHED:
1706
case NES_CM_STATE_FIN_WAIT1:
1707
case NES_CM_STATE_FIN_WAIT2:
1708
case NES_CM_STATE_LAST_ACK:
1709
case NES_CM_STATE_TSA:
1710
case NES_CM_STATE_CLOSING:
1711
case NES_CM_STATE_UNKNOWN:
1712
case NES_CM_STATE_MPAREQ_SENT:
1713
default:
1714
drop_packet(skb);
1715
break;
1716
}
1717
}
1718
1719
static int handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1720
struct tcphdr *tcph)
1721
{
1722
int datasize = 0;
1723
u32 inc_sequence;
1724
int ret = 0;
1725
int optionsize;
1726
optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
1727
1728
if (check_seq(cm_node, tcph, skb))
1729
return -EINVAL;
1730
1731
skb_pull(skb, tcph->doff << 2);
1732
inc_sequence = ntohl(tcph->seq);
1733
datasize = skb->len;
1734
switch (cm_node->state) {
1735
case NES_CM_STATE_SYN_RCVD:
1736
/* Passive OPEN */
1737
cleanup_retrans_entry(cm_node);
1738
ret = handle_tcp_options(cm_node, tcph, skb, optionsize, 1);
1739
if (ret)
1740
break;
1741
cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
1742
cm_node->state = NES_CM_STATE_ESTABLISHED;
1743
if (datasize) {
1744
cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
1745
handle_rcv_mpa(cm_node, skb);
1746
} else /* rcvd ACK only */
1747
dev_kfree_skb_any(skb);
1748
break;
1749
case NES_CM_STATE_ESTABLISHED:
1750
/* Passive OPEN */
1751
cleanup_retrans_entry(cm_node);
1752
if (datasize) {
1753
cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
1754
handle_rcv_mpa(cm_node, skb);
1755
} else
1756
drop_packet(skb);
1757
break;
1758
case NES_CM_STATE_MPAREQ_SENT:
1759
cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
1760
if (datasize) {
1761
cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
1762
handle_rcv_mpa(cm_node, skb);
1763
} else /* Could be just an ack pkt.. */
1764
dev_kfree_skb_any(skb);
1765
break;
1766
case NES_CM_STATE_LISTENING:
1767
cleanup_retrans_entry(cm_node);
1768
cm_node->state = NES_CM_STATE_CLOSED;
1769
send_reset(cm_node, skb);
1770
break;
1771
case NES_CM_STATE_CLOSED:
1772
cleanup_retrans_entry(cm_node);
1773
add_ref_cm_node(cm_node);
1774
send_reset(cm_node, skb);
1775
break;
1776
case NES_CM_STATE_LAST_ACK:
1777
case NES_CM_STATE_CLOSING:
1778
cleanup_retrans_entry(cm_node);
1779
cm_node->state = NES_CM_STATE_CLOSED;
1780
cm_node->cm_id->rem_ref(cm_node->cm_id);
1781
rem_ref_cm_node(cm_node->cm_core, cm_node);
1782
drop_packet(skb);
1783
break;
1784
case NES_CM_STATE_FIN_WAIT1:
1785
cleanup_retrans_entry(cm_node);
1786
drop_packet(skb);
1787
cm_node->state = NES_CM_STATE_FIN_WAIT2;
1788
break;
1789
case NES_CM_STATE_SYN_SENT:
1790
case NES_CM_STATE_FIN_WAIT2:
1791
case NES_CM_STATE_TSA:
1792
case NES_CM_STATE_MPAREQ_RCVD:
1793
case NES_CM_STATE_UNKNOWN:
1794
default:
1795
cleanup_retrans_entry(cm_node);
1796
drop_packet(skb);
1797
break;
1798
}
1799
return ret;
1800
}
1801
1802
1803
1804
static int handle_tcp_options(struct nes_cm_node *cm_node, struct tcphdr *tcph,
1805
struct sk_buff *skb, int optionsize, int passive)
1806
{
1807
u8 *optionsloc = (u8 *)&tcph[1];
1808
if (optionsize) {
1809
if (process_options(cm_node, optionsloc, optionsize,
1810
(u32)tcph->syn)) {
1811
nes_debug(NES_DBG_CM, "%s: Node %p, Sending RESET\n",
1812
__func__, cm_node);
1813
if (passive)
1814
passive_open_err(cm_node, skb, 1);
1815
else
1816
active_open_err(cm_node, skb, 1);
1817
return 1;
1818
}
1819
}
1820
1821
cm_node->tcp_cntxt.snd_wnd = ntohs(tcph->window) <<
1822
cm_node->tcp_cntxt.snd_wscale;
1823
1824
if (cm_node->tcp_cntxt.snd_wnd > cm_node->tcp_cntxt.max_snd_wnd)
1825
cm_node->tcp_cntxt.max_snd_wnd = cm_node->tcp_cntxt.snd_wnd;
1826
return 0;
1827
}
1828
1829
/*
1830
* active_open_err() will send reset() if flag set..
1831
* It will also send ABORT event.
1832
*/
1833
1834
static void active_open_err(struct nes_cm_node *cm_node, struct sk_buff *skb,
1835
int reset)
1836
{
1837
cleanup_retrans_entry(cm_node);
1838
if (reset) {
1839
nes_debug(NES_DBG_CM, "ERROR active err called for cm_node=%p, "
1840
"state=%d\n", cm_node, cm_node->state);
1841
add_ref_cm_node(cm_node);
1842
send_reset(cm_node, skb);
1843
} else
1844
dev_kfree_skb_any(skb);
1845
1846
cm_node->state = NES_CM_STATE_CLOSED;
1847
create_event(cm_node, NES_CM_EVENT_ABORTED);
1848
}
1849
1850
/*
1851
* passive_open_err() will either do a reset() or will free up the skb and
1852
* remove the cm_node.
1853
*/
1854
1855
static void passive_open_err(struct nes_cm_node *cm_node, struct sk_buff *skb,
1856
int reset)
1857
{
1858
cleanup_retrans_entry(cm_node);
1859
cm_node->state = NES_CM_STATE_CLOSED;
1860
if (reset) {
1861
nes_debug(NES_DBG_CM, "passive_open_err sending RST for "
1862
"cm_node=%p state =%d\n", cm_node, cm_node->state);
1863
send_reset(cm_node, skb);
1864
} else {
1865
dev_kfree_skb_any(skb);
1866
rem_ref_cm_node(cm_node->cm_core, cm_node);
1867
}
1868
}
1869
1870
/*
1871
* free_retrans_entry() routines assumes that the retrans_list_lock has
1872
* been acquired before calling.
1873
*/
1874
static void free_retrans_entry(struct nes_cm_node *cm_node)
1875
{
1876
struct nes_timer_entry *send_entry;
1877
send_entry = cm_node->send_entry;
1878
if (send_entry) {
1879
cm_node->send_entry = NULL;
1880
dev_kfree_skb_any(send_entry->skb);
1881
kfree(send_entry);
1882
rem_ref_cm_node(cm_node->cm_core, cm_node);
1883
}
1884
}
1885
1886
static void cleanup_retrans_entry(struct nes_cm_node *cm_node)
1887
{
1888
unsigned long flags;
1889
1890
spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
1891
free_retrans_entry(cm_node);
1892
spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
1893
}
1894
1895
/**
1896
* process_packet
1897
* Returns skb if to be freed, else it will return NULL if already used..
1898
*/
1899
static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
1900
struct nes_cm_core *cm_core)
1901
{
1902
enum nes_tcpip_pkt_type pkt_type = NES_PKT_TYPE_UNKNOWN;
1903
struct tcphdr *tcph = tcp_hdr(skb);
1904
u32 fin_set = 0;
1905
int ret = 0;
1906
skb_pull(skb, ip_hdr(skb)->ihl << 2);
1907
1908
nes_debug(NES_DBG_CM, "process_packet: cm_node=%p state =%d syn=%d "
1909
"ack=%d rst=%d fin=%d\n", cm_node, cm_node->state, tcph->syn,
1910
tcph->ack, tcph->rst, tcph->fin);
1911
1912
if (tcph->rst)
1913
pkt_type = NES_PKT_TYPE_RST;
1914
else if (tcph->syn) {
1915
pkt_type = NES_PKT_TYPE_SYN;
1916
if (tcph->ack)
1917
pkt_type = NES_PKT_TYPE_SYNACK;
1918
} else if (tcph->ack)
1919
pkt_type = NES_PKT_TYPE_ACK;
1920
if (tcph->fin)
1921
fin_set = 1;
1922
1923
switch (pkt_type) {
1924
case NES_PKT_TYPE_SYN:
1925
handle_syn_pkt(cm_node, skb, tcph);
1926
break;
1927
case NES_PKT_TYPE_SYNACK:
1928
handle_synack_pkt(cm_node, skb, tcph);
1929
break;
1930
case NES_PKT_TYPE_ACK:
1931
ret = handle_ack_pkt(cm_node, skb, tcph);
1932
if (fin_set && !ret)
1933
handle_fin_pkt(cm_node);
1934
break;
1935
case NES_PKT_TYPE_RST:
1936
handle_rst_pkt(cm_node, skb, tcph);
1937
break;
1938
default:
1939
if ((fin_set) && (!check_seq(cm_node, tcph, skb)))
1940
handle_fin_pkt(cm_node);
1941
drop_packet(skb);
1942
break;
1943
}
1944
}
1945
1946
/**
1947
* mini_cm_listen - create a listen node with params
1948
*/
1949
static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *cm_core,
1950
struct nes_vnic *nesvnic, struct nes_cm_info *cm_info)
1951
{
1952
struct nes_cm_listener *listener;
1953
unsigned long flags;
1954
1955
nes_debug(NES_DBG_CM, "Search for 0x%08x : 0x%04x\n",
1956
cm_info->loc_addr, cm_info->loc_port);
1957
1958
/* cannot have multiple matching listeners */
1959
listener = find_listener(cm_core, htonl(cm_info->loc_addr),
1960
htons(cm_info->loc_port), NES_CM_LISTENER_EITHER_STATE);
1961
if (listener && listener->listener_state == NES_CM_LISTENER_ACTIVE_STATE) {
1962
/* find automatically incs ref count ??? */
1963
atomic_dec(&listener->ref_count);
1964
nes_debug(NES_DBG_CM, "Not creating listener since it already exists\n");
1965
return NULL;
1966
}
1967
1968
if (!listener) {
1969
/* create a CM listen node (1/2 node to compare incoming traffic to) */
1970
listener = kzalloc(sizeof(*listener), GFP_ATOMIC);
1971
if (!listener) {
1972
nes_debug(NES_DBG_CM, "Not creating listener memory allocation failed\n");
1973
return NULL;
1974
}
1975
1976
listener->loc_addr = htonl(cm_info->loc_addr);
1977
listener->loc_port = htons(cm_info->loc_port);
1978
listener->reused_node = 0;
1979
1980
atomic_set(&listener->ref_count, 1);
1981
}
1982
/* pasive case */
1983
/* find already inc'ed the ref count */
1984
else {
1985
listener->reused_node = 1;
1986
}
1987
1988
listener->cm_id = cm_info->cm_id;
1989
atomic_set(&listener->pend_accepts_cnt, 0);
1990
listener->cm_core = cm_core;
1991
listener->nesvnic = nesvnic;
1992
atomic_inc(&cm_core->node_cnt);
1993
1994
listener->conn_type = cm_info->conn_type;
1995
listener->backlog = cm_info->backlog;
1996
listener->listener_state = NES_CM_LISTENER_ACTIVE_STATE;
1997
1998
if (!listener->reused_node) {
1999
spin_lock_irqsave(&cm_core->listen_list_lock, flags);
2000
list_add(&listener->list, &cm_core->listen_list.list);
2001
spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
2002
atomic_inc(&cm_core->listen_node_cnt);
2003
}
2004
2005
nes_debug(NES_DBG_CM, "Api - listen(): addr=0x%08X, port=0x%04x,"
2006
" listener = %p, backlog = %d, cm_id = %p.\n",
2007
cm_info->loc_addr, cm_info->loc_port,
2008
listener, listener->backlog, listener->cm_id);
2009
2010
return listener;
2011
}
2012
2013
2014
/**
2015
* mini_cm_connect - make a connection node with params
2016
*/
2017
static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core,
2018
struct nes_vnic *nesvnic, u16 private_data_len,
2019
void *private_data, struct nes_cm_info *cm_info)
2020
{
2021
int ret = 0;
2022
struct nes_cm_node *cm_node;
2023
struct nes_cm_listener *loopbackremotelistener;
2024
struct nes_cm_node *loopbackremotenode;
2025
struct nes_cm_info loopback_cm_info;
2026
u16 mpa_frame_size = sizeof(struct ietf_mpa_frame) + private_data_len;
2027
struct ietf_mpa_frame *mpa_frame = NULL;
2028
2029
/* create a CM connection node */
2030
cm_node = make_cm_node(cm_core, nesvnic, cm_info, NULL);
2031
if (!cm_node)
2032
return NULL;
2033
mpa_frame = &cm_node->mpa_frame;
2034
memcpy(mpa_frame->key, IEFT_MPA_KEY_REQ, IETF_MPA_KEY_SIZE);
2035
mpa_frame->flags = IETF_MPA_FLAGS_CRC;
2036
mpa_frame->rev = IETF_MPA_VERSION;
2037
mpa_frame->priv_data_len = htons(private_data_len);
2038
2039
/* set our node side to client (active) side */
2040
cm_node->tcp_cntxt.client = 1;
2041
cm_node->tcp_cntxt.rcv_wscale = NES_CM_DEFAULT_RCV_WND_SCALE;
2042
2043
if (cm_info->loc_addr == cm_info->rem_addr) {
2044
loopbackremotelistener = find_listener(cm_core,
2045
ntohl(nesvnic->local_ipaddr), cm_node->rem_port,
2046
NES_CM_LISTENER_ACTIVE_STATE);
2047
if (loopbackremotelistener == NULL) {
2048
create_event(cm_node, NES_CM_EVENT_ABORTED);
2049
} else {
2050
loopback_cm_info = *cm_info;
2051
loopback_cm_info.loc_port = cm_info->rem_port;
2052
loopback_cm_info.rem_port = cm_info->loc_port;
2053
loopback_cm_info.cm_id = loopbackremotelistener->cm_id;
2054
loopbackremotenode = make_cm_node(cm_core, nesvnic,
2055
&loopback_cm_info, loopbackremotelistener);
2056
if (!loopbackremotenode) {
2057
rem_ref_cm_node(cm_node->cm_core, cm_node);
2058
return NULL;
2059
}
2060
atomic_inc(&cm_loopbacks);
2061
loopbackremotenode->loopbackpartner = cm_node;
2062
loopbackremotenode->tcp_cntxt.rcv_wscale =
2063
NES_CM_DEFAULT_RCV_WND_SCALE;
2064
cm_node->loopbackpartner = loopbackremotenode;
2065
memcpy(loopbackremotenode->mpa_frame_buf, private_data,
2066
private_data_len);
2067
loopbackremotenode->mpa_frame_size = private_data_len;
2068
2069
/* we are done handling this state. */
2070
/* set node to a TSA state */
2071
cm_node->state = NES_CM_STATE_TSA;
2072
cm_node->tcp_cntxt.rcv_nxt =
2073
loopbackremotenode->tcp_cntxt.loc_seq_num;
2074
loopbackremotenode->tcp_cntxt.rcv_nxt =
2075
cm_node->tcp_cntxt.loc_seq_num;
2076
cm_node->tcp_cntxt.max_snd_wnd =
2077
loopbackremotenode->tcp_cntxt.rcv_wnd;
2078
loopbackremotenode->tcp_cntxt.max_snd_wnd =
2079
cm_node->tcp_cntxt.rcv_wnd;
2080
cm_node->tcp_cntxt.snd_wnd =
2081
loopbackremotenode->tcp_cntxt.rcv_wnd;
2082
loopbackremotenode->tcp_cntxt.snd_wnd =
2083
cm_node->tcp_cntxt.rcv_wnd;
2084
cm_node->tcp_cntxt.snd_wscale =
2085
loopbackremotenode->tcp_cntxt.rcv_wscale;
2086
loopbackremotenode->tcp_cntxt.snd_wscale =
2087
cm_node->tcp_cntxt.rcv_wscale;
2088
loopbackremotenode->state = NES_CM_STATE_MPAREQ_RCVD;
2089
create_event(loopbackremotenode, NES_CM_EVENT_MPA_REQ);
2090
}
2091
return cm_node;
2092
}
2093
2094
/* set our node side to client (active) side */
2095
cm_node->tcp_cntxt.client = 1;
2096
/* init our MPA frame ptr */
2097
memcpy(mpa_frame->priv_data, private_data, private_data_len);
2098
2099
cm_node->mpa_frame_size = mpa_frame_size;
2100
2101
/* send a syn and goto syn sent state */
2102
cm_node->state = NES_CM_STATE_SYN_SENT;
2103
ret = send_syn(cm_node, 0, NULL);
2104
2105
if (ret) {
2106
/* error in sending the syn free up the cm_node struct */
2107
nes_debug(NES_DBG_CM, "Api - connect() FAILED: dest "
2108
"addr=0x%08X, port=0x%04x, cm_node=%p, cm_id = %p.\n",
2109
cm_node->rem_addr, cm_node->rem_port, cm_node,
2110
cm_node->cm_id);
2111
rem_ref_cm_node(cm_node->cm_core, cm_node);
2112
cm_node = NULL;
2113
}
2114
2115
if (cm_node)
2116
nes_debug(NES_DBG_CM, "Api - connect(): dest addr=0x%08X,"
2117
"port=0x%04x, cm_node=%p, cm_id = %p.\n",
2118
cm_node->rem_addr, cm_node->rem_port, cm_node,
2119
cm_node->cm_id);
2120
2121
return cm_node;
2122
}
2123
2124
2125
/**
2126
* mini_cm_accept - accept a connection
2127
* This function is never called
2128
*/
2129
static int mini_cm_accept(struct nes_cm_core *cm_core,
2130
struct ietf_mpa_frame *mpa_frame, struct nes_cm_node *cm_node)
2131
{
2132
return 0;
2133
}
2134
2135
2136
/**
2137
* mini_cm_reject - reject and teardown a connection
2138
*/
2139
static int mini_cm_reject(struct nes_cm_core *cm_core,
2140
struct ietf_mpa_frame *mpa_frame, struct nes_cm_node *cm_node)
2141
{
2142
int ret = 0;
2143
int err = 0;
2144
int passive_state;
2145
struct nes_cm_event event;
2146
struct iw_cm_id *cm_id = cm_node->cm_id;
2147
struct nes_cm_node *loopback = cm_node->loopbackpartner;
2148
2149
nes_debug(NES_DBG_CM, "%s cm_node=%p type=%d state=%d\n",
2150
__func__, cm_node, cm_node->tcp_cntxt.client, cm_node->state);
2151
2152
if (cm_node->tcp_cntxt.client)
2153
return ret;
2154
cleanup_retrans_entry(cm_node);
2155
2156
if (!loopback) {
2157
passive_state = atomic_add_return(1, &cm_node->passive_state);
2158
if (passive_state == NES_SEND_RESET_EVENT) {
2159
cm_node->state = NES_CM_STATE_CLOSED;
2160
rem_ref_cm_node(cm_core, cm_node);
2161
} else {
2162
if (cm_node->state == NES_CM_STATE_LISTENER_DESTROYED) {
2163
rem_ref_cm_node(cm_core, cm_node);
2164
} else {
2165
ret = send_mpa_reject(cm_node);
2166
if (ret) {
2167
cm_node->state = NES_CM_STATE_CLOSED;
2168
err = send_reset(cm_node, NULL);
2169
if (err)
2170
WARN_ON(1);
2171
} else
2172
cm_id->add_ref(cm_id);
2173
}
2174
}
2175
} else {
2176
cm_node->cm_id = NULL;
2177
if (cm_node->state == NES_CM_STATE_LISTENER_DESTROYED) {
2178
rem_ref_cm_node(cm_core, cm_node);
2179
rem_ref_cm_node(cm_core, loopback);
2180
} else {
2181
event.cm_node = loopback;
2182
event.cm_info.rem_addr = loopback->rem_addr;
2183
event.cm_info.loc_addr = loopback->loc_addr;
2184
event.cm_info.rem_port = loopback->rem_port;
2185
event.cm_info.loc_port = loopback->loc_port;
2186
event.cm_info.cm_id = loopback->cm_id;
2187
cm_event_mpa_reject(&event);
2188
rem_ref_cm_node(cm_core, cm_node);
2189
loopback->state = NES_CM_STATE_CLOSING;
2190
2191
cm_id = loopback->cm_id;
2192
rem_ref_cm_node(cm_core, loopback);
2193
cm_id->rem_ref(cm_id);
2194
}
2195
}
2196
2197
return ret;
2198
}
2199
2200
2201
/**
2202
* mini_cm_close
2203
*/
2204
static int mini_cm_close(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node)
2205
{
2206
int ret = 0;
2207
2208
if (!cm_core || !cm_node)
2209
return -EINVAL;
2210
2211
switch (cm_node->state) {
2212
case NES_CM_STATE_SYN_RCVD:
2213
case NES_CM_STATE_SYN_SENT:
2214
case NES_CM_STATE_ONE_SIDE_ESTABLISHED:
2215
case NES_CM_STATE_ESTABLISHED:
2216
case NES_CM_STATE_ACCEPTING:
2217
case NES_CM_STATE_MPAREQ_SENT:
2218
case NES_CM_STATE_MPAREQ_RCVD:
2219
cleanup_retrans_entry(cm_node);
2220
send_reset(cm_node, NULL);
2221
break;
2222
case NES_CM_STATE_CLOSE_WAIT:
2223
cm_node->state = NES_CM_STATE_LAST_ACK;
2224
send_fin(cm_node, NULL);
2225
break;
2226
case NES_CM_STATE_FIN_WAIT1:
2227
case NES_CM_STATE_FIN_WAIT2:
2228
case NES_CM_STATE_LAST_ACK:
2229
case NES_CM_STATE_TIME_WAIT:
2230
case NES_CM_STATE_CLOSING:
2231
ret = -1;
2232
break;
2233
case NES_CM_STATE_LISTENING:
2234
cleanup_retrans_entry(cm_node);
2235
send_reset(cm_node, NULL);
2236
break;
2237
case NES_CM_STATE_MPAREJ_RCVD:
2238
case NES_CM_STATE_UNKNOWN:
2239
case NES_CM_STATE_INITED:
2240
case NES_CM_STATE_CLOSED:
2241
case NES_CM_STATE_LISTENER_DESTROYED:
2242
ret = rem_ref_cm_node(cm_core, cm_node);
2243
break;
2244
case NES_CM_STATE_TSA:
2245
if (cm_node->send_entry)
2246
printk(KERN_ERR "ERROR Close got called from STATE_TSA "
2247
"send_entry=%p\n", cm_node->send_entry);
2248
ret = rem_ref_cm_node(cm_core, cm_node);
2249
break;
2250
}
2251
return ret;
2252
}
2253
2254
2255
/**
2256
* recv_pkt - recv an ETHERNET packet, and process it through CM
2257
* node state machine
2258
*/
2259
static int mini_cm_recv_pkt(struct nes_cm_core *cm_core,
2260
struct nes_vnic *nesvnic, struct sk_buff *skb)
2261
{
2262
struct nes_cm_node *cm_node = NULL;
2263
struct nes_cm_listener *listener = NULL;
2264
struct iphdr *iph;
2265
struct tcphdr *tcph;
2266
struct nes_cm_info nfo;
2267
int skb_handled = 1;
2268
__be32 tmp_daddr, tmp_saddr;
2269
2270
if (!skb)
2271
return 0;
2272
if (skb->len < sizeof(struct iphdr) + sizeof(struct tcphdr)) {
2273
return 0;
2274
}
2275
2276
iph = (struct iphdr *)skb->data;
2277
tcph = (struct tcphdr *)(skb->data + sizeof(struct iphdr));
2278
2279
nfo.loc_addr = ntohl(iph->daddr);
2280
nfo.loc_port = ntohs(tcph->dest);
2281
nfo.rem_addr = ntohl(iph->saddr);
2282
nfo.rem_port = ntohs(tcph->source);
2283
2284
tmp_daddr = cpu_to_be32(iph->daddr);
2285
tmp_saddr = cpu_to_be32(iph->saddr);
2286
2287
nes_debug(NES_DBG_CM, "Received packet: dest=%pI4:0x%04X src=%pI4:0x%04X\n",
2288
&tmp_daddr, tcph->dest, &tmp_saddr, tcph->source);
2289
2290
do {
2291
cm_node = find_node(cm_core,
2292
nfo.rem_port, nfo.rem_addr,
2293
nfo.loc_port, nfo.loc_addr);
2294
2295
if (!cm_node) {
2296
/* Only type of packet accepted are for */
2297
/* the PASSIVE open (syn only) */
2298
if ((!tcph->syn) || (tcph->ack)) {
2299
skb_handled = 0;
2300
break;
2301
}
2302
listener = find_listener(cm_core, nfo.loc_addr,
2303
nfo.loc_port,
2304
NES_CM_LISTENER_ACTIVE_STATE);
2305
if (!listener) {
2306
nfo.cm_id = NULL;
2307
nfo.conn_type = 0;
2308
nes_debug(NES_DBG_CM, "Unable to find listener for the pkt\n");
2309
skb_handled = 0;
2310
break;
2311
}
2312
nfo.cm_id = listener->cm_id;
2313
nfo.conn_type = listener->conn_type;
2314
cm_node = make_cm_node(cm_core, nesvnic, &nfo,
2315
listener);
2316
if (!cm_node) {
2317
nes_debug(NES_DBG_CM, "Unable to allocate "
2318
"node\n");
2319
cm_packets_dropped++;
2320
atomic_dec(&listener->ref_count);
2321
dev_kfree_skb_any(skb);
2322
break;
2323
}
2324
if (!tcph->rst && !tcph->fin) {
2325
cm_node->state = NES_CM_STATE_LISTENING;
2326
} else {
2327
cm_packets_dropped++;
2328
rem_ref_cm_node(cm_core, cm_node);
2329
dev_kfree_skb_any(skb);
2330
break;
2331
}
2332
add_ref_cm_node(cm_node);
2333
} else if (cm_node->state == NES_CM_STATE_TSA) {
2334
rem_ref_cm_node(cm_core, cm_node);
2335
atomic_inc(&cm_accel_dropped_pkts);
2336
dev_kfree_skb_any(skb);
2337
break;
2338
}
2339
skb_reset_network_header(skb);
2340
skb_set_transport_header(skb, sizeof(*tcph));
2341
skb->len = ntohs(iph->tot_len);
2342
process_packet(cm_node, skb, cm_core);
2343
rem_ref_cm_node(cm_core, cm_node);
2344
} while (0);
2345
return skb_handled;
2346
}
2347
2348
2349
/**
2350
* nes_cm_alloc_core - allocate a top level instance of a cm core
2351
*/
2352
static struct nes_cm_core *nes_cm_alloc_core(void)
2353
{
2354
struct nes_cm_core *cm_core;
2355
2356
/* setup the CM core */
2357
/* alloc top level core control structure */
2358
cm_core = kzalloc(sizeof(*cm_core), GFP_KERNEL);
2359
if (!cm_core)
2360
return NULL;
2361
2362
INIT_LIST_HEAD(&cm_core->connected_nodes);
2363
init_timer(&cm_core->tcp_timer);
2364
cm_core->tcp_timer.function = nes_cm_timer_tick;
2365
2366
cm_core->mtu = NES_CM_DEFAULT_MTU;
2367
cm_core->state = NES_CM_STATE_INITED;
2368
cm_core->free_tx_pkt_max = NES_CM_DEFAULT_FREE_PKTS;
2369
2370
atomic_set(&cm_core->events_posted, 0);
2371
2372
cm_core->api = &nes_cm_api;
2373
2374
spin_lock_init(&cm_core->ht_lock);
2375
spin_lock_init(&cm_core->listen_list_lock);
2376
2377
INIT_LIST_HEAD(&cm_core->listen_list.list);
2378
2379
nes_debug(NES_DBG_CM, "Init CM Core completed -- cm_core=%p\n", cm_core);
2380
2381
nes_debug(NES_DBG_CM, "Enable QUEUE EVENTS\n");
2382
cm_core->event_wq = create_singlethread_workqueue("nesewq");
2383
cm_core->post_event = nes_cm_post_event;
2384
nes_debug(NES_DBG_CM, "Enable QUEUE DISCONNECTS\n");
2385
cm_core->disconn_wq = create_singlethread_workqueue("nesdwq");
2386
2387
print_core(cm_core);
2388
return cm_core;
2389
}
2390
2391
2392
/**
2393
* mini_cm_dealloc_core - deallocate a top level instance of a cm core
2394
*/
2395
static int mini_cm_dealloc_core(struct nes_cm_core *cm_core)
2396
{
2397
nes_debug(NES_DBG_CM, "De-Alloc CM Core (%p)\n", cm_core);
2398
2399
if (!cm_core)
2400
return -EINVAL;
2401
2402
barrier();
2403
2404
if (timer_pending(&cm_core->tcp_timer)) {
2405
del_timer(&cm_core->tcp_timer);
2406
}
2407
2408
destroy_workqueue(cm_core->event_wq);
2409
destroy_workqueue(cm_core->disconn_wq);
2410
nes_debug(NES_DBG_CM, "\n");
2411
kfree(cm_core);
2412
2413
return 0;
2414
}
2415
2416
2417
/**
2418
* mini_cm_get
2419
*/
2420
static int mini_cm_get(struct nes_cm_core *cm_core)
2421
{
2422
return cm_core->state;
2423
}
2424
2425
2426
/**
2427
* mini_cm_set
2428
*/
2429
static int mini_cm_set(struct nes_cm_core *cm_core, u32 type, u32 value)
2430
{
2431
int ret = 0;
2432
2433
switch (type) {
2434
case NES_CM_SET_PKT_SIZE:
2435
cm_core->mtu = value;
2436
break;
2437
case NES_CM_SET_FREE_PKT_Q_SIZE:
2438
cm_core->free_tx_pkt_max = value;
2439
break;
2440
default:
2441
/* unknown set option */
2442
ret = -EINVAL;
2443
}
2444
2445
return ret;
2446
}
2447
2448
2449
/**
2450
* nes_cm_init_tsa_conn setup HW; MPA frames must be
2451
* successfully exchanged when this is called
2452
*/
2453
static int nes_cm_init_tsa_conn(struct nes_qp *nesqp, struct nes_cm_node *cm_node)
2454
{
2455
int ret = 0;
2456
2457
if (!nesqp)
2458
return -EINVAL;
2459
2460
nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_IPV4 |
2461
NES_QPCONTEXT_MISC_NO_NAGLE | NES_QPCONTEXT_MISC_DO_NOT_FRAG |
2462
NES_QPCONTEXT_MISC_DROS);
2463
2464
if (cm_node->tcp_cntxt.snd_wscale || cm_node->tcp_cntxt.rcv_wscale)
2465
nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_WSCALE);
2466
2467
nesqp->nesqp_context->misc2 |= cpu_to_le32(64 << NES_QPCONTEXT_MISC2_TTL_SHIFT);
2468
2469
nesqp->nesqp_context->mss |= cpu_to_le32(((u32)cm_node->tcp_cntxt.mss) << 16);
2470
2471
nesqp->nesqp_context->tcp_state_flow_label |= cpu_to_le32(
2472
(u32)NES_QPCONTEXT_TCPSTATE_EST << NES_QPCONTEXT_TCPFLOW_TCP_STATE_SHIFT);
2473
2474
nesqp->nesqp_context->pd_index_wscale |= cpu_to_le32(
2475
(cm_node->tcp_cntxt.snd_wscale << NES_QPCONTEXT_PDWSCALE_SND_WSCALE_SHIFT) &
2476
NES_QPCONTEXT_PDWSCALE_SND_WSCALE_MASK);
2477
2478
nesqp->nesqp_context->pd_index_wscale |= cpu_to_le32(
2479
(cm_node->tcp_cntxt.rcv_wscale << NES_QPCONTEXT_PDWSCALE_RCV_WSCALE_SHIFT) &
2480
NES_QPCONTEXT_PDWSCALE_RCV_WSCALE_MASK);
2481
2482
nesqp->nesqp_context->keepalive = cpu_to_le32(0x80);
2483
nesqp->nesqp_context->ts_recent = 0;
2484
nesqp->nesqp_context->ts_age = 0;
2485
nesqp->nesqp_context->snd_nxt = cpu_to_le32(cm_node->tcp_cntxt.loc_seq_num);
2486
nesqp->nesqp_context->snd_wnd = cpu_to_le32(cm_node->tcp_cntxt.snd_wnd);
2487
nesqp->nesqp_context->rcv_nxt = cpu_to_le32(cm_node->tcp_cntxt.rcv_nxt);
2488
nesqp->nesqp_context->rcv_wnd = cpu_to_le32(cm_node->tcp_cntxt.rcv_wnd <<
2489
cm_node->tcp_cntxt.rcv_wscale);
2490
nesqp->nesqp_context->snd_max = cpu_to_le32(cm_node->tcp_cntxt.loc_seq_num);
2491
nesqp->nesqp_context->snd_una = cpu_to_le32(cm_node->tcp_cntxt.loc_seq_num);
2492
nesqp->nesqp_context->srtt = 0;
2493
nesqp->nesqp_context->rttvar = cpu_to_le32(0x6);
2494
nesqp->nesqp_context->ssthresh = cpu_to_le32(0x3FFFC000);
2495
nesqp->nesqp_context->cwnd = cpu_to_le32(2*cm_node->tcp_cntxt.mss);
2496
nesqp->nesqp_context->snd_wl1 = cpu_to_le32(cm_node->tcp_cntxt.rcv_nxt);
2497
nesqp->nesqp_context->snd_wl2 = cpu_to_le32(cm_node->tcp_cntxt.loc_seq_num);
2498
nesqp->nesqp_context->max_snd_wnd = cpu_to_le32(cm_node->tcp_cntxt.max_snd_wnd);
2499
2500
nes_debug(NES_DBG_CM, "QP%u: rcv_nxt = 0x%08X, snd_nxt = 0x%08X,"
2501
" Setting MSS to %u, PDWscale = 0x%08X, rcv_wnd = %u, context misc = 0x%08X.\n",
2502
nesqp->hwqp.qp_id, le32_to_cpu(nesqp->nesqp_context->rcv_nxt),
2503
le32_to_cpu(nesqp->nesqp_context->snd_nxt),
2504
cm_node->tcp_cntxt.mss, le32_to_cpu(nesqp->nesqp_context->pd_index_wscale),
2505
le32_to_cpu(nesqp->nesqp_context->rcv_wnd),
2506
le32_to_cpu(nesqp->nesqp_context->misc));
2507
nes_debug(NES_DBG_CM, " snd_wnd = 0x%08X.\n", le32_to_cpu(nesqp->nesqp_context->snd_wnd));
2508
nes_debug(NES_DBG_CM, " snd_cwnd = 0x%08X.\n", le32_to_cpu(nesqp->nesqp_context->cwnd));
2509
nes_debug(NES_DBG_CM, " max_swnd = 0x%08X.\n", le32_to_cpu(nesqp->nesqp_context->max_snd_wnd));
2510
2511
nes_debug(NES_DBG_CM, "Change cm_node state to TSA\n");
2512
cm_node->state = NES_CM_STATE_TSA;
2513
2514
return ret;
2515
}
2516
2517
2518
/**
2519
* nes_cm_disconn
2520
*/
2521
int nes_cm_disconn(struct nes_qp *nesqp)
2522
{
2523
struct disconn_work *work;
2524
2525
work = kzalloc(sizeof *work, GFP_ATOMIC);
2526
if (!work)
2527
return -ENOMEM; /* Timer will clean up */
2528
2529
nes_add_ref(&nesqp->ibqp);
2530
work->nesqp = nesqp;
2531
INIT_WORK(&work->work, nes_disconnect_worker);
2532
queue_work(g_cm_core->disconn_wq, &work->work);
2533
return 0;
2534
}
2535
2536
2537
/**
2538
* nes_disconnect_worker
2539
*/
2540
static void nes_disconnect_worker(struct work_struct *work)
2541
{
2542
struct disconn_work *dwork = container_of(work, struct disconn_work, work);
2543
struct nes_qp *nesqp = dwork->nesqp;
2544
2545
kfree(dwork);
2546
nes_debug(NES_DBG_CM, "processing AEQE id 0x%04X for QP%u.\n",
2547
nesqp->last_aeq, nesqp->hwqp.qp_id);
2548
nes_cm_disconn_true(nesqp);
2549
nes_rem_ref(&nesqp->ibqp);
2550
}
2551
2552
2553
/**
2554
* nes_cm_disconn_true
2555
*/
2556
static int nes_cm_disconn_true(struct nes_qp *nesqp)
2557
{
2558
unsigned long flags;
2559
int ret = 0;
2560
struct iw_cm_id *cm_id;
2561
struct iw_cm_event cm_event;
2562
struct nes_vnic *nesvnic;
2563
u16 last_ae;
2564
u8 original_hw_tcp_state;
2565
u8 original_ibqp_state;
2566
int disconn_status = 0;
2567
int issue_disconn = 0;
2568
int issue_close = 0;
2569
int issue_flush = 0;
2570
u32 flush_q = NES_CQP_FLUSH_RQ;
2571
struct ib_event ibevent;
2572
2573
if (!nesqp) {
2574
nes_debug(NES_DBG_CM, "disconnect_worker nesqp is NULL\n");
2575
return -1;
2576
}
2577
2578
spin_lock_irqsave(&nesqp->lock, flags);
2579
cm_id = nesqp->cm_id;
2580
/* make sure we havent already closed this connection */
2581
if (!cm_id) {
2582
nes_debug(NES_DBG_CM, "QP%u disconnect_worker cmid is NULL\n",
2583
nesqp->hwqp.qp_id);
2584
spin_unlock_irqrestore(&nesqp->lock, flags);
2585
return -1;
2586
}
2587
2588
nesvnic = to_nesvnic(nesqp->ibqp.device);
2589
nes_debug(NES_DBG_CM, "Disconnecting QP%u\n", nesqp->hwqp.qp_id);
2590
2591
original_hw_tcp_state = nesqp->hw_tcp_state;
2592
original_ibqp_state = nesqp->ibqp_state;
2593
last_ae = nesqp->last_aeq;
2594
2595
if (nesqp->term_flags) {
2596
issue_disconn = 1;
2597
issue_close = 1;
2598
nesqp->cm_id = NULL;
2599
if (nesqp->flush_issued == 0) {
2600
nesqp->flush_issued = 1;
2601
issue_flush = 1;
2602
}
2603
} else if ((original_hw_tcp_state == NES_AEQE_TCP_STATE_CLOSE_WAIT) ||
2604
((original_ibqp_state == IB_QPS_RTS) &&
2605
(last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET))) {
2606
issue_disconn = 1;
2607
if (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET)
2608
disconn_status = -ECONNRESET;
2609
}
2610
2611
if (((original_hw_tcp_state == NES_AEQE_TCP_STATE_CLOSED) ||
2612
(original_hw_tcp_state == NES_AEQE_TCP_STATE_TIME_WAIT) ||
2613
(last_ae == NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE) ||
2614
(last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET))) {
2615
issue_close = 1;
2616
nesqp->cm_id = NULL;
2617
if (nesqp->flush_issued == 0) {
2618
nesqp->flush_issued = 1;
2619
issue_flush = 1;
2620
}
2621
}
2622
2623
spin_unlock_irqrestore(&nesqp->lock, flags);
2624
2625
if ((issue_flush) && (nesqp->destroyed == 0)) {
2626
/* Flush the queue(s) */
2627
if (nesqp->hw_iwarp_state >= NES_AEQE_IWARP_STATE_TERMINATE)
2628
flush_q |= NES_CQP_FLUSH_SQ;
2629
flush_wqes(nesvnic->nesdev, nesqp, flush_q, 1);
2630
2631
if (nesqp->term_flags) {
2632
ibevent.device = nesqp->ibqp.device;
2633
ibevent.event = nesqp->terminate_eventtype;
2634
ibevent.element.qp = &nesqp->ibqp;
2635
nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
2636
}
2637
}
2638
2639
if ((cm_id) && (cm_id->event_handler)) {
2640
if (issue_disconn) {
2641
atomic_inc(&cm_disconnects);
2642
cm_event.event = IW_CM_EVENT_DISCONNECT;
2643
cm_event.status = disconn_status;
2644
cm_event.local_addr = cm_id->local_addr;
2645
cm_event.remote_addr = cm_id->remote_addr;
2646
cm_event.private_data = NULL;
2647
cm_event.private_data_len = 0;
2648
2649
nes_debug(NES_DBG_CM, "Generating a CM Disconnect Event"
2650
" for QP%u, SQ Head = %u, SQ Tail = %u. "
2651
"cm_id = %p, refcount = %u.\n",
2652
nesqp->hwqp.qp_id, nesqp->hwqp.sq_head,
2653
nesqp->hwqp.sq_tail, cm_id,
2654
atomic_read(&nesqp->refcount));
2655
2656
ret = cm_id->event_handler(cm_id, &cm_event);
2657
if (ret)
2658
nes_debug(NES_DBG_CM, "OFA CM event_handler "
2659
"returned, ret=%d\n", ret);
2660
}
2661
2662
if (issue_close) {
2663
atomic_inc(&cm_closes);
2664
nes_disconnect(nesqp, 1);
2665
2666
cm_id->provider_data = nesqp;
2667
/* Send up the close complete event */
2668
cm_event.event = IW_CM_EVENT_CLOSE;
2669
cm_event.status = 0;
2670
cm_event.provider_data = cm_id->provider_data;
2671
cm_event.local_addr = cm_id->local_addr;
2672
cm_event.remote_addr = cm_id->remote_addr;
2673
cm_event.private_data = NULL;
2674
cm_event.private_data_len = 0;
2675
2676
ret = cm_id->event_handler(cm_id, &cm_event);
2677
if (ret) {
2678
nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret);
2679
}
2680
2681
cm_id->rem_ref(cm_id);
2682
}
2683
}
2684
2685
return 0;
2686
}
2687
2688
2689
/**
2690
* nes_disconnect
2691
*/
2692
static int nes_disconnect(struct nes_qp *nesqp, int abrupt)
2693
{
2694
int ret = 0;
2695
struct nes_vnic *nesvnic;
2696
struct nes_device *nesdev;
2697
struct nes_ib_device *nesibdev;
2698
2699
nesvnic = to_nesvnic(nesqp->ibqp.device);
2700
if (!nesvnic)
2701
return -EINVAL;
2702
2703
nesdev = nesvnic->nesdev;
2704
nesibdev = nesvnic->nesibdev;
2705
2706
nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n",
2707
netdev_refcnt_read(nesvnic->netdev));
2708
2709
if (nesqp->active_conn) {
2710
2711
/* indicate this connection is NOT active */
2712
nesqp->active_conn = 0;
2713
} else {
2714
/* Need to free the Last Streaming Mode Message */
2715
if (nesqp->ietf_frame) {
2716
if (nesqp->lsmm_mr)
2717
nesibdev->ibdev.dereg_mr(nesqp->lsmm_mr);
2718
pci_free_consistent(nesdev->pcidev,
2719
nesqp->private_data_len+sizeof(struct ietf_mpa_frame),
2720
nesqp->ietf_frame, nesqp->ietf_frame_pbase);
2721
}
2722
}
2723
2724
/* close the CM node down if it is still active */
2725
if (nesqp->cm_node) {
2726
nes_debug(NES_DBG_CM, "Call close API\n");
2727
2728
g_cm_core->api->close(g_cm_core, nesqp->cm_node);
2729
}
2730
2731
return ret;
2732
}
2733
2734
2735
/**
2736
* nes_accept
2737
*/
2738
int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2739
{
2740
u64 u64temp;
2741
struct ib_qp *ibqp;
2742
struct nes_qp *nesqp;
2743
struct nes_vnic *nesvnic;
2744
struct nes_device *nesdev;
2745
struct nes_cm_node *cm_node;
2746
struct nes_adapter *adapter;
2747
struct ib_qp_attr attr;
2748
struct iw_cm_event cm_event;
2749
struct nes_hw_qp_wqe *wqe;
2750
struct nes_v4_quad nes_quad;
2751
u32 crc_value;
2752
int ret;
2753
int passive_state;
2754
struct nes_ib_device *nesibdev;
2755
struct ib_mr *ibmr = NULL;
2756
struct ib_phys_buf ibphysbuf;
2757
struct nes_pd *nespd;
2758
u64 tagged_offset;
2759
2760
ibqp = nes_get_qp(cm_id->device, conn_param->qpn);
2761
if (!ibqp)
2762
return -EINVAL;
2763
2764
/* get all our handles */
2765
nesqp = to_nesqp(ibqp);
2766
nesvnic = to_nesvnic(nesqp->ibqp.device);
2767
nesdev = nesvnic->nesdev;
2768
adapter = nesdev->nesadapter;
2769
2770
cm_node = (struct nes_cm_node *)cm_id->provider_data;
2771
nes_debug(NES_DBG_CM, "nes_accept: cm_node= %p nesvnic=%p, netdev=%p,"
2772
"%s\n", cm_node, nesvnic, nesvnic->netdev,
2773
nesvnic->netdev->name);
2774
2775
if (NES_CM_STATE_LISTENER_DESTROYED == cm_node->state) {
2776
if (cm_node->loopbackpartner)
2777
rem_ref_cm_node(cm_node->cm_core, cm_node->loopbackpartner);
2778
rem_ref_cm_node(cm_node->cm_core, cm_node);
2779
return -EINVAL;
2780
}
2781
2782
passive_state = atomic_add_return(1, &cm_node->passive_state);
2783
if (passive_state == NES_SEND_RESET_EVENT) {
2784
rem_ref_cm_node(cm_node->cm_core, cm_node);
2785
return -ECONNRESET;
2786
}
2787
2788
/* associate the node with the QP */
2789
nesqp->cm_node = (void *)cm_node;
2790
cm_node->nesqp = nesqp;
2791
2792
nes_debug(NES_DBG_CM, "QP%u, cm_node=%p, jiffies = %lu listener = %p\n",
2793
nesqp->hwqp.qp_id, cm_node, jiffies, cm_node->listener);
2794
atomic_inc(&cm_accepts);
2795
2796
nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n",
2797
netdev_refcnt_read(nesvnic->netdev));
2798
2799
/* allocate the ietf frame and space for private data */
2800
nesqp->ietf_frame = pci_alloc_consistent(nesdev->pcidev,
2801
sizeof(struct ietf_mpa_frame) + conn_param->private_data_len,
2802
&nesqp->ietf_frame_pbase);
2803
2804
if (!nesqp->ietf_frame) {
2805
nes_debug(NES_DBG_CM, "Unable to allocate memory for private "
2806
"data\n");
2807
return -ENOMEM;
2808
}
2809
2810
2811
/* setup the MPA frame */
2812
nesqp->private_data_len = conn_param->private_data_len;
2813
memcpy(nesqp->ietf_frame->key, IEFT_MPA_KEY_REP, IETF_MPA_KEY_SIZE);
2814
2815
memcpy(nesqp->ietf_frame->priv_data, conn_param->private_data,
2816
conn_param->private_data_len);
2817
2818
nesqp->ietf_frame->priv_data_len =
2819
cpu_to_be16(conn_param->private_data_len);
2820
nesqp->ietf_frame->rev = mpa_version;
2821
nesqp->ietf_frame->flags = IETF_MPA_FLAGS_CRC;
2822
2823
/* setup our first outgoing iWarp send WQE (the IETF frame response) */
2824
wqe = &nesqp->hwqp.sq_vbase[0];
2825
2826
if (cm_id->remote_addr.sin_addr.s_addr !=
2827
cm_id->local_addr.sin_addr.s_addr) {
2828
u64temp = (unsigned long)nesqp;
2829
nesibdev = nesvnic->nesibdev;
2830
nespd = nesqp->nespd;
2831
ibphysbuf.addr = nesqp->ietf_frame_pbase;
2832
ibphysbuf.size = conn_param->private_data_len +
2833
sizeof(struct ietf_mpa_frame);
2834
tagged_offset = (u64)(unsigned long)nesqp->ietf_frame;
2835
ibmr = nesibdev->ibdev.reg_phys_mr((struct ib_pd *)nespd,
2836
&ibphysbuf, 1,
2837
IB_ACCESS_LOCAL_WRITE,
2838
&tagged_offset);
2839
if (!ibmr) {
2840
nes_debug(NES_DBG_CM, "Unable to register memory region"
2841
"for lSMM for cm_node = %p \n",
2842
cm_node);
2843
pci_free_consistent(nesdev->pcidev,
2844
nesqp->private_data_len+sizeof(struct ietf_mpa_frame),
2845
nesqp->ietf_frame, nesqp->ietf_frame_pbase);
2846
return -ENOMEM;
2847
}
2848
2849
ibmr->pd = &nespd->ibpd;
2850
ibmr->device = nespd->ibpd.device;
2851
nesqp->lsmm_mr = ibmr;
2852
2853
u64temp |= NES_SW_CONTEXT_ALIGN>>1;
2854
set_wqe_64bit_value(wqe->wqe_words,
2855
NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX,
2856
u64temp);
2857
wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] =
2858
cpu_to_le32(NES_IWARP_SQ_WQE_STREAMING |
2859
NES_IWARP_SQ_WQE_WRPDU);
2860
wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] =
2861
cpu_to_le32(conn_param->private_data_len +
2862
sizeof(struct ietf_mpa_frame));
2863
set_wqe_64bit_value(wqe->wqe_words,
2864
NES_IWARP_SQ_WQE_FRAG0_LOW_IDX,
2865
(u64)(unsigned long)nesqp->ietf_frame);
2866
wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] =
2867
cpu_to_le32(conn_param->private_data_len +
2868
sizeof(struct ietf_mpa_frame));
2869
wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = ibmr->lkey;
2870
if (nesqp->sq_kmapped) {
2871
nesqp->sq_kmapped = 0;
2872
kunmap(nesqp->page);
2873
}
2874
2875
nesqp->nesqp_context->ird_ord_sizes |=
2876
cpu_to_le32(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
2877
NES_QPCONTEXT_ORDIRD_WRPDU);
2878
} else {
2879
nesqp->nesqp_context->ird_ord_sizes |=
2880
cpu_to_le32(NES_QPCONTEXT_ORDIRD_WRPDU);
2881
}
2882
nesqp->skip_lsmm = 1;
2883
2884
2885
/* Cache the cm_id in the qp */
2886
nesqp->cm_id = cm_id;
2887
cm_node->cm_id = cm_id;
2888
2889
/* nesqp->cm_node = (void *)cm_id->provider_data; */
2890
cm_id->provider_data = nesqp;
2891
nesqp->active_conn = 0;
2892
2893
if (cm_node->state == NES_CM_STATE_TSA)
2894
nes_debug(NES_DBG_CM, "Already state = TSA for cm_node=%p\n",
2895
cm_node);
2896
2897
nes_cm_init_tsa_conn(nesqp, cm_node);
2898
2899
nesqp->nesqp_context->tcpPorts[0] =
2900
cpu_to_le16(ntohs(cm_id->local_addr.sin_port));
2901
nesqp->nesqp_context->tcpPorts[1] =
2902
cpu_to_le16(ntohs(cm_id->remote_addr.sin_port));
2903
2904
if (ipv4_is_loopback(cm_id->remote_addr.sin_addr.s_addr))
2905
nesqp->nesqp_context->ip0 =
2906
cpu_to_le32(ntohl(nesvnic->local_ipaddr));
2907
else
2908
nesqp->nesqp_context->ip0 =
2909
cpu_to_le32(ntohl(cm_id->remote_addr.sin_addr.s_addr));
2910
2911
nesqp->nesqp_context->misc2 |= cpu_to_le32(
2912
(u32)PCI_FUNC(nesdev->pcidev->devfn) <<
2913
NES_QPCONTEXT_MISC2_SRC_IP_SHIFT);
2914
2915
nesqp->nesqp_context->arp_index_vlan |=
2916
cpu_to_le32(nes_arp_table(nesdev,
2917
le32_to_cpu(nesqp->nesqp_context->ip0), NULL,
2918
NES_ARP_RESOLVE) << 16);
2919
2920
nesqp->nesqp_context->ts_val_delta = cpu_to_le32(
2921
jiffies - nes_read_indexed(nesdev, NES_IDX_TCP_NOW));
2922
2923
nesqp->nesqp_context->ird_index = cpu_to_le32(nesqp->hwqp.qp_id);
2924
2925
nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32(
2926
((u32)1 << NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT));
2927
nesqp->nesqp_context->ird_ord_sizes |=
2928
cpu_to_le32((u32)conn_param->ord);
2929
2930
memset(&nes_quad, 0, sizeof(nes_quad));
2931
nes_quad.DstIpAdrIndex =
2932
cpu_to_le32((u32)PCI_FUNC(nesdev->pcidev->devfn) << 24);
2933
if (ipv4_is_loopback(cm_id->remote_addr.sin_addr.s_addr))
2934
nes_quad.SrcIpadr = nesvnic->local_ipaddr;
2935
else
2936
nes_quad.SrcIpadr = cm_id->remote_addr.sin_addr.s_addr;
2937
nes_quad.TcpPorts[0] = cm_id->remote_addr.sin_port;
2938
nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port;
2939
2940
/* Produce hash key */
2941
crc_value = get_crc_value(&nes_quad);
2942
nesqp->hte_index = cpu_to_be32(crc_value ^ 0xffffffff);
2943
nes_debug(NES_DBG_CM, "HTE Index = 0x%08X, CRC = 0x%08X\n",
2944
nesqp->hte_index, nesqp->hte_index & adapter->hte_index_mask);
2945
2946
nesqp->hte_index &= adapter->hte_index_mask;
2947
nesqp->nesqp_context->hte_index = cpu_to_le32(nesqp->hte_index);
2948
2949
cm_node->cm_core->api->accelerated(cm_node->cm_core, cm_node);
2950
2951
nes_debug(NES_DBG_CM, "QP%u, Destination IP = 0x%08X:0x%04X, local = "
2952
"0x%08X:0x%04X, rcv_nxt=0x%08X, snd_nxt=0x%08X, mpa + "
2953
"private data length=%zu.\n", nesqp->hwqp.qp_id,
2954
ntohl(cm_id->remote_addr.sin_addr.s_addr),
2955
ntohs(cm_id->remote_addr.sin_port),
2956
ntohl(cm_id->local_addr.sin_addr.s_addr),
2957
ntohs(cm_id->local_addr.sin_port),
2958
le32_to_cpu(nesqp->nesqp_context->rcv_nxt),
2959
le32_to_cpu(nesqp->nesqp_context->snd_nxt),
2960
conn_param->private_data_len +
2961
sizeof(struct ietf_mpa_frame));
2962
2963
2964
/* notify OF layer that accept event was successful */
2965
cm_id->add_ref(cm_id);
2966
nes_add_ref(&nesqp->ibqp);
2967
2968
cm_event.event = IW_CM_EVENT_ESTABLISHED;
2969
cm_event.status = 0;
2970
cm_event.provider_data = (void *)nesqp;
2971
cm_event.local_addr = cm_id->local_addr;
2972
cm_event.remote_addr = cm_id->remote_addr;
2973
cm_event.private_data = NULL;
2974
cm_event.private_data_len = 0;
2975
ret = cm_id->event_handler(cm_id, &cm_event);
2976
attr.qp_state = IB_QPS_RTS;
2977
nes_modify_qp(&nesqp->ibqp, &attr, IB_QP_STATE, NULL);
2978
if (cm_node->loopbackpartner) {
2979
cm_node->loopbackpartner->mpa_frame_size =
2980
nesqp->private_data_len;
2981
/* copy entire MPA frame to our cm_node's frame */
2982
memcpy(cm_node->loopbackpartner->mpa_frame_buf,
2983
nesqp->ietf_frame->priv_data, nesqp->private_data_len);
2984
create_event(cm_node->loopbackpartner, NES_CM_EVENT_CONNECTED);
2985
}
2986
if (ret)
2987
printk(KERN_ERR "%s[%u] OFA CM event_handler returned, "
2988
"ret=%d\n", __func__, __LINE__, ret);
2989
2990
return 0;
2991
}
2992
2993
2994
/**
2995
* nes_reject
2996
*/
2997
int nes_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len)
2998
{
2999
struct nes_cm_node *cm_node;
3000
struct nes_cm_node *loopback;
3001
3002
struct nes_cm_core *cm_core;
3003
3004
atomic_inc(&cm_rejects);
3005
cm_node = (struct nes_cm_node *) cm_id->provider_data;
3006
loopback = cm_node->loopbackpartner;
3007
cm_core = cm_node->cm_core;
3008
cm_node->cm_id = cm_id;
3009
cm_node->mpa_frame_size = sizeof(struct ietf_mpa_frame) + pdata_len;
3010
3011
if (cm_node->mpa_frame_size > MAX_CM_BUFFER)
3012
return -EINVAL;
3013
3014
memcpy(&cm_node->mpa_frame.key[0], IEFT_MPA_KEY_REP, IETF_MPA_KEY_SIZE);
3015
if (loopback) {
3016
memcpy(&loopback->mpa_frame.priv_data, pdata, pdata_len);
3017
loopback->mpa_frame.priv_data_len = pdata_len;
3018
loopback->mpa_frame_size = sizeof(struct ietf_mpa_frame) +
3019
pdata_len;
3020
} else {
3021
memcpy(&cm_node->mpa_frame.priv_data, pdata, pdata_len);
3022
cm_node->mpa_frame.priv_data_len = cpu_to_be16(pdata_len);
3023
}
3024
3025
cm_node->mpa_frame.rev = mpa_version;
3026
cm_node->mpa_frame.flags = IETF_MPA_FLAGS_CRC | IETF_MPA_FLAGS_REJECT;
3027
3028
return cm_core->api->reject(cm_core, &cm_node->mpa_frame, cm_node);
3029
}
3030
3031
3032
/**
3033
* nes_connect
3034
* setup and launch cm connect node
3035
*/
3036
int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
3037
{
3038
struct ib_qp *ibqp;
3039
struct nes_qp *nesqp;
3040
struct nes_vnic *nesvnic;
3041
struct nes_device *nesdev;
3042
struct nes_cm_node *cm_node;
3043
struct nes_cm_info cm_info;
3044
int apbvt_set = 0;
3045
3046
ibqp = nes_get_qp(cm_id->device, conn_param->qpn);
3047
if (!ibqp)
3048
return -EINVAL;
3049
nesqp = to_nesqp(ibqp);
3050
if (!nesqp)
3051
return -EINVAL;
3052
nesvnic = to_nesvnic(nesqp->ibqp.device);
3053
if (!nesvnic)
3054
return -EINVAL;
3055
nesdev = nesvnic->nesdev;
3056
if (!nesdev)
3057
return -EINVAL;
3058
3059
if (!(cm_id->local_addr.sin_port) || !(cm_id->remote_addr.sin_port))
3060
return -EINVAL;
3061
3062
nes_debug(NES_DBG_CM, "QP%u, current IP = 0x%08X, Destination IP = "
3063
"0x%08X:0x%04X, local = 0x%08X:0x%04X.\n", nesqp->hwqp.qp_id,
3064
ntohl(nesvnic->local_ipaddr),
3065
ntohl(cm_id->remote_addr.sin_addr.s_addr),
3066
ntohs(cm_id->remote_addr.sin_port),
3067
ntohl(cm_id->local_addr.sin_addr.s_addr),
3068
ntohs(cm_id->local_addr.sin_port));
3069
3070
atomic_inc(&cm_connects);
3071
nesqp->active_conn = 1;
3072
3073
/* cache the cm_id in the qp */
3074
nesqp->cm_id = cm_id;
3075
3076
cm_id->provider_data = nesqp;
3077
3078
nesqp->private_data_len = conn_param->private_data_len;
3079
nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32((u32)conn_param->ord);
3080
nes_debug(NES_DBG_CM, "requested ord = 0x%08X.\n", (u32)conn_param->ord);
3081
nes_debug(NES_DBG_CM, "mpa private data len =%u\n",
3082
conn_param->private_data_len);
3083
3084
if (cm_id->local_addr.sin_addr.s_addr !=
3085
cm_id->remote_addr.sin_addr.s_addr) {
3086
nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port),
3087
PCI_FUNC(nesdev->pcidev->devfn), NES_MANAGE_APBVT_ADD);
3088
apbvt_set = 1;
3089
}
3090
3091
/* set up the connection params for the node */
3092
cm_info.loc_addr = htonl(cm_id->local_addr.sin_addr.s_addr);
3093
cm_info.loc_port = htons(cm_id->local_addr.sin_port);
3094
cm_info.rem_addr = htonl(cm_id->remote_addr.sin_addr.s_addr);
3095
cm_info.rem_port = htons(cm_id->remote_addr.sin_port);
3096
cm_info.cm_id = cm_id;
3097
cm_info.conn_type = NES_CM_IWARP_CONN_TYPE;
3098
3099
cm_id->add_ref(cm_id);
3100
3101
/* create a connect CM node connection */
3102
cm_node = g_cm_core->api->connect(g_cm_core, nesvnic,
3103
conn_param->private_data_len, (void *)conn_param->private_data,
3104
&cm_info);
3105
if (!cm_node) {
3106
if (apbvt_set)
3107
nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port),
3108
PCI_FUNC(nesdev->pcidev->devfn),
3109
NES_MANAGE_APBVT_DEL);
3110
3111
cm_id->rem_ref(cm_id);
3112
return -ENOMEM;
3113
}
3114
3115
cm_node->apbvt_set = apbvt_set;
3116
nesqp->cm_node = cm_node;
3117
cm_node->nesqp = nesqp;
3118
nes_add_ref(&nesqp->ibqp);
3119
3120
return 0;
3121
}
3122
3123
3124
/**
3125
* nes_create_listen
3126
*/
3127
int nes_create_listen(struct iw_cm_id *cm_id, int backlog)
3128
{
3129
struct nes_vnic *nesvnic;
3130
struct nes_cm_listener *cm_node;
3131
struct nes_cm_info cm_info;
3132
int err;
3133
3134
nes_debug(NES_DBG_CM, "cm_id = %p, local port = 0x%04X.\n",
3135
cm_id, ntohs(cm_id->local_addr.sin_port));
3136
3137
nesvnic = to_nesvnic(cm_id->device);
3138
if (!nesvnic)
3139
return -EINVAL;
3140
3141
nes_debug(NES_DBG_CM, "nesvnic=%p, netdev=%p, %s\n",
3142
nesvnic, nesvnic->netdev, nesvnic->netdev->name);
3143
3144
nes_debug(NES_DBG_CM, "nesvnic->local_ipaddr=0x%08x, sin_addr.s_addr=0x%08x\n",
3145
nesvnic->local_ipaddr, cm_id->local_addr.sin_addr.s_addr);
3146
3147
/* setup listen params in our api call struct */
3148
cm_info.loc_addr = nesvnic->local_ipaddr;
3149
cm_info.loc_port = cm_id->local_addr.sin_port;
3150
cm_info.backlog = backlog;
3151
cm_info.cm_id = cm_id;
3152
3153
cm_info.conn_type = NES_CM_IWARP_CONN_TYPE;
3154
3155
3156
cm_node = g_cm_core->api->listen(g_cm_core, nesvnic, &cm_info);
3157
if (!cm_node) {
3158
printk(KERN_ERR "%s[%u] Error returned from listen API call\n",
3159
__func__, __LINE__);
3160
return -ENOMEM;
3161
}
3162
3163
cm_id->provider_data = cm_node;
3164
3165
if (!cm_node->reused_node) {
3166
err = nes_manage_apbvt(nesvnic,
3167
ntohs(cm_id->local_addr.sin_port),
3168
PCI_FUNC(nesvnic->nesdev->pcidev->devfn),
3169
NES_MANAGE_APBVT_ADD);
3170
if (err) {
3171
printk(KERN_ERR "nes_manage_apbvt call returned %d.\n",
3172
err);
3173
g_cm_core->api->stop_listener(g_cm_core, (void *)cm_node);
3174
return err;
3175
}
3176
atomic_inc(&cm_listens_created);
3177
}
3178
3179
cm_id->add_ref(cm_id);
3180
cm_id->provider_data = (void *)cm_node;
3181
3182
3183
return 0;
3184
}
3185
3186
3187
/**
3188
* nes_destroy_listen
3189
*/
3190
int nes_destroy_listen(struct iw_cm_id *cm_id)
3191
{
3192
if (cm_id->provider_data)
3193
g_cm_core->api->stop_listener(g_cm_core, cm_id->provider_data);
3194
else
3195
nes_debug(NES_DBG_CM, "cm_id->provider_data was NULL\n");
3196
3197
cm_id->rem_ref(cm_id);
3198
3199
return 0;
3200
}
3201
3202
3203
/**
3204
* nes_cm_recv
3205
*/
3206
int nes_cm_recv(struct sk_buff *skb, struct net_device *netdevice)
3207
{
3208
int rc = 0;
3209
cm_packets_received++;
3210
if ((g_cm_core) && (g_cm_core->api)) {
3211
rc = g_cm_core->api->recv_pkt(g_cm_core, netdev_priv(netdevice), skb);
3212
} else {
3213
nes_debug(NES_DBG_CM, "Unable to process packet for CM,"
3214
" cm is not setup properly.\n");
3215
}
3216
3217
return rc;
3218
}
3219
3220
3221
/**
3222
* nes_cm_start
3223
* Start and init a cm core module
3224
*/
3225
int nes_cm_start(void)
3226
{
3227
nes_debug(NES_DBG_CM, "\n");
3228
/* create the primary CM core, pass this handle to subsequent core inits */
3229
g_cm_core = nes_cm_alloc_core();
3230
if (g_cm_core) {
3231
return 0;
3232
} else {
3233
return -ENOMEM;
3234
}
3235
}
3236
3237
3238
/**
3239
* nes_cm_stop
3240
* stop and dealloc all cm core instances
3241
*/
3242
int nes_cm_stop(void)
3243
{
3244
g_cm_core->api->destroy_cm_core(g_cm_core);
3245
return 0;
3246
}
3247
3248
3249
/**
3250
* cm_event_connected
3251
* handle a connected event, setup QPs and HW
3252
*/
3253
static void cm_event_connected(struct nes_cm_event *event)
3254
{
3255
u64 u64temp;
3256
struct nes_qp *nesqp;
3257
struct nes_vnic *nesvnic;
3258
struct nes_device *nesdev;
3259
struct nes_cm_node *cm_node;
3260
struct nes_adapter *nesadapter;
3261
struct ib_qp_attr attr;
3262
struct iw_cm_id *cm_id;
3263
struct iw_cm_event cm_event;
3264
struct nes_hw_qp_wqe *wqe;
3265
struct nes_v4_quad nes_quad;
3266
u32 crc_value;
3267
int ret;
3268
3269
/* get all our handles */
3270
cm_node = event->cm_node;
3271
cm_id = cm_node->cm_id;
3272
nes_debug(NES_DBG_CM, "cm_event_connected - %p - cm_id = %p\n", cm_node, cm_id);
3273
nesqp = (struct nes_qp *)cm_id->provider_data;
3274
nesvnic = to_nesvnic(nesqp->ibqp.device);
3275
nesdev = nesvnic->nesdev;
3276
nesadapter = nesdev->nesadapter;
3277
3278
if (nesqp->destroyed) {
3279
return;
3280
}
3281
atomic_inc(&cm_connecteds);
3282
nes_debug(NES_DBG_CM, "QP%u attempting to connect to 0x%08X:0x%04X on"
3283
" local port 0x%04X. jiffies = %lu.\n",
3284
nesqp->hwqp.qp_id,
3285
ntohl(cm_id->remote_addr.sin_addr.s_addr),
3286
ntohs(cm_id->remote_addr.sin_port),
3287
ntohs(cm_id->local_addr.sin_port),
3288
jiffies);
3289
3290
nes_cm_init_tsa_conn(nesqp, cm_node);
3291
3292
/* set the QP tsa context */
3293
nesqp->nesqp_context->tcpPorts[0] =
3294
cpu_to_le16(ntohs(cm_id->local_addr.sin_port));
3295
nesqp->nesqp_context->tcpPorts[1] =
3296
cpu_to_le16(ntohs(cm_id->remote_addr.sin_port));
3297
if (ipv4_is_loopback(cm_id->remote_addr.sin_addr.s_addr))
3298
nesqp->nesqp_context->ip0 =
3299
cpu_to_le32(ntohl(nesvnic->local_ipaddr));
3300
else
3301
nesqp->nesqp_context->ip0 =
3302
cpu_to_le32(ntohl(cm_id->remote_addr.sin_addr.s_addr));
3303
3304
nesqp->nesqp_context->misc2 |= cpu_to_le32(
3305
(u32)PCI_FUNC(nesdev->pcidev->devfn) <<
3306
NES_QPCONTEXT_MISC2_SRC_IP_SHIFT);
3307
nesqp->nesqp_context->arp_index_vlan |= cpu_to_le32(
3308
nes_arp_table(nesdev,
3309
le32_to_cpu(nesqp->nesqp_context->ip0),
3310
NULL, NES_ARP_RESOLVE) << 16);
3311
nesqp->nesqp_context->ts_val_delta = cpu_to_le32(
3312
jiffies - nes_read_indexed(nesdev, NES_IDX_TCP_NOW));
3313
nesqp->nesqp_context->ird_index = cpu_to_le32(nesqp->hwqp.qp_id);
3314
nesqp->nesqp_context->ird_ord_sizes |=
3315
cpu_to_le32((u32)1 <<
3316
NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT);
3317
3318
/* Adjust tail for not having a LSMM */
3319
nesqp->hwqp.sq_tail = 1;
3320
3321
#if defined(NES_SEND_FIRST_WRITE)
3322
if (cm_node->send_write0) {
3323
nes_debug(NES_DBG_CM, "Sending first write.\n");
3324
wqe = &nesqp->hwqp.sq_vbase[0];
3325
u64temp = (unsigned long)nesqp;
3326
u64temp |= NES_SW_CONTEXT_ALIGN>>1;
3327
set_wqe_64bit_value(wqe->wqe_words,
3328
NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX, u64temp);
3329
wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] =
3330
cpu_to_le32(NES_IWARP_SQ_OP_RDMAW);
3331
wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] = 0;
3332
wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX] = 0;
3333
wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX] = 0;
3334
wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = 0;
3335
wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0;
3336
3337
if (nesqp->sq_kmapped) {
3338
nesqp->sq_kmapped = 0;
3339
kunmap(nesqp->page);
3340
}
3341
3342
/* use the reserved spot on the WQ for the extra first WQE */
3343
nesqp->nesqp_context->ird_ord_sizes &=
3344
cpu_to_le32(~(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
3345
NES_QPCONTEXT_ORDIRD_WRPDU |
3346
NES_QPCONTEXT_ORDIRD_ALSMM));
3347
nesqp->skip_lsmm = 1;
3348
nesqp->hwqp.sq_tail = 0;
3349
nes_write32(nesdev->regs + NES_WQE_ALLOC,
3350
(1 << 24) | 0x00800000 | nesqp->hwqp.qp_id);
3351
}
3352
#endif
3353
3354
memset(&nes_quad, 0, sizeof(nes_quad));
3355
3356
nes_quad.DstIpAdrIndex =
3357
cpu_to_le32((u32)PCI_FUNC(nesdev->pcidev->devfn) << 24);
3358
if (ipv4_is_loopback(cm_id->remote_addr.sin_addr.s_addr))
3359
nes_quad.SrcIpadr = nesvnic->local_ipaddr;
3360
else
3361
nes_quad.SrcIpadr = cm_id->remote_addr.sin_addr.s_addr;
3362
nes_quad.TcpPorts[0] = cm_id->remote_addr.sin_port;
3363
nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port;
3364
3365
/* Produce hash key */
3366
crc_value = get_crc_value(&nes_quad);
3367
nesqp->hte_index = cpu_to_be32(crc_value ^ 0xffffffff);
3368
nes_debug(NES_DBG_CM, "HTE Index = 0x%08X, After CRC = 0x%08X\n",
3369
nesqp->hte_index, nesqp->hte_index & nesadapter->hte_index_mask);
3370
3371
nesqp->hte_index &= nesadapter->hte_index_mask;
3372
nesqp->nesqp_context->hte_index = cpu_to_le32(nesqp->hte_index);
3373
3374
nesqp->ietf_frame = &cm_node->mpa_frame;
3375
nesqp->private_data_len = (u8) cm_node->mpa_frame_size;
3376
cm_node->cm_core->api->accelerated(cm_node->cm_core, cm_node);
3377
3378
/* notify OF layer we successfully created the requested connection */
3379
cm_event.event = IW_CM_EVENT_CONNECT_REPLY;
3380
cm_event.status = 0;
3381
cm_event.provider_data = cm_id->provider_data;
3382
cm_event.local_addr.sin_family = AF_INET;
3383
cm_event.local_addr.sin_port = cm_id->local_addr.sin_port;
3384
cm_event.remote_addr = cm_id->remote_addr;
3385
3386
cm_event.private_data = (void *)event->cm_node->mpa_frame_buf;
3387
cm_event.private_data_len = (u8) event->cm_node->mpa_frame_size;
3388
3389
cm_event.local_addr.sin_addr.s_addr = event->cm_info.rem_addr;
3390
ret = cm_id->event_handler(cm_id, &cm_event);
3391
nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret);
3392
3393
if (ret)
3394
printk(KERN_ERR "%s[%u] OFA CM event_handler returned, "
3395
"ret=%d\n", __func__, __LINE__, ret);
3396
attr.qp_state = IB_QPS_RTS;
3397
nes_modify_qp(&nesqp->ibqp, &attr, IB_QP_STATE, NULL);
3398
3399
nes_debug(NES_DBG_CM, "Exiting connect thread for QP%u. jiffies = "
3400
"%lu\n", nesqp->hwqp.qp_id, jiffies);
3401
3402
return;
3403
}
3404
3405
3406
/**
3407
* cm_event_connect_error
3408
*/
3409
static void cm_event_connect_error(struct nes_cm_event *event)
3410
{
3411
struct nes_qp *nesqp;
3412
struct iw_cm_id *cm_id;
3413
struct iw_cm_event cm_event;
3414
/* struct nes_cm_info cm_info; */
3415
int ret;
3416
3417
if (!event->cm_node)
3418
return;
3419
3420
cm_id = event->cm_node->cm_id;
3421
if (!cm_id) {
3422
return;
3423
}
3424
3425
nes_debug(NES_DBG_CM, "cm_node=%p, cm_id=%p\n", event->cm_node, cm_id);
3426
nesqp = cm_id->provider_data;
3427
3428
if (!nesqp) {
3429
return;
3430
}
3431
3432
/* notify OF layer about this connection error event */
3433
/* cm_id->rem_ref(cm_id); */
3434
nesqp->cm_id = NULL;
3435
cm_id->provider_data = NULL;
3436
cm_event.event = IW_CM_EVENT_CONNECT_REPLY;
3437
cm_event.status = -ECONNRESET;
3438
cm_event.provider_data = cm_id->provider_data;
3439
cm_event.local_addr = cm_id->local_addr;
3440
cm_event.remote_addr = cm_id->remote_addr;
3441
cm_event.private_data = NULL;
3442
cm_event.private_data_len = 0;
3443
3444
nes_debug(NES_DBG_CM, "call CM_EVENT REJECTED, local_addr=%08x, "
3445
"remove_addr=%08x\n", cm_event.local_addr.sin_addr.s_addr,
3446
cm_event.remote_addr.sin_addr.s_addr);
3447
3448
ret = cm_id->event_handler(cm_id, &cm_event);
3449
nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret);
3450
if (ret)
3451
printk(KERN_ERR "%s[%u] OFA CM event_handler returned, "
3452
"ret=%d\n", __func__, __LINE__, ret);
3453
cm_id->rem_ref(cm_id);
3454
3455
rem_ref_cm_node(event->cm_node->cm_core, event->cm_node);
3456
return;
3457
}
3458
3459
3460
/**
3461
* cm_event_reset
3462
*/
3463
static void cm_event_reset(struct nes_cm_event *event)
3464
{
3465
struct nes_qp *nesqp;
3466
struct iw_cm_id *cm_id;
3467
struct iw_cm_event cm_event;
3468
/* struct nes_cm_info cm_info; */
3469
int ret;
3470
3471
if (!event->cm_node)
3472
return;
3473
3474
if (!event->cm_node->cm_id)
3475
return;
3476
3477
cm_id = event->cm_node->cm_id;
3478
3479
nes_debug(NES_DBG_CM, "%p - cm_id = %p\n", event->cm_node, cm_id);
3480
nesqp = cm_id->provider_data;
3481
if (!nesqp)
3482
return;
3483
3484
nesqp->cm_id = NULL;
3485
/* cm_id->provider_data = NULL; */
3486
cm_event.event = IW_CM_EVENT_DISCONNECT;
3487
cm_event.status = -ECONNRESET;
3488
cm_event.provider_data = cm_id->provider_data;
3489
cm_event.local_addr = cm_id->local_addr;
3490
cm_event.remote_addr = cm_id->remote_addr;
3491
cm_event.private_data = NULL;
3492
cm_event.private_data_len = 0;
3493
3494
cm_id->add_ref(cm_id);
3495
ret = cm_id->event_handler(cm_id, &cm_event);
3496
atomic_inc(&cm_closes);
3497
cm_event.event = IW_CM_EVENT_CLOSE;
3498
cm_event.status = 0;
3499
cm_event.provider_data = cm_id->provider_data;
3500
cm_event.local_addr = cm_id->local_addr;
3501
cm_event.remote_addr = cm_id->remote_addr;
3502
cm_event.private_data = NULL;
3503
cm_event.private_data_len = 0;
3504
nes_debug(NES_DBG_CM, "NODE %p Generating CLOSE\n", event->cm_node);
3505
ret = cm_id->event_handler(cm_id, &cm_event);
3506
3507
nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret);
3508
3509
3510
/* notify OF layer about this connection error event */
3511
cm_id->rem_ref(cm_id);
3512
3513
return;
3514
}
3515
3516
3517
/**
3518
* cm_event_mpa_req
3519
*/
3520
static void cm_event_mpa_req(struct nes_cm_event *event)
3521
{
3522
struct iw_cm_id *cm_id;
3523
struct iw_cm_event cm_event;
3524
int ret;
3525
struct nes_cm_node *cm_node;
3526
3527
cm_node = event->cm_node;
3528
if (!cm_node)
3529
return;
3530
cm_id = cm_node->cm_id;
3531
3532
atomic_inc(&cm_connect_reqs);
3533
nes_debug(NES_DBG_CM, "cm_node = %p - cm_id = %p, jiffies = %lu\n",
3534
cm_node, cm_id, jiffies);
3535
3536
cm_event.event = IW_CM_EVENT_CONNECT_REQUEST;
3537
cm_event.status = 0;
3538
cm_event.provider_data = (void *)cm_node;
3539
3540
cm_event.local_addr.sin_family = AF_INET;
3541
cm_event.local_addr.sin_port = htons(event->cm_info.loc_port);
3542
cm_event.local_addr.sin_addr.s_addr = htonl(event->cm_info.loc_addr);
3543
3544
cm_event.remote_addr.sin_family = AF_INET;
3545
cm_event.remote_addr.sin_port = htons(event->cm_info.rem_port);
3546
cm_event.remote_addr.sin_addr.s_addr = htonl(event->cm_info.rem_addr);
3547
cm_event.private_data = cm_node->mpa_frame_buf;
3548
cm_event.private_data_len = (u8) cm_node->mpa_frame_size;
3549
3550
ret = cm_id->event_handler(cm_id, &cm_event);
3551
if (ret)
3552
printk(KERN_ERR "%s[%u] OFA CM event_handler returned, ret=%d\n",
3553
__func__, __LINE__, ret);
3554
return;
3555
}
3556
3557
3558
static void cm_event_mpa_reject(struct nes_cm_event *event)
3559
{
3560
struct iw_cm_id *cm_id;
3561
struct iw_cm_event cm_event;
3562
struct nes_cm_node *cm_node;
3563
int ret;
3564
3565
cm_node = event->cm_node;
3566
if (!cm_node)
3567
return;
3568
cm_id = cm_node->cm_id;
3569
3570
atomic_inc(&cm_connect_reqs);
3571
nes_debug(NES_DBG_CM, "cm_node = %p - cm_id = %p, jiffies = %lu\n",
3572
cm_node, cm_id, jiffies);
3573
3574
cm_event.event = IW_CM_EVENT_CONNECT_REPLY;
3575
cm_event.status = -ECONNREFUSED;
3576
cm_event.provider_data = cm_id->provider_data;
3577
3578
cm_event.local_addr.sin_family = AF_INET;
3579
cm_event.local_addr.sin_port = htons(event->cm_info.loc_port);
3580
cm_event.local_addr.sin_addr.s_addr = htonl(event->cm_info.loc_addr);
3581
3582
cm_event.remote_addr.sin_family = AF_INET;
3583
cm_event.remote_addr.sin_port = htons(event->cm_info.rem_port);
3584
cm_event.remote_addr.sin_addr.s_addr = htonl(event->cm_info.rem_addr);
3585
3586
cm_event.private_data = cm_node->mpa_frame_buf;
3587
cm_event.private_data_len = (u8) cm_node->mpa_frame_size;
3588
3589
nes_debug(NES_DBG_CM, "call CM_EVENT_MPA_REJECTED, local_addr=%08x, "
3590
"remove_addr=%08x\n",
3591
cm_event.local_addr.sin_addr.s_addr,
3592
cm_event.remote_addr.sin_addr.s_addr);
3593
3594
ret = cm_id->event_handler(cm_id, &cm_event);
3595
if (ret)
3596
printk(KERN_ERR "%s[%u] OFA CM event_handler returned, ret=%d\n",
3597
__func__, __LINE__, ret);
3598
3599
return;
3600
}
3601
3602
3603
static void nes_cm_event_handler(struct work_struct *);
3604
3605
/**
3606
* nes_cm_post_event
3607
* post an event to the cm event handler
3608
*/
3609
static int nes_cm_post_event(struct nes_cm_event *event)
3610
{
3611
atomic_inc(&event->cm_node->cm_core->events_posted);
3612
add_ref_cm_node(event->cm_node);
3613
event->cm_info.cm_id->add_ref(event->cm_info.cm_id);
3614
INIT_WORK(&event->event_work, nes_cm_event_handler);
3615
nes_debug(NES_DBG_CM, "cm_node=%p queue_work, event=%p\n",
3616
event->cm_node, event);
3617
3618
queue_work(event->cm_node->cm_core->event_wq, &event->event_work);
3619
3620
nes_debug(NES_DBG_CM, "Exit\n");
3621
return 0;
3622
}
3623
3624
3625
/**
3626
* nes_cm_event_handler
3627
* worker function to handle cm events
3628
* will free instance of nes_cm_event
3629
*/
3630
static void nes_cm_event_handler(struct work_struct *work)
3631
{
3632
struct nes_cm_event *event = container_of(work, struct nes_cm_event,
3633
event_work);
3634
struct nes_cm_core *cm_core;
3635
3636
if ((!event) || (!event->cm_node) || (!event->cm_node->cm_core))
3637
return;
3638
3639
cm_core = event->cm_node->cm_core;
3640
nes_debug(NES_DBG_CM, "event=%p, event->type=%u, events posted=%u\n",
3641
event, event->type, atomic_read(&cm_core->events_posted));
3642
3643
switch (event->type) {
3644
case NES_CM_EVENT_MPA_REQ:
3645
cm_event_mpa_req(event);
3646
nes_debug(NES_DBG_CM, "cm_node=%p CM Event: MPA REQUEST\n",
3647
event->cm_node);
3648
break;
3649
case NES_CM_EVENT_RESET:
3650
nes_debug(NES_DBG_CM, "cm_node = %p CM Event: RESET\n",
3651
event->cm_node);
3652
cm_event_reset(event);
3653
break;
3654
case NES_CM_EVENT_CONNECTED:
3655
if ((!event->cm_node->cm_id) ||
3656
(event->cm_node->state != NES_CM_STATE_TSA))
3657
break;
3658
cm_event_connected(event);
3659
nes_debug(NES_DBG_CM, "CM Event: CONNECTED\n");
3660
break;
3661
case NES_CM_EVENT_MPA_REJECT:
3662
if ((!event->cm_node->cm_id) ||
3663
(event->cm_node->state == NES_CM_STATE_TSA))
3664
break;
3665
cm_event_mpa_reject(event);
3666
nes_debug(NES_DBG_CM, "CM Event: REJECT\n");
3667
break;
3668
3669
case NES_CM_EVENT_ABORTED:
3670
if ((!event->cm_node->cm_id) ||
3671
(event->cm_node->state == NES_CM_STATE_TSA))
3672
break;
3673
cm_event_connect_error(event);
3674
nes_debug(NES_DBG_CM, "CM Event: ABORTED\n");
3675
break;
3676
case NES_CM_EVENT_DROPPED_PKT:
3677
nes_debug(NES_DBG_CM, "CM Event: DROPPED PKT\n");
3678
break;
3679
default:
3680
nes_debug(NES_DBG_CM, "CM Event: UNKNOWN EVENT TYPE\n");
3681
break;
3682
}
3683
3684
atomic_dec(&cm_core->events_posted);
3685
event->cm_info.cm_id->rem_ref(event->cm_info.cm_id);
3686
rem_ref_cm_node(cm_core, event->cm_node);
3687
kfree(event);
3688
3689
return;
3690
}
3691
3692