summaryrefslogtreecommitdiffstats
path: root/src/drivers/infiniband/hermon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/infiniband/hermon.c')
-rw-r--r--src/drivers/infiniband/hermon.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/drivers/infiniband/hermon.c b/src/drivers/infiniband/hermon.c
index bff128fd..b9c97f94 100644
--- a/src/drivers/infiniband/hermon.c
+++ b/src/drivers/infiniband/hermon.c
@@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <byteswap.h>
#include <gpxe/io.h>
#include <gpxe/pci.h>
+#include <gpxe/pcibackup.h>
#include <gpxe/malloc.h>
#include <gpxe/umalloc.h>
#include <gpxe/iobuf.h>
@@ -2551,6 +2552,25 @@ static int hermon_configure_special_qps ( struct hermon *hermon ) {
}
/**
+ * Reset device
+ *
+ * @v hermon Hermon device
+ * @v pci PCI device
+ */
+static void hermon_reset ( struct hermon *hermon,
+ struct pci_device *pci ) {
+ struct pci_config_backup backup;
+ static const uint8_t backup_exclude[] =
+ PCI_CONFIG_BACKUP_EXCLUDE ( 0x58, 0x5c );
+
+ pci_backup ( pci, &backup, backup_exclude );
+ writel ( HERMON_RESET_MAGIC,
+ ( hermon->config + HERMON_RESET_OFFSET ) );
+ mdelay ( HERMON_RESET_WAIT_TIME_MS );
+ pci_restore ( pci, &backup, backup_exclude );
+}
+
+/**
* Probe PCI device
*
* @v pci PCI device
@@ -2582,6 +2602,9 @@ static int hermon_probe ( struct pci_device *pci,
hermon->uar = ioremap ( pci_bar_start ( pci, HERMON_PCI_UAR_BAR ),
HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE );
+ /* Reset device */
+ hermon_reset ( hermon, pci );
+
/* Allocate space for mailboxes */
hermon->mailbox_in = malloc_dma ( HERMON_MBOX_SIZE,
HERMON_MBOX_ALIGN );