mirror of https://github.com/ipxe/ipxe.git
[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>pull/1/head
parent
4175b778c2
commit
9f7141a1ce
|
@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||||
#include <byteswap.h>
|
#include <byteswap.h>
|
||||||
#include <gpxe/io.h>
|
#include <gpxe/io.h>
|
||||||
#include <gpxe/pci.h>
|
#include <gpxe/pci.h>
|
||||||
|
#include <gpxe/pcibackup.h>
|
||||||
#include <gpxe/malloc.h>
|
#include <gpxe/malloc.h>
|
||||||
#include <gpxe/umalloc.h>
|
#include <gpxe/umalloc.h>
|
||||||
#include <gpxe/iobuf.h>
|
#include <gpxe/iobuf.h>
|
||||||
|
@ -2550,6 +2551,25 @@ static int hermon_configure_special_qps ( struct hermon *hermon ) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
* Probe 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 = ioremap ( pci_bar_start ( pci, HERMON_PCI_UAR_BAR ),
|
||||||
HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE );
|
HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE );
|
||||||
|
|
||||||
|
/* Reset device */
|
||||||
|
hermon_reset ( hermon, pci );
|
||||||
|
|
||||||
/* Allocate space for mailboxes */
|
/* Allocate space for mailboxes */
|
||||||
hermon->mailbox_in = malloc_dma ( HERMON_MBOX_SIZE,
|
hermon->mailbox_in = malloc_dma ( HERMON_MBOX_SIZE,
|
||||||
HERMON_MBOX_ALIGN );
|
HERMON_MBOX_ALIGN );
|
||||||
|
|
|
@ -29,6 +29,11 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||||
#define HERMON_PCI_CONFIG_BAR_SIZE 0x100000
|
#define HERMON_PCI_CONFIG_BAR_SIZE 0x100000
|
||||||
#define HERMON_PCI_UAR_BAR PCI_BASE_ADDRESS_2
|
#define HERMON_PCI_UAR_BAR PCI_BASE_ADDRESS_2
|
||||||
|
|
||||||
|
/* Device reset */
|
||||||
|
#define HERMON_RESET_OFFSET 0x0f0010
|
||||||
|
#define HERMON_RESET_MAGIC 0x01000000UL
|
||||||
|
#define HERMON_RESET_WAIT_TIME_MS 1000
|
||||||
|
|
||||||
/* Work queue entry and completion queue entry opcodes */
|
/* Work queue entry and completion queue entry opcodes */
|
||||||
#define HERMON_OPCODE_NOP 0x00
|
#define HERMON_OPCODE_NOP 0x00
|
||||||
#define HERMON_OPCODE_SEND 0x0a
|
#define HERMON_OPCODE_SEND 0x0a
|
||||||
|
|
Loading…
Reference in New Issue