Browse Source

[hermon] Reset device during probe()

Some systems will retry their boot sequence in the event of a boot
failure.  On these systems, the second and subsequent boot attempts
will fail to initialise the Hermon HCA.

Fix by resetting the HCA during probe().  This incurs a one-second
cost, but there seems to be no viable alternative.

Originally-fixed-by: Itay Gazit <itaygazit@gmail.com>
tags/v0.9.8
Michael Brown 14 years ago
parent
commit
9f7141a1ce
2 changed files with 28 additions and 0 deletions
  1. 23
    0
      src/drivers/infiniband/hermon.c
  2. 5
    0
      src/drivers/infiniband/hermon.h

+ 23
- 0
src/drivers/infiniband/hermon.c View File

@@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
29 29
 #include <byteswap.h>
30 30
 #include <gpxe/io.h>
31 31
 #include <gpxe/pci.h>
32
+#include <gpxe/pcibackup.h>
32 33
 #include <gpxe/malloc.h>
33 34
 #include <gpxe/umalloc.h>
34 35
 #include <gpxe/iobuf.h>
@@ -2550,6 +2551,25 @@ static int hermon_configure_special_qps ( struct hermon *hermon ) {
2550 2551
 	return 0;
2551 2552
 }
2552 2553
 
2554
+/**
2555
+ * Reset device
2556
+ *
2557
+ * @v hermon		Hermon device
2558
+ * @v pci		PCI device
2559
+ */
2560
+static void hermon_reset ( struct hermon *hermon,
2561
+			   struct pci_device *pci ) {
2562
+	struct pci_config_backup backup;
2563
+	static const uint8_t backup_exclude[] =
2564
+		PCI_CONFIG_BACKUP_EXCLUDE ( 0x58, 0x5c );
2565
+
2566
+	pci_backup ( pci, &backup, backup_exclude );
2567
+	writel ( HERMON_RESET_MAGIC,
2568
+		 ( hermon->config + HERMON_RESET_OFFSET ) );
2569
+	mdelay ( HERMON_RESET_WAIT_TIME_MS );
2570
+	pci_restore ( pci, &backup, backup_exclude );
2571
+}
2572
+
2553 2573
 /**
2554 2574
  * Probe PCI device
2555 2575
  *
@@ -2582,6 +2602,9 @@ static int hermon_probe ( struct pci_device *pci,
2582 2602
 	hermon->uar = ioremap ( pci_bar_start ( pci, HERMON_PCI_UAR_BAR ),
2583 2603
 				HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE );
2584 2604
 
2605
+	/* Reset device */
2606
+	hermon_reset ( hermon, pci );
2607
+
2585 2608
 	/* Allocate space for mailboxes */
2586 2609
 	hermon->mailbox_in = malloc_dma ( HERMON_MBOX_SIZE,
2587 2610
 					  HERMON_MBOX_ALIGN );

+ 5
- 0
src/drivers/infiniband/hermon.h View File

@@ -29,6 +29,11 @@ FILE_LICENCE ( GPL2_OR_LATER );
29 29
 #define HERMON_PCI_CONFIG_BAR_SIZE	0x100000
30 30
 #define HERMON_PCI_UAR_BAR		PCI_BASE_ADDRESS_2
31 31
 
32
+/* Device reset */
33
+#define HERMON_RESET_OFFSET		0x0f0010
34
+#define HERMON_RESET_MAGIC		0x01000000UL
35
+#define HERMON_RESET_WAIT_TIME_MS	1000
36
+
32 37
 /* Work queue entry and completion queue entry opcodes */
33 38
 #define HERMON_OPCODE_NOP		0x00
34 39
 #define HERMON_OPCODE_SEND		0x0a

Loading…
Cancel
Save