diff options
author | Michael Brown <mcb30@ipxe.org> | 2019-04-24 16:47:16 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2019-04-27 20:26:18 +0100 |
commit | 2dbd9c0a3ca37e90a7e570acec35f02e54bba4aa (patch) | |
tree | 1f81c74e8368ab724eb9070b8375be07442dc819 | |
parent | 9907fd54d358a993cbc389d6d956c1a2da923df9 (diff) | |
download | ipxe-2dbd9c0a3ca37e90a7e570acec35f02e54bba4aa.tar.gz |
[intelxl] Split out ring creation from context programming
The virtual function driver will use the same transmit and receive
descriptor ring structures, but will not itself construct and program
the ring context. Split out ring creation and destruction from the
programming of the ring context, to allow code to be shared between
physical and virtual function drivers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r-- | src/drivers/net/intelxl.c | 104 |
1 files changed, 76 insertions, 28 deletions
diff --git a/src/drivers/net/intelxl.c b/src/drivers/net/intelxl.c index ed6e64a6e..3e6f460ac 100644 --- a/src/drivers/net/intelxl.c +++ b/src/drivers/net/intelxl.c @@ -833,6 +833,62 @@ static void intelxl_close_admin ( struct intelxl_nic *intelxl ) { */ /** + * Allocate descriptor ring + * + * @v intelxl Intel device + * @v ring Descriptor ring + * @ret rc Return status code + */ +static int intelxl_alloc_ring ( struct intelxl_nic *intelxl, + struct intelxl_ring *ring ) { + physaddr_t address; + int rc; + + /* Allocate descriptor ring */ + ring->desc.raw = malloc_dma ( ring->len, INTELXL_ALIGN ); + if ( ! ring->desc.raw ) { + rc = -ENOMEM; + goto err_alloc; + } + address = virt_to_bus ( ring->desc.raw ); + + /* Initialise descriptor ring */ + memset ( ring->desc.raw, 0, ring->len ); + + /* Reset tail pointer */ + writel ( 0, ( intelxl->regs + ring->tail ) ); + + /* Reset counters */ + ring->prod = 0; + ring->cons = 0; + + DBGC ( intelxl, "INTELXL %p ring %06x is at [%08llx,%08llx)\n", + intelxl, ( ring->reg + ring->tail ), + ( ( unsigned long long ) address ), + ( ( unsigned long long ) address + ring->len ) ); + + return 0; + + free_dma ( ring->desc.raw, ring->len ); + err_alloc: + return rc; +} + +/** + * Free descriptor ring + * + * @v intelxl Intel device + * @v ring Descriptor ring + */ +static void intelxl_free_ring ( struct intelxl_nic *intelxl __unused, + struct intelxl_ring *ring ) { + + /* Free descriptor ring */ + free_dma ( ring->desc.raw, ring->len ); + ring->desc.raw = NULL; +} + +/** * Dump queue context (for debugging) * * @v intelxl Intel device @@ -1100,17 +1156,8 @@ static int intelxl_create_ring ( struct intelxl_nic *intelxl, int rc; /* Allocate descriptor ring */ - ring->desc.raw = malloc_dma ( ring->len, INTELXL_ALIGN ); - if ( ! ring->desc.raw ) { - rc = -ENOMEM; + if ( ( rc = intelxl_alloc_ring ( intelxl, ring ) ) != 0 ) goto err_alloc; - } - - /* Initialise descriptor ring */ - memset ( ring->desc.raw, 0, ring->len ); - - /* Reset tail pointer */ - writel ( 0, ( intelxl->regs + ring->tail ) ); /* Program queue context */ address = virt_to_bus ( ring->desc.raw ); @@ -1121,21 +1168,12 @@ static int intelxl_create_ring ( struct intelxl_nic *intelxl, if ( ( rc = intelxl_enable_ring ( intelxl, ring ) ) != 0 ) goto err_enable; - /* Reset counters */ - ring->prod = 0; - ring->cons = 0; - - DBGC ( intelxl, "INTELXL %p ring %06x is at [%08llx,%08llx)\n", - intelxl, ( ring->reg + ring->tail ), - ( ( unsigned long long ) address ), - ( ( unsigned long long ) address + ring->len ) ); - return 0; intelxl_disable_ring ( intelxl, ring ); err_enable: err_context: - free_dma ( ring->desc.raw, ring->len ); + intelxl_free_ring ( intelxl, ring ); err_alloc: return rc; } @@ -1157,8 +1195,7 @@ static void intelxl_destroy_ring ( struct intelxl_nic *intelxl, } /* Free descriptor ring */ - free_dma ( ring->desc.raw, ring->len ); - ring->desc.raw = NULL; + intelxl_free_ring ( intelxl, ring ); } /** @@ -1211,6 +1248,22 @@ static void intelxl_refill_rx ( struct intelxl_nic *intelxl ) { } } +/** + * Discard unused receive I/O buffers + * + * @v intelxl Intel device + */ +static void intelxl_empty_rx ( struct intelxl_nic *intelxl ) { + unsigned int i; + + /* Discard any unused receive buffers */ + for ( i = 0 ; i < INTELXL_RX_NUM_DESC ; i++ ) { + if ( intelxl->rx_iobuf[i] ) + free_iob ( intelxl->rx_iobuf[i] ); + intelxl->rx_iobuf[i] = NULL; + } +} + /****************************************************************************** * * Network device interface @@ -1297,7 +1350,6 @@ static int intelxl_open ( struct net_device *netdev ) { static void intelxl_close ( struct net_device *netdev ) { struct intelxl_nic *intelxl = netdev->priv; unsigned int queue; - unsigned int i; /* Dump contexts (for debugging) */ intelxl_context_dump ( intelxl, INTELXL_PFCM_LANCTXCTL_TYPE_TX, @@ -1319,11 +1371,7 @@ static void intelxl_close ( struct net_device *netdev ) { intelxl_destroy_ring ( intelxl, &intelxl->rx ); /* Discard any unused receive buffers */ - for ( i = 0 ; i < INTELXL_RX_NUM_DESC ; i++ ) { - if ( intelxl->rx_iobuf[i] ) - free_iob ( intelxl->rx_iobuf[i] ); - intelxl->rx_iobuf[i] = NULL; - } + intelxl_empty_rx ( intelxl ); } /** |