Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3971c9f6dbf26f077b929dbe14ced60a697ebcf0
Commit:     3971c9f6dbf26f077b929dbe14ced60a697ebcf0
Parent:     e8f9b2ed9882874ca96716597bd8c7113289e77b
Author:     Sean Hefty <[EMAIL PROTECTED]>
AuthorDate: Mon Dec 10 15:53:25 2007 -0800
Committer:  Roland Dreier <[EMAIL PROTECTED]>
CommitDate: Mon Feb 4 20:20:42 2008 -0800

    IB/cm: Add interim support for routed paths
    
    Paths with hop_limit > 1 indicate that the connection will be routed
    between IB subnets.  Update the subnet local field in the CM REQ based
    on the hop_limit value.  In addition, if the path is routed, then set
    the LIDs in the REQ to the permissive LIDs.  This is used to indicate
    to the passive side that it should use the LIDs in the received local
    route header (LRH) associated with the REQ when programming the QP.
    
    This is a temporary work-around to the IB CM to support IB router
    development until the IB router specification is completed.  It is not
    anticipated that this work-around will cause any interoperability
    issues with existing stacks or future stacks that will properly
    support IB routers when defined.
    
    Signed-off-by: Sean Hefty <[EMAIL PROTECTED]>
    Signed-off-by: Roland Dreier <[EMAIL PROTECTED]>
---
 drivers/infiniband/core/cm.c |   89 +++++++++++++++++++++++++++++++-----------
 1 files changed, 66 insertions(+), 23 deletions(-)

diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index c015014..638b727 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -974,6 +974,9 @@ 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;
+
        cm_format_mad_hdr(&req_msg->hdr, CM_REQ_ATTR_ID,
                          cm_form_tid(cm_id_priv, CM_MSG_SEQUENCE_REQ));
 
@@ -997,35 +1000,46 @@ static void cm_format_req(struct cm_req_msg *req_msg,
        cm_req_set_max_cm_retries(req_msg, param->max_cm_retries);
        cm_req_set_srq(req_msg, param->srq);
 
-       req_msg->primary_local_lid = param->primary_path->slid;
-       req_msg->primary_remote_lid = param->primary_path->dlid;
-       req_msg->primary_local_gid = param->primary_path->sgid;
-       req_msg->primary_remote_gid = param->primary_path->dgid;
-       cm_req_set_primary_flow_label(req_msg, param->primary_path->flow_label);
-       cm_req_set_primary_packet_rate(req_msg, param->primary_path->rate);
-       req_msg->primary_traffic_class = param->primary_path->traffic_class;
-       req_msg->primary_hop_limit = param->primary_path->hop_limit;
-       cm_req_set_primary_sl(req_msg, param->primary_path->sl);
-       cm_req_set_primary_subnet_local(req_msg, 1); /* local only... */
+       if (pri_path->hop_limit <= 1) {
+               req_msg->primary_local_lid = pri_path->slid;
+               req_msg->primary_remote_lid = pri_path->dlid;
+       } else {
+               /* Work-around until there's a way to obtain remote LID info */
+               req_msg->primary_local_lid = IB_LID_PERMISSIVE;
+               req_msg->primary_remote_lid = IB_LID_PERMISSIVE;
+       }
+       req_msg->primary_local_gid = pri_path->sgid;
+       req_msg->primary_remote_gid = pri_path->dgid;
+       cm_req_set_primary_flow_label(req_msg, pri_path->flow_label);
+       cm_req_set_primary_packet_rate(req_msg, pri_path->rate);
+       req_msg->primary_traffic_class = pri_path->traffic_class;
+       req_msg->primary_hop_limit = pri_path->hop_limit;
+       cm_req_set_primary_sl(req_msg, pri_path->sl);
+       cm_req_set_primary_subnet_local(req_msg, (pri_path->hop_limit <= 1));
        cm_req_set_primary_local_ack_timeout(req_msg,
                cm_ack_timeout(cm_id_priv->av.port->cm_dev->ack_delay,
-                              param->primary_path->packet_life_time));
+                              pri_path->packet_life_time));
 
