]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[pci] Generalise function-level reset mechanism
authorMichael Brown <mcb30@ipxe.org>
Mon, 8 Aug 2022 15:39:40 +0000 (16:39 +0100)
committerMichael Brown <mcb30@ipxe.org>
Mon, 8 Aug 2022 15:39:40 +0000 (16:39 +0100)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/bus/pciextra.c
src/drivers/net/intelxlvf.c
src/include/ipxe/pci.h

index 3082d8a3da514861ddda2cd18fb2dbfd0dbcdb51..23617bc9a6f16b48e31a4a6a3ff9eac5f88587c4 100644 (file)
@@ -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 );
+}
index 752de781593d74b917f8584abcd251b5c4b1bd28..b5957a53b62f9b30cbee0704a0c65ba7dec82f87 100644 (file)
@@ -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 );
index 933f485307dcd29e5e73ad950885c5aaeee83c91..bf6174c23e2b8c1b9041c817963c2991db67942d 100644 (file)
@@ -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