aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/nes
diff options
context:
space:
mode:
authorFaisal Latif <faisal.latif@intel.com>2009-03-06 18:15:01 -0500
committerRoland Dreier <rolandd@cisco.com>2009-03-06 18:15:01 -0500
commit9d5ab13325d0bb855cf856946c140a68ceb20e32 (patch)
treec226cba67009db77052aceb1c7bf885da63fa4b8 /drivers/infiniband/hw/nes
parent0145f341a951b998d6d0fa38992a42d2a90b5bab (diff)
RDMA/nes: Handle MPA Reject message properly
While doing testing, there are failures as MPA Reject call is not handled. To handle MPA Reject call, following changes are done: *Handle inbound/outbound MPA Reject response message. When nes_reject() is called for pending MPA request reply, send the MPA Reject message to its peer (active side)cm_node. The peer cm_node (active side) will indicate Reject message event for the pending Connect Request. *Handle MPA Reject response message for loopback connections and listener. When MPA Request is rejected, check if it is a loopback connection and if it is then it will send Reject message event to its peer loopback node. Also when destroying listener, check if the cm_nodes for that listener are loopback or not. *Add gracefull connection close with the MPA Reject response message. Send gracefull close (FIN, FIN ACK..) to terminate the cm_nodes. *Some code re-org while making the above changes. Removed recv_list and recv_list_lock from the cm_node structure as there can be only one receive close entry on the timer. Also implemented handle_recv_entry() as receive close entry is processed from both nes_rem_ref_cm_node() as well as nes_cm_timer_tick(). Signed-off-by: Faisal Latif <faisal.latif@intel.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/nes')
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c580
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.h10
2 files changed, 399 insertions, 191 deletions
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index bd918df3d22c..5327f2bec6bf 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -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);
@@ -871,7 +917,8 @@ static int add_hte_node(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node
871static 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,
872 struct nes_cm_listener *listener, int free_hanging_nodes) 918 struct nes_cm_listener *listener, int free_hanging_nodes)
873{ 919{
874 int ret = 1; 920 int ret = -EINVAL;
921 int err = 0;
875 unsigned long flags; 922 unsigned long flags;
876 struct list_head *list_pos = NULL; 923 struct list_head *list_pos = NULL;
877 struct list_head *list_temp = NULL; 924 struct list_head *list_temp = NULL;
@@ -900,10 +947,60 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
900 947
901 list_for_each_safe(list_pos, list_temp, &reset_list) { 948 list_for_each_safe(list_pos, list_temp, &reset_list) {
902 cm_node = container_of(list_pos, struct nes_cm_node, 949 cm_node = container_of(list_pos, struct nes_cm_node,
903 reset_entry); 950 reset_entry);
904 cleanup_retrans_entry(cm_node); 951 {
905 send_reset(cm_node, NULL); 952 struct nes_cm_node *loopback = cm_node->loopbackpartner;
906 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 }
907 } 1004 }
908 1005
909 spin_lock_irqsave(&cm_core->listen_list_lock, flags); 1006 spin_lock_irqsave(&cm_core->listen_list_lock, flags);
@@ -964,6 +1061,7 @@ static inline int mini_cm_accelerated(struct nes_cm_core *cm_core,
964 if (cm_node->accept_pend) { 1061 if (cm_node->accept_pend) {
965 BUG_ON(!cm_node->listener); 1062 BUG_ON(!cm_node->listener);
966 atomic_dec(&cm_node->listener->pend_accepts_cnt); 1063 atomic_dec(&cm_node->listener->pend_accepts_cnt);
1064 cm_node->accept_pend = 0;
967 BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0); 1065 BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0);
968 } 1066 }
969 1067
@@ -990,7 +1088,7 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip)
990 memset(&fl, 0, sizeof fl); 1088 memset(&fl, 0, sizeof fl);
991 fl.nl_u.ip4_u.daddr = htonl(dst_ip); 1089 fl.nl_u.ip4_u.daddr = htonl(dst_ip);
992 if (ip_route_output_key(&init_net, &rt, &fl)) { 1090 if (ip_route_output_key(&init_net, &rt, &fl)) {
993 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",
994 __func__, dst_ip); 1092 __func__, dst_ip);
995 return rc; 1093 return rc;
996 } 1094 }
@@ -1053,8 +1151,6 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
1053 cm_node->cm_id); 1151 cm_node->cm_id);
1054 1152
1055 spin_lock_init(&cm_node->retrans_list_lock); 1153 spin_lock_init(&cm_node->retrans_list_lock);
1056 INIT_LIST_HEAD(&cm_node->recv_list);
1057 spin_lock_init(&cm_node->recv_list_lock);
1058 1154
1059 cm_node->loopbackpartner = NULL; 1155 cm_node->loopbackpartner = NULL;
1060 atomic_set(&cm_node->ref_count, 1); 1156 atomic_set(&cm_node->ref_count, 1);
@@ -1122,10 +1218,7 @@ static int add_ref_cm_node(struct nes_cm_node *cm_node)
1122static int rem_ref_cm_node(struct nes_cm_core *cm_core, 1218static int rem_ref_cm_node(struct nes_cm_core *cm_core,
1123 struct nes_cm_node *cm_node) 1219 struct nes_cm_node *cm_node)
1124{ 1220{
1125 unsigned long flags, qplockflags; 1221 unsigned long flags;
1126 struct nes_timer_entry *recv_entry;
1127 struct iw_cm_id *cm_id;
1128 struct list_head *list_core, *list_node_temp;
1129 struct nes_qp *nesqp; 1222 struct nes_qp *nesqp;
1130 1223
1131 if (!cm_node) 1224 if (!cm_node)
@@ -1146,38 +1239,9 @@ static int rem_ref_cm_node(struct nes_cm_core *cm_core,
1146 atomic_dec(&cm_node->listener->pend_accepts_cnt); 1239 atomic_dec(&cm_node->listener->pend_accepts_cnt);
1147 BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0); 1240 BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0);
1148 } 1241 }
1149 BUG_ON(cm_node->send_entry); 1242 WARN_ON(cm_node->send_entry);
1150 spin_lock_irqsave(&cm_node->recv_list_lock, flags); 1243 if (cm_node->recv_entry)
1151 list_for_each_safe(list_core, list_node_temp, &cm_node->recv_list) { 1244 handle_recv_entry(cm_node, 0);
1152 recv_entry = container_of(list_core, struct nes_timer_entry,
1153 list);
1154 list_del(&recv_entry->list);
1155 cm_id = cm_node->cm_id;
1156 spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
1157 nesqp = (struct nes_qp *)recv_entry->skb;
1158 spin_lock_irqsave(&nesqp->lock, qplockflags);
1159 if (nesqp->cm_id) {
1160 nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: HIT A "
1161 "NES_TIMER_TYPE_CLOSE with something to do!\n",
1162 nesqp->hwqp.qp_id, cm_id);
1163 nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
1164 nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT;
1165 nesqp->ibqp_state = IB_QPS_ERR;
1166 spin_unlock_irqrestore(&nesqp->lock, qplockflags);
1167 nes_cm_disconn(nesqp);
1168 } else {
1169 spin_unlock_irqrestore(&nesqp->lock, qplockflags);
1170 nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: HIT A "
1171 "NES_TIMER_TYPE_CLOSE with nothing to do!\n",
1172 nesqp->hwqp.qp_id, cm_id);
1173 }
1174 cm_id->rem_ref(cm_id);
1175
1176 kfree(recv_entry);
1177 spin_lock_irqsave(&cm_node->recv_list_lock, flags);
1178 }
1179 spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
1180
1181 if (cm_node->listener) { 1245 if (cm_node->listener) {
1182 mini_cm_dec_refcnt_listen(cm_core, cm_node->listener, 0); 1246 mini_cm_dec_refcnt_listen(cm_core, cm_node->listener, 0);
1183 } else { 1247 } else {
@@ -1262,8 +1326,7 @@ static void drop_packet(struct sk_buff *skb)
1262 dev_kfree_skb_any(skb); 1326 dev_kfree_skb_any(skb);
1263} 1327}
1264 1328
1265static 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)
1266 struct tcphdr *tcph)
1267{ 1330{
1268 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. "
1269 "refcnt=%d\n", cm_node, cm_node->state, 1332 "refcnt=%d\n", cm_node, cm_node->state,
@@ -1275,23 +1338,30 @@ static void handle_fin_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1275 case NES_CM_STATE_SYN_SENT: 1338 case NES_CM_STATE_SYN_SENT:
1276 case NES_CM_STATE_ESTABLISHED: 1339 case NES_CM_STATE_ESTABLISHED:
1277 case NES_CM_STATE_MPAREQ_SENT: 1340 case NES_CM_STATE_MPAREQ_SENT:
1341 case NES_CM_STATE_MPAREJ_RCVD:
1278 cm_node->state = NES_CM_STATE_LAST_ACK; 1342 cm_node->state = NES_CM_STATE_LAST_ACK;
1279 send_fin(cm_node, skb); 1343 send_fin(cm_node, NULL);
1280 break; 1344 break;
1281 case NES_CM_STATE_FIN_WAIT1: 1345 case NES_CM_STATE_FIN_WAIT1:
1282 cm_node->state = NES_CM_STATE_CLOSING; 1346 cm_node->state = NES_CM_STATE_CLOSING;
1283 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.. */
1284 break; 1351 break;
1285 case NES_CM_STATE_FIN_WAIT2: 1352 case NES_CM_STATE_FIN_WAIT2:
1286 cm_node->state = NES_CM_STATE_TIME_WAIT; 1353 cm_node->state = NES_CM_STATE_TIME_WAIT;
1287 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:
1288 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);
1289 break; 1360 break;
1290 case NES_CM_STATE_TSA: 1361 case NES_CM_STATE_TSA:
1291 default: 1362 default:
1292 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",
1293 cm_node, cm_node->state); 1364 cm_node, cm_node->state);
1294 drop_packet(skb);
1295 break; 1365 break;
1296 } 1366 }
1297} 1367}
@@ -1337,23 +1407,35 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1337 cleanup_retrans_entry(cm_node); 1407 cleanup_retrans_entry(cm_node);
1338 drop_packet(skb); 1408 drop_packet(skb);
1339 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__);
1340 default: 1419 default:
1341 drop_packet(skb); 1420 drop_packet(skb);
1342 break; 1421 break;
1343 } 1422 }
1344} 1423}
1345 1424
1346static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb, 1425
1347 enum nes_cm_event_type type) 1426static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb)
1348{ 1427{
1349 1428
1350 int ret; 1429 int ret = 0;
1351 int datasize = skb->len; 1430 int datasize = skb->len;
1352 u8 *dataloc = skb->data; 1431 u8 *dataloc = skb->data;
1353 ret = parse_mpa(cm_node, dataloc, datasize); 1432
1354 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) {
1355 nes_debug(NES_DBG_CM, "didn't like MPA Request\n"); 1437 nes_debug(NES_DBG_CM, "didn't like MPA Request\n");
1356 if (type == NES_CM_EVENT_CONNECTED) { 1438 if (cm_node->state == NES_CM_STATE_MPAREQ_SENT) {
1357 nes_debug(NES_DBG_CM, "%s[%u] create abort for " 1439 nes_debug(NES_DBG_CM, "%s[%u] create abort for "
1358 "cm_node=%p listener=%p state=%d\n", __func__, 1440 "cm_node=%p listener=%p state=%d\n", __func__,
1359 __LINE__, cm_node, cm_node->listener, 1441 __LINE__, cm_node, cm_node->listener,
@@ -1362,18 +1444,38 @@ static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb,
1362 } else { 1444 } else {
1363 passive_open_err(cm_node, skb, 1); 1445 passive_open_err(cm_node, skb, 1);
1364 } 1446 }
1365 } else { 1447 return;
1366 cleanup_retrans_entry(cm_node); 1448 }
1367 dev_kfree_skb_any(skb); 1449
1368 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;
1369 cm_node->state = NES_CM_STATE_TSA; 1469 cm_node->state = NES_CM_STATE_TSA;
1370 else 1470 }
1371 atomic_set(&cm_node->passive_state,
1372 NES_PASSIVE_STATE_INDICATED);
1373 create_event(cm_node, type);
1374 1471
1472 break;
1473 default:
1474 WARN_ON(1);
1475 break;
1375 } 1476 }
1376 return ; 1477 dev_kfree_skb_any(skb);
1478 create_event(cm_node, type);
1377} 1479}
1378 1480
1379static 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)
@@ -1461,8 +1563,6 @@ static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1461 break; 1563 break;
1462 case NES_CM_STATE_LISTENING: 1564 case NES_CM_STATE_LISTENING:
1463 /* Passive OPEN */ 1565 /* Passive OPEN */
1464 cm_node->accept_pend = 1;
1465 atomic_inc(&cm_node->listener->pend_accepts_cnt);
1466 if (atomic_read(&cm_node->listener->pend_accepts_cnt) > 1566 if (atomic_read(&cm_node->listener->pend_accepts_cnt) >
1467 cm_node->listener->backlog) { 1567 cm_node->listener->backlog) {
1468 nes_debug(NES_DBG_CM, "drop syn due to backlog " 1568 nes_debug(NES_DBG_CM, "drop syn due to backlog "
@@ -1480,6 +1580,9 @@ static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1480 } 1580 }
1481 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + 1; 1581 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + 1;
1482 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
1483 cm_node->state = NES_CM_STATE_SYN_RCVD; 1586 cm_node->state = NES_CM_STATE_SYN_RCVD;
1484 send_syn(cm_node, 1, skb); 1587 send_syn(cm_node, 1, skb);
1485 break; 1588 break;
@@ -1514,6 +1617,7 @@ static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1514 inc_sequence = ntohl(tcph->seq); 1617 inc_sequence = ntohl(tcph->seq);
1515 switch (cm_node->state) { 1618 switch (cm_node->state) {
1516 case NES_CM_STATE_SYN_SENT: 1619 case NES_CM_STATE_SYN_SENT:
1620 cleanup_retrans_entry(cm_node);
1517 /* active open */ 1621 /* active open */
1518 if (check_syn(cm_node, tcph, skb)) 1622 if (check_syn(cm_node, tcph, skb))
1519 return; 1623 return;
@@ -1563,10 +1667,7 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1563 u32 rem_seq; 1667 u32 rem_seq;
1564 int ret; 1668 int ret;
1565 int optionsize; 1669 int optionsize;
1566 u32 temp_seq = cm_node->tcp_cntxt.loc_seq_num;
1567
1568 optionsize = (tcph->doff << 2) - sizeof(struct tcphdr); 1670 optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
1569 cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
1570 1671
1571 if (check_seq(cm_node, tcph, skb)) 1672 if (check_seq(cm_node, tcph, skb))
1572 return; 1673 return;
@@ -1576,7 +1677,7 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1576 rem_seq = ntohl(tcph->seq); 1677 rem_seq = ntohl(tcph->seq);
1577 rem_seq_ack = ntohl(tcph->ack_seq); 1678 rem_seq_ack = ntohl(tcph->ack_seq);
1578 datasize = skb->len; 1679 datasize = skb->len;
1579 1680 cleanup_retrans_entry(cm_node);
1580 switch (cm_node->state) { 1681 switch (cm_node->state) {
1581 case NES_CM_STATE_SYN_RCVD: 1682 case NES_CM_STATE_SYN_RCVD:
1582 /* Passive OPEN */ 1683 /* Passive OPEN */
@@ -1584,7 +1685,6 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1584 if (ret) 1685 if (ret)
1585 break; 1686 break;
1586 cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); 1687 cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
1587 cm_node->tcp_cntxt.loc_seq_num = temp_seq;
1588 if (cm_node->tcp_cntxt.rem_ack_num != 1688 if (cm_node->tcp_cntxt.rem_ack_num !=
1589 cm_node->tcp_cntxt.loc_seq_num) { 1689 cm_node->tcp_cntxt.loc_seq_num) {
1590 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");
@@ -1593,31 +1693,30 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1593 return; 1693 return;
1594 } 1694 }
1595 cm_node->state = NES_CM_STATE_ESTABLISHED; 1695 cm_node->state = NES_CM_STATE_ESTABLISHED;
1696 cleanup_retrans_entry(cm_node);
1596 if (datasize) { 1697 if (datasize) {
1597 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; 1698 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
1598 cm_node->state = NES_CM_STATE_MPAREQ_RCVD; 1699 handle_rcv_mpa(cm_node, skb);
1599 handle_rcv_mpa(cm_node, skb, NES_CM_EVENT_MPA_REQ); 1700 } else { /* rcvd ACK only */
1600 } else { /* rcvd ACK only */
1601 dev_kfree_skb_any(skb); 1701 dev_kfree_skb_any(skb);
1602 cleanup_retrans_entry(cm_node); 1702 cleanup_retrans_entry(cm_node);
1603 } 1703 }
1604 break; 1704 break;
1605 case NES_CM_STATE_ESTABLISHED: 1705 case NES_CM_STATE_ESTABLISHED:
1606 /* Passive OPEN */ 1706 /* Passive OPEN */
1607 /* We expect mpa frame to be received only */ 1707 cleanup_retrans_entry(cm_node);
1608 if (datasize) { 1708 if (datasize) {
1609 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; 1709 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
1610 cm_node->state = NES_CM_STATE_MPAREQ_RCVD; 1710 handle_rcv_mpa(cm_node, skb);
1611 handle_rcv_mpa(cm_node, skb,
1612 NES_CM_EVENT_MPA_REQ);
1613 } else 1711 } else
1614 drop_packet(skb); 1712 drop_packet(skb);
1615 break; 1713 break;
1616 case NES_CM_STATE_MPAREQ_SENT: 1714 case NES_CM_STATE_MPAREQ_SENT:
1715 cleanup_retrans_entry(cm_node);
1617 cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); 1716 cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
1618 if (datasize) { 1717 if (datasize) {
1619 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; 1718 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
1620 handle_rcv_mpa(cm_node, skb, NES_CM_EVENT_CONNECTED); 1719 handle_rcv_mpa(cm_node, skb);
1621 } else { /* Could be just an ack pkt.. */ 1720 } else { /* Could be just an ack pkt.. */
1622 cleanup_retrans_entry(cm_node); 1721 cleanup_retrans_entry(cm_node);
1623 dev_kfree_skb_any(skb); 1722 dev_kfree_skb_any(skb);
@@ -1628,13 +1727,24 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1628 cleanup_retrans_entry(cm_node); 1727 cleanup_retrans_entry(cm_node);
1629 send_reset(cm_node, skb); 1728 send_reset(cm_node, skb);
1630 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;
1631 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;
1632 case NES_CM_STATE_SYN_SENT: 1744 case NES_CM_STATE_SYN_SENT:
1633 case NES_CM_STATE_FIN_WAIT2: 1745 case NES_CM_STATE_FIN_WAIT2:
1634 case NES_CM_STATE_TSA: 1746 case NES_CM_STATE_TSA:
1635 case NES_CM_STATE_MPAREQ_RCVD: 1747 case NES_CM_STATE_MPAREQ_RCVD:
1636 case NES_CM_STATE_LAST_ACK:
1637 case NES_CM_STATE_CLOSING:
1638 case NES_CM_STATE_UNKNOWN: 1748 case NES_CM_STATE_UNKNOWN:
1639 default: 1749 default:
1640 drop_packet(skb); 1750 drop_packet(skb);
@@ -1744,6 +1854,7 @@ static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
1744{ 1854{
1745 enum nes_tcpip_pkt_type pkt_type = NES_PKT_TYPE_UNKNOWN; 1855 enum nes_tcpip_pkt_type pkt_type = NES_PKT_TYPE_UNKNOWN;
1746 struct tcphdr *tcph = tcp_hdr(skb); 1856 struct tcphdr *tcph = tcp_hdr(skb);
1857 u32 fin_set = 0;
1747 skb_pull(skb, ip_hdr(skb)->ihl << 2); 1858 skb_pull(skb, ip_hdr(skb)->ihl << 2);
1748 1859
1749 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 "
@@ -1756,10 +1867,10 @@ static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
1756 pkt_type = NES_PKT_TYPE_SYN; 1867 pkt_type = NES_PKT_TYPE_SYN;
1757 if (tcph->ack) 1868 if (tcph->ack)
1758 pkt_type = NES_PKT_TYPE_SYNACK; 1869 pkt_type = NES_PKT_TYPE_SYNACK;
1759 } else if (tcph->fin) 1870 } else if (tcph->ack)
1760 pkt_type = NES_PKT_TYPE_FIN;
1761 else if (tcph->ack)
1762 pkt_type = NES_PKT_TYPE_ACK; 1871 pkt_type = NES_PKT_TYPE_ACK;
1872 if (tcph->fin)
1873 fin_set = 1;
1763 1874
1764 switch (pkt_type) { 1875 switch (pkt_type) {
1765 case NES_PKT_TYPE_SYN: 1876 case NES_PKT_TYPE_SYN:
@@ -1770,15 +1881,16 @@ static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
1770 break; 1881 break;
1771 case NES_PKT_TYPE_ACK: 1882 case NES_PKT_TYPE_ACK:
1772 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);
1773 break; 1886 break;
1774 case NES_PKT_TYPE_RST: 1887 case NES_PKT_TYPE_RST:
1775 handle_rst_pkt(cm_node, skb, tcph); 1888 handle_rst_pkt(cm_node, skb, tcph);
1776 break; 1889 break;
1777 case NES_PKT_TYPE_FIN:
1778 handle_fin_pkt(cm_node, skb, tcph);
1779 break;
1780 default: 1890 default:
1781 drop_packet(skb); 1891 drop_packet(skb);
1892 if (fin_set)
1893 handle_fin_pkt(cm_node);
1782 break; 1894 break;
1783 } 1895 }
1784} 1896}
@@ -1921,7 +2033,7 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core,
1921 loopbackremotenode->tcp_cntxt.rcv_wscale; 2033 loopbackremotenode->tcp_cntxt.rcv_wscale;
1922 loopbackremotenode->tcp_cntxt.snd_wscale = 2034 loopbackremotenode->tcp_cntxt.snd_wscale =
1923 cm_node->tcp_cntxt.rcv_wscale; 2035 cm_node->tcp_cntxt.rcv_wscale;
1924 2036 loopbackremotenode->state = NES_CM_STATE_MPAREQ_RCVD;
1925 create_event(loopbackremotenode, NES_CM_EVENT_MPA_REQ); 2037 create_event(loopbackremotenode, NES_CM_EVENT_MPA_REQ);
1926 } 2038 }
1927 return cm_node; 2039 return cm_node;
@@ -1976,7 +2088,11 @@ static int mini_cm_reject(struct nes_cm_core *cm_core,
1976 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)
1977{ 2089{
1978 int ret = 0; 2090 int ret = 0;
2091 int err = 0;
1979 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;
1980 2096
1981 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",
1982 __func__, cm_node, cm_node->tcp_cntxt.client, cm_node->state); 2098 __func__, cm_node, cm_node->tcp_cntxt.client, cm_node->state);
@@ -1985,12 +2101,38 @@ static int mini_cm_reject(struct nes_cm_core *cm_core,
1985 return ret; 2101 return ret;
1986 cleanup_retrans_entry(cm_node); 2102 cleanup_retrans_entry(cm_node);
1987 2103
1988 passive_state = atomic_add_return(1, &cm_node->passive_state); 2104 if (!loopback) {
1989 cm_node->state = NES_CM_STATE_CLOSED; 2105 passive_state = atomic_add_return(1, &cm_node->passive_state);
1990 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);
1991 rem_ref_cm_node(cm_core, cm_node); 2128 rem_ref_cm_node(cm_core, cm_node);
1992 else 2129 loopback->state = NES_CM_STATE_CLOSING;
1993 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
1994 return ret; 2136 return ret;
1995} 2137}
1996 2138
@@ -2027,6 +2169,7 @@ static int mini_cm_close(struct nes_cm_core *cm_core, struct nes_cm_node *cm_nod
2027 case NES_CM_STATE_CLOSING: 2169 case NES_CM_STATE_CLOSING:
2028 ret = -1; 2170 ret = -1;
2029 break; 2171 break;
2172 case NES_CM_STATE_MPAREJ_RCVD:
2030 case NES_CM_STATE_LISTENING: 2173 case NES_CM_STATE_LISTENING:
2031 case NES_CM_STATE_UNKNOWN: 2174 case NES_CM_STATE_UNKNOWN:
2032 case NES_CM_STATE_INITED: 2175 case NES_CM_STATE_INITED:
@@ -2223,15 +2366,15 @@ static int mini_cm_set(struct nes_cm_core *cm_core, u32 type, u32 value)
2223 int ret = 0; 2366 int ret = 0;
2224 2367
2225 switch (type) { 2368 switch (type) {
2226 case NES_CM_SET_PKT_SIZE: 2369 case NES_CM_SET_PKT_SIZE:
2227 cm_core->mtu = value; 2370 cm_core->mtu = value;
2228 break; 2371 break;
2229 case NES_CM_SET_FREE_PKT_Q_SIZE: 2372 case NES_CM_SET_FREE_PKT_Q_SIZE:
2230 cm_core->free_tx_pkt_max = value; 2373 cm_core->free_tx_pkt_max = value;
2231 break; 2374 break;
2232 default: 2375 default:
2233 /* unknown set option */ 2376 /* unknown set option */
2234 ret = -EINVAL; 2377 ret = -EINVAL;
2235 } 2378 }
2236 2379
2237 return ret; 2380 return ret;
@@ -2621,9 +2764,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2621 NES_QPCONTEXT_ORDIRD_WRPDU); 2764 NES_QPCONTEXT_ORDIRD_WRPDU);
2622 } else { 2765 } else {
2623 nesqp->nesqp_context->ird_ord_sizes |= 2766 nesqp->nesqp_context->ird_ord_sizes |=
2624 cpu_to_le32((NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | 2767 cpu_to_le32(NES_QPCONTEXT_ORDIRD_WRPDU);
2625 NES_QPCONTEXT_ORDIRD_WRPDU |
2626 NES_QPCONTEXT_ORDIRD_ALSMM));
2627 } 2768 }
2628 nesqp->skip_lsmm = 1; 2769 nesqp->skip_lsmm = 1;
2629 2770
@@ -2745,23 +2886,35 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2745int nes_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len) 2886int nes_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len)
2746{ 2887{
2747 struct nes_cm_node *cm_node; 2888 struct nes_cm_node *cm_node;
2889 struct nes_cm_node *loopback;
2890
2748 struct nes_cm_core *cm_core; 2891 struct nes_cm_core *cm_core;
2749 2892
2750 atomic_inc(&cm_rejects); 2893 atomic_inc(&cm_rejects);
2751 cm_node = (struct nes_cm_node *) cm_id->provider_data; 2894 cm_node = (struct nes_cm_node *) cm_id->provider_data;
2895 loopback = cm_node->loopbackpartner;
2752 cm_core = cm_node->cm_core; 2896 cm_core = cm_node->cm_core;
2897 cm_node->cm_id = cm_id;
2753 cm_node->mpa_frame_size = sizeof(struct ietf_mpa_frame) + pdata_len; 2898 cm_node->mpa_frame_size = sizeof(struct ietf_mpa_frame) + pdata_len;
2754 2899
2900 if (cm_node->mpa_frame_size > MAX_CM_BUFFER)
2901 return -EINVAL;
2902
2755 strcpy(&cm_node->mpa_frame.key[0], IEFT_MPA_KEY_REP); 2903 strcpy(&cm_node->mpa_frame.key[0], IEFT_MPA_KEY_REP);
2756 memcpy(&cm_node->mpa_frame.priv_data, pdata, pdata_len); 2904 if (loopback) {
2905 memcpy(&loopback->mpa_frame.priv_data, pdata, pdata_len);
2906 loopback->mpa_frame.priv_data_len = pdata_len;
2907 loopback->mpa_frame_size = sizeof(struct ietf_mpa_frame) +
2908 pdata_len;
2909 } else {
2910 memcpy(&cm_node->mpa_frame.priv_data, pdata, pdata_len);
2911 cm_node->mpa_frame.priv_data_len = cpu_to_be16(pdata_len);
2912 }
2757 2913
2758 cm_node->mpa_frame.priv_data_len = cpu_to_be16(pdata_len);
2759 cm_node->mpa_frame.rev = mpa_version; 2914 cm_node->mpa_frame.rev = mpa_version;
2760 cm_node->mpa_frame.flags = IETF_MPA_FLAGS_CRC | IETF_MPA_FLAGS_REJECT; 2915 cm_node->mpa_frame.flags = IETF_MPA_FLAGS_CRC | IETF_MPA_FLAGS_REJECT;
2761 2916
2762 cm_core->api->reject(cm_core, &cm_node->mpa_frame, cm_node); 2917 return cm_core->api->reject(cm_core, &cm_node->mpa_frame, cm_node);
2763
2764 return 0;
2765} 2918}
2766 2919
2767 2920
@@ -3270,13 +3423,56 @@ static void cm_event_mpa_req(struct nes_cm_event *event)
3270 cm_event.remote_addr.sin_family = AF_INET; 3423 cm_event.remote_addr.sin_family = AF_INET;
3271 cm_event.remote_addr.sin_port = htons(event->cm_info.rem_port); 3424 cm_event.remote_addr.sin_port = htons(event->cm_info.rem_port);
3272 cm_event.remote_addr.sin_addr.s_addr = htonl(event->cm_info.rem_addr); 3425 cm_event.remote_addr.sin_addr.s_addr = htonl(event->cm_info.rem_addr);
3426 cm_event.private_data = cm_node->mpa_frame_buf;
3427 cm_event.private_data_len = (u8) cm_node->mpa_frame_size;
3428
3429 ret = cm_id->event_handler(cm_id, &cm_event);
3430 if (ret)
3431 printk(KERN_ERR "%s[%u] OFA CM event_handler returned, ret=%d\n",
3432 __func__, __LINE__, ret);
3433 return;
3434}
3435
3436
3437static void cm_event_mpa_reject(struct nes_cm_event *event)
3438{
3439 struct iw_cm_id *cm_id;
3440 struct iw_cm_event cm_event;
3441 struct nes_cm_node *cm_node;
3442 int ret;
3443
3444 cm_node = event->cm_node;
3445 if (!cm_node)
3446 return;
3447 cm_id = cm_node->cm_id;
3448
3449 atomic_inc(&cm_connect_reqs);
3450 nes_debug(NES_DBG_CM, "cm_node = %p - cm_id = %p, jiffies = %lu\n",
3451 cm_node, cm_id, jiffies);
3452
3453 cm_event.event = IW_CM_EVENT_CONNECT_REPLY;
3454 cm_event.status = -ECONNREFUSED;
3455 cm_event.provider_data = cm_id->provider_data;
3456
3457 cm_event.local_addr.sin_family = AF_INET;
3458 cm_event.local_addr.sin_port = htons(event->cm_info.loc_port);
3459 cm_event.local_addr.sin_addr.s_addr = htonl(event->cm_info.loc_addr);
3460
3461 cm_event.remote_addr.sin_family = AF_INET;
3462 cm_event.remote_addr.sin_port = htons(event->cm_info.rem_port);
3463 cm_event.remote_addr.sin_addr.s_addr = htonl(event->cm_info.rem_addr);
3273 3464
3274 cm_event.private_data = cm_node->mpa_frame_buf; 3465 cm_event.private_data = cm_node->mpa_frame_buf;
3275 cm_event.private_data_len = (u8) cm_node->mpa_frame_size; 3466 cm_event.private_data_len = (u8) cm_node->mpa_frame_size;
3467
3468 nes_debug(NES_DBG_CM, "call CM_EVENT_MPA_REJECTED, local_addr=%08x, "
3469 "remove_addr=%08x\n",
3470 cm_event.local_addr.sin_addr.s_addr,
3471 cm_event.remote_addr.sin_addr.s_addr);
3276 3472
3277 ret = cm_id->event_handler(cm_id, &cm_event); 3473 ret = cm_id->event_handler(cm_id, &cm_event);
3278 if (ret) 3474 if (ret)
3279 printk("%s[%u] OFA CM event_handler returned, ret=%d\n", 3475 printk(KERN_ERR "%s[%u] OFA CM event_handler returned, ret=%d\n",
3280 __func__, __LINE__, ret); 3476 __func__, __LINE__, ret);
3281 3477
3282 return; 3478 return;
@@ -3341,6 +3537,14 @@ static void nes_cm_event_handler(struct work_struct *work)
3341 cm_event_connected(event); 3537 cm_event_connected(event);
3342 nes_debug(NES_DBG_CM, "CM Event: CONNECTED\n"); 3538 nes_debug(NES_DBG_CM, "CM Event: CONNECTED\n");
3343 break; 3539 break;
3540 case NES_CM_EVENT_MPA_REJECT:
3541 if ((!event->cm_node->cm_id) ||
3542 (event->cm_node->state == NES_CM_STATE_TSA))
3543 break;
3544 cm_event_mpa_reject(event);
3545 nes_debug(NES_DBG_CM, "CM Event: REJECT\n");
3546 break;
3547
3344 case NES_CM_EVENT_ABORTED: 3548 case NES_CM_EVENT_ABORTED:
3345 if ((!event->cm_node->cm_id) || 3549 if ((!event->cm_node->cm_id) ||
3346 (event->cm_node->state == NES_CM_STATE_TSA)) 3550 (event->cm_node->state == NES_CM_STATE_TSA))
diff --git a/drivers/infiniband/hw/nes/nes_cm.h b/drivers/infiniband/hw/nes/nes_cm.h
index 4ab2bebf12ac..d5f778202eb7 100644
--- a/drivers/infiniband/hw/nes/nes_cm.h
+++ b/drivers/infiniband/hw/nes/nes_cm.h
@@ -39,6 +39,9 @@
39#define NES_MANAGE_APBVT_DEL 0 39#define NES_MANAGE_APBVT_DEL 0
40#define NES_MANAGE_APBVT_ADD 1 40#define NES_MANAGE_APBVT_ADD 1
41 41
42#define NES_MPA_REQUEST_ACCEPT 1
43#define NES_MPA_REQUEST_REJECT 2
44
42/* IETF MPA -- defines, enums, structs */ 45/* IETF MPA -- defines, enums, structs */
43#define IEFT_MPA_KEY_REQ "MPA ID Req Frame" 46#define IEFT_MPA_KEY_REQ "MPA ID Req Frame"
44#define IEFT_MPA_KEY_REP "MPA ID Rep Frame" 47#define IEFT_MPA_KEY_REP "MPA ID Rep Frame"
@@ -186,6 +189,7 @@ enum nes_cm_node_state {
186 NES_CM_STATE_ACCEPTING, 189 NES_CM_STATE_ACCEPTING,
187 NES_CM_STATE_MPAREQ_SENT, 190 NES_CM_STATE_MPAREQ_SENT,
188 NES_CM_STATE_MPAREQ_RCVD, 191 NES_CM_STATE_MPAREQ_RCVD,
192 NES_CM_STATE_MPAREJ_RCVD,
189 NES_CM_STATE_TSA, 193 NES_CM_STATE_TSA,
190 NES_CM_STATE_FIN_WAIT1, 194 NES_CM_STATE_FIN_WAIT1,
191 NES_CM_STATE_FIN_WAIT2, 195 NES_CM_STATE_FIN_WAIT2,
@@ -278,13 +282,12 @@ struct nes_cm_node {
278 struct nes_timer_entry *send_entry; 282 struct nes_timer_entry *send_entry;
279 283
280 spinlock_t retrans_list_lock; 284 spinlock_t retrans_list_lock;
281 struct list_head recv_list; 285 struct nes_timer_entry *recv_entry;
282 spinlock_t recv_list_lock;
283 286
284 int send_write0; 287 int send_write0;
285 union { 288 union {
286 struct ietf_mpa_frame mpa_frame; 289 struct ietf_mpa_frame mpa_frame;
287 u8 mpa_frame_buf[NES_CM_DEFAULT_MTU]; 290 u8 mpa_frame_buf[MAX_CM_BUFFER];
288 }; 291 };
289 u16 mpa_frame_size; 292 u16 mpa_frame_size;
290 struct iw_cm_id *cm_id; 293 struct iw_cm_id *cm_id;
@@ -326,6 +329,7 @@ enum nes_cm_event_type {
326 NES_CM_EVENT_MPA_REQ, 329 NES_CM_EVENT_MPA_REQ,
327 NES_CM_EVENT_MPA_CONNECT, 330 NES_CM_EVENT_MPA_CONNECT,
328 NES_CM_EVENT_MPA_ACCEPT, 331 NES_CM_EVENT_MPA_ACCEPT,
332 NES_CM_EVENT_MPA_REJECT,
329 NES_CM_EVENT_MPA_ESTABLISHED, 333 NES_CM_EVENT_MPA_ESTABLISHED,
330 NES_CM_EVENT_CONNECTED, 334 NES_CM_EVENT_CONNECTED,
331 NES_CM_EVENT_CLOSED, 335 NES_CM_EVENT_CLOSED,