aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Wise <swise@opengridcomputing.com>2014-03-26 18:08:09 -0400
committerRoland Dreier <roland@purestorage.com>2014-06-10 13:12:06 -0400
commit9eccfe109b276fddf2908d1a70f7f4449b92f08f (patch)
treec28209c1f6eefd7d2a2f661e0c60e2f2712442ee
parent5647263cb136a2795b67b9ce46f2debb653e3373 (diff)
RDMA/cxgb4: Add support for iWARP Port Mapper user space service
Based on original work by Vipul Pandya. Signed-off-by: Steve Wise <swise@opengridcomputing.com> [ Fix htons -> ntohs to make sparse happy. - Roland ] Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r--drivers/infiniband/hw/cxgb4/cm.c180
-rw-r--r--drivers/infiniband/hw/cxgb4/device.c81
-rw-r--r--drivers/infiniband/hw/cxgb4/iw_cxgb4.h44
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 */
540static 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 */
552static 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
560static 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
531static int send_connect(struct c4iw_ep *ep) 569static 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);
2859fail4:
2860 dst_release(ep->dst);
2861fail3: 2939fail3:
2940 dst_release(ep->dst);
2941fail2:
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);
2864fail2: 2944fail1:
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);
2867out: 2947out:
@@ -2871,7 +2951,8 @@ out:
2871static int create_server6(struct c4iw_dev *dev, struct c4iw_listen_ep *ep) 2951static 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)
2892static int create_server4(struct c4iw_dev *dev, struct c4iw_listen_ep *ep) 2973static 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
3090fail3:
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);
2975fail2: 3093fail2:
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 */
81static 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
80static int count_idrs(int id, void *p, void *data) 90static 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
733enum c4iw_ep_history { 736enum 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
815static 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
810static inline struct c4iw_ep *to_ep(struct iw_cm_id *cm_id) 854static 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;