Browse Source

[Infiniband] Centralise MAD operations

Pull out common code for handling management datagrams from arbel.c
and hermon.c into infiniband.c.

Add port number to struct ib_device.

Add open(), close() and mad() methods to struct ib_device_operations.
tags/v0.9.4
Michael Brown 16 years ago
parent
commit
6570203571
4 changed files with 499 additions and 550 deletions
  1. 102
    270
      src/drivers/infiniband/arbel.c
  2. 105
    273
      src/drivers/infiniband/hermon.c
  3. 70
    7
      src/include/gpxe/infiniband.h
  4. 222
    0
      src/net/infiniband.c

+ 102
- 270
src/drivers/infiniband/arbel.c View File

34
 #include <gpxe/iobuf.h>
34
 #include <gpxe/iobuf.h>
35
 #include <gpxe/netdevice.h>
35
 #include <gpxe/netdevice.h>
36
 #include <gpxe/infiniband.h>
36
 #include <gpxe/infiniband.h>
37
-#include <gpxe/ipoib.h>
38
 #include "arbel.h"
37
 #include "arbel.h"
39
 
38
 
40
 /**
39
 /**
349
 }
348
 }
350
 
349
 
351
 static inline int
350
 static inline int
352
-arbel_cmd_mad_ifc ( struct arbel *arbel, union arbelprm_mad *mad ) {
351
+arbel_cmd_mad_ifc ( struct arbel *arbel, unsigned int port,
352
+		    union arbelprm_mad *mad ) {
353
 	return arbel_cmd ( arbel,
353
 	return arbel_cmd ( arbel,
354
 			   ARBEL_HCR_INOUT_CMD ( ARBEL_HCR_MAD_IFC,
354
 			   ARBEL_HCR_INOUT_CMD ( ARBEL_HCR_MAD_IFC,
355
 						 1, sizeof ( *mad ),
355
 						 1, sizeof ( *mad ),
356
 						 1, sizeof ( *mad ) ),
356
 						 1, sizeof ( *mad ) ),
357
-			   0x03, mad, PXE_IB_PORT, mad );
357
+			   0x03, mad, port, mad );
358
 }
358
 }
359
 
359
 
360
 static inline int
360
 static inline int
776
 	MLX_FILL_1 ( &qpctx, 5,
776
 	MLX_FILL_1 ( &qpctx, 5,
777
 		     qpc_eec_data.usr_page, arbel->limits.reserved_uars );
777
 		     qpc_eec_data.usr_page, arbel->limits.reserved_uars );
778
 	MLX_FILL_1 ( &qpctx, 10, qpc_eec_data.primary_address_path.port_number,
778
 	MLX_FILL_1 ( &qpctx, 10, qpc_eec_data.primary_address_path.port_number,
779
-		     PXE_IB_PORT );
779
+		     ibdev->port );
780
 	MLX_FILL_1 ( &qpctx, 27, qpc_eec_data.pd, ARBEL_GLOBAL_PD );
780
 	MLX_FILL_1 ( &qpctx, 27, qpc_eec_data.pd, ARBEL_GLOBAL_PD );
781
 	MLX_FILL_1 ( &qpctx, 29, qpc_eec_data.wqe_lkey, arbel->reserved_lkey );
781
 	MLX_FILL_1 ( &qpctx, 29, qpc_eec_data.wqe_lkey, arbel->reserved_lkey );
782
 	MLX_FILL_1 ( &qpctx, 30, qpc_eec_data.ssc, 1 );
782
 	MLX_FILL_1 ( &qpctx, 30, qpc_eec_data.ssc, 1 );
955
 	memset ( &wqe->ud, 0, sizeof ( wqe->ud ) );
955
 	memset ( &wqe->ud, 0, sizeof ( wqe->ud ) );
956
 	MLX_FILL_2 ( &wqe->ud, 0,
956
 	MLX_FILL_2 ( &wqe->ud, 0,
957
 		     ud_address_vector.pd, ARBEL_GLOBAL_PD,
957
 		     ud_address_vector.pd, ARBEL_GLOBAL_PD,
958
-		     ud_address_vector.port_number, PXE_IB_PORT );
958
+		     ud_address_vector.port_number, ibdev->port );
959
 	MLX_FILL_2 ( &wqe->ud, 1,
959
 	MLX_FILL_2 ( &wqe->ud, 1,
960
 		     ud_address_vector.rlid, av->dlid,
960
 		     ud_address_vector.rlid, av->dlid,
961
 		     ud_address_vector.g, av->gid_present );
961
 		     ud_address_vector.g, av->gid_present );
1206
 	}
1206
 	}
1207
 }
1207
 }
1208
 
1208
 
1209
+/***************************************************************************
1210
+ *
1211
+ * Infiniband link-layer operations
1212
+ *
1213
+ ***************************************************************************
1214
+ */
1215
+
1216
+/**
1217
+ * Initialise Infiniband link
1218
+ *
1219
+ * @v ibdev		Infiniband device
1220
+ * @ret rc		Return status code
1221
+ */
1222
+static int arbel_open ( struct ib_device *ibdev ) {
1223
+	struct arbel *arbel = ibdev->dev_priv;
1224
+	struct arbelprm_init_ib init_ib;
1225
+	int rc;
1226
+
1227
+	memset ( &init_ib, 0, sizeof ( init_ib ) );
1228
+	MLX_FILL_3 ( &init_ib, 0,
1229
+		     mtu_cap, ARBEL_MTU_2048,
1230
+		     port_width_cap, 3,
1231
+		     vl_cap, 1 );
1232
+	MLX_FILL_1 ( &init_ib, 1, max_gid, 1 );
1233
+	MLX_FILL_1 ( &init_ib, 2, max_pkey, 64 );
1234
+	if ( ( rc = arbel_cmd_init_ib ( arbel, ibdev->port,
1235
+					&init_ib ) ) != 0 ) {
1236
+		DBGC ( arbel, "Arbel %p could not intialise IB: %s\n",
1237
+		       arbel, strerror ( rc ) );
1238
+		return rc;
1239
+	}
1240
+
1241
+	return 0;
1242
+}
1243
+
1244
+/**
1245
+ * Close Infiniband link
1246
+ *
1247
+ * @v ibdev		Infiniband device
1248
+ */
1249
+static void arbel_close ( struct ib_device *ibdev ) {
1250
+	struct arbel *arbel = ibdev->dev_priv;
1251
+	int rc;
1252
+
1253
+	if ( ( rc = arbel_cmd_close_ib ( arbel, ibdev->port ) ) != 0 ) {
1254
+		DBGC ( arbel, "Arbel %p could not close IB: %s\n",
1255
+		       arbel, strerror ( rc ) );
1256
+		/* Nothing we can do about this */
1257
+	}
1258
+}
1259
+
1209
 /***************************************************************************
1260
 /***************************************************************************
1210
  *
1261
  *
1211
  * Multicast group operations
1262
  * Multicast group operations
1302
 	}
1353
 	}
1303
 }
1354
 }
1304
 
1355
 
1305
-/** Arbel Infiniband operations */
1306
-static struct ib_device_operations arbel_ib_operations = {
1307
-	.create_cq	= arbel_create_cq,
1308
-	.destroy_cq	= arbel_destroy_cq,
1309
-	.create_qp	= arbel_create_qp,
1310
-	.destroy_qp	= arbel_destroy_qp,
1311
-	.post_send	= arbel_post_send,
1312
-	.post_recv	= arbel_post_recv,
1313
-	.poll_cq	= arbel_poll_cq,
1314
-	.mcast_attach	= arbel_mcast_attach,
1315
-	.mcast_detach	= arbel_mcast_detach,
1316
-};
1317
-
1318
 /***************************************************************************
1356
 /***************************************************************************
1319
  *
1357
  *
1320
- * MAD IFC operations
1358
+ * MAD operations
1321
  *
1359
  *
1322
  ***************************************************************************
1360
  ***************************************************************************
1323
  */
1361
  */
1324
 
1362
 
