b29fa413eaf0973dfb909b917523e524272f0207
[mirror/winof/.git] / ulp / ipoib / kernel / ipoib_xfr_mgr.h
1 /*\r
2  * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
3  *\r
4  * This software is available to you under the OpenIB.org BSD license\r
5  * below:\r
6  *\r
7  *     Redistribution and use in source and binary forms, with or\r
8  *     without modification, are permitted provided that the following\r
9  *     conditions are met:\r
10  *\r
11  *      - Redistributions of source code must retain the above\r
12  *        copyright notice, this list of conditions and the following\r
13  *        disclaimer.\r
14  *\r
15  *      - Redistributions in binary form must reproduce the above\r
16  *        copyright notice, this list of conditions and the following\r
17  *        disclaimer in the documentation and/or other materials\r
18  *        provided with the distribution.\r
19  *\r
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
23  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
24  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
25  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
26  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
27  * SOFTWARE.\r
28  *\r
29  * $Id$\r
30  */\r
31 \r
32 \r
33 #ifndef _IPOIB_XFR_MGR_H_\r
34 #define _IPOIB_XFR_MGR_H_\r
35 \r
36 \r
37 #include <iba/ib_al.h>\r
38 #include <complib/cl_types.h>\r
39 #include <complib/cl_qpool.h>\r
40 #include <complib/cl_spinlock.h>\r
41 #include <complib/cl_qlist.h>\r
42 #include <complib/cl_qpool.h>\r
43 #include <complib/cl_list.h>\r
44 \r
45 \r
46 #include "ipoib_driver.h"\r
47 #include "ip_stats.h"\r
48 #include "ip_packet.h"\r
49 \r
50 \r
51 #include <complib/cl_packon.h>\r
52 /****s* IPoIB Driver/ipoib_hw_addr_t\r
53 * NAME\r
54 *   ipoib_hw_addr_t\r
55 *\r
56 * DESCRIPTION\r
57 *   The ipoib_hw_addr_t structure defines an IPoIB compatible hardware\r
58 *   address.  Values in this structure are stored in network order.\r
59 *\r
60 * SYNOPSIS\r
61 */\r
62 typedef struct _ipoib_hw_addr\r
63 {\r
64         uint32_t        flags_qpn;\r
65         ib_gid_t        gid;\r
66 \r
67 }       PACK_SUFFIX ipoib_hw_addr_t;\r
68 /*\r
69 * FIELDS\r
70 *       flags_qpn\r
71 *               Flags and queue pair number.  Use ipoib_addr_get_flags,\r
72 *               ipoib_addr_set_flags, ipoib_addr_set_qpn, and ipoib_addr_get_qpn\r
73 *               to manipulate the contents.\r
74 *\r
75 *       gid\r
76 *               IB GID value.\r
77 *\r
78 * SEE ALSO\r
79 *       IPoIB, ipoib_addr_get_flags, ipoib_addr_set_flags, ipoib_addr_set_qpn,\r
80 *       ipoib_addr_get_qpn\r
81 *********/\r
82 #include <complib/cl_packoff.h>\r
83 \r
84 \r
85 \r
86 #ifdef __cplusplus\r
87 extern "C"\r
88 {\r
89 #endif\r
90 \r
91 \r
92 /*\r
93  * Address accessors\r
94  */\r
95 \r
96 static inline uint8_t\r
97 ipoib_addr_get_flags(\r
98         IN              const   ipoib_hw_addr_t* const          p_addr )\r
99 {\r
100         return (uint8_t)(cl_ntoh32( p_addr->flags_qpn ) >> 24);\r
101 }\r
102 \r
103 static inline void\r
104 ipoib_addr_set_flags(\r
105         IN                              ipoib_hw_addr_t* const          p_addr,\r
106         IN              const   uint8_t                                         flags )\r
107 {\r
108         p_addr->flags_qpn &= cl_ntoh32( 0xFFFFFF00 );\r
109         p_addr->flags_qpn |= cl_ntoh32( flags );\r
110 }\r
111 \r
112 static inline net32_t\r
113 ipoib_addr_get_qpn(\r
114         IN              const   ipoib_hw_addr_t* const          p_addr )\r
115 {\r
116         return cl_ntoh32( cl_ntoh32( p_addr->flags_qpn ) >> 8 );\r
117 }\r
118 \r
119 static inline void\r
120 ipoib_addr_set_qpn(\r
121         IN                              ipoib_hw_addr_t* const          p_addr,\r
122         IN              const   net32_t                                         qpn )\r
123 {\r
124         p_addr->flags_qpn = cl_ntoh32( (cl_ntoh32(\r
125                 p_addr->flags_qpn ) & 0x000000FF ) | (cl_ntoh32( qpn ) << 8) );\r
126 }\r
127 \r
128 \r
129 /****f* IPOIB/ipoib_mac_from_sst_guid\r
130 * NAME\r
131 *       ipoib_mac_from_sst_guid\r
132 *\r
133 * DESCRIPTION\r
134 *       Generates an ethernet MAC address given a SilverStorm port GUID.\r
135 *\r
136 * SYNOPSIS\r
137 */\r
138 static inline ib_api_status_t\r
139 ipoib_mac_from_sst_guid(\r
140         IN              const   net64_t                                         port_guid,\r
141                 OUT                     mac_addr_t* const                       p_mac_addr )\r
142 {\r
143         const uint8_t   *p_guid = (const uint8_t*)&port_guid;\r
144         uint32_t                low24;\r
145 \r
146         /* Port guid is in network byte order.  OUI is in lower 3 bytes. */\r
147         ASSERT( p_guid[0] == 0x00 && p_guid[1] == 0x06 && p_guid[2] == 0x6a );\r
148 \r
149         /*\r
150          * We end up using only the lower 23-bits of the GUID.  Trap that\r
151          * the 24th (bit 23) through 27th (bit 26) bit aren't set.\r
152          */\r
153         if( port_guid & CL_HTON64( 0x0000000007800000 ) )\r
154                 return IB_INVALID_GUID;\r
155 \r
156         low24 = 0x00FFF000 -\r
157                 ((((uint32_t)cl_ntoh64( port_guid ) & 0x00FFFFFF) - 0x101) * 2);\r
158         low24 -= p_guid[3]; /* minus port number */\r
159 \r
160         p_mac_addr->addr[0] = p_guid[0];\r
161         p_mac_addr->addr[1] = p_guid[1];\r
162         p_mac_addr->addr[2] = p_guid[2];\r
163         p_mac_addr->addr[3] = (uint8_t)(low24 >> 16);\r
164         p_mac_addr->addr[4] = (uint8_t)(low24 >> 8);\r
165         p_mac_addr->addr[5] = (uint8_t)low24;\r
166         \r
167         return IB_SUCCESS;\r
168 }\r
169 /*\r
170 * PARAMETERS\r
171 *       port_guid\r
172 *               The port GUID, in network byte order, for which to generate a\r
173 *               MAC address.\r
174 *\r
175 *       p_mac_addr\r
176 *               Pointer to a mac address in which to store the results.\r
177 *\r
178 * RETURN VALUES\r
179 *       IB_SUCCESS\r
180 *               The MAC address was successfully converted.\r
181 *\r
182 *       IB_INVALID_GUID\r
183 *               The port GUID provided was not a known GUID format.\r
184 *\r
185 * NOTES\r
186 *       The algorithm to convert portGuid to MAC address is as per DN0074, and\r
187 *       assumes a 2 port HCA.\r
188 *\r
189 * SEE ALSO\r
190 *       IPOIB\r
191 *********/\r
192 \r
193 \r
194 /****f* IPOIB/ipoib_mac_from_mlx_guid\r
195 * NAME\r
196 *       ipoib_mac_from_sst_guid\r
197 *\r
198 * DESCRIPTION\r
199 *       Generates an ethernet MAC address given a Mellanox port GUID.\r
200 *\r
201 * SYNOPSIS\r
202 */\r
203 static inline ib_api_status_t\r
204 ipoib_mac_from_mlx_guid(\r
205         IN              const   net64_t                                         port_guid,\r
206                 OUT                     mac_addr_t* const                       p_mac_addr )\r
207 {\r
208         const uint8_t   *p_guid = (const uint8_t*)&port_guid;\r
209         uint32_t                low24;\r
210 \r
211         /* Port guid is in network byte order.  OUI is in lower 3 bytes. */\r
212         ASSERT( p_guid[0] == 0x00 && p_guid[1] == 0x02 && p_guid[2] == 0xc9 );\r
213 \r
214         if( (port_guid & CL_HTON64( 0x000000ffff000000 )) !=\r
215                 CL_HTON64(0x0000000200000000))\r
216         {\r
217                 return IB_INVALID_GUID;\r
218         }\r
219 \r
220         low24 = ((uint32_t)cl_ntoh64( port_guid ) & 0x00FFFFFF);\r
221 \r
222         p_mac_addr->addr[0] = p_guid[0];\r
223         p_mac_addr->addr[1] = p_guid[1];\r
224         p_mac_addr->addr[2] = p_guid[2];\r
225         p_mac_addr->addr[3] = (uint8_t)(low24 >> 16);\r
226         p_mac_addr->addr[4] = (uint8_t)(low24 >> 8);\r
227         p_mac_addr->addr[5] = (uint8_t)low24;\r
228         \r
229         return IB_SUCCESS;\r
230 }\r
231 /*\r
232 * PARAMETERS\r
233 *       port_guid\r
234 *               The port GUID, in network byte order, for which to generate a\r
235 *               MAC address.\r
236 *\r
237 *       p_mac_addr\r
238 *               Pointer to a mac address in which to store the results.\r
239 *\r
240 * RETURN VALUES\r
241 *       IB_SUCCESS\r
242 *               The MAC address was successfully converted.\r
243 *\r
244 *       IB_INVALID_GUID\r
245 *               The port GUID provided was not a known GUID format.\r
246 *\r
247 * NOTES\r
248 *       The algorithm to convert portGuid to MAC address is as per DN0074, and\r
249 *       assumes a 2 port HCA.\r
250 *\r
251 * SEE ALSO\r
252 *       IPOIB\r
253 *********/\r
254 \r
255 \r
256 /****f* IPOIB/ipoib_mac_from_guid\r
257 * NAME\r
258 *       ipoib_mac_from_guid\r
259 *\r
260 * DESCRIPTION\r
261 *       Generates an ethernet MAC address given a port GUID.\r
262 *\r
263 * SYNOPSIS\r
264 */\r
265 static inline ib_api_status_t\r
266 ipoib_mac_from_guid(\r
267         IN              const   net64_t                                         port_guid,\r
268                 OUT                     mac_addr_t* const                       p_mac_addr )\r
269 {\r
270         ib_api_status_t status;\r
271         const uint8_t   *p_guid = (const uint8_t*)&port_guid;\r
272         uint32_t                laa;\r
273 \r
274         /* Port guid is in network byte order.  OUI is in lower 3 bytes. */\r
275         if( p_guid[0] == 0x00 && p_guid[1] == 0x06 && p_guid[2] == 0x6a )\r
276         {\r
277                 status = ipoib_mac_from_sst_guid( port_guid, p_mac_addr );\r
278                 if( status == IB_SUCCESS )\r
279                         return IB_SUCCESS;\r
280         }\r
281         if( p_guid[0] == 0x00 && p_guid[1] == 0x02 && p_guid[2] == 0xc9 )\r
282         {\r
283                 status = ipoib_mac_from_mlx_guid( port_guid, p_mac_addr );\r
284                 if( status == IB_SUCCESS )\r
285                         return IB_SUCCESS;\r
286         }\r
287         \r
288         /* Value of zero is reserved. */\r
289         laa = cl_atomic_inc( &g_ipoib.laa_idx );\r
290 \r
291         if( !laa )\r
292                 return IB_INVALID_GUID;\r
293 \r
294         p_mac_addr->addr[0] = 2; /* LAA bit */\r
295         p_mac_addr->addr[1] = 0;\r
296         p_mac_addr->addr[2] = (uint8_t)(laa >> 24);\r
297         p_mac_addr->addr[3] = (uint8_t)(laa >> 16);\r
298         p_mac_addr->addr[4] = (uint8_t)(laa >> 8);\r
299         p_mac_addr->addr[5] = (uint8_t)laa;\r
300         \r
301         return IB_SUCCESS;\r
302 }\r
303 /*\r
304 * PARAMETERS\r
305 *       port_guid\r
306 *               The port GUID, in network byte order, for which to generate a\r
307 *               MAC address.\r
308 *\r
309 *       p_mac_addr\r
310 *               Pointer to a mac address in which to store the results.\r
311 *\r
312 * RETURN VALUES\r
313 *       IB_SUCCESS\r
314 *               The MAC address was successfully converted.\r
315 *\r
316 *       IB_INVALID_GUID\r
317 *               The port GUID provided was not a known GUID format.\r
318 *\r
319 * NOTES\r
320 *       Creates a locally administered address using a global incrementing counter.\r
321 *\r
322 * SEE ALSO\r
323 *       IPOIB\r
324 *********/\r
325 \r
326 \r
327 /****f* IPOIB/ipoib_sst_guid_from_mac\r
328 * NAME\r
329 *       ipoib_sst_guid_from_mac\r
330 *\r
331 * DESCRIPTION\r
332 *       Generates a port GUID given an ethernet MAC address.\r
333 *\r
334 * SYNOPSIS\r
335 */\r
336 static inline ib_api_status_t\r
337 ipoib_sst_guid_from_mac(\r
338         IN              const   mac_addr_t                                      mac,\r
339                 OUT                     net64_t* const                          p_port_guid )\r
340 {\r
341         uint8_t         *p_guid = (uint8_t*)p_port_guid;\r
342         uint32_t        low24;\r
343 \r
344         /* MAC address is in network byte order.  OUI is in lower 3 bytes. */\r
345         if( mac.addr[0] != 0x00 || \r
346                 mac.addr[1] != 0x06 || \r
347                 mac.addr[2] != 0x6a )\r
348         {\r
349                 return IB_INVALID_GUID;\r
350         }\r
351 \r
352         low24 = mac.addr[3] << 16 || mac.addr[4] << 8 || mac.addr[5];\r
353 \r
354         low24 = 0x00FFF000 - low24;\r
355         /* Divide by two */\r
356         low24 >>= 1;\r
357         /* Add the serial number base offset. */\r
358         low24 += 0x101;\r
359 \r
360         /* OUI */\r
361         p_guid[0] = mac.addr[0];\r
362         p_guid[1] = mac.addr[1];\r
363         p_guid[2] = mac.addr[2];\r
364         /* Port number */\r
365         p_guid[3] = mac.addr[5] & 0x01;\r
366         /* Type */\r
367         p_guid[4] = 0x98;\r
368         /* Serial Number */\r
369         p_guid[5] = (uint8_t)(low24 >> 16);\r
370         p_guid[6] = (uint8_t)(low24 >> 8);\r
371         p_guid[7] = (uint8_t)low24;\r
372         \r
373         return IB_SUCCESS;\r
374 }\r
375 /*\r
376 * PARAMETERS\r
377 *       port_guid\r
378 *               The port GUID, in network byte order, for which to generate a\r
379 *               MAC address.\r
380 *\r
381 *       p_mac_addr\r
382 *               Pointer to a mac address in which to store the results.\r
383 *\r
384 * RETURN VALUES\r
385 *       IB_SUCCESS\r
386 *               The MAC address was successfully converted.\r
387 *\r
388 *       IB_INVALID_GUID\r
389 *               The port GUID provided was not a known GUID format.\r
390 *\r
391 * NOTES\r
392 *       The algorithm to convert portGuid to MAC address is as per DN0074, and\r
393 *       assumes a 2 port HCA.\r
394 *\r
395 * SEE ALSO\r
396 *       IPOIB\r
397 *********/\r
398 \r
399 \r
400 /****f* IPOIB/ipoib_mlx_guid_from_mac\r
401 * NAME\r
402 *       ipoib_mlx_guid_from_mac\r
403 *\r
404 * DESCRIPTION\r
405 *       Generates a port GUID given an ethernet MAC address.\r
406 *\r
407 * SYNOPSIS\r
408 */\r
409 static inline ib_api_status_t\r
410 ipoib_mlx_guid_from_mac(\r
411         IN              const   mac_addr_t                                      mac,\r
412                 OUT                     net64_t* const                          p_port_guid )\r
413 {\r
414         uint8_t         *p_guid = (uint8_t*)p_port_guid;\r
415         uint32_t        low24;\r
416 \r
417         /* MAC address is in network byte order.  OUI is in lower 3 bytes. */\r
418         if( mac.addr[0] != 0x00 || \r
419                 mac.addr[1] != 0x02 || \r
420                 mac.addr[2] != 0xc9 )\r
421         {\r
422                 return IB_INVALID_GUID;\r
423         }\r
424 \r
425         low24 = mac.addr[3] << 16 || mac.addr[4] << 8 || mac.addr[5];\r
426 \r
427         /* OUI */\r
428         p_guid[0] = mac.addr[0];\r
429         p_guid[1] = mac.addr[1];\r
430         p_guid[2] = mac.addr[2];\r
431         p_guid[3] = 0x02;\r
432         p_guid[4] = 0x00;\r
433         /* Serial Number */\r
434         p_guid[5] = (uint8_t)(low24 >> 16);\r
435         p_guid[6] = (uint8_t)(low24 >> 8);\r
436         p_guid[7] = (uint8_t)low24;\r
437         \r
438         return IB_SUCCESS;\r
439 }\r
440 /*\r
441 * PARAMETERS\r
442 *       port_guid\r
443 *               The port GUID, in network byte order, for which to generate a\r
444 *               MAC address.\r
445 *\r
446 *       p_mac_addr\r
447 *               Pointer to a mac address in which to store the results.\r
448 *\r
449 * RETURN VALUES\r
450 *       IB_SUCCESS\r
451 *               The MAC address was successfully converted.\r
452 *\r
453 *       IB_INVALID_GUID\r
454 *               The port GUID provided was not a known GUID format.\r
455 *\r
456 * NOTES\r
457 *       The algorithm to convert portGuid to MAC address is as \r
458 *\r
459 * SEE ALSO\r
460 *       IPOIB\r
461 *********/\r
462 \r
463 \r
464 #ifdef __cplusplus\r
465 }\r
466 #endif\r
467 \r
468 #endif  /* _IPOIB_XFR_MGR_H_ */\r