Allow recording of TX and RX errors to aid in end-user debugging.
[people/holger/gpxe.git] / src / include / gpxe / netdevice.h
1 #ifndef _GPXE_NETDEVICE_H
2 #define _GPXE_NETDEVICE_H
3
4 /** @file
5  *
6  * Network device management
7  *
8  */
9
10 #include <stdint.h>
11 #include <gpxe/list.h>
12 #include <gpxe/tables.h>
13 #include <gpxe/refcnt.h>
14
15 struct io_buffer;
16 struct net_device;
17 struct net_protocol;
18 struct ll_protocol;
19 struct device;
20
21 /** Maximum length of a link-layer address */
22 #define MAX_LL_ADDR_LEN 6
23
24 /** Maximum length of a link-layer header */
25 #define MAX_LL_HEADER_LEN 16
26
27 /** Maximum length of a network-layer address */
28 #define MAX_NET_ADDR_LEN 4
29
30 /**
31  * A network-layer protocol
32  *
33  */
34 struct net_protocol {
35         /** Protocol name */
36         const char *name;
37         /**
38          * Process received packet
39          *
40          * @v iobuf     I/O buffer
41          * @v netdev    Network device
42          * @v ll_source Link-layer source address
43          *
44          * This method takes ownership of the I/O buffer.
45          */
46         int ( * rx ) ( struct io_buffer *iobuf, struct net_device *netdev,
47                        const void *ll_source );
48         /**
49          * Transcribe network-layer address
50          *
51          * @v net_addr  Network-layer address
52          * @ret string  Human-readable transcription of address
53          *
54          * This method should convert the network-layer address into a
55          * human-readable format (e.g. dotted quad notation for IPv4).
56          *
57          * The buffer used to hold the transcription is statically
58          * allocated.
59          */
60         const char * ( *ntoa ) ( const void * net_addr );
61         /** Network-layer protocol
62          *
63          * This is an ETH_P_XXX constant, in network-byte order
64          */
65         uint16_t net_proto;
66         /** Network-layer address length */
67         uint8_t net_addr_len;
68 };
69
70 /**
71  * A link-layer protocol
72  *
73  */
74 struct ll_protocol {
75         /** Protocol name */
76         const char *name;
77         /**
78          * Transmit network-layer packet via network device
79          *
80          * @v iobuf             I/O buffer
81          * @v netdev            Network device
82          * @v net_protocol      Network-layer protocol
83          * @v ll_dest           Link-layer destination address
84          * @ret rc              Return status code
85          *
86          * This method should prepend in the link-layer header
87          * (e.g. the Ethernet DIX header) and transmit the packet.
88          * This method takes ownership of the I/O buffer.
89          */
90         int ( * tx ) ( struct io_buffer *iobuf, struct net_device *netdev,
91                        struct net_protocol *net_protocol,
92                        const void *ll_dest );
93         /**
94          * Handle received packet
95          *
96          * @v iobuf     I/O buffer
97          * @v netdev    Network device
98          *
99          * This method should strip off the link-layer header
100          * (e.g. the Ethernet DIX header) and pass the packet to
101          * net_rx().  This method takes ownership of the packet
102          * buffer.
103          */
104         int ( * rx ) ( struct io_buffer *iobuf, struct net_device *netdev );
105         /**
106          * Transcribe link-layer address
107          *
108          * @v ll_addr   Link-layer address
109          * @ret string  Human-readable transcription of address
110          *
111          * This method should convert the link-layer address into a
112          * human-readable format.
113          *
114          * The buffer used to hold the transcription is statically
115          * allocated.
116          */
117         const char * ( * ntoa ) ( const void * ll_addr );
118         /** Link-layer protocol
119          *
120          * This is an ARPHRD_XXX constant, in network byte order.
121          */
122         uint16_t ll_proto;
123         /** Link-layer address length */
124         uint8_t ll_addr_len;
125         /** Link-layer header length */
126         uint8_t ll_header_len;
127         /** Link-layer broadcast address */
128         const uint8_t *ll_broadcast;
129 };
130
131 /**
132  * Network device statistics
133  *
134  */
135 struct net_device_stats {
136         /** Count of successfully completed transmissions */
137         unsigned int tx_ok;
138         /** Count of transmission errors */
139         unsigned int tx_err;
140         /** Count of successfully received packets */
141         unsigned int rx_ok;
142         /** Count of reception errors */
143         unsigned int rx_err;
144 };
145
146 /**
147  * A network device
148  *
149  * This structure represents a piece of networking hardware.  It has
150  * properties such as a link-layer address and methods for
151  * transmitting and receiving raw packets.
152  *
153  * Note that this structure must represent a generic network device,
154  * not just an Ethernet device.
155  */
156 struct net_device {
157         /** Reference counter */
158         struct refcnt refcnt;
159         /** List of network devices */
160         struct list_head list;
161         /** Name of this network device */
162         char name[8];
163         /** Underlying hardware device */
164         struct device *dev;
165
166         /** Open network device
167          *
168          * @v netdev    Network device
169          * @ret rc      Return status code
170          *
171          * This method should allocate RX I/O buffers and enable
172          * the hardware to start transmitting and receiving packets.
173          */
174         int ( * open ) ( struct net_device *netdev );
175         /** Close network device
176          *
177          * @v netdev    Network device
178          *
179          * This method should stop the flow of packets, and free up
180          * any packets that are currently in the device's TX queue.
181          */
182         void ( * close ) ( struct net_device *netdev );
183         /** Transmit packet
184          *
185          * @v netdev    Network device
186          * @v iobuf     I/O buffer
187          * @ret rc      Return status code
188          *
189          * This method should cause the hardware to initiate
190          * transmission of the I/O buffer.
191          *
192          * If this method returns success, the I/O buffer remains
193          * owned by the net device's TX queue, and the net device must
194          * eventually call netdev_tx_complete() to free the buffer.
195          * If this method returns failure, the I/O buffer is
196          * immediately released; the failure is interpreted as
197          * "failure to enqueue buffer".
198          *
199          * This method is guaranteed to be called only when the device
200          * is open.
201          */
202         int ( * transmit ) ( struct net_device *netdev, struct io_buffer *iobuf );
203         /** Poll for received packet
204          *
205          * @v netdev    Network device
206          * @v rx_quota  Maximum number of packets to receive
207          *
208          * This method should cause the hardware to check for received
209          * packets.  Any received packets should be delivered via
210          * netdev_rx(), up to a maximum of @c rx_quota packets.
211          *
212          * This method is guaranteed to be called only when the device
213          * is open.
214          */
215         void ( * poll ) ( struct net_device *netdev, unsigned int rx_quota );
216
217         /** Link-layer protocol */
218         struct ll_protocol *ll_protocol;
219         /** Link-layer address
220          *
221          * For Ethernet, this is the MAC address.
222          */
223         uint8_t ll_addr[MAX_LL_ADDR_LEN];
224
225         /** Current device state
226          *
227          * This is the bitwise-OR of zero or more NETDEV_XXX constants.
228          */
229         unsigned int state;
230         /** TX packet queue */
231         struct list_head tx_queue;
232         /** RX packet queue */
233         struct list_head rx_queue;
234         /** Device statistics */
235         struct net_device_stats stats;
236
237         /** Driver private data */
238         void *priv;
239 };
240
241 /** Network device is open */
242 #define NETDEV_OPEN 0x0001
243
244 /** Declare a link-layer protocol */
245 #define __ll_protocol  __table ( struct ll_protocol, ll_protocols, 01 )
246
247 /** Declare a network-layer protocol */
248 #define __net_protocol __table ( struct net_protocol, net_protocols, 01 )
249
250 extern struct list_head net_devices;
251
252 /**
253  * Get printable network device hardware address
254  *
255  * @v netdev            Network device
256  * @ret name            Hardware address
257  */
258 static inline const char * netdev_hwaddr ( struct net_device *netdev ) {
259         return netdev->ll_protocol->ntoa ( netdev->ll_addr );
260 }
261
262 /** Iterate over all network devices */
263 #define for_each_netdev( netdev ) \
264         list_for_each_entry ( (netdev), &net_devices, list )
265
266 /** There exist some network devices
267  *
268  * @ret existence       Existence of network devices
269  */
270 static inline int have_netdevs ( void ) {
271         return ( ! list_empty ( &net_devices ) );
272 }
273
274 /**
275  * Get reference to network device
276  *
277  * @v netdev            Network device
278  * @ret netdev          Network device
279  */
280 static inline __attribute__ (( always_inline )) struct net_device *
281 netdev_get ( struct net_device *netdev ) {
282         ref_get ( &netdev->refcnt );
283         return netdev;
284 }
285
286 /**
287  * Drop reference to network device
288  *
289  * @v netdev            Network device
290  */
291 static inline __attribute__ (( always_inline )) void
292 netdev_put ( struct net_device *netdev ) {
293         ref_put ( &netdev->refcnt );
294 }
295
296 extern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf );
297 extern void netdev_tx_complete_err ( struct net_device *netdev,
298                                  struct io_buffer *iobuf, int rc );
299 extern void netdev_tx_complete_next_err ( struct net_device *netdev, int rc );
300 extern void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf );
301 extern void netdev_rx_err ( struct net_device *netdev,
302                             struct io_buffer *iobuf, int rc );
303 extern int netdev_poll ( struct net_device *netdev, unsigned int rx_quota );
304 extern struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev );
305 extern struct net_device * alloc_netdev ( size_t priv_size );
306 extern int register_netdev ( struct net_device *netdev );
307 extern int netdev_open ( struct net_device *netdev );
308 extern void netdev_close ( struct net_device *netdev );
309 extern void unregister_netdev ( struct net_device *netdev );
310 extern struct net_device * find_netdev ( const char *name );
311 extern struct net_device * find_netdev_by_location ( unsigned int bus_type,
312                                                      unsigned int location );
313 extern int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
314                     struct net_protocol *net_protocol, const void *ll_dest );
315 extern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
316                     uint16_t net_proto, const void *ll_source );
317
318 /**
319  * Complete network transmission
320  *
321  * @v netdev            Network device
322  * @v iobuf             I/O buffer
323  *
324  * The packet must currently be in the network device's TX queue.
325  */
326 static inline void netdev_tx_complete ( struct net_device *netdev,
327                                         struct io_buffer *iobuf ) {
328         netdev_tx_complete_err ( netdev, iobuf, 0 );
329 }
330
331 /**
332  * Complete network transmission
333  *
334  * @v netdev            Network device
335  *
336  * Completes the oldest outstanding packet in the TX queue.
337  */
338 static inline void netdev_tx_complete_next ( struct net_device *netdev ) {
339         netdev_tx_complete_next_err ( netdev, 0 );
340 }
341
342 #endif /* _GPXE_NETDEVICE_H */