Browse Source

Use pkey table access to determine broadcast GID directly.

tags/v0.9.3
Michael Brown 17 years ago
parent
commit
e05a8cd4de
2 changed files with 72 additions and 9 deletions
  1. 64
    9
      src/drivers/net/mlx_ipoib/mt25218.c
  2. 8
    0
      src/include/gpxe/infiniband.h

+ 64
- 9
src/drivers/net/mlx_ipoib/mt25218.c View File

1206
 	return 0;
1206
 	return 0;
1207
 }
1207
 }
1208
 
1208
 
1209
-static int arbel_get_port_gid ( struct arbel *arbel, struct ib_gid *gid ) {
1210
-	struct ib_mad_port_info port_info;
1211
-	struct ib_mad_guid_info guid_info;
1209
+static int arbel_get_pkey_table ( struct arbel *arbel,
1210
+				  struct ib_mad_pkey_table *pkey_table ) {
1211
+	union arbelprm_mad mad;
1212
+	struct ib_mad_hdr *hdr = &mad.mad.mad_hdr;
1213
+	int rc;
1214
+
1215
+	memset ( &mad, 0, sizeof ( mad ) );
1216
+	hdr->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
1217
+	hdr->class_version = 1;
1218
+	hdr->method = IB_MGMT_METHOD_GET;
1219
+	hdr->attr_id = htons ( IB_SMP_ATTR_PKEY_TABLE );
1220
+	if ( ( rc = arbel_mad_ifc ( arbel, &mad ) ) != 0 ) {
1221
+		DBGC ( arbel, "Arbel %p could not get pkey table: %s\n",
1222
+		       arbel, strerror ( rc ) );
1223
+		return rc;
1224
+	}
1225
+	memcpy ( pkey_table, &mad.mad.pkey_table, sizeof ( *pkey_table ) );
1226
+	return 0;
1227
+}
1228
+
1229
+static int arbel_get_port_gid ( struct arbel *arbel,
1230
+				struct ib_gid *port_gid ) {
1231
+	union {
1232
+		/* This union exists just to save stack space */
1233
+		struct ib_mad_port_info port_info;
1234
+		struct ib_mad_guid_info guid_info;
1235
+	} u;
1212
 	int rc;
1236
 	int rc;
1213
 
1237
 
1214
-	if ( ( rc = arbel_get_port_info ( arbel, &port_info ) ) != 0 )
1238
+	/* Port info gives us the first half of the port GID */
1239
+	if ( ( rc = arbel_get_port_info ( arbel, &u.port_info ) ) != 0 )
1215
 		return rc;
1240
 		return rc;
1216
-	if ( ( rc = arbel_get_guid_info ( arbel, &guid_info ) ) != 0 )
1241
+	memcpy ( &port_gid->bytes[0], u.port_info.gid_prefix, 8 );
1242
+
1243
+	/* GUID info gives us the second half of the port GID */
1244
+	if ( ( rc = arbel_get_guid_info ( arbel, &u.guid_info ) ) != 0 )
1217
 		return rc;
1245
 		return rc;
1218
-	memcpy ( &gid->bytes[0], port_info.gid_prefix, 8 );
1219
-	memcpy ( &gid->bytes[8], guid_info.gid_local, 8 );
1246
+	memcpy ( &port_gid->bytes[8], u.guid_info.gid_local, 8 );
1247
+
1220
 	return 0;
1248
 	return 0;
1221
 }
1249
 }
1222
 
1250
 
1251
+static int arbel_get_broadcast_gid ( struct arbel *arbel,
1252
+				     struct ib_gid *broadcast_gid ) {
1253
+	static const struct ib_gid ipv4_broadcast_gid = {
1254
+		{ 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
1255
+		  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff }
1256
+	};
1257
+	struct ib_mad_pkey_table pkey_table;
1258
+	int rc;
1259
+
1260
+	/* Start with the IPv4 broadcast GID */
1261
+	memcpy ( broadcast_gid, &ipv4_broadcast_gid,
1262
+		 sizeof ( *broadcast_gid ) );
1223
 
1263
 
1264
+	/* Add partition key */
1265
+	if ( ( rc = arbel_get_pkey_table ( arbel, &pkey_table ) ) != 0 )
1266
+		return rc;
1267
+	memcpy ( &broadcast_gid->bytes[4], &pkey_table.pkey[0][0],
1268
+		 sizeof ( pkey_table.pkey[0][0] ) );
1269
+
1270
+	return 0;
1271
+}
1224
 
