|
@@ -296,6 +296,62 @@ static int ipoib_mc_hash ( unsigned int af __unused,
|
296
|
296
|
return -ENOTSUP;
|
297
|
297
|
}
|
298
|
298
|
|
|
299
|
+/**
|
|
300
|
+ * Generate Mellanox Ethernet-compatible compressed link-layer address
|
|
301
|
+ *
|
|
302
|
+ * @v ll_addr Link-layer address
|
|
303
|
+ * @v eth_addr Ethernet-compatible address to fill in
|
|
304
|
+ */
|
|
305
|
+static int ipoib_mlx_eth_addr ( const struct ib_gid_half *guid,
|
|
306
|
+ uint8_t *eth_addr ) {
|
|
307
|
+ eth_addr[0] = ( ( guid->u.bytes[3] == 2 ) ? 0x00 : 0x02 );
|
|
308
|
+ eth_addr[1] = guid->u.bytes[1];
|
|
309
|
+ eth_addr[2] = guid->u.bytes[2];
|
|
310
|
+ eth_addr[3] = guid->u.bytes[5];
|
|
311
|
+ eth_addr[4] = guid->u.bytes[6];
|
|
312
|
+ eth_addr[5] = guid->u.bytes[7];
|
|
313
|
+ return 0;
|
|
314
|
+}
|
|
315
|
+
|
|
316
|
+/** An IPoIB Ethernet-compatible compressed link-layer address generator */
|
|
317
|
+struct ipoib_eth_addr_handler {
|
|
318
|
+ /** GUID byte 1 */
|
|
319
|
+ uint8_t byte1;
|
|
320
|
+ /** GUID byte 2 */
|
|
321
|
+ uint8_t byte2;
|
|
322
|
+ /** Handler */
|
|
323
|
+ int ( * eth_addr ) ( const struct ib_gid_half *guid,
|
|
324
|
+ uint8_t *eth_addr );
|
|
325
|
+};
|
|
326
|
+
|
|
327
|
+/** IPoIB Ethernet-compatible compressed link-layer address generators */
|
|
328
|
+static struct ipoib_eth_addr_handler ipoib_eth_addr_handlers[] = {
|
|
329
|
+ { 0x02, 0xc9, ipoib_mlx_eth_addr },
|
|
330
|
+};
|
|
331
|
+
|
|
332
|
+/**
|
|
333
|
+ * Generate Ethernet-compatible compressed link-layer address
|
|
334
|
+ *
|
|
335
|
+ * @v ll_addr Link-layer address
|
|
336
|
+ * @v eth_addr Ethernet-compatible address to fill in
|
|
337
|
+ */
|
|
338
|
+static int ipoib_eth_addr ( const void *ll_addr, void *eth_addr ) {
|
|
339
|
+ const struct ipoib_mac *ipoib_addr = ll_addr;
|
|
340
|
+ const struct ib_gid_half *guid = &ipoib_addr->gid.u.half[1];
|
|
341
|
+ struct ipoib_eth_addr_handler *handler;
|
|
342
|
+ unsigned int i;
|
|
343
|
+
|
|
344
|
+ for ( i = 0 ; i < ( sizeof ( ipoib_eth_addr_handlers ) /
|
|
345
|
+ sizeof ( ipoib_eth_addr_handlers[0] ) ) ; i++ ) {
|
|
346
|
+ handler = &ipoib_eth_addr_handlers[i];
|
|
347
|
+ if ( ( handler->byte1 == guid->u.bytes[1] ) &&
|
|
348
|
+ ( handler->byte2 == guid->u.bytes[2] ) ) {
|
|
349
|
+ return handler->eth_addr ( guid, eth_addr );
|
|
350
|
+ }
|
|
351
|
+ }
|
|
352
|
+ return -ENOTSUP;
|
|
353
|
+}
|
|
354
|
+
|
299
|
355
|
/** IPoIB protocol */
|
300
|
356
|
struct ll_protocol ipoib_protocol __ll_protocol = {
|
301
|
357
|
.name = "IPoIB",
|
|
@@ -308,6 +364,7 @@ struct ll_protocol ipoib_protocol __ll_protocol = {
|
308
|
364
|
.init_addr = ipoib_init_addr,
|
309
|
365
|
.ntoa = ipoib_ntoa,
|
310
|
366
|
.mc_hash = ipoib_mc_hash,
|
|
367
|
+ .eth_addr = ipoib_eth_addr,
|
311
|
368
|
};
|
312
|
369
|
|
313
|
370
|
/**
|