[IPoIB] This patch adds support for user-define mask for generic mac generation....
[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 #define MAC_ADDR_SIZE 6\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 /*\r
321 * PARAMETERS\r
322 *       port_guid\r
323 *               The port GUID, in network byte order, for which to generate a\r
324 *               MAC address.\r
325 *\r
326 *       guid_mask\r
327 *               Each BIT in the mask indicates whether to include the appropriate BYTE\r
328 *               to the MAC address. Bit 0 corresponds to the less significant BYTE , i.e.\r
329 *               highest index in the MAC array\r
330 *\r
331 *       p_mac_addr\r
332 *               Pointer to a mac address in which to store the results.\r
333 *\r
334 * RETURN VALUES\r
335 *       IB_SUCCESS\r
336 *               The MAC address was successfully converted.\r
337 *\r
338 *       IB_INVALID_GUID\r
339 *               The port GUID provided was not a known GUID format.\r
340 *\r
341 * SEE ALSO\r
342 *       IPOIB\r
343 *********/\r
344 \r
345 \r
346 /****f* IPOIB/ipoib_mac_from_voltaire_guid\r
347 * NAME\r
348 *       ipoib_mac_from_voltaire_guid\r
349 *\r
350 * DESCRIPTION\r
351 *       Generates an ethernet MAC address given a Voltaire port GUID.\r
352 *\r
353 * SYNOPSIS\r
354 */\r
355 static inline ib_api_status_t\r
356 ipoib_mac_from_voltaire_guid(\r
357         IN              const   net64_t                                         port_guid,\r
358                 OUT                     mac_addr_t* const                       p_mac_addr )\r
359 {\r
360         const uint8_t   *p_guid = (const uint8_t*)&port_guid;\r
361 \r
362         /* Port guid is in network byte order.  OUI is in lower 3 bytes. */\r
363         ASSERT( p_guid[0] == 0x00 && p_guid[1] == 0x08 && p_guid[2] == 0xf1 );\r
364 \r
365         p_mac_addr->addr[0] = p_guid[0];\r
366         p_mac_addr->addr[1] = p_guid[1];\r
367         p_mac_addr->addr[2] = p_guid[2];\r
368         p_mac_addr->addr[3] = p_guid[4] ^ p_guid[6];\r
369         p_mac_addr->addr[4] = p_guid[5] ^ p_guid[7];\r
370         p_mac_addr->addr[5] = p_guid[5] + p_guid[6] + p_guid[7];\r
371 \r
372         return IB_SUCCESS;\r
373 }\r
374 \r
375 /****f* IPOIB/ipoib_mac_from_supermicro_guid\r
376 * NAME\r
377 *       ipoib_mac_from_supermicro_guid\r
378 *\r
379 * DESCRIPTION\r
380 *       Generates an ethernet MAC address given a supermicro port GUID.\r
381 *\r
382 * SYNOPSIS\r
383 */\r
384 static inline ib_api_status_t\r
385 ipoib_mac_from_supermicro_guid(\r
386         IN              const   net64_t                                         port_guid,\r
387                 OUT                     mac_addr_t* const                       p_mac_addr )\r
388 {\r
389         const uint8_t   *p_guid = (const uint8_t*)&port_guid;\r
390 \r
391         /* Port guid is in network byte order.  OUI is in lower 3 bytes. */\r
392         ASSERT( p_guid[0] == 0x00 && p_guid[1] == 0x30 && p_guid[2] == 0x48 \r
393         && p_guid[3] == 0xff && p_guid[4] == 0xff);\r
394 \r
395         p_mac_addr->addr[0] = 0;\r
396         p_mac_addr->addr[1] = 0x30;\r
397         p_mac_addr->addr[2] = 0x48; \r
398         p_mac_addr->addr[3] = p_guid[5];\r
399         p_mac_addr->addr[4] = p_guid[6];\r
400         p_mac_addr->addr[5] = p_guid[7];\r
401 \r
402         return IB_SUCCESS;\r
403 }\r
404 \r
405 /****f* IPOIB/ipoib_mac_from_cisco_guid\r
406 * NAME\r
407 *       ipoib_mac_from_cisco_guid\r
408 *\r
409 * DESCRIPTION\r
410 *       Generates an ethernet MAC address given a Cisco port GUID.\r
411 *\r
412 * SYNOPSIS\r
413 */\r
414 static inline ib_api_status_t\r
415 ipoib_mac_from_cisco_guid(\r
416         IN              const   net64_t                                         port_guid,\r
417                 OUT                     mac_addr_t* const                       p_mac_addr )\r
418 {\r
419         const uint8_t   *p_guid = (const uint8_t*)&port_guid;\r
420 \r
421         /* Port guid is in network byte order.  OUI is in lower 3 bytes. */\r
422         ASSERT( p_guid[0] == 0x00 && p_guid[1] == 0x5 && p_guid[2] == 0xad);\r
423 \r
424         p_mac_addr->addr[0] = 0;\r
425         p_mac_addr->addr[1] = 0x5;\r
426         p_mac_addr->addr[2] = 0xad; \r
427         p_mac_addr->addr[3] = p_guid[5];\r
428         p_mac_addr->addr[4] = p_guid[6];\r
429         p_mac_addr->addr[5] = p_guid[7];\r
430 \r
431         return IB_SUCCESS;\r
432 }\r
433 \r
434 /****f* IPOIB/ipoib_mac_from_hp_guid\r
435 * NAME\r
436 *       ipoib_mac_from_hp_guid\r
437 *\r
438 * DESCRIPTION\r
439 *       Generates an ethernet MAC address given a HP port GUID.\r
440 *\r
441 * SYNOPSIS\r
442 */\r
443 static inline ib_api_status_t\r
444 ipoib_mac_from_hp_guid(\r
445         IN              const   net64_t                                         port_guid,\r
446                 OUT                     mac_addr_t* const                       p_mac_addr )\r
447 {\r
448         const uint8_t   *p_guid = (const uint8_t*)&port_guid;\r
449 \r
450         /* Port guid is in network byte order.  OUI is in lower 3 bytes. */\r
451         ASSERT( p_guid[0] == 0x00 && p_guid[1] == 0x1a && p_guid[2] == 0x4b);\r
452 \r
453         p_mac_addr->addr[0] = 0;\r
454         p_mac_addr->addr[1] = 0x1a;\r
455         p_mac_addr->addr[2] = 0x4b; \r
456         p_mac_addr->addr[3] = p_guid[5];\r
457         p_mac_addr->addr[4] = p_guid[6];\r
458         p_mac_addr->addr[5] = p_guid[7];\r
459 \r
460         return IB_SUCCESS;\r
461 }\r
462 \r
463 /*\r
464 * PARAMETERS\r
465 *       port_guid\r
466 *               The port GUID, in network byte order, for which to generate a\r
467 *               MAC address.\r
468 *\r
469 *       p_mac_addr\r
470 *               Pointer to a mac address in which to store the results.\r
471 *\r
472 * RETURN VALUES\r
473 *       IB_SUCCESS\r
474 *               The MAC address was successfully converted.\r
475 *\r
476 * SEE ALSO\r
477 *       IPOIB\r
478 *********/\r
479 \r
480 \r
481 /****f* IPOIB/ipoib_mac_from_guid\r
482 * NAME\r
483 *       ipoib_mac_from_guid\r
484 *\r
485 * DESCRIPTION\r
486 *       Generates an ethernet MAC address given a port GUID.\r
487 *\r
488 * SYNOPSIS\r
489 */\r
490 static inline ib_api_status_t\r
491 ipoib_mac_from_guid(\r
492         IN              const   net64_t                                         port_guid,\r
493         IN                              uint32_t                                        guid_mask,\r
494                 OUT                     mac_addr_t* const                       p_mac_addr\r
495                 )\r
496 {\r
497         static const guid_default_mask = 0xE7; //==0b 11100111\r
498         ib_api_status_t status;\r
499         const uint8_t   *p_guid = (const uint8_t*)&port_guid;\r
500         uint32_t                laa;\r
501 \r
502         if ( guid_mask ) \r
503         {\r
504                 status = ipoib_mac_from_general_guid(port_guid, guid_mask, p_mac_addr);\r
505                 if( status == IB_SUCCESS )\r
506                                 return IB_SUCCESS;\r
507                 //otherwise, mask was invalid, getting back to standard flow\r
508         }\r
509                         \r
510         if( p_guid[0] == 0 ) \r
511         {\r
512                 if( p_guid[1] == 0x02 && p_guid[2] == 0xc9 )\r
513                 {\r
514                         status = ipoib_mac_from_mlx_guid( port_guid, p_mac_addr );\r
515                         if( status == IB_SUCCESS )\r
516                                 return IB_SUCCESS;\r
517                 }\r
518                 else if( p_guid[1] == 0x08 && p_guid[2] == 0xf1 )\r
519                 {\r
520                         status = ipoib_mac_from_voltaire_guid( port_guid, p_mac_addr );\r
521                         if( status == IB_SUCCESS )\r
522                                 return IB_SUCCESS;\r
523                 }\r
524                 else if( p_guid[1] == 0x30 && p_guid[2] == 0x48 )\r
525                 {\r
526                         status = ipoib_mac_from_supermicro_guid( port_guid, p_mac_addr );\r
527                         if( status == IB_SUCCESS )\r
528                                 return IB_SUCCESS;\r
529                 }\r
530                 else if( p_guid[1] == 0x05 && p_guid[2] == 0xad )\r
531                 {\r
532                         status = ipoib_mac_from_cisco_guid( port_guid, p_mac_addr );\r
533                         if( status == IB_SUCCESS )\r
534                                 return IB_SUCCESS;\r
535                 }        \r
536                 /* Port guid is in network byte order.  OUI is in lower 3 bytes. */\r
537                 else if( p_guid[1] == 0x06 && p_guid[2] == 0x6a )\r
538                 {\r
539                         status = ipoib_mac_from_sst_guid( port_guid, p_mac_addr );\r
540                         if( status == IB_SUCCESS )\r
541                                 return IB_SUCCESS;\r
542                 }\r
543                 else if( p_guid[1] == 0x1a && p_guid[2] == 0x4b )\r
544                 {\r
545                         status = ipoib_mac_from_hp_guid( port_guid, p_mac_addr );\r
546                         if( status == IB_SUCCESS )\r
547                                 return IB_SUCCESS;\r
548                 }\r
549                 else if( p_guid[1] == 0x18 && p_guid[2] == 0x8b )\r
550                 {\r
551                         status = ipoib_mac_from_dell_guid( port_guid, p_mac_addr );\r
552                         if( status == IB_SUCCESS )\r
553                                 return IB_SUCCESS;\r
554                 }\r
555         }\r
556 \r
557         /* Value of zero is reserved. */\r
558         laa = cl_atomic_inc( &g_ipoib.laa_idx );\r
559 \r
560         if( !laa )\r
561                 return IB_INVALID_GUID;\r
562 \r
563         p_mac_addr->addr[0] = 2; /* LAA bit */\r
564         p_mac_addr->addr[1] = 0;\r
565         p_mac_addr->addr[2] = (uint8_t)(laa >> 24);\r
566         p_mac_addr->addr[3] = (uint8_t)(laa >> 16);\r
567         p_mac_addr->addr[4] = (uint8_t)(laa >> 8);\r
568         p_mac_addr->addr[5] = (uint8_t)laa;\r
569         \r
570         return IB_SUCCESS;\r
571 }\r
572 /*\r
573 * PARAMETERS\r
574 *       port_guid\r
575 *               The port GUID, in network byte order, for which to generate a\r
576 *               MAC address.\r
577 *\r
578 *       p_mac_addr\r
579 *               Pointer to a mac address in which to store the results.\r
580 *\r
581 * RETURN VALUES\r
582 *       IB_SUCCESS\r
583 *               The MAC address was successfully converted.\r
584 *\r
585 *       IB_INVALID_GUID\r
586 *               The port GUID provided was not a known GUID format.\r
587 *\r
588 * NOTES\r
589 *       Creates a locally administered address using a global incrementing counter.\r
590 *\r
591 * SEE ALSO\r
592 *       IPOIB\r
593 *********/\r
594 \r
595 \r
596 /****f* IPOIB/ipoib_sst_guid_from_mac\r
597 * NAME\r
598 *       ipoib_sst_guid_from_mac\r
599 *\r
600 * DESCRIPTION\r
601 *       Generates a port GUID given an ethernet MAC address.\r
602 *\r
603 * SYNOPSIS\r
604 */\r
605 static inline ib_api_status_t\r
606 ipoib_sst_guid_from_mac(\r
607         IN              const   mac_addr_t                                      mac,\r
608                 OUT                     net64_t* const                          p_port_guid )\r
609 {\r
610         uint8_t         *p_guid = (uint8_t*)p_port_guid;\r
611         uint32_t        low24;\r
612 \r
613         /* MAC address is in network byte order.  OUI is in lower 3 bytes. */\r
614         if( mac.addr[0] != 0x00 || \r
615                 mac.addr[1] != 0x06 || \r
616                 mac.addr[2] != 0x6a )\r
617         {\r
618                 return IB_INVALID_GUID;\r
619         }\r
620 \r
621         low24 = mac.addr[3] << 16 || mac.addr[4] << 8 || mac.addr[5];\r
622 \r
623         low24 = 0x00FFF000 - low24;\r
624         /* Divide by two */\r
625         low24 >>= 1;\r
626         /* Add the serial number base offset. */\r
627         low24 += 0x101;\r
628 \r
629         /* OUI */\r
630         p_guid[0] = mac.addr[0];\r
631         p_guid[1] = mac.addr[1];\r
632         p_guid[2] = mac.addr[2];\r
633         /* Port number */\r
634         p_guid[3] = mac.addr[5] & 0x01;\r
635         /* Type */\r
636         p_guid[4] = 0x98;\r
637         /* Serial Number */\r
638         p_guid[5] = (uint8_t)(low24 >> 16);\r
639         p_guid[6] = (uint8_t)(low24 >> 8);\r
640         p_guid[7] = (uint8_t)low24;\r
641         \r
642         return IB_SUCCESS;\r
643 }\r
644 /*\r
645 * PARAMETERS\r
646 *       port_guid\r
647 *               The port GUID, in network byte order, for which to generate a\r
648 *               MAC address.\r
649 *\r
650 *       p_mac_addr\r
651 *               Pointer to a mac address in which to store the results.\r
652 *\r
653 * RETURN VALUES\r
654 *       IB_SUCCESS\r
655 *               The MAC address was successfully converted.\r
656 *\r
657 *       IB_INVALID_GUID\r
658 *               The port GUID provided was not a known GUID format.\r
659 *\r
660 * NOTES\r
661 *       The algorithm to convert portGuid to MAC address is as per DN0074, and\r
662 *       assumes a 2 port HCA.\r
663 *\r
664 * SEE ALSO\r
665 *       IPOIB\r
666 *********/\r
667 \r
668 \r
669 /****f* IPOIB/ipoib_mlx_guid_from_mac\r
670 * NAME\r
671 *       ipoib_mlx_guid_from_mac\r
672 *\r
673 * DESCRIPTION\r
674 *       Generates a port GUID given an ethernet MAC address.\r
675 *\r
676 * SYNOPSIS\r
677 */\r
678 static inline ib_api_status_t\r
679 ipoib_mlx_guid_from_mac(\r
680         IN              const   mac_addr_t                                      mac,\r
681                 OUT                     net64_t* const                          p_port_guid )\r
682 {\r
683         uint8_t         *p_guid = (uint8_t*)p_port_guid;\r
684         uint32_t        low24;\r
685 \r
686         /* MAC address is in network byte order.  OUI is in lower 3 bytes. */\r
687         if( mac.addr[0] != 0x00 || \r
688                 mac.addr[1] != 0x02 || \r
689                 mac.addr[2] != 0xc9 )\r
690         {\r
691                 return IB_INVALID_GUID;\r
692         }\r
693 \r
694         low24 = mac.addr[3] << 16 || mac.addr[4] << 8 || mac.addr[5];\r
695 \r
696         /* OUI */\r
697         p_guid[0] = mac.addr[0];\r
698         p_guid[1] = mac.addr[1];\r
699         p_guid[2] = mac.addr[2];\r
700         p_guid[3] = 0x02;\r
701         p_guid[4] = 0x00;\r
702         /* Serial Number */\r
703         p_guid[5] = (uint8_t)(low24 >> 16);\r
704         p_guid[6] = (uint8_t)(low24 >> 8);\r
705         p_guid[7] = (uint8_t)low24;\r
706         \r
707         return IB_SUCCESS;\r
708 }\r
709 /*\r
710 * PARAMETERS\r
711 *       port_guid\r
712 *               The port GUID, in network byte order, for which to generate a\r
713 *               MAC address.\r
714 *\r
715 *       p_mac_addr\r
716 *               Pointer to a mac address in which to store the results.\r
717 *\r
718 * RETURN VALUES\r
719 *       IB_SUCCESS\r
720 *               The MAC address was successfully converted.\r
721 *\r
722 *       IB_INVALID_GUID\r
723 *               The port GUID provided was not a known GUID format.\r
724 *\r
725 * NOTES\r
726 *       The algorithm to convert portGuid to MAC address is as \r
727 *\r
728 * SEE ALSO\r
729 *       IPOIB\r
730 *********/\r
731 \r
732 \r
733 /****f* IPOIB/ipoib_is_voltaire_router_gid\r
734 * NAME\r
735 *       ipoib_is_voltaire_router_gid\r
736 *\r
737 * DESCRIPTION\r
738 *       Checks whether the GID belongs to Voltaire IP router\r
739 *\r
740 * SYNOPSIS\r
741 */\r
742 boolean_t\r
743 static inline\r
744 ipoib_is_voltaire_router_gid(\r
745         IN              const   ib_gid_t                                        *p_gid )\r
746 {\r
747         static const uint8_t VOLTAIRE_GUID_PREFIX[] = {0, 0x08, 0xf1, 0, 0x1};\r
748 \r
749         return !cl_memcmp( &p_gid->unicast.interface_id, VOLTAIRE_GUID_PREFIX,\r
750                 sizeof(VOLTAIRE_GUID_PREFIX) );\r
751 }\r
752 \r
753 \r
754 #ifdef __cplusplus\r
755 }\r
756 #endif\r
757 \r
758 #endif  /* _IPOIB_XFR_MGR_H_ */\r