Browse Source

[hermon] Add BOFM support

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 13 years ago
parent
commit
e809985ca9
3 changed files with 415 additions and 58 deletions
  1. 104
    17
      src/drivers/infiniband/MT25408_PRM.h
  2. 294
    33
      src/drivers/infiniband/hermon.c
  3. 17
    8
      src/drivers/infiniband/hermon.h

+ 104
- 17
src/drivers/infiniband/MT25408_PRM.h View File

@@ -1335,7 +1335,11 @@ struct hermonprm_virtual_physical_mapping_st {	/* Little Endian */
1335 1335
 /* MOD_STAT_CFG            #### michal - gdror fix */
1336 1336
 
1337 1337
 struct hermonprm_mod_stat_cfg_st {	/* Little Endian */
1338
-    pseudo_bit_t	reserved0[0x00010];
1338
+    pseudo_bit_t	log_pg_sz[0x00008];
1339
+    pseudo_bit_t	log_pg_sz_m[0x00001];
1340
+    pseudo_bit_t	reserved0[0x00005];
1341
+    pseudo_bit_t	dife[0x00001];
1342
+    pseudo_bit_t	dife_m[0x00001];
1339 1343
     pseudo_bit_t	rx_options[0x00004];   /* number of RX options to sweep when doing SerDes parameters AutoNegotiation. */
1340 1344
     pseudo_bit_t	reserved1[0x00003];
1341 1345
     pseudo_bit_t	rx_options_m[0x00001]; /* Modify rx_options */
@@ -1343,46 +1347,129 @@ struct hermonprm_mod_stat_cfg_st {	/* Little Endian */
1343 1347
     pseudo_bit_t	reserved2[0x00003];
1344 1348
     pseudo_bit_t	tx_options_m[0x00001]; /* Modify tx_options */
1345 1349
 /* -------------- */
1346
-    pseudo_bit_t	reserved3[0x00020];
1350
+    pseudo_bit_t	reserved3[0x00010];
1351
+    pseudo_bit_t	qdr_rx_options[0x00004];
1352
+    pseudo_bit_t	reserved4[0x00003];
1353
+    pseudo_bit_t	qdr_rx_options_m[0x00001];
1354
+    pseudo_bit_t	qdr_tx_options[0x00004];
1355
+    pseudo_bit_t	reserved5[0x00003];
1356
+    pseudo_bit_t	qdr_tx_options_m[0x00001];
1347 1357
 /* -------------- */
1348
-    pseudo_bit_t	pre_amp[0x00004];      /* Pre Amplitude */
1349
-    pseudo_bit_t	pre_emp_pre_amp[0x00004];
1350
-    pseudo_bit_t	pre_emp_out[0x00004];  /* Pre Emphasis Out */
1351
-    pseudo_bit_t	voltage[0x00004];
1352
-    pseudo_bit_t	equ[0x00004];          /* Equalization */
1353
-    pseudo_bit_t	reserved4[0x0000b];
1354
-    pseudo_bit_t	serdes_m[0x00001];     /* Modify serdes parameters */
1358
+    pseudo_bit_t	reserved6[0x00020];
1355 1359
 /* -------------- */
1356 1360
     pseudo_bit_t	lid[0x00010];          /* default LID */
1357 1361
     pseudo_bit_t	lid_m[0x00001];        /* Modify default LID */
1358
-    pseudo_bit_t	reserved5[0x00003];
1362
+    pseudo_bit_t	reserved7[0x00003];
1359 1363
     pseudo_bit_t	port_en[0x00001];      /* enable port (E_Key) */
1360 1364
     pseudo_bit_t	port_en_m[0x00001];    /* Modify  port_en */
1361
-    pseudo_bit_t	reserved6[0x0000a];
1365
+    pseudo_bit_t	reserved8[0x00002];
1366
+    pseudo_bit_t	port_pause_mode[0x00002];
1367
+    pseudo_bit_t	reserved9[0x00001];
1368
+    pseudo_bit_t	port_pause_mode_m[0x00001];
1369
+    pseudo_bit_t	reserved10[0x00004];
1362 1370
 /* -------------- */
1363
-    pseudo_bit_t	reserved7[0x0001f];
1371
+    pseudo_bit_t	reserved11[0x0001f];
1364 1372
     pseudo_bit_t	guid_hi_m[0x00001];    /* Modify guid_hi */
1365 1373
 /* -------------- */
1366 1374
     pseudo_bit_t	guid_hi[0x00020];
1367 1375
 /* -------------- */
1368
-    pseudo_bit_t	reserved8[0x0001f];
1376
+    pseudo_bit_t	reserved12[0x0001f];
1369 1377
     pseudo_bit_t	guid_lo_m[0x00001];    /* Modify guid_lo */
1370 1378
 /* -------------- */
1371 1379
     pseudo_bit_t	guid_lo[0x00020];
1372 1380
 /* -------------- */
1373
-    pseudo_bit_t	reserved9[0x0001f];
1381
+    pseudo_bit_t	reserved13[0x0001f];
1374 1382
     pseudo_bit_t	nodeguid_hi_m[0x00001];
1375 1383
 /* -------------- */
1376 1384
     pseudo_bit_t	nodeguid_hi[0x00020];
1377 1385
 /* -------------- */
1378
-    pseudo_bit_t	reserved10[0x0001f];
1386
+    pseudo_bit_t	reserved14[0x0001f];
1379 1387
     pseudo_bit_t	nodeguid_lo_m[0x00001];
1380 1388
 /* -------------- */
1381 1389
     pseudo_bit_t	nodeguid_lo[0x00020];
1382 1390
 /* -------------- */
1383
-    pseudo_bit_t	reserved11[0x00680];
1391
+    pseudo_bit_t	ob_preemp_pre[0x00005];
1392
+    pseudo_bit_t	reserved15[0x00003];
1393
+    pseudo_bit_t	ob_preemp_post[0x00005];
1394
+    pseudo_bit_t	reserved16[0x00003];
1395
+    pseudo_bit_t	ob_preemp_main[0x00005];
1396
+    pseudo_bit_t	reserved17[0x00003];
1397
+    pseudo_bit_t	ob_preemp[0x00005];
1398
+    pseudo_bit_t	reserved18[0x00002];
1399
+    pseudo_bit_t	serdes_m[0x00001];
1384 1400
 /* -------------- */
1385
-}; 
1401
+    pseudo_bit_t	inbuf_ind_en[0x00003];
1402
+    pseudo_bit_t	reserved19[0x00001];
1403
+    pseudo_bit_t	sd_main[0x00004];
1404
+    pseudo_bit_t	reserved20[0x00004];
1405
+    pseudo_bit_t	sd_equal[0x00004];
1406
+    pseudo_bit_t	reserved21[0x00004];
1407
+    pseudo_bit_t	sd_mux_main[0x00002];
1408
+    pseudo_bit_t	reserved22[0x00002];
1409
+    pseudo_bit_t	mux_eq[0x00002];
1410
+    pseudo_bit_t	reserved23[0x00002];
1411
+    pseudo_bit_t	sigdet_th[0x00003];
1412
+    pseudo_bit_t	reserved24[0x00001];
1413
+/* -------------- */
1414
+    pseudo_bit_t	reserved25[0x00040];
1415
+/* -------------- */
1416
+    pseudo_bit_t	port_protocol[0x00008];
1417
+    pseudo_bit_t	port_dual[0x00001];
1418
+    pseudo_bit_t	reserved26[0x00006];
1419
+    pseudo_bit_t	port_protocol_m[0x00001];
1420
+    pseudo_bit_t	num_port[0x00008];
1421
+    pseudo_bit_t	reserved27[0x00008];
1422
+/* -------------- */
1423
+    pseudo_bit_t	port_protocol_vpi[0x00008];
1424
+    pseudo_bit_t	reserved28[0x00018];
1425
+/* -------------- */
1426
+    pseudo_bit_t	reserved29[0x00180];
1427
+/* -------------- */
1428
+    pseudo_bit_t	fw_rev_major[0x00010];
1429
+    pseudo_bit_t	reserved30[0x0000f];
1430
+    pseudo_bit_t	fw_rev_support[0x00001];
1431
+/* -------------- */
1432
+    pseudo_bit_t	fw_rev_minor[0x00010];
1433
+    pseudo_bit_t	fw_rev_subminor[0x00010];
1434
+/* -------------- */
1435
+    pseudo_bit_t	cmd_interface_rev[0x00010];
1436
+    pseudo_bit_t	reserved31[0x00010];
1437
+/* -------------- */
1438
+    pseudo_bit_t	reserved32[0x00060];
1439
+/* -------------- */
1440
+    pseudo_bit_t	mac_high[0x00010];
1441
+    pseudo_bit_t	reserved33[0x0000f];
1442
+    pseudo_bit_t	mac_m[0x00001];
1443
+/* -------------- */
1444
+    pseudo_bit_t	mac_low[0x00020];
1445
+/* -------------- */
1446
+    pseudo_bit_t	reserved34[0x00010];
1447
+    pseudo_bit_t	num_veps[0x00008];
1448
+    pseudo_bit_t	num_vep_groups[0x00008];
1449
+/* -------------- */
1450
+    pseudo_bit_t	reserved35[0x00020];
1451
+/* -------------- */
1452
+    pseudo_bit_t	reserved36[0x00018];
1453
+    pseudo_bit_t	outer_vlan_en[0x00001];
1454
+    pseudo_bit_t	reserved37[0x00002];
1455
+    pseudo_bit_t	outer_vlan_en_m[0x00001];
1456
+    pseudo_bit_t	port_net_boot[0x00001];
1457
+    pseudo_bit_t	reserved38[0x00002];
1458
+    pseudo_bit_t	port_net_boot_m[0x00001];
1459
+/* -------------- */
1460
+    pseudo_bit_t	reserved39[0x00060];
1461
+/* -------------- */
1462
+    pseudo_bit_t	port_eth_mode_capability[0x0001f];
1463
+    pseudo_bit_t	reserved40[0x00001];
1464
+/* -------------- */
1465
+    pseudo_bit_t	port_eth_mode_enabled[0x0001f];
1466
+    pseudo_bit_t	port_eth_mod_m[0x00001];
1467
+/* -------------- */
1468
+    pseudo_bit_t	port_eth_mode_current[0x0001f];
1469
+    pseudo_bit_t	reserved41[0x00001];
1470
+/* -------------- */
1471
+    pseudo_bit_t	reserved42[0x00220];
1472
+};
1386 1473
 
1387 1474
 /* SRQ Context */
1388 1475
 

+ 294
- 33
src/drivers/infiniband/hermon.c View File

@@ -40,6 +40,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
40 40
 #include <ipxe/ethernet.h>
41 41
 #include <ipxe/fcoe.h>
42 42
 #include <ipxe/vlan.h>
43
+#include <ipxe/bofm.h>
43 44
 #include "hermon.h"
44 45
 
45 46
 /**
@@ -496,6 +497,17 @@ hermon_cmd_mgid_hash ( struct hermon *hermon, const union ib_gid *gid,
496 497
 			    0, gid, 0, hash );
497 498
 }
498 499
 
500
+static inline int
501
+hermon_cmd_mod_stat_cfg ( struct hermon *hermon, unsigned int mode,
502
+			  unsigned int input_mod,
503
+			  struct hermonprm_scalar_parameter *portion ) {
504
+	return hermon_cmd ( hermon,
505
+			    HERMON_HCR_INOUT_CMD ( HERMON_HCR_MOD_STAT_CFG,
506
+						   0, sizeof ( *portion ),
507
+						   0, sizeof ( *portion ) ),
508
+			    mode, portion, input_mod, portion );
509
+}
510
+
499 511
 static inline int
500 512
 hermon_cmd_query_port ( struct hermon *hermon, unsigned int port,
501 513
 			struct hermonprm_query_port_cap *query_port ) {
@@ -682,6 +694,59 @@ static void hermon_free_mtt ( struct hermon *hermon,
682 694
 			      mtt->num_pages );
683 695
 }
684 696
 
697
+/***************************************************************************
698
+ *
699
+ * Static configuration operations
700
+ *
701
+ ***************************************************************************
702
+ */
703
+
704
+/**
705
+ * Calculate offset within static configuration
706
+ *
707
+ * @v field		Field
708
+ * @ret offset		Offset
709
+ */
710
+#define HERMON_MOD_STAT_CFG_OFFSET( field )				     \
711
+	( ( MLX_BIT_OFFSET ( struct hermonprm_mod_stat_cfg_st, field ) / 8 ) \
712
+	  & ~( sizeof ( struct hermonprm_scalar_parameter ) - 1 ) )
713
+
714
+/**
715
+ * Query or modify static configuration
716
+ *
717
+ * @v hermon		Hermon device
718
+ * @v port		Port
719
+ * @v mode		Command mode
720
+ * @v offset		Offset within static configuration
721
+ * @v stat_cfg		Static configuration
722
+ * @ret rc		Return status code
723
+ */
724
+static int hermon_mod_stat_cfg ( struct hermon *hermon, unsigned int port,
725
+				 unsigned int mode, unsigned int offset,
726
+				 struct hermonprm_mod_stat_cfg *stat_cfg ) {
727
+	struct hermonprm_scalar_parameter *portion =
728
+		( ( void * ) &stat_cfg->u.bytes[offset] );
729
+	struct hermonprm_mod_stat_cfg_input_mod mod;
730
+	int rc;
731
+
732
+	/* Sanity check */
733
+	assert ( ( offset % sizeof ( *portion ) ) == 0 );
734
+
735
+	/* Construct input modifier */
736
+	memset ( &mod, 0, sizeof ( mod ) );
737
+	MLX_FILL_2 ( &mod, 0,
738
+		     portnum, port,
739
+		     offset, offset );
740
+
741
+	/* Issue command */
742
+	if ( ( rc = hermon_cmd_mod_stat_cfg ( hermon, mode,
743
+					      be32_to_cpu ( mod.u.dwords[0] ),
744
+					      portion ) ) != 0 )
745
+		return rc;
746
+
747
+	return 0;
748
+}
749
+
685 750
 /***************************************************************************
686 751
  *
687 752
  * MAD operations
@@ -3230,6 +3295,103 @@ static void hermon_free_icm ( struct hermon *hermon ) {
3230 3295
 	hermon->icm = UNULL;
3231 3296
 }
3232 3297
 
3298
+/***************************************************************************
3299
+ *
3300
+ * BOFM interface
3301
+ *
3302
+ ***************************************************************************
3303
+ */
3304
+
3305
+/**
3306
+ * Harvest Ethernet MAC for BOFM
3307
+ *
3308
+ * @v bofm		BOFM device
3309
+ * @v mport		Multi-port index
3310
+ * @v mac		MAC to fill in
3311
+ * @ret rc		Return status code
3312
+ */
3313
+static int hermon_bofm_harvest ( struct bofm_device *bofm, unsigned int mport,
3314
+				 uint8_t *mac ) {
3315
+	struct hermon *hermon = container_of ( bofm, struct hermon, bofm );
3316
+	struct hermonprm_mod_stat_cfg stat_cfg;
3317
+	union {
3318
+		uint8_t bytes[8];
3319
+		uint32_t dwords[2];
3320
+	} buf;
3321
+	int rc;
3322
+
3323
+	/* Query static configuration */
3324
+	if ( ( rc = hermon_mod_stat_cfg ( hermon, mport,
3325
+					  HERMON_MOD_STAT_CFG_QUERY,
3326
+					  HERMON_MOD_STAT_CFG_OFFSET ( mac_m ),
3327
+					  &stat_cfg ) ) != 0 ) {
3328
+		DBGC ( hermon, "Hermon %p port %d could not query "
3329
+		       "configuration: %s\n", hermon, mport, strerror ( rc ) );
3330
+		return rc;
3331
+	}
3332
+
3333
+	/* Retrieve MAC address */
3334
+	buf.dwords[0] = htonl ( MLX_GET ( &stat_cfg, mac_high ) );
3335
+	buf.dwords[1] = htonl ( MLX_GET ( &stat_cfg, mac_low ) );
3336
+	memcpy ( mac, &buf.bytes[ sizeof ( buf.bytes ) - ETH_ALEN ],
3337
+		 ETH_ALEN );
3338
+
3339
+	DBGC ( hermon, "Hermon %p port %d harvested MAC address %s\n",
3340
+	       hermon, mport, eth_ntoa ( mac ) );
3341
+
3342
+	return 0;
3343
+}
3344
+
3345
+/**
3346
+ * Update Ethernet MAC for BOFM
3347
+ *
3348
+ * @v bofm		BOFM device
3349
+ * @v mport		Multi-port index
3350
+ * @v mac		MAC to fill in
3351
+ * @ret rc		Return status code
3352
+ */
3353
+static int hermon_bofm_update ( struct bofm_device *bofm, unsigned int mport,
3354
+				const uint8_t *mac ) {
3355
+	struct hermon *hermon = container_of ( bofm, struct hermon, bofm );
3356
+	struct hermonprm_mod_stat_cfg stat_cfg;
3357
+	union {
3358
+		uint8_t bytes[8];
3359
+		uint32_t dwords[2];
3360
+	} buf;
3361
+	int rc;
3362
+
3363
+	/* Prepare MAC address */
3364
+	memset ( &buf, 0, sizeof ( buf ) );
3365
+	memcpy ( &buf.bytes[ sizeof ( buf.bytes ) - ETH_ALEN ], mac,
3366
+		 ETH_ALEN );
3367
+
3368
+	/* Modify static configuration */
3369
+	memset ( &stat_cfg, 0, sizeof ( stat_cfg ) );
3370
+	MLX_FILL_2 ( &stat_cfg, 36,
3371
+		     mac_m, 1,
3372
+		     mac_high, ntohl ( buf.dwords[0] ) );
3373
+	MLX_FILL_1 ( &stat_cfg, 37, mac_low, ntohl ( buf.dwords[1] ) );
3374
+	if ( ( rc = hermon_mod_stat_cfg ( hermon, mport,
3375
+					  HERMON_MOD_STAT_CFG_SET,
3376
+					  HERMON_MOD_STAT_CFG_OFFSET ( mac_m ),
3377
+					  &stat_cfg ) ) != 0 ) {
3378
+		DBGC ( hermon, "Hermon %p port %d could not modify "
3379
+		       "configuration: %s\n", hermon, mport, strerror ( rc ) );
3380
+		return rc;
3381
+	}
3382
+
3383
+	DBGC ( hermon, "Hermon %p port %d updated MAC address to %s\n",
3384
+	       hermon, mport, eth_ntoa ( mac ) );
3385
+
3386
+	return 0;
3387
+}
3388
+
3389
+/** Hermon BOFM operations */
3390
+static struct bofm_operations hermon_bofm_operations = {
3391
+	.harvest = hermon_bofm_harvest,
3392
+	.update = hermon_bofm_update,
3393
+};
3394
+
3233 3395
 /***************************************************************************
3234 3396
  *
3235 3397
  * PCI interface
@@ -3325,6 +3487,72 @@ static void hermon_reset ( struct hermon *hermon,
3325 3487
 	pci_restore ( pci, &backup, backup_exclude );
3326 3488
 }
3327 3489
 
3490
+/**
3491
+ * Allocate Hermon device
3492
+ *
3493
+ * @v pci		PCI device
3494
+ * @v id		PCI ID
3495
+ * @ret rc		Return status code
3496
+ */
3497
+static struct hermon * hermon_alloc ( void ) {
3498
+	struct hermon *hermon;
3499
+
3500
+	/* Allocate Hermon device */
3501
+	hermon = zalloc ( sizeof ( *hermon ) );
3502
+	if ( ! hermon )
3503
+		goto err_hermon;
3504
+
3505
+	/* Allocate space for mailboxes */
3506
+	hermon->mailbox_in = malloc_dma ( HERMON_MBOX_SIZE,
3507
+					  HERMON_MBOX_ALIGN );
3508
+	if ( ! hermon->mailbox_in )
3509
+		goto err_mailbox_in;
3510
+	hermon->mailbox_out = malloc_dma ( HERMON_MBOX_SIZE,
3511
+					   HERMON_MBOX_ALIGN );
3512
+	if ( ! hermon->mailbox_out )
3513
+		goto err_mailbox_out;
3514
+
3515
+	return hermon;
3516
+
3517
+	free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE );
3518
+ err_mailbox_out:
3519
+	free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
3520
+ err_mailbox_in:
3521
+	free ( hermon );
3522
+ err_hermon:
3523
+	return NULL;
3524
+}
3525
+
3526
+/**
3527
+ * Free Hermon device
3528
+ *
3529
+ * @v hermon		Hermon device
3530
+ */
3531
+static void hermon_free ( struct hermon *hermon ) {
3532
+
3533
+	free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE );
3534
+	free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
3535
+	free ( hermon );
3536
+}
3537
+
3538
+/**
3539
+ * Initialise Hermon PCI parameters
3540
+ *
3541
+ * @v hermon		Hermon device
3542
+ * @v pci		PCI device
3543
+ */
3544
+static void hermon_pci_init ( struct hermon *hermon, struct pci_device *pci ) {
3545
+
3546
+	/* Fix up PCI device */
3547
+	adjust_pci_device ( pci );
3548
+
3549
+	/* Get PCI BARs */
3550
+	hermon->config = ioremap ( pci_bar_start ( pci, HERMON_PCI_CONFIG_BAR),
3551
+				   HERMON_PCI_CONFIG_BAR_SIZE );
3552
+	hermon->uar = ioremap ( pci_bar_start ( pci, HERMON_PCI_UAR_BAR ),
3553
+				HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE );
3554
+}
3555
+
3328 3556
 /**
3329 3557
  * Probe PCI device
3330 3558
  *
@@ -3342,39 +3570,19 @@ static int hermon_probe ( struct pci_device *pci ) {
3342 3570
 	int rc;
3343 3571
 
3344 3572
 	/* Allocate Hermon device */
