mirror of https://github.com/ipxe/ipxe.git
[pci] Generalise function-level reset mechanism
Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/697/head^2
parent
9dfcdc04c8
commit
0965cec53c
|
@ -1,6 +1,7 @@
|
|||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ipxe/timer.h>
|
||||
#include <ipxe/pci.h>
|
||||
|
||||
static int pci_find_capability_common ( struct pci_device *pci,
|
||||
|
@ -112,3 +113,24 @@ unsigned long pci_bar_size ( struct pci_device *pci, unsigned int reg ) {
|
|||
size = size & ~( size - 1 );
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform PCI Express function-level reset (FLR)
|
||||
*
|
||||
* @v pci PCI device
|
||||
* @v exp PCI Express Capability address
|
||||
*/
|
||||
void pci_reset ( struct pci_device *pci, unsigned int exp ) {
|
||||
uint16_t control;
|
||||
|
||||
/* Perform a PCIe function-level reset */
|
||||
pci_read_config_word ( pci, ( exp + PCI_EXP_DEVCTL ), &control );
|
||||
control |= PCI_EXP_DEVCTL_FLR;
|
||||
pci_write_config_word ( pci, ( exp + PCI_EXP_DEVCTL ), control );
|
||||
|
||||
/* Allow time for reset to complete */
|
||||
mdelay ( PCI_EXP_FLR_DELAY_MS );
|
||||
|
||||
/* Re-enable device */
|
||||
adjust_pci_device ( pci );
|
||||
}
|
||||
|
|
|
@ -45,23 +45,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
******************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reset hardware via PCIe function-level reset
|
||||
*
|
||||
* @v intelxl Intel device
|
||||
*/
|
||||
static void intelxlvf_reset_flr ( struct intelxl_nic *intelxl,
|
||||
struct pci_device *pci ) {
|
||||
uint16_t control;
|
||||
|
||||
/* Perform a PCIe function-level reset */
|
||||
pci_read_config_word ( pci, ( intelxl->exp + PCI_EXP_DEVCTL ),
|
||||
&control );
|
||||
pci_write_config_word ( pci, ( intelxl->exp + PCI_EXP_DEVCTL ),
|
||||
( control | PCI_EXP_DEVCTL_FLR ) );
|
||||
mdelay ( INTELXL_RESET_DELAY_MS );
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for admin event queue to be torn down
|
||||
*
|
||||
|
@ -637,7 +620,7 @@ static int intelxlvf_probe ( struct pci_device *pci ) {
|
|||
}
|
||||
|
||||
/* Reset the function via PCIe FLR */
|
||||
intelxlvf_reset_flr ( intelxl, pci );
|
||||
pci_reset ( pci, intelxl->exp );
|
||||
|
||||
/* Enable MSI-X dummy interrupt */
|
||||
if ( ( rc = intelxl_msix_enable ( intelxl, pci ) ) != 0 )
|
||||
|
@ -669,7 +652,7 @@ static int intelxlvf_probe ( struct pci_device *pci ) {
|
|||
err_open_admin:
|
||||
intelxl_msix_disable ( intelxl, pci );
|
||||
err_msix:
|
||||
intelxlvf_reset_flr ( intelxl, pci );
|
||||
pci_reset ( pci, intelxl->exp );
|
||||
err_exp:
|
||||
iounmap ( intelxl->regs );
|
||||
err_ioremap:
|
||||
|
@ -701,7 +684,7 @@ static void intelxlvf_remove ( struct pci_device *pci ) {
|
|||
intelxl_msix_disable ( intelxl, pci );
|
||||
|
||||
/* Reset the function via PCIe FLR */
|
||||
intelxlvf_reset_flr ( intelxl, pci );
|
||||
pci_reset ( pci, intelxl->exp );
|
||||
|
||||
/* Free network device */
|
||||
iounmap ( intelxl->regs );
|
||||
|
|
|
@ -309,6 +309,7 @@ extern int pci_find_capability ( struct pci_device *pci, int capability );
|
|||
extern int pci_find_next_capability ( struct pci_device *pci,
|
||||
int pos, int capability );
|
||||
extern unsigned long pci_bar_size ( struct pci_device *pci, unsigned int reg );
|
||||
extern void pci_reset ( struct pci_device *pci, unsigned int exp );
|
||||
|
||||
/**
|
||||
* Initialise PCI device
|
||||
|
|
Loading…
Reference in New Issue