aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/smi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/core/smi.c')
-rw-r--r--drivers/infiniband/core/smi.c80
1 files changed, 46 insertions, 34 deletions
diff --git a/drivers/infiniband/core/smi.c b/drivers/infiniband/core/smi.c
index e6c6810c8c41..b6dedc0918fe 100644
--- a/drivers/infiniband/core/smi.c
+++ b/drivers/infiniband/core/smi.c
@@ -39,84 +39,80 @@
39#include <rdma/ib_smi.h> 39#include <rdma/ib_smi.h>
40#include "smi.h" 40#include "smi.h"
41 41
42/* 42static enum smi_action __smi_handle_dr_smp_send(u8 node_type, int port_num,
43 * Fixup a directed route SMP for sending 43 u8 *hop_ptr, u8 hop_cnt,
44 * Return IB_SMI_DISCARD if the SMP should be discarded 44 const u8 *initial_path,
45 */ 45 const u8 *return_path,
46enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp, 46 u8 direction,
47 u8 node_type, int port_num) 47 bool dr_dlid_is_permissive,
48 bool dr_slid_is_permissive)
48{ 49{
49 u8 hop_ptr, hop_cnt;
50
51 hop_ptr = smp->hop_ptr;
52 hop_cnt = smp->hop_cnt;
53
54 /* See section 14.2.2.2, Vol 1 IB spec */ 50 /* See section 14.2.2.2, Vol 1 IB spec */
55 /* C14-6 -- valid hop_cnt values are from 0 to 63 */ 51 /* C14-6 -- valid hop_cnt values are from 0 to 63 */
56 if (hop_cnt >= IB_SMP_MAX_PATH_HOPS) 52 if (hop_cnt >= IB_SMP_MAX_PATH_HOPS)
57 return IB_SMI_DISCARD; 53 return IB_SMI_DISCARD;
58 54
59 if (!ib_get_smp_direction(smp)) { 55 if (!direction) {
60 /* C14-9:1 */ 56 /* C14-9:1 */
61 if (hop_cnt && hop_ptr == 0) { 57 if (hop_cnt && *hop_ptr == 0) {
62 smp->hop_ptr++; 58 (*hop_ptr)++;
63 return (smp->initial_path[smp->hop_ptr] == 59 return (initial_path[*hop_ptr] ==
64 port_num ? IB_SMI_HANDLE : IB_SMI_DISCARD); 60 port_num ? IB_SMI_HANDLE : IB_SMI_DISCARD);
65 } 61 }
66 62
67 /* C14-9:2 */ 63 /* C14-9:2 */
68 if (hop_ptr && hop_ptr < hop_cnt) { 64 if (*hop_ptr && *hop_ptr < hop_cnt) {
69 if (node_type != RDMA_NODE_IB_SWITCH) 65 if (node_type != RDMA_NODE_IB_SWITCH)
70 return IB_SMI_DISCARD; 66 return IB_SMI_DISCARD;
71 67
72 /* smp->return_path set when received */ 68 /* return_path set when received */
73 smp->hop_ptr++; 69 (*hop_ptr)++;
74 return (smp->initial_path[smp->hop_ptr] == 70 return (initial_path[*hop_ptr] ==
75 port_num ? IB_SMI_HANDLE : IB_SMI_DISCARD); 71 port_num ? IB_SMI_HANDLE : IB_SMI_DISCARD);
76 } 72 }
77 73
78 /* C14-9:3 -- We're at the end of the DR segment of path */ 74 /* C14-9:3 -- We're at the end of the DR segment of path */
79 if (hop_ptr == hop_cnt) { 75 if (*hop_ptr == hop_cnt) {
80 /* smp->return_path set when received */ 76 /* return_path set when received */
81 smp->hop_ptr++; 77 (*hop_ptr)++;
82 return (node_type == RDMA_NODE_IB_SWITCH || 78 return (node_type == RDMA_NODE_IB_SWITCH ||
83 smp->dr_dlid == IB_LID_PERMISSIVE ? 79 dr_dlid_is_permissive ?
84 IB_SMI_HANDLE : IB_SMI_DISCARD); 80 IB_SMI_HANDLE : IB_SMI_DISCARD);
85 } 81 }
86 82
87 /* C14-9:4 -- hop_ptr = hop_cnt + 1 -> give to SMA/SM */ 83 /* C14-9:4 -- hop_ptr = hop_cnt + 1 -> give to SMA/SM */
88 /* C14-9:5 -- Fail unreasonable hop pointer */ 84 /* C14-9:5 -- Fail unreasonable hop pointer */
89 return (hop_ptr == hop_cnt + 1 ? IB_SMI_HANDLE : IB_SMI_DISCARD); 85 return (*hop_ptr == hop_cnt + 1 ? IB_SMI_HANDLE : IB_SMI_DISCARD);
90 86
91 } else { 87 } else {
92 /* C14-13:1 */ 88 /* C14-13:1 */
93 if (hop_cnt && hop_ptr == hop_cnt + 1) { 89 if (hop_cnt && *hop_ptr == hop_cnt + 1) {
94 smp->hop_ptr--; 90 (*hop_ptr)--;
95 return (smp->return_path[smp->hop_ptr] == 91 return (return_path[*hop_ptr] ==
96 port_num ? IB_SMI_HANDLE : IB_SMI_DISCARD); 92 port_num ? IB_SMI_HANDLE : IB_SMI_DISCARD);
97 } 93 }
98 94
99 /* C14-13:2 */ 95 /* C14-13:2 */
100 if (2 <= hop_ptr && hop_ptr <= hop_cnt) { 96 if (2 <= *hop_ptr && *hop_ptr <= hop_cnt) {
101 if (node_type != RDMA_NODE_IB_SWITCH) 97 if (node_type != RDMA_NODE_IB_SWITCH)
102 return IB_SMI_DISCARD; 98 return IB_SMI_DISCARD;
103 99
104 smp->hop_ptr--; 100 (*hop_ptr)--;
105 return (smp->return_path[smp->hop_ptr] == 101 return (return_path[*hop_ptr] ==
106 port_num ? IB_SMI_HANDLE : IB_SMI_DISCARD); 102 port_num ? IB_SMI_HANDLE : IB_SMI_DISCARD);
107 } 103 }
108 104
109 /* C14-13:3 -- at the end of the DR segment of path */ 105 /* C14-13:3 -- at the end of the DR segment of path */
110 if (hop_ptr == 1) { 106 if (*hop_ptr == 1) {
111 smp->hop_ptr--; 107 (*hop_ptr)--;
112 /* C14-13:3 -- SMPs destined for SM shouldn't be here */ 108 /* C14-13:3 -- SMPs destined for SM shouldn't be here */
113 return (node_type == RDMA_NODE_IB_SWITCH || 109 return (node_type == RDMA_NODE_IB_SWITCH ||
114 smp->dr_slid == IB_LID_PERMISSIVE ? 110 dr_slid_is_permissive ?
115 IB_SMI_HANDLE : IB_SMI_DISCARD); 111 IB_SMI_HANDLE : IB_SMI_DISCARD);
116 } 112 }
117 113
118 /* C14-13:4 -- hop_ptr = 0 -> should have gone to SM */ 114 /* C14-13:4 -- hop_ptr = 0 -> should have gone to SM */
119 if (hop_ptr == 0) 115 if (*hop_ptr == 0)
120 return IB_SMI_HANDLE; 116 return IB_SMI_HANDLE;
121 117
122 /* C14-13:5 -- Check for unreasonable hop pointer */ 118 /* C14-13:5 -- Check for unreasonable hop pointer */
@@ -125,6 +121,22 @@ enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp,
125} 121}
126 122
127/* 123/*
124 * Fixup a directed route SMP for sending
125 * Return IB_SMI_DISCARD if the SMP should be discarded
126 */
127enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp,
128 u8 node_type, int port_num)
129{
130 return __smi_handle_dr_smp_send(node_type, port_num,
131 &smp->hop_ptr, smp->hop_cnt,
132 smp->initial_path,
133 smp->return_path,
134 ib_get_smp_direction(smp),
135 smp->dr_dlid == IB_LID_PERMISSIVE,
136 smp->dr_slid == IB_LID_PERMISSIVE);
137}
138
139/*
128 * Adjust information for a received SMP 140 * Adjust information for a received SMP
129 * Return IB_SMI_DISCARD if the SMP should be dropped 141 * Return IB_SMI_DISCARD if the SMP should be dropped
130 */ 142 */