aboutsummaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2022-03-09 00:24:22 +0000
committerMichael Brown <mcb30@ipxe.org>2022-08-10 12:29:47 +0100
commitb4216fa5063e464a16361bba247d49e8620a2cf2 (patch)
treeeaace0ba01029bad3d32dbbbcef61e8a10d1aabd /src/drivers
parent1b61c2118ca54a8d9ad71cc402e7c9f6094f4ec6 (diff)
downloadipxe-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.c25
-rw-r--r--src/drivers/net/intelxl.h11
-rw-r--r--src/drivers/net/intelxlvf.c10
-rw-r--r--src/drivers/net/intelxlvf.h11
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