-       if (param->alternate_path) {
-               req_msg->alt_local_lid = param->alternate_path->slid;
-               req_msg->alt_remote_lid = param->alternate_path->dlid;
-               req_msg->alt_local_gid = param->alternate_path->sgid;
-               req_msg->alt_remote_gid = param->alternate_path->dgid;
+       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;
+               } else {
+                       req_msg->alt_local_lid = IB_LID_PERMISSIVE;
+                       req_msg->alt_remote_lid = IB_LID_PERMISSIVE;
+               }
+               req_msg->alt_local_gid = alt_path->sgid;
+               req_msg->alt_remote_gid = alt_path->dgid;
                cm_req_set_alt_flow_label(req_msg,
-                                         param->alternate_path->flow_label);
-               cm_req_set_alt_packet_rate(req_msg, 
param->alternate_path->rate);
-               req_msg->alt_traffic_class = 
param->alternate_path->traffic_class;
-               req_msg->alt_hop_limit = param->alternate_path->hop_limit;
-               cm_req_set_alt_sl(req_msg, param->alternate_path->sl);
-               cm_req_set_alt_subnet_local(req_msg, 1); /* local only... */
+                                         alt_path->flow_label);
+               cm_req_set_alt_packet_rate(req_msg, alt_path->rate);
+               req_msg->alt_traffic_class = alt_path->traffic_class;
+               req_msg->alt_hop_limit = alt_path->hop_limit;
+               cm_req_set_alt_sl(req_msg, alt_path->sl);
+               cm_req_set_alt_subnet_local(req_msg, (alt_path->hop_limit <= 
1));
                cm_req_set_alt_local_ack_timeout(req_msg,
                        cm_ack_timeout(cm_id_priv->av.port->cm_dev->ack_delay,
-                                      
param->alternate_path->packet_life_time));
+                                      alt_path->packet_life_time));
        }
 
        if (param->private_data && param->private_data_len)
@@ -1441,6 +1455,34 @@ out:
        return listen_cm_id_priv;
 }
 
+/*
+ * Work-around for inter-subnet connections.  If the LIDs are permissive,
+ * we need to override the LID/SL data in the REQ with the LID information
+ * in the work completion.
+ */
+static void cm_process_routed_req(struct cm_req_msg *req_msg, struct ib_wc *wc)
+{
+       if (!cm_req_get_primary_subnet_local(req_msg)) {
+               if (req_msg->primary_local_lid == IB_LID_PERMISSIVE) {
+                       req_msg->primary_local_lid = cpu_to_be16(wc->slid);
+                       cm_req_set_primary_sl(req_msg, wc->sl);
+               }
+
+               if (req_msg->primary_remote_lid == IB_LID_PERMISSIVE)
+                       req_msg->primary_remote_lid = 
cpu_to_be16(wc->dlid_path_bits);
+       }
+
+       if (!cm_req_get_alt_subnet_local(req_msg)) {
+               if (req_msg->alt_local_lid == IB_LID_PERMISSIVE) {
+                       req_msg->alt_local_lid = cpu_to_be16(wc->slid);
+                       cm_req_set_alt_sl(req_msg, wc->sl);
+               }
+
+               if (req_msg->alt_remote_lid == IB_LID_PERMISSIVE)
+                       req_msg->alt_remote_lid = 
cpu_to_be16(wc->dlid_path_bits);
+       }
+}
+
 static int cm_req_handler(struct cm_work *work)
 {
        struct ib_cm_id *cm_id;
@@ -1481,6 +1523,7 @@ static int cm_req_handler(struct cm_work *work)
        cm_id_priv->id.service_id = req_msg->service_id;
        cm_id_priv->id.service_mask = __constant_cpu_to_be64(~0ULL);
 
+       cm_process_routed_req(req_msg, work->mad_recv_wc->wc);
        cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]);
        ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av);
        if (ret) {
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to