summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2019-04-24 17:47:16 +0200
committerMichael Brown2019-04-27 21:26:18 +0200
commit2dbd9c0a3ca37e90a7e570acec35f02e54bba4aa (patch)
tree1f81c74e8368ab724eb9070b8375be07442dc819
parent[intelxl] Allow for arbitrary placement of ring tail registers (diff)
downloadipxe-2dbd9c0a3ca37e90a7e570acec35f02e54bba4aa.tar.gz
ipxe-2dbd9c0a3ca37e90a7e570acec35f02e54bba4aa.tar.xz
ipxe-2dbd9c0a3ca37e90a7e570acec35f02e54bba4aa.zip
[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.c104
1 files 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
@@ -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 );
}
/**