Browse Source

Read port GID directly using MAD IFC.

tags/v0.9.3
Michael Brown 16 years ago
parent
commit
67836430e6
3 changed files with 242 additions and 15 deletions
  1. 7
    0
      src/drivers/net/mlx_ipoib/arbel.h
  2. 120
    15
      src/drivers/net/mlx_ipoib/mt25218.c
  3. 115
    0
      src/include/gpxe/infiniband.h

+ 7
- 0
src/drivers/net/mlx_ipoib/arbel.h View File

@@ -33,6 +33,7 @@
33 33
 #define ARBEL_HCR_INIT2RTR_QPEE		0x001a
34 34
 #define ARBEL_HCR_RTR2RTS_QPEE		0x001b
35 35
 #define ARBEL_HCR_2RST_QPEE		0x0021
36
+#define ARBEL_HCR_MAD_IFC		0x0024
36 37
 #define ARBEL_HCR_READ_MGM		0x0025
37 38
 #define ARBEL_HCR_WRITE_MGM		0x0026
38 39
 #define ARBEL_HCR_MGID_HASH		0x0027
@@ -67,6 +68,7 @@ struct MLX_DECLARE_STRUCT ( arbelprm_completion_with_error );
67 68
 struct MLX_DECLARE_STRUCT ( arbelprm_cq_arm_db_record );
68 69
 struct MLX_DECLARE_STRUCT ( arbelprm_cq_ci_db_record );
69 70
 struct MLX_DECLARE_STRUCT ( arbelprm_hca_command_register );
71
+struct MLX_DECLARE_STRUCT ( arbelprm_mad_ifc );
70 72
 struct MLX_DECLARE_STRUCT ( arbelprm_mgm_entry );
71 73
 struct MLX_DECLARE_STRUCT ( arbelprm_mgm_hash );
72 74
 struct MLX_DECLARE_STRUCT ( arbelprm_qp_db_record );
@@ -126,6 +128,11 @@ union arbelprm_doorbell_register {
126 128
 	uint32_t dword[2];
127 129
 } __attribute__ (( packed ));
128 130
 
131
+union arbelprm_mad {
132
+	struct arbelprm_mad_ifc ifc;
133
+	union ib_mad mad;
134
+} __attribute__ (( packed ));
135
+
129 136
 /*
130 137
  * gPXE-specific definitions
131 138
  *

+ 120
- 15
src/drivers/net/mlx_ipoib/mt25218.c View File

@@ -549,6 +549,15 @@ arbel_cmd_2rst_qpee ( struct arbel *arbel, unsigned long qpn ) {
549 549
 			   0x03, NULL, qpn, NULL );
550 550
 }
551 551
 
552
+static inline int
553
+arbel_cmd_mad_ifc ( struct arbel *arbel, union arbelprm_mad *mad ) {
554
+	return arbel_cmd ( arbel,
555
+			   ARBEL_HCR_INOUT_CMD ( ARBEL_HCR_MAD_IFC,
556
+						 1, sizeof ( *mad ),
557
+						 1, sizeof ( *mad ) ),
558
+			   0x03, mad, PXE_IB_PORT, mad );
559
+}
560
+
552 561
 static inline int
553 562
 arbel_cmd_read_mgm ( struct arbel *arbel, unsigned int index,
554 563
 		     struct arbelprm_mgm_entry *mgm ) {
@@ -1233,6 +1242,15 @@ static int arbel_complete ( struct ib_device *ibdev,
1233 1242
 	return rc;
1234 1243
 }			     
1235 1244
 
1245
+/**
1246
+ * Drain event queue
1247
+ *
1248
+ * @v arbel		Arbel device
1249
+ */
1250
+static void arbel_drain_eq ( struct arbel *arbel ) {
1251
+#warning "drain the event queue"
1252
+}
1253
+
1236 1254
 /**
1237 1255
  * Poll completion queue
1238 1256
  *
@@ -1252,6 +1270,9 @@ static void arbel_poll_cq ( struct ib_device *ibdev,
1252 1270
 	unsigned int cqe_idx_mask;
1253 1271
 	int rc;
1254 1272
 
1273
+	/* Drain the event queue */
1274
+	arbel_drain_eq ( arbel );
1275
+
1255 1276
 	while ( 1 ) {
1256 1277
 		/* Look for completion entry */
1257 1278
 		cqe_idx_mask = ( cq->num_cqes - 1 );
@@ -1377,8 +1398,6 @@ static void arbel_mcast_detach ( struct ib_device *ibdev,
1377 1398
 	}
1378 1399
 }
