[Settings] Add per-netdevice settings block
[people/sha0/gpxe.git] / src / net / netdevice.c
1 /*
2  * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 #include <stdint.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <byteswap.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <gpxe/if_ether.h>
26 #include <gpxe/iobuf.h>
27 #include <gpxe/tables.h>
28 #include <gpxe/process.h>
29 #include <gpxe/init.h>
30 #include <gpxe/device.h>
31 #include <gpxe/netdevice.h>
32
33 /** @file
34  *
35  * Network device management
36  *
37  */
38
39 /** Registered network-layer protocols */
40 static struct net_protocol net_protocols[0]
41         __table_start ( struct net_protocol, net_protocols );
42 static struct net_protocol net_protocols_end[0]
43         __table_end ( struct net_protocol, net_protocols );
44
45 /** List of network devices */
46 struct list_head net_devices = LIST_HEAD_INIT ( net_devices );
47
48 /**
49  * Transmit raw packet via network device
50  *
51  * @v netdev            Network device
52  * @v iobuf             I/O buffer
53  * @ret rc              Return status code
54  *
55  * Transmits the packet via the specified network device.  This
56  * function takes ownership of the I/O buffer.
57  */
58 int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf ) {
59         int rc;
60
61         DBGC ( netdev, "NETDEV %p transmitting %p (%p+%zx)\n",
62                netdev, iobuf, iobuf->data, iob_len ( iobuf ) );
63
64         list_add_tail ( &iobuf->list, &netdev->tx_queue );
65
66         if ( ! ( netdev->state & NETDEV_OPEN ) ) {
67                 rc = -ENETUNREACH;
68                 goto err;
69         }
70                 
71         if ( ( rc = netdev->op->transmit ( netdev, iobuf ) ) != 0 )
72                 goto err;
73
74         return 0;
75
76  err:
77         netdev_tx_complete_err ( netdev, iobuf, rc );
78         return rc;
79 }
80
81 /**
82  * Complete network transmission
83  *
84  * @v netdev            Network device
85  * @v iobuf             I/O buffer
86  * @v rc                Packet status code
87  *
88  * The packet must currently be in the network device's TX queue.
89  */
90 void netdev_tx_complete_err ( struct net_device *netdev,
91                               struct io_buffer *iobuf, int rc ) {
92
93         /* Update statistics counter */
94         if ( rc == 0 ) {
95                 netdev->stats.tx_ok++;
96                 DBGC ( netdev, "NETDEV %p transmission %p complete\n",
97                        netdev, iobuf );
98         } else {
99                 netdev->stats.tx_err++;
100                 DBGC ( netdev, "NETDEV %p transmission %p failed: %s\n",
101                        netdev, iobuf, strerror ( rc ) );
102         }
103
104         /* Catch data corruption as early as possible */
105         assert ( iobuf->list.next != NULL );
106         assert ( iobuf->list.prev != NULL );
107
108         /* Dequeue and free I/O buffer */
109         list_del ( &iobuf->list );
110         free_iob ( iobuf );
111 }
112
113 /**
114  * Complete network transmission
115  *
116  * @v netdev            Network device
117  * @v rc                Packet status code
118  *
119  * Completes the oldest outstanding packet in the TX queue.
120  */
121 void netdev_tx_complete_next_err ( struct net_device *netdev, int rc ) {
122         struct io_buffer *iobuf;
123
124         list_for_each_entry ( iobuf, &netdev->tx_queue, list ) {
125                 netdev_tx_complete_err ( netdev, iobuf, rc );
126                 return;
127         }
128 }
129
130 /**
131  * Flush device's transmit queue
132  *
133  * @v netdev            Network device
134  */
135 static void netdev_tx_flush ( struct net_device *netdev ) {
136
137         /* Discard any packets in the TX queue */
138         while ( ! list_empty ( &netdev->tx_queue ) ) {
139                 netdev_tx_complete_next_err ( netdev, -ECANCELED );
140         }
141 }
142
143 /**
144  * Add packet to receive queue
145  *
146  * @v netdev            Network device
147  * @v iobuf             I/O buffer, or NULL
148  *
149  * The packet is added to the network device's RX queue.  This
150  * function takes ownership of the I/O buffer.
151  */
152 void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf ) {
153
154         DBGC ( netdev, "NETDEV %p received %p (%p+%zx)\n",
155                netdev, iobuf, iobuf->data, iob_len ( iobuf ) );
156
157         /* Enqueue packet */
158         list_add_tail ( &iobuf->list, &netdev->rx_queue );
159
160         /* Update statistics counter */
161         netdev->stats.rx_ok++;
162 }
163
164 /**
165  * Discard received packet
166  *
167  * @v netdev            Network device
168  * @v iobuf             I/O buffer, or NULL
169  * @v rc                Packet status code
170  *
171  * The packet is discarded and an RX error is recorded.  This function
172  * takes ownership of the I/O buffer.  @c iobuf may be NULL if, for
173  * example, the net device wishes to report an error due to being
174  * unable to allocate an I/O buffer.
175  */
176 void netdev_rx_err ( struct net_device *netdev,
177                      struct io_buffer *iobuf, int rc ) {
178
179         DBGC ( netdev, "NETDEV %p failed to receive %p: %s\n",
180                netdev, iobuf, strerror ( rc ) );
181
182         /* Discard packet */
183         free_iob ( iobuf );
184
185         /* Update statistics counter */
186         netdev->stats.rx_err++;
187 }
188
189 /**
190  * Poll for completed and received packets on network device
191  *
192  * @v netdev            Network device
193  *
194  * Polls the network device for completed transmissions and received
195  * packets.  Any received packets will be added to the RX packet queue
196  * via netdev_rx().
197  */
198 void netdev_poll ( struct net_device *netdev ) {
199
200         if ( netdev->state & NETDEV_OPEN )
201                 netdev->op->poll ( netdev );
202 }
203
204 /**
205  * Remove packet from device's receive queue
206  *
207  * @v netdev            Network device
208  * @ret iobuf           I/O buffer, or NULL
209  *
210  * Removes the first packet from the device's RX queue and returns it.
211  * Ownership of the packet is transferred to the caller.
212  */
213 struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev ) {
214         struct io_buffer *iobuf;
215
216         list_for_each_entry ( iobuf, &netdev->rx_queue, list ) {
217                 list_del ( &iobuf->list );
218                 return iobuf;
219         }
220         return NULL;
221 }
222
223 /**
224  * Flush device's receive queue
225  *
226  * @v netdev            Network device
227  */
228 static void netdev_rx_flush ( struct net_device *netdev ) {
229         struct io_buffer *iobuf;
230
231         /* Discard any packets in the RX queue */
232         while ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) {
233                 netdev_rx_err ( netdev, iobuf, -ECANCELED );
234         }
235 }
236
237 /**
238  * Free network device
239  *
240  * @v refcnt            Network device reference counter
241  */
242 static void free_netdev ( struct refcnt *refcnt ) {
243         struct net_device *netdev =
244                 container_of ( refcnt, struct net_device, refcnt );
245         
246         netdev_tx_flush ( netdev );
247         netdev_rx_flush ( netdev );
248         free ( netdev );
249 }
250
251 /**
252  * Allocate network device
253  *
254  * @v priv_size         Size of private data area (net_device::priv)
255  * @ret netdev          Network device, or NULL
256  *
257  * Allocates space for a network device and its private data area.
258  */
259 struct net_device * alloc_netdev ( size_t priv_size ) {
260         struct net_device *netdev;
261         size_t total_len;
262
263         total_len = ( sizeof ( *netdev ) + priv_size );
264         netdev = zalloc ( total_len );
265         if ( netdev ) {
266                 netdev->refcnt.free = free_netdev;
267                 INIT_LIST_HEAD ( &netdev->tx_queue );
268                 INIT_LIST_HEAD ( &netdev->rx_queue );
269                 settings_init ( &netdev->settings,
270                                 &netdev_settings_operations, &netdev->refcnt,
271                                 netdev->name );
272                 netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
273         }
274         return netdev;
275 }
276
277 /**
278  * Register network device
279  *
280  * @v netdev            Network device
281  * @ret rc              Return status code
282  *
283  * Gives the network device a name and adds it to the list of network
284  * devices.
285  */
286 int register_netdev ( struct net_device *netdev ) {
287         static unsigned int ifindex = 0;
288         int rc;
289
290         /* Create device name */
291         snprintf ( netdev->name, sizeof ( netdev->name ), "net%d",
292                    ifindex++ );
293
294         /* Register per-netdev configuration settings */
295         if ( ( rc = register_settings ( &netdev->settings, NULL ) ) != 0 ) {
296                 DBGC ( netdev, "NETDEV %p could not register settings: %s\n",
297                        netdev, strerror ( rc ) );
298                 return rc;
299         }
300
301         /* Add to device list */
302         netdev_get ( netdev );
303         list_add_tail ( &netdev->list, &net_devices );
304         DBGC ( netdev, "NETDEV %p registered as %s (phys %s hwaddr %s)\n",
305                netdev, netdev->name, netdev->dev->name,
306                netdev_hwaddr ( netdev ) );
307
308         return 0;
309 }
310
311 /**
312  * Open network device
313  *
314  * @v netdev            Network device
315  * @ret rc              Return status code
316  */
317 int netdev_open ( struct net_device *netdev ) {
318         int rc;
319
320         /* Do nothing if device is already open */
321         if ( netdev->state & NETDEV_OPEN )
322                 return 0;
323
324         DBGC ( netdev, "NETDEV %p opening\n", netdev );
325
326         /* Open the device */
327         if ( ( rc = netdev->op->open ( netdev ) ) != 0 )
328                 return rc;
329
330         /* Mark as opened */
331         netdev->state |= NETDEV_OPEN;
332         return 0;
333 }
334
335 /**
336  * Close network device
337  *
338  * @v netdev            Network device
339  */
340 void netdev_close ( struct net_device *netdev ) {
341
342         /* Do nothing if device is already closed */
343         if ( ! ( netdev->state & NETDEV_OPEN ) )
344                 return;
345
346         DBGC ( netdev, "NETDEV %p closing\n", netdev );
347
348         /* Close the device */
349         netdev->op->close ( netdev );
350
351         /* Flush TX and RX queues */
352         netdev_tx_flush ( netdev );
353         netdev_rx_flush ( netdev );
354
355         /* Mark as closed */
356         netdev->state &= ~NETDEV_OPEN;
357 }
358
359 /**
360  * Unregister network device
361  *
362  * @v netdev            Network device
363  *
364  * Removes the network device from the list of network devices.
365  */
366 void unregister_netdev ( struct net_device *netdev ) {
367
368         /* Ensure device is closed */
369         netdev_close ( netdev );
370
371         /* Unregister per-netdev configuration settings */
372         unregister_settings ( &netdev->settings );
373
374         /* Remove from device list */
375         list_del ( &netdev->list );
376         netdev_put ( netdev );
377         DBGC ( netdev, "NETDEV %p unregistered\n", netdev );
378 }
379
380 /** Enable or disable interrupts
381  *
382  * @v netdev            Network device
383  * @v enable            Interrupts should be enabled
384  */
385 void netdev_irq ( struct net_device *netdev, int enable ) {
386         netdev->op->irq ( netdev, enable );
387 }
388
389 /**
390  * Get network device by name
391  *
392  * @v name              Network device name
393  * @ret netdev          Network device, or NULL
394  */
395 struct net_device * find_netdev ( const char *name ) {
396         struct net_device *netdev;
397
398         list_for_each_entry ( netdev, &net_devices, list ) {
399                 if ( strcmp ( netdev->name, name ) == 0 )
400                         return netdev;
401         }
402
403         return NULL;
404 }
405
406 /**
407  * Get network device by PCI bus:dev.fn address
408  *
409  * @v bus_type          Bus type
410  * @v location          Bus location
411  * @ret netdev          Network device, or NULL
412  */
413 struct net_device * find_netdev_by_location ( unsigned int bus_type,
414                                               unsigned int location ) {
415         struct net_device *netdev;
416
417         list_for_each_entry ( netdev, &net_devices, list ) {
418                 if ( ( netdev->dev->desc.bus_type == bus_type ) &&
419                      ( netdev->dev->desc.location == location ) )
420                         return netdev;
421         }
422
423         return NULL;    
424 }
425
426 /**
427  * Transmit network-layer packet
428  *
429  * @v iobuf             I/O buffer
430  * @v netdev            Network device
431  * @v net_protocol      Network-layer protocol
432  * @v ll_dest           Destination link-layer address
433  * @ret rc              Return status code
434  *
435  * Prepends link-layer headers to the I/O buffer and transmits the
436  * packet via the specified network device.  This function takes
437  * ownership of the I/O buffer.
438  */
439 int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
440              struct net_protocol *net_protocol, const void *ll_dest ) {
441
442         /* Force a poll on the netdevice to (potentially) clear any
443          * backed-up TX completions.  This is needed on some network
444          * devices to avoid excessive losses due to small TX ring
445          * sizes.
446          */
447         netdev_poll ( netdev );
448
449         return netdev->ll_protocol->tx ( iobuf, netdev, net_protocol, ll_dest );
450 }
451
452 /**
453  * Process received network-layer packet
454  *
455  * @v iobuf             I/O buffer
456  * @v netdev            Network device
457  * @v net_proto         Network-layer protocol, in network-byte order
458  * @v ll_source         Source link-layer address
459  * @ret rc              Return status code
460  */
461 int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
462              uint16_t net_proto, const void *ll_source ) {
463         struct net_protocol *net_protocol;
464
465         /* Hand off to network-layer protocol, if any */
466         for ( net_protocol = net_protocols ; net_protocol < net_protocols_end ;
467               net_protocol++ ) {
468                 if ( net_protocol->net_proto == net_proto ) {
469                         return net_protocol->rx ( iobuf, netdev, ll_source );
470                 }
471         }
472         free_iob ( iobuf );
473         return 0;
474 }
475
476 /**
477  * Single-step the network stack
478  *
479  * @v process           Network stack process
480  *
481  * This polls all interfaces for received packets, and processes
482  * packets from the RX queue.
483  */
484 static void net_step ( struct process *process __unused ) {
485         struct net_device *netdev;
486         struct io_buffer *iobuf;
487
488         /* Poll and process each network device */
489         list_for_each_entry ( netdev, &net_devices, list ) {
490
491                 /* Poll for new packets */
492                 netdev_poll ( netdev );
493
494                 /* Process at most one received packet.  Give priority
495                  * to getting packets out of the NIC over processing
496                  * the received packets, because we advertise a window
497                  * that assumes that we can receive packets from the
498                  * NIC faster than they arrive.
499                  */
500                 if ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) {
501                         DBGC ( netdev, "NETDEV %p processing %p (%p+%zx)\n",
502                                netdev, iobuf, iobuf->data,
503                                iob_len ( iobuf ) );
504                         netdev->ll_protocol->rx ( iobuf, netdev );
505                 }
506         }
507 }
508
509 /** Networking stack process */
510 struct process net_process __permanent_process = {
511         .step = net_step,
512 };