1325
-static int arbel_mad_ifc ( struct arbel *arbel,
1326
-			   union arbelprm_mad *mad ) {
1327
-	struct ib_mad_hdr *hdr = &mad->mad.mad_hdr;
1328
-	int rc;
1329
-
1330
-	hdr->base_version = IB_MGMT_BASE_VERSION;
1331
-	if ( ( rc = arbel_cmd_mad_ifc ( arbel, mad ) ) != 0 ) {
1332
-		DBGC ( arbel, "Arbel %p could not issue MAD IFC: %s\n",
1333
-		       arbel, strerror ( rc ) );
1334
-		return rc;
1335
-	}
1336
-	if ( hdr->status != 0 ) {
1337
-		DBGC ( arbel, "Arbel %p MAD IFC status %04x\n",
1338
-		       arbel, ntohs ( hdr->status ) );
1339
-		return -EIO;
1340
-	}
1341
-	return 0;
1342
-}
1343
-
1344
-static int arbel_get_port_info ( struct arbel *arbel,
1345
-				 struct ib_mad_port_info *port_info ) {
1346
-	union arbelprm_mad mad;
1347
-	struct ib_mad_hdr *hdr = &mad.mad.mad_hdr;
1348
-	int rc;
1349
-
1350
-	memset ( &mad, 0, sizeof ( mad ) );
1351
-	hdr->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
1352
-	hdr->class_version = 1;
1353
-	hdr->method = IB_MGMT_METHOD_GET;
1354
-	hdr->attr_id = htons ( IB_SMP_ATTR_PORT_INFO );
1355
-	hdr->attr_mod = htonl ( PXE_IB_PORT );
1356
-	if ( ( rc = arbel_mad_ifc ( arbel, &mad ) ) != 0 ) {
1357
-		DBGC ( arbel, "Arbel %p could not get port info: %s\n",
1358
-		       arbel, strerror ( rc ) );
1359
-		return rc;
1360
-	}
1361
-	memcpy ( port_info, &mad.mad.port_info, sizeof ( *port_info ) );
1362
-	return 0;
1363
-}
1364
-
1365
-static int arbel_get_guid_info ( struct arbel *arbel,
1366
-				 struct ib_mad_guid_info *guid_info ) {
1367
-	union arbelprm_mad mad;
1368
-	struct ib_mad_hdr *hdr = &mad.mad.mad_hdr;
1369
-	int rc;
1370
-
1371
-	memset ( &mad, 0, sizeof ( mad ) );
1372
-	hdr->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
1373
-	hdr->class_version = 1;
1374
-	hdr->method = IB_MGMT_METHOD_GET;
1375
-	hdr->attr_id = htons ( IB_SMP_ATTR_GUID_INFO );
1376
-	if ( ( rc = arbel_mad_ifc ( arbel, &mad ) ) != 0 ) {
1377
-		DBGC ( arbel, "Arbel %p could not get GUID info: %s\n",
1378
-		       arbel, strerror ( rc ) );
1379
-		return rc;
1380
-	}
1381
-	memcpy ( guid_info, &mad.mad.guid_info, sizeof ( *guid_info ) );
1382
-	return 0;
1383
-}
1384
-
1385
-static int arbel_get_pkey_table ( struct arbel *arbel,
1386
-				  struct ib_mad_pkey_table *pkey_table ) {
1387
-	union arbelprm_mad mad;
1388
-	struct ib_mad_hdr *hdr = &mad.mad.mad_hdr;
1389
-	int rc;
1390
-
1391
-	memset ( &mad, 0, sizeof ( mad ) );
1392
-	hdr->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
1393
-	hdr->class_version = 1;
1394
-	hdr->method = IB_MGMT_METHOD_GET;
1395
-	hdr->attr_id = htons ( IB_SMP_ATTR_PKEY_TABLE );
1396
-	if ( ( rc = arbel_mad_ifc ( arbel, &mad ) ) != 0 ) {
1397
-		DBGC ( arbel, "Arbel %p could not get pkey table: %s\n",
1398
-		       arbel, strerror ( rc ) );
1399
-		return rc;
1400
-	}
1401
-	memcpy ( pkey_table, &mad.mad.pkey_table, sizeof ( *pkey_table ) );
1402
-	return 0;
1403
-}
1404
-
1405
-static int arbel_get_port_gid ( struct arbel *arbel,
1406
-				struct ib_gid *port_gid ) {
1407
-	union {
1408
-		/* This union exists just to save stack space */
1409
-		struct ib_mad_port_info port_info;
1410
-		struct ib_mad_guid_info guid_info;
1411
-	} u;
1412
-	int rc;
1413
-
1414
-	/* Port info gives us the first half of the port GID */
1415
-	if ( ( rc = arbel_get_port_info ( arbel, &u.port_info ) ) != 0 )
1416
-		return rc;
1417
-	memcpy ( &port_gid->u.bytes[0], u.port_info.gid_prefix, 8 );
1418
-	
1419
-	/* GUID info gives us the second half of the port GID */
1420
-	if ( ( rc = arbel_get_guid_info ( arbel, &u.guid_info ) ) != 0 )
1421
-		return rc;
1422
-	memcpy ( &port_gid->u.bytes[8], u.guid_info.gid_local, 8 );
1423
-
1424
-	return 0;
1425
-}
1426
-
1427
-static int arbel_get_sm_lid ( struct arbel *arbel,
1428
-			      unsigned long *sm_lid ) {
1429
-	struct ib_mad_port_info port_info;
1430
-	int rc;
1431
-
1432
-	if ( ( rc = arbel_get_port_info ( arbel, &port_info ) ) != 0 )
1433
-		return rc;
1434
-	*sm_lid = ntohs ( port_info.mastersm_lid );
1435
-	return 0;
1436
-}
1437
-
1438
-static int arbel_get_pkey ( struct arbel *arbel, unsigned int *pkey ) {
1439
-	struct ib_mad_pkey_table pkey_table;
1440
-	int rc;
1441
-
1442
-	if ( ( rc = arbel_get_pkey_table ( arbel, &pkey_table ) ) != 0 )
1443
-		return rc;
1444
-	*pkey = ntohs ( pkey_table.pkey[0][0] );
1445
-	return 0;
1446
-}
1447
-
1448
-/**
1449
- * Wait for link up
1450
- *
1451
- * @v arbel		Arbel device
1452
- * @ret rc		Return status code
1453
- *
1454
- * This function shouldn't really exist.  Unfortunately, IB links take
1455
- * a long time to come up, and we can't get various key parameters
1456
- * e.g. our own IPoIB MAC address without information from the subnet
1457
- * manager).  We should eventually make link-up an asynchronous event.
1458
- */
1459
-static int arbel_wait_for_link ( struct arbel *arbel ) {
1460
-	struct ib_mad_port_info port_info;
1461
-	unsigned int retries;
1462
-	int rc;
1463
-
1464
-	printf ( "Waiting for Infiniband link-up..." );
1465
-	for ( retries = 20 ; retries ; retries-- ) {
1466
-		if ( ( rc = arbel_get_port_info ( arbel, &port_info ) ) != 0 )
1467
-			continue;
1468
-		if ( ( ( port_info.port_state__link_speed_supported ) & 0xf )
1469
-		     == 4 ) {
1470
-			printf ( "ok\n" );
1471
-			return 0;
1472
-		}
1473
-		printf ( "." );
1474
-		sleep ( 1 );
1475
-	}
1476
-	printf ( "failed\n" );
1477
-	return -ENODEV;
1478
-};
1479
-
1480
 /**
1363
 /**
1481
- * Get MAD parameters
1364
+ * Issue management datagram
1482
  *
1365
  *
1483
- * @v arbel		Arbel device
1366
+ * @v ibdev		Infiniband device
1367
+ * @v mad		Management datagram
1368
+ * @v len		Length of management datagram
1484
  * @ret rc		Return status code
1369
  * @ret rc		Return status code
1485
  */
1370
  */
1486
-static int arbel_get_mad_params ( struct ib_device *ibdev ) {
1371
+static int arbel_mad ( struct ib_device *ibdev, struct ib_mad_hdr *mad,
1372
+		       size_t len ) {
1487
 	struct arbel *arbel = ibdev->dev_priv;
1373
 	struct arbel *arbel = ibdev->dev_priv;
1374
+	union arbelprm_mad mad_ifc;
1488
 	int rc;
1375
 	int rc;
1489
 
1376
 
1490
-	/* Get subnet manager LID */
1491
-	if ( ( rc = arbel_get_sm_lid ( arbel, &ibdev->sm_lid ) ) != 0 ) {
1492
-		DBGC ( arbel, "Arbel %p could not determine subnet manager "
1493
-		       "LID: %s\n", arbel, strerror ( rc ) );
1494
-		return rc;
1495
-	}
1377
+	/* Copy in request packet */
1378
+	memset ( &mad_ifc, 0, sizeof ( mad_ifc ) );
1379
+	assert ( len <= sizeof ( mad_ifc.mad ) );
1380
+	memcpy ( &mad_ifc.mad, mad, len );
1496
 
1381
 
1497
-	/* Get port GID */
1498
-	if ( ( rc = arbel_get_port_gid ( arbel, &ibdev->port_gid ) ) != 0 ) {
1499
-		DBGC ( arbel, "Arbel %p could not determine port GID: %s\n",
1382
+	/* Issue MAD */
1383
+	if ( ( rc = arbel_cmd_mad_ifc ( arbel, ibdev->port,
1384
+					&mad_ifc ) ) != 0 ) {
1385
+		DBGC ( arbel, "Arbel %p could not issue MAD IFC: %s\n",
1500
 		       arbel, strerror ( rc ) );
1386
 		       arbel, strerror ( rc ) );
1501
 		return rc;
1387
 		return rc;
1502
 	}
1388
 	}
1503
 
1389
 
1504
-	/* Get partition key */
1505
-	if ( ( rc = arbel_get_pkey ( arbel, &ibdev->pkey ) ) != 0 ) {
1506
-		DBGC ( arbel, "Arbel %p could not determine partition key: "
1507
-		       "%s\n", arbel, strerror ( rc ) );
1508
-		return rc;
1509
-	}
1390
+	/* Copy out reply packet */
1391
+	memcpy ( mad, &mad_ifc.mad, len );
1510
 
1392
 
1393
+	if ( mad->status != 0 ) {
1394
+		DBGC ( arbel, "Arbel %p MAD IFC status %04x\n",
1395
+		       arbel, ntohs ( mad->status ) );
1396
+		return -EIO;
1397
+	}
1511
 	return 0;
1398
 	return 0;
1512
 }
1399
 }
