IB/mad: Create a generic helper for DR SMP Recv processing
authorIra Weiny <ira.weiny@intel.com>
Sat, 6 Jun 2015 18:38:26 +0000 (14:38 -0400)
committerDoug Ledford <dledford@redhat.com>
Fri, 12 Jun 2015 18:49:16 +0000 (14:49 -0400)
IB and OPA SMPs share the same processing algorithm but have different header
formats and permissive LID detection.

Add a helper function which is generic to processing DR SMP Recv messages which
can be used by both IB and OPA SMP code.

Use this function in the current IB function smi_handle_dr_smp_recv.

Signed-off-by: Ira Weiny <ira.weiny@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/core/smi.c

index b6dedc0918fea13b6fbc4d55ec7f635d564edf29..eb39146adb801535af04b830bd08366eda982242 100644 (file)
@@ -136,91 +136,104 @@ enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp,
                                        smp->dr_slid == IB_LID_PERMISSIVE);
 }
 
-/*
- * Adjust information for a received SMP
- * Return IB_SMI_DISCARD if the SMP should be dropped
- */
-enum smi_action smi_handle_dr_smp_recv(struct ib_smp *smp, u8 node_type,
-                                      int port_num, int phys_port_cnt)
+static enum smi_action __smi_handle_dr_smp_recv(u8 node_type, int port_num,
+                                               int phys_port_cnt,
+                                               u8 *hop_ptr, u8 hop_cnt,
+                                               const u8 *initial_path,
+                                               u8 *return_path,
+                                               u8 direction,
+                                               bool dr_dlid_is_permissive,
+                                               bool dr_slid_is_permissive)
 {
-       u8 hop_ptr, hop_cnt;
-
-       hop_ptr = smp->hop_ptr;
-       hop_cnt = smp->hop_cnt;
-
        /* See section 14.2.2.2, Vol 1 IB spec */
        /* C14-6 -- valid hop_cnt values are from 0 to 63 */
        if (hop_cnt >= IB_SMP_MAX_PATH_HOPS)
                return IB_SMI_DISCARD;
 
-       if (!ib_get_smp_direction(smp)) {
+       if (!direction) {
                /* C14-9:1 -- sender should have incremented hop_ptr */
-               if (hop_cnt && hop_ptr == 0)
+               if (hop_cnt && *hop_ptr == 0)
                        return IB_SMI_DISCARD;
 
                /* C14-9:2 -- intermediate hop */
-               if (hop_ptr && hop_ptr < hop_cnt) {
+               if (*hop_ptr && *hop_ptr < hop_cnt) {
                        if (node_type != RDMA_NODE_IB_SWITCH)
                                return IB_SMI_DISCARD;
 
-                       smp->return_path[hop_ptr] = port_num;
-                       /* smp->hop_ptr updated when sending */
-                       return (smp->initial_path[hop_ptr+1] <= phys_port_cnt ?
+                       return_path[*hop_ptr] = port_num;
+                       /* hop_ptr updated when sending */
+                       return (initial_path[*hop_ptr+1] <= phys_port_cnt ?
                                IB_SMI_HANDLE : IB_SMI_DISCARD);
                }
 
                /* C14-9:3 -- We're at the end of the DR segment of path */
-               if (hop_ptr == hop_cnt) {
+               if (*hop_ptr == hop_cnt) {
                        if (hop_cnt)
-                               smp->return_path[hop_ptr] = port_num;
-                       /* smp->hop_ptr updated when sending */
+                               return_path[*hop_ptr] = port_num;
+                       /* hop_ptr updated when sending */
 
                        return (node_type == RDMA_NODE_IB_SWITCH ||
-                               smp->dr_dlid == IB_LID_PERMISSIVE ?
+                               dr_dlid_is_permissive ?
                                IB_SMI_HANDLE : IB_SMI_DISCARD);
                }
 
                /* C14-9:4 -- hop_ptr = hop_cnt + 1 -> give to SMA/SM */
                /* C14-9:5 -- fail unreasonable hop pointer */
-               return (hop_ptr == hop_cnt + 1 ? IB_SMI_HANDLE : IB_SMI_DISCARD);
+               return (*hop_ptr == hop_cnt + 1 ? IB_SMI_HANDLE : IB_SMI_DISCARD);
 
        } else {
 
                /* C14-13:1 */
-               if (hop_cnt && hop_ptr == hop_cnt + 1) {
-                       smp->hop_ptr--;
-                       return (smp->return_path[smp->hop_ptr] ==
+               if (hop_cnt && *hop_ptr == hop_cnt + 1) {
+                       (*hop_ptr)--;
+                       return (return_path[*hop_ptr] ==
                                port_num ? IB_SMI_HANDLE : IB_SMI_DISCARD);
                }
 
                /* C14-13:2 */
-               if (2 <= hop_ptr && hop_ptr <= hop_cnt) {
+               if (2 <= *hop_ptr && *hop_ptr <= hop_cnt) {
                        if (node_type != RDMA_NODE_IB_SWITCH)
                                return IB_SMI_DISCARD;
 
-                       /* smp->hop_ptr updated when sending */
-                       return (smp->return_path[hop_ptr-1] <= phys_port_cnt ?
+                       /* hop_ptr updated when sending */
+                       return (return_path[*hop_ptr-1] <= phys_port_cnt ?
                                IB_SMI_HANDLE : IB_SMI_DISCARD);
                }
 
                /* C14-13:3 -- We're at the end of the DR segment of path */
-               if (hop_ptr == 1) {
-                       if (smp->dr_slid == IB_LID_PERMISSIVE) {
+               if (*hop_ptr == 1) {
+                       if (dr_slid_is_permissive) {
                                /* giving SMP to SM - update hop_ptr */
-                               smp->hop_ptr--;
+                               (*hop_ptr)--;
                                return IB_SMI_HANDLE;
                        }
-                       /* smp->hop_ptr updated when sending */
+                       /* hop_ptr updated when sending */
                        return (node_type == RDMA_NODE_IB_SWITCH ?
                                IB_SMI_HANDLE : IB_SMI_DISCARD);
                }
 
                /* C14-13:4 -- hop_ptr = 0 -> give to SM */
                /* C14-13:5 -- Check for unreasonable hop pointer */
-               return (hop_ptr == 0 ? IB_SMI_HANDLE : IB_SMI_DISCARD);
+               return (*hop_ptr == 0 ? IB_SMI_HANDLE : IB_SMI_DISCARD);
        }
 }
 
+/*
+ * Adjust information for a received SMP
+ * Return IB_SMI_DISCARD if the SMP should be dropped
+ */
+enum smi_action smi_handle_dr_smp_recv(struct ib_smp *smp, u8 node_type,
+                                      int port_num, int phys_port_cnt)
+{
+       return __smi_handle_dr_smp_recv(node_type, port_num, phys_port_cnt,
+                                       &smp->hop_ptr, smp->hop_cnt,
+                                       smp->initial_path,
+                                       smp->return_path,
+                                       ib_get_smp_direction(smp),
+                                       smp->dr_dlid == IB_LID_PERMISSIVE,
+                                       smp->dr_slid == IB_LID_PERMISSIVE);
+}
+
 enum smi_forward_action smi_check_forward_dr_smp(struct ib_smp *smp)
 {
        u8 hop_ptr, hop_cnt;