[netdevice] Add netdev argument to link-layer push and pull handlers
[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 FILE_LICENCE ( GPL2_OR_LATER );
20
21 #include <stdint.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <byteswap.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <gpxe/if_ether.h>
28 #include <gpxe/iobuf.h>
29 #include <gpxe/tables.h>
30 #include <gpxe/process.h>
31 #include <gpxe/init.h>
32 #include <gpxe/device.h>
33 #include <gpxe/netdevice.h>
34
35 /** @file
36  *
37  * Network device management
38  *
39  */
40
41 /** List of network devices */
42 struct list_head net_devices = LIST_HEAD_INIT ( net_devices );
43
44 /** List of open network devices, in reverse order of opening */
45 struct list_head open_net_devices = LIST_HEAD_INIT ( open_net_devices );
46
47 /**
48  * Record network device statistic
49  *
50  * @v stats             Network device statistics
51  * @v rc                Status code
52  */
53 static void netdev_record_stat ( struct net_device_stats *stats, int rc ) {
54         struct net_device_error *error;
55         struct net_device_error *least_common_error;
56         unsigned int i;
57
58         /* If this is not an error, just update the good counter */
59         if ( rc == 0 ) {
60                 stats->good++;
61                 return;
62         }
63
64         /* Update the bad counter */
65         stats->bad++;
66
67         /* Locate the appropriate error record */
68         least_common_error = &stats->errors[0];
69         for ( i = 0 ; i < ( sizeof ( stats->errors ) /
70                             sizeof ( stats->errors[0] ) ) ; i++ ) {
71                 error = &stats->errors[i];
72                 /* Update matching record, if found */
73                 if ( error->rc == rc ) {
74                         error->count++;
75                         return;
76                 }
77                 if ( error->count < least_common_error->count )
78                         least_common_error = error;
79         }
80
81         /* Overwrite the least common error record */
82         least_common_error->rc = rc;
83         least_common_error->count = 1;
84 }
85
86 /**
87  * Transmit raw packet via network device
88  *
89  * @v netdev            Network device
90  * @v iobuf             I/O buffer
91  * @ret rc              Return status code
92  *
93  * Transmits the packet via the specified network device.  This
94  * function takes ownership of the I/O buffer.
95  */
96 int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf ) {
97         int rc;
98
99         DBGC ( netdev, "NETDEV %p transmitting %p (%p+%zx)\n",
100                netdev, iobuf, iobuf->data, iob_len ( iobuf ) );
101
102         list_add_tail ( &iobuf->list, &netdev->tx_queue );
103
104         if ( ! ( netdev->state & NETDEV_OPEN ) ) {
105                 rc = -ENETUNREACH;
106                 goto err;
107         }
108                 
109         if ( ( rc = netdev->op->transmit ( netdev, iobuf ) ) != 0 )
110                 goto err;
111
112         return 0;
113
114  err:
115         netdev_tx_complete_err ( netdev, iobuf, rc );
116         return rc;
117 }
118
119 /**
120  * Complete network transmission
121  *
122  * @v netdev            Network device
123  * @v iobuf             I/O buffer
124  * @v rc                Packet status code
125  *
126  * The packet must currently be in the network device's TX queue.
127  */
128 void netdev_tx_complete_err ( struct net_device *netdev,
129                               struct io_buffer *iobuf, int rc ) {
130
131         /* Update statistics counter */
132         netdev_record_stat ( &netdev->tx_stats, rc );
133         if ( rc == 0 ) {
134                 DBGC ( netdev, "NETDEV %p transmission %p complete\n",
135                        netdev, iobuf );
136         } else {
137                 DBGC ( netdev, "NETDEV %p transmission %p failed: %s\n",
138                        netdev, iobuf, strerror ( rc ) );
139         }
140
141         /* Catch data corruption as early as possible */
142         assert ( iobuf->list.next != NULL );
143         assert ( iobuf->list.prev != NULL );
144
145         /* Dequeue and free I/O buffer */
146         list_del ( &iobuf->list );
147         free_iob ( iobuf );
148 }
149
150 /**
151  * Complete network transmission
152  *
153  * @v netdev            Network device
154  * @v rc                Packet status code
155  *
156  * Completes the oldest outstanding packet in the TX queue.
157  */
158 void netdev_tx_complete_next_err ( struct net_device *netdev, int rc ) {
159         struct io_buffer *iobuf;
160
161         list_for_each_entry ( iobuf, &netdev->tx_queue, list ) {
162                 netdev_tx_complete_err ( netdev, iobuf, rc );
163                 return;
164         }
165 }
166
167 /**
168  * Flush device's transmit queue
169  *
170  * @v netdev            Network device
171  */
172 static void netdev_tx_flush ( struct net_device *netdev ) {
173
174         /* Discard any packets in the TX queue */
175         while ( ! list_empty ( &netdev->tx_queue ) ) {
176                 netdev_tx_complete_next_err ( netdev, -ECANCELED );
177         }
178 }
179
180 /**
181  * Add packet to receive queue
182  *
183  * @v netdev            Network device
184  * @v iobuf             I/O buffer, or NULL
185  *
186  * The packet is added to the network device's RX queue.  This
187  * function takes ownership of the I/O buffer.
188  */
189 void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf ) {
190
191         DBGC ( netdev, "NETDEV %p received %p (%p+%zx)\n",
192                netdev, iobuf, iobuf->data, iob_len ( iobuf ) );
193
194         /* Enqueue packet */
195         list_add_tail ( &iobuf->list, &netdev->rx_queue );
196
197         /* Update statistics counter */
198         netdev_record_stat ( &netdev->rx_stats, 0 );
199 }
200
201 /**
202  * Discard received packet
203  *
204  * @v netdev            Network device
205  * @v iobuf             I/O buffer, or NULL
206  * @v rc                Packet status code
207  *
208  * The packet is discarded and an RX error is recorded.  This function
209  * takes ownership of the I/O buffer.  @c iobuf may be NULL if, for
210  * example, the net device wishes to report an error due to being
211  * unable to allocate an I/O buffer.
212  */
213 void netdev_rx_err ( struct net_device *netdev,
214                      struct io_buffer *iobuf, int rc ) {
215
216         DBGC ( netdev, "NETDEV %p failed to receive %p: %s\n",
217                netdev, iobuf, strerror ( rc ) );
218
219         /* Discard packet */
220         free_iob ( iobuf );
221
222         /* Update statistics counter */
223         netdev_record_stat ( &netdev->rx_stats, rc );
224 }
225
226 /**
227  * Poll for completed and received packets on network device
228  *
229  * @v netdev            Network device
230  *
231  * Polls the network device for completed transmissions and received
232  * packets.  Any received packets will be added to the RX packet queue
233  * via netdev_rx().
234  */
235 void netdev_poll ( struct net_device *netdev ) {
236
237         if ( netdev->state & NETDEV_OPEN )
238                 netdev->op->poll ( netdev );
239 }
240
241 /**
242  * Remove packet from device's receive queue
243  *
244  * @v netdev            Network device
245  * @ret iobuf           I/O buffer, or NULL
246  *
247  * Removes the first packet from the device's RX queue and returns it.
248  * Ownership of the packet is transferred to the caller.
249  */
250 struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev ) {
251         struct io_buffer *iobuf;
252
253         list_for_each_entry ( iobuf, &netdev->rx_queue, list ) {
254                 list_del ( &iobuf->list );
255                 return iobuf;
256         }
257         return NULL;
258 }
259
260 /**
261  * Flush device's receive queue
262  *
263  * @v netdev            Network device
264  */
265 static void netdev_rx_flush ( struct net_device *netdev ) {
266         struct io_buffer *iobuf;
267
268         /* Discard any packets in the RX queue */
269         while ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) {
270                 netdev_rx_err ( netdev, iobuf, -ECANCELED );
271         }
272 }
273
274 /**
275  * Free network device
276  *
277  * @v refcnt            Network device reference counter
278  */
279 static void free_netdev ( struct refcnt *refcnt ) {
280         struct net_device *netdev =
281                 container_of ( refcnt, struct net_device, refcnt );
282         
283         netdev_tx_flush ( netdev );
284         netdev_rx_flush ( netdev );
285         clear_settings ( netdev_settings ( netdev ) );
286         free ( netdev );
287 }
288
289 /**
290  * Allocate network device
291  *
292  * @v priv_size         Size of private data area (net_device::priv)
293  * @ret netdev          Network device, or NULL
294  *
295  * Allocates space for a network device and its private data area.
296  */
297 struct net_device * alloc_netdev ( size_t priv_size ) {
298         struct net_device *netdev;
299         size_t total_len;
300
301         total_len = ( sizeof ( *netdev ) + priv_size );
302         netdev = zalloc ( total_len );
303         if ( netdev ) {
304                 netdev->refcnt.free = free_netdev;
305                 INIT_LIST_HEAD ( &netdev->tx_queue );
306                 INIT_LIST_HEAD ( &netdev->rx_queue );
307                 netdev_settings_init ( netdev );
308                 netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
309         }
310         return netdev;
311 }
312
313 /**
314  * Register network device
315  *
316  * @v netdev            Network device
317  * @ret rc              Return status code
318  *
319  * Gives the network device a name and adds it to the list of network
320  * devices.
321  */
322 int register_netdev ( struct net_device *netdev ) {
323         static unsigned int ifindex = 0;
324         int rc;
325
326         /* Create device name */
327         snprintf ( netdev->name, sizeof ( netdev->name ), "net%d",
328                    ifindex++ );
329
330         /* Register per-netdev configuration settings */
331         if ( ( rc = register_settings ( netdev_settings ( netdev ),
332                                         NULL ) ) != 0 ) {
333                 DBGC ( netdev, "NETDEV %p could not register settings: %s\n",
334                        netdev, strerror ( rc ) );
335                 return rc;
336         }
337
338         /* Add to device list */
339         netdev_get ( netdev );
340         list_add_tail ( &netdev->list, &net_devices );
341         DBGC ( netdev, "NETDEV %p registered as %s (phys %s hwaddr %s)\n",
342                netdev, netdev->name, netdev->dev->name,
343                netdev_hwaddr ( netdev ) );
344
345         return 0;
346 }
347
348 /**
349  * Open network device
350  *
351  * @v netdev            Network device
352  * @ret rc              Return status code
353  */
354 int netdev_open ( struct net_device *netdev ) {
355         int rc;
356
357         /* Do nothing if device is already open */
358         if ( netdev->state & NETDEV_OPEN )
359                 return 0;
360
361         DBGC ( netdev, "NETDEV %p opening\n", netdev );
362
363         /* Open the device */
364         if ( ( rc = netdev->op->open ( netdev ) ) != 0 )
365                 return rc;
366
367         /* Mark as opened */
368         netdev->state |= NETDEV_OPEN;
369
370         /* Add to head of open devices list */
371         list_add ( &netdev->open_list, &open_net_devices );
372
373         return 0;
374 }
375
376 /**
377  * Close network device
378  *
379  * @v netdev            Network device
380  */
381 void netdev_close ( struct net_device *netdev ) {
382
383         /* Do nothing if device is already closed */
384         if ( ! ( netdev->state & NETDEV_OPEN ) )
385                 return;
386
387         DBGC ( netdev, "NETDEV %p closing\n", netdev );
388
389         /* Close the device */
390         netdev->op->close ( netdev );
391
392         /* Flush TX and RX queues */
393         netdev_tx_flush ( netdev );
394         netdev_rx_flush ( netdev );
395
396         /* Mark as closed */
397         netdev->state &= ~NETDEV_OPEN;
398
399         /* Remove from open devices list */
400         list_del ( &netdev->open_list );
401 }
402
403 /**
404  * Unregister network device
405  *
406  * @v netdev            Network device
407  *
408  * Removes the network device from the list of network devices.
409  */
410 void unregister_netdev ( struct net_device *netdev ) {
411
412         /* Ensure device is closed */
413         netdev_close ( netdev );
414
415         /* Unregister per-netdev configuration settings */
416         unregister_settings ( netdev_settings ( netdev ) );
417
418         /* Remove from device list */
419         list_del ( &netdev->list );
420         netdev_put ( netdev );
421         DBGC ( netdev, "NETDEV %p unregistered\n", netdev );
422 }
423
424 /** Enable or disable interrupts
425  *
426  * @v netdev            Network device
427  * @v enable            Interrupts should be enabled
428  */
429 void netdev_irq ( struct net_device *netdev, int enable ) {
430         netdev->op->irq ( netdev, enable );
431 }
432
433 /**
434  * Get network device by name
435  *
436  * @v name              Network device name
437  * @ret netdev          Network device, or NULL
438  */
439 struct net_device * find_netdev ( const char *name ) {
440         struct net_device *netdev;
441
442         list_for_each_entry ( netdev, &net_devices, list ) {
443                 if ( strcmp ( netdev->name, name ) == 0 )
444                         return netdev;
445         }
446
447         return NULL;
448 }
449
450 /**
451  * Get network device by PCI bus:dev.fn address
452  *
453  * @v bus_type          Bus type
454  * @v location          Bus location
455  * @ret netdev          Network device, or NULL
456  */
457 struct net_device * find_netdev_by_location ( unsigned int bus_type,
458                                               unsigned int location ) {
459         struct net_device *netdev;
460
461         list_for_each_entry ( netdev, &net_devices, list ) {
462                 if ( ( netdev->dev->desc.bus_type == bus_type ) &&
463                      ( netdev->dev->desc.location == location ) )
464                         return netdev;
465         }
466
467         return NULL;    
468 }
469
470 /**
471  * Get most recently opened network device
472  *
473  * @ret netdev          Most recently opened network device, or NULL
474  */
475 struct net_device * last_opened_netdev ( void ) {
476         struct net_device *netdev;
477
478         list_for_each_entry ( netdev, &open_net_devices, open_list ) {
479                 assert ( netdev->state & NETDEV_OPEN );
480                 return netdev;
481         }
482
483         return NULL;
484 }
485
486 /**
487  * Transmit network-layer packet
488  *
489  * @v iobuf             I/O buffer
490  * @v netdev            Network device
491  * @v net_protocol      Network-layer protocol
492  * @v ll_dest           Destination link-layer address
493  * @ret rc              Return status code
494  *
495  * Prepends link-layer headers to the I/O buffer and transmits the
496  * packet via the specified network device.  This function takes
497  * ownership of the I/O buffer.
498  */
499 int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
500              struct net_protocol *net_protocol, const void *ll_dest ) {
501         struct ll_protocol *ll_protocol = netdev->ll_protocol;
502         int rc;
503
504         /* Force a poll on the netdevice to (potentially) clear any
505          * backed-up TX completions.  This is needed on some network
506          * devices to avoid excessive losses due to small TX ring
507          * sizes.
508          */
509         netdev_poll ( netdev );
510
511         /* Add link-layer header */
512         if ( ( rc = ll_protocol->push ( netdev, iobuf, ll_dest, netdev->ll_addr,
513                                         net_protocol->net_proto ) ) != 0 ) {
514                 free_iob ( iobuf );
515                 return rc;
516         }
517
518         /* Transmit packet */
519         return netdev_tx ( netdev, iobuf );
520 }
521
522 /**
523  * Process received network-layer packet
524  *
525  * @v iobuf             I/O buffer
526  * @v netdev            Network device
527  * @v net_proto         Network-layer protocol, in network-byte order
528  * @v ll_source         Source link-layer address
529  * @ret rc              Return status code
530  */
531 int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
532              uint16_t net_proto, const void *ll_source ) {
533         struct net_protocol *net_protocol;
534
535         /* Hand off to network-layer protocol, if any */
536         for_each_table_entry ( net_protocol, NET_PROTOCOLS ) {
537                 if ( net_protocol->net_proto == net_proto )
538                         return net_protocol->rx ( iobuf, netdev, ll_source );
539         }
540
541         DBGC ( netdev, "NETDEV %p unknown network protocol %04x\n",
542                netdev, ntohs ( net_proto ) );
543         free_iob ( iobuf );
544         return 0;
545 }
546
547 /**
548  * Single-step the network stack
549  *
550  * @v process           Network stack process
551  *
552  * This polls all interfaces for received packets, and processes
553  * packets from the RX queue.
554  */
555 static void net_step ( struct process *process __unused ) {
556         struct net_device *netdev;
557         struct io_buffer *iobuf;
558         struct ll_protocol *ll_protocol;
559         const void *ll_dest;
560         const void *ll_source;
561         uint16_t net_proto;
562         int rc;
563
564         /* Poll and process each network device */
565         list_for_each_entry ( netdev, &net_devices, list ) {
566
567                 /* Poll for new packets */
568                 netdev_poll ( netdev );
569
570                 /* Process at most one received packet.  Give priority
571                  * to getting packets out of the NIC over processing
572                  * the received packets, because we advertise a window
573                  * that assumes that we can receive packets from the
574                  * NIC faster than they arrive.
575                  */
576                 if ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) {
577
578                         DBGC ( netdev, "NETDEV %p processing %p (%p+%zx)\n",
579                                netdev, iobuf, iobuf->data,
580                                iob_len ( iobuf ) );
581
582                         /* Remove link-layer header */
583                         ll_protocol = netdev->ll_protocol;
584                         if ( ( rc = ll_protocol->pull ( netdev, iobuf,
585                                                         &ll_dest, &ll_source,
586                                                         &net_proto ) ) != 0 ) {
587                                 free_iob ( iobuf );
588                                 continue;
589                         }
590
591                         net_rx ( iobuf, netdev, net_proto, ll_source );
592                 }
593         }
594 }
595
596 /** Networking stack process */
597 struct process net_process __permanent_process = {
598         .step = net_step,
599 };