]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[intelxl] Use non-zero MSI-X vector for virtual function interrupts
authorMichael Brown <mcb30@ipxe.org>
Wed, 9 Mar 2022 00:24:22 +0000 (00:24 +0000)
committerMichael Brown <mcb30@ipxe.org>
Wed, 10 Aug 2022 11:29:47 +0000 (12:29 +0100)
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>
src/drivers/net/intelxl.c
src/drivers/net/intelxl.h
src/drivers/net/intelxlvf.c
src/drivers/net/intelxlvf.h

index 20db51acf737ae721dd365443e7c53c946b61a04..a7fbd60f950a7c18c37ae6f4d0587af47abd6ad4 100644 (file)
@@ -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 );
index f3588bd34abcb46df55f9ae6500814bba5e05eba..92d7f88824e6281a19b7786202151ecce064a739 100644 (file)
@@ -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 *
index d9922a7c645b0af54e45d018f4c8f544eb4f66d0..7dedf0f71b81b7e8fbfc98dc34b36276adc9fdec 100644 (file)
@@ -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 );
index cf449a744df73495069ac56ebd600b09207833b3..58ade11e96b552bd1efdafc687a04fa8d257684a 100644 (file)
@@ -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