diff options
-rw-r--r-- | drivers/infiniband/core/smi.c | 79 |
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 | /* | 139 | static 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, |
143 | enum 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 | */ | ||
225 | enum 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 | |||
224 | enum smi_forward_action smi_check_forward_dr_smp(struct ib_smp *smp) | 237 | enum 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; |