1513
 
1400
 
1401
+/** Arbel Infiniband operations */
1402
+static struct ib_device_operations arbel_ib_operations = {
1403
+	.create_cq	= arbel_create_cq,
1404
+	.destroy_cq	= arbel_destroy_cq,
1405
+	.create_qp	= arbel_create_qp,
1406
+	.destroy_qp	= arbel_destroy_qp,
1407
+	.post_send	= arbel_post_send,
1408
+	.post_recv	= arbel_post_recv,
1409
+	.poll_cq	= arbel_poll_cq,
1410
+	.open		= arbel_open,
1411
+	.close		= arbel_close,
1412
+	.mcast_attach	= arbel_mcast_attach,
1413
+	.mcast_detach	= arbel_mcast_detach,
1414
+	.mad		= arbel_mad,
1415
+};
1416
+
1514
 /***************************************************************************
1417
 /***************************************************************************
1515
  *
1418
  *
1516
  * Firmware control
1419
  * Firmware control
1882
 	arbel->icm = UNULL;
1785
 	arbel->icm = UNULL;
1883
 }
1786
 }
1884
 
1787
 
1885
-/***************************************************************************
1886
- *
1887
- * Infiniband link-layer operations
1888
- *
1889
- ***************************************************************************
1890
- */
1891
-
1892
-/**
1893
- * Initialise Infiniband link
1894
- *
1895
- * @v arbel		Arbel device
1896
- * @ret rc		Return status code
1897
- */
1898
-static int arbel_init_ib ( struct arbel *arbel ) {
1899
-	struct arbelprm_init_ib init_ib;
1900
-	int rc;
1901
-
1902
-	memset ( &init_ib, 0, sizeof ( init_ib ) );
1903
-	MLX_FILL_3 ( &init_ib, 0,
1904
-		     mtu_cap, ARBEL_MTU_2048,
1905
-		     port_width_cap, 3,
1906
-		     vl_cap, 1 );
1907
-	MLX_FILL_1 ( &init_ib, 1, max_gid, 1 );
1908
-	MLX_FILL_1 ( &init_ib, 2, max_pkey, 64 );
1909
-	if ( ( rc = arbel_cmd_init_ib ( arbel, PXE_IB_PORT,
1910
-					&init_ib ) ) != 0 ) {
1911
-		DBGC ( arbel, "Arbel %p could not intialise IB: %s\n",
1912
-		       arbel, strerror ( rc ) );
1913
-		return rc;
1914
-	}
1915
-
1916
-	return 0;
1917
-}
1918
-
1919
-/**
1920
- * Close Infiniband link
1921
- *
1922
- * @v arbel		Arbel device
1923
- */
1924
-static void arbel_close_ib ( struct arbel *arbel ) {
1925
-	int rc;
1926
-
1927
-	if ( ( rc = arbel_cmd_close_ib ( arbel, PXE_IB_PORT ) ) != 0 ) {
1928
-		DBGC ( arbel, "Arbel %p could not close IB: %s\n",
1929
-		       arbel, strerror ( rc ) );
1930
-		/* Nothing we can do about this */
1931
-	}
1932
-}
1933
-
1934
 /***************************************************************************
1788
 /***************************************************************************
1935
  *
1789
  *
1936
  * PCI interface
1790
  * PCI interface
1997
 	ibdev->op = &arbel_ib_operations;
1851
 	ibdev->op = &arbel_ib_operations;
1998
 	pci_set_drvdata ( pci, ibdev );
1852
 	pci_set_drvdata ( pci, ibdev );
1999
 	ibdev->dev = &pci->dev;
1853
 	ibdev->dev = &pci->dev;
1854
+	ibdev->port = PXE_IB_PORT;
2000
 	arbel = ibdev->dev_priv;
1855
 	arbel = ibdev->dev_priv;
2001
 	memset ( arbel, 0, sizeof ( *arbel ) );
1856
 	memset ( arbel, 0, sizeof ( *arbel ) );
2002
 
1857
 
2047
 	if ( ( rc = arbel_setup_mpt ( arbel ) ) != 0 )
1902
 	if ( ( rc = arbel_setup_mpt ( arbel ) ) != 0 )
2048
 		goto err_setup_mpt;
1903
 		goto err_setup_mpt;
2049
 
1904
 
2050
-	/* Bring up IB layer */
2051
-	if ( ( rc = arbel_init_ib ( arbel ) ) != 0 )
2052
-		goto err_init_ib;
2053
-
2054
-	/* Wait for link */
2055
-	if ( ( rc = arbel_wait_for_link ( arbel ) ) != 0 )
2056
-		goto err_wait_for_link;
2057
-
2058
-	/* Get MAD parameters */
2059
-	if ( ( rc = arbel_get_mad_params ( ibdev ) ) != 0 )
2060
-		goto err_get_mad_params;
2061
-
2062
-	DBGC ( arbel, "Arbel %p port GID is %08lx:%08lx:%08lx:%08lx\n", arbel,
2063
-	       htonl ( ibdev->port_gid.u.dwords[0] ),
2064
-	       htonl ( ibdev->port_gid.u.dwords[1] ),
2065
-	       htonl ( ibdev->port_gid.u.dwords[2] ),
2066
-	       htonl ( ibdev->port_gid.u.dwords[3] ) );
2067
-
2068
-	/* Add IPoIB device */
2069
-	if ( ( rc = ipoib_probe ( ibdev ) ) != 0 ) {
2070
-		DBGC ( arbel, "Arbel %p could not add IPoIB device: %s\n",
1905
+	/* Register Infiniband device */
1906
+	if ( ( rc = register_ibdev ( ibdev ) ) != 0 ) {
1907
+		DBGC ( arbel, "Arbel %p could not register IB device: %s\n",
2071
 		       arbel, strerror ( rc ) );
1908
 		       arbel, strerror ( rc ) );
2072
-		goto err_ipoib_probe;
1909
+		goto err_register_ibdev;
2073
 	}
1910
 	}
2074
 
1911
 
2075
 	return 0;
1912
 	return 0;
2076
 
1913
 
2077
- err_ipoib_probe:
2078
- err_get_mad_params:
2079
- err_wait_for_link:
2080
-	arbel_close_ib ( arbel );
2081
- err_init_ib:
1914
+ err_register_ibdev:
2082
  err_setup_mpt:
1915
  err_setup_mpt:
2083
 	arbel_cmd_close_hca ( arbel );
1916
 	arbel_cmd_close_hca ( arbel );
2084
  err_init_hca:
1917
  err_init_hca:
2105
 	struct ib_device *ibdev = pci_get_drvdata ( pci );
1938
 	struct ib_device *ibdev = pci_get_drvdata ( pci );
2106
 	struct arbel *arbel = ibdev->dev_priv;
1939
 	struct arbel *arbel = ibdev->dev_priv;
2107
 
1940
 
2108
-	ipoib_remove ( ibdev );
2109
-	arbel_close_ib ( arbel );
1941
+	unregister_ibdev ( ibdev );
2110
 	arbel_cmd_close_hca ( arbel );
1942
 	arbel_cmd_close_hca ( arbel );
2111
 	arbel_free_icm ( arbel );
1943
 	arbel_free_icm ( arbel );
2112
 	arbel_stop_firmware ( arbel );
1944
 	arbel_stop_firmware ( arbel );

+ 105
- 273
src/drivers/infiniband/hermon.c View File

32
 #include <gpxe/iobuf.h>
32
 #include <gpxe/iobuf.h>
33
 #include <gpxe/netdevice.h>
