]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[intel] Update driver to use DMA API
authorMichael Brown <mcb30@ipxe.org>
Fri, 13 Nov 2020 19:55:22 +0000 (19:55 +0000)
committerMichael Brown <mcb30@ipxe.org>
Fri, 13 Nov 2020 19:55:22 +0000 (19:55 +0000)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/net/intel.c
src/drivers/net/intel.h
src/drivers/net/intelx.c
src/drivers/net/intelxvf.c

index 3a4e4341b36fc102c508d7754847c67d5e37ca44..4afe43938aff2797b3c594767219230efe3f402b 100644 (file)
@@ -32,7 +32,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/ethernet.h>
 #include <ipxe/if_ether.h>
 #include <ipxe/iobuf.h>
-#include <ipxe/malloc.h>
+#include <ipxe/dma.h>
 #include <ipxe/pci.h>
 #include <ipxe/profile.h>
 #include "intel.h"
@@ -504,7 +504,8 @@ int intel_create_ring ( struct intel_nic *intel, struct intel_ring *ring ) {
         * prevent any possible page-crossing errors due to hardware
         * errata.
         */
-       ring->desc = malloc_phys ( ring->len, ring->len );
+       ring->desc = dma_alloc ( intel->dma, ring->len, ring->len,
+                                &ring->map );
        if ( ! ring->desc )
                return -ENOMEM;
 
@@ -512,7 +513,7 @@ int intel_create_ring ( struct intel_nic *intel, struct intel_ring *ring ) {
        memset ( ring->desc, 0, ring->len );
 
        /* Program ring address */
-       address = virt_to_bus ( ring->desc );
+       address = ring->map.addr;
        writel ( ( address & 0xffffffffUL ),
                 ( intel->regs + ring->reg + INTEL_xDBAL ) );
        if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) ) {
@@ -553,7 +554,7 @@ void intel_destroy_ring ( struct intel_nic *intel, struct intel_ring *ring ) {
        intel_reset_ring ( intel, ring->reg );
 
        /* Free descriptor ring */
-       free_phys ( ring->desc, ring->len );
+       dma_free ( intel->dma, ring->desc, ring->len, &ring->map );
        ring->desc = NULL;
        ring->prod = 0;
        ring->cons = 0;
@@ -567,32 +568,36 @@ void intel_destroy_ring ( struct intel_nic *intel, struct intel_ring *ring ) {
 void intel_refill_rx ( struct intel_nic *intel ) {
        struct intel_descriptor *rx;
        struct io_buffer *iobuf;
+       struct dma_mapping *map;
        unsigned int rx_idx;
        unsigned int rx_tail;
        physaddr_t address;
        unsigned int refilled = 0;
 
        /* Refill ring */
-       while ( ( intel->rx.prod - intel->rx.cons ) < INTEL_RX_FILL ) {
+       while ( ( intel->rx.ring.prod -
+                 intel->rx.ring.cons ) < INTEL_RX_FILL ) {
+
+               /* Get next receive descriptor */
+               rx_idx = ( intel->rx.ring.prod % INTEL_NUM_RX_DESC );
+               rx = &intel->rx.ring.desc[rx_idx];
+               map = &intel->rx.map[rx_idx];
+               assert ( intel->rx.iobuf[rx_idx] == NULL );
 
                /* Allocate I/O buffer */
-               iobuf = alloc_iob ( INTEL_RX_MAX_LEN );
+               iobuf = dma_alloc_rx_iob ( intel->dma, INTEL_RX_MAX_LEN, map );
                if ( ! iobuf ) {
                        /* Wait for next refill */
                        break;
                }
+               intel->rx.iobuf[rx_idx] = iobuf;
 
-               /* Get next receive descriptor */
-               rx_idx = ( intel->rx.prod++ % INTEL_NUM_RX_DESC );
-               rx = &intel->rx.desc[rx_idx];
+               /* Update producer index */
+               intel->rx.ring.prod++;
 
                /* Populate receive descriptor */
-               address = virt_to_bus ( iobuf->data );
-               intel->rx.describe ( rx, address, 0 );
-
-               /* Record I/O buffer */
-               assert ( intel->rx_iobuf[rx_idx] == NULL );
-               intel->rx_iobuf[rx_idx] = iobuf;
+               address = map->addr;
+               intel->rx.ring.describe ( rx, address, 0 );
 
                DBGC2 ( intel, "INTEL %p RX %d is [%llx,%llx)\n", intel, rx_idx,
                        ( ( unsigned long long ) address ),
@@ -603,26 +608,40 @@ void intel_refill_rx ( struct intel_nic *intel ) {
        /* Push descriptors to card, if applicable */
        if ( refilled ) {
                wmb();
-               rx_tail = ( intel->rx.prod % INTEL_NUM_RX_DESC );
+               rx_tail = ( intel->rx.ring.prod % INTEL_NUM_RX_DESC );
                profile_start ( &intel_vm_refill_profiler );
-               writel ( rx_tail, intel->regs + intel->rx.reg + INTEL_xDT );
+               writel ( rx_tail,
+                        intel->regs + intel->rx.ring.reg + INTEL_xDT );
                profile_stop ( &intel_vm_refill_profiler );
                profile_exclude ( &intel_vm_refill_profiler );
        }
 }
 
 /**
- * Discard unused receive I/O buffers
+ * Flush unused I/O buffers
  *
  * @v intel            Intel device
+ *
+ * Discard any unused receive I/O buffers and unmap any incomplete
+ * transmit I/O buffers.
  */
-void intel_empty_rx ( struct intel_nic *intel ) {
+void intel_flush ( struct intel_nic *intel ) {
        unsigned int i;
+       unsigned int tx_idx;
 
+       /* Discard unused receive buffers */
        for ( i = 0 ; i < INTEL_NUM_RX_DESC ; i++ ) {
-               if ( intel->rx_iobuf[i] )
-                       free_iob ( intel->rx_iobuf[i] );
-               intel->rx_iobuf[i] = NULL;
+               if ( intel->rx.iobuf[i] ) {
+                       dma_unmap ( intel->dma, &intel->rx.map[i] );
+                       free_iob ( intel->rx.iobuf[i] );
+               }
+               intel->rx.iobuf[i] = NULL;
+       }
+
+       /* Unmap incomplete transmit buffers */
+       for ( i = intel->tx.ring.cons ; i != intel->tx.ring.prod ; i++ ) {
+               tx_idx = ( i % INTEL_NUM_TX_DESC );
+               dma_unmap ( intel->dma, &intel->tx.map[tx_idx] );
        }
 }
 
@@ -653,11 +672,11 @@ static int intel_open ( struct net_device *netdev ) {
        }
 
        /* Create transmit descriptor ring */
-       if ( ( rc = intel_create_ring ( intel, &intel->tx ) ) != 0 )
+       if ( ( rc = intel_create_ring ( intel, &intel->tx.ring ) ) != 0 )
                goto err_create_tx;
 
        /* Create receive descriptor ring */
-       if ( ( rc = intel_create_ring ( intel, &intel->rx ) ) != 0 )
+       if ( ( rc = intel_create_ring ( intel, &intel->rx.ring ) ) != 0 )
                goto err_create_rx;
 
        /* Program MAC address */
@@ -696,9 +715,9 @@ static int intel_open ( struct net_device *netdev ) {
 
        return 0;
 
-       intel_destroy_ring ( intel, &intel->rx );
+       intel_destroy_ring ( intel, &intel->rx.ring );
  err_create_rx:
-       intel_destroy_ring ( intel, &intel->tx );
+       intel_destroy_ring ( intel, &intel->tx.ring );
  err_create_tx:
        return rc;
 }
@@ -718,13 +737,13 @@ static void intel_close ( struct net_device *netdev ) {
        writel ( 0, intel->regs + INTEL_TCTL );
 
        /* Destroy receive descriptor ring */
-       intel_destroy_ring ( intel, &intel->rx );
+       intel_destroy_ring ( intel, &intel->rx.ring );
 
-       /* Discard any unused receive buffers */
-       intel_empty_rx ( intel );
+       /* Flush unused buffers */
+       intel_flush ( intel );
 
        /* Destroy transmit descriptor ring */
-       intel_destroy_ring ( intel, &intel->tx );
+       intel_destroy_ring ( intel, &intel->tx.ring );
 
        /* Reset the NIC, to flush the transmit and receive FIFOs */
        intel_reset ( intel );
@@ -740,29 +759,39 @@ static void intel_close ( struct net_device *netdev ) {
 int intel_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
        struct intel_nic *intel = netdev->priv;
        struct intel_descriptor *tx;
+       struct dma_mapping *map;
        unsigned int tx_idx;
        unsigned int tx_tail;
        physaddr_t address;
        size_t len;
+       int rc;
 
        /* Get next transmit descriptor */
-       if ( ( intel->tx.prod - intel->tx.cons ) >= INTEL_TX_FILL ) {
+       if ( ( intel->tx.ring.prod - intel->tx.ring.cons ) >= INTEL_TX_FILL ) {
                DBGC ( intel, "INTEL %p out of transmit descriptors\n", intel );
                return -ENOBUFS;
        }
-       tx_idx = ( intel->tx.prod++ % INTEL_NUM_TX_DESC );
-       tx_tail = ( intel->tx.prod % INTEL_NUM_TX_DESC );
-       tx = &intel->tx.desc[tx_idx];
+       tx_idx = ( intel->tx.ring.prod % INTEL_NUM_TX_DESC );
+       tx = &intel->tx.ring.desc[tx_idx];
+       map = &intel->tx.map[tx_idx];
+
+       /* Map I/O buffer */
+       if ( ( rc = dma_map_tx_iob ( intel->dma, iobuf, map ) ) != 0 )
+               return rc;
+
+       /* Update producer index */
+       intel->tx.ring.prod++;
 
        /* Populate transmit descriptor */
-       address = virt_to_bus ( iobuf->data );
+       address = map->addr;
        len = iob_len ( iobuf );
-       intel->tx.describe ( tx, address, len );
+       intel->tx.ring.describe ( tx, address, len );
        wmb();
 
        /* Notify card that there are packets ready to transmit */
        profile_start ( &intel_vm_tx_profiler );
-       writel ( tx_tail, intel->regs + intel->tx.reg + INTEL_xDT );
+       tx_tail = ( intel->tx.ring.prod % INTEL_NUM_TX_DESC );
+       writel ( tx_tail, intel->regs + intel->tx.ring.reg + INTEL_xDT );
        profile_stop ( &intel_vm_tx_profiler );
        profile_exclude ( &intel_vm_tx_profiler );
 
@@ -784,11 +813,11 @@ void intel_poll_tx ( struct net_device *netdev ) {
        unsigned int tx_idx;
 
        /* Check for completed packets */
-       while ( intel->tx.cons != intel->tx.prod ) {
+       while ( intel->tx.ring.cons != intel->tx.ring.prod ) {
 
                /* Get next transmit descriptor */
-               tx_idx = ( intel->tx.cons % INTEL_NUM_TX_DESC );
-               tx = &intel->tx.desc[tx_idx];
+               tx_idx = ( intel->tx.ring.cons % INTEL_NUM_TX_DESC );
+               tx = &intel->tx.ring.desc[tx_idx];
 
                /* Stop if descriptor is still in use */
                if ( ! ( tx->status & cpu_to_le32 ( INTEL_DESC_STATUS_DD ) ) )
@@ -796,9 +825,12 @@ void intel_poll_tx ( struct net_device *netdev ) {
 
                DBGC2 ( intel, "INTEL %p TX %d complete\n", intel, tx_idx );
 
+               /* Unmap I/O buffer */
+               dma_unmap ( intel->dma, &intel->tx.map[tx_idx] );
+
                /* Complete TX descriptor */
                netdev_tx_complete_next ( netdev );
-               intel->tx.cons++;
+               intel->tx.ring.cons++;
        }
 }
 
@@ -815,19 +847,22 @@ void intel_poll_rx ( struct net_device *netdev ) {
        size_t len;
 
        /* Check for received packets */
-       while ( intel->rx.cons != intel->rx.prod ) {
+       while ( intel->rx.ring.cons != intel->rx.ring.prod ) {
 
                /* Get next receive descriptor */
-               rx_idx = ( intel->rx.cons % INTEL_NUM_RX_DESC );
-               rx = &intel->rx.desc[rx_idx];
+               rx_idx = ( intel->rx.ring.cons % INTEL_NUM_RX_DESC );
+               rx = &intel->rx.ring.desc[rx_idx];
 
                /* Stop if descriptor is still in use */
                if ( ! ( rx->status & cpu_to_le32 ( INTEL_DESC_STATUS_DD ) ) )
                        return;
 
+               /* Unmap I/O buffer */
+               dma_unmap ( intel->dma, &intel->rx.map[rx_idx] );
+
                /* Populate I/O buffer */
-               iobuf = intel->rx_iobuf[rx_idx];
-               intel->rx_iobuf[rx_idx] = NULL;
+               iobuf = intel->rx.iobuf[rx_idx];
+               intel->rx.iobuf[rx_idx] = NULL;
                len = le16_to_cpu ( rx->length );
                iob_put ( iobuf, len );
 
@@ -842,7 +877,7 @@ void intel_poll_rx ( struct net_device *netdev ) {
                                intel, rx_idx, len );
                        netdev_rx ( netdev, iobuf );
                }
-               intel->rx.cons++;
+               intel->rx.ring.cons++;
        }
 }
 
@@ -948,11 +983,12 @@ static int intel_probe ( struct pci_device *pci ) {
        pci_set_drvdata ( pci, netdev );
        netdev->dev = &pci->dev;
        memset ( intel, 0, sizeof ( *intel ) );
+       intel->dma = &pci->dma;
        intel->port = PCI_FUNC ( pci->busdevfn );
        intel->flags = pci->id->driver_data;
-       intel_init_ring ( &intel->tx, INTEL_NUM_TX_DESC, INTEL_TD,
+       intel_init_ring ( &intel->tx.ring, INTEL_NUM_TX_DESC, INTEL_TD,
                          intel_describe_tx );
-       intel_init_ring ( &intel->rx, INTEL_NUM_RX_DESC, INTEL_RD,
+       intel_init_ring ( &intel->rx.ring, INTEL_NUM_RX_DESC, INTEL_RD,
                          intel_describe_rx );
 
        /* Fix up PCI device */
index 9d740efc3927f71363d763a8425e240d86ccedc8..731b5f225662f0ffc43a6e057358c487a1658c7c 100644 (file)
@@ -12,6 +12,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <stdint.h>
 #include <ipxe/if_ether.h>
 #include <ipxe/nvs.h>
+#include <ipxe/dma.h>
 
 /** Intel BAR size */
 #define INTEL_BAR_SIZE ( 128 * 1024 )
@@ -212,6 +213,8 @@ union intel_receive_address {
 struct intel_ring {
        /** Descriptors */
        struct intel_descriptor *desc;
+       /** Descriptor ring DMA mapping */
+       struct dma_mapping map;
        /** Producer index */
        unsigned int prod;
        /** Consumer index */
@@ -273,10 +276,30 @@ intel_init_mbox ( struct intel_mailbox *mbox, unsigned int ctrl,
        mbox->mem = mem;
 }
 
+/** Transmit ring */
+struct intel_tx_ring {
+       /** Descriptor ring */
+       struct intel_ring ring;
+       /** DMA mappings */
+       struct dma_mapping map[INTEL_NUM_TX_DESC];
+};
+
+/** Receive ring */
+struct intel_rx_ring {
+       /** Descriptor ring */
+       struct intel_ring ring;
+       /** I/O buffers */
+       struct io_buffer *iobuf[INTEL_NUM_RX_DESC];
+       /** DMA mappings */
+       struct dma_mapping map[INTEL_NUM_RX_DESC];
+};
+
 /** An Intel network card */
 struct intel_nic {
        /** Registers */
        void *regs;
+       /** DMA device */
+       struct dma_device *dma;
        /** Port number (for multi-port devices) */
        unsigned int port;
        /** Flags */
@@ -294,12 +317,10 @@ struct intel_nic {
        /** Mailbox */
        struct intel_mailbox mbox;
 
-       /** Transmit descriptor ring */
-       struct intel_ring tx;
-       /** Receive descriptor ring */
-       struct intel_ring rx;
-       /** Receive I/O buffers */
-       struct io_buffer *rx_iobuf[INTEL_NUM_RX_DESC];
+       /** Transmit ring */
+       struct intel_tx_ring tx;
+       /** Receive ring */
+       struct intel_rx_ring rx;
 };
 
 /** Driver flags */
@@ -328,14 +349,14 @@ static inline void intel_diag ( struct intel_nic *intel ) {
 
        DBGC ( intel, "INTEL %p TX %04x(%02x)/%04x(%02x) "
               "RX %04x(%02x)/%04x(%02x)\n", intel,
-              ( intel->tx.cons & 0xffff ),
-              readl ( intel->regs + intel->tx.reg + INTEL_xDH ),
-              ( intel->tx.prod & 0xffff ),
-              readl ( intel->regs + intel->tx.reg + INTEL_xDT ),
-              ( intel->rx.cons & 0xffff ),
-              readl ( intel->regs + intel->rx.reg + INTEL_xDH ),
-              ( intel->rx.prod & 0xffff ),
-              readl ( intel->regs + intel->rx.reg + INTEL_xDT ) );
+              ( intel->tx.ring.cons & 0xffff ),
+              readl ( intel->regs + intel->tx.ring.reg + INTEL_xDH ),
+              ( intel->tx.ring.prod & 0xffff ),
+              readl ( intel->regs + intel->tx.ring.reg + INTEL_xDT ),
+              ( intel->rx.ring.cons & 0xffff ),
+              readl ( intel->regs + intel->rx.ring.reg + INTEL_xDH ),
+              ( intel->rx.ring.prod & 0xffff ),
+              readl ( intel->regs + intel->rx.ring.reg + INTEL_xDT ) );
 }
 
 extern void intel_describe_tx ( struct intel_descriptor *tx,
@@ -350,7 +371,7 @@ extern int intel_create_ring ( struct intel_nic *intel,
 extern void intel_destroy_ring ( struct intel_nic *intel,
                                 struct intel_ring *ring );
 extern void intel_refill_rx ( struct intel_nic *intel );
-extern void intel_empty_rx ( struct intel_nic *intel );
+extern void intel_flush ( struct intel_nic *intel );
 extern int intel_transmit ( struct net_device *netdev,
                            struct io_buffer *iobuf );
 extern void intel_poll_tx ( struct net_device *netdev );
index 38e8467a9d760205104940a6e880b0666b8ef086..3fa68bb3c676b1ce783accf1917a619598eb0aa0 100644 (file)
@@ -32,7 +32,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/ethernet.h>
 #include <ipxe/if_ether.h>
 #include <ipxe/iobuf.h>
-#include <ipxe/malloc.h>
 #include <ipxe/pci.h>
 #include "intelx.h"
 
@@ -186,11 +185,11 @@ static int intelx_open ( struct net_device *netdev ) {
        int rc;
 
        /* Create transmit descriptor ring */
-       if ( ( rc = intel_create_ring ( intel, &intel->tx ) ) != 0 )
+       if ( ( rc = intel_create_ring ( intel, &intel->tx.ring ) ) != 0 )
                goto err_create_tx;
 
        /* Create receive descriptor ring */
-       if ( ( rc = intel_create_ring ( intel, &intel->rx ) ) != 0 )
+       if ( ( rc = intel_create_ring ( intel, &intel->rx.ring ) ) != 0 )
                goto err_create_rx;
 
        /* Program MAC address */
@@ -264,9 +263,9 @@ static int intelx_open ( struct net_device *netdev ) {
 
        return 0;
 
-       intel_destroy_ring ( intel, &intel->rx );
+       intel_destroy_ring ( intel, &intel->rx.ring );
  err_create_rx:
-       intel_destroy_ring ( intel, &intel->tx );
+       intel_destroy_ring ( intel, &intel->tx.ring );
  err_create_tx:
        return rc;
 }
@@ -292,13 +291,13 @@ static void intelx_close ( struct net_device *netdev ) {
        writel ( dmatxctl, intel->regs + INTELX_DMATXCTL );
 
        /* Destroy receive descriptor ring */
-       intel_destroy_ring ( intel, &intel->rx );
+       intel_destroy_ring ( intel, &intel->rx.ring );
 
-       /* Discard any unused receive buffers */
-       intel_empty_rx ( intel );
+       /* Flush unused buffers */
+       intel_flush ( intel );
 
        /* Destroy transmit descriptor ring */
-       intel_destroy_ring ( intel, &intel->tx );
+       intel_destroy_ring ( intel, &intel->tx.ring );
 
        /* Reset the NIC, to flush the transmit and receive FIFOs */
        intelx_reset ( intel );
@@ -395,10 +394,11 @@ static int intelx_probe ( struct pci_device *pci ) {
        pci_set_drvdata ( pci, netdev );
        netdev->dev = &pci->dev;
        memset ( intel, 0, sizeof ( *intel ) );
+       intel->dma = &pci->dma;
        intel->port = PCI_FUNC ( pci->busdevfn );
-       intel_init_ring ( &intel->tx, INTEL_NUM_TX_DESC, INTELX_TD,
+       intel_init_ring ( &intel->tx.ring, INTEL_NUM_TX_DESC, INTELX_TD,
                          intel_describe_tx );
-       intel_init_ring ( &intel->rx, INTEL_NUM_RX_DESC, INTELX_RD,
+       intel_init_ring ( &intel->rx.ring, INTEL_NUM_RX_DESC, INTELX_RD,
                          intel_describe_rx );
 
        /* Fix up PCI device */
index fef3024e9c307ff192a59727d8a261fa9c71003b..4941fc57bbd8a96c04e8ed5999a5a6a04bb44a78 100644 (file)
@@ -276,11 +276,11 @@ static int intelxvf_open ( struct net_device *netdev ) {
        }
 
        /* Create transmit descriptor ring */
-       if ( ( rc = intel_create_ring ( intel, &intel->tx ) ) != 0 )
+       if ( ( rc = intel_create_ring ( intel, &intel->tx.ring ) ) != 0 )
                goto err_create_tx;
 
        /* Create receive descriptor ring */
-       if ( ( rc = intel_create_ring ( intel, &intel->rx ) ) != 0 )
+       if ( ( rc = intel_create_ring ( intel, &intel->rx.ring ) ) != 0 )
                goto err_create_rx;
 
        /* Allocate interrupt vectors */
@@ -317,9 +317,9 @@ static int intelxvf_open ( struct net_device *netdev ) {
 
        return 0;
 
-       intel_destroy_ring ( intel, &intel->rx );
+       intel_destroy_ring ( intel, &intel->rx.ring );
  err_create_rx:
-       intel_destroy_ring ( intel, &intel->tx );
+       intel_destroy_ring ( intel, &intel->tx.ring );
  err_create_tx:
  err_mbox_set_mtu:
  err_mbox_set_mac:
@@ -337,13 +337,13 @@ static void intelxvf_close ( struct net_device *netdev ) {
        struct intel_nic *intel = netdev->priv;
 
        /* Destroy receive descriptor ring */
-       intel_destroy_ring ( intel, &intel->rx );
+       intel_destroy_ring ( intel, &intel->rx.ring );
 
-       /* Discard any unused receive buffers */
-       intel_empty_rx ( intel );
+       /* Flush unused buffers */
+       intel_flush ( intel );
 
        /* Destroy transmit descriptor ring */
-       intel_destroy_ring ( intel, &intel->tx );
+       intel_destroy_ring ( intel, &intel->tx.ring );
 
        /* Reset the function */
        intelxvf_reset ( intel );
@@ -446,10 +446,11 @@ static int intelxvf_probe ( struct pci_device *pci ) {
        pci_set_drvdata ( pci, netdev );
        netdev->dev = &pci->dev;
        memset ( intel, 0, sizeof ( *intel ) );
+       intel->dma = &pci->dma;
        intel_init_mbox ( &intel->mbox, INTELXVF_MBCTRL, INTELXVF_MBMEM );
-       intel_init_ring ( &intel->tx, INTEL_NUM_TX_DESC, INTELXVF_TD(0),
+       intel_init_ring ( &intel->tx.ring, INTEL_NUM_TX_DESC, INTELXVF_TD(0),
                          intel_describe_tx_adv );
-       intel_init_ring ( &intel->rx, INTEL_NUM_RX_DESC, INTELXVF_RD(0),
+       intel_init_ring ( &intel->rx.ring, INTEL_NUM_RX_DESC, INTELXVF_RD(0),
                          intel_describe_rx );
 
        /* Fix up PCI device */