diff options
Diffstat (limited to 'drivers/infiniband/hw/nes/nes_cm.c')
-rw-r--r-- | drivers/infiniband/hw/nes/nes_cm.c | 106 |
1 files changed, 53 insertions, 53 deletions
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 52425154acd4..11c7d6642014 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <net/neighbour.h> | 56 | #include <net/neighbour.h> |
57 | #include <net/route.h> | 57 | #include <net/route.h> |
58 | #include <net/ip_fib.h> | 58 | #include <net/ip_fib.h> |
59 | #include <net/tcp.h> | ||
59 | 60 | ||
60 | #include "nes.h" | 61 | #include "nes.h" |
61 | 62 | ||
@@ -426,6 +427,7 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
426 | if (type == NES_TIMER_TYPE_CLOSE) { | 427 | if (type == NES_TIMER_TYPE_CLOSE) { |
427 | new_send->timetosend += (HZ/10); | 428 | new_send->timetosend += (HZ/10); |
428 | if (cm_node->recv_entry) { | 429 | if (cm_node->recv_entry) { |
430 | kfree(new_send); | ||
429 | WARN_ON(1); | 431 | WARN_ON(1); |
430 | return -EINVAL; | 432 | return -EINVAL; |
431 | } | 433 | } |
@@ -445,8 +447,8 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
445 | if (ret != NETDEV_TX_OK) { | 447 | if (ret != NETDEV_TX_OK) { |
446 | nes_debug(NES_DBG_CM, "Error sending packet %p " | 448 | nes_debug(NES_DBG_CM, "Error sending packet %p " |
447 | "(jiffies = %lu)\n", new_send, jiffies); | 449 | "(jiffies = %lu)\n", new_send, jiffies); |
448 | atomic_dec(&new_send->skb->users); | ||
449 | new_send->timetosend = jiffies; | 450 | new_send->timetosend = jiffies; |
451 | ret = NETDEV_TX_OK; | ||
450 | } else { | 452 | } else { |
451 | cm_packets_sent++; | 453 | cm_packets_sent++; |
452 | if (!send_retrans) { | 454 | if (!send_retrans) { |
@@ -539,6 +541,7 @@ static void nes_cm_timer_tick(unsigned long pass) | |||
539 | struct list_head *list_node; | 541 | struct list_head *list_node; |
540 | struct nes_cm_core *cm_core = g_cm_core; | 542 | struct nes_cm_core *cm_core = g_cm_core; |
541 | u32 settimer = 0; | 543 | u32 settimer = 0; |
544 | unsigned long timetosend; | ||
542 | int ret = NETDEV_TX_OK; | 545 | int ret = NETDEV_TX_OK; |
543 | 546 | ||
544 | struct list_head timer_list; | 547 | struct list_head timer_list; |
@@ -630,7 +633,6 @@ static void nes_cm_timer_tick(unsigned long pass) | |||
630 | nes_debug(NES_DBG_CM, "rexmit failed for " | 633 | nes_debug(NES_DBG_CM, "rexmit failed for " |
631 | "node=%p\n", cm_node); | 634 | "node=%p\n", cm_node); |
632 | cm_packets_bounced++; | 635 | cm_packets_bounced++; |
633 | atomic_dec(&send_entry->skb->users); | ||
634 | send_entry->retrycount--; | 636 | send_entry->retrycount--; |
635 | nexttimeout = jiffies + NES_SHORT_TIME; | 637 | nexttimeout = jiffies + NES_SHORT_TIME; |
636 | settimer = 1; | 638 | settimer = 1; |
@@ -644,8 +646,11 @@ static void nes_cm_timer_tick(unsigned long pass) | |||
644 | send_entry->retrycount); | 646 | send_entry->retrycount); |
645 | if (send_entry->send_retrans) { | 647 | if (send_entry->send_retrans) { |
646 | send_entry->retranscount--; | 648 | send_entry->retranscount--; |
649 | timetosend = (NES_RETRY_TIMEOUT << | ||
650 | (NES_DEFAULT_RETRANS - send_entry->retranscount)); | ||
651 | |||
647 | send_entry->timetosend = jiffies + | 652 | send_entry->timetosend = jiffies + |
648 | NES_RETRY_TIMEOUT; | 653 | min(timetosend, NES_MAX_TIMEOUT); |
649 | if (nexttimeout > send_entry->timetosend || | 654 | if (nexttimeout > send_entry->timetosend || |
650 | !settimer) { | 655 | !settimer) { |
651 | nexttimeout = send_entry->timetosend; | 656 | nexttimeout = send_entry->timetosend; |
@@ -666,11 +671,6 @@ static void nes_cm_timer_tick(unsigned long pass) | |||
666 | 671 | ||
667 | spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); | 672 | spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); |
668 | rem_ref_cm_node(cm_node->cm_core, cm_node); | 673 | rem_ref_cm_node(cm_node->cm_core, cm_node); |
669 | if (ret != NETDEV_TX_OK) { | ||
670 | nes_debug(NES_DBG_CM, "rexmit failed for cm_node=%p\n", | ||
671 | cm_node); | ||
672 | break; | ||
673 | } | ||
674 | } | 674 | } |
675 | 675 | ||
676 | if (settimer) { | 676 | if (settimer) { |
@@ -859,7 +859,6 @@ static struct nes_cm_listener *find_listener(struct nes_cm_core *cm_core, | |||
859 | { | 859 | { |
860 | unsigned long flags; | 860 | unsigned long flags; |
861 | struct nes_cm_listener *listen_node; | 861 | struct nes_cm_listener *listen_node; |
862 | __be32 tmp_addr = cpu_to_be32(dst_addr); | ||
863 | 862 | ||
864 | /* walk list and find cm_node associated with this session ID */ | 863 | /* walk list and find cm_node associated with this session ID */ |
865 | spin_lock_irqsave(&cm_core->listen_list_lock, flags); | 864 | spin_lock_irqsave(&cm_core->listen_list_lock, flags); |
@@ -876,9 +875,6 @@ static struct nes_cm_listener *find_listener(struct nes_cm_core *cm_core, | |||
876 | } | 875 | } |
877 | spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); | 876 | spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); |
878 | 877 | ||
879 | nes_debug(NES_DBG_CM, "Unable to find listener for %pI4:%x\n", | ||
880 | &tmp_addr, dst_port); | ||
881 | |||
882 | /* no listener */ | 878 | /* no listener */ |
883 | return NULL; | 879 | return NULL; |
884 | } | 880 | } |
@@ -1262,7 +1258,6 @@ static int rem_ref_cm_node(struct nes_cm_core *cm_core, | |||
1262 | cm_node->nesqp = NULL; | 1258 | cm_node->nesqp = NULL; |
1263 | } | 1259 | } |
1264 | 1260 | ||
1265 | cm_node->freed = 1; | ||
1266 | kfree(cm_node); | 1261 | kfree(cm_node); |
1267 | return 0; | 1262 | return 0; |
1268 | } | 1263 | } |
@@ -1331,18 +1326,20 @@ static void handle_fin_pkt(struct nes_cm_node *cm_node) | |||
1331 | nes_debug(NES_DBG_CM, "Received FIN, cm_node = %p, state = %u. " | 1326 | nes_debug(NES_DBG_CM, "Received FIN, cm_node = %p, state = %u. " |
1332 | "refcnt=%d\n", cm_node, cm_node->state, | 1327 | "refcnt=%d\n", cm_node, cm_node->state, |
1333 | atomic_read(&cm_node->ref_count)); | 1328 | atomic_read(&cm_node->ref_count)); |
1334 | cm_node->tcp_cntxt.rcv_nxt++; | ||
1335 | cleanup_retrans_entry(cm_node); | ||
1336 | switch (cm_node->state) { | 1329 | switch (cm_node->state) { |
1337 | case NES_CM_STATE_SYN_RCVD: | 1330 | case NES_CM_STATE_SYN_RCVD: |
1338 | case NES_CM_STATE_SYN_SENT: | 1331 | case NES_CM_STATE_SYN_SENT: |
1339 | case NES_CM_STATE_ESTABLISHED: | 1332 | case NES_CM_STATE_ESTABLISHED: |
1340 | case NES_CM_STATE_MPAREQ_SENT: | 1333 | case NES_CM_STATE_MPAREQ_SENT: |
1341 | case NES_CM_STATE_MPAREJ_RCVD: | 1334 | case NES_CM_STATE_MPAREJ_RCVD: |
1335 | cm_node->tcp_cntxt.rcv_nxt++; | ||
1336 | cleanup_retrans_entry(cm_node); | ||
1342 | cm_node->state = NES_CM_STATE_LAST_ACK; | 1337 | cm_node->state = NES_CM_STATE_LAST_ACK; |
1343 | send_fin(cm_node, NULL); | 1338 | send_fin(cm_node, NULL); |
1344 | break; | 1339 | break; |
1345 | case NES_CM_STATE_FIN_WAIT1: | 1340 | case NES_CM_STATE_FIN_WAIT1: |
1341 | cm_node->tcp_cntxt.rcv_nxt++; | ||
1342 | cleanup_retrans_entry(cm_node); | ||
1346 | cm_node->state = NES_CM_STATE_CLOSING; | 1343 | cm_node->state = NES_CM_STATE_CLOSING; |
1347 | send_ack(cm_node, NULL); | 1344 | send_ack(cm_node, NULL); |
1348 | /* Wait for ACK as this is simultanous close.. | 1345 | /* Wait for ACK as this is simultanous close.. |
@@ -1350,11 +1347,15 @@ static void handle_fin_pkt(struct nes_cm_node *cm_node) | |||
1350 | * Just rm the node.. Done.. */ | 1347 | * Just rm the node.. Done.. */ |
1351 | break; | 1348 | break; |
1352 | case NES_CM_STATE_FIN_WAIT2: | 1349 | case NES_CM_STATE_FIN_WAIT2: |
1350 | cm_node->tcp_cntxt.rcv_nxt++; | ||
1351 | cleanup_retrans_entry(cm_node); | ||
1353 | cm_node->state = NES_CM_STATE_TIME_WAIT; | 1352 | cm_node->state = NES_CM_STATE_TIME_WAIT; |
1354 | send_ack(cm_node, NULL); | 1353 | send_ack(cm_node, NULL); |
1355 | schedule_nes_timer(cm_node, NULL, NES_TIMER_TYPE_CLOSE, 1, 0); | 1354 | schedule_nes_timer(cm_node, NULL, NES_TIMER_TYPE_CLOSE, 1, 0); |
1356 | break; | 1355 | break; |
1357 | case NES_CM_STATE_TIME_WAIT: | 1356 | case NES_CM_STATE_TIME_WAIT: |
1357 | cm_node->tcp_cntxt.rcv_nxt++; | ||
1358 | cleanup_retrans_entry(cm_node); | ||
1358 | cm_node->state = NES_CM_STATE_CLOSED; | 1359 | cm_node->state = NES_CM_STATE_CLOSED; |
1359 | rem_ref_cm_node(cm_node->cm_core, cm_node); | 1360 | rem_ref_cm_node(cm_node->cm_core, cm_node); |
1360 | break; | 1361 | break; |
@@ -1390,7 +1391,6 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1390 | passive_state = atomic_add_return(1, &cm_node->passive_state); | 1391 | passive_state = atomic_add_return(1, &cm_node->passive_state); |
1391 | if (passive_state == NES_SEND_RESET_EVENT) | 1392 | if (passive_state == NES_SEND_RESET_EVENT) |
1392 | create_event(cm_node, NES_CM_EVENT_RESET); | 1393 | create_event(cm_node, NES_CM_EVENT_RESET); |
1393 | cleanup_retrans_entry(cm_node); | ||
1394 | cm_node->state = NES_CM_STATE_CLOSED; | 1394 | cm_node->state = NES_CM_STATE_CLOSED; |
1395 | dev_kfree_skb_any(skb); | 1395 | dev_kfree_skb_any(skb); |
1396 | break; | 1396 | break; |
@@ -1404,17 +1404,16 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1404 | active_open_err(cm_node, skb, reset); | 1404 | active_open_err(cm_node, skb, reset); |
1405 | break; | 1405 | break; |
1406 | case NES_CM_STATE_CLOSED: | 1406 | case NES_CM_STATE_CLOSED: |
1407 | cleanup_retrans_entry(cm_node); | ||
1408 | drop_packet(skb); | 1407 | drop_packet(skb); |
1409 | break; | 1408 | break; |
1409 | case NES_CM_STATE_LAST_ACK: | ||
1410 | cm_node->cm_id->rem_ref(cm_node->cm_id); | ||
1410 | case NES_CM_STATE_TIME_WAIT: | 1411 | case NES_CM_STATE_TIME_WAIT: |
1411 | cleanup_retrans_entry(cm_node); | ||
1412 | cm_node->state = NES_CM_STATE_CLOSED; | 1412 | cm_node->state = NES_CM_STATE_CLOSED; |
1413 | rem_ref_cm_node(cm_node->cm_core, cm_node); | 1413 | rem_ref_cm_node(cm_node->cm_core, cm_node); |
1414 | drop_packet(skb); | 1414 | drop_packet(skb); |
1415 | break; | 1415 | break; |
1416 | case NES_CM_STATE_FIN_WAIT1: | 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__); | 1417 | nes_debug(NES_DBG_CM, "Bad state %s[%u]\n", __func__, __LINE__); |
1419 | default: | 1418 | default: |
1420 | drop_packet(skb); | 1419 | drop_packet(skb); |
@@ -1461,6 +1460,7 @@ static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb) | |||
1461 | NES_PASSIVE_STATE_INDICATED); | 1460 | NES_PASSIVE_STATE_INDICATED); |
1462 | break; | 1461 | break; |
1463 | case NES_CM_STATE_MPAREQ_SENT: | 1462 | case NES_CM_STATE_MPAREQ_SENT: |
1463 | cleanup_retrans_entry(cm_node); | ||
1464 | if (res_type == NES_MPA_REQUEST_REJECT) { | 1464 | if (res_type == NES_MPA_REQUEST_REJECT) { |
1465 | type = NES_CM_EVENT_MPA_REJECT; | 1465 | type = NES_CM_EVENT_MPA_REJECT; |
1466 | cm_node->state = NES_CM_STATE_MPAREJ_RCVD; | 1466 | cm_node->state = NES_CM_STATE_MPAREJ_RCVD; |
@@ -1524,7 +1524,7 @@ static int check_seq(struct nes_cm_node *cm_node, struct tcphdr *tcph, | |||
1524 | rcv_wnd = cm_node->tcp_cntxt.rcv_wnd; | 1524 | rcv_wnd = cm_node->tcp_cntxt.rcv_wnd; |
1525 | if (ack_seq != loc_seq_num) | 1525 | if (ack_seq != loc_seq_num) |
1526 | err = 1; | 1526 | err = 1; |
1527 | else if ((seq + rcv_wnd) < rcv_nxt) | 1527 | else if (!between(seq, rcv_nxt, (rcv_nxt+rcv_wnd))) |
1528 | err = 1; | 1528 | err = 1; |
1529 | if (err) { | 1529 | if (err) { |
1530 | nes_debug(NES_DBG_CM, "%s[%u] create abort for cm_node=%p " | 1530 | nes_debug(NES_DBG_CM, "%s[%u] create abort for cm_node=%p " |
@@ -1658,49 +1658,39 @@ static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1658 | } | 1658 | } |
1659 | } | 1659 | } |
1660 | 1660 | ||
1661 | static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | 1661 | static int handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, |
1662 | struct tcphdr *tcph) | 1662 | struct tcphdr *tcph) |
1663 | { | 1663 | { |
1664 | int datasize = 0; | 1664 | int datasize = 0; |
1665 | u32 inc_sequence; | 1665 | u32 inc_sequence; |
1666 | u32 rem_seq_ack; | 1666 | u32 rem_seq_ack; |
1667 | u32 rem_seq; | 1667 | u32 rem_seq; |
1668 | int ret; | 1668 | int ret = 0; |
1669 | int optionsize; | 1669 | int optionsize; |
1670 | optionsize = (tcph->doff << 2) - sizeof(struct tcphdr); | 1670 | optionsize = (tcph->doff << 2) - sizeof(struct tcphdr); |
1671 | 1671 | ||
1672 | if (check_seq(cm_node, tcph, skb)) | 1672 | if (check_seq(cm_node, tcph, skb)) |
1673 | return; | 1673 | return -EINVAL; |
1674 | 1674 | ||
1675 | skb_pull(skb, tcph->doff << 2); | 1675 | skb_pull(skb, tcph->doff << 2); |
1676 | inc_sequence = ntohl(tcph->seq); | 1676 | inc_sequence = ntohl(tcph->seq); |
1677 | rem_seq = ntohl(tcph->seq); | 1677 | rem_seq = ntohl(tcph->seq); |
1678 | rem_seq_ack = ntohl(tcph->ack_seq); | 1678 | rem_seq_ack = ntohl(tcph->ack_seq); |
1679 | datasize = skb->len; | 1679 | datasize = skb->len; |
1680 | cleanup_retrans_entry(cm_node); | ||
1681 | switch (cm_node->state) { | 1680 | switch (cm_node->state) { |
1682 | case NES_CM_STATE_SYN_RCVD: | 1681 | case NES_CM_STATE_SYN_RCVD: |
1683 | /* Passive OPEN */ | 1682 | /* Passive OPEN */ |
1683 | cleanup_retrans_entry(cm_node); | ||
1684 | ret = handle_tcp_options(cm_node, tcph, skb, optionsize, 1); | 1684 | ret = handle_tcp_options(cm_node, tcph, skb, optionsize, 1); |
1685 | if (ret) | 1685 | if (ret) |
1686 | break; | 1686 | break; |
1687 | cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); | 1687 | cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); |
1688 | if (cm_node->tcp_cntxt.rem_ack_num != | ||
1689 | cm_node->tcp_cntxt.loc_seq_num) { | ||
1690 | nes_debug(NES_DBG_CM, "rem_ack_num != loc_seq_num\n"); | ||
1691 | cleanup_retrans_entry(cm_node); | ||
1692 | send_reset(cm_node, skb); | ||
1693 | return; | ||
1694 | } | ||
1695 | cm_node->state = NES_CM_STATE_ESTABLISHED; | 1688 | cm_node->state = NES_CM_STATE_ESTABLISHED; |
1696 | cleanup_retrans_entry(cm_node); | ||
1697 | if (datasize) { | 1689 | if (datasize) { |
1698 | cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; | 1690 | cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; |
1699 | handle_rcv_mpa(cm_node, skb); | 1691 | handle_rcv_mpa(cm_node, skb); |
1700 | } else { /* rcvd ACK only */ | 1692 | } else /* rcvd ACK only */ |
1701 | dev_kfree_skb_any(skb); | 1693 | dev_kfree_skb_any(skb); |
1702 | cleanup_retrans_entry(cm_node); | ||
1703 | } | ||
1704 | break; | 1694 | break; |
1705 | case NES_CM_STATE_ESTABLISHED: | 1695 | case NES_CM_STATE_ESTABLISHED: |
1706 | /* Passive OPEN */ | 1696 | /* Passive OPEN */ |
@@ -1712,15 +1702,12 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1712 | drop_packet(skb); | 1702 | drop_packet(skb); |
1713 | break; | 1703 | break; |
1714 | case NES_CM_STATE_MPAREQ_SENT: | 1704 | case NES_CM_STATE_MPAREQ_SENT: |
1715 | cleanup_retrans_entry(cm_node); | ||
1716 | cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); | 1705 | cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); |
1717 | if (datasize) { | 1706 | if (datasize) { |
1718 | cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; | 1707 | cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; |
1719 | handle_rcv_mpa(cm_node, skb); | 1708 | handle_rcv_mpa(cm_node, skb); |
1720 | } else { /* Could be just an ack pkt.. */ | 1709 | } else /* Could be just an ack pkt.. */ |
1721 | cleanup_retrans_entry(cm_node); | ||
1722 | dev_kfree_skb_any(skb); | 1710 | dev_kfree_skb_any(skb); |
1723 | } | ||
1724 | break; | 1711 | break; |
1725 | case NES_CM_STATE_LISTENING: | 1712 | case NES_CM_STATE_LISTENING: |
1726 | case NES_CM_STATE_CLOSED: | 1713 | case NES_CM_STATE_CLOSED: |
@@ -1728,11 +1715,10 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1728 | send_reset(cm_node, skb); | 1715 | send_reset(cm_node, skb); |
1729 | break; | 1716 | break; |
1730 | case NES_CM_STATE_LAST_ACK: | 1717 | case NES_CM_STATE_LAST_ACK: |
1718 | case NES_CM_STATE_CLOSING: | ||
1731 | cleanup_retrans_entry(cm_node); | 1719 | cleanup_retrans_entry(cm_node); |
1732 | cm_node->state = NES_CM_STATE_CLOSED; | 1720 | cm_node->state = NES_CM_STATE_CLOSED; |
1733 | cm_node->cm_id->rem_ref(cm_node->cm_id); | 1721 | 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); | 1722 | rem_ref_cm_node(cm_node->cm_core, cm_node); |
1737 | drop_packet(skb); | 1723 | drop_packet(skb); |
1738 | break; | 1724 | break; |
@@ -1747,9 +1733,11 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1747 | case NES_CM_STATE_MPAREQ_RCVD: | 1733 | case NES_CM_STATE_MPAREQ_RCVD: |
1748 | case NES_CM_STATE_UNKNOWN: | 1734 | case NES_CM_STATE_UNKNOWN: |
1749 | default: | 1735 | default: |
1736 | cleanup_retrans_entry(cm_node); | ||
1750 | drop_packet(skb); | 1737 | drop_packet(skb); |
1751 | break; | 1738 | break; |
1752 | } | 1739 | } |
1740 | return ret; | ||
1753 | } | 1741 | } |
1754 | 1742 | ||
1755 | 1743 | ||
@@ -1855,6 +1843,7 @@ static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1855 | enum nes_tcpip_pkt_type pkt_type = NES_PKT_TYPE_UNKNOWN; | 1843 | enum nes_tcpip_pkt_type pkt_type = NES_PKT_TYPE_UNKNOWN; |
1856 | struct tcphdr *tcph = tcp_hdr(skb); | 1844 | struct tcphdr *tcph = tcp_hdr(skb); |
1857 | u32 fin_set = 0; | 1845 | u32 fin_set = 0; |
1846 | int ret = 0; | ||
1858 | skb_pull(skb, ip_hdr(skb)->ihl << 2); | 1847 | skb_pull(skb, ip_hdr(skb)->ihl << 2); |
1859 | 1848 | ||
1860 | nes_debug(NES_DBG_CM, "process_packet: cm_node=%p state =%d syn=%d " | 1849 | nes_debug(NES_DBG_CM, "process_packet: cm_node=%p state =%d syn=%d " |
@@ -1880,17 +1869,17 @@ static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1880 | handle_synack_pkt(cm_node, skb, tcph); | 1869 | handle_synack_pkt(cm_node, skb, tcph); |
1881 | break; | 1870 | break; |
1882 | case NES_PKT_TYPE_ACK: | 1871 | case NES_PKT_TYPE_ACK: |
1883 | handle_ack_pkt(cm_node, skb, tcph); | 1872 | ret = handle_ack_pkt(cm_node, skb, tcph); |
1884 | if (fin_set) | 1873 | if (fin_set && !ret) |
1885 | handle_fin_pkt(cm_node); | 1874 | handle_fin_pkt(cm_node); |
1886 | break; | 1875 | break; |
1887 | case NES_PKT_TYPE_RST: | 1876 | case NES_PKT_TYPE_RST: |
1888 | handle_rst_pkt(cm_node, skb, tcph); | 1877 | handle_rst_pkt(cm_node, skb, tcph); |
1889 | break; | 1878 | break; |
1890 | default: | 1879 | default: |
1891 | drop_packet(skb); | 1880 | if ((fin_set) && (!check_seq(cm_node, tcph, skb))) |
1892 | if (fin_set) | ||
1893 | handle_fin_pkt(cm_node); | 1881 | handle_fin_pkt(cm_node); |
1882 | drop_packet(skb); | ||
1894 | break; | 1883 | break; |
1895 | } | 1884 | } |
1896 | } | 1885 | } |
@@ -1999,13 +1988,17 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core, | |||
1999 | if (loopbackremotelistener == NULL) { | 1988 | if (loopbackremotelistener == NULL) { |
2000 | create_event(cm_node, NES_CM_EVENT_ABORTED); | 1989 | create_event(cm_node, NES_CM_EVENT_ABORTED); |
2001 | } else { | 1990 | } else { |
2002 | atomic_inc(&cm_loopbacks); | ||
2003 | loopback_cm_info = *cm_info; | 1991 | loopback_cm_info = *cm_info; |
2004 | loopback_cm_info.loc_port = cm_info->rem_port; | 1992 | loopback_cm_info.loc_port = cm_info->rem_port; |
2005 | loopback_cm_info.rem_port = cm_info->loc_port; | 1993 | loopback_cm_info.rem_port = cm_info->loc_port; |
2006 | loopback_cm_info.cm_id = loopbackremotelistener->cm_id; | 1994 | loopback_cm_info.cm_id = loopbackremotelistener->cm_id; |
2007 | loopbackremotenode = make_cm_node(cm_core, nesvnic, | 1995 | loopbackremotenode = make_cm_node(cm_core, nesvnic, |
2008 | &loopback_cm_info, loopbackremotelistener); | 1996 | &loopback_cm_info, loopbackremotelistener); |
1997 | if (!loopbackremotenode) { | ||
1998 | rem_ref_cm_node(cm_node->cm_core, cm_node); | ||
1999 | return NULL; | ||
2000 | } | ||
2001 | atomic_inc(&cm_loopbacks); | ||
2009 | loopbackremotenode->loopbackpartner = cm_node; | 2002 | loopbackremotenode->loopbackpartner = cm_node; |
2010 | loopbackremotenode->tcp_cntxt.rcv_wscale = | 2003 | loopbackremotenode->tcp_cntxt.rcv_wscale = |
2011 | NES_CM_DEFAULT_RCV_WND_SCALE; | 2004 | NES_CM_DEFAULT_RCV_WND_SCALE; |
@@ -2690,6 +2683,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2690 | struct ib_mr *ibmr = NULL; | 2683 | struct ib_mr *ibmr = NULL; |
2691 | struct ib_phys_buf ibphysbuf; | 2684 | struct ib_phys_buf ibphysbuf; |
2692 | struct nes_pd *nespd; | 2685 | struct nes_pd *nespd; |
2686 | u64 tagged_offset; | ||
2693 | 2687 | ||
2694 | 2688 | ||
2695 | 2689 | ||
@@ -2711,7 +2705,6 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2711 | /* associate the node with the QP */ | 2705 | /* associate the node with the QP */ |
2712 | nesqp->cm_node = (void *)cm_node; | 2706 | nesqp->cm_node = (void *)cm_node; |
2713 | cm_node->nesqp = nesqp; | 2707 | cm_node->nesqp = nesqp; |
2714 | nes_add_ref(&nesqp->ibqp); | ||
2715 | 2708 | ||
2716 | nes_debug(NES_DBG_CM, "QP%u, cm_node=%p, jiffies = %lu listener = %p\n", | 2709 | nes_debug(NES_DBG_CM, "QP%u, cm_node=%p, jiffies = %lu listener = %p\n", |
2717 | nesqp->hwqp.qp_id, cm_node, jiffies, cm_node->listener); | 2710 | nesqp->hwqp.qp_id, cm_node, jiffies, cm_node->listener); |
@@ -2755,14 +2748,18 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2755 | ibphysbuf.addr = nesqp->ietf_frame_pbase; | 2748 | ibphysbuf.addr = nesqp->ietf_frame_pbase; |
2756 | ibphysbuf.size = conn_param->private_data_len + | 2749 | ibphysbuf.size = conn_param->private_data_len + |
2757 | sizeof(struct ietf_mpa_frame); | 2750 | sizeof(struct ietf_mpa_frame); |
2751 | tagged_offset = (u64)(unsigned long)nesqp->ietf_frame; | ||
2758 | ibmr = nesibdev->ibdev.reg_phys_mr((struct ib_pd *)nespd, | 2752 | ibmr = nesibdev->ibdev.reg_phys_mr((struct ib_pd *)nespd, |
2759 | &ibphysbuf, 1, | 2753 | &ibphysbuf, 1, |
2760 | IB_ACCESS_LOCAL_WRITE, | 2754 | IB_ACCESS_LOCAL_WRITE, |
2761 | (u64 *)&nesqp->ietf_frame); | 2755 | &tagged_offset); |
2762 | if (!ibmr) { | 2756 | if (!ibmr) { |
2763 | nes_debug(NES_DBG_CM, "Unable to register memory region" | 2757 | nes_debug(NES_DBG_CM, "Unable to register memory region" |
2764 | "for lSMM for cm_node = %p \n", | 2758 | "for lSMM for cm_node = %p \n", |
2765 | cm_node); | 2759 | cm_node); |
2760 | pci_free_consistent(nesdev->pcidev, | ||
2761 | nesqp->private_data_len+sizeof(struct ietf_mpa_frame), | ||
2762 | nesqp->ietf_frame, nesqp->ietf_frame_pbase); | ||
2766 | return -ENOMEM; | 2763 | return -ENOMEM; |
2767 | } | 2764 | } |
2768 | 2765 | ||
@@ -2782,7 +2779,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2782 | sizeof(struct ietf_mpa_frame)); | 2779 | sizeof(struct ietf_mpa_frame)); |
2783 | set_wqe_64bit_value(wqe->wqe_words, | 2780 | set_wqe_64bit_value(wqe->wqe_words, |
2784 | NES_IWARP_SQ_WQE_FRAG0_LOW_IDX, | 2781 | NES_IWARP_SQ_WQE_FRAG0_LOW_IDX, |
2785 | (u64)nesqp->ietf_frame); | 2782 | (u64)(unsigned long)nesqp->ietf_frame); |
2786 | wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = | 2783 | wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = |
2787 | cpu_to_le32(conn_param->private_data_len + | 2784 | cpu_to_le32(conn_param->private_data_len + |
2788 | sizeof(struct ietf_mpa_frame)); | 2785 | sizeof(struct ietf_mpa_frame)); |
@@ -2879,6 +2876,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2879 | 2876 | ||
2880 | /* notify OF layer that accept event was successful */ | 2877 | /* notify OF layer that accept event was successful */ |
2881 | cm_id->add_ref(cm_id); | 2878 | cm_id->add_ref(cm_id); |
2879 | nes_add_ref(&nesqp->ibqp); | ||
2882 | 2880 | ||
2883 | cm_event.event = IW_CM_EVENT_ESTABLISHED; | 2881 | cm_event.event = IW_CM_EVENT_ESTABLISHED; |
2884 | cm_event.status = IW_CM_EVENT_STATUS_ACCEPTED; | 2882 | cm_event.status = IW_CM_EVENT_STATUS_ACCEPTED; |
@@ -2959,6 +2957,7 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2959 | struct nes_device *nesdev; | 2957 | struct nes_device *nesdev; |
2960 | struct nes_cm_node *cm_node; | 2958 | struct nes_cm_node *cm_node; |
2961 | struct nes_cm_info cm_info; | 2959 | struct nes_cm_info cm_info; |
2960 | int apbvt_set = 0; | ||
2962 | 2961 | ||
2963 | ibqp = nes_get_qp(cm_id->device, conn_param->qpn); | 2962 | ibqp = nes_get_qp(cm_id->device, conn_param->qpn); |
2964 | if (!ibqp) | 2963 | if (!ibqp) |
@@ -2996,9 +2995,11 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2996 | conn_param->private_data_len); | 2995 | conn_param->private_data_len); |
2997 | 2996 | ||
2998 | if (cm_id->local_addr.sin_addr.s_addr != | 2997 | if (cm_id->local_addr.sin_addr.s_addr != |
2999 | cm_id->remote_addr.sin_addr.s_addr) | 2998 | cm_id->remote_addr.sin_addr.s_addr) { |
3000 | nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port), | 2999 | nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port), |
3001 | PCI_FUNC(nesdev->pcidev->devfn), NES_MANAGE_APBVT_ADD); | 3000 | PCI_FUNC(nesdev->pcidev->devfn), NES_MANAGE_APBVT_ADD); |
3001 | apbvt_set = 1; | ||
3002 | } | ||
3002 | 3003 | ||
3003 | /* set up the connection params for the node */ | 3004 | /* set up the connection params for the node */ |
3004 | cm_info.loc_addr = htonl(cm_id->local_addr.sin_addr.s_addr); | 3005 | cm_info.loc_addr = htonl(cm_id->local_addr.sin_addr.s_addr); |
@@ -3015,8 +3016,7 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
3015 | conn_param->private_data_len, (void *)conn_param->private_data, | 3016 | conn_param->private_data_len, (void *)conn_param->private_data, |
3016 | &cm_info); | 3017 | &cm_info); |
3017 | if (!cm_node) { | 3018 | if (!cm_node) { |
3018 | if (cm_id->local_addr.sin_addr.s_addr != | 3019 | if (apbvt_set) |
3019 | cm_id->remote_addr.sin_addr.s_addr) | ||
3020 | nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port), | 3020 | nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port), |
3021 | PCI_FUNC(nesdev->pcidev->devfn), | 3021 | PCI_FUNC(nesdev->pcidev->devfn), |
3022 | NES_MANAGE_APBVT_DEL); | 3022 | NES_MANAGE_APBVT_DEL); |
@@ -3025,7 +3025,7 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
3025 | return -ENOMEM; | 3025 | return -ENOMEM; |
3026 | } | 3026 | } |
3027 | 3027 | ||
3028 | cm_node->apbvt_set = 1; | 3028 | cm_node->apbvt_set = apbvt_set; |
3029 | nesqp->cm_node = cm_node; | 3029 | nesqp->cm_node = cm_node; |
3030 | cm_node->nesqp = nesqp; | 3030 | cm_node->nesqp = nesqp; |
3031 | nes_add_ref(&nesqp->ibqp); | 3031 | nes_add_ref(&nesqp->ibqp); |