33
 #include <gpxe/netdevice.h>
34
 #include <gpxe/infiniband.h>
34
 #include <gpxe/infiniband.h>
35
-#include <gpxe/ipoib.h>
36
 #include "hermon.h"
35
 #include "hermon.h"
37
 
36
 
38
 /**
37
 /**
390
 }
389
 }
391
 
390
 
392
 static inline int
391
 static inline int
393
-hermon_cmd_mad_ifc ( struct hermon *hermon, union hermonprm_mad *mad ) {
392
+hermon_cmd_mad_ifc ( struct hermon *hermon, unsigned int port,
393
+		     union hermonprm_mad *mad ) {
394
 	return hermon_cmd ( hermon,
394
 	return hermon_cmd ( hermon,
395
 			    HERMON_HCR_INOUT_CMD ( HERMON_HCR_MAD_IFC,
395
 			    HERMON_HCR_INOUT_CMD ( HERMON_HCR_MAD_IFC,
396
 						   1, sizeof ( *mad ),
396
 						   1, sizeof ( *mad ),
397
 						   1, sizeof ( *mad ) ),
397
 						   1, sizeof ( *mad ) ),
398
-			    0x03, mad, PXE_IB_PORT, mad );
398
+			    0x03, mad, port, mad );
399
 }
399
 }
400
 
400
 
401
 static inline int
401
 static inline int
785
 		goto err_alloc_mtt;
785
 		goto err_alloc_mtt;
786
 	}
786
 	}
787
 
787
 
788
-	/* Hand queue over to hardware */
788
+	/* Transition queue to INIT state */
789
 	memset ( &qpctx, 0, sizeof ( qpctx ) );
789
 	memset ( &qpctx, 0, sizeof ( qpctx ) );
790
 	MLX_FILL_2 ( &qpctx, 2,
790
 	MLX_FILL_2 ( &qpctx, 2,
791
 		     qpc_eec_data.pm_state, 0x03 /* Always 0x03 for UD */,
791
 		     qpc_eec_data.pm_state, 0x03 /* Always 0x03 for UD */,
817
 		goto err_rst2init_qp;
817
 		goto err_rst2init_qp;
818
 	}
818
 	}
819
 
819
 
820
+	/* Transition queue to RTR state */
820
 	memset ( &qpctx, 0, sizeof ( qpctx ) );
821
 	memset ( &qpctx, 0, sizeof ( qpctx ) );
