[IPoIB] This patch reuses ipoib_mac_from_general_guid and contains important bugfix...
[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_mlx_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         net16_t                 guid_middle;\r
211 \r
212         /* Port guid is in network byte order.  OUI is in lower 3 bytes. */\r
213         ASSERT( p_guid[0] == 0x00 && p_guid[1] == 0x02 && p_guid[2] == 0xc9 );\r
214 \r
215         guid_middle = (net16_t)((port_guid & CL_HTON64( 0x000000ffff000000 )) >>24);\r
216 \r
217         if (guid_middle == 2) {\r
218                         p_mac_addr->addr[0] = 0;\r
219         } else if (guid_middle == 3) {\r
220                         p_mac_addr->addr[0] = 2;\r
221         } else {\r
222                 return IB_INVALID_GUID;\r
223         }\r
224         low24 = ((uint32_t)cl_ntoh64( port_guid ) & 0x00FFFFFF);\r
225 \r
226         p_mac_addr->addr[1] = p_guid[1];\r
227         p_mac_addr->addr[2] = p_guid[2];\r
228         p_mac_addr->addr[3] = (uint8_t)(low24 >> 16);\r
229         p_mac_addr->addr[4] = (uint8_t)(low24 >> 8);\r
230         p_mac_addr->addr[5] = (uint8_t)low24;\r
231         \r
232         return IB_SUCCESS;\r
233 }\r
234 \r
235 /****f* IPOIB/ipoib_mac_from_dell_guid\r
236 * NAME\r
237 *       ipoib_mac_from_dell_guid\r
238 *\r
239 * DESCRIPTION\r
240 *       Generates an ethernet MAC address given a DELL port GUID.\r
241 *\r
242 * SYNOPSIS\r
243 */\r
244 static inline ib_api_status_t\r
245 ipoib_mac_from_dell_guid(\r
246         IN              const   net64_t                                         port_guid,\r
247                 OUT                     mac_addr_t* const                       p_mac_addr )\r
248 {\r
249         const uint8_t   *p_guid = (const uint8_t*)&port_guid;\r
250 \r
251         /* Port guid is in network byte order.  OUI is in lower 3 bytes. */\r
252         ASSERT( p_guid[0] == 0x00 && p_guid[1] == 0x18 && p_guid[2] == 0x8b );\r
253         \r
254         p_mac_addr->addr[0] = p_guid[0];\r
255         p_mac_addr->addr[1] = p_guid[1];\r
256         p_mac_addr->addr[2] = p_guid[2];\r
257         p_mac_addr->addr[3] = p_guid[5];\r
258         p_mac_addr->addr[4] = p_guid[6];\r
259         p_mac_addr->addr[5] = p_guid[7];\r
260         \r
261         return IB_SUCCESS;\r
262 }\r
263 /*\r
264 * PARAMETERS\r
265 *       port_guid\r
266 *               The port GUID, in network byte order, for which to generate a\r
267 *               MAC address.\r
268 *\r
269 *       p_mac_addr\r
270 *               Pointer to a mac address in which to store the results.\r
271 *\r
272 * RETURN VALUES\r
273 *       IB_SUCCESS\r
274 *               The MAC address was successfully converted.\r
275 *\r
276 *********/\r
277 \r
278 \r
279 /****f* IPOIB/ipoib_mac_from_general_guid\r
280 * NAME\r
281 *       ipoib_mac_from_dell_guid\r
282 *\r
283 * DESCRIPTION\r
284 *       Generates an ethernet MAC address given general port GUID and a bitwise mask\r
285 *\r
286 * SYNOPSIS\r
287 */\r
288 static inline ib_api_status_t\r
289 ipoib_mac_from_general_guid(\r
290         IN              const   net64_t                                         port_guid,\r
291         IN                              uint32_t                                                guid_mask,\r
292                 OUT                     mac_addr_t* const                       p_mac_addr )\r
293 {\r
294         static const mac_addr_size =  HW_ADDR_LEN;\r
295         uint8_t i;\r
296         const uint8_t   *p_guid = (const uint8_t*)&port_guid;\r
297         int digit_counter = 0;\r
298 \r
299         //All non-zero bits of guid_mask indicates the number of an appropriate byte in\r
300         // port_guid, that will be used in MAC address construction\r
301         for (i = 7; guid_mask; guid_mask >>= 1, --i) {\r
302                 if (guid_mask & 1 ) {\r
303                         ++digit_counter;\r
304                         if (digit_counter > mac_addr_size) {\r
305                                 //to avoid negative index\r
306                                 return IB_INVALID_GUID_MASK;\r
307                         }\r
308                         p_mac_addr->addr[mac_addr_size - digit_counter] = p_guid [i];\r
309                 }\r
310         }\r
311                 // check for the mask validity: it should have 6 non-zero bits\r
312                 if (digit_counter != mac_addr_size) {\r
313                         return IB_INVALID_GUID_MASK;\r
314                 }\r
315                 \r
316         return IB_SUCCESS;\r
317 }\r
318 \r
319 /*\r
320 * PARAMETERS\r
321 *       port_guid\r
322 *               The port GUID, in network byte order, for which to generate a\r
323 *               MAC address.\r
324 *\r
325 *       guid_mask\r
326 *               Each BIT in the mask indicates whether to include the appropriate BYTE\r
327 *               to the MAC address. Bit 0 corresponds to the less significant BYTE , i.e.\r
328 *               highest index in the MAC array\r
329 *\r
330 *       p_mac_addr\r
331 *               Pointer to a mac address in which to store the results.\r
332 *\r
333 * RETURN VALUES\r
334 *       IB_SUCCESS\r
335 *               The MAC address was successfully converted.\r
336 *\r
337 *       IB_INVALID_GUID\r
338 *               The port GUID provided was not a known GUID format.\r
339 *\r
340 * SEE ALSO\r
341 *       IPOIB\r
342 *********/\r
343 \r
344 \r
345 /****f* IPOIB/ipoib_mac_from_voltaire_guid\r
346 * NAME\r
347 *       ipoib_mac_from_voltaire_guid\r
348 *\r
349 * DESCRIPTION\r
350 *       Generates an ethernet MAC address given a Voltaire port GUID.\r
351 *\r
352 * SYNOPSIS\r
353 */\r
354 static inline ib_api_status_t\r
355 ipoib_mac_from_voltaire_guid(\r
356         IN              const   net64_t                                         port_guid,\r
357                 OUT                     mac_addr_t* const                       p_mac_addr )\r
358 {\r
359         const uint8_t   *p_guid = (const uint8_t*)&port_guid;\r
360 \r
361         /* Port guid is in network byte order.  OUI is in lower 3 bytes. */\r
362         ASSERT( p_guid[0] == 0x00 && p_guid[1] == 0x08 && p_guid[2] == 0xf1 );\r
363 \r
364         p_mac_addr->addr[0] = p_guid[0];\r
365         p_mac_addr->addr[1] = p_guid[1];\r
366         p_mac_addr->addr[2] = p_guid[2];\r
367         p_mac_addr->addr[3] = p_guid[4] ^ p_guid[6];\r
368         p_mac_addr->addr[4] = p_guid[5] ^ p_guid[7];\r
369         p_mac_addr->addr[5] = p_guid[5] + p_guid[6] + p_guid[7];\r
370 \r
371         return IB_SUCCESS;\r
372 }\r
373 \r
374 \r
375 /****f* IPOIB/ipoib_mac_from_guid\r
376 * NAME\r
377 *       ipoib_mac_from_guid\r
378 *\r
379 * DESCRIPTION\r
380 *       Generates an ethernet MAC address given a port GUID.\r
381 *\r
382 * SYNOPSIS\r
383 */\r
384 static inline ib_api_status_t\r
385 ipoib_mac_from_guid(\r
386         IN              const   net64_t                                         port_guid,\r
387         IN                              uint32_t                                        guid_mask,\r
388                 OUT                     mac_addr_t* const                       p_mac_addr\r
389                 )\r
390 {\r
391         static const guid_default_mask = 0xE7; //==0b 11100111\r
392         ib_api_status_t status = IB_INVALID_GUID;\r
393         ib_api_status_t mask_status = IB_SUCCESS;\r
394         const uint8_t   *p_guid = (const uint8_t*)&port_guid;\r
395         uint32_t                laa;\r
396 \r
397         if ( guid_mask ) \r
398         {\r
399                 mask_status = ipoib_mac_from_general_guid(port_guid, guid_mask, p_mac_addr);\r
400                 if( mask_status == IB_SUCCESS )\r
401                                 return IB_SUCCESS;\r
402                 //otherwise, mask was invalid, getting back to standard flow\r
403                 /*if (status == IB_INVALID_GUID_MASK)\r
404                 {\r
405                         IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_ERROR,\r
406                         ("Invalid GUID mask received, rejecting it") );\r
407                 }*/\r
408         }\r
409                         \r
410         if( p_guid[0] == 0 ) \r
411         {\r
412                 if( p_guid[1] == 0x02 && p_guid[2] == 0xc9 )\r
413                 {\r
414                         status = ipoib_mac_from_mlx_guid( port_guid, p_mac_addr );\r
415                 }\r
416                 else if( p_guid[1] == 0x08 && p_guid[2] == 0xf1 )\r
417                 {\r
418                         status = ipoib_mac_from_voltaire_guid( port_guid, p_mac_addr );\r
419                 }\r
420                 else if( p_guid[1] == 0x30 && p_guid[2] == 0x48 )\r
421                 {\r
422                         //Supermicro GUID\r
423                         status =ipoib_mac_from_general_guid(port_guid, guid_default_mask, p_mac_addr);\r
424                 }\r
425                 else if( p_guid[1] == 0x05 && p_guid[2] == 0xad )\r
426                 {\r
427                         //Cisco GUID \r
428                         status =ipoib_mac_from_general_guid(port_guid, guid_default_mask, p_mac_addr);\r
429                 }        \r
430                 /* Port guid is in network byte order.  OUI is in lower 3 bytes. */\r
431                 else if( p_guid[1] == 0x06 && p_guid[2] == 0x6a )\r
432                 {\r
433                         status = ipoib_mac_from_sst_guid( port_guid, p_mac_addr );\r
434                 }\r
435                 else if( p_guid[1] == 0x1a && p_guid[2] == 0x4b )\r
436                 {\r
437                         //HP GUID\r
438                         status =ipoib_mac_from_general_guid(port_guid, guid_default_mask, p_mac_addr);\r
439                 }\r
440                 else if( p_guid[1] == 0x18 && p_guid[2] == 0x8b )\r
441                 {\r
442                         //DELL GUID\r
443                         status =ipoib_mac_from_general_guid(port_guid, guid_default_mask, p_mac_addr);\r
444                 }\r
445                 \r
446                 if (status == IB_SUCCESS )\r
447                 {\r
448                         ASSERT ( mask_status == IB_SUCCESS || mask_status == IB_INVALID_GUID_MASK );\r
449                         return mask_status; \r
450                 }\r
451         }\r
452 \r
453         /* Value of zero is reserved. */\r
454         laa = cl_atomic_inc( &g_ipoib.laa_idx );\r
455 \r
456         if( !laa )\r
457                 return IB_INVALID_GUID;\r
458 \r
459         p_mac_addr->addr[0] = 2; /* LAA bit */\r
460         p_mac_addr->addr[1] = 0;\r
461         p_mac_addr->addr[2] = (uint8_t)(laa >> 24);\r
462         p_mac_addr->addr[3] = (uint8_t)(laa >> 16);\r
463         p_mac_addr->addr[4] = (uint8_t)(laa >> 8);\r
464         p_mac_addr->addr[5] = (uint8_t)laa;\r
465         \r
466         return mask_status;\r
467 }\r
468 /*\r
469 * PARAMETERS\r
470 *       port_guid\r
471 *               The port GUID, in network byte order, for which to generate a\r
472 *               MAC address.\r
473 *\r
474 *       p_mac_addr\r
475 *               Pointer to a mac address in which to store the results.\r
476 *\r
477 * RETURN VALUES\r
478 *       IB_SUCCESS\r
479 *               The MAC address was successfully converted.\r
480 *\r
481 *       IB_INVALID_GUID\r
482 *               The port GUID provided was not a known GUID format.\r
483 *\r
484 * NOTES\r
485 *       Creates a locally administered address using a global incrementing counter.\r
486 *\r
487 * SEE ALSO\r
488 *       IPOIB\r
489 *********/\r
490 \r
491 \r
492 /****f* IPOIB/ipoib_sst_guid_from_mac\r
493 * NAME\r
494 *       ipoib_sst_guid_from_mac\r
495 *\r
496 * DESCRIPTION\r
497 *       Generates a port GUID given an ethernet MAC address.\r
498 *\r
499 * SYNOPSIS\r
500 */\r
501 static inline ib_api_status_t\r
502 ipoib_sst_guid_from_mac(\r
503         IN              const   mac_addr_t                                      mac,\r
504                 OUT                     net64_t* const                          p_port_guid )\r
505 {\r
506         uint8_t         *p_guid = (uint8_t*)p_port_guid;\r
507         uint32_t        low24;\r
508 \r
509         /* MAC address is in network byte order.  OUI is in lower 3 bytes. */\r
510         if( mac.addr[0] != 0x00 || \r
511                 mac.addr[1] != 0x06 || \r
512                 mac.addr[2] != 0x6a )\r
513         {\r
514                 return IB_INVALID_GUID;\r
515         }\r
516 \r
517         low24 = mac.addr[3] << 16 || mac.addr[4] << 8 || mac.addr[5];\r
518 \r
519         low24 = 0x00FFF000 - low24;\r
520         /* Divide by two */\r
521         low24 >>= 1;\r
522         /* Add the serial number base offset. */\r
523         low24 += 0x101;\r
524 \r
525         /* OUI */\r
526         p_guid[0] = mac.addr[0];\r
527         p_guid[1] = mac.addr[1];\r
528         p_guid[2] = mac.addr[2];\r
529         /* Port number */\r
530         p_guid[3] = mac.addr[5] & 0x01;\r
531         /* Type */\r
532         p_guid[4] = 0x98;\r
533         /* Serial Number */\r
534         p_guid[5] = (uint8_t)(low24 >> 16);\r
535         p_guid[6] = (uint8_t)(low24 >> 8);\r
536         p_guid[7] = (uint8_t)low24;\r
537         \r
538         return IB_SUCCESS;\r
539 }\r
540 /*\r
541 * PARAMETERS\r
542 *       port_guid\r
543 *               The port GUID, in network byte order, for which to generate a\r
544 *               MAC address.\r
545 *\r
546 *       p_mac_addr\r
547 *               Pointer to a mac address in which to store the results.\r
548 *\r
549 * RETURN VALUES\r
550 *       IB_SUCCESS\r
551 *               The MAC address was successfully converted.\r
552 *\r
553 *       IB_INVALID_GUID\r
554 *               The port GUID provided was not a known GUID format.\r
555 *\r
556 * NOTES\r
557 *       The algorithm to convert portGuid to MAC address is as per DN0074, and\r
558 *       assumes a 2 port HCA.\r
559 *\r
560 * SEE ALSO\r
561 *       IPOIB\r
562 *********/\r
563 \r
564 \r
565 /****f* IPOIB/ipoib_mlx_guid_from_mac\r
566 * NAME\r
567 *       ipoib_mlx_guid_from_mac\r
568 *\r
569 * DESCRIPTION\r
570 *       Generates a port GUID given an ethernet MAC address.\r
571 *\r
572 * SYNOPSIS\r
573 */\r
574 static inline ib_api_status_t\r
575 ipoib_mlx_guid_from_mac(\r
576         IN              const   mac_addr_t                                      mac,\r
577                 OUT                     net64_t* const                          p_port_guid )\r
578 {\r
579         uint8_t         *p_guid = (uint8_t*)p_port_guid;\r
580         uint32_t        low24;\r
581 \r
582         /* MAC address is in network byte order.  OUI is in lower 3 bytes. */\r
583         if( mac.addr[0] != 0x00 || \r
584                 mac.addr[1] != 0x02 || \r
585                 mac.addr[2] != 0xc9 )\r
586         {\r
587                 return IB_INVALID_GUID;\r
588         }\r
589 \r
590         low24 = mac.addr[3] << 16 || mac.addr[4] << 8 || mac.addr[5];\r
591 \r
592         /* OUI */\r
593         p_guid[0] = mac.addr[0];\r
594         p_guid[1] = mac.addr[1];\r
595         p_guid[2] = mac.addr[2];\r
596         p_guid[3] = 0x02;\r
597         p_guid[4] = 0x00;\r
598         /* Serial Number */\r
599         p_guid[5] = (uint8_t)(low24 >> 16);\r
600         p_guid[6] = (uint8_t)(low24 >> 8);\r
601         p_guid[7] = (uint8_t)low24;\r
602         \r
603         return IB_SUCCESS;\r
604 }\r
605 /*\r
606 * PARAMETERS\r
607 *       port_guid\r
608 *               The port GUID, in network byte order, for which to generate a\r
609 *               MAC address.\r
610 *\r
611 *       p_mac_addr\r
612 *               Pointer to a mac address in which to store the results.\r
613 *\r
614 * RETURN VALUES\r
615 *       IB_SUCCESS\r
616 *               The MAC address was successfully converted.\r
617 *\r
618 *       IB_INVALID_GUID\r
619 *               The port GUID provided was not a known GUID format.\r
620 *\r
621 * NOTES\r
622 *       The algorithm to convert portGuid to MAC address is as \r
623 *\r
624 * SEE ALSO\r
625 *       IPOIB\r
626 *********/\r
627 \r
628 \r
629 /****f* IPOIB/ipoib_is_voltaire_router_gid\r
630 * NAME\r
631 *       ipoib_is_voltaire_router_gid\r
632 *\r
633 * DESCRIPTION\r
634 *       Checks whether the GID belongs to Voltaire IP router\r
635 *\r
636 * SYNOPSIS\r
637 */\r
638 boolean_t\r
639 static inline\r
640 ipoib_is_voltaire_router_gid(\r
641         IN              const   ib_gid_t                                        *p_gid )\r
642 {\r
643         static const uint8_t VOLTAIRE_GUID_PREFIX[] = {0, 0x08, 0xf1, 0, 0x1};\r
644 \r
645         return !cl_memcmp( &p_gid->unicast.interface_id, VOLTAIRE_GUID_PREFIX,\r
646                 sizeof(VOLTAIRE_GUID_PREFIX) );\r
647 }\r
648 \r
649 \r
650 #ifdef __cplusplus\r
651 }\r
652 #endif\r
653 \r
654 #endif  /* _IPOIB_XFR_MGR_H_ */\r