iPXE
netfront.h
Go to the documentation of this file.
00001 #ifndef _NETFRONT_H
00002 #define _NETFRONT_H
00003 
00004 /** @file
00005  *
00006  * Xen netfront driver
00007  *
00008  */
00009 
00010 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00011 
00012 #include <ipxe/xen.h>
00013 #include <xen/io/netif.h>
00014 
00015 /** Number of transmit ring entries */
00016 #define NETFRONT_NUM_TX_DESC 16
00017 
00018 /** Number of receive ring entries */
00019 #define NETFRONT_NUM_RX_DESC 32
00020 
00021 /** Receive ring fill level
00022  *
00023  * The xen-netback driver from kernels 3.18 to 4.2 inclusive have a
00024  * bug (CA-163395) which prevents packet reception if fewer than 18
00025  * receive descriptors are available.  This was fixed in upstream
00026  * kernel commit d5d4852 ("xen-netback: require fewer guest Rx slots
00027  * when not using GSO").
00028  *
00029  * We provide 18 receive descriptors to avoid unpleasant silent
00030  * failures on these kernel versions.
00031  */
00032 #define NETFRONT_RX_FILL 18
00033 
00034 /** Grant reference indices */
00035 enum netfront_ref_index {
00036         /** Transmit ring grant reference index */
00037         NETFRONT_REF_TX_RING = 0,
00038         /** Transmit descriptor grant reference base index */
00039         NETFRONT_REF_TX_BASE,
00040         /** Receive ring grant reference index */
00041         NETFRONT_REF_RX_RING = ( NETFRONT_REF_TX_BASE + NETFRONT_NUM_TX_DESC ),
00042         /** Receive descriptor grant reference base index */
00043         NETFRONT_REF_RX_BASE,
00044         /** Total number of grant references required */
00045         NETFRONT_REF_COUNT = ( NETFRONT_REF_RX_BASE + NETFRONT_NUM_RX_DESC )
00046 };
00047 
00048 /** A netfront descriptor ring */
00049 struct netfront_ring {
00050         /** Shared ring */
00051         union {
00052                 /** Transmit shared ring */
00053                 netif_tx_sring_t *tx;
00054                 /** Receive shared ring */
00055                 netif_rx_sring_t *rx;
00056                 /** Raw pointer */
00057                 void *raw;
00058         } sring;
00059         /** Shared ring grant reference key */
00060         const char *ref_key;
00061         /** Shared ring grant reference */
00062         grant_ref_t ref;
00063 
00064         /** Maximum number of used descriptors */
00065         size_t count;
00066         /** I/O buffers, indexed by buffer ID */
00067         struct io_buffer **iobufs;
00068         /** I/O buffer grant references, indexed by buffer ID */
00069         grant_ref_t *refs;
00070 
00071         /** Buffer ID ring */
00072         uint8_t *ids;
00073         /** Buffer ID ring producer counter */
00074         unsigned int id_prod;
00075         /** Buffer ID ring consumer counter */
00076         unsigned int id_cons;
00077 };
00078 
00079 /**
00080  * Initialise descriptor ring
00081  *
00082  * @v ring              Descriptor ring
00083  * @v ref_key           Shared ring grant reference key
00084  * @v ref               Shared ring grant reference
00085  * @v count             Maxium number of used descriptors
00086  * @v iobufs            I/O buffers
00087  * @v refs              I/O buffer grant references
00088  * @v ids               Buffer IDs
00089  */
00090 static inline __attribute__ (( always_inline )) void
00091 netfront_init_ring ( struct netfront_ring *ring, const char *ref_key,
00092                      grant_ref_t ref, unsigned int count,
00093                      struct io_buffer **iobufs, grant_ref_t *refs,
00094                      uint8_t *ids ) {
00095 
00096         ring->ref_key = ref_key;
00097         ring->ref = ref;
00098         ring->count = count;
00099         ring->iobufs = iobufs;
00100         ring->refs = refs;
00101         ring->ids = ids;
00102 }
00103 
00104 /**
00105  * Calculate descriptor ring fill level
00106  *
00107  * @v ring              Descriptor ring
00108  * @v fill              Fill level
00109  */
00110 static inline __attribute__ (( always_inline )) unsigned int
00111 netfront_ring_fill ( struct netfront_ring *ring ) {
00112         unsigned int fill_level;
00113 
00114         fill_level = ( ring->id_prod - ring->id_cons );
00115         assert ( fill_level <= ring->count );
00116         return fill_level;
00117 }
00118 
00119 /**
00120  * Check whether or not descriptor ring is full
00121  *
00122  * @v ring              Descriptor ring
00123  * @v is_full           Ring is full
00124  */
00125 static inline __attribute__ (( always_inline )) int
00126 netfront_ring_is_full ( struct netfront_ring *ring ) {
00127 
00128         return ( netfront_ring_fill ( ring ) >= ring->count );
00129 }
00130 
00131 /**
00132  * Check whether or not descriptor ring is empty
00133  *
00134  * @v ring              Descriptor ring
00135  * @v is_empty          Ring is empty
00136  */
00137 static inline __attribute__ (( always_inline )) int
00138 netfront_ring_is_empty ( struct netfront_ring *ring ) {
00139 
00140         return ( netfront_ring_fill ( ring ) == 0 );
00141 }
00142 
00143 /** A netfront NIC */
00144 struct netfront_nic {
00145         /** Xen device */
00146         struct xen_device *xendev;
00147         /** Grant references */
00148         grant_ref_t refs[NETFRONT_REF_COUNT];
00149 
00150         /** Transmit ring */
00151         struct netfront_ring tx;
00152         /** Transmit front ring */
00153         netif_tx_front_ring_t tx_fring;
00154         /** Transmit I/O buffers */
00155         struct io_buffer *tx_iobufs[NETFRONT_NUM_TX_DESC];
00156         /** Transmit I/O buffer IDs */
00157         uint8_t tx_ids[NETFRONT_NUM_TX_DESC];
00158 
00159         /** Receive ring */
00160         struct netfront_ring rx;
00161         /** Receive front ring */
00162         netif_rx_front_ring_t rx_fring;
00163         /** Receive I/O buffers */
00164         struct io_buffer *rx_iobufs[NETFRONT_NUM_RX_DESC];
00165         /** Receive I/O buffer IDs */
00166         uint8_t rx_ids[NETFRONT_NUM_RX_DESC];
00167 
00168         /** Event channel */
00169         struct evtchn_send event;
00170 };
00171 
00172 /** Transmit shared ring field */
00173 #define tx_sring tx.sring.tx
00174 
00175 /** Receive shared ring field */
00176 #define rx_sring rx.sring.rx
00177 
00178 #endif /* _NETFRONT_H */