3345
-	hermon = zalloc ( sizeof ( *hermon ) );
3573
+	hermon = hermon_alloc();
3346 3574
 	if ( ! hermon ) {
3347 3575
 		rc = -ENOMEM;
3348
-		goto err_alloc_hermon;
3576
+		goto err_alloc;
3349 3577
 	}
3350 3578
 	pci_set_drvdata ( pci, hermon );
3351 3579
 
3352
-	/* Fix up PCI device */
3353
-	adjust_pci_device ( pci );
3354
-
3355
-	/* Get PCI BARs */
3356
-	hermon->config = ioremap ( pci_bar_start ( pci, HERMON_PCI_CONFIG_BAR),
3357
-				   HERMON_PCI_CONFIG_BAR_SIZE );
3358
-	hermon->uar = ioremap ( pci_bar_start ( pci, HERMON_PCI_UAR_BAR ),
3359
-				HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE );
3580
+	/* Initialise PCI parameters */
3581
+	hermon_pci_init ( hermon, pci );
3360 3582
 
3361 3583
 	/* Reset device */
3362 3584
 	hermon_reset ( hermon, pci );
3363 3585
 
3364
-	/* Allocate space for mailboxes */
3365
-	hermon->mailbox_in = malloc_dma ( HERMON_MBOX_SIZE,
3366
-					  HERMON_MBOX_ALIGN );
3367
-	if ( ! hermon->mailbox_in ) {
3368
-		rc = -ENOMEM;
3369
-		goto err_mailbox_in;
3370
-	}
3371
-	hermon->mailbox_out = malloc_dma ( HERMON_MBOX_SIZE,
3372
-					   HERMON_MBOX_ALIGN );
3373
-	if ( ! hermon->mailbox_out ) {
3374
-		rc = -ENOMEM;
3375
-		goto err_mailbox_out;
3376
-	}
3377
-
3378 3586
 	/* Start firmware */
