diff options
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/cm.c | 412 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/device.c | 85 | ||||
| -rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 9 | ||||
| -rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/t4_msg.h | 46 |
4 files changed, 497 insertions, 55 deletions
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 4878704b6d7..036ddd28152 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c | |||
| @@ -38,10 +38,12 @@ | |||
| 38 | #include <linux/inetdevice.h> | 38 | #include <linux/inetdevice.h> |
| 39 | #include <linux/ip.h> | 39 | #include <linux/ip.h> |
| 40 | #include <linux/tcp.h> | 40 | #include <linux/tcp.h> |
| 41 | #include <linux/if_vlan.h> | ||
| 41 | 42 | ||
| 42 | #include <net/neighbour.h> | 43 | #include <net/neighbour.h> |
| 43 | #include <net/netevent.h> | 44 | #include <net/netevent.h> |
| 44 | #include <net/route.h> | 45 | #include <net/route.h> |
| 46 | #include <net/tcp.h> | ||
| 45 | 47 | ||
| 46 | #include "iw_cxgb4.h" | 48 | #include "iw_cxgb4.h" |
| 47 | 49 | ||
| @@ -1569,13 +1571,14 @@ static int pass_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 1569 | struct c4iw_listen_ep *ep = lookup_stid(t, stid); | 1571 | struct c4iw_listen_ep *ep = lookup_stid(t, stid); |
| 1570 | 1572 | ||
| 1571 | if (!ep) { | 1573 | if (!ep) { |
| 1572 | printk(KERN_ERR MOD "stid %d lookup failure!\n", stid); | 1574 | PDBG("%s stid %d lookup failure!\n", __func__, stid); |
| 1573 | return 0; | 1575 | goto out; |
| 1574 | } | 1576 | } |
| 1575 | PDBG("%s ep %p status %d error %d\n", __func__, ep, | 1577 | PDBG("%s ep %p status %d error %d\n", __func__, ep, |
| 1576 | rpl->status, status2errno(rpl->status)); | 1578 | rpl->status, status2errno(rpl->status)); |
| 1577 | c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status)); | 1579 | c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status)); |
| 1578 | 1580 | ||
| 1581 | out: | ||
| 1579 | return 0; | 1582 | return 0; |
| 1580 | } | 1583 | } |
| 1581 | 1584 | ||
| @@ -1779,15 +1782,23 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 1779 | unsigned int hwtid = GET_TID(req); | 1782 | unsigned int hwtid = GET_TID(req); |
| 1780 | struct dst_entry *dst; | 1783 | struct dst_entry *dst; |
| 1781 | struct rtable *rt; | 1784 | struct rtable *rt; |
| 1782 | __be32 local_ip, peer_ip; | 1785 | __be32 local_ip, peer_ip = 0; |
| 1783 | __be16 local_port, peer_port; | 1786 | __be16 local_port, peer_port; |
| 1784 | int err; | 1787 | int err; |
| 1788 | u16 peer_mss = ntohs(req->tcpopt.mss); | ||
| 1785 | 1789 | ||
| 1786 | parent_ep = lookup_stid(t, stid); | 1790 | parent_ep = lookup_stid(t, stid); |
| 1787 | PDBG("%s parent ep %p tid %u\n", __func__, parent_ep, hwtid); | 1791 | if (!parent_ep) { |
| 1788 | 1792 | PDBG("%s connect request on invalid stid %d\n", __func__, stid); | |
| 1793 | goto reject; | ||
| 1794 | } | ||
| 1789 | get_4tuple(req, &local_ip, &peer_ip, &local_port, &peer_port); | 1795 | get_4tuple(req, &local_ip, &peer_ip, &local_port, &peer_port); |
| 1790 | 1796 | ||
| 1797 | PDBG("%s parent ep %p hwtid %u laddr 0x%x raddr 0x%x lport %d " \ | ||
| 1798 | "rport %d peer_mss %d\n", __func__, parent_ep, hwtid, | ||
| 1799 | ntohl(local_ip), ntohl(peer_ip), ntohs(local_port), | ||
| 1800 | ntohs(peer_port), peer_mss); | ||
| 1801 | |||
| 1791 | if (state_read(&parent_ep->com) != LISTEN) { | 1802 | if (state_read(&parent_ep->com) != LISTEN) { |
| 1792 | printk(KERN_ERR "%s - listening ep not in LISTEN\n", | 1803 | printk(KERN_ERR "%s - listening ep not in LISTEN\n", |
| 1793 | __func__); | 1804 | __func__); |
| @@ -1821,6 +1832,9 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 1821 | goto reject; | 1832 | goto reject; |
| 1822 | } | 1833 | } |
| 1823 | 1834 | ||
| 1835 | if (peer_mss && child_ep->mtu > (peer_mss + 40)) | ||
| 1836 | child_ep->mtu = peer_mss + 40; | ||
| 1837 | |||
| 1824 | state_set(&child_ep->com, CONNECTING); | 1838 | state_set(&child_ep->com, CONNECTING); |
| 1825 | child_ep->com.dev = dev; | 1839 | child_ep->com.dev = dev; |
| 1826 | child_ep->com.cm_id = NULL; | 1840 | child_ep->com.cm_id = NULL; |
| @@ -1861,6 +1875,9 @@ static int pass_establish(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 1861 | ep->snd_seq = be32_to_cpu(req->snd_isn); | 1875 | ep->snd_seq = be32_to_cpu(req->snd_isn); |
| 1862 | ep->rcv_seq = be32_to_cpu(req->rcv_isn); | 1876 | ep->rcv_seq = be32_to_cpu(req->rcv_isn); |
| 1863 | 1877 | ||
| 1878 | PDBG("%s ep %p hwtid %u tcp_opt 0x%02x\n", __func__, ep, tid, | ||
| 1879 | ntohs(req->tcp_opt)); | ||
| 1880 | |||
| 1864 | set_emss(ep, ntohs(req->tcp_opt)); | 1881 | set_emss(ep, ntohs(req->tcp_opt)); |
| 1865 | 1882 | ||
| 1866 | dst_confirm(ep->dst); | 1883 | dst_confirm(ep->dst); |
| @@ -2478,7 +2495,6 @@ int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog) | |||
| 2478 | struct c4iw_dev *dev = to_c4iw_dev(cm_id->device); | 2495 | struct c4iw_dev *dev = to_c4iw_dev(cm_id->device); |
| 2479 | struct c4iw_listen_ep *ep; | 2496 | struct c4iw_listen_ep *ep; |
| 2480 | 2497 | ||
| 2481 | |||
| 2482 | might_sleep(); | 2498 | might_sleep(); |
| 2483 | 2499 | ||
| 2484 | ep = alloc_ep(sizeof(*ep), GFP_KERNEL); | 2500 | ep = alloc_ep(sizeof(*ep), GFP_KERNEL); |
| @@ -2497,30 +2513,49 @@ int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog) | |||
| 2497 | /* | 2513 | /* |
| 2498 | * Allocate a server TID. | 2514 | * Allocate a server TID. |
| 2499 | */ | 2515 | */ |
| 2500 | ep->stid = cxgb4_alloc_stid(dev->rdev.lldi.tids, PF_INET, ep); | 2516 | if (dev->rdev.lldi.enable_fw_ofld_conn) |
| 2517 | ep->stid = cxgb4_alloc_sftid(dev->rdev.lldi.tids, PF_INET, ep); | ||
| 2518 | else | ||
| 2519 | ep->stid = cxgb4_alloc_stid(dev->rdev.lldi.tids, PF_INET, ep); | ||
| 2520 | |||
| 2501 | if (ep->stid == -1) { | 2521 | if (ep->stid == -1) { |
| 2502 | printk(KERN_ERR MOD "%s - cannot alloc stid.\n", __func__); | 2522 | printk(KERN_ERR MOD "%s - cannot alloc stid.\n", __func__); |
| 2503 | err = -ENOMEM; | 2523 | err = -ENOMEM; |
| 2504 | goto fail2; | 2524 | goto fail2; |
| 2505 | } | 2525 | } |
| 2506 | |||
| 2507 | state_set(&ep->com, LISTEN); | 2526 | state_set(&ep->com, LISTEN); |
| 2508 | c4iw_init_wr_wait(&ep->com.wr_wait); | 2527 | if (dev->rdev.lldi.enable_fw_ofld_conn) { |
| 2509 | err = cxgb4_create_server(ep->com.dev->rdev.lldi.ports[0], ep->stid, | 2528 | do { |
| 2510 | ep->com.local_addr.sin_addr.s_addr, | 2529 | err = cxgb4_create_server_filter( |
| 2511 | ep->com.local_addr.sin_port, | 2530 | ep->com.dev->rdev.lldi.ports[0], ep->stid, |
| 2512 | ep->com.dev->rdev.lldi.rxq_ids[0]); | 2531 | ep->com.local_addr.sin_addr.s_addr, |
| 2513 | if (err) | 2532 | ep->com.local_addr.sin_port, |
| 2514 | goto fail3; | 2533 | ep->com.dev->rdev.lldi.rxq_ids[0]); |
| 2515 | 2534 | if (err == -EBUSY) { | |
| 2516 | /* wait for pass_open_rpl */ | 2535 | set_current_state(TASK_UNINTERRUPTIBLE); |
| 2517 | err = c4iw_wait_for_reply(&ep->com.dev->rdev, &ep->com.wr_wait, 0, 0, | 2536 | schedule_timeout(usecs_to_jiffies(100)); |
| 2518 | __func__); | 2537 | } |
| 2538 | } while (err == -EBUSY); | ||
| 2539 | } else { | ||
| 2540 | c4iw_init_wr_wait(&ep->com.wr_wait); | ||
| 2541 | err = cxgb4_create_server(ep->com.dev->rdev.lldi.ports[0], | ||
| 2542 | ep->stid, ep->com.local_addr.sin_addr.s_addr, | ||
| 2543 | ep->com.local_addr.sin_port, | ||
| 2544 | ep->com.dev->rdev.lldi.rxq_ids[0]); | ||
| 2545 | if (!err) | ||
| 2546 | err = c4iw_wait_for_reply(&ep->com.dev->rdev, | ||
| 2547 | &ep->com.wr_wait, | ||
| 2548 | 0, 0, __func__); | ||
| 2549 | } | ||
| 2519 | if (!err) { | 2550 | if (!err) { |
| 2520 | cm_id->provider_data = ep; | 2551 | cm_id->provider_data = ep; |
| 2521 | goto out; | 2552 | goto out; |
| 2522 | } | 2553 | } |
| 2523 | fail3: | 2554 | pr_err("%s cxgb4_create_server/filter failed err %d " \ |
| 2555 | "stid %d laddr %08x lport %d\n", \ | ||
| 2556 | __func__, err, ep->stid, | ||
| 2557 | ntohl(ep->com.local_addr.sin_addr.s_addr), | ||
| 2558 | ntohs(ep->com.local_addr.sin_port)); | ||
| 2524 | cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, PF_INET); | 2559 | cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, PF_INET); |
| 2525 | fail2: | 2560 | fail2: |
| 2526 | cm_id->rem_ref(cm_id); | 2561 | cm_id->rem_ref(cm_id); |
| @@ -2539,12 +2574,18 @@ int c4iw_destroy_listen(struct iw_cm_id *cm_id) | |||
| 2539 | 2574 | ||
| 2540 | might_sleep(); | 2575 | might_sleep(); |
| 2541 | state_set(&ep->com, DEAD); | 2576 | state_set(&ep->com, DEAD); |
| 2542 | c4iw_init_wr_wait(&ep->com.wr_wait); | 2577 | if (ep->com.dev->rdev.lldi.enable_fw_ofld_conn) { |
| 2543 | err = listen_stop(ep); | 2578 | err = cxgb4_remove_server_filter( |
| 2544 | if (err) | 2579 | ep->com.dev->rdev.lldi.ports[0], ep->stid, |
| 2545 | goto done; | 2580 | ep->com.dev->rdev.lldi.rxq_ids[0], 0); |
| 2546 | err = c4iw_wait_for_reply(&ep->com.dev->rdev, &ep->com.wr_wait, 0, 0, | 2581 | } else { |
| 2547 | __func__); | 2582 | c4iw_init_wr_wait(&ep->com.wr_wait); |
| 2583 | err = listen_stop(ep); | ||
| 2584 | if (err) | ||
| 2585 | goto done; | ||
| 2586 | err = c4iw_wait_for_reply(&ep->com.dev->rdev, &ep->com.wr_wait, | ||
| 2587 | 0, 0, __func__); | ||
| 2588 | } | ||
| 2548 | cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, PF_INET); | 2589 | cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, PF_INET); |
| 2549 | done: | 2590 | done: |
| 2550 | cm_id->rem_ref(cm_id); | ||
