|
@@ -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" ),
|