aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIra Weiny <ira.weiny@intel.com>2015-06-06 14:38:26 -0400
committerDoug Ledford <dledford@redhat.com>2015-06-12 14:49:16 -0400
commit86f0e67a21508b3e6020d53ef92a73081ed7eae1 (patch)
tree6741fabfc028ae7a10fb9bf52534751e0d7e100d
parent92f1505604be05a01851203a5759ad9ed33c8d91 (diff)
IB/mad: Create a generic helper for DR SMP Recv processing
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>
-rw-r--r--drivers/infiniband/core/smi.c79
1 files changed, 46 insertions, 33 deletions
diff --git a/drivers/infiniband/core/smi.c b/drivers/infiniband/core/smi.c
index b6dedc0918fe..eb39146adb80 100644
--- a/drivers/infiniband/core/smi.c
+++ b/drivers/infiniband/core/smi.c
@@ -136,91 +136,104 @@ enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp,
136 smp->dr_slid == IB_LID_PERMISSIVE); 136 smp->dr_slid == IB_LID_PERMISSIVE);
137} 137}
138 138
139/* 139static enum smi_action __smi_handle_dr_smp_recv(u8 node_type, int port_num,
140 * Adjust information for a received SMP 140 int phys_port_cnt,
141 * Return IB_SMI_DISCARD if the SMP should be dropped 141 u8 *hop_ptr, u8 hop_cnt,
142 */ 142 const u8 *initial_path,
143enum smi_action smi_handle_dr_smp_recv(struct ib_smp *smp, u8 node_type, 143 u8 *return_path,
144 int port_num, int phys_port_cnt) 144 u8 direction,
145 bool dr_dlid_is_permissive,
146 bool dr_slid_is_permissive)
145{ 147{
146 u8 hop_ptr, hop_cnt;
147
148 hop_ptr = smp->hop_ptr;
149 hop_cnt = smp->hop_cnt;
150
151 /* See section 14.2.2.2, Vol 1 IB spec */ 148 /* See section 14.2.2.2, Vol 1 IB spec */
152 /* C14-6 -- valid hop_cnt values are from 0 to 63 */ 149 /* C14-6 -- valid hop_cnt values are from 0 to 63 */
153 if (hop_cnt >= IB_SMP_MAX_PATH_HOPS) 150 if (hop_cnt >= IB_SMP_MAX_PATH_HOPS)
154 return IB_SMI_DISCARD; 151 return IB_SMI_DISCARD;
155 152
156 if (!ib_get_smp_direction(smp)) { 153 if (!direction) {
157 /* C14-9:1 -- sender should have incremented hop_ptr */ 154 /* C14-9:1 -- sender should have incremented hop_ptr */
158 if (hop_cnt && hop_ptr == 0) 155 if (hop_cnt && *hop_ptr == 0)
159 return IB_SMI_DISCARD; 156 return IB_SMI_DISCARD;
160 157
161 /* C14-9:2 -- intermediate hop */ 158 /* C14-9:2 -- intermediate hop */
162 if (hop_ptr && hop_ptr < hop_cnt) { 159 if (*hop_ptr && *hop_ptr < hop_cnt) {
163 if (node_type != RDMA_NODE_IB_SWITCH) 160 if (node_type != RDMA_NODE_IB_SWITCH)
164 return IB_SMI_DISCARD; 161 return IB_SMI_DISCARD;
165 162
166 smp->return_path[hop_ptr] = port_num; 163 return_path[*hop_ptr] = port_num;
167 /* smp->hop_ptr updated when sending */ 164 /* hop_ptr updated when sending */
168 return (smp->initial_path[hop_ptr+1] <= phys_port_cnt ? 165 return (initial_path[*hop_ptr+1] <= phys_port_cnt ?
169 IB_SMI_HANDLE : IB_SMI_DISCARD); 166 IB_SMI_HANDLE : IB_SMI_DISCARD);
170 } 167 }
171 168
172 /* C14-9:3 -- We're at the end of the DR segment of path */ 169 /* C14-9:3 -- We're at the end of the DR segment of path */
173 if (hop_ptr == hop_cnt) { 170 if (*hop_ptr == hop_cnt) {
174 if (hop_cnt) 171 if (hop_cnt)
175 smp->return_path[hop_ptr] = port_num; 172 return_path[*hop_ptr] = port_num;
176 /* smp->hop_ptr updated when sending */ 173 /* hop_ptr updated when sending */
177 174
178 return (node_type == RDMA_NODE_IB_SWITCH || 175 return (node_type == RDMA_NODE_IB_SWITCH ||
179 smp->dr_dlid == IB_LID_PERMISSIVE ? 176 dr_dlid_is_permissive ?
180 IB_SMI_HANDLE : IB_SMI_DISCARD); 177 IB_SMI_HANDLE : IB_SMI_DISCARD);
181 } 178 }
182 179
183 /* C14-9:4 -- hop_ptr = hop_cnt + 1 -> give to SMA/SM */ 180 /* C14-9:4 -- hop_ptr = hop_cnt + 1 -> give to SMA/SM */
184 /* C14-9:5 -- fail unreasonable hop pointer */ 181 /* C14-9:5 -- fail unreasonable hop pointer */
185 return (hop_ptr == hop_cnt + 1 ? IB_SMI_HANDLE : IB_SMI_DISCARD); 182 return (*hop_ptr == hop_cnt + 1 ? IB_SMI_HANDLE : IB_SMI_DISCARD);
186 183
187 } else { 184 } else {
188 185
189 /* C14-13:1 */ 186 /* C14-13:1 */
190 if (hop_cnt && hop_ptr == hop_cnt + 1) { 187 if (hop_cnt && *hop_ptr == hop_cnt + 1) {
191 smp->hop_ptr--; 188 (*hop_ptr)--;
192 return (smp->return_path[smp->hop_ptr] == 189 return (return_path[*hop_ptr] ==
193 port_num ? IB_SMI_HANDLE : IB_SMI_DISCARD); 190 port_num ? IB_SMI_HANDLE : IB_SMI_DISCARD);
194 } 191 }
195 192
196 /* C14-13:2 */ 193 /* C14-13:2 */
197 if (2 <= hop_ptr && hop_ptr <= hop_cnt) { 194 if (2 <= *hop_ptr && *hop_ptr <= hop_cnt) {
198 if (node_type != RDMA_NODE_IB_SWITCH) 195 if (node_type != RDMA_NODE_IB_SWITCH)
199 return IB_SMI_DISCARD; 196 return IB_SMI_DISCARD;
200 197
201 /* smp->hop_ptr updated when sending */ 198 /* hop_ptr updated when sending */
202 return (smp->return_path[hop_ptr-1] <= phys_port_cnt ? 199 return (return_path[*hop_ptr-1] <= phys_port_cnt ?
203 IB_SMI_HANDLE : IB_SMI_DISCARD); 200 IB_SMI_HANDLE : IB_SMI_DISCARD);
204 } 201 }
205 202
206 /* C14-13:3 -- We're at the end of the DR segment of path */ 203 /* C14-13:3 -- We're at the end of the DR segment of path */
207 if (hop_ptr == 1) { 204 if (*hop_ptr == 1) {
208 if (smp->dr_slid == IB_LID_PERMISSIVE) { 205 if (dr_slid_is_permissive) {
209 /* giving SMP to SM - update hop_ptr */ 206 /* giving SMP to SM - update hop_ptr */
210 smp->hop_ptr--; 207 (*hop_ptr)--;
211 return IB_SMI_HANDLE; 208 return IB_SMI_HANDLE;
212 } 209 }
213 /* smp->hop_ptr updated when sending */ 210 /* hop_ptr updated when sending */
214 return (node_type == RDMA_NODE_IB_SWITCH ? 211 return (node_type == RDMA_NODE_IB_SWITCH ?
215 IB_SMI_HANDLE : IB_SMI_DISCARD); 212 IB_SMI_HANDLE : IB_SMI_DISCARD);
216 } 213 }
217 214
218 /* C14-13:4 -- hop_ptr = 0 -> give to SM */ 215 /* C14-13:4 -- hop_ptr = 0 -> give to SM */
219 /* C14-13:5 -- Check for unreasonable hop pointer */ 216 /* C14-13:5 -- Check for unreasonable hop pointer */
220 return (hop_ptr == 0 ? IB_SMI_HANDLE : IB_SMI_DISCARD); 217 return (*hop_ptr == 0 ? IB_SMI_HANDLE : IB_SMI_DISCARD);
221 } 218 }
222} 219}
223 220
221/*
222 * Adjust information for a received SMP
223 * Return IB_SMI_DISCARD if the SMP should be dropped
224 */
225enum smi_action smi_handle_dr_smp_recv(struct ib_smp *smp, u8 node_type,
226 int port_num, int phys_port_cnt)
227{
228 return __smi_handle_dr_smp_recv(node_type, port_num, phys_port_cnt,
229 &smp->hop_ptr, smp->hop_cnt,
230 smp->initial_path,
231 smp->return_path,
232 ib_get_smp_direction(smp),
233 smp->dr_dlid == IB_LID_PERMISSIVE,
234 smp->dr_slid == IB_LID_PERMISSIVE);
235}
236
224enum smi_forward_action smi_check_forward_dr_smp(struct ib_smp *smp) 237enum smi_forward_action smi_check_forward_dr_smp(struct ib_smp *smp)
225{ 238{
226 u8 hop_ptr, hop_cnt; 239 u8 hop_ptr, hop_cnt;