aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/nes/nes_cm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/nes/nes_cm.c')
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c586
1 files changed, 393 insertions, 193 deletions
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 4a65b96db2c..52425154acd 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved. 2 * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 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 5 * licenses. You may choose to be licensed under the terms of the GNU
@@ -103,6 +103,7 @@ static int nes_disconnect(struct nes_qp *nesqp, int abrupt);
103static void nes_disconnect_worker(struct work_struct *work); 103static void nes_disconnect_worker(struct work_struct *work);
104 104
105static int send_mpa_request(struct nes_cm_node *, struct sk_buff *); 105static int send_mpa_request(struct nes_cm_node *, struct sk_buff *);
106static int send_mpa_reject(struct nes_cm_node *);
106static int send_syn(struct nes_cm_node *, u32, struct sk_buff *); 107static int send_syn(struct nes_cm_node *, u32, struct sk_buff *);
107static int send_reset(struct nes_cm_node *, struct sk_buff *); 108static int send_reset(struct nes_cm_node *, struct sk_buff *);
108static int send_ack(struct nes_cm_node *cm_node, struct sk_buff *skb); 109static int send_ack(struct nes_cm_node *cm_node, struct sk_buff *skb);
@@ -113,8 +114,7 @@ static void process_packet(struct nes_cm_node *, struct sk_buff *,
113static void active_open_err(struct nes_cm_node *, struct sk_buff *, int); 114static void active_open_err(struct nes_cm_node *, struct sk_buff *, int);
114static void passive_open_err(struct nes_cm_node *, struct sk_buff *, int); 115static void passive_open_err(struct nes_cm_node *, struct sk_buff *, int);
115static void cleanup_retrans_entry(struct nes_cm_node *); 116static void cleanup_retrans_entry(struct nes_cm_node *);
116static void handle_rcv_mpa(struct nes_cm_node *, struct sk_buff *, 117static void handle_rcv_mpa(struct nes_cm_node *, struct sk_buff *);
117 enum nes_cm_event_type);
118static void free_retrans_entry(struct nes_cm_node *cm_node); 118static void free_retrans_entry(struct nes_cm_node *cm_node);
119static int handle_tcp_options(struct nes_cm_node *cm_node, struct tcphdr *tcph, 119static int handle_tcp_options(struct nes_cm_node *cm_node, struct tcphdr *tcph,
120 struct sk_buff *skb, int optionsize, int passive); 120 struct sk_buff *skb, int optionsize, int passive);
@@ -124,6 +124,8 @@ static void cm_event_connected(struct nes_cm_event *);
124static void cm_event_connect_error(struct nes_cm_event *); 124static void cm_event_connect_error(struct nes_cm_event *);
125static void cm_event_reset(struct nes_cm_event *); 125static void cm_event_reset(struct nes_cm_event *);
126static void cm_event_mpa_req(struct nes_cm_event *); 126static void cm_event_mpa_req(struct nes_cm_event *);
127static void cm_event_mpa_reject(struct nes_cm_event *);
128static void handle_recv_entry(struct nes_cm_node *cm_node, u32 rem_node);
127 129
128static void print_core(struct nes_cm_core *core); 130static void print_core(struct nes_cm_core *core);
129 131
@@ -196,7 +198,6 @@ static struct nes_cm_event *create_event(struct nes_cm_node *cm_node,
196 */ 198 */
197static int send_mpa_request(struct nes_cm_node *cm_node, struct sk_buff *skb) 199static int send_mpa_request(struct nes_cm_node *cm_node, struct sk_buff *skb)
198{ 200{
199 int ret;
200 if (!skb) { 201 if (!skb) {
201 nes_debug(NES_DBG_CM, "skb set to NULL\n"); 202 nes_debug(NES_DBG_CM, "skb set to NULL\n");
202 return -1; 203 return -1;
@@ -206,11 +207,27 @@ static int send_mpa_request(struct nes_cm_node *cm_node, struct sk_buff *skb)
206 form_cm_frame(skb, cm_node, NULL, 0, &cm_node->mpa_frame, 207 form_cm_frame(skb, cm_node, NULL, 0, &cm_node->mpa_frame,
207 cm_node->mpa_frame_size, SET_ACK); 208 cm_node->mpa_frame_size, SET_ACK);
208 209
209 ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0); 210 return schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0);
210 if (ret < 0) 211}
211 return ret;
212 212
213 return 0; 213
214
215static int send_mpa_reject(struct nes_cm_node *cm_node)
216{
217 struct sk_buff *skb = NULL;
218
219 skb = dev_alloc_skb(MAX_CM_BUFFER);
220 if (!skb) {
221 nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
222 return -ENOMEM;
223 }
224
225 /* send an MPA reject frame */
226 form_cm_frame(skb, cm_node, NULL, 0, &cm_node->mpa_frame,
227 cm_node->mpa_frame_size, SET_ACK | SET_FIN);
228
229 cm_node->state = NES_CM_STATE_FIN_WAIT1;
230 return schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0);
214} 231}
215 232
216 233
@@ -218,14 +235,17 @@ static int send_mpa_request(struct nes_cm_node *cm_node, struct sk_buff *skb)
218 * recv_mpa - process a received TCP pkt, we are expecting an 235 * recv_mpa - process a received TCP pkt, we are expecting an
219 * IETF MPA frame 236 * IETF MPA frame
220 */ 237 */
221static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 len) 238static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 *type,
239 u32 len)
222{ 240{
223 struct ietf_mpa_frame *mpa_frame; 241 struct ietf_mpa_frame *mpa_frame;
224 242
243 *type = NES_MPA_REQUEST_ACCEPT;
244
225 /* assume req frame is in tcp data payload */ 245 /* assume req frame is in tcp data payload */
226 if (len < sizeof(struct ietf_mpa_frame)) { 246 if (len < sizeof(struct ietf_mpa_frame)) {
227 nes_debug(NES_DBG_CM, "The received ietf buffer was too small (%x)\n", len); 247 nes_debug(NES_DBG_CM, "The received ietf buffer was too small (%x)\n", len);
228 return -1; 248 return -EINVAL;
229 } 249 }
230 250
231 mpa_frame = (struct ietf_mpa_frame *)buffer; 251 mpa_frame = (struct ietf_mpa_frame *)buffer;
@@ -234,14 +254,25 @@ static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 len)
234 if (cm_node->mpa_frame_size + sizeof(struct ietf_mpa_frame) != len) { 254 if (cm_node->mpa_frame_size + sizeof(struct ietf_mpa_frame) != len) {
235 nes_debug(NES_DBG_CM, "The received ietf buffer was not right" 255 nes_debug(NES_DBG_CM, "The received ietf buffer was not right"
236 " complete (%x + %x != %x)\n", 256 " complete (%x + %x != %x)\n",
237 cm_node->mpa_frame_size, (u32)sizeof(struct ietf_mpa_frame), len); 257 cm_node->mpa_frame_size,
238 return -1; 258 (u32)sizeof(struct ietf_mpa_frame), len);
259 return -EINVAL;
260 }
261 /* make sure it does not exceed the max size */
262 if (len > MAX_CM_BUFFER) {
263 nes_debug(NES_DBG_CM, "The received ietf buffer was too large"
264 " (%x + %x != %x)\n",
265 cm_node->mpa_frame_size,
266 (u32)sizeof(struct ietf_mpa_frame), len);
267 return -EINVAL;
239 } 268 }
240 269
241 /* copy entire MPA frame to our cm_node's frame */ 270 /* copy entire MPA frame to our cm_node's frame */
242 memcpy(cm_node->mpa_frame_buf, buffer + sizeof(struct ietf_mpa_frame), 271 memcpy(cm_node->mpa_frame_buf, buffer + sizeof(struct ietf_mpa_frame),
243 cm_node->mpa_frame_size); 272 cm_node->mpa_frame_size);
244 273
274 if (mpa_frame->flags & IETF_MPA_FLAGS_REJECT)
275 *type = NES_MPA_REQUEST_REJECT;
245 return 0; 276 return 0;
246} 277}
247 278
@@ -380,7 +411,7 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
380 411
381 new_send = kzalloc(sizeof(*new_send), GFP_ATOMIC); 412 new_send = kzalloc(sizeof(*new_send), GFP_ATOMIC);
382 if (!new_send) 413 if (!new_send)
383 return -1; 414 return -ENOMEM;
384 415
385 /* new_send->timetosend = currenttime */ 416 /* new_send->timetosend = currenttime */
386 new_send->retrycount = NES_DEFAULT_RETRYS; 417 new_send->retrycount = NES_DEFAULT_RETRYS;
@@ -394,9 +425,11 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
394 425
395 if (type == NES_TIMER_TYPE_CLOSE) { 426 if (type == NES_TIMER_TYPE_CLOSE) {
396 new_send->timetosend += (HZ/10); 427 new_send->timetosend += (HZ/10);
397 spin_lock_irqsave(&cm_node->recv_list_lock, flags); 428 if (cm_node->recv_entry) {
398 list_add_tail(&new_send->list, &cm_node->recv_list); 429 WARN_ON(1);
399 spin_unlock_irqrestore(&cm_node->recv_list_lock, flags); 430 return -EINVAL;
431 }
432 cm_node->recv_entry = new_send;
400 } 433 }
401 434
402 if (type == NES_TIMER_TYPE_SEND) { 435 if (type == NES_TIMER_TYPE_SEND) {
@@ -435,24 +468,78 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
435 return ret; 468 return ret;
436} 469}
437 470
471static void nes_retrans_expired(struct nes_cm_node *cm_node)
472{
473 switch (cm_node->state) {
474 case NES_CM_STATE_SYN_RCVD:
475 case NES_CM_STATE_CLOSING:
476 rem_ref_cm_node(cm_node->cm_core, cm_node);
477 break;
478 case NES_CM_STATE_LAST_ACK:
479 case NES_CM_STATE_FIN_WAIT1:
480 case NES_CM_STATE_MPAREJ_RCVD:
481 send_reset(cm_node, NULL);
482 break;
483 default:
484 create_event(cm_node, NES_CM_EVENT_ABORTED);
485 }
486}
487
488static void handle_recv_entry(struct nes_cm_node *cm_node, u32 rem_node)
489{
490 struct nes_timer_entry *recv_entry = cm_node->recv_entry;
491 struct iw_cm_id *cm_id = cm_node->cm_id;
492 struct nes_qp *nesqp;
493 unsigned long qplockflags;
494
495 if (!recv_entry)
496 return;
497 nesqp = (struct nes_qp *)recv_entry->skb;
498 if (nesqp) {
499 spin_lock_irqsave(&nesqp->lock, qplockflags);
500 if (nesqp->cm_id) {
501 nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
502 "refcount = %d: HIT A "
503 "NES_TIMER_TYPE_CLOSE with something "
504 "to do!!!\n", nesqp->hwqp.qp_id, cm_id,
505 atomic_read(&nesqp->refcount));
506 nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
507 nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT;
508 nesqp->ibqp_state = IB_QPS_ERR;
509 spin_unlock_irqrestore(&nesqp->lock, qplockflags);
510 nes_cm_disconn(nesqp);
511 } else {
512 spin_unlock_irqrestore(&nesqp->lock, qplockflags);
513 nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
514 "refcount = %d: HIT A "
515 "NES_TIMER_TYPE_CLOSE with nothing "
516 "to do!!!\n", nesqp->hwqp.qp_id, cm_id,
517 atomic_read(&nesqp->refcount));
518 }
519 } else if (rem_node) {
520 /* TIME_WAIT state */
521 rem_ref_cm_node(cm_node->cm_core, cm_node);
522 }
523 if (cm_node->cm_id)
524 cm_id->rem_ref(cm_id);
525 kfree(recv_entry);
526 cm_node->recv_entry = NULL;
527}
438 528
439/** 529/**
440 * nes_cm_timer_tick 530 * nes_cm_timer_tick
441 */ 531 */
442static void nes_cm_timer_tick(unsigned long pass) 532static void nes_cm_timer_tick(unsigned long pass)
443{ 533{
444 unsigned long flags, qplockflags; 534 unsigned long flags;
445 unsigned long nexttimeout = jiffies + NES_LONG_TIME; 535 unsigned long nexttimeout = jiffies + NES_LONG_TIME;
446 struct iw_cm_id *cm_id;
447 struct nes_cm_node *cm_node; 536 struct nes_cm_node *cm_node;
448 struct nes_timer_entry *send_entry, *recv_entry; 537 struct nes_timer_entry *send_entry, *recv_entry;
449 struct list_head *list_core, *list_core_temp; 538 struct list_head *list_core_temp;
450 struct list_head *list_node, *list_node_temp; 539 struct list_head *list_node;
451 struct nes_cm_core *cm_core = g_cm_core; 540 struct nes_cm_core *cm_core = g_cm_core;
452 struct nes_qp *nesqp;
453 u32 settimer = 0; 541 u32 settimer = 0;
454 int ret = NETDEV_TX_OK; 542 int ret = NETDEV_TX_OK;
455 enum nes_cm_node_state last_state;
456 543
457 struct list_head timer_list; 544 struct list_head timer_list;
458 INIT_LIST_HEAD(&timer_list); 545 INIT_LIST_HEAD(&timer_list);
@@ -461,7 +548,7 @@ static void nes_cm_timer_tick(unsigned long pass)
461 list_for_each_safe(list_node, list_core_temp, 548 list_for_each_safe(list_node, list_core_temp,
462 &cm_core->connected_nodes) { 549 &cm_core->connected_nodes) {
463 cm_node = container_of(list_node, struct nes_cm_node, list); 550 cm_node = container_of(list_node, struct nes_cm_node, list);
464 if (!list_empty(&cm_node->recv_list) || (cm_node->send_entry)) { 551 if ((cm_node->recv_entry) || (cm_node->send_entry)) {
465 add_ref_cm_node(cm_node); 552 add_ref_cm_node(cm_node);
466 list_add(&cm_node->timer_entry, &timer_list); 553 list_add(&cm_node->timer_entry, &timer_list);
467 } 554 }
@@ -471,54 +558,18 @@ static void nes_cm_timer_tick(unsigned long pass)
471 list_for_each_safe(list_node, list_core_temp, &timer_list) { 558 list_for_each_safe(list_node, list_core_temp, &timer_list) {
472 cm_node = container_of(list_node, struct nes_cm_node, 559 cm_node = container_of(list_node, struct nes_cm_node,
473 timer_entry); 560 timer_entry);
474 spin_lock_irqsave(&cm_node->recv_list_lock, flags); 561 recv_entry = cm_node->recv_entry;
475 list_for_each_safe(list_core, list_node_temp, 562
476 &cm_node->recv_list) { 563 if (recv_entry) {
477 recv_entry = container_of(list_core,
478 struct nes_timer_entry, list);
479 if (!recv_entry)
480 break;
481 if (time_after(recv_entry->timetosend, jiffies)) { 564 if (time_after(recv_entry->timetosend, jiffies)) {
482 if (nexttimeout > recv_entry->timetosend || 565 if (nexttimeout > recv_entry->timetosend ||
483 !settimer) { 566 !settimer) {
484 nexttimeout = recv_entry->timetosend; 567 nexttimeout = recv_entry->timetosend;
485 settimer = 1; 568 settimer = 1;
486 } 569 }
487 continue; 570 } else
488 } 571 handle_recv_entry(cm_node, 1);
489 list_del(&recv_entry->list);
490 cm_id = cm_node->cm_id;
491 spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
492 nesqp = (struct nes_qp *)recv_entry->skb;
493 spin_lock_irqsave(&nesqp->lock, qplockflags);
494 if (nesqp->cm_id) {
495 nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
496 "refcount = %d: HIT A "
497 "NES_TIMER_TYPE_CLOSE with something "
498 "to do!!!\n", nesqp->hwqp.qp_id, cm_id,
499 atomic_read(&nesqp->refcount));
500 nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
501 nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT;
502 nesqp->ibqp_state = IB_QPS_ERR;
503 spin_unlock_irqrestore(&nesqp->lock,
504 qplockflags);
505 nes_cm_disconn(nesqp);
506 } else {
507 spin_unlock_irqrestore(&nesqp->lock,
508 qplockflags);
509 nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
510 "refcount = %d: HIT A "
511 "NES_TIMER_TYPE_CLOSE with nothing "
512 "to do!!!\n", nesqp->hwqp.qp_id, cm_id,
513 atomic_read(&nesqp->refcount));
514 }
515 if (cm_id)
516 cm_id->rem_ref(cm_id);
517
518 kfree(recv_entry);
519 spin_lock_irqsave(&cm_node->recv_list_lock, flags);
520 } 572 }
521 spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
522 573
523 spin_lock_irqsave(&cm_node->retrans_list_lock, flags); 574 spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
524 do { 575 do {
@@ -533,12 +584,11 @@ static void nes_cm_timer_tick(unsigned long pass)
533 nexttimeout = 584 nexttimeout =
534 send_entry->timetosend; 585 send_entry->timetosend;
535 settimer = 1; 586 settimer = 1;
536 break;
537 } 587 }
538 } else { 588 } else {
539 free_retrans_entry(cm_node); 589 free_retrans_entry(cm_node);
540 break;
541 } 590 }
591 break;
542 } 592 }
543 593
544 if ((cm_node->state == NES_CM_STATE_TSA) || 594 if ((cm_node->state == NES_CM_STATE_TSA) ||
@@ -550,16 +600,12 @@ static void nes_cm_timer_tick(unsigned long pass)
550 if (!send_entry->retranscount || 600 if (!send_entry->retranscount ||
551 !send_entry->retrycount) { 601 !send_entry->retrycount) {
552 cm_packets_dropped++; 602 cm_packets_dropped++;
553 last_state = cm_node->state;
554 cm_node->state = NES_CM_STATE_CLOSED;
555 free_retrans_entry(cm_node); 603 free_retrans_entry(cm_node);
604
556 spin_unlock_irqrestore( 605 spin_unlock_irqrestore(
557 &cm_node->retrans_list_lock, flags); 606 &cm_node->retrans_list_lock, flags);
558 if (last_state == NES_CM_STATE_SYN_RCVD) 607 nes_retrans_expired(cm_node);
559 rem_ref_cm_node(cm_core, cm_node); 608 cm_node->state = NES_CM_STATE_CLOSED;
560 else
561 create_event(cm_node,
562 NES_CM_EVENT_ABORTED);
563 spin_lock_irqsave(&cm_node->retrans_list_lock, 609 spin_lock_irqsave(&cm_node->retrans_list_lock,
564 flags); 610 flags);
565 break; 611 break;
@@ -714,7 +760,7 @@ static int send_reset(struct nes_cm_node *cm_node, struct sk_buff *skb)
714 skb = dev_alloc_skb(MAX_CM_BUFFER); 760 skb = dev_alloc_skb(MAX_CM_BUFFER);
715 if (!skb) { 761 if (!skb) {
716 nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); 762 nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
717 return -1; 763 return -ENOMEM;
718 } 764 }
719 765
720 form_cm_frame(skb, cm_node, NULL, 0, NULL, 0, flags); 766 form_cm_frame(skb, cm_node, NULL, 0, NULL, 0, flags);
@@ -778,14 +824,10 @@ static struct nes_cm_node *find_node(struct nes_cm_core *cm_core,
778 unsigned long flags; 824 unsigned long flags;
779 struct list_head *hte; 825 struct list_head *hte;
780 struct nes_cm_node *cm_node; 826 struct nes_cm_node *cm_node;
781 __be32 tmp_addr = cpu_to_be32(loc_addr);
782 827
783 /* get a handle on the hte */ 828 /* get a handle on the hte */
784 hte = &cm_core->connected_nodes; 829 hte = &cm_core->connected_nodes;
785 830
786 nes_debug(NES_DBG_CM, "Searching for an owner node: %pI4:%x from core %p->%p\n",
787 &tmp_addr, loc_port, cm_core, hte);
788
789 /* walk list and find cm_node associated with this session ID */ 831 /* walk list and find cm_node associated with this session ID */
790 spin_lock_irqsave(&cm_core->ht_lock, flags); 832 spin_lock_irqsave(&cm_core->ht_lock, flags);
791 list_for_each_entry(cm_node, hte, list) { 833 list_for_each_entry(cm_node, hte, list) {
@@ -875,7 +917,8 @@ static int add_hte_node(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node
875static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core, 917static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
876 struct nes_cm_listener *listener, int free_hanging_nodes) 918 struct nes_cm_listener *listener, int free_hanging_nodes)
877{ 919{
878 int ret = 1; 920 int ret = -EINVAL;
921 int err = 0;
879 unsigned long flags; 922 unsigned long flags;
880 struct list_head *list_pos = NULL; 923 struct list_head *list_pos = NULL;
881 struct list_head *list_temp = NULL; 924 struct list_head *list_temp = NULL;
@@ -904,10 +947,60 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
904 947
905 list_for_each_safe(list_pos, list_temp, &reset_list) { 948 list_for_each_safe(list_pos, list_temp, &reset_list) {
906 cm_node = container_of(list_pos, struct nes_cm_node, 949 cm_node = container_of(list_pos, struct nes_cm_node,
907 reset_entry); 950 reset_entry);
908 cleanup_retrans_entry(cm_node); 951 {
909 send_reset(cm_node, NULL); 952 struct nes_cm_node *loopback = cm_node->loopbackpartner;
910 rem_ref_cm_node(cm_node->cm_core, cm_node); 953 if (NES_CM_STATE_FIN_WAIT1 <= cm_node->state) {
954 rem_ref_cm_node(cm_node->cm_core, cm_node);
955 } else {
956 if (!loopback) {
957 cleanup_retrans_entry(cm_node);
958 err = send_reset(cm_node, NULL);
959 if (err) {
960 cm_node->state =
961 NES_CM_STATE_CLOSED;
962 WARN_ON(1);
963 } else {
964 cm_node->state =
965 NES_CM_STATE_CLOSED;
966 rem_ref_cm_node(
967 cm_node->cm_core,
968 cm_node);
969 }
970 } else {
971 struct nes_cm_event event;
972
973 event.cm_node = loopback;
974 event.cm_info.rem_addr =
975 loopback->rem_addr;
976 event.cm_info.loc_addr =
977 loopback->loc_addr;
978 event.cm_info.rem_port =
979 loopback->rem_port;
980 event.cm_info.loc_port =
981 loopback->loc_port;
982 event.cm_info.cm_id = loopback->cm_id;
983 cm_event_connect_error(&event);
984 loopback->state = NES_CM_STATE_CLOSED;
985
986 event.cm_node = cm_node;
987 event.cm_info.rem_addr =
988 cm_node->rem_addr;
989 event.cm_info.loc_addr =
990 cm_node->loc_addr;
991 event.cm_info.rem_port =
992 cm_node->rem_port;
993 event.cm_info.loc_port =
994 cm_node->loc_port;
995 event.cm_info.cm_id = cm_node->cm_id;
996 cm_event_reset(&event);
997
998 rem_ref_cm_node(cm_node->cm_core,
999 cm_node);
1000
1001 }
1002 }
1003 }
911 } 1004 }
912 1005
913 spin_lock_irqsave(&cm_core->listen_list_lock, flags); 1006 spin_lock_irqsave(&cm_core->listen_list_lock, flags);
@@ -968,6 +1061,7 @@ static inline int mini_cm_accelerated(struct nes_cm_core *cm_core,
968 if (cm_node->accept_pend) { 1061 if (cm_node->accept_pend) {
969 BUG_ON(!cm_node->listener); 1062 BUG_ON(!cm_node->listener);
970 atomic_dec(&cm_node->listener->pend_accepts_cnt); 1063 atomic_dec(&cm_node->listener->pend_accepts_cnt);
1064 cm_node->accept_pend = 0;
971 BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0); 1065 BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0);
972 } 1066 }
973 1067
@@ -994,7 +1088,7 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip)
994 memset(&fl, 0, sizeof fl); 1088 memset(&fl, 0, sizeof fl);
995 fl.nl_u.ip4_u.daddr = htonl(dst_ip); 1089 fl.nl_u.ip4_u.daddr = htonl(dst_ip);
996 if (ip_route_output_key(&init_net, &rt, &fl)) { 1090 if (ip_route_output_key(&init_net, &rt, &fl)) {
997 printk("%s: ip_route_output_key failed for 0x%08X\n", 1091 printk(KERN_ERR "%s: ip_route_output_key failed for 0x%08X\n",
998 __func__, dst_ip); 1092 __func__, dst_ip);
999 return rc; 1093 return rc;
1000 } 1094 }
@@ -1057,8 +1151,6 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
1057 cm_node->cm_id); 1151 cm_node->cm_id);
1058 1152
1059 spin_lock_init(&cm_node->retrans_list_lock); 1153 spin_lock_init(&cm_node->retrans_list_lock);
1060 INIT_LIST_HEAD(&cm_node->recv_list);
1061 spin_lock_init(&cm_node->recv_list_lock);
1062 1154
1063 cm_node->loopbackpartner = NULL; 1155 cm_node->loopbackpartner = NULL;
1064 atomic_set(&cm_node->ref_count, 1); 1156 atomic_set(&cm_node->ref_count, 1);
@@ -1126,10 +1218,7 @@ static int add_ref_cm_node(struct nes_cm_node *cm_node)
1126static int rem_ref_cm_node(struct nes_cm_core *cm_core, 1218static int rem_ref_cm_node(struct nes_cm_core *cm_core,
1127 struct nes_cm_node *cm_node) 1219 struct nes_cm_node *cm_node)
1128{ 1220{
1129 unsigned long flags, qplockflags; 1221 unsigned long flags;
1130 struct nes_timer_entry *recv_entry;
1131 struct iw_cm_id *cm_id;
1132 struct list_head *list_core, *list_node_temp;
1133 struct nes_qp *nesqp; 1222 struct nes_qp *nesqp;
1134 1223
1135 if (!cm_node) 1224 if (!cm_node)
@@ -1150,38 +1239,9 @@ static int rem_ref_cm_node(struct nes_cm_core *cm_core,
1150 atomic_dec(&cm_node->listener->pend_accepts_cnt); 1239 atomic_dec(&cm_node->listener->pend_accepts_cnt);
1151 BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0); 1240 BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0);
1152 } 1241 }
1153 BUG_ON(cm_node->send_entry); 1242 WARN_ON(cm_node->send_entry);
1154 spin_lock_irqsave(&cm_node->recv_list_lock, flags); 1243 if (cm_node->recv_entry)
1155 list_for_each_safe(list_core, list_node_temp, &cm_node->recv_list) { 1244 handle_recv_entry(cm_node, 0);
1156 recv_entry = container_of(list_core, struct nes_timer_entry,
1157 list);
1158 list_del(&recv_entry->list);
1159 cm_id = cm_node->cm_id;
1160 spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
1161 nesqp = (struct nes_qp *)recv_entry->skb;
1162 spin_lock_irqsave(&nesqp->lock, qplockflags);
1163 if (nesqp->cm_id) {
1164 nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: HIT A "
1165 "NES_TIMER_TYPE_CLOSE with something to do!\n",
1166 nesqp->hwqp.qp_id, cm_id);
1167 nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
1168 nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT;
1169 nesqp->ibqp_state = IB_QPS_ERR;
1170 spin_unlock_irqrestore(&nesqp->lock, qplockflags);
1171 nes_cm_disconn(nesqp);
1172 } else {
1173 spin_unlock_irqrestore(&nesqp->lock, qplockflags);
1174 nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: HIT A "
1175 "NES_TIMER_TYPE_CLOSE with nothing to do!\n",
1176 nesqp->hwqp.qp_id, cm_id);
1177 }
1178 cm_id->rem_ref(cm_id);
1179
1180 kfree(recv_entry);
1181 spin_lock_irqsave(&cm_node->recv_list_lock, flags);
1182 }
1183 spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
1184
1185 if (cm_node->listener) { 1245 if (cm_node->listener) {
1186 mini_cm_dec_refcnt_listen(cm_core, cm_node->listener, 0); 1246 mini_cm_dec_refcnt_listen(cm_core, cm_node->listener, 0);
1187 } else { 1247 } else {
@@ -1266,8 +1326,7 @@ static void drop_packet(struct sk_buff *skb)
1266 dev_kfree_skb_any(skb); 1326 dev_kfree_skb_any(skb);
1267} 1327}
1268 1328
1269static void handle_fin_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, 1329static void handle_fin_pkt(struct nes_cm_node *cm_node)
1270 struct tcphdr *tcph)
1271{ 1330{
1272 nes_debug(NES_DBG_CM, "Received FIN, cm_node = %p, state = %u. " 1331 nes_debug(NES_DBG_CM, "Received FIN, cm_node = %p, state = %u. "
1273 "refcnt=%d\n", cm_node, cm_node->state, 1332 "refcnt=%d\n", cm_node, cm_node->state,
@@ -1279,23 +1338,30 @@ static void handle_fin_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1279 case NES_CM_STATE_SYN_SENT: 1338 case NES_CM_STATE_SYN_SENT:
1280 case NES_CM_STATE_ESTABLISHED: 1339 case NES_CM_STATE_ESTABLISHED:
1281 case NES_CM_STATE_MPAREQ_SENT: 1340 case NES_CM_STATE_MPAREQ_SENT:
1341 case NES_CM_STATE_MPAREJ_RCVD:
1282 cm_node->state = NES_CM_STATE_LAST_ACK; 1342 cm_node->state = NES_CM_STATE_LAST_ACK;
1283 send_fin(cm_node, skb); 1343 send_fin(cm_node, NULL);
1284 break; 1344 break;
1285 case NES_CM_STATE_FIN_WAIT1: 1345 case NES_CM_STATE_FIN_WAIT1:
1286 cm_node->state = NES_CM_STATE_CLOSING; 1346 cm_node->state = NES_CM_STATE_CLOSING;
1287 send_ack(cm_node, skb); 1347 send_ack(cm_node, NULL);
1348 /* Wait for ACK as this is simultanous close..
1349 * After we receive ACK, do not send anything..
1350 * Just rm the node.. Done.. */
1288 break; 1351 break;
1289 case NES_CM_STATE_FIN_WAIT2: 1352 case NES_CM_STATE_FIN_WAIT2:
1290 cm_node->state = NES_CM_STATE_TIME_WAIT; 1353 cm_node->state = NES_CM_STATE_TIME_WAIT;
1291 send_ack(cm_node, skb); 1354 send_ack(cm_node, NULL);
1355 schedule_nes_timer(cm_node, NULL, NES_TIMER_TYPE_CLOSE, 1, 0);
1356 break;
1357 case NES_CM_STATE_TIME_WAIT:
1292 cm_node->state = NES_CM_STATE_CLOSED; 1358 cm_node->state = NES_CM_STATE_CLOSED;
1359 rem_ref_cm_node(cm_node->cm_core, cm_node);
1293 break; 1360 break;
1294 case NES_CM_STATE_TSA: 1361 case NES_CM_STATE_TSA:
1295 default: 1362 default:
1296 nes_debug(NES_DBG_CM, "Error Rcvd FIN for node-%p state = %d\n", 1363 nes_debug(NES_DBG_CM, "Error Rcvd FIN for node-%p state = %d\n",
1297 cm_node, cm_node->state); 1364 cm_node, cm_node->state);
1298 drop_packet(skb);
1299 break; 1365 break;
1300 } 1366 }
1301} 1367}
@@ -1341,23 +1407,35 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1341 cleanup_retrans_entry(cm_node); 1407 cleanup_retrans_entry(cm_node);
1342 drop_packet(skb); 1408 drop_packet(skb);
1343 break; 1409 break;
1410 case NES_CM_STATE_TIME_WAIT:
1411 cleanup_retrans_entry(cm_node);
1412 cm_node->state = NES_CM_STATE_CLOSED;
1413 rem_ref_cm_node(cm_node->cm_core, cm_node);
1414 drop_packet(skb);
1415 break;
1416 case NES_CM_STATE_FIN_WAIT1:
1417 cleanup_retrans_entry(cm_node);
1418 nes_debug(NES_DBG_CM, "Bad state %s[%u]\n", __func__, __LINE__);
1344 default: 1419 default:
1345 drop_packet(skb); 1420 drop_packet(skb);
1346 break; 1421 break;
1347 } 1422 }
1348} 1423}
1349 1424
1350static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb, 1425
1351 enum nes_cm_event_type type) 1426static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb)
1352{ 1427{
1353 1428
1354 int ret; 1429 int ret = 0;
1355 int datasize = skb->len; 1430 int datasize = skb->len;
1356 u8 *dataloc = skb->data; 1431 u8 *dataloc = skb->data;
1357 ret = parse_mpa(cm_node, dataloc, datasize); 1432
1358 if (ret < 0) { 1433 enum nes_cm_event_type type = NES_CM_EVENT_UNKNOWN;
1434 u32 res_type;
1435 ret = parse_mpa(cm_node, dataloc, &res_type, datasize);
1436 if (ret) {
1359 nes_debug(NES_DBG_CM, "didn't like MPA Request\n"); 1437 nes_debug(NES_DBG_CM, "didn't like MPA Request\n");
1360 if (type == NES_CM_EVENT_CONNECTED) { 1438 if (cm_node->state == NES_CM_STATE_MPAREQ_SENT) {
1361 nes_debug(NES_DBG_CM, "%s[%u] create abort for " 1439 nes_debug(NES_DBG_CM, "%s[%u] create abort for "
1362 "cm_node=%p listener=%p state=%d\n", __func__, 1440 "cm_node=%p listener=%p state=%d\n", __func__,
1363 __LINE__, cm_node, cm_node->listener, 1441 __LINE__, cm_node, cm_node->listener,
@@ -1366,18 +1444,38 @@ static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb,
1366 } else { 1444 } else {
1367 passive_open_err(cm_node, skb, 1); 1445 passive_open_err(cm_node, skb, 1);
1368 } 1446 }
1369 } else { 1447 return;
1370 cleanup_retrans_entry(cm_node); 1448 }
1371 dev_kfree_skb_any(skb); 1449
1372 if (type == NES_CM_EVENT_CONNECTED) 1450 switch (cm_node->state) {
1451 case NES_CM_STATE_ESTABLISHED:
1452 if (res_type == NES_MPA_REQUEST_REJECT) {
1453 /*BIG problem as we are receiving the MPA.. So should
1454 * not be REJECT.. This is Passive Open.. We can
1455 * only receive it Reject for Active Open...*/
1456 WARN_ON(1);
1457 }
1458 cm_node->state = NES_CM_STATE_MPAREQ_RCVD;
1459 type = NES_CM_EVENT_MPA_REQ;
1460 atomic_set(&cm_node->passive_state,
1461 NES_PASSIVE_STATE_INDICATED);
1462 break;
1463 case NES_CM_STATE_MPAREQ_SENT:
1464 if (res_type == NES_MPA_REQUEST_REJECT) {
1465 type = NES_CM_EVENT_MPA_REJECT;
1466 cm_node->state = NES_CM_STATE_MPAREJ_RCVD;
1467 } else {
1468 type = NES_CM_EVENT_CONNECTED;
1373 cm_node->state = NES_CM_STATE_TSA; 1469 cm_node->state = NES_CM_STATE_TSA;
1374 else 1470 }
1375 atomic_set(&cm_node->passive_state,
1376 NES_PASSIVE_STATE_INDICATED);
1377 create_event(cm_node, type);
1378 1471
1472 break;
1473 default:
1474 WARN_ON(1);
1475 break;
1379 } 1476 }
1380 return ; 1477 dev_kfree_skb_any(skb);
1478 create_event(cm_node, type);
1381} 1479}
1382 1480
1383static void indicate_pkt_err(struct nes_cm_node *cm_node, struct sk_buff *skb) 1481static void indicate_pkt_err(struct nes_cm_node *cm_node, struct sk_buff *skb)
@@ -1465,8 +1563,6 @@ static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1465 break; 1563 break;
1466 case NES_CM_STATE_LISTENING: 1564 case NES_CM_STATE_LISTENING:
1467 /* Passive OPEN */ 1565 /* Passive OPEN */
1468 cm_node->accept_pend = 1;
1469 atomic_inc(&cm_node->listener->pend_accepts_cnt);
1470 if (atomic_read(&cm_node->listener->pend_accepts_cnt) > 1566 if (atomic_read(&cm_node->listener->pend_accepts_cnt) >
1471 cm_node->listener->backlog) { 1567 cm_node->listener->backlog) {
1472 nes_debug(NES_DBG_CM, "drop syn due to backlog " 1568 nes_debug(NES_DBG_CM, "drop syn due to backlog "
@@ -1484,6 +1580,9 @@ static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1484 } 1580 }
1485 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + 1; 1581 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + 1;
1486 BUG_ON(cm_node->send_entry); 1582 BUG_ON(cm_node->send_entry);
1583 cm_node->accept_pend = 1;
1584 atomic_inc(&cm_node->listener->pend_accepts_cnt);
1585
1487 cm_node->state = NES_CM_STATE_SYN_RCVD; 1586 cm_node->state = NES_CM_STATE_SYN_RCVD;
1488 send_syn(cm_node, 1, skb); 1587 send_syn(cm_node, 1, skb);
1489 break; 1588 break;
@@ -1518,6 +1617,7 @@ static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1518 inc_sequence = ntohl(tcph->seq); 1617 inc_sequence = ntohl(tcph->seq);
1519 switch (cm_node->state) { 1618 switch (cm_node->state) {
1520 case NES_CM_STATE_SYN_SENT: 1619 case NES_CM_STATE_SYN_SENT:
1620 cleanup_retrans_entry(cm_node);
1521 /* active open */ 1621 /* active open */
1522 if (check_syn(cm_node, tcph, skb)) 1622 if (check_syn(cm_node, tcph, skb))
1523 return; 1623 return;
@@ -1567,10 +1667,7 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1567 u32 rem_seq; 1667 u32 rem_seq;
1568 int ret; 1668 int ret;
1569 int optionsize; 1669 int optionsize;
1570 u32 temp_seq = cm_node->tcp_cntxt.loc_seq_num;
1571
1572 optionsize = (tcph->doff << 2) - sizeof(struct tcphdr); 1670 optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
1573 cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
1574 1671
1575 if (check_seq(cm_node, tcph, skb)) 1672 if (check_seq(cm_node, tcph, skb))
1576 return; 1673 return;
@@ -1580,7 +1677,7 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1580 rem_seq = ntohl(tcph->seq); 1677 rem_seq = ntohl(tcph->seq);
1581 rem_seq_ack = ntohl(tcph->ack_seq); 1678 rem_seq_ack = ntohl(tcph->ack_seq);
1582 datasize = skb->len; 1679 datasize = skb->len;
1583 1680 cleanup_retrans_entry(cm_node);
1584 switch (cm_node->state) { 1681 switch (cm_node->state) {
1585 case NES_CM_STATE_SYN_RCVD: 1682 case NES_CM_STATE_SYN_RCVD:
1586 /* Passive OPEN */ 1683 /* Passive OPEN */
@@ -1588,7 +1685,6 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1588 if (ret) 1685 if (ret)
1589 break; 1686 break;
1590 cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); 1687 cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
1591 cm_node->tcp_cntxt.loc_seq_num = temp_seq;
1592 if (cm_node->tcp_cntxt.rem_ack_num != 1688 if (cm_node->tcp_cntxt.rem_ack_num !=
1593 cm_node->tcp_cntxt.loc_seq_num) { 1689 cm_node->tcp_cntxt.loc_seq_num) {
1594 nes_debug(NES_DBG_CM, "rem_ack_num != loc_seq_num\n"); 1690 nes_debug(NES_DBG_CM, "rem_ack_num != loc_seq_num\n");
@@ -1597,31 +1693,30 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1597 return; 1693 return;
1598 } 1694 }
1599 cm_node->state = NES_CM_STATE_ESTABLISHED; 1695 cm_node->state = NES_CM_STATE_ESTABLISHED;
1696 cleanup_retrans_entry(cm_node);
1600 if (datasize) { 1697 if (datasize) {
1601 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; 1698 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
1602 cm_node->state = NES_CM_STATE_MPAREQ_RCVD; 1699 handle_rcv_mpa(cm_node, skb);
1603 handle_rcv_mpa(cm_node, skb, NES_CM_EVENT_MPA_REQ); 1700 } else { /* rcvd ACK only */
1604 } else { /* rcvd ACK only */
1605 dev_kfree_skb_any(skb); 1701 dev_kfree_skb_any(skb);
1606 cleanup_retrans_entry(cm_node); 1702 cleanup_retrans_entry(cm_node);
1607 } 1703 }
1608 break; 1704 break;
1609 case NES_CM_STATE_ESTABLISHED: 1705 case NES_CM_STATE_ESTABLISHED:
1610 /* Passive OPEN */ 1706 /* Passive OPEN */
1611 /* We expect mpa frame to be received only */ 1707 cleanup_retrans_entry(cm_node);
1612 if (datasize) { 1708 if (datasize) {
1613 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; 1709 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
1614 cm_node->state = NES_CM_STATE_MPAREQ_RCVD; 1710 handle_rcv_mpa(cm_node, skb);
1615 handle_rcv_mpa(cm_node, skb,
1616 NES_CM_EVENT_MPA_REQ);
1617 } else 1711 } else
1618 drop_packet(skb); 1712 drop_packet(skb);
1619 break; 1713 break;
1620 case NES_CM_STATE_MPAREQ_SENT: 1714 case NES_CM_STATE_MPAREQ_SENT:
1715 cleanup_retrans_entry(cm_node);
1621 cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); 1716 cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
1622 if (datasize) { 1717 if (datasize) {
1623 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; 1718 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
1624 handle_rcv_mpa(cm_node, skb, NES_CM_EVENT_CONNECTED); 1719 handle_rcv_mpa(cm_node, skb);
1625 } else { /* Could be just an ack pkt.. */ 1720 } else { /* Could be just an ack pkt.. */
1626 cleanup_retrans_entry(cm_node); 1721 cleanup_retrans_entry(cm_node);
1627 dev_kfree_skb_any(skb); 1722 dev_kfree_skb_any(skb);
@@ -1632,13 +1727,24 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1632 cleanup_retrans_entry(cm_node); 1727 cleanup_retrans_entry(cm_node);
1633 send_reset(cm_node, skb); 1728 send_reset(cm_node, skb);
1634 break; 1729 break;
1730 case NES_CM_STATE_LAST_ACK:
1731 cleanup_retrans_entry(cm_node);
1732 cm_node->state = NES_CM_STATE_CLOSED;
1733 cm_node->cm_id->rem_ref(cm_node->cm_id);
1734 case NES_CM_STATE_CLOSING:
1735 cleanup_retrans_entry(cm_node);
1736 rem_ref_cm_node(cm_node->cm_core, cm_node);
1737 drop_packet(skb);
1738 break;
1635 case NES_CM_STATE_FIN_WAIT1: 1739 case NES_CM_STATE_FIN_WAIT1:
1740 cleanup_retrans_entry(cm_node);
1741 drop_packet(skb);
1742 cm_node->state = NES_CM_STATE_FIN_WAIT2;
1743 break;
1636 case NES_CM_STATE_SYN_SENT: 1744 case NES_CM_STATE_SYN_SENT:
1637 case NES_CM_STATE_FIN_WAIT2: 1745 case NES_CM_STATE_FIN_WAIT2:
1638 case NES_CM_STATE_TSA: 1746 case NES_CM_STATE_TSA:
1639 case NES_CM_STATE_MPAREQ_RCVD: 1747 case NES_CM_STATE_MPAREQ_RCVD:
1640 case NES_CM_STATE_LAST_ACK:
1641 case NES_CM_STATE_CLOSING:
1642 case NES_CM_STATE_UNKNOWN: 1748 case NES_CM_STATE_UNKNOWN:
1643 default: 1749 default:
1644 drop_packet(skb); 1750 drop_packet(skb);
@@ -1748,6 +1854,7 @@ static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
1748{ 1854{
1749 enum nes_tcpip_pkt_type pkt_type = NES_PKT_TYPE_UNKNOWN; 1855 enum nes_tcpip_pkt_type pkt_type = NES_PKT_TYPE_UNKNOWN;
1750 struct tcphdr *tcph = tcp_hdr(skb); 1856 struct tcphdr *tcph = tcp_hdr(skb);
1857 u32 fin_set = 0;
1751 skb_pull(skb, ip_hdr(skb)->ihl << 2); 1858 skb_pull(skb, ip_hdr(skb)->ihl << 2);
1752 1859
1753 nes_debug(NES_DBG_CM, "process_packet: cm_node=%p state =%d syn=%d " 1860 nes_debug(NES_DBG_CM, "process_packet: cm_node=%p state =%d syn=%d "
@@ -1760,10 +1867,10 @@ static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
1760 pkt_type = NES_PKT_TYPE_SYN; 1867 pkt_type = NES_PKT_TYPE_SYN;
1761 if (tcph->ack) 1868 if (tcph->ack)
1762 pkt_type = NES_PKT_TYPE_SYNACK; 1869 pkt_type = NES_PKT_TYPE_SYNACK;
1763 } else if (tcph->fin) 1870 } else if (tcph->ack)
1764 pkt_type = NES_PKT_TYPE_FIN;
1765 else if (tcph->ack)
1766 pkt_type = NES_PKT_TYPE_ACK; 1871 pkt_type = NES_PKT_TYPE_ACK;
1872 if (tcph->fin)
1873 fin_set = 1;
1767 1874
1768 switch (pkt_type) { 1875 switch (pkt_type) {
1769 case NES_PKT_TYPE_SYN: 1876 case NES_PKT_TYPE_SYN:
@@ -1774,15 +1881,16 @@ static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
1774 break; 1881 break;
1775 case NES_PKT_TYPE_ACK: 1882 case NES_PKT_TYPE_ACK:
1776 handle_ack_pkt(cm_node, skb, tcph); 1883 handle_ack_pkt(cm_node, skb, tcph);
1884 if (fin_set)
1885 handle_fin_pkt(cm_node);
1777 break; 1886 break;
1778 case NES_PKT_TYPE_RST: 1887 case NES_PKT_TYPE_RST:
1779 handle_rst_pkt(cm_node, skb, tcph); 1888 handle_rst_pkt(cm_node, skb, tcph);
1780 break; 1889 break;
1781 case NES_PKT_TYPE_FIN:
1782 handle_fin_pkt(cm_node, skb, tcph);
1783 break;
1784 default: 1890 default:
1785 drop_packet(skb); 1891 drop_packet(skb);
1892 if (fin_set)
1893 handle_fin_pkt(cm_node);
1786 break; 1894 break;
1787 } 1895 }
1788} 1896}
@@ -1925,7 +2033,7 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core,
1925 loopbackremotenode->tcp_cntxt.rcv_wscale; 2033 loopbackremotenode->tcp_cntxt.rcv_wscale;
1926 loopbackremotenode->tcp_cntxt.snd_wscale = 2034 loopbackremotenode->tcp_cntxt.snd_wscale =
1927 cm_node->tcp_cntxt.rcv_wscale; 2035 cm_node->tcp_cntxt.rcv_wscale;
1928 2036 loopbackremotenode->state = NES_CM_STATE_MPAREQ_RCVD;
1929 create_event(loopbackremotenode, NES_CM_EVENT_MPA_REQ); 2037 create_event(loopbackremotenode, NES_CM_EVENT_MPA_REQ);
1930 } 2038 }
1931 return cm_node; 2039 return cm_node;
@@ -1980,7 +2088,11 @@ static int mini_cm_reject(struct nes_cm_core *cm_core,
1980 struct ietf_mpa_frame *mpa_frame, struct nes_cm_node *cm_node) 2088 struct ietf_mpa_frame *mpa_frame, struct nes_cm_node *cm_node)
1981{ 2089{
1982 int ret = 0; 2090 int ret = 0;
2091 int err = 0;
1983 int passive_state; 2092 int passive_state;
2093 struct nes_cm_event event;
2094 struct iw_cm_id *cm_id = cm_node->cm_id;
2095 struct nes_cm_node *loopback = cm_node->loopbackpartner;
1984 2096
1985 nes_debug(NES_DBG_CM, "%s cm_node=%p type=%d state=%d\n", 2097 nes_debug(NES_DBG_CM, "%s cm_node=%p type=%d state=%d\n",
1986 __func__, cm_node, cm_node->tcp_cntxt.client, cm_node->state); 2098 __func__, cm_node, cm_node->tcp_cntxt.client, cm_node->state);
@@ -1989,12 +2101,38 @@ static int mini_cm_reject(struct nes_cm_core *cm_core,
1989 return ret; 2101 return ret;
1990 cleanup_retrans_entry(cm_node); 2102 cleanup_retrans_entry(cm_node);
1991 2103
1992 passive_state = atomic_add_return(1, &cm_node->passive_state); 2104 if (!loopback) {
1993 cm_node->state = NES_CM_STATE_CLOSED; 2105 passive_state = atomic_add_return(1, &cm_node->passive_state);
1994 if (passive_state == NES_SEND_RESET_EVENT) 2106 if (passive_state == NES_SEND_RESET_EVENT) {
2107 cm_node->state = NES_CM_STATE_CLOSED;
2108 rem_ref_cm_node(cm_core, cm_node);
2109 } else {
2110 ret = send_mpa_reject(cm_node);
2111 if (ret) {
2112 cm_node->state = NES_CM_STATE_CLOSED;
2113 err = send_reset(cm_node, NULL);
2114 if (err)
2115 WARN_ON(1);
2116 } else
2117 cm_id->add_ref(cm_id);
2118 }
2119 } else {
2120 cm_node->cm_id = NULL;
2121 event.cm_node = loopback;
2122 event.cm_info.rem_addr = loopback->rem_addr;
2123 event.cm_info.loc_addr = loopback->loc_addr;
2124 event.cm_info.rem_port = loopback->rem_port;
2125 event.cm_info.loc_port = loopback->loc_port;
2126 event.cm_info.cm_id = loopback->cm_id;
2127 cm_event_mpa_reject(&event);
1995 rem_ref_cm_node(cm_core, cm_node); 2128 rem_ref_cm_node(cm_core, cm_node);
1996 else 2129 loopback->state = NES_CM_STATE_CLOSING;
1997 ret = send_reset(cm_node, NULL); 2130
2131 cm_id = loopback->cm_id;
2132 rem_ref_cm_node(cm_core, loopback);
2133 cm_id->rem_ref(cm_id);
2134 }
2135
1998 return ret; 2136 return ret;
1999} 2137}
2000 2138
@@ -2031,6 +2169,7 @@ static int mini_cm_close(struct nes_cm_core *cm_core, struct nes_cm_node *cm_nod
2031 case NES_CM_STATE_CLOSING: 2169 case NES_CM_STATE_CLOSING:
2032 ret = -1; 2170 ret = -1;
2033 break; 2171 break;
2172 case NES_CM_STATE_MPAREJ_RCVD:
2034 case NES_CM_STATE_LISTENING: 2173 case NES_CM_STATE_LISTENING:
2035 case NES_CM_STATE_UNKNOWN: 2174 case NES_CM_STATE_UNKNOWN:
2036 case NES_CM_STATE_INITED: 2175 case NES_CM_STATE_INITED:
@@ -2227,15 +2366,15 @@ static int mini_cm_set(struct nes_cm_core *cm_core, u32 type, u32 value)
2227 int ret = 0; 2366 int ret = 0;
2228 2367
2229 switch (type) { 2368 switch (type) {
2230 case NES_CM_SET_PKT_SIZE: 2369 case NES_CM_SET_PKT_SIZE:
2231 cm_core->mtu = value; 2370 cm_core->mtu = value;
2232 break; 2371 break;
2233 case NES_CM_SET_FREE_PKT_Q_SIZE: 2372 case NES_CM_SET_FREE_PKT_Q_SIZE:
2234 cm_core->free_tx_pkt_max = value; 2373 cm_core->free_tx_pkt_max = value;
2235 break; 2374 break;
2236 default: 2375 default:
2237 /* unknown set option */ 2376 /* unknown set option */
2238 ret = -EINVAL; 2377 ret = -EINVAL;
2239 } 2378 }
2240 2379
2241 return ret; 2380 return ret;
@@ -2654,9 +2793,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2654 NES_QPCONTEXT_ORDIRD_WRPDU); 2793 NES_QPCONTEXT_ORDIRD_WRPDU);
2655 } else { 2794 } else {
2656 nesqp->nesqp_context->ird_ord_sizes |= 2795 nesqp->nesqp_context->ird_ord_sizes |=
2657 cpu_to_le32((NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | 2796 cpu_to_le32(NES_QPCONTEXT_ORDIRD_WRPDU);
2658 NES_QPCONTEXT_ORDIRD_WRPDU |
2659 NES_QPCONTEXT_ORDIRD_ALSMM));
2660 } 2797 }
2661 nesqp->skip_lsmm = 1; 2798 nesqp->skip_lsmm = 1;
2662 2799
@@ -2778,23 +2915,35 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2778int nes_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len) 2915int nes_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len)
2779{ 2916{
2780 struct nes_cm_node *cm_node; 2917 struct nes_cm_node *cm_node;
2918 struct nes_cm_node *loopback;
2919
2781 struct nes_cm_core *cm_core; 2920 struct nes_cm_core *cm_core;
2782 2921
2783 atomic_inc(&cm_rejects); 2922 atomic_inc(&cm_rejects);
2784 cm_node = (struct nes_cm_node *) cm_id->provider_data; 2923 cm_node = (struct nes_cm_node *) cm_id->provider_data;
2924 loopback = cm_node->loopbackpartner;
2785 cm_core = cm_node->cm_core; 2925 cm_core = cm_node->cm_core;
2926 cm_node->cm_id = cm_id;
2786 cm_node->mpa_frame_size = sizeof(struct ietf_mpa_frame) + pdata_len; 2927 cm_node->mpa_frame_size = sizeof(struct ietf_mpa_frame) + pdata_len;
2787 2928
2929 if (cm_node->mpa_frame_size > MAX_CM_BUFFER)
2930 return -EINVAL;
2931
2788 strcpy(&cm_node->mpa_frame.key[0], IEFT_MPA_KEY_REP); 2932 strcpy(&cm_node->mpa_frame.key[0], IEFT_MPA_KEY_REP);
2789 memcpy(&cm_node->mpa_frame.priv_data, pdata, pdata_len); 2933 if (loopback) {
2934 memcpy(&loopback->mpa_frame.priv_data, pdata, pdata_len);
2935 loopback->mpa_frame.priv_data_len = pdata_len;
2936 loopback->mpa_frame_size = sizeof(struct ietf_mpa_frame) +
2937 pdata_len;
2938 } else {
2939 memcpy(&cm_node->mpa_frame.priv_data, pdata, pdata_len);
2940 cm_node->mpa_frame.priv_data_len = cpu_to_be16(pdata_len);
2941 }
2790 2942
2791 cm_node->mpa_frame.priv_data_len = cpu_to_be16(pdata_len);
2792 cm_node->mpa_frame.rev = mpa_version; 2943 cm_node->mpa_frame.rev = mpa_version;
2793 cm_node->mpa_frame.flags = IETF_MPA_FLAGS_CRC | IETF_MPA_FLAGS_REJECT; 2944 cm_node->mpa_frame.flags = IETF_MPA_FLAGS_CRC | IETF_MPA_FLAGS_REJECT;
2794 2945
2795 cm_core->api->reject(cm_core, &cm_node->mpa_frame, cm_node); 2946 return cm_core->api->reject(cm_core, &cm_node->mpa_frame, cm_node);
2796
2797 return 0;
2798} 2947}
2799 2948
2800 2949
@@ -3303,13 +3452,56 @@ static void cm_event_mpa_req(struct nes_cm_event *event)
3303 cm_event.remote_addr.sin_family = AF_INET; 3452 cm_event.remote_addr.sin_family = AF_INET;
3304 cm_event.remote_addr.sin_port = htons(event->cm_info.rem_port); 3453 cm_event.remote_addr.sin_port = htons(event->cm_info.rem_port);
3305 cm_event.remote_addr.sin_addr.s_addr = htonl(event->cm_info.rem_addr); 3454 cm_event.remote_addr.sin_addr.s_addr = htonl(event->cm_info.rem_addr);
3455 cm_event.private_data = cm_node->mpa_frame_buf;
3456 cm_event.private_data_len = (u8) cm_node->mpa_frame_size;
3457
3458 ret = cm_id->event_handler(cm_id, &cm_event);
3459 if (ret)
3460 printk(KERN_ERR "%s[%u] OFA CM event_handler returned, ret=%d\n",
3461 __func__, __LINE__, ret);
3462 return;
3463}
3464
3465
3466static void cm_event_mpa_reject(struct nes_cm_event *event)
3467{
3468 struct iw_cm_id *cm_id;
3469 struct iw_cm_event cm_event;
3470 struct nes_cm_node *cm_node;
3471 int ret;
3472
3473 cm_node = event->cm_node;
3474 if (!cm_node)
3475 return;
3476 cm_id = cm_node->cm_id;
3477
3478 atomic_inc(&cm_connect_reqs);
3479 nes_debug(NES_DBG_CM, "cm_node = %p - cm_id = %p, jiffies = %lu\n",
3480 cm_node, cm_id, jiffies);
3481
3482 cm_event.event = IW_CM_EVENT_CONNECT_REPLY;
3483 cm_event.status = -ECONNREFUSED;
3484 cm_event.provider_data = cm_id->provider_data;
3485
3486 cm_event.local_addr.sin_family = AF_INET;
3487 cm_event.local_addr.sin_port = htons(event->cm_info.loc_port);
3488 cm_event.local_addr.sin_addr.s_addr = htonl(event->cm_info.loc_addr);
3489
3490 cm_event.remote_addr.sin_family = AF_INET;
3491 cm_event.remote_addr.sin_port = htons(event->cm_info.rem_port);
3492 cm_event.remote_addr.sin_addr.s_addr = htonl(event->cm_info.rem_addr);
3306 3493
3307 cm_event.private_data = cm_node->mpa_frame_buf; 3494 cm_event.private_data = cm_node->mpa_frame_buf;
3308 cm_event.private_data_len = (u8) cm_node->mpa_frame_size; 3495 cm_event.private_data_len = (u8) cm_node->mpa_frame_size;
3496
3497 nes_debug(NES_DBG_CM, "call CM_EVENT_MPA_REJECTED, local_addr=%08x, "
3498 "remove_addr=%08x\n",
3499 cm_event.local_addr.sin_addr.s_addr,
3500 cm_event.remote_addr.sin_addr.s_addr);
3309 3501
3310 ret = cm_id->event_handler(cm_id, &cm_event); 3502 ret = cm_id->event_handler(cm_id, &cm_event);
3311 if (ret) 3503 if (ret)
3312 printk("%s[%u] OFA CM event_handler returned, ret=%d\n", 3504 printk(KERN_ERR "%s[%u] OFA CM event_handler returned, ret=%d\n",
3313 __func__, __LINE__, ret); 3505 __func__, __LINE__, ret);
3314 3506
3315 return; 3507 return;
@@ -3374,6 +3566,14 @@ static void nes_cm_event_handler(struct work_struct *work)
3374 cm_event_connected(event); 3566 cm_event_connected(event);
3375 nes_debug(NES_DBG_CM, "CM Event: CONNECTED\n"); 3567 nes_debug(NES_DBG_CM, "CM Event: CONNECTED\n");
3376 break; 3568 break;
3569 case NES_CM_EVENT_MPA_REJECT:
3570 if ((!event->cm_node->cm_id) ||
3571 (event->cm_node->state == NES_CM_STATE_TSA))
3572 break;
3573 cm_event_mpa_reject(event);
3574 nes_debug(NES_DBG_CM, "CM Event: REJECT\n");
3575 break;
3576
3377 case NES_CM_EVENT_ABORTED: 3577 case NES_CM_EVENT_ABORTED:
3378 if ((!event->cm_node->cm_id) || 3578 if ((!event->cm_node->cm_id) ||
3379 (event->cm_node->state == NES_CM_STATE_TSA)) 3579 (event->cm_node->state == NES_CM_STATE_TSA))