1272
 
1225
 /**
1273
 /**
1226
  * Probe PCI device
1274
  * Probe PCI device
1282
 		goto err_get_port_gid;
1330
 		goto err_get_port_gid;
1283
 	}
1331
 	}
1284
 
1332
 
1333
+	/* Get broadcast GID */
1334
+	if ( ( rc = arbel_get_broadcast_gid ( arbel,
1335
+					      &ibdev->broadcast_gid ) ) != 0 ){
1336
+		DBGC ( arbel, "Arbel %p could not determine broadcast GID: "
1337
+		       "%s\n", arbel, strerror ( rc ) );
1338
+		goto err_get_broadcast_gid;
1339
+	}
1340
+
1285
 	struct ud_av_st *bcast_av = ib_data.bcast_av;
1341
 	struct ud_av_st *bcast_av = ib_data.bcast_av;
1286
 	struct arbelprm_ud_address_vector *bav =
1342
 	struct arbelprm_ud_address_vector *bav =
1287
 		( struct arbelprm_ud_address_vector * ) &bcast_av->av;
1343
 		( struct arbelprm_ud_address_vector * ) &bcast_av->av;
1294
 	av->gid_present = 1;
1350
 	av->gid_present = 1;
1295
 	memcpy ( &av->gid, ( ( void * ) bav ) + 16, 16 );
1351
 	memcpy ( &av->gid, ( ( void * ) bav ) + 16, 16 );
1296
 
1352
 
1297
-	memcpy ( &ibdev->broadcast_gid, &ib_data.bcast_gid, 16 );
1298
-
1299
 	/* Add IPoIB device */
1353
 	/* Add IPoIB device */
1300
 	if ( ( rc = ipoib_probe ( ibdev ) ) != 0 ) {
1354
 	if ( ( rc = ipoib_probe ( ibdev ) ) != 0 ) {
1301
 		DBGC ( arbel, "Arbel %p could not add IPoIB device: %s\n",
1355
 		DBGC ( arbel, "Arbel %p could not add IPoIB device: %s\n",
1306
 	return 0;
1360
 	return 0;
1307
 
1361
 
1308
  err_ipoib_probe:
1362
  err_ipoib_probe:
1363
+ err_get_broadcast_gid:
1309
  err_get_port_gid:
1364
  err_get_port_gid:
1310
  err_query_dev_lim:
1365
  err_query_dev_lim:
1311
 	ib_driver_close ( 0 );
1366
 	ib_driver_close ( 0 );

+ 8
- 0
src/include/gpxe/infiniband.h View File

468
 	uint8_t link_speed_enabled__link_speed_active;
468
 	uint8_t link_speed_enabled__link_speed_active;
469
 } __attribute__ (( packed ));
469
 } __attribute__ (( packed ));
470
 
470
 
471
+struct ib_mad_pkey_table {
472
+	struct ib_mad_hdr mad_hdr;
473
+	uint32_t mkey[2];
474
+	uint32_t reserved[8];
475
+	uint16_t pkey[16][2];
476
+} __attribute__ (( packed ));
477
+
471
 union ib_mad {
478
 union ib_mad {
472
 	struct ib_mad_hdr mad_hdr;
479
 	struct ib_mad_hdr mad_hdr;
473
 	struct ib_mad_data data;
480
 	struct ib_mad_data data;
474
 	struct ib_mad_guid_info guid_info;
481
 	struct ib_mad_guid_info guid_info;
475
 	struct ib_mad_port_info port_info;
482
 	struct ib_mad_port_info port_info;
483
+	struct ib_mad_pkey_table pkey_table;
476
 } __attribute__ (( packed ));
484
 } __attribute__ (( packed ));
477
 
485
 
478
 #endif /* _GPXE_INFINIBAND_H */
486
 #endif /* _GPXE_INFINIBAND_H */

Loading…
Cancel
Save