]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/infiniband/core/cm.c
IB/SA: Add OPA path record type
[karo-tx-linux.git] / drivers / infiniband / core / cm.c
index 6535f09dc575c1df7f6dc22c04be96ccc65130c1..1844770f3ae838bd63f3837bc0f475b0c8b5f1b1 100644 (file)
@@ -228,7 +228,7 @@ struct cm_device {
 struct cm_av {
        struct cm_port *port;
        union ib_gid dgid;
-       struct ib_ah_attr ah_attr;
+       struct rdma_ah_attr ah_attr;
        u16 pkey_index;
        u8 timeout;
 };
@@ -241,7 +241,7 @@ struct cm_work {
        __be32 local_id;                        /* Established / timewait */
        __be32 remote_id;
        struct ib_cm_event cm_event;
-       struct ib_sa_path_rec path[0];
+       struct sa_path_rec path[0];
 };
 
 struct cm_timewait_info {
@@ -343,7 +343,7 @@ static int cm_alloc_msg(struct cm_id_private *cm_id_priv,
                ret = -ENODEV;
                goto out;
        }
-       ah = ib_create_ah(mad_agent->qp->pd, &av->ah_attr);
+       ah = rdma_create_ah(mad_agent->qp->pd, &av->ah_attr);
        if (IS_ERR(ah)) {
                ret = PTR_ERR(ah);
                goto out;
@@ -355,7 +355,7 @@ static int cm_alloc_msg(struct cm_id_private *cm_id_priv,
                               GFP_ATOMIC,
                               IB_MGMT_BASE_VERSION);
        if (IS_ERR(m)) {
-               ib_destroy_ah(ah);
+               rdma_destroy_ah(ah);
                ret = PTR_ERR(m);
                goto out;
        }
@@ -390,7 +390,7 @@ static int cm_alloc_response_msg(struct cm_port *port,
                               GFP_ATOMIC,
                               IB_MGMT_BASE_VERSION);
        if (IS_ERR(m)) {
-               ib_destroy_ah(ah);
+               rdma_destroy_ah(ah);
                return PTR_ERR(m);
        }
        m->ah = ah;
@@ -400,7 +400,7 @@ static int cm_alloc_response_msg(struct cm_port *port,
 
 static void cm_free_msg(struct ib_mad_send_buf *msg)
 {
-       ib_destroy_ah(msg->ah);
+       rdma_destroy_ah(msg->ah);
        if (msg->context[0])
                cm_deref_id(msg->context[0]);
        ib_free_send_mad(msg);
@@ -440,7 +440,7 @@ static void cm_init_av_for_response(struct cm_port *port, struct ib_wc *wc,
                           grh, &av->ah_attr);
 }
 
-static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av,
+static int cm_init_av_by_path(struct sa_path_rec *path, struct cm_av *av,
                              struct cm_id_private *cm_id_priv)
 {
        struct cm_device *cm_dev;
@@ -453,7 +453,8 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av,
        read_lock_irqsave(&cm.device_lock, flags);
        list_for_each_entry(cm_dev, &cm.device_list, list) {
                if (!ib_find_cached_gid(cm_dev->ib_device, &path->sgid,
-                                       path->gid_type, ndev, &p, NULL)) {
+                                       sa_conv_pathrec_to_gid_type(path),
+                                       ndev, &p, NULL)) {
                        port = cm_dev->port[p-1];
                        break;
                }
@@ -1172,8 +1173,8 @@ static void cm_format_req(struct cm_req_msg *req_msg,
                          struct cm_id_private *cm_id_priv,
                          struct ib_cm_req_param *param)
 {
-       struct ib_sa_path_rec *pri_path = param->primary_path;
-       struct ib_sa_path_rec *alt_path = param->alternate_path;
+       struct sa_path_rec *pri_path = param->primary_path;
+       struct sa_path_rec *alt_path = param->alternate_path;
 
        cm_format_mad_hdr(&req_msg->hdr, CM_REQ_ATTR_ID,
                          cm_form_tid(cm_id_priv, CM_MSG_SEQUENCE_REQ));
@@ -1202,8 +1203,10 @@ static void cm_format_req(struct cm_req_msg *req_msg,
        }
 
        if (pri_path->hop_limit <= 1) {
-               req_msg->primary_local_lid = pri_path->slid;
-               req_msg->primary_remote_lid = pri_path->dlid;
+               req_msg->primary_local_lid =
+                       htons(ntohl(sa_path_get_slid(pri_path)));
+               req_msg->primary_remote_lid =
+                       htons(ntohl(sa_path_get_dlid(pri_path)));
        } else {
                /* Work-around until there's a way to obtain remote LID info */
                req_msg->primary_local_lid = IB_LID_PERMISSIVE;
@@ -1223,8 +1226,10 @@ static void cm_format_req(struct cm_req_msg *req_msg,
 
        if (alt_path) {
                if (alt_path->hop_limit <= 1) {
-                       req_msg->alt_local_lid = alt_path->slid;
-                       req_msg->alt_remote_lid = alt_path->dlid;
+                       req_msg->alt_local_lid =
+                               htons(ntohl(sa_path_get_slid(alt_path)));
+                       req_msg->alt_remote_lid =
+                               htons(ntohl(sa_path_get_dlid(alt_path)));
                } else {
                        req_msg->alt_local_lid = IB_LID_PERMISSIVE;
                        req_msg->alt_remote_lid = IB_LID_PERMISSIVE;
@@ -1401,14 +1406,15 @@ static inline int cm_is_active_peer(__be64 local_ca_guid, __be64 remote_ca_guid,
 }
 
 static void cm_format_paths_from_req(struct cm_req_msg *req_msg,
-                                           struct ib_sa_path_rec *primary_path,
-                                           struct ib_sa_path_rec *alt_path)
+                                    struct sa_path_rec *primary_path,
+                                    struct sa_path_rec *alt_path)
 {
-       memset(primary_path, 0, sizeof *primary_path);
        primary_path->dgid = req_msg->primary_local_gid;
        primary_path->sgid = req_msg->primary_remote_gid;
-       primary_path->dlid = req_msg->primary_local_lid;
-       primary_path->slid = req_msg->primary_remote_lid;
+       sa_path_set_dlid(primary_path,
+                        htonl(ntohs(req_msg->primary_local_lid)));
+       sa_path_set_slid(primary_path,
+                        htonl(ntohs(req_msg->primary_remote_lid)));
        primary_path->flow_label = cm_req_get_primary_flow_label(req_msg);
        primary_path->hop_limit = req_msg->primary_hop_limit;
        primary_path->traffic_class = req_msg->primary_traffic_class;
@@ -1423,14 +1429,15 @@ static void cm_format_paths_from_req(struct cm_req_msg *req_msg,
        primary_path->packet_life_time =
                cm_req_get_primary_local_ack_timeout(req_msg);
        primary_path->packet_life_time -= (primary_path->packet_life_time > 0);
-       primary_path->service_id = req_msg->service_id;
+       sa_path_set_service_id(primary_path, req_msg->service_id);
 
        if (req_msg->alt_local_lid) {
-               memset(alt_path, 0, sizeof *alt_path);
                alt_path->dgid = req_msg->alt_local_gid;
                alt_path->sgid = req_msg->alt_remote_gid;
-               alt_path->dlid = req_msg->alt_local_lid;
-               alt_path->slid = req_msg->alt_remote_lid;
+               sa_path_set_dlid(alt_path,
+                                htonl(ntohs(req_msg->alt_local_lid)));
+               sa_path_set_slid(alt_path,
+                                htonl(ntohs(req_msg->alt_remote_lid)));
                alt_path->flow_label = cm_req_get_alt_flow_label(req_msg);
                alt_path->hop_limit = req_msg->alt_hop_limit;
                alt_path->traffic_class = req_msg->alt_traffic_class;
@@ -1445,7 +1452,7 @@ static void cm_format_paths_from_req(struct cm_req_msg *req_msg,
                alt_path->packet_life_time =
                        cm_req_get_alt_local_ack_timeout(req_msg);
                alt_path->packet_life_time -= (alt_path->packet_life_time > 0);
-               alt_path->service_id = req_msg->service_id;
+               sa_path_set_service_id(alt_path, req_msg->service_id);
        }
 }
 
@@ -1722,6 +1729,7 @@ static int cm_req_handler(struct cm_work *work)
        struct cm_req_msg *req_msg;
        union ib_gid gid;
        struct ib_gid_attr gid_attr;
+       const struct ib_global_route *grh;
        int ret;
 
        req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
@@ -1758,21 +1766,34 @@ static int cm_req_handler(struct cm_work *work)
        cm_id_priv->id.service_mask = ~cpu_to_be64(0);
 
        cm_process_routed_req(req_msg, work->mad_recv_wc->wc);
-       cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]);
 
-       memcpy(work->path[0].dmac, cm_id_priv->av.ah_attr.dmac, ETH_ALEN);
-       work->path[0].hop_limit = cm_id_priv->av.ah_attr.grh.hop_limit;
+       memset(&work->path[0], 0, sizeof(work->path[0]));
+       memset(&work->path[1], 0, sizeof(work->path[1]));
+       grh = rdma_ah_read_grh(&cm_id_priv->av.ah_attr);
        ret = ib_get_cached_gid(work->port->cm_dev->ib_device,
                                work->port->port_num,
-                               cm_id_priv->av.ah_attr.grh.sgid_index,
+                               grh->sgid_index,
                                &gid, &gid_attr);
        if (!ret) {
                if (gid_attr.ndev) {
-                       work->path[0].ifindex = gid_attr.ndev->ifindex;
-                       work->path[0].net = dev_net(gid_attr.ndev);
+                       work->path[0].rec_type =
+                               sa_conv_gid_to_pathrec_type(gid_attr.gid_type);
+                       sa_path_set_ifindex(&work->path[0],
+                                           gid_attr.ndev->ifindex);
+                       sa_path_set_ndev(&work->path[0],
+                                        dev_net(gid_attr.ndev));
                        dev_put(gid_attr.ndev);
+               } else {
+                       work->path[0].rec_type = SA_PATH_REC_TYPE_IB;
                }
-               work->path[0].gid_type = gid_attr.gid_type;
+               if (req_msg->alt_local_lid)
+                       work->path[1].rec_type = work->path[0].rec_type;
+               cm_format_paths_from_req(req_msg, &work->path[0],
+                                        &work->path[1]);
+               if (cm_id_priv->av.ah_attr.type == RDMA_AH_ATTR_TYPE_ROCE)
+                       sa_path_set_dmac(&work->path[0],
+                                        cm_id_priv->av.ah_attr.roce.dmac);
+               work->path[0].hop_limit = grh->hop_limit;
                ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av,
                                         cm_id_priv);
        }
@@ -1782,11 +1803,18 @@ static int cm_req_handler(struct cm_work *work)
                                            &work->path[0].sgid,
                                            &gid_attr);
                if (!err && gid_attr.ndev) {
-                       work->path[0].ifindex = gid_attr.ndev->ifindex;
-                       work->path[0].net = dev_net(gid_attr.ndev);
+                       work->path[0].rec_type =
+                               sa_conv_gid_to_pathrec_type(gid_attr.gid_type);
+                       sa_path_set_ifindex(&work->path[0],
+                                           gid_attr.ndev->ifindex);
+                       sa_path_set_ndev(&work->path[0],
+                                        dev_net(gid_attr.ndev));
                        dev_put(gid_attr.ndev);
+               } else {
+                       work->path[0].rec_type = SA_PATH_REC_TYPE_IB;
                }
-               work->path[0].gid_type = gid_attr.gid_type;
+               if (req_msg->alt_local_lid)
+                       work->path[1].rec_type = work->path[0].rec_type;
                ib_send_cm_rej(cm_id, IB_CM_REJ_INVALID_GID,
                               &work->path[0].sgid, sizeof work->path[0].sgid,
                               NULL, 0);
@@ -2811,7 +2839,7 @@ out:
 
 static void cm_format_lap(struct cm_lap_msg *lap_msg,
                          struct cm_id_private *cm_id_priv,
-                         struct ib_sa_path_rec *alternate_path,
+                         struct sa_path_rec *alternate_path,
                          const void *private_data,
                          u8 private_data_len)
 {
@@ -2822,8 +2850,10 @@ static void cm_format_lap(struct cm_lap_msg *lap_msg,
        cm_lap_set_remote_qpn(lap_msg, cm_id_priv->remote_qpn);
        /* todo: need remote CM response timeout */
        cm_lap_set_remote_resp_timeout(lap_msg, 0x1F);
-       lap_msg->alt_local_lid = alternate_path->slid;
-       lap_msg->alt_remote_lid = alternate_path->dlid;
+       lap_msg->alt_local_lid =
+               htons(ntohl(sa_path_get_slid(alternate_path)));
+       lap_msg->alt_remote_lid =
+               htons(ntohl(sa_path_get_dlid(alternate_path)));
        lap_msg->alt_local_gid = alternate_path->sgid;
        lap_msg->alt_remote_gid = alternate_path->dgid;
        cm_lap_set_flow_label(lap_msg, alternate_path->flow_label);
@@ -2841,7 +2871,7 @@ static void cm_format_lap(struct cm_lap_msg *lap_msg,
 }
 
 int ib_send_cm_lap(struct ib_cm_id *cm_id,
-                  struct ib_sa_path_rec *alternate_path,
+                  struct sa_path_rec *alternate_path,
                   const void *private_data,
                   u8 private_data_len)
 {
@@ -2895,14 +2925,15 @@ out:    spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 EXPORT_SYMBOL(ib_send_cm_lap);
 
 static void cm_format_path_from_lap(struct cm_id_private *cm_id_priv,
-                                   struct ib_sa_path_rec *path,
+                                   struct sa_path_rec *path,
                                    struct cm_lap_msg *lap_msg)
 {
        memset(path, 0, sizeof *path);
+       path->rec_type = SA_PATH_REC_TYPE_IB;
        path->dgid = lap_msg->alt_local_gid;
        path->sgid = lap_msg->alt_remote_gid;
-       path->dlid = lap_msg->alt_local_lid;
-       path->slid = lap_msg->alt_remote_lid;
+       sa_path_set_dlid(path, htonl(ntohs(lap_msg->alt_local_lid)));
+       sa_path_set_slid(path, htonl(ntohs(lap_msg->alt_remote_lid)));
        path->flow_label = cm_lap_get_flow_label(lap_msg);
        path->hop_limit = lap_msg->alt_hop_limit;
        path->traffic_class = cm_lap_get_traffic_class(lap_msg);
@@ -3708,7 +3739,7 @@ static void cm_recv_handler(struct ib_mad_agent *mad_agent,
        atomic_long_inc(&port->counter_group[CM_RECV].
                        counter[attr_id - CM_ATTR_ID_OFFSET]);
 
-       work = kmalloc(sizeof *work + sizeof(struct ib_sa_path_rec) * paths,
+       work = kmalloc(sizeof(*work) + sizeof(struct sa_path_rec) * paths,
                       GFP_KERNEL);
        if (!work) {
                ib_free_recv_mad(mad_recv_wc);
@@ -3800,7 +3831,7 @@ static int cm_init_qp_rtr_attr(struct cm_id_private *cm_id_priv,
                                        cm_id_priv->responder_resources;
                        qp_attr->min_rnr_timer = 0;
                }
-               if (cm_id_priv->alt_av.ah_attr.dlid) {
+               if (rdma_ah_get_dlid(&cm_id_priv->alt_av.ah_attr)) {
                        *qp_attr_mask |= IB_QP_ALT_PATH;
                        qp_attr->alt_port_num = cm_id_priv->alt_av.port->port_num;
                        qp_attr->alt_pkey_index = cm_id_priv->alt_av.pkey_index;
@@ -3854,7 +3885,7 @@ static int cm_init_qp_rts_attr(struct cm_id_private *cm_id_priv,
                        default:
                                break;
                        }
-                       if (cm_id_priv->alt_av.ah_attr.dlid) {
+                       if (rdma_ah_get_dlid(&cm_id_priv->alt_av.ah_attr)) {
                                *qp_attr_mask |= IB_QP_PATH_MIG_STATE;
                                qp_attr->path_mig_state = IB_MIG_REARM;
                        }