RDMA/srpt: Fix handling of iWARP logins
[linux-2.6-block.git] / drivers / infiniband / ulp / srpt / ib_srpt.c
index 1a039f16d315422b969df3bbbb15c5843b6d8865..fbfadeedc195783f4e3187ed721317ad315f8a93 100644 (file)
@@ -556,24 +556,16 @@ static int srpt_refresh_port(struct srpt_port *sport)
        struct ib_port_attr port_attr;
        int ret;
 
-       memset(&port_modify, 0, sizeof(port_modify));
-       port_modify.set_port_cap_mask = IB_PORT_DEVICE_MGMT_SUP;
-       port_modify.clr_port_cap_mask = 0;
-
-       ret = ib_modify_port(sport->sdev->device, sport->port, 0, &port_modify);
-       if (ret)
-               goto err_mod_port;
-
        ret = ib_query_port(sport->sdev->device, sport->port, &port_attr);
        if (ret)
-               goto err_query_port;
+               return ret;
 
        sport->sm_lid = port_attr.sm_lid;
        sport->lid = port_attr.lid;
 
        ret = rdma_query_gid(sport->sdev->device, sport->port, 0, &sport->gid);
        if (ret)
-               goto err_query_port;
+               return ret;
 
        sport->port_guid_wwn.priv = sport;
        srpt_format_guid(sport->port_guid, sizeof(sport->port_guid),
@@ -584,6 +576,20 @@ static int srpt_refresh_port(struct srpt_port *sport)
                 be64_to_cpu(sport->gid.global.subnet_prefix),
                 be64_to_cpu(sport->gid.global.interface_id));
 
+       if (rdma_protocol_iwarp(sport->sdev->device, sport->port))
+               return 0;
+
+       memset(&port_modify, 0, sizeof(port_modify));
+       port_modify.set_port_cap_mask = IB_PORT_DEVICE_MGMT_SUP;
+       port_modify.clr_port_cap_mask = 0;
+
+       ret = ib_modify_port(sport->sdev->device, sport->port, 0, &port_modify);
+       if (ret) {
+               pr_warn("%s-%d: enabling device management failed (%d). Note: this is expected if SR-IOV is enabled.\n",
+                       dev_name(&sport->sdev->device->dev), sport->port, ret);
+               return 0;
+       }
+
        if (!sport->mad_agent) {
                memset(&reg_req, 0, sizeof(reg_req));
                reg_req.mgmt_class = IB_MGMT_CLASS_DEVICE_MGMT;
@@ -599,23 +605,14 @@ static int srpt_refresh_port(struct srpt_port *sport)
                                                         srpt_mad_recv_handler,
                                                         sport, 0);
                if (IS_ERR(sport->mad_agent)) {
-                       ret = PTR_ERR(sport->mad_agent);
+                       pr_err("%s-%d: MAD agent registration failed (%ld). Note: this is expected if SR-IOV is enabled.\n",
+                              dev_name(&sport->sdev->device->dev), sport->port,
+                              PTR_ERR(sport->mad_agent));
                        sport->mad_agent = NULL;
-                       goto err_query_port;
                }
        }
 
        return 0;
-
-err_query_port:
-
-       port_modify.set_port_cap_mask = 0;
-       port_modify.clr_port_cap_mask = IB_PORT_DEVICE_MGMT_SUP;
-       ib_modify_port(sport->sdev->device, sport->port, 0, &port_modify);
-
-err_mod_port:
-
-       return ret;
 }
 
 /**
@@ -1767,8 +1764,8 @@ static int srpt_create_ch_ib(struct srpt_rdma_ch *ch)
                goto out;
 
 retry:
-       ch->cq = ib_alloc_cq(sdev->device, ch, ch->rq_size + sq_size,
-                       0 /* XXX: spread CQs */, IB_POLL_WORKQUEUE);
+       ch->cq = ib_alloc_cq_any(sdev->device, ch, ch->rq_size + sq_size,
+                                IB_POLL_WORKQUEUE);
        if (IS_ERR(ch->cq)) {
                ret = PTR_ERR(ch->cq);
                pr_err("failed to create CQ cqe= %d ret= %d\n",
@@ -2505,6 +2502,7 @@ static int srpt_rdma_cm_req_recv(struct rdma_cm_id *cm_id,
        struct srpt_device *sdev;
        struct srp_login_req req;
        const struct srp_login_req_rdma *req_rdma;
+       struct sa_path_rec *path_rec = cm_id->route.path_rec;
        char src_addr[40];
 
        sdev = ib_get_client_data(cm_id->device, &srpt_client);
@@ -2530,7 +2528,7 @@ static int srpt_rdma_cm_req_recv(struct rdma_cm_id *cm_id,
                 &cm_id->route.addr.src_addr);
 
        return srpt_cm_req_recv(sdev, NULL, cm_id, cm_id->port_num,
-                               cm_id->route.path_rec->pkey, &req, src_addr);
+                               path_rec ? path_rec->pkey : 0, &req, src_addr);
 }
 
 static void srpt_cm_rej_recv(struct srpt_rdma_ch *ch,