821
 	MLX_FILL_2 ( &qpctx, 4,
822
 	MLX_FILL_2 ( &qpctx, 4,
822
 		     qpc_eec_data.mtu, HERMON_MTU_2048,
823
 		     qpc_eec_data.mtu, HERMON_MTU_2048,
824
 	MLX_FILL_1 ( &qpctx, 16,
825
 	MLX_FILL_1 ( &qpctx, 16,
825
 		     qpc_eec_data.primary_address_path.sched_queue,
826
 		     qpc_eec_data.primary_address_path.sched_queue,
826
 		     ( 0x83 /* default policy */ |
827
 		     ( 0x83 /* default policy */ |
827
-		       ( ( PXE_IB_PORT - 1 ) << 6 ) ) );
828
+		       ( ( ibdev->port - 1 ) << 6 ) ) );
828
 	if ( ( rc = hermon_cmd_init2rtr_qp ( hermon, qp->qpn,
829
 	if ( ( rc = hermon_cmd_init2rtr_qp ( hermon, qp->qpn,
829
 					     &qpctx ) ) != 0 ) {
830
 					     &qpctx ) ) != 0 ) {
830
 		DBGC ( hermon, "Hermon %p INIT2RTR_QP failed: %s\n",
831
 		DBGC ( hermon, "Hermon %p INIT2RTR_QP failed: %s\n",
949
 	MLX_FILL_1 ( &wqe->ctrl, 2, c, 0x03 /* generate completion */ );
950
 	MLX_FILL_1 ( &wqe->ctrl, 2, c, 0x03 /* generate completion */ );
950
 	MLX_FILL_2 ( &wqe->ud, 0,
951
 	MLX_FILL_2 ( &wqe->ud, 0,
951
 		     ud_address_vector.pd, HERMON_GLOBAL_PD,
952
 		     ud_address_vector.pd, HERMON_GLOBAL_PD,
952
-		     ud_address_vector.port_number, PXE_IB_PORT );
953
+		     ud_address_vector.port_number, ibdev->port );
953
 	MLX_FILL_2 ( &wqe->ud, 1,
954
 	MLX_FILL_2 ( &wqe->ud, 1,
954
 		     ud_address_vector.rlid, av->dlid,
955
 		     ud_address_vector.rlid, av->dlid,
955
 		     ud_address_vector.g, av->gid_present );
956
 		     ud_address_vector.g, av->gid_present );
1162
 	}
1163
 	}
1163
 }
1164
 }
1164
 
1165
 
1166
+/***************************************************************************
1167
+ *
1168
+ * Infiniband link-layer operations
1169
+ *
1170
+ ***************************************************************************
1171
+ */
1172
+
1173
+/**
1174
+ * Initialise Infiniband link
1175
+ *
1176
+ * @v ibdev		Infiniband device
1177
+ * @ret rc		Return status code
1178
+ */
1179
+static int hermon_open ( struct ib_device *ibdev ) {
1180
+	struct hermon *hermon = ibdev->dev_priv;
1181
+	struct hermonprm_init_port init_port;
1182
+	int rc;
1183
+
1184
+	memset ( &init_port, 0, sizeof ( init_port ) );
1185
+	MLX_FILL_2 ( &init_port, 0,
1186
+		     port_width_cap, 3,
1187
+		     vl_cap, 1 );
1188
+	MLX_FILL_2 ( &init_port, 1,
1189
+		     mtu, HERMON_MTU_2048,
1190
+		     max_gid, 1 );
1191
+	MLX_FILL_1 ( &init_port, 2, max_pkey, 64 );
1192
+	if ( ( rc = hermon_cmd_init_port ( hermon, ibdev->port,
1193
+					   &init_port ) ) != 0 ) {
1194
+		DBGC ( hermon, "Hermon %p could not intialise port: %s\n",
1195
+		       hermon, strerror ( rc ) );
1196
+		return rc;
1197
+	}
1198
+
1199
+	return 0;
1200
+}
1201
+
1202
+/**
1203
+ * Close Infiniband link
1204
+ *
1205
+ * @v ibdev		Infiniband device
1206
+ */
1207
+static void hermon_close ( struct ib_device *ibdev ) {
1208
+	struct hermon *hermon = ibdev->dev_priv;
1209
+	int rc;
1210
+
1211
+	if ( ( rc = hermon_cmd_close_port ( hermon, ibdev->port ) ) != 0 ) {
1212
+		DBGC ( hermon, "Hermon %p could not close port: %s\n",
1213
+		       hermon, strerror ( rc ) );
1214
+		/* Nothing we can do about this */
1215
+	}
1216
+}
1217
+
1165
 /***************************************************************************
1218
 /***************************************************************************
1166
  *
1219
  *
1167
  * Multicast group operations
1220
  * Multicast group operations
1257
 	}
1310
 	}
1258
 }
1311
 }
1259
 
1312
 
1260
-/** Hermon Infiniband operations */
1261
-static struct ib_device_operations hermon_ib_operations = {
1262
-	.create_cq	= hermon_create_cq,
1263
-	.destroy_cq	= hermon_destroy_cq,
1264
-	.create_qp	= hermon_create_qp,
1265
-	.destroy_qp	= hermon_destroy_qp,
1266
-	.post_send	= hermon_post_send,
1267
-	.post_recv	= hermon_post_recv,
1268
-	.poll_cq	= hermon_poll_cq,
1269
-	.mcast_attach	= hermon_mcast_attach,
1270
-	.mcast_detach	= hermon_mcast_detach,
1271
-};
1272
-
1273
 /***************************************************************************
1313
 /***************************************************************************
1274
  *
1314
  *
1275
- * MAD IFC operations
1315
+ * MAD operations
1276
  *
1316
  *
1277
  ***************************************************************************
1317
  ***************************************************************************
1278
  */
1318
  */
1279
 
1319
 
1280
-static int hermon_mad_ifc ( struct hermon *hermon,
1281
-			    union hermonprm_mad *mad ) {
1282
-	struct ib_mad_hdr *hdr = &mad->mad.mad_hdr;
1283
-	int rc;
1284
-
1285
-	hdr->base_version = IB_MGMT_BASE_VERSION;
1286
-	if ( ( rc = hermon_cmd_mad_ifc ( hermon, mad ) ) != 0 ) {
1287
-		DBGC ( hermon, "Hermon %p could not issue MAD IFC: %s\n",
1288
-		       hermon, strerror ( rc ) );
1289
-		return rc;
1290
-	}
1291
-	if ( hdr->status != 0 ) {
1292
-		DBGC ( hermon, "Hermon %p MAD IFC status %04x\n",
1293
-		       hermon, ntohs ( hdr->status ) );
1294
-		return -EIO;
1295
-	}
1296
-	return 0;
1297
-}
1298
-
1299
-static int hermon_get_port_info ( struct hermon *hermon,
1300
-				  struct ib_mad_port_info *port_info ) {
1301
-	union hermonprm_mad mad;
1302
-	struct ib_mad_hdr *hdr = &mad.mad.mad_hdr;
1303
-	int rc;
1304
-
1305
-	memset ( &mad, 0, sizeof ( mad ) );
1306
-	hdr->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
1307
-	hdr->class_version = 1;
1308
-	hdr->method = IB_MGMT_METHOD_GET;
1309
-	hdr->attr_id = htons ( IB_SMP_ATTR_PORT_INFO );
1310
-	hdr->attr_mod = htonl ( PXE_IB_PORT );
1311
-	if ( ( rc = hermon_mad_ifc ( hermon, &mad ) ) != 0 ) {
1312
-		DBGC ( hermon, "Hermon %p could not get port info: %s\n",
1313
-		       hermon, strerror ( rc ) );
1314
-		return rc;
1315
-	}
1316
-	memcpy ( port_info, &mad.mad.port_info, sizeof ( *port_info ) );
1317
-	return 0;
1318
-}
1319
-
1320
-static int hermon_get_guid_info ( struct hermon *hermon,
1321
-				  struct ib_mad_guid_info *guid_info ) {
1322
-	union hermonprm_mad mad;
1323
-	struct ib_mad_hdr *hdr = &mad.mad.mad_hdr;
1324
-	int rc;
1325
-
1326
-	memset ( &mad, 0, sizeof ( mad ) );
1327
-	hdr->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
1328
-	hdr->class_version = 1;
1329
-	hdr->method = IB_MGMT_METHOD_GET;
1330
-	hdr->attr_id = htons ( IB_SMP_ATTR_GUID_INFO );
1331
-	if ( ( rc = hermon_mad_ifc ( hermon, &mad ) ) != 0 ) {
1332
-		DBGC ( hermon, "Hermon %p could not get GUID info: %s\n",
1333
-		       hermon, strerror ( rc ) );
1334
-		return rc;
1335
-	}
1336
-	memcpy ( guid_info, &mad.mad.guid_info, sizeof ( *guid_info ) );
1337
-	return 0;
1338
-}
1339
-
1340
-static int hermon_get_pkey_table ( struct hermon *hermon,
1341
-				   struct ib_mad_pkey_table *pkey_table ) {
1342
-	union hermonprm_mad mad;
1343
-	struct ib_mad_hdr *hdr = &mad.mad.mad_hdr;
1344
-	int rc;
1345
-
1346
-	memset ( &mad, 0, sizeof ( mad ) );
1347
-	hdr->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
1348
-	hdr->class_version = 1;
1349
-	hdr->method = IB_MGMT_METHOD_GET;
1350
-	hdr->attr_id = htons ( IB_SMP_ATTR_PKEY_TABLE );
1351
-	if ( ( rc = hermon_mad_ifc ( hermon, &mad ) ) != 0 ) {
1352
-		DBGC ( hermon, "Hermon %p could not get pkey table: %s\n",
1353
-		       hermon, strerror ( rc ) );
1354
-		return rc;
1355
-	}
1356
-	memcpy ( pkey_table, &mad.mad.pkey_table, sizeof ( *pkey_table ) );
1357
-	return 0;
1358
-}
1359
-
1360
-static int hermon_get_port_gid ( struct hermon *hermon,
1361
-				 struct ib_gid *port_gid ) {
1362
-	union {
1363
-		/* This union exists just to save stack space */
1364
-		struct ib_mad_port_info port_info;
1365
-		struct ib_mad_guid_info guid_info;
1366
-	} u;
1367
-	int rc;
1368
-
1369
-	/* Port info gives us the first half of the port GID */
1370
-	if ( ( rc = hermon_get_port_info ( hermon, &u.port_info ) ) != 0 )
1371
-		return rc;
1372
-	memcpy ( &port_gid->u.bytes[0], u.port_info.gid_prefix, 8 );
1373
-
1374
-	/* GUID info gives us the second half of the port GID */
1375
-	if ( ( rc = hermon_get_guid_info ( hermon, &u.guid_info ) ) != 0 )
1376
-		return rc;
1377
-	memcpy ( &port_gid->u.bytes[8], u.guid_info.gid_local, 8 );
1378
-
1379
-	return 0;
1380
-}
1381
-
1382
-static int hermon_get_sm_lid ( struct hermon *hermon,
1383
-			       unsigned long *sm_lid ) {
1384
-	struct ib_mad_port_info port_info;
1385
-	int rc;
1386
-
1387
-	if ( ( rc = hermon_get_port_info ( hermon, &port_info ) ) != 0 )
1388
-		return rc;
1389
-	*sm_lid = ntohs ( port_info.mastersm_lid );
1390
-	return 0;
1391
-}
1392
-
1393
-static int hermon_get_pkey ( struct hermon *hermon, unsigned int *pkey ) {
1394
-	struct ib_mad_pkey_table pkey_table;
1395
-	int rc;
1396
-
1397
-	if ( ( rc = hermon_get_pkey_table ( hermon, &pkey_table ) ) != 0 )
1398
-		return rc;
1399
-	*pkey = ntohs ( pkey_table.pkey[0][0] );
1400
-	return 0;
1401
-}
1402
-
1403
 /**
1320
 /**
1404
- * Wait for link up
1321
+ * Issue management datagram
1405
  *
1322
  *
1406
- * @v hermon		Hermon device
1407
- * @ret rc		Return status code
1408
- *
1409
- * This function shouldn't really exist.  Unfortunately, IB links take
1410
- * a long time to come up, and we can't get various key parameters
1411
- * e.g. our own IPoIB MAC address without information from the subnet
1412
- * manager).  We should eventually make link-up an asynchronous event.
1413
- */
1414
-static int hermon_wait_for_link ( struct hermon *hermon ) {
1415
-	struct ib_mad_port_info port_info;
1416
-	unsigned int retries;
1417
-	int rc;
1418
-
1419
-	printf ( "Waiting for Infiniband link-up..." );
1420
-	for ( retries = 20 ; retries ; retries-- ) {
1421
-		if ( ( rc = hermon_get_port_info ( hermon,
1422
-						   &port_info ) ) != 0 )
1423
-			continue;
1424
-		if ( ( ( port_info.port_state__link_speed_supported ) & 0xf )
1425
-		     == 4 ) {
1426
-			printf ( "ok\n" );
1427
-			return 0;
1428
-		}
1429
-		printf ( "." );
1430
-		sleep ( 1 );
1431
-	}
1432
-	printf ( "failed\n" );
1433
-	return -ENODEV;
1434
-};
1435
-
1436
-/**
1437
- * Get MAD parameters
1438
- *
1439
- * @v hermon		Hermon device
1323
+ * @v ibdev		Infiniband device
1324
+ * @v mad		Management datagram
1325
+ * @v len		Length of management datagram
1440
  * @ret rc		Return status code
1326
  * @ret rc		Return status code
1441
  */
1327
  */
1442
-static int hermon_get_mad_params ( struct ib_device *ibdev ) {
1328
+static int hermon_mad ( struct ib_device *ibdev, struct ib_mad_hdr *mad,
1329
+			size_t len ) {
1443
 	struct hermon *hermon = ibdev->dev_priv;
1330
 	struct hermon *hermon = ibdev->dev_priv;
1331
+	union hermonprm_mad mad_ifc;
1444
 	int rc;
1332
 	int rc;
1445
 
1333
 
1446
-	/* Get subnet manager LID */
1447
-	if ( ( rc = hermon_get_sm_lid ( hermon, &ibdev->sm_lid ) ) != 0 ) {
1448
-		DBGC ( hermon, "Hermon %p could not determine subnet manager "
1449
-		       "LID: %s\n", hermon, strerror ( rc ) );
1450
-		return rc;
1451
-	}
1334
+	/* Copy in request packet */
1335
+	memset ( &mad_ifc, 0, sizeof ( mad_ifc ) );
1336
+	assert ( len <= sizeof ( mad_ifc.mad ) );
1337
+	memcpy ( &mad_ifc.mad, mad, len );
1452
 
1338
 
1453
-	/* Get port GID */
1454
-	if ( ( rc = hermon_get_port_gid ( hermon, &ibdev->port_gid ) ) != 0 ) {
1455
-		DBGC ( hermon, "Hermon %p could not determine port GID: %s\n",
1339
+	/* Issue MAD */
1340
+	if ( ( rc = hermon_cmd_mad_ifc ( hermon, ibdev->port,
1341
+					 &mad_ifc ) ) != 0 ) {
1342
+		DBGC ( hermon, "Hermon %p could not issue MAD IFC: %s\n",
1456
 		       hermon, strerror ( rc ) );
1343
 		       hermon, strerror ( rc ) );
1457
 		return rc;
1344
 		return rc;
1458
 	}
1345
 	}
1459
 
1346
 
1460
-	/* Get partition key */
1461
-	if ( ( rc = hermon_get_pkey ( hermon, &ibdev->pkey ) ) != 0 ) {
1462
-		DBGC ( hermon, "Hermon %p could not determine partition key: "
1463
-		       "%s\n", hermon, strerror ( rc ) );
1464
-		return rc;
1465
-	}
1347
+	/* Copy out reply packet */
1348
+	memcpy ( mad, &mad_ifc.mad, len );
1466
 
1349
 
1350
+	if ( mad->status != 0 ) {
1351
+		DBGC ( hermon, "Hermon %p MAD IFC status %04x\n",
1352
+		       hermon, ntohs ( mad->status ) );
1353
+		return -EIO;
1354
+	}
1467
 	return 0;
1355
 	return 0;
1468
 }
1356
 }
1469
 
1357
 
1358
+/** Hermon Infiniband operations */
1359
+static struct ib_device_operations hermon_ib_operations = {
1360
+	.create_cq	= hermon_create_cq,
1361
+	.destroy_cq	= hermon_destroy_cq,
1362
+	.create_qp	= hermon_create_qp,
1363
+	.destroy_qp	= hermon_destroy_qp,
1364
+	.post_send	= hermon_post_send,
1365
+	.post_recv	= hermon_post_recv,
1366
+	.poll_cq	= hermon_poll_cq,
1367
+	.open		= hermon_open,
1368
+	.close		= hermon_close,
1369
+	.mcast_attach	= hermon_mcast_attach,
1370
+	.mcast_detach	= hermon_mcast_detach,
1371
+	.mad		= hermon_mad,
1372
+};
1373
+
1470
 /***************************************************************************
1374
 /***************************************************************************
1471
  *
1375
  *
1472
  * Firmware control
1376
  * Firmware control
1914
 	hermon->icm = UNULL;
1818
 	hermon->icm = UNULL;
1915
 }
1819
 }
1916
 
1820
 
1917
-/***************************************************************************
1918
- *
1919
- * Infiniband link-layer operations
1920
- *
1921
- ***************************************************************************
1922
- */
1923
-
1924
-/**
1925
- * Initialise Infiniband link
1926
- *
1927
- * @v hermon		Hermon device
1928
- * @ret rc		Return status code
1929
- */
1930
-static int hermon_init_port ( struct hermon *hermon ) {
1931
-	struct hermonprm_init_port init_port;
1932
-	int rc;
1933
-
1934
-	memset ( &init_port, 0, sizeof ( init_port ) );
1935
-	MLX_FILL_2 ( &init_port, 0,
1936
-		     port_width_cap, 3,
1937
-		     vl_cap, 1 );
1938
-	MLX_FILL_2 ( &init_port, 1,
1939
-		     mtu, HERMON_MTU_2048,
1940
-		     max_gid, 1 );
1941
-	MLX_FILL_1 ( &init_port, 2, max_pkey, 64 );
1942
-	if ( ( rc = hermon_cmd_init_port ( hermon, PXE_IB_PORT,
1943
-					   &init_port ) ) != 0 ) {
1944
-		DBGC ( hermon, "Hermon %p could not intialise port: %s\n",
1945
-		       hermon, strerror ( rc ) );
1946
-		return rc;
1947
-	}
1948
-
1949
-	return 0;
1950
-}
1951
-
1952
-/**
1953
- * Close Infiniband link
1954
- *
1955
- * @v hermon		Hermon device
1956
- */
1957
-static void hermon_close_port ( struct hermon *hermon ) {
1958
-	int rc;
1959
-
1960
-	if ( ( rc = hermon_cmd_close_port ( hermon, PXE_IB_PORT ) ) != 0 ) {
1961
-		DBGC ( hermon, "Hermon %p could not close port: %s\n",
1962
-		       hermon, strerror ( rc ) );
1963
-		/* Nothing we can do about this */
1964
-	}
1965
-}
1966
-
1967
 /***************************************************************************
1821
 /***************************************************************************
1968
  *
1822
  *
1969
  * PCI interface
1823
  * PCI interface
2030
 	ibdev->op = &hermon_ib_operations;
1884
 	ibdev->op = &hermon_ib_operations;
2031
 	pci_set_drvdata ( pci, ibdev );
1885
 	pci_set_drvdata ( pci, ibdev );
2032
 	ibdev->dev = &pci->dev;
1886
 	ibdev->dev = &pci->dev;
1887
+	ibdev->port = PXE_IB_PORT;
2033
 	hermon = ibdev->dev_priv;
1888
 	hermon = ibdev->dev_priv;
2034
 	memset ( hermon, 0, sizeof ( *hermon ) );
1889
 	memset ( hermon, 0, sizeof ( *hermon ) );
2035
 
1890
 
2084
 	if ( ( rc = hermon_setup_mpt ( hermon ) ) != 0 )
1939
 	if ( ( rc = hermon_setup_mpt ( hermon ) ) != 0 )
2085
 		goto err_setup_mpt;
1940
 		goto err_setup_mpt;
2086
 
1941
 
2087
-	/* Bring up IB layer */
2088
-	if ( ( rc = hermon_init_port ( hermon ) ) != 0 )
2089
-		goto err_init_port;
2090
-
2091
-	/* Wait for link */
2092
-	if ( ( rc = hermon_wait_for_link ( hermon ) ) != 0 )
2093
-		goto err_wait_for_link;
2094
-
2095
-	/* Get MAD parameters */
2096
-	if ( ( rc = hermon_get_mad_params ( ibdev ) ) != 0 )
2097
-		goto err_get_mad_params;
2098
-
2099
-	DBGC ( hermon, "Hermon %p port GID is %08lx:%08lx:%08lx:%08lx\n",
2100
-	       hermon, htonl ( ibdev->port_gid.u.dwords[0] ),
2101
-	       htonl ( ibdev->port_gid.u.dwords[1] ),
2102
-	       htonl ( ibdev->port_gid.u.dwords[2] ),
2103
-	       htonl ( ibdev->port_gid.u.dwords[3] ) );
2104
-
2105
-	/* Add IPoIB device */
2106
-	if ( ( rc = ipoib_probe ( ibdev ) ) != 0 ) {
2107
-		DBGC ( hermon, "Hermon %p could not add IPoIB device: %s\n",
1942
+	/* Register Infiniband device */
1943
+	if ( ( rc = register_ibdev ( ibdev ) ) != 0 ) {
1944
+		DBGC ( hermon, "Hermon %p could not register IB device: %s\n",
2108
 		       hermon, strerror ( rc ) );
1945
 		       hermon, strerror ( rc ) );
2109
-		goto err_ipoib_probe;
1946
+		goto err_register_ibdev;
2110
 	}
1947
 	}
2111
 
1948
 
2112
 	return 0;
1949
 	return 0;
2113
 
1950
 
2114
- err_ipoib_probe:
2115
- err_get_mad_params:
2116
- err_wait_for_link:
2117
-	hermon_close_port ( hermon );
2118
- err_init_port:
1951
+ err_register_ibdev:
2119
  err_setup_mpt:
1952
  err_setup_mpt:
2120
 	hermon_cmd_close_hca ( hermon );
1953
 	hermon_cmd_close_hca ( hermon );
2121
  err_init_hca:
1954
  err_init_hca:
2142
 	struct ib_device *ibdev = pci_get_drvdata ( pci );
1975
 	struct ib_device *ibdev = pci_get_drvdata ( pci );
2143
 	struct hermon *hermon = ibdev->dev_priv;
1976
 	struct hermon *hermon = ibdev->dev_priv;
2144
 
1977
 
2145
-	ipoib_remove ( ibdev );
2146
-	hermon_close_port ( hermon );
1978
+	unregister_ibdev ( ibdev );
2147
 	hermon_cmd_close_hca ( hermon );
1979
 	hermon_cmd_close_hca ( hermon );
2148
 	hermon_free_icm ( hermon );
1980
 	hermon_free_icm ( hermon );
2149
 	hermon_stop_firmware ( hermon );
1981
 	hermon_stop_firmware ( hermon );

+ 70
- 7
src/include/gpxe/infiniband.h View File

156
 	struct ib_gid gid;
156
 	struct ib_gid gid;
157
 };
157
 };
