]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[intelxl] Allow for virtual function admin queue register maps
authorMichael Brown <mcb30@ipxe.org>
Fri, 22 Mar 2019 15:04:12 +0000 (15:04 +0000)
committerMichael Brown <mcb30@ipxe.org>
Sat, 27 Apr 2019 19:25:59 +0000 (20:25 +0100)
The register map for the virtual functions appears to have been
constructed using a random number generator.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/net/intelxl.c
src/drivers/net/intelxl.h

index 66221cbaffec623680aef733111dedba9bbc8a3f..1f0ca2c086fd3ae615bef3d22257fba21ca28a62 100644 (file)
@@ -123,6 +123,15 @@ static int intelxl_fetch_mac ( struct intelxl_nic *intelxl,
  ******************************************************************************
  */
 
+/** Admin queue register offsets */
+static const struct intelxl_admin_offsets intelxl_admin_offsets = {
+       .bal = INTELXL_ADMIN_BAL,
+       .bah = INTELXL_ADMIN_BAH,
+       .len = INTELXL_ADMIN_LEN,
+       .head = INTELXL_ADMIN_HEAD,
+       .tail = INTELXL_ADMIN_TAIL,
+};
+
 /**
  * Create admin queue
  *
@@ -133,7 +142,8 @@ static int intelxl_fetch_mac ( struct intelxl_nic *intelxl,
 static int intelxl_create_admin ( struct intelxl_nic *intelxl,
                                  struct intelxl_admin *admin ) {
        size_t len = ( sizeof ( admin->desc[0] ) * INTELXL_ADMIN_NUM_DESC );
-       void *admin_regs = ( intelxl->regs + admin->reg );
+       const struct intelxl_admin_offsets *regs = admin->regs;
+       void *admin_regs = ( intelxl->regs + admin->base );
        physaddr_t address;
 
        /* Allocate admin queue */
@@ -147,30 +157,30 @@ static int intelxl_create_admin ( struct intelxl_nic *intelxl,
        memset ( admin->desc, 0, len );
 
        /* Reset head and tail registers */
-       writel ( 0, admin_regs + INTELXL_ADMIN_HEAD );
-       writel ( 0, admin_regs + INTELXL_ADMIN_TAIL );
+       writel ( 0, admin_regs + regs->head );
+       writel ( 0, admin_regs + regs->tail );
 
        /* Reset queue index */
        admin->index = 0;
 
        /* Program queue address */
        address = virt_to_bus ( admin->desc );
-       writel ( ( address & 0xffffffffUL ), admin_regs + INTELXL_ADMIN_BAL );
+       writel ( ( address & 0xffffffffUL ), admin_regs + regs->bal );
        if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) ) {
                writel ( ( ( ( uint64_t ) address ) >> 32 ),
-                        admin_regs + INTELXL_ADMIN_BAH );
+                        admin_regs + regs->bah );
        } else {
-               writel ( 0, admin_regs + INTELXL_ADMIN_BAH );
+               writel ( 0, admin_regs + regs->bah );
        }
 
        /* Program queue length and enable queue */
        writel ( ( INTELXL_ADMIN_LEN_LEN ( INTELXL_ADMIN_NUM_DESC ) |
                   INTELXL_ADMIN_LEN_ENABLE ),
-                admin_regs + INTELXL_ADMIN_LEN );
+                admin_regs + regs->len );
 
        DBGC ( intelxl, "INTELXL %p A%cQ is at [%08llx,%08llx) buf "
               "[%08llx,%08llx)\n", intelxl,
-              ( ( admin->reg == INTELXL_ADMIN_CMD ) ? 'T' : 'R' ),
+              ( ( admin == &intelxl->command ) ? 'T' : 'R' ),
               ( ( unsigned long long ) address ),
               ( ( unsigned long long ) address + len ),
               ( ( unsigned long long ) virt_to_bus ( admin->buffer ) ),
@@ -188,10 +198,11 @@ static int intelxl_create_admin ( struct intelxl_nic *intelxl,
 static void intelxl_destroy_admin ( struct intelxl_nic *intelxl,
                                    struct intelxl_admin *admin ) {
        size_t len = ( sizeof ( admin->desc[0] ) * INTELXL_ADMIN_NUM_DESC );
-       void *admin_regs = ( intelxl->regs + admin->reg );
+       const struct intelxl_admin_offsets *regs = admin->regs;
+       void *admin_regs = ( intelxl->regs + admin->base );
 
        /* Disable queue */
-       writel ( 0, admin_regs + INTELXL_ADMIN_LEN );
+       writel ( 0, admin_regs + regs->len );
 
        /* Free queue */
        free_dma ( admin->desc, ( len + sizeof ( *admin->buffer ) ) );
@@ -207,7 +218,8 @@ static void intelxl_destroy_admin ( struct intelxl_nic *intelxl,
 static int intelxl_admin_command ( struct intelxl_nic *intelxl,
                                   struct intelxl_admin_descriptor *cmd ) {
        struct intelxl_admin *admin = &intelxl->command;
-       void *admin_regs = ( intelxl->regs + admin->reg );
+       const struct intelxl_admin_offsets *regs = admin->regs;
+       void *admin_regs = ( intelxl->regs + admin->base );
        struct intelxl_admin_descriptor *desc;
        uint64_t buffer;
        unsigned int index;
@@ -245,7 +257,7 @@ static int intelxl_admin_command ( struct intelxl_nic *intelxl,
 
        /* Post command descriptor */
        wmb();
-       writel ( tail, admin_regs + INTELXL_ADMIN_TAIL );
+       writel ( tail, admin_regs + regs->tail );
 
        /* Wait for completion */
        for ( i = 0 ; i < INTELXL_ADMIN_MAX_WAIT_MS ; i++ ) {
@@ -558,13 +570,14 @@ static int intelxl_admin_link ( struct net_device *netdev ) {
  */
 static void intelxl_refill_admin ( struct intelxl_nic *intelxl ) {
        struct intelxl_admin *admin = &intelxl->event;
-       void *admin_regs = ( intelxl->regs + admin->reg );
+       const struct intelxl_admin_offsets *regs = admin->regs;
+       void *admin_regs = ( intelxl->regs + admin->base );
        unsigned int tail;
 
        /* Update tail pointer */
        tail = ( ( admin->index + INTELXL_ADMIN_NUM_DESC - 1 ) %
                 INTELXL_ADMIN_NUM_DESC );
-       writel ( tail, admin_regs + INTELXL_ADMIN_TAIL );
+       writel ( tail, admin_regs + regs->tail );
 }
 
 /**
@@ -1383,8 +1396,10 @@ static int intelxl_probe ( struct pci_device *pci ) {
        netdev->dev = &pci->dev;
        memset ( intelxl, 0, sizeof ( *intelxl ) );
        intelxl->pf = PCI_FUNC ( pci->busdevfn );
-       intelxl_init_admin ( &intelxl->command, INTELXL_ADMIN_CMD );
-       intelxl_init_admin ( &intelxl->event, INTELXL_ADMIN_EVT );
+       intelxl_init_admin ( &intelxl->command, INTELXL_ADMIN_CMD,
+                            &intelxl_admin_offsets );
+       intelxl_init_admin ( &intelxl->event, INTELXL_ADMIN_EVT,
+                            &intelxl_admin_offsets );
        intelxl_init_ring ( &intelxl->tx, INTELXL_TX_NUM_DESC,
                            intelxl_context_tx );
        intelxl_init_ring ( &intelxl->rx, INTELXL_RX_NUM_DESC,
index fd3fc75b808851492e78dac834d7c3c51f9aad7d..138fc2ef0974841610ee2357257ef5b882c897dc 100644 (file)
@@ -53,6 +53,24 @@ struct intelxl_nic;
 /** Admin Queue Tail Register (offset) */
 #define INTELXL_ADMIN_TAIL 0x400
 
+/** Admin queue register offsets
+ *
+ * The physical and virtual function register maps have no discernible
+ * relationship.
+ */
+struct intelxl_admin_offsets {
+       /** Base Address Low Register offset */
+       unsigned int bal;
+       /** Base Address High Register offset */
+       unsigned int bah;
+       /** Length Register offset */
+       unsigned int len;
+       /** Head Register offset */
+       unsigned int head;
+       /** Tail Register offset */
+       unsigned int tail;
+};
+
 /** Admin queue data buffer command parameters */
 struct intelxl_admin_buffer_params {
        /** Reserved */
@@ -343,8 +361,10 @@ struct intelxl_admin {
        /** Queue index */
        unsigned int index;
 
-       /** Register block */
-       unsigned int reg;
+       /** Register block base */
+       unsigned int base;
+       /** Register offsets */
+       const struct intelxl_admin_offsets *regs;
        /** Data buffer */
        union intelxl_admin_buffer *buffer;
 };
@@ -353,12 +373,15 @@ struct intelxl_admin {
  * Initialise admin queue
  *
  * @v admin            Admin queue
- * @v reg              Register block
+ * @v base             Register block base
+ * @v regs             Register offsets
  */
 static inline __attribute__ (( always_inline )) void
-intelxl_init_admin ( struct intelxl_admin *admin, unsigned int reg ) {
+intelxl_init_admin ( struct intelxl_admin *admin, unsigned int base,
+                    const struct intelxl_admin_offsets *regs ) {
 
-       admin->reg = reg;
+       admin->base = base;
+       admin->regs = regs;
 }
 
 /** Number of admin queue descriptors */