diff options
author | Michael Brown <mcb30@ipxe.org> | 2022-03-09 00:24:22 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2022-08-10 12:29:47 +0100 |
commit | b4216fa5063e464a16361bba247d49e8620a2cf2 (patch) | |
tree | eaace0ba01029bad3d32dbbbcef61e8a10d1aabd /src/drivers | |
parent | 1b61c2118ca54a8d9ad71cc402e7c9f6094f4ec6 (diff) | |
download | ipxe-b4216fa5063e464a16361bba247d49e8620a2cf2.zip ipxe-b4216fa5063e464a16361bba247d49e8620a2cf2.tar.gz ipxe-b4216fa5063e464a16361bba247d49e8620a2cf2.tar.bz2 |
[intelxl] Use non-zero MSI-X vector for virtual function interrupts
The 100 Gigabit physical function driver requires a virtual function
driver to request that transmit and receive queues are mapped to MSI-X
vector 1 or higher.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers')
-rw-r--r-- | src/drivers/net/intelxl.c | 25 | ||||
-rw-r--r-- | src/drivers/net/intelxl.h | 11 | ||||
-rw-r--r-- | src/drivers/net/intelxlvf.c | 10 | ||||
-rw-r--r-- | src/drivers/net/intelxlvf.h | 11 |
4 files changed, 39 insertions, 18 deletions
diff --git a/src/drivers/net/intelxl.c b/src/drivers/net/intelxl.c index 20db51a..a7fbd60 100644 --- a/src/drivers/net/intelxl.c +++ b/src/drivers/net/intelxl.c @@ -104,10 +104,11 @@ static int intelxl_fetch_mac ( struct intelxl_nic *intelxl, * * @v intelxl Intel device * @v pci PCI device + * @v vector MSI-X vector * @ret rc Return status code */ int intelxl_msix_enable ( struct intelxl_nic *intelxl, - struct pci_device *pci ) { + struct pci_device *pci, unsigned int vector ) { int rc; /* Map dummy target location */ @@ -126,12 +127,12 @@ int intelxl_msix_enable ( struct intelxl_nic *intelxl, goto err_enable; } - /* Configure interrupt zero to write to dummy location */ - pci_msix_map ( &intelxl->msix.cap, 0, + /* Configure interrupt to write to dummy location */ + pci_msix_map ( &intelxl->msix.cap, vector, dma ( &intelxl->msix.map, &intelxl->msix.msg ), 0 ); - /* Enable dummy interrupt zero */ - pci_msix_unmask ( &intelxl->msix.cap, 0 ); + /* Enable dummy interrupt */ + pci_msix_unmask ( &intelxl->msix.cap, vector ); return 0; @@ -147,12 +148,13 @@ int intelxl_msix_enable ( struct intelxl_nic *intelxl, * * @v intelxl Intel device * @v pci PCI device + * @v vector MSI-X vector */ void intelxl_msix_disable ( struct intelxl_nic *intelxl, - struct pci_device *pci ) { + struct pci_device *pci, unsigned int vector ) { - /* Disable dummy interrupt zero */ - pci_msix_mask ( &intelxl->msix.cap, 0 ); + /* Disable dummy interrupts */ + pci_msix_mask ( &intelxl->msix.cap, vector ); /* Disable MSI-X capability */ pci_msix_disable ( pci, &intelxl->msix.cap ); @@ -1707,7 +1709,8 @@ static int intelxl_probe ( struct pci_device *pci ) { goto err_fetch_mac; /* Enable MSI-X dummy interrupt */ - if ( ( rc = intelxl_msix_enable ( intelxl, pci ) ) != 0 ) + if ( ( rc = intelxl_msix_enable ( intelxl, pci, + INTELXL_MSIX_VECTOR ) ) != 0 ) goto err_msix; /* Open admin queues */ @@ -1767,7 +1770,7 @@ static int intelxl_probe ( struct pci_device *pci ) { err_admin_clear_pxe: intelxl_close_admin ( intelxl ); err_open_admin: - intelxl_msix_disable ( intelxl, pci ); + intelxl_msix_disable ( intelxl, pci, INTELXL_MSIX_VECTOR ); err_msix: err_fetch_mac: pci_reset ( pci, intelxl->exp ); @@ -1796,7 +1799,7 @@ static void intelxl_remove ( struct pci_device *pci ) { intelxl_close_admin ( intelxl ); /* Disable MSI-X dummy interrupt */ - intelxl_msix_disable ( intelxl, pci ); + intelxl_msix_disable ( intelxl, pci, INTELXL_MSIX_VECTOR ); /* Reset the NIC */ pci_reset ( pci, intelxl->exp ); diff --git a/src/drivers/net/intelxl.h b/src/drivers/net/intelxl.h index f3588bd..92d7f88 100644 --- a/src/drivers/net/intelxl.h +++ b/src/drivers/net/intelxl.h @@ -1035,7 +1035,10 @@ struct intelxl_msix { struct dma_mapping map; }; -/** An Intel 40Gigabit network card */ +/** MSI-X interrupt vector */ +#define INTELXL_MSIX_VECTOR 0 + +/** An Intel 40 Gigabit network card */ struct intelxl_nic { /** Registers */ void *regs; @@ -1084,9 +1087,11 @@ struct intelxl_nic { }; extern int intelxl_msix_enable ( struct intelxl_nic *intelxl, - struct pci_device *pci ); + struct pci_device *pci, + unsigned int vector ); extern void intelxl_msix_disable ( struct intelxl_nic *intelxl, - struct pci_device *pci ); + struct pci_device *pci, + unsigned int vector ); extern struct intelxl_admin_descriptor * intelxl_admin_command_descriptor ( struct intelxl_nic *intelxl ); extern union intelxl_admin_buffer * diff --git a/src/drivers/net/intelxlvf.c b/src/drivers/net/intelxlvf.c index d9922a7..7dedf0f 100644 --- a/src/drivers/net/intelxlvf.c +++ b/src/drivers/net/intelxlvf.c @@ -399,6 +399,7 @@ static int intelxlvf_admin_irq_map ( struct net_device *netdev ) { buf = intelxl_admin_command_buffer ( intelxl ); buf->irq.count = cpu_to_le16 ( 1 ); buf->irq.vsi = cpu_to_le16 ( intelxl->vsi ); + buf->irq.vec = cpu_to_le16 ( INTELXLVF_MSIX_VECTOR ); buf->irq.rxmap = cpu_to_le16 ( 0x0001 ); buf->irq.txmap = cpu_to_le16 ( 0x0001 ); @@ -583,7 +584,7 @@ static int intelxlvf_probe ( struct pci_device *pci ) { pci_set_drvdata ( pci, netdev ); netdev->dev = &pci->dev; memset ( intelxl, 0, sizeof ( *intelxl ) ); - intelxl->intr = INTELXLVF_VFINT_DYN_CTL0; + intelxl->intr = INTELXLVF_VFINT_DYN_CTLN ( INTELXLVF_MSIX_VECTOR ); intelxl_init_admin ( &intelxl->command, INTELXLVF_ADMIN, &intelxlvf_admin_command_offsets ); intelxl_init_admin ( &intelxl->event, INTELXLVF_ADMIN, @@ -623,7 +624,8 @@ static int intelxlvf_probe ( struct pci_device *pci ) { pci_reset ( pci, intelxl->exp ); /* Enable MSI-X dummy interrupt */ - if ( ( rc = intelxl_msix_enable ( intelxl, pci ) ) != 0 ) + if ( ( rc = intelxl_msix_enable ( intelxl, pci, + INTELXLVF_MSIX_VECTOR ) ) != 0 ) goto err_msix; /* Open admin queues */ @@ -650,7 +652,7 @@ static int intelxlvf_probe ( struct pci_device *pci ) { err_reset_admin: intelxl_close_admin ( intelxl ); err_open_admin: - intelxl_msix_disable ( intelxl, pci ); + intelxl_msix_disable ( intelxl, pci, INTELXLVF_MSIX_VECTOR ); err_msix: pci_reset ( pci, intelxl->exp ); err_exp: @@ -681,7 +683,7 @@ static void intelxlvf_remove ( struct pci_device *pci ) { intelxl_close_admin ( intelxl ); /* Disable MSI-X dummy interrupt */ - intelxl_msix_disable ( intelxl, pci ); + intelxl_msix_disable ( intelxl, pci, INTELXLVF_MSIX_VECTOR ); /* Reset the function via PCIe FLR */ pci_reset ( pci, intelxl->exp ); diff --git a/src/drivers/net/intelxlvf.h b/src/drivers/net/intelxlvf.h index cf449a7..58ade11 100644 --- a/src/drivers/net/intelxlvf.h +++ b/src/drivers/net/intelxlvf.h @@ -14,12 +14,23 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** BAR size */ #define INTELXLVF_BAR_SIZE 0x10000 +/** MSI-X vector + * + * The 100 Gigabit physical function driver requires a virtual + * function driver to request that transmit and receive queues are + * mapped to MSI-X vector 1 or higher. + */ +#define INTELXLVF_MSIX_VECTOR 1 + /** Transmit Queue Tail Register */ #define INTELXLVF_QTX_TAIL 0x00000 /** Receive Queue Tail Register */ #define INTELXLVF_QRX_TAIL 0x02000 +/** VF Interrupt N Dynamic Control Register */ +#define INTELXLVF_VFINT_DYN_CTLN( x ) ( 0x3800 + ( 0x4 * ( (x) - 1 ) ) ) + /** VF Interrupt Zero Dynamic Control Register */ #define INTELXLVF_VFINT_DYN_CTL0 0x5c00 |