158
 
158
 
159
+struct ib_mad_hdr;
160
+
159
 /**
161
 /**
160
  * Infiniband device operations
162
  * Infiniband device operations
161
  *
163
  *
237
 			     struct ib_completion_queue *cq,
239
 			     struct ib_completion_queue *cq,
238
 			     ib_completer_t complete_send,
240
 			     ib_completer_t complete_send,
239
 			     ib_completer_t complete_recv );
241
 			     ib_completer_t complete_recv );
242
+	/**
243
+	 * Open port
244
+	 *
245
+	 * @v ibdev		Infiniband device
246
+	 * @ret rc		Return status code
247
+	 */
248
+	int ( * open ) ( struct ib_device *ibdev );
249
+	/**
250
+	 * Close port
251
+	 *
252
+	 * @v ibdev		Infiniband device
253
+	 */
254
+	void ( * close ) ( struct ib_device *ibdev );
240
 	/** Attach to multicast group
255
 	/** Attach to multicast group
241
 	 *
256
 	 *
242
 	 * @v ibdev		Infiniband device
257
 	 * @v ibdev		Infiniband device
256
 	void ( * mcast_detach ) ( struct ib_device *ibdev,
271
 	void ( * mcast_detach ) ( struct ib_device *ibdev,
257
 				  struct ib_queue_pair *qp,
272
 				  struct ib_queue_pair *qp,
258
 				  struct ib_gid *gid );
273
 				  struct ib_gid *gid );
274
+	/**
275
+	 * Issue management datagram
276
+	 *
277
+	 * @v ibdev		Infiniband device
278
+	 * @v mad		Management datagram
279
+	 * @v len		Length of management datagram
280
+	 * @ret rc		Return status code
281
+	 */
282
+	int ( * mad ) ( struct ib_device *ibdev, struct ib_mad_hdr *mad,
283
+			size_t len );
259
 };
