I have only done basic testing (i.e., the link comes up and IPoIB still works)
but I think this fixes the problem.

Signed-off-by: Ralph Campbell <[EMAIL PROTECTED]>

Index: include/rdma/ib_mad.h
===================================================================
--- include/rdma/ib_mad.h       (revision 4978)
+++ include/rdma/ib_mad.h       (working copy)
@@ -596,7 +596,7 @@
  */
 struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
                                            u32 remote_qpn, u16 pkey_index,
-                                           int rmpp_active,
+                                           int rmpp_active, int directed_route,
                                            int hdr_len, int data_len,
                                            gfp_t gfp_mask);
 
Index: core/user_mad.c
===================================================================
--- core/user_mad.c     (revision 4978)
+++ core/user_mad.c     (working copy)
@@ -51,6 +51,7 @@
 
 #include <rdma/ib_mad.h>
 #include <rdma/ib_user_mad.h>
+#include <rdma/ib_smi.h>
 
 MODULE_AUTHOR("Roland Dreier");
 MODULE_DESCRIPTION("InfiniBand userspace MAD packet access");
@@ -339,6 +340,8 @@
        __be64 *tid;
        int ret, length, hdr_len, copy_offset;
        int rmpp_active, has_rmpp_header;
+       int directed_route;
+       struct ib_smp *smp;
 
        if (count < sizeof (struct ib_user_mad) + IB_MGMT_RMPP_HDR)
                return -EINVAL;
@@ -415,9 +418,20 @@
                goto err_ah;
        }
 
