diff options
Diffstat (limited to 'drivers/infiniband/hw/nes/nes_cm.c')
-rw-r--r-- | drivers/infiniband/hw/nes/nes_cm.c | 279 |
1 files changed, 145 insertions, 134 deletions
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 2854a6f7fdfe..a812db243477 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c | |||
@@ -86,15 +86,14 @@ static int mini_cm_accept(struct nes_cm_core *, struct ietf_mpa_frame *, | |||
86 | struct nes_cm_node *); | 86 | struct nes_cm_node *); |
87 | static int mini_cm_reject(struct nes_cm_core *, struct ietf_mpa_frame *, | 87 | static int mini_cm_reject(struct nes_cm_core *, struct ietf_mpa_frame *, |
88 | struct nes_cm_node *); | 88 | struct nes_cm_node *); |
89 | static void mini_cm_recv_pkt(struct nes_cm_core *, struct nes_vnic *, | 89 | static int mini_cm_recv_pkt(struct nes_cm_core *, struct nes_vnic *, |
90 | struct sk_buff *); | 90 | struct sk_buff *); |
91 | static int mini_cm_dealloc_core(struct nes_cm_core *); | 91 | static int mini_cm_dealloc_core(struct nes_cm_core *); |
92 | static int mini_cm_get(struct nes_cm_core *); | 92 | static int mini_cm_get(struct nes_cm_core *); |
93 | static int mini_cm_set(struct nes_cm_core *, u32, u32); | 93 | static int mini_cm_set(struct nes_cm_core *, u32, u32); |
94 | 94 | ||
95 | static struct sk_buff *form_cm_frame(struct sk_buff *, struct nes_cm_node *, | 95 | static void form_cm_frame(struct sk_buff *, struct nes_cm_node *, |
96 | void *, u32, void *, u32, u8); | 96 | void *, u32, void *, u32, u8); |
97 | static struct sk_buff *get_free_pkt(struct nes_cm_node *cm_node); | ||
98 | static int add_ref_cm_node(struct nes_cm_node *); | 97 | static int add_ref_cm_node(struct nes_cm_node *); |
99 | static int rem_ref_cm_node(struct nes_cm_core *, struct nes_cm_node *); | 98 | static int rem_ref_cm_node(struct nes_cm_core *, struct nes_cm_node *); |
100 | 99 | ||
@@ -251,7 +250,7 @@ static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 len) | |||
251 | * form_cm_frame - get a free packet and build empty frame Use | 250 | * form_cm_frame - get a free packet and build empty frame Use |
252 | * node info to build. | 251 | * node info to build. |
253 | */ | 252 | */ |
254 | static struct sk_buff *form_cm_frame(struct sk_buff *skb, | 253 | static void form_cm_frame(struct sk_buff *skb, |
255 | struct nes_cm_node *cm_node, void *options, u32 optionsize, | 254 | struct nes_cm_node *cm_node, void *options, u32 optionsize, |
256 | void *data, u32 datasize, u8 flags) | 255 | void *data, u32 datasize, u8 flags) |
257 | { | 256 | { |
@@ -339,7 +338,6 @@ static struct sk_buff *form_cm_frame(struct sk_buff *skb, | |||
339 | skb_shinfo(skb)->nr_frags = 0; | 338 | skb_shinfo(skb)->nr_frags = 0; |
340 | cm_packets_created++; | 339 | cm_packets_created++; |
341 | 340 | ||
342 | return skb; | ||
343 | } | 341 | } |
344 | 342 | ||
345 | 343 | ||
@@ -356,7 +354,6 @@ static void print_core(struct nes_cm_core *core) | |||
356 | 354 | ||
357 | nes_debug(NES_DBG_CM, "State : %u \n", core->state); | 355 | nes_debug(NES_DBG_CM, "State : %u \n", core->state); |
358 | 356 | ||
359 | nes_debug(NES_DBG_CM, "Tx Free cnt : %u \n", skb_queue_len(&core->tx_free_list)); | ||
360 | nes_debug(NES_DBG_CM, "Listen Nodes : %u \n", atomic_read(&core->listen_node_cnt)); | 357 | nes_debug(NES_DBG_CM, "Listen Nodes : %u \n", atomic_read(&core->listen_node_cnt)); |
361 | nes_debug(NES_DBG_CM, "Active Nodes : %u \n", atomic_read(&core->node_cnt)); | 358 | nes_debug(NES_DBG_CM, "Active Nodes : %u \n", atomic_read(&core->node_cnt)); |
362 | 359 | ||
@@ -381,8 +378,6 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
381 | int ret = 0; | 378 | int ret = 0; |
382 | u32 was_timer_set; | 379 | u32 was_timer_set; |
383 | 380 | ||
384 | if (!cm_node) | ||
385 | return -EINVAL; | ||
386 | new_send = kzalloc(sizeof(*new_send), GFP_ATOMIC); | 381 | new_send = kzalloc(sizeof(*new_send), GFP_ATOMIC); |
387 | if (!new_send) | 382 | if (!new_send) |
388 | return -1; | 383 | return -1; |
@@ -459,13 +454,23 @@ static void nes_cm_timer_tick(unsigned long pass) | |||
459 | int ret = NETDEV_TX_OK; | 454 | int ret = NETDEV_TX_OK; |
460 | enum nes_cm_node_state last_state; | 455 | enum nes_cm_node_state last_state; |
461 | 456 | ||
457 | struct list_head timer_list; | ||
458 | INIT_LIST_HEAD(&timer_list); | ||
462 | spin_lock_irqsave(&cm_core->ht_lock, flags); | 459 | spin_lock_irqsave(&cm_core->ht_lock, flags); |
463 | 460 | ||
464 | list_for_each_safe(list_node, list_core_temp, | 461 | list_for_each_safe(list_node, list_core_temp, |
465 | &cm_core->connected_nodes) { | 462 | &cm_core->connected_nodes) { |
466 | cm_node = container_of(list_node, struct nes_cm_node, list); | 463 | cm_node = container_of(list_node, struct nes_cm_node, list); |
467 | add_ref_cm_node(cm_node); | 464 | if (!list_empty(&cm_node->recv_list) || (cm_node->send_entry)) { |
468 | spin_unlock_irqrestore(&cm_core->ht_lock, flags); | 465 | add_ref_cm_node(cm_node); |
466 | list_add(&cm_node->timer_entry, &timer_list); | ||
467 | } | ||
468 | } | ||
469 | spin_unlock_irqrestore(&cm_core->ht_lock, flags); | ||
470 | |||
471 | list_for_each_safe(list_node, list_core_temp, &timer_list) { | ||
472 | cm_node = container_of(list_node, struct nes_cm_node, | ||
473 | timer_entry); | ||
469 | spin_lock_irqsave(&cm_node->recv_list_lock, flags); | 474 | spin_lock_irqsave(&cm_node->recv_list_lock, flags); |
470 | list_for_each_safe(list_core, list_node_temp, | 475 | list_for_each_safe(list_core, list_node_temp, |
471 | &cm_node->recv_list) { | 476 | &cm_node->recv_list) { |
@@ -519,7 +524,7 @@ static void nes_cm_timer_tick(unsigned long pass) | |||
519 | do { | 524 | do { |
520 | send_entry = cm_node->send_entry; | 525 | send_entry = cm_node->send_entry; |
521 | if (!send_entry) | 526 | if (!send_entry) |
522 | continue; | 527 | break; |
523 | if (time_after(send_entry->timetosend, jiffies)) { | 528 | if (time_after(send_entry->timetosend, jiffies)) { |
524 | if (cm_node->state != NES_CM_STATE_TSA) { | 529 | if (cm_node->state != NES_CM_STATE_TSA) { |
525 | if ((nexttimeout > | 530 | if ((nexttimeout > |
@@ -528,18 +533,18 @@ static void nes_cm_timer_tick(unsigned long pass) | |||
528 | nexttimeout = | 533 | nexttimeout = |
529 | send_entry->timetosend; | 534 | send_entry->timetosend; |
530 | settimer = 1; | 535 | settimer = 1; |
531 | continue; | 536 | break; |
532 | } | 537 | } |
533 | } else { | 538 | } else { |
534 | free_retrans_entry(cm_node); | 539 | free_retrans_entry(cm_node); |
535 | continue; | 540 | break; |
536 | } | 541 | } |
537 | } | 542 | } |
538 | 543 | ||
539 | if ((cm_node->state == NES_CM_STATE_TSA) || | 544 | if ((cm_node->state == NES_CM_STATE_TSA) || |
540 | (cm_node->state == NES_CM_STATE_CLOSED)) { | 545 | (cm_node->state == NES_CM_STATE_CLOSED)) { |
541 | free_retrans_entry(cm_node); | 546 | free_retrans_entry(cm_node); |
542 | continue; | 547 | break; |
543 | } | 548 | } |
544 | 549 | ||
545 | if (!send_entry->retranscount || | 550 | if (!send_entry->retranscount || |
@@ -557,7 +562,7 @@ static void nes_cm_timer_tick(unsigned long pass) | |||
557 | NES_CM_EVENT_ABORTED); | 562 | NES_CM_EVENT_ABORTED); |
558 | spin_lock_irqsave(&cm_node->retrans_list_lock, | 563 | spin_lock_irqsave(&cm_node->retrans_list_lock, |
559 | flags); | 564 | flags); |
560 | continue; | 565 | break; |
561 | } | 566 | } |
562 | atomic_inc(&send_entry->skb->users); | 567 | atomic_inc(&send_entry->skb->users); |
563 | cm_packets_retrans++; | 568 | cm_packets_retrans++; |
@@ -583,7 +588,7 @@ static void nes_cm_timer_tick(unsigned long pass) | |||
583 | send_entry->retrycount--; | 588 | send_entry->retrycount--; |
584 | nexttimeout = jiffies + NES_SHORT_TIME; | 589 | nexttimeout = jiffies + NES_SHORT_TIME; |
585 | settimer = 1; | 590 | settimer = 1; |
586 | continue; | 591 | break; |
587 | } else { | 592 | } else { |
588 | cm_packets_sent++; | 593 | cm_packets_sent++; |
589 | } | 594 | } |
@@ -615,14 +620,12 @@ static void nes_cm_timer_tick(unsigned long pass) | |||
615 | 620 | ||
616 | spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); | 621 | spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); |
617 | rem_ref_cm_node(cm_node->cm_core, cm_node); | 622 | rem_ref_cm_node(cm_node->cm_core, cm_node); |
618 | spin_lock_irqsave(&cm_core->ht_lock, flags); | ||
619 | if (ret != NETDEV_TX_OK) { | 623 | if (ret != NETDEV_TX_OK) { |
620 | nes_debug(NES_DBG_CM, "rexmit failed for cm_node=%p\n", | 624 | nes_debug(NES_DBG_CM, "rexmit failed for cm_node=%p\n", |
621 | cm_node); | 625 | cm_node); |
622 | break; | 626 | break; |
623 | } | 627 | } |
624 | } | 628 | } |
625 | spin_unlock_irqrestore(&cm_core->ht_lock, flags); | ||
626 | 629 | ||
627 | if (settimer) { | 630 | if (settimer) { |
628 | if (!timer_pending(&cm_core->tcp_timer)) { | 631 | if (!timer_pending(&cm_core->tcp_timer)) { |
@@ -683,7 +686,7 @@ static int send_syn(struct nes_cm_node *cm_node, u32 sendack, | |||
683 | optionssize += 1; | 686 | optionssize += 1; |
684 | 687 | ||
685 | if (!skb) | 688 | if (!skb) |
686 | skb = get_free_pkt(cm_node); | 689 | skb = dev_alloc_skb(MAX_CM_BUFFER); |
687 | if (!skb) { | 690 | if (!skb) { |
688 | nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); | 691 | nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); |
689 | return -1; | 692 | return -1; |
@@ -708,7 +711,7 @@ static int send_reset(struct nes_cm_node *cm_node, struct sk_buff *skb) | |||
708 | int flags = SET_RST | SET_ACK; | 711 | int flags = SET_RST | SET_ACK; |
709 | 712 | ||
710 | if (!skb) | 713 | if (!skb) |
711 | skb = get_free_pkt(cm_node); | 714 | skb = dev_alloc_skb(MAX_CM_BUFFER); |
712 | if (!skb) { | 715 | if (!skb) { |
713 | nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); | 716 | nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); |
714 | return -1; | 717 | return -1; |
@@ -729,7 +732,7 @@ static int send_ack(struct nes_cm_node *cm_node, struct sk_buff *skb) | |||
729 | int ret; | 732 | int ret; |
730 | 733 | ||
731 | if (!skb) | 734 | if (!skb) |
732 | skb = get_free_pkt(cm_node); | 735 | skb = dev_alloc_skb(MAX_CM_BUFFER); |
733 | 736 | ||
734 | if (!skb) { | 737 | if (!skb) { |
735 | nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); | 738 | nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); |
@@ -752,7 +755,7 @@ static int send_fin(struct nes_cm_node *cm_node, struct sk_buff *skb) | |||
752 | 755 | ||
753 | /* if we didn't get a frame get one */ | 756 | /* if we didn't get a frame get one */ |
754 | if (!skb) | 757 | if (!skb) |
755 | skb = get_free_pkt(cm_node); | 758 | skb = dev_alloc_skb(MAX_CM_BUFFER); |
756 | 759 | ||
757 | if (!skb) { | 760 | if (!skb) { |
758 | nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); | 761 | nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); |
@@ -767,59 +770,15 @@ static int send_fin(struct nes_cm_node *cm_node, struct sk_buff *skb) | |||
767 | 770 | ||
768 | 771 | ||
769 | /** | 772 | /** |
770 | * get_free_pkt | ||
771 | */ | ||
772 | static struct sk_buff *get_free_pkt(struct nes_cm_node *cm_node) | ||
773 | { | ||
774 | struct sk_buff *skb, *new_skb; | ||
775 | |||
776 | /* check to see if we need to repopulate the free tx pkt queue */ | ||
777 | if (skb_queue_len(&cm_node->cm_core->tx_free_list) < NES_CM_FREE_PKT_LO_WATERMARK) { | ||
778 | while (skb_queue_len(&cm_node->cm_core->tx_free_list) < | ||
779 | cm_node->cm_core->free_tx_pkt_max) { | ||
780 | /* replace the frame we took, we won't get it back */ | ||
781 | new_skb = dev_alloc_skb(cm_node->cm_core->mtu); | ||
782 | BUG_ON(!new_skb); | ||
783 | /* add a replacement frame to the free tx list head */ | ||
784 | skb_queue_head(&cm_node->cm_core->tx_free_list, new_skb); | ||
785 | } | ||
786 | } | ||
787 | |||
788 | skb = skb_dequeue(&cm_node->cm_core->tx_free_list); | ||
789 | |||
790 | return skb; | ||
791 | } | ||
792 | |||
793 | |||
794 | /** | ||
795 | * make_hashkey - generate hash key from node tuple | ||
796 | */ | ||
797 | static inline int make_hashkey(u16 loc_port, nes_addr_t loc_addr, u16 rem_port, | ||
798 | nes_addr_t rem_addr) | ||
799 | { | ||
800 | u32 hashkey = 0; | ||
801 | |||
802 | hashkey = loc_addr + rem_addr + loc_port + rem_port; | ||
803 | hashkey = (hashkey % NES_CM_HASHTABLE_SIZE); | ||
804 | |||
805 | return hashkey; | ||
806 | } | ||
807 | |||
808 | |||
809 | /** | ||
810 | * find_node - find a cm node that matches the reference cm node | 773 | * find_node - find a cm node that matches the reference cm node |
811 | */ | 774 | */ |
812 | static struct nes_cm_node *find_node(struct nes_cm_core *cm_core, | 775 | static struct nes_cm_node *find_node(struct nes_cm_core *cm_core, |
813 | u16 rem_port, nes_addr_t rem_addr, u16 loc_port, nes_addr_t loc_addr) | 776 | u16 rem_port, nes_addr_t rem_addr, u16 loc_port, nes_addr_t loc_addr) |
814 | { | 777 | { |
815 | unsigned long flags; | 778 | unsigned long flags; |
816 | u32 hashkey; | ||
817 | struct list_head *hte; | 779 | struct list_head *hte; |
818 | struct nes_cm_node *cm_node; | 780 | struct nes_cm_node *cm_node; |
819 | 781 | ||
820 | /* make a hash index key for this packet */ | ||
821 | hashkey = make_hashkey(loc_port, loc_addr, rem_port, rem_addr); | ||
822 | |||
823 | /* get a handle on the hte */ | 782 | /* get a handle on the hte */ |
824 | hte = &cm_core->connected_nodes; | 783 | hte = &cm_core->connected_nodes; |
825 | 784 | ||
@@ -887,7 +846,6 @@ static struct nes_cm_listener *find_listener(struct nes_cm_core *cm_core, | |||
887 | static int add_hte_node(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node) | 846 | static int add_hte_node(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node) |
888 | { | 847 | { |
889 | unsigned long flags; | 848 | unsigned long flags; |
890 | u32 hashkey; | ||
891 | struct list_head *hte; | 849 | struct list_head *hte; |
892 | 850 | ||
893 | if (!cm_node || !cm_core) | 851 | if (!cm_node || !cm_core) |
@@ -896,11 +854,6 @@ static int add_hte_node(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node | |||
896 | nes_debug(NES_DBG_CM, "Adding Node %p to Active Connection HT\n", | 854 | nes_debug(NES_DBG_CM, "Adding Node %p to Active Connection HT\n", |
897 | cm_node); | 855 | cm_node); |
898 | 856 | ||
899 | /* first, make an index into our hash table */ | ||
900 | hashkey = make_hashkey(cm_node->loc_port, cm_node->loc_addr, | ||
901 | cm_node->rem_port, cm_node->rem_addr); | ||
902 | cm_node->hashkey = hashkey; | ||
903 | |||
904 | spin_lock_irqsave(&cm_core->ht_lock, flags); | 857 | spin_lock_irqsave(&cm_core->ht_lock, flags); |
905 | 858 | ||
906 | /* get a handle on the hash table element (list head for this slot) */ | 859 | /* get a handle on the hash table element (list head for this slot) */ |
@@ -925,28 +878,36 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core, | |||
925 | struct list_head *list_pos = NULL; | 878 | struct list_head *list_pos = NULL; |
926 | struct list_head *list_temp = NULL; | 879 | struct list_head *list_temp = NULL; |
927 | struct nes_cm_node *cm_node = NULL; | 880 | struct nes_cm_node *cm_node = NULL; |
881 | struct list_head reset_list; | ||
928 | 882 | ||
929 | nes_debug(NES_DBG_CM, "attempting listener= %p free_nodes= %d, " | 883 | nes_debug(NES_DBG_CM, "attempting listener= %p free_nodes= %d, " |
930 | "refcnt=%d\n", listener, free_hanging_nodes, | 884 | "refcnt=%d\n", listener, free_hanging_nodes, |
931 | atomic_read(&listener->ref_count)); | 885 | atomic_read(&listener->ref_count)); |
932 | /* free non-accelerated child nodes for this listener */ | 886 | /* free non-accelerated child nodes for this listener */ |
887 | INIT_LIST_HEAD(&reset_list); | ||
933 | if (free_hanging_nodes) { | 888 | if (free_hanging_nodes) { |
934 | spin_lock_irqsave(&cm_core->ht_lock, flags); | 889 | spin_lock_irqsave(&cm_core->ht_lock, flags); |
935 | list_for_each_safe(list_pos, list_temp, | 890 | list_for_each_safe(list_pos, list_temp, |
936 | &g_cm_core->connected_nodes) { | 891 | &g_cm_core->connected_nodes) { |
937 | cm_node = container_of(list_pos, struct nes_cm_node, | 892 | cm_node = container_of(list_pos, struct nes_cm_node, |
938 | list); | 893 | list); |
939 | if ((cm_node->listener == listener) && | 894 | if ((cm_node->listener == listener) && |
940 | (!cm_node->accelerated)) { | 895 | (!cm_node->accelerated)) { |
941 | cleanup_retrans_entry(cm_node); | 896 | add_ref_cm_node(cm_node); |
942 | spin_unlock_irqrestore(&cm_core->ht_lock, | 897 | list_add(&cm_node->reset_entry, &reset_list); |
943 | flags); | ||
944 | send_reset(cm_node, NULL); | ||
945 | spin_lock_irqsave(&cm_core->ht_lock, flags); | ||
946 | } | 898 | } |
947 | } | 899 | } |
948 | spin_unlock_irqrestore(&cm_core->ht_lock, flags); | 900 | spin_unlock_irqrestore(&cm_core->ht_lock, flags); |
949 | } | 901 | } |
902 | |||
903 | list_for_each_safe(list_pos, list_temp, &reset_list) { | ||
904 | cm_node = container_of(list_pos, struct nes_cm_node, | ||
905 | reset_entry); | ||
906 | cleanup_retrans_entry(cm_node); | ||
907 | send_reset(cm_node, NULL); | ||
908 | rem_ref_cm_node(cm_node->cm_core, cm_node); | ||
909 | } | ||
910 | |||
950 | spin_lock_irqsave(&cm_core->listen_list_lock, flags); | 911 | spin_lock_irqsave(&cm_core->listen_list_lock, flags); |
951 | if (!atomic_dec_return(&listener->ref_count)) { | 912 | if (!atomic_dec_return(&listener->ref_count)) { |
952 | list_del(&listener->list); | 913 | list_del(&listener->list); |
@@ -1123,7 +1084,10 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core, | |||
1123 | 1084 | ||
1124 | cm_node->loopbackpartner = NULL; | 1085 | cm_node->loopbackpartner = NULL; |
1125 | /* get the mac addr for the remote node */ | 1086 | /* get the mac addr for the remote node */ |
1126 | arpindex = nes_arp_table(nesdev, cm_node->rem_addr, NULL, NES_ARP_RESOLVE); | 1087 | if (ipv4_is_loopback(htonl(cm_node->rem_addr))) |
1088 | arpindex = nes_arp_table(nesdev, ntohl(nesvnic->local_ipaddr), NULL, NES_ARP_RESOLVE); | ||
1089 | else | ||
1090 | arpindex = nes_arp_table(nesdev, cm_node->rem_addr, NULL, NES_ARP_RESOLVE); | ||
1127 | if (arpindex < 0) { | 1091 | if (arpindex < 0) { |
1128 | arpindex = nes_addr_resolve_neigh(nesvnic, cm_info->rem_addr); | 1092 | arpindex = nes_addr_resolve_neigh(nesvnic, cm_info->rem_addr); |
1129 | if (arpindex < 0) { | 1093 | if (arpindex < 0) { |
@@ -1303,7 +1267,6 @@ static void drop_packet(struct sk_buff *skb) | |||
1303 | static void handle_fin_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | 1267 | static void handle_fin_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, |
1304 | struct tcphdr *tcph) | 1268 | struct tcphdr *tcph) |
1305 | { | 1269 | { |
1306 | atomic_inc(&cm_resets_recvd); | ||
1307 | nes_debug(NES_DBG_CM, "Received FIN, cm_node = %p, state = %u. " | 1270 | nes_debug(NES_DBG_CM, "Received FIN, cm_node = %p, state = %u. " |
1308 | "refcnt=%d\n", cm_node, cm_node->state, | 1271 | "refcnt=%d\n", cm_node, cm_node->state, |
1309 | atomic_read(&cm_node->ref_count)); | 1272 | atomic_read(&cm_node->ref_count)); |
@@ -1341,6 +1304,7 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1341 | { | 1304 | { |
1342 | 1305 | ||
1343 | int reset = 0; /* whether to send reset in case of err.. */ | 1306 | int reset = 0; /* whether to send reset in case of err.. */ |
1307 | int passive_state; | ||
1344 | atomic_inc(&cm_resets_recvd); | 1308 | atomic_inc(&cm_resets_recvd); |
1345 | nes_debug(NES_DBG_CM, "Received Reset, cm_node = %p, state = %u." | 1309 | nes_debug(NES_DBG_CM, "Received Reset, cm_node = %p, state = %u." |
1346 | " refcnt=%d\n", cm_node, cm_node->state, | 1310 | " refcnt=%d\n", cm_node, cm_node->state, |
@@ -1354,7 +1318,14 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1354 | cm_node->listener, cm_node->state); | 1318 | cm_node->listener, cm_node->state); |
1355 | active_open_err(cm_node, skb, reset); | 1319 | active_open_err(cm_node, skb, reset); |
1356 | break; | 1320 | break; |
1357 | /* For PASSIVE open states, remove the cm_node event */ | 1321 | case NES_CM_STATE_MPAREQ_RCVD: |
1322 | passive_state = atomic_add_return(1, &cm_node->passive_state); | ||
1323 | if (passive_state == NES_SEND_RESET_EVENT) | ||
1324 | create_event(cm_node, NES_CM_EVENT_RESET); | ||
1325 | cleanup_retrans_entry(cm_node); | ||
1326 | cm_node->state = NES_CM_STATE_CLOSED; | ||
1327 | dev_kfree_skb_any(skb); | ||
1328 | break; | ||
1358 | case NES_CM_STATE_ESTABLISHED: | 1329 | case NES_CM_STATE_ESTABLISHED: |
1359 | case NES_CM_STATE_SYN_RCVD: | 1330 | case NES_CM_STATE_SYN_RCVD: |
1360 | case NES_CM_STATE_LISTENING: | 1331 | case NES_CM_STATE_LISTENING: |
@@ -1362,7 +1333,14 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1362 | passive_open_err(cm_node, skb, reset); | 1333 | passive_open_err(cm_node, skb, reset); |
1363 | break; | 1334 | break; |
1364 | case NES_CM_STATE_TSA: | 1335 | case NES_CM_STATE_TSA: |
1336 | active_open_err(cm_node, skb, reset); | ||
1337 | break; | ||
1338 | case NES_CM_STATE_CLOSED: | ||
1339 | cleanup_retrans_entry(cm_node); | ||
1340 | drop_packet(skb); | ||
1341 | break; | ||
1365 | default: | 1342 | default: |
1343 | drop_packet(skb); | ||
1366 | break; | 1344 | break; |
1367 | } | 1345 | } |
1368 | } | 1346 | } |
@@ -1391,6 +1369,9 @@ static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1391 | dev_kfree_skb_any(skb); | 1369 | dev_kfree_skb_any(skb); |
1392 | if (type == NES_CM_EVENT_CONNECTED) | 1370 | if (type == NES_CM_EVENT_CONNECTED) |
1393 | cm_node->state = NES_CM_STATE_TSA; | 1371 | cm_node->state = NES_CM_STATE_TSA; |
1372 | else | ||
1373 | atomic_set(&cm_node->passive_state, | ||
1374 | NES_PASSIVE_STATE_INDICATED); | ||
1394 | create_event(cm_node, type); | 1375 | create_event(cm_node, type); |
1395 | 1376 | ||
1396 | } | 1377 | } |
@@ -1471,7 +1452,7 @@ static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1471 | int optionsize; | 1452 | int optionsize; |
1472 | 1453 | ||
1473 | optionsize = (tcph->doff << 2) - sizeof(struct tcphdr); | 1454 | optionsize = (tcph->doff << 2) - sizeof(struct tcphdr); |
1474 | skb_pull(skb, tcph->doff << 2); | 1455 | skb_trim(skb, 0); |
1475 | inc_sequence = ntohl(tcph->seq); | 1456 | inc_sequence = ntohl(tcph->seq); |
1476 | 1457 | ||
1477 | switch (cm_node->state) { | 1458 | switch (cm_node->state) { |
@@ -1504,6 +1485,10 @@ static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1504 | cm_node->state = NES_CM_STATE_SYN_RCVD; | 1485 | cm_node->state = NES_CM_STATE_SYN_RCVD; |
1505 | send_syn(cm_node, 1, skb); | 1486 | send_syn(cm_node, 1, skb); |
1506 | break; | 1487 | break; |
1488 | case NES_CM_STATE_CLOSED: | ||
1489 | cleanup_retrans_entry(cm_node); | ||
1490 | send_reset(cm_node, skb); | ||
1491 | break; | ||
1507 | case NES_CM_STATE_TSA: | 1492 | case NES_CM_STATE_TSA: |
1508 | case NES_CM_STATE_ESTABLISHED: | 1493 | case NES_CM_STATE_ESTABLISHED: |
1509 | case NES_CM_STATE_FIN_WAIT1: | 1494 | case NES_CM_STATE_FIN_WAIT1: |
@@ -1512,7 +1497,6 @@ static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1512 | case NES_CM_STATE_LAST_ACK: | 1497 | case NES_CM_STATE_LAST_ACK: |
1513 | case NES_CM_STATE_CLOSING: | 1498 | case NES_CM_STATE_CLOSING: |
1514 | case NES_CM_STATE_UNKNOWN: | 1499 | case NES_CM_STATE_UNKNOWN: |
1515 | case NES_CM_STATE_CLOSED: | ||
1516 | default: | 1500 | default: |
1517 | drop_packet(skb); | 1501 | drop_packet(skb); |
1518 | break; | 1502 | break; |
@@ -1528,7 +1512,7 @@ static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1528 | int optionsize; | 1512 | int optionsize; |
1529 | 1513 | ||
1530 | optionsize = (tcph->doff << 2) - sizeof(struct tcphdr); | 1514 | optionsize = (tcph->doff << 2) - sizeof(struct tcphdr); |
1531 | skb_pull(skb, tcph->doff << 2); | 1515 | skb_trim(skb, 0); |
1532 | inc_sequence = ntohl(tcph->seq); | 1516 | inc_sequence = ntohl(tcph->seq); |
1533 | switch (cm_node->state) { | 1517 | switch (cm_node->state) { |
1534 | case NES_CM_STATE_SYN_SENT: | 1518 | case NES_CM_STATE_SYN_SENT: |
@@ -1552,6 +1536,12 @@ static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1552 | /* passive open, so should not be here */ | 1536 | /* passive open, so should not be here */ |
1553 | passive_open_err(cm_node, skb, 1); | 1537 | passive_open_err(cm_node, skb, 1); |
1554 | break; | 1538 | break; |
1539 | case NES_CM_STATE_LISTENING: | ||
1540 | case NES_CM_STATE_CLOSED: | ||
1541 | cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq); | ||
1542 | cleanup_retrans_entry(cm_node); | ||
1543 | send_reset(cm_node, skb); | ||
1544 | break; | ||
1555 | case NES_CM_STATE_ESTABLISHED: | 1545 | case NES_CM_STATE_ESTABLISHED: |
1556 | case NES_CM_STATE_FIN_WAIT1: | 1546 | case NES_CM_STATE_FIN_WAIT1: |
1557 | case NES_CM_STATE_FIN_WAIT2: | 1547 | case NES_CM_STATE_FIN_WAIT2: |
@@ -1559,7 +1549,6 @@ static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1559 | case NES_CM_STATE_TSA: | 1549 | case NES_CM_STATE_TSA: |
1560 | case NES_CM_STATE_CLOSING: | 1550 | case NES_CM_STATE_CLOSING: |
1561 | case NES_CM_STATE_UNKNOWN: | 1551 | case NES_CM_STATE_UNKNOWN: |
1562 | case NES_CM_STATE_CLOSED: | ||
1563 | case NES_CM_STATE_MPAREQ_SENT: | 1552 | case NES_CM_STATE_MPAREQ_SENT: |
1564 | default: | 1553 | default: |
1565 | drop_packet(skb); | 1554 | drop_packet(skb); |
@@ -1574,6 +1563,13 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1574 | u32 inc_sequence; | 1563 | u32 inc_sequence; |
1575 | u32 rem_seq_ack; | 1564 | u32 rem_seq_ack; |
1576 | u32 rem_seq; | 1565 | u32 rem_seq; |
1566 | int ret; | ||
1567 | int optionsize; | ||
1568 | u32 temp_seq = cm_node->tcp_cntxt.loc_seq_num; | ||
1569 | |||
1570 | optionsize = (tcph->doff << 2) - sizeof(struct tcphdr); | ||
1571 | cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq); | ||
1572 | |||
1577 | if (check_seq(cm_node, tcph, skb)) | 1573 | if (check_seq(cm_node, tcph, skb)) |
1578 | return; | 1574 | return; |
1579 | 1575 | ||
@@ -1586,7 +1582,18 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1586 | switch (cm_node->state) { | 1582 | switch (cm_node->state) { |
1587 | case NES_CM_STATE_SYN_RCVD: | 1583 | case NES_CM_STATE_SYN_RCVD: |
1588 | /* Passive OPEN */ | 1584 | /* Passive OPEN */ |
1585 | ret = handle_tcp_options(cm_node, tcph, skb, optionsize, 1); | ||
1586 | if (ret) | ||
1587 | break; | ||
1589 | cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); | 1588 | cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); |
1589 | cm_node->tcp_cntxt.loc_seq_num = temp_seq; | ||
1590 | if (cm_node->tcp_cntxt.rem_ack_num != | ||
1591 | cm_node->tcp_cntxt.loc_seq_num) { | ||
1592 | nes_debug(NES_DBG_CM, "rem_ack_num != loc_seq_num\n"); | ||
1593 | cleanup_retrans_entry(cm_node); | ||
1594 | send_reset(cm_node, skb); | ||
1595 | return; | ||
1596 | } | ||
1590 | cm_node->state = NES_CM_STATE_ESTABLISHED; | 1597 | cm_node->state = NES_CM_STATE_ESTABLISHED; |
1591 | if (datasize) { | 1598 | if (datasize) { |
1592 | cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; | 1599 | cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; |
@@ -1618,11 +1625,15 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1618 | dev_kfree_skb_any(skb); | 1625 | dev_kfree_skb_any(skb); |
1619 | } | 1626 | } |
1620 | break; | 1627 | break; |
1628 | case NES_CM_STATE_LISTENING: | ||
1629 | case NES_CM_STATE_CLOSED: | ||
1630 | cleanup_retrans_entry(cm_node); | ||
1631 | send_reset(cm_node, skb); | ||
1632 | break; | ||
1621 | case NES_CM_STATE_FIN_WAIT1: | 1633 | case NES_CM_STATE_FIN_WAIT1: |
1622 | case NES_CM_STATE_SYN_SENT: | 1634 | case NES_CM_STATE_SYN_SENT: |
1623 | case NES_CM_STATE_FIN_WAIT2: | 1635 | case NES_CM_STATE_FIN_WAIT2: |
1624 | case NES_CM_STATE_TSA: | 1636 | case NES_CM_STATE_TSA: |
1625 | case NES_CM_STATE_CLOSED: | ||
1626 | case NES_CM_STATE_MPAREQ_RCVD: | 1637 | case NES_CM_STATE_MPAREQ_RCVD: |
1627 | case NES_CM_STATE_LAST_ACK: | 1638 | case NES_CM_STATE_LAST_ACK: |
1628 | case NES_CM_STATE_CLOSING: | 1639 | case NES_CM_STATE_CLOSING: |
@@ -1645,9 +1656,9 @@ static int handle_tcp_options(struct nes_cm_node *cm_node, struct tcphdr *tcph, | |||
1645 | nes_debug(NES_DBG_CM, "%s: Node %p, Sending RESET\n", | 1656 | nes_debug(NES_DBG_CM, "%s: Node %p, Sending RESET\n", |
1646 | __func__, cm_node); | 1657 | __func__, cm_node); |
1647 | if (passive) | 1658 | if (passive) |
1648 | passive_open_err(cm_node, skb, 0); | 1659 | passive_open_err(cm_node, skb, 1); |
1649 | else | 1660 | else |
1650 | active_open_err(cm_node, skb, 0); | 1661 | active_open_err(cm_node, skb, 1); |
1651 | return 1; | 1662 | return 1; |
1652 | } | 1663 | } |
1653 | } | 1664 | } |
@@ -1967,6 +1978,7 @@ static int mini_cm_reject(struct nes_cm_core *cm_core, | |||
1967 | struct ietf_mpa_frame *mpa_frame, struct nes_cm_node *cm_node) | 1978 | struct ietf_mpa_frame *mpa_frame, struct nes_cm_node *cm_node) |
1968 | { | 1979 | { |
1969 | int ret = 0; | 1980 | int ret = 0; |
1981 | int passive_state; | ||
1970 | 1982 | ||
1971 | nes_debug(NES_DBG_CM, "%s cm_node=%p type=%d state=%d\n", | 1983 | nes_debug(NES_DBG_CM, "%s cm_node=%p type=%d state=%d\n", |
1972 | __func__, cm_node, cm_node->tcp_cntxt.client, cm_node->state); | 1984 | __func__, cm_node, cm_node->tcp_cntxt.client, cm_node->state); |
@@ -1974,9 +1986,13 @@ static int mini_cm_reject(struct nes_cm_core *cm_core, | |||
1974 | if (cm_node->tcp_cntxt.client) | 1986 | if (cm_node->tcp_cntxt.client) |
1975 | return ret; | 1987 | return ret; |
1976 | cleanup_retrans_entry(cm_node); | 1988 | cleanup_retrans_entry(cm_node); |
1977 | cm_node->state = NES_CM_STATE_CLOSED; | ||
1978 | 1989 | ||
1979 | ret = send_reset(cm_node, NULL); | 1990 | passive_state = atomic_add_return(1, &cm_node->passive_state); |
1991 | cm_node->state = NES_CM_STATE_CLOSED; | ||
1992 | if (passive_state == NES_SEND_RESET_EVENT) | ||
1993 | rem_ref_cm_node(cm_core, cm_node); | ||
1994 | else | ||
1995 | ret = send_reset(cm_node, NULL); | ||
1980 | return ret; | 1996 | return ret; |
1981 | } | 1997 | } |
1982 | 1998 | ||
@@ -2034,7 +2050,7 @@ static int mini_cm_close(struct nes_cm_core *cm_core, struct nes_cm_node *cm_nod | |||
2034 | * recv_pkt - recv an ETHERNET packet, and process it through CM | 2050 | * recv_pkt - recv an ETHERNET packet, and process it through CM |
2035 | * node state machine | 2051 | * node state machine |
2036 | */ | 2052 | */ |
2037 | static void mini_cm_recv_pkt(struct nes_cm_core *cm_core, | 2053 | static int mini_cm_recv_pkt(struct nes_cm_core *cm_core, |
2038 | struct nes_vnic *nesvnic, struct sk_buff *skb) | 2054 | struct nes_vnic *nesvnic, struct sk_buff *skb) |
2039 | { | 2055 | { |
2040 | struct nes_cm_node *cm_node = NULL; | 2056 | struct nes_cm_node *cm_node = NULL; |
@@ -2042,23 +2058,16 @@ static void mini_cm_recv_pkt(struct nes_cm_core *cm_core, | |||
2042 | struct iphdr *iph; | 2058 | struct iphdr *iph; |
2043 | struct tcphdr *tcph; | 2059 | struct tcphdr *tcph; |
2044 | struct nes_cm_info nfo; | 2060 | struct nes_cm_info nfo; |
2061 | int skb_handled = 1; | ||
2045 | 2062 | ||
2046 | if (!skb) | 2063 | if (!skb) |
2047 | return; | 2064 | return 0; |
2048 | if (skb->len < sizeof(struct iphdr) + sizeof(struct tcphdr)) { | 2065 | if (skb->len < sizeof(struct iphdr) + sizeof(struct tcphdr)) { |
2049 | dev_kfree_skb_any(skb); | 2066 | return 0; |
2050 | return; | ||
2051 | } | 2067 | } |
2052 | 2068 | ||
2053 | iph = (struct iphdr *)skb->data; | 2069 | iph = (struct iphdr *)skb->data; |
2054 | tcph = (struct tcphdr *)(skb->data + sizeof(struct iphdr)); | 2070 | tcph = (struct tcphdr *)(skb->data + sizeof(struct iphdr)); |
2055 | skb_reset_network_header(skb); | ||
2056 | skb_set_transport_header(skb, sizeof(*tcph)); | ||
2057 | if (!tcph) { | ||
2058 | dev_kfree_skb_any(skb); | ||
2059 | return; | ||
2060 | } | ||
2061 | skb->len = ntohs(iph->tot_len); | ||
2062 | 2071 | ||
2063 | nfo.loc_addr = ntohl(iph->daddr); | 2072 | nfo.loc_addr = ntohl(iph->daddr); |
2064 | nfo.loc_port = ntohs(tcph->dest); | 2073 | nfo.loc_port = ntohs(tcph->dest); |
@@ -2077,23 +2086,21 @@ static void mini_cm_recv_pkt(struct nes_cm_core *cm_core, | |||
2077 | /* Only type of packet accepted are for */ | 2086 | /* Only type of packet accepted are for */ |
2078 | /* the PASSIVE open (syn only) */ | 2087 | /* the PASSIVE open (syn only) */ |
2079 | if ((!tcph->syn) || (tcph->ack)) { | 2088 | if ((!tcph->syn) || (tcph->ack)) { |
2080 | cm_packets_dropped++; | 2089 | skb_handled = 0; |
2081 | break; | 2090 | break; |
2082 | } | 2091 | } |
2083 | listener = find_listener(cm_core, nfo.loc_addr, | 2092 | listener = find_listener(cm_core, nfo.loc_addr, |
2084 | nfo.loc_port, | 2093 | nfo.loc_port, |
2085 | NES_CM_LISTENER_ACTIVE_STATE); | 2094 | NES_CM_LISTENER_ACTIVE_STATE); |
2086 | if (listener) { | 2095 | if (!listener) { |
2087 | nfo.cm_id = listener->cm_id; | 2096 | nfo.cm_id = NULL; |
2088 | nfo.conn_type = listener->conn_type; | 2097 | nfo.conn_type = 0; |
2089 | } else { | 2098 | nes_debug(NES_DBG_CM, "Unable to find listener for the pkt\n"); |
2090 | nes_debug(NES_DBG_CM, "Unable to find listener " | 2099 | skb_handled = 0; |
2091 | "for the pkt\n"); | ||
2092 | cm_packets_dropped++; | ||
2093 | dev_kfree_skb_any(skb); | ||
2094 | break; | 2100 | break; |
2095 | } | 2101 | } |
2096 | 2102 | nfo.cm_id = listener->cm_id; | |
2103 | nfo.conn_type = listener->conn_type; | ||
2097 | cm_node = make_cm_node(cm_core, nesvnic, &nfo, | 2104 | cm_node = make_cm_node(cm_core, nesvnic, &nfo, |
2098 | listener); | 2105 | listener); |
2099 | if (!cm_node) { | 2106 | if (!cm_node) { |
@@ -2119,9 +2126,13 @@ static void mini_cm_recv_pkt(struct nes_cm_core *cm_core, | |||
2119 | dev_kfree_skb_any(skb); | 2126 | dev_kfree_skb_any(skb); |
2120 | break; | 2127 | break; |
2121 | } | 2128 | } |
2129 | skb_reset_network_header(skb); | ||
2130 | skb_set_transport_header(skb, sizeof(*tcph)); | ||
2131 | skb->len = ntohs(iph->tot_len); | ||
2122 | process_packet(cm_node, skb, cm_core); | 2132 | process_packet(cm_node, skb, cm_core); |
2123 | rem_ref_cm_node(cm_core, cm_node); | 2133 | rem_ref_cm_node(cm_core, cm_node); |
2124 | } while (0); | 2134 | } while (0); |
2135 | return skb_handled; | ||
2125 | } | 2136 | } |
2126 | 2137 | ||
2127 | 2138 | ||
@@ -2130,10 +2141,7 @@ static void mini_cm_recv_pkt(struct nes_cm_core *cm_core, | |||
2130 | */ | 2141 | */ |
2131 | static struct nes_cm_core *nes_cm_alloc_core(void) | 2142 | static struct nes_cm_core *nes_cm_alloc_core(void) |
2132 | { | 2143 | { |
2133 | int i; | ||
2134 | |||
2135 | struct nes_cm_core *cm_core; | 2144 | struct nes_cm_core *cm_core; |
2136 | struct sk_buff *skb = NULL; | ||
2137 | 2145 | ||
2138 | /* setup the CM core */ | 2146 | /* setup the CM core */ |
2139 | /* alloc top level core control structure */ | 2147 | /* alloc top level core control structure */ |
@@ -2151,19 +2159,6 @@ static struct nes_cm_core *nes_cm_alloc_core(void) | |||
2151 | 2159 | ||
2152 | atomic_set(&cm_core->events_posted, 0); | 2160 | atomic_set(&cm_core->events_posted, 0); |
2153 | 2161 | ||
2154 | /* init the packet lists */ | ||
2155 | skb_queue_head_init(&cm_core->tx_free_list); | ||
2156 | |||
2157 | for (i = 0; i < NES_CM_DEFAULT_FRAME_CNT; i++) { | ||
2158 | skb = dev_alloc_skb(cm_core->mtu); | ||
2159 | if (!skb) { | ||
2160 | kfree(cm_core); | ||
2161 | return NULL; | ||
2162 | } | ||
2163 | /* add 'raw' skb to free frame list */ | ||
2164 | skb_queue_head(&cm_core->tx_free_list, skb); | ||
2165 | } | ||
2166 | |||
2167 | cm_core->api = &nes_cm_api; | 2162 | cm_core->api = &nes_cm_api; |
2168 | 2163 | ||
2169 | spin_lock_init(&cm_core->ht_lock); | 2164 | spin_lock_init(&cm_core->ht_lock); |
@@ -2392,7 +2387,6 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp) | |||
2392 | atomic_inc(&cm_disconnects); | 2387 | atomic_inc(&cm_disconnects); |
2393 | cm_event.event = IW_CM_EVENT_DISCONNECT; | 2388 | cm_event.event = IW_CM_EVENT_DISCONNECT; |
2394 | if (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET) { | 2389 | if (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET) { |
2395 | issued_disconnect_reset = 1; | ||
2396 | cm_event.status = IW_CM_EVENT_STATUS_RESET; | 2390 | cm_event.status = IW_CM_EVENT_STATUS_RESET; |
2397 | nes_debug(NES_DBG_CM, "Generating a CM " | 2391 | nes_debug(NES_DBG_CM, "Generating a CM " |
2398 | "Disconnect Event (status reset) for " | 2392 | "Disconnect Event (status reset) for " |
@@ -2542,6 +2536,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2542 | struct nes_v4_quad nes_quad; | 2536 | struct nes_v4_quad nes_quad; |
2543 | u32 crc_value; | 2537 | u32 crc_value; |
2544 | int ret; | 2538 | int ret; |
2539 | int passive_state; | ||
2545 | 2540 | ||
2546 | ibqp = nes_get_qp(cm_id->device, conn_param->qpn); | 2541 | ibqp = nes_get_qp(cm_id->device, conn_param->qpn); |
2547 | if (!ibqp) | 2542 | if (!ibqp) |
@@ -2709,8 +2704,6 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2709 | conn_param->private_data_len + | 2704 | conn_param->private_data_len + |
2710 | sizeof(struct ietf_mpa_frame)); | 2705 | sizeof(struct ietf_mpa_frame)); |
2711 | 2706 | ||
2712 | attr.qp_state = IB_QPS_RTS; | ||
2713 | nes_modify_qp(&nesqp->ibqp, &attr, IB_QP_STATE, NULL); | ||
2714 | 2707 | ||
2715 | /* notify OF layer that accept event was successfull */ | 2708 | /* notify OF layer that accept event was successfull */ |
2716 | cm_id->add_ref(cm_id); | 2709 | cm_id->add_ref(cm_id); |
@@ -2723,6 +2716,8 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2723 | cm_event.private_data = NULL; | 2716 | cm_event.private_data = NULL; |
2724 | cm_event.private_data_len = 0; | 2717 | cm_event.private_data_len = 0; |
2725 | ret = cm_id->event_handler(cm_id, &cm_event); | 2718 | ret = cm_id->event_handler(cm_id, &cm_event); |
2719 | attr.qp_state = IB_QPS_RTS; | ||
2720 | nes_modify_qp(&nesqp->ibqp, &attr, IB_QP_STATE, NULL); | ||
2726 | if (cm_node->loopbackpartner) { | 2721 | if (cm_node->loopbackpartner) { |
2727 | cm_node->loopbackpartner->mpa_frame_size = | 2722 | cm_node->loopbackpartner->mpa_frame_size = |
2728 | nesqp->private_data_len; | 2723 | nesqp->private_data_len; |
@@ -2735,6 +2730,9 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2735 | printk(KERN_ERR "%s[%u] OFA CM event_handler returned, " | 2730 | printk(KERN_ERR "%s[%u] OFA CM event_handler returned, " |
2736 | "ret=%d\n", __func__, __LINE__, ret); | 2731 | "ret=%d\n", __func__, __LINE__, ret); |
2737 | 2732 | ||
2733 | passive_state = atomic_add_return(1, &cm_node->passive_state); | ||
2734 | if (passive_state == NES_SEND_RESET_EVENT) | ||
2735 | create_event(cm_node, NES_CM_EVENT_RESET); | ||
2738 | return 0; | 2736 | return 0; |
2739 | } | 2737 | } |
2740 | 2738 | ||
@@ -2938,15 +2936,16 @@ int nes_destroy_listen(struct iw_cm_id *cm_id) | |||
2938 | */ | 2936 | */ |
2939 | int nes_cm_recv(struct sk_buff *skb, struct net_device *netdevice) | 2937 | int nes_cm_recv(struct sk_buff *skb, struct net_device *netdevice) |
2940 | { | 2938 | { |
2939 | int rc = 0; | ||
2941 | cm_packets_received++; | 2940 | cm_packets_received++; |
2942 | if ((g_cm_core) && (g_cm_core->api)) { | 2941 | if ((g_cm_core) && (g_cm_core->api)) { |
2943 | g_cm_core->api->recv_pkt(g_cm_core, netdev_priv(netdevice), skb); | 2942 | rc = g_cm_core->api->recv_pkt(g_cm_core, netdev_priv(netdevice), skb); |
2944 | } else { | 2943 | } else { |
2945 | nes_debug(NES_DBG_CM, "Unable to process packet for CM," | 2944 | nes_debug(NES_DBG_CM, "Unable to process packet for CM," |
2946 | " cm is not setup properly.\n"); | 2945 | " cm is not setup properly.\n"); |
2947 | } | 2946 | } |
2948 | 2947 | ||
2949 | return 0; | 2948 | return rc; |
2950 | } | 2949 | } |
2951 | 2950 | ||
2952 | 2951 | ||
@@ -3217,6 +3216,18 @@ static void cm_event_reset(struct nes_cm_event *event) | |||
3217 | cm_event.private_data_len = 0; | 3216 | cm_event.private_data_len = 0; |
3218 | 3217 | ||
3219 | ret = cm_id->event_handler(cm_id, &cm_event); | 3218 | ret = cm_id->event_handler(cm_id, &cm_event); |
3219 | cm_id->add_ref(cm_id); | ||
3220 | atomic_inc(&cm_closes); | ||
3221 | cm_event.event = IW_CM_EVENT_CLOSE; | ||
3222 | cm_event.status = IW_CM_EVENT_STATUS_OK; | ||
3223 | cm_event.provider_data = cm_id->provider_data; | ||
3224 | cm_event.local_addr = cm_id->local_addr; | ||
3225 | cm_event.remote_addr = cm_id->remote_addr; | ||
3226 | cm_event.private_data = NULL; | ||
3227 | cm_event.private_data_len = 0; | ||
3228 | nes_debug(NES_DBG_CM, "NODE %p Generating CLOSE\n", event->cm_node); | ||
3229 | ret = cm_id->event_handler(cm_id, &cm_event); | ||
3230 | |||
3220 | nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret); | 3231 | nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret); |
3221 | 3232 | ||
3222 | 3233 | ||