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