+       /*
+        * Directed route handling starts if the initial LID routed part of
+        * a request or the ending LID routed part of a response is empty.
+        * See section 14.2.2, Vol 1 IB spec.
+        */
+       smp = (struct ib_smp *) packet->mad.data;
+       if (smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
+               directed_route = (ib_get_smp_direction(smp) ?
+                       smp->dr_dlid : smp->dr_slid) == IB_LID_PERMISSIVE;
+       else
+               directed_route = 0;
        packet->msg = ib_create_send_mad(agent,
                                         be32_to_cpu(packet->mad.hdr.qpn),
-                                        0, rmpp_active,
+                                        0, rmpp_active, directed_route,
                                         hdr_len, length - hdr_len,
                                         GFP_KERNEL);
        if (IS_ERR(packet->msg)) {
Index: core/agent.c
===================================================================
--- core/agent.c        (revision 4978)
+++ core/agent.c        (working copy)
@@ -103,6 +103,7 @@
        struct ib_mad_send_buf *send_buf;
        struct ib_ah *ah;
        int ret;
+       int directed_route;
 
        port_priv = ib_get_agent_port(device, port_num);
        if (!port_priv) {
@@ -118,7 +119,20 @@
                return ret;
        }
 
+       /*
+        * Directed route handling starts if the initial LID routed part of
+        * a request or the ending LID routed part of a response is empty.
+        * See section 14.2.2, Vol 1 IB spec.
+        */
+       if (mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {
+               struct ib_smp *smp = (struct ib_smp *) mad;
+
+               directed_route = (ib_get_smp_direction(smp) ?
+                       smp->dr_dlid : smp->dr_slid) == IB_LID_PERMISSIVE;
+       } else
+               directed_route = 0;
        send_buf = ib_create_send_mad(agent, wc->src_qp, wc->pkey_index, 0,
+                                     directed_route,
                                      IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
                                      GFP_KERNEL);
        if (IS_ERR(send_buf)) {
Index: core/sa_query.c
===================================================================
--- core/sa_query.c     (revision 4978)
+++ core/sa_query.c     (working copy)
@@ -574,7 +574,7 @@
                return -ENOMEM;
 
        query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0,
-                                                    0, IB_MGMT_SA_HDR,
+                                                    0, 0, IB_MGMT_SA_HDR,
                                                     IB_MGMT_SA_DATA, gfp_mask);
        if (!query->sa_query.mad_buf) {
                ret = -ENOMEM;
@@ -695,7 +695,7 @@
                return -ENOMEM;
 
        query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0,
-                                                    0, IB_MGMT_SA_HDR,
+                                                    0, 0, IB_MGMT_SA_HDR,
                                                     IB_MGMT_SA_DATA, gfp_mask);
        if (!query->sa_query.mad_buf) {
                ret = -ENOMEM;
@@ -787,7 +787,7 @@
                return -ENOMEM;
 
        query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0,
-                                                    0, IB_MGMT_SA_HDR,
+                                                    0, 0, IB_MGMT_SA_HDR,
                                                     IB_MGMT_SA_DATA, gfp_mask);
        if (!query->sa_query.mad_buf) {
                ret = -ENOMEM;
Index: core/ping.c
===================================================================
--- core/ping.c (revision 4978)
+++ core/ping.c (working copy)
@@ -127,7 +127,7 @@
        }
 
        msg = ib_create_send_mad(mad_agent, mad_recv_wc->wc->src_qp,
-                                mad_recv_wc->wc->pkey_index, 0,
+                                mad_recv_wc->wc->pkey_index, 0, 0,
                                 IB_MGMT_VENDOR_HDR,
                                 mad_recv_wc->mad_len - IB_MGMT_VENDOR_HDR,
                                 GFP_KERNEL);
Index: core/mad_rmpp.c
===================================================================
--- core/mad_rmpp.c     (revision 4978)
+++ core/mad_rmpp.c     (working copy)
@@ -138,8 +138,9 @@
        int ret;
 
        msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp,
-                                recv_wc->wc->pkey_index, 1, IB_MGMT_RMPP_HDR,
-                                IB_MGMT_RMPP_DATA, GFP_KERNEL);
+                                recv_wc->wc->pkey_index, 1, 0,
+                                IB_MGMT_RMPP_HDR, IB_MGMT_RMPP_DATA,
+                                GFP_KERNEL);
        if (!msg)
                return;
 
@@ -163,7 +164,7 @@
                return (void *) ah;
 
        msg = ib_create_send_mad(agent, recv_wc->wc->src_qp,
-                                recv_wc->wc->pkey_index, 1,
+                                recv_wc->wc->pkey_index, 1, 0,
                                 IB_MGMT_RMPP_HDR, IB_MGMT_RMPP_DATA,
                                 GFP_KERNEL);
        if (IS_ERR(msg))
Index: core/mad.c
===================================================================
--- core/mad.c  (revision 4978)
+++ core/mad.c  (working copy)
@@ -665,7 +665,8 @@
        struct ib_wc mad_wc;
        struct ib_send_wr *send_wr = &mad_send_wr->send_wr;
 
-       if (!smi_handle_dr_smp_send(smp, device->node_type, port_num)) {
+       if (mad_send_wr->directed_route &&
+           !smi_handle_dr_smp_send(smp, device->node_type, port_num)) {
                ret = -EINVAL;
                printk(KERN_ERR PFX "Invalid directed route\n");
                goto out;
@@ -699,8 +700,7 @@
        ret = device->process_mad(device, 0, port_num, &mad_wc, NULL,
                                  (struct ib_mad *)smp,
                                  (struct ib_mad *)&mad_priv->mad);
-       switch (ret)
-       {
+       switch (ret) {
        case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY:
                if (response_mad(&mad_priv->mad.mad) &&
                    mad_agent_priv->agent.recv_handler) {
@@ -773,7 +773,7 @@
 
 struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
                                            u32 remote_qpn, u16 pkey_index,
-                                           int rmpp_active,
+                                           int rmpp_active, int directed_route,
                                            int hdr_len, int data_len,
                                            gfp_t gfp_mask)
 {
@@ -818,6 +818,8 @@
        mad_send_wr->send_wr.wr.ud.remote_qkey = IB_QP_SET_QKEY;
        mad_send_wr->send_wr.wr.ud.pkey_index = pkey_index;
 
+       mad_send_wr->directed_route = directed_route;
+
        if (rmpp_active) {
                struct ib_rmpp_mad *rmpp_mad = mad_send_wr->send_buf.mad;
                rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(hdr_len -
Index: core/mad_priv.h
===================================================================
--- core/mad_priv.h     (revision 4978)
+++ core/mad_priv.h     (working copy)
@@ -124,10 +124,11 @@
        struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG];
        __be64 tid;
        unsigned long timeout;
-       int retries;
-       int retry;
-       int refcount;
+       unsigned int retries;
+       unsigned int retry;
+       unsigned int refcount;
        enum ib_wc_status status;
+       int directed_route;
 
        /* RMPP control */
        int last_ack;
Index: core/cm.c
===================================================================
--- core/cm.c   (revision 4978)
+++ core/cm.c   (working copy)
@@ -177,7 +177,7 @@
 
        m = ib_create_send_mad(mad_agent, cm_id_priv->id.remote_cm_qpn, 
                               cm_id_priv->av.pkey_index,
-                              0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
+                              0, 0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
                               GFP_ATOMIC);
        if (IS_ERR(m)) {
                ib_destroy_ah(ah);
@@ -207,7 +207,7 @@
                return PTR_ERR(ah);
 
        m = ib_create_send_mad(port->mad_agent, 1, mad_recv_wc->wc->pkey_index,
-                              0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
+                              0, 0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
                               GFP_ATOMIC);
        if (IS_ERR(m)) {
                ib_destroy_ah(ah);
Index: hw/mthca/mthca_mad.c
===================================================================
--- hw/mthca/mthca_mad.c        (revision 4978)
+++ hw/mthca/mthca_mad.c        (working copy)
@@ -117,7 +117,8 @@
        unsigned long flags;
 
        if (agent) {
-               send_buf = ib_create_send_mad(agent, qpn, 0, 0, IB_MGMT_MAD_HDR,
+               send_buf = ib_create_send_mad(agent, qpn, 0, 0, 0,
+                                             IB_MGMT_MAD_HDR,
                                              IB_MGMT_MAD_DATA, GFP_ATOMIC);
                /*
                 * We rely here on the fact that MLX QPs don't use the

-- 
Ralph Campbell <[EMAIL PROTECTED]>

_______________________________________________
openib-general mailing list
[email protected]
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to