aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;