3379 3587
 	if ( ( rc = hermon_start_firmware ( hermon ) ) != 0 )
3380 3588
 		goto err_start_firmware;
@@ -3483,12 +3691,8 @@ static int hermon_probe ( struct pci_device *pci ) {
3483 3691
  err_get_cap:
3484 3692
 	hermon_stop_firmware ( hermon );
3485 3693
  err_start_firmware:
3486
-	free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE );
3487
- err_mailbox_out:
3488
-	free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
3489
- err_mailbox_in:
3490
-	free ( hermon );
3491
- err_alloc_hermon:
3694
+	hermon_free ( hermon );
3695
+ err_alloc:
3492 3696
 	return rc;
3493 3697
 }
3494 3698
 
@@ -3511,15 +3715,65 @@ static void hermon_remove ( struct pci_device *pci ) {
3511 3715
 	hermon_free_icm ( hermon );
3512 3716
 	hermon_stop_firmware ( hermon );
3513 3717
 	hermon_stop_firmware ( hermon );
3514
-	free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE );
3515
-	free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
3516 3718
 	for ( i = ( hermon->cap.num_ports - 1 ) ; i >= 0 ; i-- ) {
3517 3719
 		netdev_nullify ( hermon->port[i].netdev );
3518 3720
 		netdev_put ( hermon->port[i].netdev );
3519 3721
 	}
