summaryrefslogtreecommitdiffstats
path: root/src/drivers/net/netfront.h
diff options
context:
space:
mode:
authorMichael Brown2014-07-29 00:39:28 +0200
committerMichael Brown2014-07-29 16:57:56 +0200
commit793a806611f5a7b3a404afb27c837a3da381952e (patch)
tree7b3936a05873097850052e6a6f4b4dd30afb4a0e /src/drivers/net/netfront.h
parent[xen] Add basic support for PV-HVM domains (diff)
downloadipxe-793a806611f5a7b3a404afb27c837a3da381952e.tar.gz
ipxe-793a806611f5a7b3a404afb27c837a3da381952e.tar.xz
ipxe-793a806611f5a7b3a404afb27c837a3da381952e.zip
[xen] Add support for Xen netfront virtual NICs
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/net/netfront.h')
-rw-r--r--src/drivers/net/netfront.h153
1 files changed, 153 insertions, 0 deletions
diff --git a/src/drivers/net/netfront.h b/src/drivers/net/netfront.h
new file mode 100644
index 00000000..b3f899f3
--- /dev/null
+++ b/src/drivers/net/netfront.h
@@ -0,0 +1,153 @@
+#ifndef _NETFRONT_H
+#define _NETFRONT_H
+
+/** @file
+ *
+ * Xen netfront driver
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <ipxe/xen.h>
+#include <xen/io/netif.h>
+
+/** Number of transmit ring entries */
+#define NETFRONT_NUM_TX_DESC 16
+
+/** Number of receive ring entries */
+#define NETFRONT_NUM_RX_DESC 8
+
+/** Grant reference indices */
+enum netfront_ref_index {
+ /** Transmit ring grant reference index */
+ NETFRONT_REF_TX_RING = 0,
+ /** Transmit descriptor grant reference base index */
+ NETFRONT_REF_TX_BASE,
+ /** Receive ring grant reference index */
+ NETFRONT_REF_RX_RING = ( NETFRONT_REF_TX_BASE + NETFRONT_NUM_TX_DESC ),
+ /** Receive descriptor grant reference base index */
+ NETFRONT_REF_RX_BASE,
+ /** Total number of grant references required */
+ NETFRONT_REF_COUNT = ( NETFRONT_REF_RX_BASE + NETFRONT_NUM_RX_DESC )
+};
+
+/** A netfront descriptor ring */
+struct netfront_ring {
+ /** Shared ring */
+ union {
+ /** Transmit shared ring */
+ netif_tx_sring_t *tx;
+ /** Receive shared ring */
+ netif_rx_sring_t *rx;
+ /** Raw pointer */
+ void *raw;
+ } sring;
+ /** Shared ring grant reference key */
+ const char *ref_key;
+ /** Shared ring grant reference */
+ grant_ref_t ref;
+
+ /** Maximum number of used descriptors */
+ size_t count;
+ /** I/O buffers, indexed by buffer ID */
+ struct io_buffer **iobufs;
+ /** I/O buffer grant references, indexed by buffer ID */
+ grant_ref_t *refs;
+
+ /** Buffer ID ring */
+ uint8_t *ids;
+ /** Buffer ID ring producer counter */
+ unsigned int id_prod;
+ /** Buffer ID ring consumer counter */
+ unsigned int id_cons;
+};
+
+/**
+ * Initialise descriptor ring
+ *
+ * @v ring Descriptor ring
+ * @v ref_key Shared ring grant reference key
+ * @v ref Shared ring grant reference
+ * @v count Maxium number of used descriptors
+ * @v iobufs I/O buffers
+ * @v refs I/O buffer grant references
+ * @v ids Buffer IDs
+ */
+static inline __attribute__ (( always_inline )) void
+netfront_init_ring ( struct netfront_ring *ring, const char *ref_key,
+ grant_ref_t ref, unsigned int count,
+ struct io_buffer **iobufs, grant_ref_t *refs,
+ uint8_t *ids ) {
+
+ ring->ref_key = ref_key;
+ ring->ref = ref;
+ ring->count = count;
+ ring->iobufs = iobufs;
+ ring->refs = refs;
+ ring->ids = ids;
+}
+
+/**
+ * Check whether or not descriptor ring is full
+ *
+ * @v ring Descriptor ring
+ * @v is_full Ring is full
+ */
+static inline __attribute__ (( always_inline )) int
+netfront_ring_is_full ( struct netfront_ring *ring ) {
+ unsigned int fill_level;
+
+ fill_level = ( ring->id_prod - ring->id_cons );
+ assert ( fill_level <= ring->count );
+ return ( fill_level >= ring->count );
+}
+
+/**
+ * Check whether or not descriptor ring is empty
+ *
+ * @v ring Descriptor ring
+ * @v is_empty Ring is empty
+ */
+static inline __attribute__ (( always_inline )) int
+netfront_ring_is_empty ( struct netfront_ring *ring ) {
+
+ return ( ring->id_prod == ring->id_cons );
+}
+
+/** A netfront NIC */
+struct netfront_nic {
+ /** Xen device */
+ struct xen_device *xendev;
+ /** Grant references */
+ grant_ref_t refs[NETFRONT_REF_COUNT];
+
+ /** Transmit ring */
+ struct netfront_ring tx;
+ /** Transmit front ring */
+ netif_tx_front_ring_t tx_fring;
+ /** Transmit I/O buffers */
+ struct io_buffer *tx_iobufs[NETFRONT_NUM_TX_DESC];
+ /** Transmit I/O buffer IDs */
+ uint8_t tx_ids[NETFRONT_NUM_TX_DESC];
+
+ /** Receive ring */
+ struct netfront_ring rx;
+ /** Receive front ring */
+ netif_rx_front_ring_t rx_fring;
+ /** Receive I/O buffers */
+ struct io_buffer *rx_iobufs[NETFRONT_NUM_RX_DESC];
+ /** Receive I/O buffer IDs */
+ uint8_t rx_ids[NETFRONT_NUM_RX_DESC];
+
+ /** Event channel */
+ struct evtchn_send event;
+};
+
+/** Transmit shared ring field */
+#define tx_sring tx.sring.tx
+
+/** Receive shared ring field */
+#define rx_sring rx.sring.rx
+
+#endif /* _NETFRONT_H */