1379 1400
 
1380
-
1381
-
1382 1401
 /** Arbel Infiniband operations */
1383 1402
 static struct ib_device_operations arbel_ib_operations = {
1384 1403
 	.create_cq	= arbel_create_cq,
@@ -1392,20 +1411,83 @@ static struct ib_device_operations arbel_ib_operations = {
1392 1411
 	.mcast_detach	= arbel_mcast_detach,
1393 1412
 };
1394 1413
 
1395
-/**
1396
- * Remove PCI device
1397
- *
1398
- * @v pci		PCI device
1399
- */
1400
-static void arbel_remove ( struct pci_device *pci ) {
1401
-	struct net_device *netdev = pci_get_drvdata ( pci );
1402 1414
 
1403
-	unregister_netdev ( netdev );
1404
-	ib_driver_close ( 0 );
1405
-	netdev_nullify ( netdev );
1406
-	netdev_put ( netdev );
1415
+static int arbel_mad_ifc ( struct arbel *arbel,
1416
+			   union arbelprm_mad *mad ) {
1417
+	struct ib_mad_hdr *hdr = &mad->mad.mad_hdr;
1418
+	int rc;
1419
+
1420
+	hdr->base_version = IB_MGMT_BASE_VERSION;
1421
+	if ( ( rc = arbel_cmd_mad_ifc ( arbel, mad ) ) != 0 ) {
1422
+		DBGC ( arbel, "Arbel %p could not issue MAD IFC: %s\n",
1423
+		       arbel, strerror ( rc ) );
1424
+		return rc;
1425
+	}
1426
+	if ( hdr->status != 0 ) {
1427
+		DBGC ( arbel, "Arbel %p MAD IFC status %04x\n",
1428
+		       arbel, ntohs ( hdr->status ) );
1429
+		return -EIO;
1430
+	}
1431
+	return 0;
1432
+}
1433
+
1434
+static int arbel_get_port_info ( struct arbel *arbel,
1435
+				 struct ib_mad_port_info *port_info ) {
1436
+	union arbelprm_mad mad;
1437
+	struct ib_mad_hdr *hdr = &mad.mad.mad_hdr;
1438
+	int rc;
1439
+
1440
+	memset ( &mad, 0, sizeof ( mad ) );
1441
+	hdr->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
1442
+	hdr->class_version = 1;
1443
+	hdr->method = IB_MGMT_METHOD_GET;
1444
+	hdr->attr_id = htons ( IB_SMP_ATTR_PORT_INFO );
1445
+	hdr->attr_mod = htonl ( PXE_IB_PORT );
1446
+	if ( ( rc = arbel_mad_ifc ( arbel, &mad ) ) != 0 ) {
1447
+		DBGC ( arbel, "Arbel %p could not get port info: %s\n",
1448
+		       arbel, strerror ( rc ) );
1449
+		return rc;
1450
+	}
1451
+	memcpy ( port_info, &mad.mad.port_info, sizeof ( *port_info ) );
1452
+	return 0;
1453
+}
1454
+
1455
+static int arbel_get_guid_info ( struct arbel *arbel,
1456
+				 struct ib_mad_guid_info *guid_info ) {
1457
+	union arbelprm_mad mad;
1458
+	struct ib_mad_hdr *hdr = &mad.mad.mad_hdr;
1459
+	int rc;
1460
+
1461
+	memset ( &mad, 0, sizeof ( mad ) );
1462
+	hdr->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
1463
+	hdr->class_version = 1;
1464
+	hdr->method = IB_MGMT_METHOD_GET;
1465
+	hdr->attr_id = htons ( IB_SMP_ATTR_GUID_INFO );
1466
+	if ( ( rc = arbel_mad_ifc ( arbel, &mad ) ) != 0 ) {
1467
+		DBGC ( arbel, "Arbel %p could not get GUID info: %s\n",
1468
+		       arbel, strerror ( rc ) );
1469
+		return rc;
1470
+	}
1471
+	memcpy ( guid_info, &mad.mad.guid_info, sizeof ( *guid_info ) );
1472
+	return 0;
1407 1473
 }
1408 1474
 
1475
+static int arbel_get_port_gid ( struct arbel *arbel, struct ib_gid *gid ) {
1476
+	struct ib_mad_port_info port_info;
1477
+	struct ib_mad_guid_info guid_info;
1478
+	int rc;
1479
+
1480
+	if ( ( rc = arbel_get_port_info ( arbel, &port_info ) ) != 0 )
1481
+		return rc;
1482
+	if ( ( rc = arbel_get_guid_info ( arbel, &guid_info ) ) != 0 )
1483
+		return rc;
1484
+	memcpy ( &gid->bytes[0], port_info.gid_prefix, 8 );
1485
+	memcpy ( &gid->bytes[8], guid_info.gid_local, 8 );
1486
+	return 0;
1487
+}
1488
+
1489
+
1490
+
1409 1491
 /**
1410 1492
  * Probe PCI device
1411 1493
  *
@@ -1514,11 +1596,20 @@ static int arbel_probe ( struct pci_device *pci,
1514 1596
 		      strerror ( rc ) );
1515 1597
 		return rc;
1516 1598
 	}
1517
-				      
1599
+
1600
+	if ( ( rc = arbel_get_port_gid ( arbel, &ibdev->port_gid ) ) != 0 ) {
1601
+		DBGC ( arbel, "Arbel %p could not determine port GID: %s\n",
1602
+		       arbel, strerror ( rc ) );
1603
+		return rc;
1604
+	}
1605
+
1606
+	DBG ( "Port GID:\n" );
1607
+	DBG_HD ( &ibdev->port_gid, sizeof ( ibdev->port_gid ) );
1608
+		
1518 1609
 
1519 1610
 	mac = ( ( struct ib_mac * ) netdev->ll_addr );
1520 1611
 	mac->qpn = htonl ( mlx->own_qp->qpn );
1521
-	memcpy ( &mac->gid, ib_data.port_gid.raw, sizeof ( mac->gid ) );	
1612
+	memcpy ( &mac->gid, &ibdev->port_gid, sizeof ( mac->gid ) );	
1522 1613
 #endif
1523 1614
 
1524 1615
 #if 0
@@ -1545,6 +1636,20 @@ static int arbel_probe ( struct pci_device *pci,
1545 1636
 	return rc;
1546 1637
 }
1547 1638
 
1639
+/**
1640
+ * Remove PCI device
1641
+ *
1642
+ * @v pci		PCI device
1643
+ */
1644
+static void arbel_remove ( struct pci_device *pci ) {
1645
+	struct net_device *netdev = pci_get_drvdata ( pci );
1646
+
1647
+	unregister_netdev ( netdev );
1648
+	ib_driver_close ( 0 );
1649
+	netdev_nullify ( netdev );
1650
+	netdev_put ( netdev );
1651
+}
1652
+
1548 1653
 static struct pci_device_id arbel_nics[] = {
1549 1654
 	PCI_ROM ( 0x15b3, 0x6282, "MT25218", "MT25218 HCA driver" ),
1550 1655
 	PCI_ROM ( 0x15b3, 0x6274, "MT25204", "MT25204 HCA driver" ),

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

@@ -277,6 +277,8 @@ struct ib_device_operations {
277 277
 
278 278
 /** An Infiniband device */
279 279
 struct ib_device {	
280
+	/** Port GID */
281
+	struct ib_gid port_gid;
280 282
 	/** Infiniband operations */
281 283
 	struct ib_device_operations *op;
282 284
 	/** Device private data */
@@ -323,6 +325,119 @@ ib_mcast_detach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
323 325
 	ibdev->op->mcast_detach ( ibdev, qp, gid );
324 326
 }
325 327
 
328
+/*****************************************************************************
329
+ *
330
+ * Management datagrams
331
+ *
332
+ * Portions Copyright (c) 2004 Mellanox Technologies Ltd.  All rights
333
+ * reserved.
334
+ *
335
+ */
336
+
337
+/* Management base version */
338
+#define IB_MGMT_BASE_VERSION			1
339
+
340
+/* Management classes */
341
+#define IB_MGMT_CLASS_SUBN_LID_ROUTED		0x01
342
+#define IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE	0x81
343
+#define IB_MGMT_CLASS_SUBN_ADM			0x03
344
+#define IB_MGMT_CLASS_PERF_MGMT			0x04
345
+#define IB_MGMT_CLASS_BM			0x05
346
+#define IB_MGMT_CLASS_DEVICE_MGMT		0x06
347
+#define IB_MGMT_CLASS_CM			0x07
348
+#define IB_MGMT_CLASS_SNMP			0x08
349
+#define IB_MGMT_CLASS_VENDOR_RANGE2_START	0x30
350
+#define IB_MGMT_CLASS_VENDOR_RANGE2_END		0x4F
351
+
352
+/* Management methods */
353
+#define IB_MGMT_METHOD_GET			0x01
354
+#define IB_MGMT_METHOD_SET			0x02
355
+#define IB_MGMT_METHOD_GET_RESP			0x81
356
+#define IB_MGMT_METHOD_SEND			0x03
357
+#define IB_MGMT_METHOD_TRAP			0x05
358
+#define IB_MGMT_METHOD_REPORT			0x06
359
+#define IB_MGMT_METHOD_REPORT_RESP		0x86
360
+#define IB_MGMT_METHOD_TRAP_REPRESS		0x07
361
+#define IB_MGMT_METHOD_DELETE			0x15
362
+#define IB_MGMT_METHOD_RESP			0x80
363
+
364
+/* Subnet management attributes */
365
+#define IB_SMP_ATTR_NOTICE			0x0002
366
+#define IB_SMP_ATTR_NODE_DESC			0x0010
367
+#define IB_SMP_ATTR_NODE_INFO			0x0011
368
+#define IB_SMP_ATTR_SWITCH_INFO			0x0012
369
+#define IB_SMP_ATTR_GUID_INFO			0x0014
370
+#define IB_SMP_ATTR_PORT_INFO			0x0015
371
+#define IB_SMP_ATTR_PKEY_TABLE			0x0016
372
+#define IB_SMP_ATTR_SL_TO_VL_TABLE		0x0017
373
+#define IB_SMP_ATTR_VL_ARB_TABLE		0x0018
374
+#define IB_SMP_ATTR_LINEAR_FORWARD_TABLE	0x0019
375
+#define IB_SMP_ATTR_RANDOM_FORWARD_TABLE	0x001A
376
+#define IB_SMP_ATTR_MCAST_FORWARD_TABLE		0x001B
377
+#define IB_SMP_ATTR_SM_INFO			0x0020
378
+#define IB_SMP_ATTR_VENDOR_DIAG			0x0030
379
+#define IB_SMP_ATTR_LED_INFO			0x0031
380
+#define IB_SMP_ATTR_VENDOR_MASK			0xFF00
381
+
382
+struct ib_mad_hdr {
383
+	uint8_t base_version;
384
+	uint8_t mgmt_class;
385
+	uint8_t class_version;
386
+	uint8_t method;
387
+	uint16_t status;
388
+	uint16_t class_specific;
389
+	uint64_t tid;
390
+	uint16_t attr_id;
391
+	uint16_t resv;
392
+	uint32_t attr_mod;
393
+} __attribute__ (( packed ));
394
+
395
+struct ib_mad_data {
396
+	struct ib_mad_hdr mad_hdr;
397
+	uint8_t data[232];
398
+} __attribute__ (( packed ));
399
+
400
+struct ib_mad_guid_info {
401
+	struct ib_mad_hdr mad_hdr;
402
+	uint32_t mkey[2];
403
+	uint32_t reserved[8];
404
+	uint8_t gid_local[8];
405
+} __attribute__ (( packed ));
406
+
407
+struct ib_mad_port_info {
408
+	struct ib_mad_hdr mad_hdr;
409
+	uint32_t mkey[2];
410
+	uint32_t reserved[8];
411
+	uint32_t mkey2[2];
412
+	uint8_t gid_prefix[8];
413
+	uint16_t lid;
414
+	uint16_t mastersm_lid;
415
+	uint32_t cap_mask;
416
+	uint16_t diag_code;
417
+	uint16_t mkey_lease_period;
418
+	uint8_t local_port_num;
419
+	uint8_t link_width_enabled;
420
+	uint8_t link_width_supported;
421
+	uint8_t link_width_active;
422
+	uint8_t port_state__link_speed_supported;
423
+	uint8_t link_down_def_state__port_phys_state;
424
+	uint8_t lmc__r1__mkey_prot_bits;
425
+	uint8_t link_speed_enabled__link_speed_active;
426
+} __attribute__ (( packed ));
427
+
428
+union ib_mad {
429
+	struct ib_mad_hdr mad_hdr;
430
+	struct ib_mad_data data;
431
+	struct ib_mad_guid_info guid_info;
432
+	struct ib_mad_port_info port_info;
433
+} __attribute__ (( packed ));
434
+
435
+
436
+
437
+
438
+
439
+
440
+
326 441
 
327 442
 extern struct ll_protocol infiniband_protocol;
328 443
 

Loading…
Cancel
Save