3520 3722
 	for ( i = ( hermon->cap.num_ports - 1 ) ; i >= 0 ; i-- )
3521 3723
 		ibdev_put ( hermon->port[i].ibdev );
3522
-	free ( hermon );
3724
+	hermon_free ( hermon );
3725
+}
3726
+
3727
+/**
3728
+ * Probe PCI device for BOFM
3729
+ *
3730
+ * @v pci		PCI device
3731
+ * @v id		PCI ID
3732
+ * @ret rc		Return status code
3733
+ */
3734
+static int hermon_bofm_probe ( struct pci_device *pci ) {
3735
+	struct hermon *hermon;
3736
+	int rc;
3737
+
3738
+	/* Allocate Hermon device */
3739
+	hermon = hermon_alloc();
3740
+	if ( ! hermon ) {
3741
+		rc = -ENOMEM;
3742
+		goto err_alloc;
3743
+	}
3744
+	pci_set_drvdata ( pci, hermon );
3745
+
3746
+	/* Initialise PCI parameters */
3747
+	hermon_pci_init ( hermon, pci );
3748
+
3749
+	/* Initialise BOFM device */
3750
+	bofm_init ( &hermon->bofm, pci, &hermon_bofm_operations );
3751
+
3752
+	/* Register BOFM device */
3753
+	if ( ( rc = bofm_register ( &hermon->bofm ) ) != 0 ) {
3754
+		DBGC ( hermon, "Hermon %p could not register BOFM device: "
3755
+		       "%s\n", hermon, strerror ( rc ) );
3756
+		goto err_bofm_register;
3757
+	}
3758
+
3759
+	return 0;
3760
+
3761
+ err_bofm_register:
3762
+	hermon_free ( hermon );
3763
+ err_alloc:
3764
+	return rc;
3765
+}
3766
+
3767
+/**
3768
+ * Remove PCI device for BOFM
3769
+ *
3770
+ * @v pci		PCI device
3771
+ */
3772
+static void hermon_bofm_remove ( struct pci_device *pci ) {
3773
+	struct hermon *hermon = pci_get_drvdata ( pci );
3774
+
3775
+	bofm_unregister ( &hermon->bofm );
3776
+	hermon_free ( hermon );
3523 3777
 }
