2 * Copyright (c) 2005 SilverStorm Technologies. All rights reserved.
\r
4 * This software is available to you under the OpenIB.org BSD license
\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
11 * - Redistributions of source code must retain the above
\r
12 * copyright notice, this list of conditions and the following
\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
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
33 #ifndef _IPOIB_XFR_MGR_H_
\r
34 #define _IPOIB_XFR_MGR_H_
\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
46 #include "ipoib_driver.h"
\r
47 #include "ip_stats.h"
\r
48 #include "ip_packet.h"
\r
51 #include <complib/cl_packon.h>
\r
52 /****s* IPoIB Driver/ipoib_hw_addr_t
\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
62 typedef struct _ipoib_hw_addr
\r
67 } PACK_SUFFIX ipoib_hw_addr_t;
\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
79 * IPoIB, ipoib_addr_get_flags, ipoib_addr_set_flags, ipoib_addr_set_qpn,
\r
80 * ipoib_addr_get_qpn
\r
82 #include <complib/cl_packoff.h>
\r
96 static inline uint8_t
\r
97 ipoib_addr_get_flags(
\r
98 IN const ipoib_hw_addr_t* const p_addr )
\r
100 return (uint8_t)(cl_ntoh32( p_addr->flags_qpn ) >> 24);
\r
104 ipoib_addr_set_flags(
\r
105 IN ipoib_hw_addr_t* const p_addr,
\r
106 IN const uint8_t flags )
\r
108 p_addr->flags_qpn &= cl_ntoh32( 0xFFFFFF00 );
\r
109 p_addr->flags_qpn |= cl_ntoh32( flags );
\r
112 static inline net32_t
\r
113 ipoib_addr_get_qpn(
\r
114 IN const ipoib_hw_addr_t* const p_addr )
\r
116 return cl_ntoh32( cl_ntoh32( p_addr->flags_qpn ) >> 8 );
\r
120 ipoib_addr_set_qpn(
\r
121 IN ipoib_hw_addr_t* const p_addr,
\r
122 IN const net32_t qpn )
\r
124 p_addr->flags_qpn = cl_ntoh32( (cl_ntoh32(
\r
125 p_addr->flags_qpn ) & 0x000000FF ) | (cl_ntoh32( qpn ) << 8) );
\r
129 /****f* IPOIB/ipoib_mac_from_sst_guid
\r
131 * ipoib_mac_from_sst_guid
\r
134 * Generates an ethernet MAC address given a SilverStorm port GUID.
\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
143 const uint8_t *p_guid = (const uint8_t*)&port_guid;
\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
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
153 if( port_guid & CL_HTON64( 0x0000000007800000 ) )
\r
154 return IB_INVALID_GUID;
\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
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
172 * The port GUID, in network byte order, for which to generate a
\r
176 * Pointer to a mac address in which to store the results.
\r
180 * The MAC address was successfully converted.
\r
183 * The port GUID provided was not a known GUID format.
\r
186 * The algorithm to convert portGuid to MAC address is as per DN0074, and
\r
187 * assumes a 2 port HCA.
\r
194 /****f* IPOIB/ipoib_mac_from_mlx_guid
\r
196 * ipoib_mac_from_sst_guid
\r
199 * Generates an ethernet MAC address given a Mellanox port GUID.
\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
208 const uint8_t *p_guid = (const uint8_t*)&port_guid;
\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
214 if( (port_guid & CL_HTON64( 0x000000ffff000000 )) !=
\r
215 CL_HTON64(0x0000000200000000))
\r
217 return IB_INVALID_GUID;
\r
220 low24 = ((uint32_t)cl_ntoh64( port_guid ) & 0x00FFFFFF);
\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
234 * The port GUID, in network byte order, for which to generate a
\r
238 * Pointer to a mac address in which to store the results.
\r
242 * The MAC address was successfully converted.
\r
245 * The port GUID provided was not a known GUID format.
\r
252 /****f* IPOIB/ipoib_mac_from_voltaire_guid
\r
254 * ipoib_mac_from_voltaire_guid
\r
257 * Generates an ethernet MAC address given a Voltaire port GUID.
\r
261 static inline ib_api_status_t
\r
262 ipoib_mac_from_voltaire_guid(
\r
263 IN const net64_t port_guid,
\r
264 OUT mac_addr_t* const p_mac_addr )
\r
266 const uint8_t *p_guid = (const uint8_t*)&port_guid;
\r
268 /* Port guid is in network byte order. OUI is in lower 3 bytes. */
\r
269 ASSERT( p_guid[0] == 0x00 && p_guid[1] == 0x08 && p_guid[2] == 0xf1 );
\r
271 p_mac_addr->addr[0] = p_guid[0];
\r
272 p_mac_addr->addr[1] = p_guid[1];
\r
273 p_mac_addr->addr[2] = p_guid[2];
\r
274 p_mac_addr->addr[3] = p_guid[4] ^ p_guid[6];
\r
275 p_mac_addr->addr[4] = p_guid[5] ^ p_guid[7];
\r
276 p_mac_addr->addr[5] = p_guid[5] + p_guid[6] + p_guid[7];
\r
283 * The port GUID, in network byte order, for which to generate a
\r
287 * Pointer to a mac address in which to store the results.
\r
291 * The MAC address was successfully converted.
\r
298 /****f* IPOIB/ipoib_mac_from_guid
\r
300 * ipoib_mac_from_guid
\r
303 * Generates an ethernet MAC address given a port GUID.
\r
307 static inline ib_api_status_t
\r
308 ipoib_mac_from_guid(
\r
309 IN const net64_t port_guid,
\r
310 OUT mac_addr_t* const p_mac_addr )
\r
312 ib_api_status_t status;
\r
313 const uint8_t *p_guid = (const uint8_t*)&port_guid;
\r
316 /* Port guid is in network byte order. OUI is in lower 3 bytes. */
\r
317 if( p_guid[0] == 0x00 && p_guid[1] == 0x06 && p_guid[2] == 0x6a )
\r
319 status = ipoib_mac_from_sst_guid( port_guid, p_mac_addr );
\r
320 if( status == IB_SUCCESS )
\r
323 else if( p_guid[0] == 0x00 && p_guid[1] == 0x02 && p_guid[2] == 0xc9 )
\r
325 status = ipoib_mac_from_mlx_guid( port_guid, p_mac_addr );
\r
326 if( status == IB_SUCCESS )
\r
329 else if( p_guid[0] == 0x00 && p_guid[1] == 0x08 && p_guid[2] == 0xf1 )
\r
331 status = ipoib_mac_from_voltaire_guid( port_guid, p_mac_addr );
\r
332 if( status == IB_SUCCESS )
\r
336 /* Value of zero is reserved. */
\r
337 laa = cl_atomic_inc( &g_ipoib.laa_idx );
\r
340 return IB_INVALID_GUID;
\r
342 p_mac_addr->addr[0] = 2; /* LAA bit */
\r
343 p_mac_addr->addr[1] = 0;
\r
344 p_mac_addr->addr[2] = (uint8_t)(laa >> 24);
\r
345 p_mac_addr->addr[3] = (uint8_t)(laa >> 16);
\r
346 p_mac_addr->addr[4] = (uint8_t)(laa >> 8);
\r
347 p_mac_addr->addr[5] = (uint8_t)laa;
\r
354 * The port GUID, in network byte order, for which to generate a
\r
358 * Pointer to a mac address in which to store the results.
\r
362 * The MAC address was successfully converted.
\r
365 * The port GUID provided was not a known GUID format.
\r
368 * Creates a locally administered address using a global incrementing counter.
\r
375 /****f* IPOIB/ipoib_sst_guid_from_mac
\r
377 * ipoib_sst_guid_from_mac
\r
380 * Generates a port GUID given an ethernet MAC address.
\r
384 static inline ib_api_status_t
\r
385 ipoib_sst_guid_from_mac(
\r
386 IN const mac_addr_t mac,
\r
387 OUT net64_t* const p_port_guid )
\r
389 uint8_t *p_guid = (uint8_t*)p_port_guid;
\r
392 /* MAC address is in network byte order. OUI is in lower 3 bytes. */
\r
393 if( mac.addr[0] != 0x00 ||
\r
394 mac.addr[1] != 0x06 ||
\r
395 mac.addr[2] != 0x6a )
\r
397 return IB_INVALID_GUID;
\r
400 low24 = mac.addr[3] << 16 || mac.addr[4] << 8 || mac.addr[5];
\r
402 low24 = 0x00FFF000 - low24;
\r
403 /* Divide by two */
\r
405 /* Add the serial number base offset. */
\r
409 p_guid[0] = mac.addr[0];
\r
410 p_guid[1] = mac.addr[1];
\r
411 p_guid[2] = mac.addr[2];
\r
413 p_guid[3] = mac.addr[5] & 0x01;
\r
416 /* Serial Number */
\r
417 p_guid[5] = (uint8_t)(low24 >> 16);
\r
418 p_guid[6] = (uint8_t)(low24 >> 8);
\r
419 p_guid[7] = (uint8_t)low24;
\r
426 * The port GUID, in network byte order, for which to generate a
\r
430 * Pointer to a mac address in which to store the results.
\r
434 * The MAC address was successfully converted.
\r
437 * The port GUID provided was not a known GUID format.
\r
440 * The algorithm to convert portGuid to MAC address is as per DN0074, and
\r
441 * assumes a 2 port HCA.
\r
448 /****f* IPOIB/ipoib_mlx_guid_from_mac
\r
450 * ipoib_mlx_guid_from_mac
\r
453 * Generates a port GUID given an ethernet MAC address.
\r
457 static inline ib_api_status_t
\r
458 ipoib_mlx_guid_from_mac(
\r
459 IN const mac_addr_t mac,
\r
460 OUT net64_t* const p_port_guid )
\r
462 uint8_t *p_guid = (uint8_t*)p_port_guid;
\r
465 /* MAC address is in network byte order. OUI is in lower 3 bytes. */
\r
466 if( mac.addr[0] != 0x00 ||
\r
467 mac.addr[1] != 0x02 ||
\r
468 mac.addr[2] != 0xc9 )
\r
470 return IB_INVALID_GUID;
\r
473 low24 = mac.addr[3] << 16 || mac.addr[4] << 8 || mac.addr[5];
\r
476 p_guid[0] = mac.addr[0];
\r
477 p_guid[1] = mac.addr[1];
\r
478 p_guid[2] = mac.addr[2];
\r
481 /* Serial Number */
\r
482 p_guid[5] = (uint8_t)(low24 >> 16);
\r
483 p_guid[6] = (uint8_t)(low24 >> 8);
\r
484 p_guid[7] = (uint8_t)low24;
\r
491 * The port GUID, in network byte order, for which to generate a
\r
495 * Pointer to a mac address in which to store the results.
\r
499 * The MAC address was successfully converted.
\r
502 * The port GUID provided was not a known GUID format.
\r
505 * The algorithm to convert portGuid to MAC address is as
\r
516 #endif /* _IPOIB_XFR_MGR_H_ */
\r