From 2dbd9c0a3ca37e90a7e570acec35f02e54bba4aa Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Wed, 24 Apr 2019 16:47:16 +0100 Subject: [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 --- src/drivers/net/intelxl.c | 104 +++++++++++++++++++++++++++++++++------------- 1 file changed, 76 insertions(+), 28 deletions(-) diff --git a/src/drivers/net/intelxl.c b/src/drivers/net/intelxl.c index ed6e64a6..3e6f460a 100644 --- a/src/drivers/net/intelxl.c +++ b/src/drivers/net/intelxl.c @@ -832,6 +832,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) * @@ -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 ); } /** -- cgit v1.2.3-55-g7522