284
 };
260
 
285
 
261
 /** An Infiniband device */
286
 /** An Infiniband device */
262
 struct ib_device {
287
 struct ib_device {
288
+	/** Underlying device */
289
+	struct device *dev;
290
+	/** Infiniband operations */
291
+	struct ib_device_operations *op;
292
+	/** Port number */
293
+	unsigned int port;
263
 	/** Port GID */
294
 	/** Port GID */
264
 	struct ib_gid port_gid;
295
 	struct ib_gid port_gid;
265
 	/** Subnet manager LID */
296
 	/** Subnet manager LID */
266
 	unsigned long sm_lid;
297
 	unsigned long sm_lid;
267
 	/** Partition key */
298
 	/** Partition key */
268
 	unsigned int pkey;
299
 	unsigned int pkey;
269
-	/** Underlying device */
270
-	struct device *dev;
271
-	/** Infiniband operations */
272
-	struct ib_device_operations *op;
273
 	/** Device private data */
300
 	/** Device private data */
274
 	void *dev_priv;
301
 	void *dev_priv;
275
 	/** Owner private data */
302
 	/** Owner private data */
289
 extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
316
 extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
290
 					   unsigned long qpn, int is_send );
317
 					   unsigned long qpn, int is_send );
291
 extern struct ib_device * alloc_ibdev ( size_t priv_size );
318
 extern struct ib_device * alloc_ibdev ( size_t priv_size );
319
+extern int register_ibdev ( struct ib_device *ibdev );
320
+extern void unregister_ibdev ( struct ib_device *ibdev );
292
 extern void free_ibdev ( struct ib_device *ibdev );
321
 extern void free_ibdev ( struct ib_device *ibdev );
293
 
322
 
294
 /**
323
 /**
334
 	ibdev->op->poll_cq ( ibdev, cq, complete_send, complete_recv );
363
 	ibdev->op->poll_cq ( ibdev, cq, complete_send, complete_recv );
335
 }
364
 }
336
 
365
 
366
+/**
367
+ * Open port
368
+ *
369
+ * @v ibdev		Infiniband device
370
+ * @ret rc		Return status code
371
+ */
372
+static inline __attribute__ (( always_inline )) int
373
+ib_open ( struct ib_device *ibdev ) {
374
+	return ibdev->op->open ( ibdev );
375
+}
376
+
377
+/**
378
+ * Close port
379
+ *
380
+ * @v ibdev		Infiniband device
381
+ */
382
+static inline __attribute__ (( always_inline )) void
383
+ib_close ( struct ib_device *ibdev ) {
384
+	ibdev->op->close ( ibdev );
385
+}
337
 
386
 
338
 /**
387
 /**
339
  * Attach to multicast group
388
  * Attach to multicast group
362
 	ibdev->op->mcast_detach ( ibdev, qp, gid );
411
 	ibdev->op->mcast_detach ( ibdev, qp, gid );
363
 }
412
 }
364
 
413
 
414
+/**
415
+ * Issue management datagram
416
+ *
417
+ * @v ibdev		Infiniband device
418
+ * @v mad		Management datagram
419
+ * @v len		Length of management datagram
420
+ * @ret rc		Return status code
421
+ */
422
+static inline __attribute__ (( always_inline )) int
423
+ib_mad ( struct ib_device *ibdev, struct ib_mad_hdr *mad, size_t len ) {
424
+	return ibdev->op->mad ( ibdev, mad, len );
425
+}
426
+
365
 /**
427
 /**
366
  * Set Infiniband owner-private data
428
  * Set Infiniband owner-private data
367
  *
429
  *
368
  * @v pci		Infiniband device
430
  * @v pci		Infiniband device
369
  * @v priv		Private data
431
  * @v priv		Private data
370
  */
432
  */
371
-static inline void ib_set_ownerdata ( struct ib_device *ibdev,
372
-				      void *owner_priv ) {
433
+static inline __attribute__ (( always_inline )) void
434
+ib_set_ownerdata ( struct ib_device *ibdev, void *owner_priv ) {
373
 	ibdev->owner_priv = owner_priv;
435
 	ibdev->owner_priv = owner_priv;
374
 }
436
 }
375
 
437
 
379
  * @v pci		Infiniband device
441
  * @v pci		Infiniband device
380
  * @ret priv		Private data
442
  * @ret priv		Private data
381
  */
443
  */
382
-static inline void * ib_get_ownerdata ( struct ib_device *ibdev ) {
444
+static inline __attribute__ (( always_inline )) void *
445
+ib_get_ownerdata ( struct ib_device *ibdev ) {
383
 	return ibdev->owner_priv;
446
 	return ibdev->owner_priv;
384
 }
447
 }
385
 
448
 

+ 222
- 0
src/net/infiniband.c View File

20
 #include <stdlib.h>
20
 #include <stdlib.h>
21
 #include <stdio.h>
21
 #include <stdio.h>
22
 #include <string.h>
22
 #include <string.h>
23
+#include <unistd.h>
23
 #include <byteswap.h>
24
 #include <byteswap.h>
24
 #include <errno.h>
25
 #include <errno.h>
25
 #include <assert.h>
26
 #include <assert.h>
27
 #include <gpxe/if_arp.h>
28
 #include <gpxe/if_arp.h>
28
 #include <gpxe/netdevice.h>
29
 #include <gpxe/netdevice.h>
29
 #include <gpxe/iobuf.h>
30
 #include <gpxe/iobuf.h>
31
+#include <gpxe/ipoib.h>
30
 #include <gpxe/infiniband.h>
32
 #include <gpxe/infiniband.h>
31
 
33
 