3524 3778
 
3525 3779
 static struct pci_device_id hermon_nics[] = {
@@ -3543,3 +3797,10 @@ struct pci_driver hermon_driver __pci_driver = {
3543 3797
 	.probe = hermon_probe,
3544 3798
 	.remove = hermon_remove,
3545 3799
 };
3800
+
3801
+struct pci_driver hermon_bofm_driver __bofm_driver = {
3802
+	.ids = hermon_nics,
3803
+	.id_count = ( sizeof ( hermon_nics ) / sizeof ( hermon_nics[0] ) ),
3804
+	.probe = hermon_bofm_probe,
3805
+	.remove = hermon_bofm_remove,
3806
+};

+ 17
- 8
src/drivers/infiniband/hermon.h View File

@@ -12,6 +12,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
12 12
 #include <stdint.h>
13 13
 #include <ipxe/uaccess.h>
14 14
 #include <ipxe/ib_packet.h>
15
+#include <ipxe/bofm.h>
15 16
 #include "mlx_bitops.h"
16 17
 #include "MT25408_PRM.h"
17 18
 
@@ -131,6 +132,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
131 132
 
132 133
 #define HERMON_RETRY_MAX		0x07
133 134
 
135
+#define HERMON_MOD_STAT_CFG_SET		0x01
136
+#define HERMON_MOD_STAT_CFG_QUERY	0x03
137
+
134 138
 /*
135 139
  * Datatypes that seem to be missing from the autogenerated documentation
136 140
  *
@@ -417,13 +421,14 @@ struct hermonprm_set_port_vlan_st {
417 421
 /* -------------- */
418 422
 } __attribute__ (( packed ));
