diff options
-rw-r--r-- | drivers/infiniband/hw/cxgb4/cm.c | 180 | ||||
-rw-r--r-- | drivers/infiniband/hw/cxgb4/device.c | 81 | ||||
-rw-r--r-- | drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 44 |
3 files changed, 262 insertions, 43 deletions
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 1f863a96a480..7de6c9fcf883 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2009-2010 Chelsio, Inc. All rights reserved. | 2 | * Copyright (c) 2009-2014 Chelsio, Inc. All rights reserved. |
3 | * | 3 | * |
4 | * This software is available to you under a choice of one of two | 4 | * This software is available to you under a choice of one of two |
5 | * licenses. You may choose to be licensed under the terms of the GNU | 5 | * licenses. You may choose to be licensed under the terms of the GNU |
@@ -294,6 +294,12 @@ void _c4iw_free_ep(struct kref *kref) | |||
294 | dst_release(ep->dst); | 294 | dst_release(ep->dst); |
295 | cxgb4_l2t_release(ep->l2t); | 295 | cxgb4_l2t_release(ep->l2t); |
296 | } | 296 | } |
297 | if (test_bit(RELEASE_MAPINFO, &ep->com.flags)) { | ||
298 | print_addr(&ep->com, __func__, "remove_mapinfo/mapping"); | ||
299 | iwpm_remove_mapinfo(&ep->com.local_addr, | ||
300 | &ep->com.mapped_local_addr); | ||
301 | iwpm_remove_mapping(&ep->com.local_addr, RDMA_NL_C4IW); | ||
302 | } | ||
297 | kfree(ep); | 303 | kfree(ep); |
298 | } | 304 | } |
299 | 305 | ||
@@ -528,6 +534,38 @@ static int send_abort(struct c4iw_ep *ep, struct sk_buff *skb, gfp_t gfp) | |||
528 | return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t); | 534 | return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t); |
529 | } | 535 | } |
530 | 536 | ||
537 | /* | ||
538 | * c4iw_form_pm_msg - Form a port mapper message with mapping info | ||
539 | */ | ||
540 | static void c4iw_form_pm_msg(struct c4iw_ep *ep, | ||
541 | struct iwpm_sa_data *pm_msg) | ||
542 | { | ||
543 | memcpy(&pm_msg->loc_addr, &ep->com.local_addr, | ||
544 | sizeof(ep->com.local_addr)); | ||
545 | memcpy(&pm_msg->rem_addr, &ep->com.remote_addr, | ||
546 | sizeof(ep->com.remote_addr)); | ||
547 | } | ||
548 | |||
549 | /* | ||
550 | * c4iw_form_reg_msg - Form a port mapper message with dev info | ||
551 | */ | ||
552 | static void c4iw_form_reg_msg(struct c4iw_dev *dev, | ||
553 | struct iwpm_dev_data *pm_msg) | ||
554 | { | ||
555 | memcpy(pm_msg->dev_name, dev->ibdev.name, IWPM_DEVNAME_SIZE); | ||
556 | memcpy(pm_msg->if_name, dev->rdev.lldi.ports[0]->name, | ||
557 | IWPM_IFNAME_SIZE); | ||
558 | } | ||
559 | |||
560 | static void c4iw_record_pm_msg(struct c4iw_ep *ep, | ||
561 | struct iwpm_sa_data *pm_msg) | ||
562 | { | ||
563 | memcpy(&ep->com.mapped_local_addr, &pm_msg->mapped_loc_addr, | ||
564 | sizeof(ep->com.mapped_local_addr)); | ||
565 | memcpy(&ep->com.mapped_remote_addr, &pm_msg->mapped_rem_addr, | ||
566 | sizeof(ep->com.mapped_remote_addr)); | ||
567 | } | ||
568 | |||
531 | static int send_connect(struct c4iw_ep *ep) | 569 | static int send_connect(struct c4iw_ep *ep) |
532 | { | 570 | { |
533 | struct cpl_act_open_req *req; | 571 | struct cpl_act_open_req *req; |
@@ -546,10 +584,14 @@ static int send_connect(struct c4iw_ep *ep) | |||
546 | int sizev6 = is_t4(ep->com.dev->rdev.lldi.adapter_type) ? | 584 | int sizev6 = is_t4(ep->com.dev->rdev.lldi.adapter_type) ? |
547 | sizeof(struct cpl_act_open_req6) : | 585 | sizeof(struct cpl_act_open_req6) : |
548 | sizeof(struct cpl_t5_act_open_req6); | 586 | sizeof(struct cpl_t5_act_open_req6); |
549 | struct sockaddr_in *la = (struct sockaddr_in *)&ep->com.local_addr; | 587 | struct sockaddr_in *la = (struct sockaddr_in *) |
550 | struct sockaddr_in *ra = (struct sockaddr_in *)&ep->com.remote_addr; | 588 | &ep->com.mapped_local_addr; |
551 | struct sockaddr_in6 *la6 = (struct sockaddr_in6 *)&ep->com.local_addr; | 589 | struct sockaddr_in *ra = (struct sockaddr_in *) |
552 | struct sockaddr_in6 *ra6 = (struct sockaddr_in6 *)&ep->com.remote_addr; | 590 | &ep->com.mapped_remote_addr; |
591 | struct sockaddr_in6 *la6 = (struct sockaddr_in6 *) | ||
592 | &ep->com.mapped_local_addr; | ||
593 | struct sockaddr_in6 *ra6 = (struct sockaddr_in6 *) | ||
594 | &ep->com.mapped_remote_addr; | ||
553 | 595 | ||
554 | wrlen = (ep->com.remote_addr.ss_family == AF_INET) ? | 596 | wrlen = (ep->com.remote_addr.ss_family == AF_INET) ? |
555 | roundup(sizev4, 16) : | 597 | roundup(sizev4, 16) : |
@@ -1627,10 +1669,10 @@ static void send_fw_act_open_req(struct c4iw_ep *ep, unsigned int atid) | |||
1627 | req->le.filter = cpu_to_be32(cxgb4_select_ntuple( | 1669 | req->le.filter = cpu_to_be32(cxgb4_select_ntuple( |
1628 | ep->com.dev->rdev.lldi.ports[0], | 1670 | ep->com.dev->rdev.lldi.ports[0], |
1629 | ep->l2t)); | 1671 | ep->l2t)); |
1630 | sin = (struct sockaddr_in *)&ep->com.local_addr; | 1672 | sin = (struct sockaddr_in *)&ep->com.mapped_local_addr; |
1631 | req->le.lport = sin->sin_port; | 1673 | req->le.lport = sin->sin_port; |
1632 | req->le.u.ipv4.lip = sin->sin_addr.s_addr; | 1674 | req->le.u.ipv4.lip = sin->sin_addr.s_addr; |
1633 | sin = (struct sockaddr_in *)&ep->com.remote_addr; | 1675 | sin = (struct sockaddr_in *)&ep->com.mapped_remote_addr; |
1634 | req->le.pport = sin->sin_port; | 1676 | req->le.pport = sin->sin_port; |
1635 | req->le.u.ipv4.pip = sin->sin_addr.s_addr; | 1677 | req->le.u.ipv4.pip = sin->sin_addr.s_addr; |
1636 | req->tcb.t_state_to_astid = | 1678 | req->tcb.t_state_to_astid = |
@@ -1870,10 +1912,10 @@ static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1870 | struct sockaddr_in6 *ra6; | 1912 | struct sockaddr_in6 *ra6; |
1871 | 1913 | ||
1872 | ep = lookup_atid(t, atid); | 1914 | ep = lookup_atid(t, atid); |
1873 | la = (struct sockaddr_in *)&ep->com.local_addr; | 1915 | la = (struct sockaddr_in *)&ep->com.mapped_local_addr; |
1874 | ra = (struct sockaddr_in *)&ep->com.remote_addr; | 1916 | ra = (struct sockaddr_in *)&ep->com.mapped_remote_addr; |
1875 | la6 = (struct sockaddr_in6 *)&ep->com.local_addr; | 1917 | la6 = (struct sockaddr_in6 *)&ep->com.mapped_local_addr; |
1876 | ra6 = (struct sockaddr_in6 *)&ep->com.remote_addr; | 1918 | ra6 = (struct sockaddr_in6 *)&ep->com.mapped_remote_addr; |
1877 | 1919 | ||
1878 | PDBG("%s ep %p atid %u status %u errno %d\n", __func__, ep, atid, | 1920 | PDBG("%s ep %p atid %u status %u errno %d\n", __func__, ep, atid, |
1879 | status, status2errno(status)); | 1921 | status, status2errno(status)); |
@@ -2730,13 +2772,15 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2730 | struct c4iw_dev *dev = to_c4iw_dev(cm_id->device); | 2772 | struct c4iw_dev *dev = to_c4iw_dev(cm_id->device); |
2731 | struct c4iw_ep *ep; | 2773 | struct c4iw_ep *ep; |
2732 | int err = 0; | 2774 | int err = 0; |
2733 | struct sockaddr_in *laddr = (struct sockaddr_in *)&cm_id->local_addr; | 2775 | struct sockaddr_in *laddr; |
2734 | struct sockaddr_in *raddr = (struct sockaddr_in *)&cm_id->remote_addr; | 2776 | struct sockaddr_in *raddr; |
2735 | struct sockaddr_in6 *laddr6 = (struct sockaddr_in6 *)&cm_id->local_addr; | 2777 | struct sockaddr_in6 *laddr6; |
2736 | struct sockaddr_in6 *raddr6 = (struct sockaddr_in6 *) | 2778 | struct sockaddr_in6 *raddr6; |
2737 | &cm_id->remote_addr; | 2779 | struct iwpm_dev_data pm_reg_msg; |
2780 | struct iwpm_sa_data pm_msg; | ||
2738 | __u8 *ra; | 2781 | __u8 *ra; |
2739 | int iptype; | 2782 | int iptype; |
2783 | int iwpm_err = 0; | ||
2740 | 2784 | ||
2741 | if ((conn_param->ord > c4iw_max_read_depth) || | 2785 | if ((conn_param->ord > c4iw_max_read_depth) || |
2742 | (conn_param->ird > c4iw_max_read_depth)) { | 2786 | (conn_param->ird > c4iw_max_read_depth)) { |
@@ -2767,7 +2811,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2767 | if (!ep->com.qp) { | 2811 | if (!ep->com.qp) { |
2768 | PDBG("%s qpn 0x%x not found!\n", __func__, conn_param->qpn); | 2812 | PDBG("%s qpn 0x%x not found!\n", __func__, conn_param->qpn); |
2769 | err = -EINVAL; | 2813 | err = -EINVAL; |
2770 | goto fail2; | 2814 | goto fail1; |
2771 | } | 2815 | } |
2772 | ref_qp(ep); | 2816 | ref_qp(ep); |
2773 | PDBG("%s qpn 0x%x qp %p cm_id %p\n", __func__, conn_param->qpn, | 2817 | PDBG("%s qpn 0x%x qp %p cm_id %p\n", __func__, conn_param->qpn, |
@@ -2780,10 +2824,50 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2780 | if (ep->atid == -1) { | 2824 | if (ep->atid == -1) { |
2781 | printk(KERN_ERR MOD "%s - cannot alloc atid.\n", __func__); | 2825 | printk(KERN_ERR MOD "%s - cannot alloc atid.\n", __func__); |
2782 | err = -ENOMEM; | 2826 | err = -ENOMEM; |
2783 | goto fail2; | 2827 | goto fail1; |
2784 | } | 2828 | } |
2785 | insert_handle(dev, &dev->atid_idr, ep, ep->atid); | 2829 | insert_handle(dev, &dev->atid_idr, ep, ep->atid); |
2786 | 2830 | ||
2831 | memcpy(&ep->com.local_addr, &cm_id->local_addr, | ||
2832 | sizeof(ep->com.local_addr)); | ||
2833 | memcpy(&ep->com.remote_addr, &cm_id->remote_addr, | ||
2834 | sizeof(ep->com.remote_addr)); | ||
2835 | |||
2836 | /* No port mapper available, go with the specified peer information */ | ||
2837 | memcpy(&ep->com.mapped_local_addr, &cm_id->local_addr, | ||
2838 | sizeof(ep->com.mapped_local_addr)); | ||
2839 | memcpy(&ep->com.mapped_remote_addr, &cm_id->remote_addr, | ||
2840 | sizeof(ep->com.mapped_remote_addr)); | ||
2841 | |||
2842 | c4iw_form_reg_msg(dev, &pm_reg_msg); | ||
2843 | iwpm_err = iwpm_register_pid(&pm_reg_msg, RDMA_NL_C4IW); | ||
2844 | if (iwpm_err) { | ||
2845 | PDBG("%s: Port Mapper reg pid fail (err = %d).\n", | ||
2846 | __func__, iwpm_err); | ||
2847 | } | ||
2848 | if (iwpm_valid_pid() && !iwpm_err) { | ||
2849 | c4iw_form_pm_msg(ep, &pm_msg); | ||
2850 | iwpm_err = iwpm_add_and_query_mapping(&pm_msg, RDMA_NL_C4IW); | ||
2851 | if (iwpm_err) | ||
2852 | PDBG("%s: Port Mapper query fail (err = %d).\n", | ||
2853 | __func__, iwpm_err); | ||
2854 | else | ||
2855 | c4iw_record_pm_msg(ep, &pm_msg); | ||
2856 | } | ||
2857 | if (iwpm_create_mapinfo(&ep->com.local_addr, | ||
2858 | &ep->com.mapped_local_addr, RDMA_NL_C4IW)) { | ||
2859 | iwpm_remove_mapping(&ep->com.local_addr, RDMA_NL_C4IW); | ||
2860 | err = -ENOMEM; | ||
2861 | goto fail1; | ||
2862 | } | ||
2863 | print_addr(&ep->com, __func__, "add_query/create_mapinfo"); | ||
2864 | set_bit(RELEASE_MAPINFO, &ep->com.flags); | ||
2865 | |||
2866 | laddr = (struct sockaddr_in *)&ep->com.mapped_local_addr; | ||
2867 | raddr = (struct sockaddr_in *)&ep->com.mapped_remote_addr; | ||
2868 | laddr6 = (struct sockaddr_in6 *)&ep->com.mapped_local_addr; | ||
2869 | raddr6 = (struct sockaddr_in6 *) &ep->com.mapped_remote_addr; | ||
2870 | |||
2787 | if (cm_id->remote_addr.ss_family == AF_INET) { | 2871 | if (cm_id->remote_addr.ss_family == AF_INET) { |
2788 | iptype = 4; | 2872 | iptype = 4; |
2789 | ra = (__u8 *)&raddr->sin_addr; | 2873 | ra = (__u8 *)&raddr->sin_addr; |
@@ -2794,7 +2878,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2794 | if ((__force int)raddr->sin_addr.s_addr == INADDR_ANY) { | 2878 | if ((__force int)raddr->sin_addr.s_addr == INADDR_ANY) { |
2795 | err = pick_local_ipaddrs(dev, cm_id); | 2879 | err = pick_local_ipaddrs(dev, cm_id); |
2796 | if (err) | 2880 | if (err) |
2797 | goto fail2; | 2881 | goto fail1; |
2798 | } | 2882 | } |
2799 | 2883 | ||
2800 | /* find a route */ | 2884 | /* find a route */ |
@@ -2814,7 +2898,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2814 | if (ipv6_addr_type(&raddr6->sin6_addr) == IPV6_ADDR_ANY) { | 2898 | if (ipv6_addr_type(&raddr6->sin6_addr) == IPV6_ADDR_ANY) { |
2815 | err = pick_local_ip6addrs(dev, cm_id); | 2899 | err = pick_local_ip6addrs(dev, cm_id); |
2816 | if (err) | 2900 | if (err) |
2817 | goto fail2; | 2901 | goto fail1; |
2818 | } | 2902 | } |
2819 | 2903 | ||
2820 | /* find a route */ | 2904 | /* find a route */ |
@@ -2830,13 +2914,13 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2830 | if (!ep->dst) { | 2914 | if (!ep->dst) { |
2831 | printk(KERN_ERR MOD "%s - cannot find route.\n", __func__); | 2915 | printk(KERN_ERR MOD "%s - cannot find route.\n", __func__); |
2832 | err = -EHOSTUNREACH; | 2916 | err = -EHOSTUNREACH; |
2833 | goto fail3; | 2917 | goto fail2; |
2834 | } | 2918 | } |
2835 | 2919 | ||
2836 | err = import_ep(ep, iptype, ra, ep->dst, ep->com.dev, true); | 2920 | err = import_ep(ep, iptype, ra, ep->dst, ep->com.dev, true); |
2837 | if (err) { | 2921 | if (err) { |
2838 | printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__); | 2922 | printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__); |
2839 | goto fail4; | 2923 | goto fail3; |
2840 | } | 2924 | } |
2841 | 2925 | ||
2842 | PDBG("%s txq_idx %u tx_chan %u smac_idx %u rss_qid %u l2t_idx %u\n", | 2926 | PDBG("%s txq_idx %u tx_chan %u smac_idx %u rss_qid %u l2t_idx %u\n", |
@@ -2845,10 +2929,6 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2845 | 2929 | ||
2846 | state_set(&ep->com, CONNECTING); | 2930 | state_set(&ep->com, CONNECTING); |
2847 | ep->tos = 0; | 2931 | ep->tos = 0; |
2848 | memcpy(&ep->com.local_addr, &cm_id->local_addr, | ||
2849 | sizeof(ep->com.local_addr)); | ||
2850 | memcpy(&ep->com.remote_addr, &cm_id->remote_addr, | ||
2851 | sizeof(ep->com.remote_addr)); | ||
2852 | 2932 | ||
2853 | /* send connect request to rnic */ | 2933 | /* send connect request to rnic */ |
2854 | err = send_connect(ep); | 2934 | err = send_connect(ep); |
@@ -2856,12 +2936,12 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2856 | goto out; | 2936 | goto out; |
2857 | 2937 | ||
2858 | cxgb4_l2t_release(ep->l2t); | 2938 | cxgb4_l2t_release(ep->l2t); |
2859 | fail4: | ||
2860 | dst_release(ep->dst); | ||
2861 | fail3: | 2939 | fail3: |
2940 | dst_release(ep->dst); | ||
2941 | fail2: | ||
2862 | remove_handle(ep->com.dev, &ep->com.dev->atid_idr, ep->atid); | 2942 | remove_handle(ep->com.dev, &ep->com.dev->atid_idr, ep->atid); |
2863 | cxgb4_free_atid(ep->com.dev->rdev.lldi.tids, ep->atid); | 2943 | cxgb4_free_atid(ep->com.dev->rdev.lldi.tids, ep->atid); |
2864 | fail2: | 2944 | fail1: |
2865 | cm_id->rem_ref(cm_id); | 2945 | cm_id->rem_ref(cm_id); |
2866 | c4iw_put_ep(&ep->com); | 2946 | c4iw_put_ep(&ep->com); |
2867 | out: | 2947 | out: |
@@ -2871,7 +2951,8 @@ out: | |||
2871 | static int create_server6(struct c4iw_dev *dev, struct c4iw_listen_ep *ep) | 2951 | static int create_server6(struct c4iw_dev *dev, struct c4iw_listen_ep *ep) |
2872 | { | 2952 | { |
2873 | int err; | 2953 | int err; |
2874 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ep->com.local_addr; | 2954 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) |
2955 | &ep->com.mapped_local_addr; | ||
2875 | 2956 | ||
2876 | c4iw_init_wr_wait(&ep->com.wr_wait); | 2957 | c4iw_init_wr_wait(&ep->com.wr_wait); |
2877 | err = cxgb4_create_server6(ep->com.dev->rdev.lldi.ports[0], | 2958 | err = cxgb4_create_server6(ep->com.dev->rdev.lldi.ports[0], |
@@ -2892,7 +2973,8 @@ static int create_server6(struct c4iw_dev *dev, struct c4iw_listen_ep *ep) | |||
2892 | static int create_server4(struct c4iw_dev *dev, struct c4iw_listen_ep *ep) | 2973 | static int create_server4(struct c4iw_dev *dev, struct c4iw_listen_ep *ep) |
2893 | { | 2974 | { |
2894 | int err; | 2975 | int err; |
2895 | struct sockaddr_in *sin = (struct sockaddr_in *)&ep->com.local_addr; | 2976 | struct sockaddr_in *sin = (struct sockaddr_in *) |
2977 | &ep->com.mapped_local_addr; | ||
2896 | 2978 | ||
2897 | if (dev->rdev.lldi.enable_fw_ofld_conn) { | 2979 | if (dev->rdev.lldi.enable_fw_ofld_conn) { |
2898 | do { | 2980 | do { |
@@ -2927,6 +3009,9 @@ int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog) | |||
2927 | int err = 0; | 3009 | int err = 0; |
2928 | struct c4iw_dev *dev = to_c4iw_dev(cm_id->device); | 3010 | struct c4iw_dev *dev = to_c4iw_dev(cm_id->device); |
2929 | struct c4iw_listen_ep *ep; | 3011 | struct c4iw_listen_ep *ep; |
3012 | struct iwpm_dev_data pm_reg_msg; | ||
3013 | struct iwpm_sa_data pm_msg; | ||
3014 | int iwpm_err = 0; | ||
2930 | 3015 | ||
2931 | might_sleep(); | 3016 | might_sleep(); |
2932 | 3017 | ||
@@ -2961,6 +3046,37 @@ int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog) | |||
2961 | goto fail2; | 3046 | goto fail2; |
2962 | } | 3047 | } |
2963 | insert_handle(dev, &dev->stid_idr, ep, ep->stid); | 3048 | insert_handle(dev, &dev->stid_idr, ep, ep->stid); |
3049 | |||
3050 | /* No port mapper available, go with the specified info */ | ||
3051 | memcpy(&ep->com.mapped_local_addr, &cm_id->local_addr, | ||
3052 | sizeof(ep->com.mapped_local_addr)); | ||
3053 | |||
3054 | c4iw_form_reg_msg(dev, &pm_reg_msg); | ||
3055 | iwpm_err = iwpm_register_pid(&pm_reg_msg, RDMA_NL_C4IW); | ||
3056 | if (iwpm_err) { | ||
3057 | PDBG("%s: Port Mapper reg pid fail (err = %d).\n", | ||
3058 | __func__, iwpm_err); | ||
3059 | } | ||
3060 | if (iwpm_valid_pid() && !iwpm_err) { | ||
3061 | memcpy(&pm_msg.loc_addr, &ep->com.local_addr, | ||
3062 | sizeof(ep->com.local_addr)); | ||
3063 | iwpm_err = iwpm_add_mapping(&pm_msg, RDMA_NL_C4IW); | ||
3064 | if (iwpm_err) | ||
3065 | PDBG("%s: Port Mapper query fail (err = %d).\n", | ||
3066 | __func__, iwpm_err); | ||
3067 | else | ||
3068 | memcpy(&ep->com.mapped_local_addr, | ||
3069 | &pm_msg.mapped_loc_addr, | ||
3070 | sizeof(ep->com.mapped_local_addr)); | ||
3071 | } | ||
3072 | if (iwpm_create_mapinfo(&ep->com.local_addr, | ||
3073 | &ep->com.mapped_local_addr, RDMA_NL_C4IW)) { | ||
3074 | err = -ENOMEM; | ||
3075 | goto fail3; | ||
3076 | } | ||
3077 | print_addr(&ep->com, __func__, "add_mapping/create_mapinfo"); | ||
3078 | |||
3079 | set_bit(RELEASE_MAPINFO, &ep->com.flags); | ||
2964 | state_set(&ep->com, LISTEN); | 3080 | state_set(&ep->com, LISTEN); |
2965 | if (ep->com.local_addr.ss_family == AF_INET) | 3081 | if (ep->com.local_addr.ss_family == AF_INET) |
2966 | err = create_server4(dev, ep); | 3082 | err = create_server4(dev, ep); |
@@ -2970,6 +3086,8 @@ int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog) | |||
2970 | cm_id->provider_data = ep; | 3086 | cm_id->provider_data = ep; |
2971 | goto out; | 3087 | goto out; |
2972 | } | 3088 | } |
3089 | |||
3090 | fail3: | ||
2973 | cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, | 3091 | cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, |
2974 | ep->com.local_addr.ss_family); | 3092 | ep->com.local_addr.ss_family); |
2975 | fail2: | 3093 | fail2: |
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index f4fa50a609e2..bd749e75cec4 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c | |||
@@ -77,6 +77,16 @@ struct c4iw_debugfs_data { | |||
77 | int pos; | 77 | int pos; |
78 | }; | 78 | }; |
79 | 79 | ||
80 | /* registered cxgb4 netlink callbacks */ | ||
81 | static struct ibnl_client_cbs c4iw_nl_cb_table[] = { | ||
82 | [RDMA_NL_IWPM_REG_PID] = {.dump = iwpm_register_pid_cb}, | ||
83 | [RDMA_NL_IWPM_ADD_MAPPING] = {.dump = iwpm_add_mapping_cb}, | ||
84 | [RDMA_NL_IWPM_QUERY_MAPPING] = {.dump = iwpm_add_and_query_mapping_cb}, | ||
85 | [RDMA_NL_IWPM_HANDLE_ERR] = {.dump = iwpm_mapping_error_cb}, | ||
86 | [RDMA_NL_IWPM_MAPINFO] = {.dump = iwpm_mapping_info_cb}, | ||
87 | [RDMA_NL_IWPM_MAPINFO_NUM] = {.dump = iwpm_ack_mapping_info_cb} | ||
88 | }; | ||
89 | |||
80 | static int count_idrs(int id, void *p, void *data) | 90 | static int count_idrs(int id, void *p, void *data) |
81 | { | 91 | { |
82 | int *countp = data; | 92 | int *countp = data; |
@@ -113,35 +123,49 @@ static int dump_qp(int id, void *p, void *data) | |||
113 | &qp->ep->com.local_addr; | 123 | &qp->ep->com.local_addr; |
114 | struct sockaddr_in *rsin = (struct sockaddr_in *) | 124 | struct sockaddr_in *rsin = (struct sockaddr_in *) |
115 | &qp->ep->com.remote_addr; | 125 | &qp->ep->com.remote_addr; |
126 | struct sockaddr_in *mapped_lsin = (struct sockaddr_in *) | ||
127 | &qp->ep->com.mapped_local_addr; | ||
128 | struct sockaddr_in *mapped_rsin = (struct sockaddr_in *) | ||
129 | &qp->ep->com.mapped_remote_addr; | ||
116 | 130 | ||
117 | cc = snprintf(qpd->buf + qpd->pos, space, | 131 | cc = snprintf(qpd->buf + qpd->pos, space, |
118 | "rc qp sq id %u rq id %u state %u " | 132 | "rc qp sq id %u rq id %u state %u " |
119 | "onchip %u ep tid %u state %u " | 133 | "onchip %u ep tid %u state %u " |
120 | "%pI4:%u->%pI4:%u\n", | 134 | "%pI4:%u/%u->%pI4:%u/%u\n", |
121 | qp->wq.sq.qid, qp->wq.rq.qid, | 135 | qp->wq.sq.qid, qp->wq.rq.qid, |
122 | (int)qp->attr.state, | 136 | (int)qp->attr.state, |
123 | qp->wq.sq.flags & T4_SQ_ONCHIP, | 137 | qp->wq.sq.flags & T4_SQ_ONCHIP, |
124 | qp->ep->hwtid, (int)qp->ep->com.state, | 138 | qp->ep->hwtid, (int)qp->ep->com.state, |
125 | &lsin->sin_addr, ntohs(lsin->sin_port), | 139 | &lsin->sin_addr, ntohs(lsin->sin_port), |
126 | &rsin->sin_addr, ntohs(rsin->sin_port)); | 140 | ntohs(mapped_lsin->sin_port), |
141 | &rsin->sin_addr, ntohs(rsin->sin_port), | ||
142 | ntohs(mapped_rsin->sin_port)); | ||
127 | } else { | 143 | } else { |
128 | struct sockaddr_in6 *lsin6 = (struct sockaddr_in6 *) | 144 | struct sockaddr_in6 *lsin6 = (struct sockaddr_in6 *) |
129 | &qp->ep->com.local_addr; | 145 | &qp->ep->com.local_addr; |
130 | struct sockaddr_in6 *rsin6 = (struct sockaddr_in6 *) | 146 | struct sockaddr_in6 *rsin6 = (struct sockaddr_in6 *) |
131 | &qp->ep->com.remote_addr; | 147 | &qp->ep->com.remote_addr; |
148 | struct sockaddr_in6 *mapped_lsin6 = | ||
149 | (struct sockaddr_in6 *) | ||
150 | &qp->ep->com.mapped_local_addr; | ||
151 | struct sockaddr_in6 *mapped_rsin6 = | ||
152 | (struct sockaddr_in6 *) | ||
153 | &qp->ep->com.mapped_remote_addr; | ||
132 | 154 | ||
133 | cc = snprintf(qpd->buf + qpd->pos, space, | 155 | cc = snprintf(qpd->buf + qpd->pos, space, |
134 | "rc qp sq id %u rq id %u state %u " | 156 | "rc qp sq id %u rq id %u state %u " |
135 | "onchip %u ep tid %u state %u " | 157 | "onchip %u ep tid %u state %u " |
136 | "%pI6:%u->%pI6:%u\n", | 158 | "%pI6:%u/%u->%pI6:%u/%u\n", |
137 | qp->wq.sq.qid, qp->wq.rq.qid, | 159 | qp->wq.sq.qid, qp->wq.rq.qid, |
138 | (int)qp->attr.state, | 160 | (int)qp->attr.state, |
139 | qp->wq.sq.flags & T4_SQ_ONCHIP, | 161 | qp->wq.sq.flags & T4_SQ_ONCHIP, |
140 | qp->ep->hwtid, (int)qp->ep->com.state, | 162 | qp->ep->hwtid, (int)qp->ep->com.state, |
141 | &lsin6->sin6_addr, | 163 | &lsin6->sin6_addr, |
142 | ntohs(lsin6->sin6_port), | 164 | ntohs(lsin6->sin6_port), |
165 | ntohs(mapped_lsin6->sin6_port), | ||
143 | &rsin6->sin6_addr, | 166 | &rsin6->sin6_addr, |
144 | ntohs(rsin6->sin6_port)); | 167 | ntohs(rsin6->sin6_port), |
168 | ntohs(mapped_rsin6->sin6_port)); | ||
145 | } | 169 | } |
146 | } else | 170 | } else |
147 | cc = snprintf(qpd->buf + qpd->pos, space, | 171 | cc = snprintf(qpd->buf + qpd->pos, space, |
@@ -386,31 +410,43 @@ static int dump_ep(int id, void *p, void *data) | |||
386 | &ep->com.local_addr; | 410 | &ep->com.local_addr; |
387 | struct sockaddr_in *rsin = (struct sockaddr_in *) | 411 | struct sockaddr_in *rsin = (struct sockaddr_in *) |
388 | &ep->com.remote_addr; | 412 | &ep->com.remote_addr; |
413 | struct sockaddr_in *mapped_lsin = (struct sockaddr_in *) | ||
414 | &ep->com.mapped_local_addr; | ||
415 | struct sockaddr_in *mapped_rsin = (struct sockaddr_in *) | ||
416 | &ep->com.mapped_remote_addr; | ||
389 | 417 | ||
390 | cc = snprintf(epd->buf + epd->pos, space, | 418 | cc = snprintf(epd->buf + epd->pos, space, |
391 | "ep %p cm_id %p qp %p state %d flags 0x%lx " | 419 | "ep %p cm_id %p qp %p state %d flags 0x%lx " |
392 | "history 0x%lx hwtid %d atid %d " | 420 | "history 0x%lx hwtid %d atid %d " |
393 | "%pI4:%d <-> %pI4:%d\n", | 421 | "%pI4:%d/%d <-> %pI4:%d/%d\n", |
394 | ep, ep->com.cm_id, ep->com.qp, | 422 | ep, ep->com.cm_id, ep->com.qp, |
395 | (int)ep->com.state, ep->com.flags, | 423 | (int)ep->com.state, ep->com.flags, |
396 | ep->com.history, ep->hwtid, ep->atid, | 424 | ep->com.history, ep->hwtid, ep->atid, |
397 | &lsin->sin_addr, ntohs(lsin->sin_port), | 425 | &lsin->sin_addr, ntohs(lsin->sin_port), |
398 | &rsin->sin_addr, ntohs(rsin->sin_port)); | 426 | ntohs(mapped_lsin->sin_port), |
427 | &rsin->sin_addr, ntohs(rsin->sin_port), | ||
428 | ntohs(mapped_rsin->sin_port)); | ||
399 | } else { | 429 | } else { |
400 | struct sockaddr_in6 *lsin6 = (struct sockaddr_in6 *) | 430 | struct sockaddr_in6 *lsin6 = (struct sockaddr_in6 *) |
401 | &ep->com.local_addr; | 431 | &ep->com.local_addr; |
402 | struct sockaddr_in6 *rsin6 = (struct sockaddr_in6 *) | 432 | struct sockaddr_in6 *rsin6 = (struct sockaddr_in6 *) |
403 | &ep->com.remote_addr; | 433 | &ep->com.remote_addr; |
434 | struct sockaddr_in6 *mapped_lsin6 = (struct sockaddr_in6 *) | ||
435 | &ep->com.mapped_local_addr; | ||
436 | struct sockaddr_in6 *mapped_rsin6 = (struct sockaddr_in6 *) | ||
437 | &ep->com.mapped_remote_addr; | ||
404 | 438 | ||
405 | cc = snprintf(epd->buf + epd->pos, space, | 439 | cc = snprintf(epd->buf + epd->pos, space, |
406 | "ep %p cm_id %p qp %p state %d flags 0x%lx " | 440 | "ep %p cm_id %p qp %p state %d flags 0x%lx " |
407 | "history 0x%lx hwtid %d atid %d " | 441 | "history 0x%lx hwtid %d atid %d " |
408 | "%pI6:%d <-> %pI6:%d\n", | 442 | "%pI6:%d/%d <-> %pI6:%d/%d\n", |
409 | ep, ep->com.cm_id, ep->com.qp, | 443 | ep, ep->com.cm_id, ep->com.qp, |
410 | (int)ep->com.state, ep->com.flags, | 444 | (int)ep->com.state, ep->com.flags, |
411 | ep->com.history, ep->hwtid, ep->atid, | 445 | ep->com.history, ep->hwtid, ep->atid, |
412 | &lsin6->sin6_addr, ntohs(lsin6->sin6_port), | 446 | &lsin6->sin6_addr, ntohs(lsin6->sin6_port), |
413 | &rsin6->sin6_addr, ntohs(rsin6->sin6_port)); | 447 | ntohs(mapped_lsin6->sin6_port), |
448 | &rsin6->sin6_addr, ntohs(rsin6->sin6_port), | ||
449 | ntohs(mapped_rsin6->sin6_port)); | ||
414 | } | 450 | } |
415 | if (cc < space) | 451 | if (cc < space) |
416 | epd->pos += cc; | 452 | epd->pos += cc; |
@@ -431,23 +467,29 @@ static int dump_listen_ep(int id, void *p, void *data) | |||
431 | if (ep->com.local_addr.ss_family == AF_INET) { | 467 | if (ep->com.local_addr.ss_family == AF_INET) { |
432 | struct sockaddr_in *lsin = (struct sockaddr_in *) | 468 | struct sockaddr_in *lsin = (struct sockaddr_in *) |
433 | &ep->com.local_addr; | 469 | &ep->com.local_addr; |
470 | struct sockaddr_in *mapped_lsin = (struct sockaddr_in *) | ||
471 | &ep->com.mapped_local_addr; | ||
434 | 472 | ||
435 | cc = snprintf(epd->buf + epd->pos, space, | 473 | cc = snprintf(epd->buf + epd->pos, space, |
436 | "ep %p cm_id %p state %d flags 0x%lx stid %d " | 474 | "ep %p cm_id %p state %d flags 0x%lx stid %d " |
437 | "backlog %d %pI4:%d\n", | 475 | "backlog %d %pI4:%d/%d\n", |
438 | ep, ep->com.cm_id, (int)ep->com.state, | 476 | ep, ep->com.cm_id, (int)ep->com.state, |
439 | ep->com.flags, ep->stid, ep->backlog, | 477 | ep->com.flags, ep->stid, ep->backlog, |
440 | &lsin->sin_addr, ntohs(lsin->sin_port)); | 478 | &lsin->sin_addr, ntohs(lsin->sin_port), |
479 | ntohs(mapped_lsin->sin_port)); | ||
441 | } else { | 480 | } else { |
442 | struct sockaddr_in6 *lsin6 = (struct sockaddr_in6 *) | 481 | struct sockaddr_in6 *lsin6 = (struct sockaddr_in6 *) |
443 | &ep->com.local_addr; | 482 | &ep->com.local_addr; |
483 | struct sockaddr_in6 *mapped_lsin6 = (struct sockaddr_in6 *) | ||
484 | &ep->com.mapped_local_addr; | ||
444 | 485 | ||
445 | cc = snprintf(epd->buf + epd->pos, space, | 486 | cc = snprintf(epd->buf + epd->pos, space, |
446 | "ep %p cm_id %p state %d flags 0x%lx stid %d " | 487 | "ep %p cm_id %p state %d flags 0x%lx stid %d " |
447 | "backlog %d %pI6:%d\n", | 488 | "backlog %d %pI6:%d/%d\n", |
448 | ep, ep->com.cm_id, (int)ep->com.state, | 489 | ep, ep->com.cm_id, (int)ep->com.state, |
449 | ep->com.flags, ep->stid, ep->backlog, | 490 | ep->com.flags, ep->stid, ep->backlog, |
450 | &lsin6->sin6_addr, ntohs(lsin6->sin6_port)); | 491 | &lsin6->sin6_addr, ntohs(lsin6->sin6_port), |
492 | ntohs(mapped_lsin6->sin6_port)); | ||
451 | } | 493 | } |
452 | if (cc < space) | 494 | if (cc < space) |
453 | epd->pos += cc; | 495 | epd->pos += cc; |
@@ -687,6 +729,7 @@ static void c4iw_dealloc(struct uld_ctx *ctx) | |||
687 | if (ctx->dev->rdev.oc_mw_kva) | 729 | if (ctx->dev->rdev.oc_mw_kva) |
688 | iounmap(ctx->dev->rdev.oc_mw_kva); | 730 | iounmap(ctx->dev->rdev.oc_mw_kva); |
689 | ib_dealloc_device(&ctx->dev->ibdev); | 731 | ib_dealloc_device(&ctx->dev->ibdev); |
732 | iwpm_exit(RDMA_NL_C4IW); | ||
690 | ctx->dev = NULL; | 733 | ctx->dev = NULL; |
691 | } | 734 | } |
692 | 735 | ||
@@ -780,6 +823,14 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) | |||
780 | c4iw_debugfs_root); | 823 | c4iw_debugfs_root); |
781 | setup_debugfs(devp); | 824 | setup_debugfs(devp); |
782 | } | 825 | } |
826 | |||
827 | ret = iwpm_init(RDMA_NL_C4IW); | ||
828 | if (ret) { | ||
829 | pr_err("port mapper initialization failed with %d\n", ret); | ||
830 | ib_dealloc_device(&devp->ibdev); | ||
831 | return ERR_PTR(ret); | ||
832 | } | ||
833 | |||
783 | return devp; | 834 | return devp; |
784 | } | 835 | } |
785 | 836 | ||
@@ -1274,6 +1325,11 @@ static int __init c4iw_init_module(void) | |||
1274 | printk(KERN_WARNING MOD | 1325 | printk(KERN_WARNING MOD |
1275 | "could not create debugfs entry, continuing\n"); | 1326 | "could not create debugfs entry, continuing\n"); |
1276 | 1327 | ||
1328 | if (ibnl_add_client(RDMA_NL_C4IW, RDMA_NL_IWPM_NUM_OPS, | ||
1329 | c4iw_nl_cb_table)) | ||
1330 | pr_err("%s[%u]: Failed to add netlink callback\n" | ||
1331 | , __func__, __LINE__); | ||
1332 | |||
1277 | cxgb4_register_uld(CXGB4_ULD_RDMA, &c4iw_uld_info); | 1333 | cxgb4_register_uld(CXGB4_ULD_RDMA, &c4iw_uld_info); |
1278 | 1334 | ||
1279 | return 0; | 1335 | return 0; |
@@ -1291,6 +1347,7 @@ static void __exit c4iw_exit_module(void) | |||
1291 | } | 1347 | } |
1292 | mutex_unlock(&dev_mutex); | 1348 | mutex_unlock(&dev_mutex); |
1293 | cxgb4_unregister_uld(CXGB4_ULD_RDMA); | 1349 | cxgb4_unregister_uld(CXGB4_ULD_RDMA); |
1350 | ibnl_remove_client(RDMA_NL_C4IW); | ||
1294 | c4iw_cm_term(); | 1351 | c4iw_cm_term(); |
1295 | debugfs_remove_recursive(c4iw_debugfs_root); | 1352 | debugfs_remove_recursive(c4iw_debugfs_root); |
1296 | } | 1353 | } |
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index 7474b490760a..6f533fbcc4b3 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h | |||
@@ -52,6 +52,8 @@ | |||
52 | 52 | ||
53 | #include <rdma/ib_verbs.h> | 53 | #include <rdma/ib_verbs.h> |
54 | #include <rdma/iw_cm.h> | 54 | #include <rdma/iw_cm.h> |
55 | #include <rdma/rdma_netlink.h> | ||
56 | #include <rdma/iw_portmap.h> | ||
55 | 57 | ||
56 | #include "cxgb4.h" | 58 | #include "cxgb4.h" |
57 | #include "cxgb4_uld.h" | 59 | #include "cxgb4_uld.h" |
@@ -728,6 +730,7 @@ enum c4iw_ep_flags { | |||
728 | CLOSE_SENT = 3, | 730 | CLOSE_SENT = 3, |
729 | TIMEOUT = 4, | 731 | TIMEOUT = 4, |
730 | QP_REFERENCED = 5, | 732 | QP_REFERENCED = 5, |
733 | RELEASE_MAPINFO = 6, | ||
731 | }; | 734 | }; |
732 | 735 | ||
733 | enum c4iw_ep_history { | 736 | enum c4iw_ep_history { |
@@ -764,6 +767,8 @@ struct c4iw_ep_common { | |||
764 | struct mutex mutex; | 767 | struct mutex mutex; |
765 | struct sockaddr_storage local_addr; | 768 | struct sockaddr_storage local_addr; |
766 | struct sockaddr_storage remote_addr; | 769 | struct sockaddr_storage remote_addr; |
770 | struct sockaddr_storage mapped_local_addr; | ||
771 | struct sockaddr_storage mapped_remote_addr; | ||
767 | struct c4iw_wr_wait wr_wait; | 772 | struct c4iw_wr_wait wr_wait; |
768 | unsigned long flags; | 773 | unsigned long flags; |
769 | unsigned long history; | 774 | unsigned long history; |
@@ -807,6 +812,45 @@ struct c4iw_ep { | |||
807 | unsigned int retry_count; | 812 | unsigned int retry_count; |
808 | }; | 813 | }; |
809 | 814 | ||
815 | static inline void print_addr(struct c4iw_ep_common *epc, const char *func, | ||
816 | const char *msg) | ||
817 | { | ||
818 | |||
819 | #define SINA(a) (&(((struct sockaddr_in *)(a))->sin_addr.s_addr)) | ||
820 | #define SINP(a) ntohs(((struct sockaddr_in *)(a))->sin_port) | ||
821 | #define SIN6A(a) (&(((struct sockaddr_in6 *)(a))->sin6_addr)) | ||
822 | #define SIN6P(a) ntohs(((struct sockaddr_in6 *)(a))->sin6_port) | ||
823 | |||
824 | if (c4iw_debug) { | ||
825 | switch (epc->local_addr.ss_family) { | ||
826 | case AF_INET: | ||
827 | PDBG("%s %s %pI4:%u/%u <-> %pI4:%u/%u\n", | ||
828 | func, msg, SINA(&epc->local_addr), | ||
829 | SINP(&epc->local_addr), | ||
830 | SINP(&epc->mapped_local_addr), | ||
831 | SINA(&epc->remote_addr), | ||
832 | SINP(&epc->remote_addr), | ||
833 | SINP(&epc->mapped_remote_addr)); | ||
834 | break; | ||
835 | case AF_INET6: | ||
836 | PDBG("%s %s %pI6:%u/%u <-> %pI6:%u/%u\n", | ||
837 | func, msg, SIN6A(&epc->local_addr), | ||
838 | SIN6P(&epc->local_addr), | ||
839 | SIN6P(&epc->mapped_local_addr), | ||
840 | SIN6A(&epc->remote_addr), | ||
841 | SIN6P(&epc->remote_addr), | ||
842 | SIN6P(&epc->mapped_remote_addr)); | ||
843 | break; | ||
844 | default: | ||
845 | break; | ||
846 | } | ||
847 | } | ||
848 | #undef SINA | ||
849 | #undef SINP | ||
850 | #undef SIN6A | ||
851 | #undef SIN6P | ||
852 | } | ||
853 | |||
810 | static inline struct c4iw_ep *to_ep(struct iw_cm_id *cm_id) | 854 | static inline struct c4iw_ep *to_ep(struct iw_cm_id *cm_id) |
811 | { | 855 | { |
812 | return cm_id->provider_data; | 856 | return cm_id->provider_data; |