32
 /** @file
34
 /** @file
184
 	return NULL;
186
 	return NULL;
185
 }
187
 }
186
 
188
 
189
+/***************************************************************************
190
+ *
191
+ * Management datagram operations
192
+ *
193
+ ***************************************************************************
194
+ */
195
+
196
+/**
197
+ * Get port information
198
+ *
199
+ * @v ibdev		Infiniband device
200
+ * @v port_info		Port information datagram to fill in
201
+ * @ret rc		Return status code
202
+ */
203
+static int ib_get_port_info ( struct ib_device *ibdev,
204
+			      struct ib_mad_port_info *port_info ) {
205
+	struct ib_mad_hdr *hdr = &port_info->mad_hdr;
206
+	int rc;
207
+
208
+	/* Construct MAD */
209
+	memset ( port_info, 0, sizeof ( *port_info ) );
210
+	hdr->base_version = IB_MGMT_BASE_VERSION;
211
+	hdr->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
212
+	hdr->class_version = 1;
213
+	hdr->method = IB_MGMT_METHOD_GET;
214
+	hdr->attr_id = htons ( IB_SMP_ATTR_PORT_INFO );
215
+	hdr->attr_mod = htonl ( ibdev->port );
216
+
217
+	if ( ( rc = ib_mad ( ibdev, hdr, sizeof ( *port_info ) ) ) != 0 ) {
218
+		DBGC ( ibdev, "IBDEV %p could not get port info: %s\n",
219
+		       ibdev, strerror ( rc ) );
220
+		return rc;
221
+	}
222
+	return 0;
223
+}
224
+
225
+/**
226
+ * Get GUID information
227
+ *
228
+ * @v ibdev		Infiniband device
229
+ * @v guid_info		GUID information datagram to fill in
230
+ * @ret rc		Return status code
231
+ */
232
+static int ib_get_guid_info ( struct ib_device *ibdev,
233
+			      struct ib_mad_guid_info *guid_info ) {
234
+	struct ib_mad_hdr *hdr = &guid_info->mad_hdr;
235
+	int rc;
236
+
237
+	/* Construct MAD */
238
+	memset ( guid_info, 0, sizeof ( *guid_info ) );
239
+	hdr->base_version = IB_MGMT_BASE_VERSION;
240
+	hdr->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
241
+	hdr->class_version = 1;
242
+	hdr->method = IB_MGMT_METHOD_GET;
243
+	hdr->attr_id = htons ( IB_SMP_ATTR_GUID_INFO );
244
+
245
+	if ( ( rc = ib_mad ( ibdev, hdr, sizeof ( *guid_info ) ) ) != 0 ) {
246
+		DBGC ( ibdev, "IBDEV %p could not get GUID info: %s\n",
247
+		       ibdev, strerror ( rc ) );
248
+		return rc;
249
+	}
250
+	return 0;
251
+}
252
+
253
+/**
254
+ * Get partition key table
255
+ *
256
+ * @v ibdev		Infiniband device
257
+ * @v guid_info		Partition key table datagram to fill in
258
+ * @ret rc		Return status code
259
+ */
260
+static int ib_get_pkey_table ( struct ib_device *ibdev,
261
+			       struct ib_mad_pkey_table *pkey_table ) {
262
+	struct ib_mad_hdr *hdr = &pkey_table->mad_hdr;
263
+	int rc;
264
+
265
+	/* Construct MAD */
266
+	memset ( pkey_table, 0, sizeof ( *pkey_table ) );
267
+	hdr->base_version = IB_MGMT_BASE_VERSION;
268
+	hdr->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
269
+	hdr->class_version = 1;
270
+	hdr->method = IB_MGMT_METHOD_GET;
271
+	hdr->attr_id = htons ( IB_SMP_ATTR_PKEY_TABLE );
272
+
273
+	if ( ( rc = ib_mad ( ibdev, hdr, sizeof ( *pkey_table ) ) ) != 0 ) {
274
+		DBGC ( ibdev, "IBDEV %p could not get pkey table: %s\n",
275
+		       ibdev, strerror ( rc ) );
276
+		return rc;
277
+	}
278
+	return 0;
279
+}
280
+
281
+/**
282
+ * Wait for link up
283
+ *
284
+ * @v ibdev		Infiniband device
285
+ * @ret rc		Return status code
286
+ *
287
+ * This function shouldn't really exist.  Unfortunately, IB links take
288
+ * a long time to come up, and we can't get various key parameters
289
+ * e.g. our own IPoIB MAC address without information from the subnet
290
+ * manager).  We should eventually make link-up an asynchronous event.
291
+ */
292
+static int ib_wait_for_link ( struct ib_device *ibdev ) {
293
+	struct ib_mad_port_info port_info;
294
+	unsigned int retries;
295
+	int rc;
296
+
297
+	printf ( "Waiting for Infiniband link-up..." );
298
+	for ( retries = 20 ; retries ; retries-- ) {
299
+		if ( ( rc = ib_get_port_info ( ibdev, &port_info ) ) != 0 )
300
+			continue;
301
+		if ( ( ( port_info.port_state__link_speed_supported ) & 0xf )
302
+		     == 4 ) {
303
+			printf ( "ok\n" );
304
+			return 0;
305
+		}
306
+		printf ( "." );
307
+		sleep ( 1 );
308
+	}
309
+	printf ( "failed\n" );
310
+	return -ENODEV;
311
+};
312
+
313
+/**
314
+ * Get MAD parameters
315
+ *
316
+ * @v ibdev		Infiniband device
317
+ * @ret rc		Return status code
318
+ */
319
+static int ib_get_mad_params ( struct ib_device *ibdev ) {
320
+	union {
321
+		/* This union exists just to save stack space */
322
+		struct ib_mad_port_info port_info;
323
+		struct ib_mad_guid_info guid_info;
324
+		struct ib_mad_pkey_table pkey_table;
325
+	} u;
326
+	int rc;
327
+
328
+	/* Port info gives us the first half of the port GID and the SM LID */
329
+	if ( ( rc = ib_get_port_info ( ibdev, &u.port_info ) ) != 0 )
330
+		return rc;
331
+	memcpy ( &ibdev->port_gid.u.bytes[0], u.port_info.gid_prefix, 8 );
332
+	ibdev->sm_lid = ntohs ( u.port_info.mastersm_lid );
333
+
334
+	/* GUID info gives us the second half of the port GID */
335
+	if ( ( rc = ib_get_guid_info ( ibdev, &u.guid_info ) ) != 0 )
336
+		return rc;
337
+	memcpy ( &ibdev->port_gid.u.bytes[8], u.guid_info.gid_local, 8 );
338
+
339
+	/* Get partition key */
340
+	if ( ( rc = ib_get_pkey_table ( ibdev, &u.pkey_table ) ) != 0 )
341
+		return rc;
342
+	ibdev->pkey = ntohs ( u.pkey_table.pkey[0][0] );
343
+
344
+	DBGC ( ibdev, "IBDEV %p port GID is %08lx:%08lx:%08lx:%08lx\n",
345
+	       ibdev, htonl ( ibdev->port_gid.u.dwords[0] ),
346
+	       htonl ( ibdev->port_gid.u.dwords[1] ),
347
+	       htonl ( ibdev->port_gid.u.dwords[2] ),
348
+	       htonl ( ibdev->port_gid.u.dwords[3] ) );
349
+
350
+	return 0;
351
+}
352
+
353
+/***************************************************************************
354
+ *
355
+ * Infiniband device creation/destruction
356
+ *
357
+ ***************************************************************************
358
+ */
359
+
187
 /**
360
 /**
188
  * Allocate Infiniband device
361
  * Allocate Infiniband device
189
  *
362
  *
202
 	return ibdev;
375
 	return ibdev;
203
 }
376
 }
204
 
377
 
378
+/**
379
+ * Register Infiniband device
380
+ *
381
+ * @v ibdev		Infiniband device
382
+ * @ret rc		Return status code
383
+ */
384
+int register_ibdev ( struct ib_device *ibdev ) {
385
+	int rc;
386
+
387
+	/* Open link */
388
+	if ( ( rc = ib_open ( ibdev ) ) != 0 )
389
+		goto err_open;
390
+
391
+	/* Wait for link */
392
+	if ( ( rc = ib_wait_for_link ( ibdev ) ) != 0 )
393
+		goto err_wait_for_link;
394
+
395
+	/* Get MAD parameters */
396
+	if ( ( rc = ib_get_mad_params ( ibdev ) ) != 0 )
397
+		goto err_get_mad_params;
398
+
399
+	/* Add IPoIB device */
400
+	if ( ( rc = ipoib_probe ( ibdev ) ) != 0 ) {
401
+		DBGC ( ibdev, "IBDEV %p could not add IPoIB device: %s\n",
402
+		       ibdev, strerror ( rc ) );
403
+		goto err_ipoib_probe;
404
+	}
405
+
406
+	return 0;
407
+
408
+ err_ipoib_probe:
409
+ err_get_mad_params:
410
+ err_wait_for_link:
411
+	ib_close ( ibdev );
412
+ err_open:
413
+	return rc;
414
+}
415
+
416
+/**
417
+ * Unregister Infiniband device
418
+ *
419
+ * @v ibdev		Infiniband device
420
+ */
421
+void unregister_ibdev ( struct ib_device *ibdev ) {
422
+	ipoib_remove ( ibdev );
423
+	ib_close ( ibdev );
424
+}
425
+
205
 /**
426
 /**
206
  * Free Infiniband device
427
  * Free Infiniband device
207
  *
428
  *
210
 void free_ibdev ( struct ib_device *ibdev ) {
431
 void free_ibdev ( struct ib_device *ibdev ) {
211
 	free ( ibdev );
432
 	free ( ibdev );
212
 }
433
 }
434
+

Loading…
Cancel
Save