419 423
 
420
-struct hermonprm_mod_stat_cfg_pf_net_boot_st {
421
-	pseudo_bit_t reserved1[0x0001c];
422
-	pseudo_bit_t pf_net_boot[0x00001];
423
-	pseudo_bit_t reserved2[0x00002];
424
-	pseudo_bit_t pf_net_boot_m[0x00001];
425
-/* -------------- */
426
-	pseudo_bit_t reserved0[0x00020];
424
+struct hermonprm_mod_stat_cfg_input_mod_st {
425
+	pseudo_bit_t offset[0x00008];
426
+	pseudo_bit_t portnum[0x00008];
427
+	pseudo_bit_t xnum[0x00004];
428
+	pseudo_bit_t linkspeed[0x00003];
429
+	pseudo_bit_t autoneg[0x00001];
430
+	pseudo_bit_t reserved[0x00004];
431
+	pseudo_bit_t setup_mode[0x00004];
427 432
 } __attribute__ (( packed ));
428 433
 
429 434
 /*
@@ -444,7 +449,8 @@ struct MLX_DECLARE_STRUCT ( hermonprm_init_hca );
444 449
 struct MLX_DECLARE_STRUCT ( hermonprm_mad_ifc );
445 450
 struct MLX_DECLARE_STRUCT ( hermonprm_mcg_entry );
446 451
 struct MLX_DECLARE_STRUCT ( hermonprm_mgm_hash );
447
-struct MLX_DECLARE_STRUCT ( hermonprm_mod_stat_cfg_pf_net_boot );
452
+struct MLX_DECLARE_STRUCT ( hermonprm_mod_stat_cfg );
453
+struct MLX_DECLARE_STRUCT ( hermonprm_mod_stat_cfg_input_mod );
448 454
 struct MLX_DECLARE_STRUCT ( hermonprm_mpt );
449 455
 struct MLX_DECLARE_STRUCT ( hermonprm_mtt );
450 456
 struct MLX_DECLARE_STRUCT ( hermonprm_port_state_change_event );
@@ -866,6 +872,9 @@ struct hermon {
866 872
 
867 873
 	/** Ports */
868 874
 	struct hermon_port port[HERMON_MAX_PORTS];
875
+
876
+	/** BOFM device */
877
+	struct bofm_device bofm;
869 878
 };
870 879
 
871 880
 /** Global protection domain */

Loading…
Cancel
Save