[undi] Fill in ProtType correctly in PXENV_UNDI_ISR
[people/balajirrao/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 ( netdev ),
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 ( netdev ),
296                                         NULL ) ) != 0 ) {
297                 DBGC ( netdev, "NETDEV %p could not register settings: %s\n",
298                        netdev, strerror ( rc ) );
299                 return rc;
300         }
301
302         /* Add to device list */
303         netdev_get ( netdev );
304         list_add_tail ( &netdev->list, &net_devices );
305         DBGC ( netdev, "NETDEV %p registered as %s (phys %s hwaddr %s)\n",
306                netdev, netdev->name, netdev->dev->name,
307                netdev_hwaddr ( netdev ) );
308
309         return 0;
310 }
311
312 /**
313  * Open network device
314  *
315  * @v netdev            Network device
316  * @ret rc              Return status code
317  */
318 int netdev_open ( struct net_device *netdev ) {
319         int rc;
320
321         /* Do nothing if device is already open */
322         if ( netdev->state & NETDEV_OPEN )
323                 return 0;
324
325         DBGC ( netdev, "NETDEV %p opening\n", netdev );
326
327         /* Open the device */
328         if ( ( rc = netdev->op->open ( netdev ) ) != 0 )
329                 return rc;
330
331         /* Mark as opened */
332         netdev->state |= NETDEV_OPEN;
333         return 0;
334 }
335
336 /**
337  * Close network device
338  *
339  * @v netdev            Network device
340  */
341 void netdev_close ( struct net_device *netdev ) {
342
343         /* Do nothing if device is already closed */
344         if ( ! ( netdev->state & NETDEV_OPEN ) )
345                 return;
346
347         DBGC ( netdev, "NETDEV %p closing\n", netdev );
348
349         /* Close the device */
350         netdev->op->close ( netdev );
351
352         /* Flush TX and RX queues */
353         netdev_tx_flush ( netdev );
354         netdev_rx_flush ( netdev );
355
356         /* Mark as closed */
357         netdev->state &= ~NETDEV_OPEN;
358 }
359
360 /**
361  * Unregister network device
362  *
363  * @v netdev            Network device
364  *
365  * Removes the network device from the list of network devices.
366  */
367 void unregister_netdev ( struct net_device *netdev ) {
368
369         /* Ensure device is closed */
370         netdev_close ( netdev );
371
372         /* Unregister per-netdev configuration settings */
373         unregister_settings ( netdev_settings ( netdev ) );
374
375         /* Remove from device list */
376         list_del ( &netdev->list );
377         netdev_put ( netdev );
378         DBGC ( netdev, "NETDEV %p unregistered\n", netdev );
379 }
380
381 /** Enable or disable interrupts
382  *
383  * @v netdev            Network device
384  * @v enable            Interrupts should be enabled
385  */
386 void netdev_irq ( struct net_device *netdev, int enable ) {
387         netdev->op->irq ( netdev, enable );
388 }
389
390 /**
391  * Get network device by name
392  *
393  * @v name              Network device name
394  * @ret netdev          Network device, or NULL
395  */
396 struct net_device * find_netdev ( const char *name ) {
397         struct net_device *netdev;
398
399         list_for_each_entry ( netdev, &net_devices, list ) {
400                 if ( strcmp ( netdev->name, name ) == 0 )
401                         return netdev;
402         }
403
404         return NULL;
405 }
406
407 /**
408  * Get network device by PCI bus:dev.fn address
409  *
410  * @v bus_type          Bus type
411  * @v location          Bus location
412  * @ret netdev          Network device, or NULL
413  */
414 struct net_device * find_netdev_by_location ( unsigned int bus_type,
415                                               unsigned int location ) {
416         struct net_device *netdev;
417
418         list_for_each_entry ( netdev, &net_devices, list ) {
419                 if ( ( netdev->dev->desc.bus_type == bus_type ) &&
420                      ( netdev->dev->desc.location == location ) )
421                         return netdev;
422         }
423
424         return NULL;    
425 }
426
427 /**
428  * Transmit network-layer packet
429  *
430  * @v iobuf             I/O buffer
431  * @v netdev            Network device
432  * @v net_protocol      Network-layer protocol
433  * @v ll_dest           Destination link-layer address
434  * @ret rc              Return status code
435  *
436  * Prepends link-layer headers to the I/O buffer and transmits the
437  * packet via the specified network device.  This function takes
438  * ownership of the I/O buffer.
439  */
440 int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
441              struct net_protocol *net_protocol, const void *ll_dest ) {
442         int rc;
443
444         /* Force a poll on the netdevice to (potentially) clear any
445          * backed-up TX completions.  This is needed on some network
446          * devices to avoid excessive losses due to small TX ring
447          * sizes.
448          */
449         netdev_poll ( netdev );
450
451         /* Add link-layer header */
452         if ( ( rc = netdev->ll_protocol->push ( iobuf, netdev, net_protocol,
453                                                 ll_dest ) ) != 0 ) {
454                 free_iob ( iobuf );
455                 return rc;
456         }
457
458         /* Transmit packet */
459         return netdev_tx ( netdev, iobuf );
460 }
461
462 /**
463  * Process received network-layer packet
464  *
465  * @v iobuf             I/O buffer
466  * @v netdev            Network device
467  * @v net_proto         Network-layer protocol, in network-byte order
468  * @v ll_source         Source link-layer address
469  * @ret rc              Return status code
470  */
471 int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
472              uint16_t net_proto, const void *ll_source ) {
473         struct net_protocol *net_protocol;
474
475         /* Hand off to network-layer protocol, if any */
476         for ( net_protocol = net_protocols ; net_protocol < net_protocols_end ;
477               net_protocol++ ) {
478                 if ( net_protocol->net_proto == net_proto ) {
479                         return net_protocol->rx ( iobuf, netdev, ll_source );
480                 }
481         }
482         free_iob ( iobuf );
483         return 0;
484 }
485
486 /**
487  * Single-step the network stack
488  *
489  * @v process           Network stack process
490  *
491  * This polls all interfaces for received packets, and processes
492  * packets from the RX queue.
493  */
494 static void net_step ( struct process *process __unused ) {
495         struct net_device *netdev;
496         struct io_buffer *iobuf;
497         struct ll_protocol *ll_protocol;
498         uint16_t net_proto;
499         const void *ll_source;
500         int rc;
501
502         /* Poll and process each network device */
503         list_for_each_entry ( netdev, &net_devices, list ) {
504
505                 /* Poll for new packets */
506                 netdev_poll ( netdev );
507
508                 /* Process at most one received packet.  Give priority
509                  * to getting packets out of the NIC over processing
510                  * the received packets, because we advertise a window
511                  * that assumes that we can receive packets from the
512                  * NIC faster than they arrive.
513                  */
514                 if ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) {
515
516                         DBGC ( netdev, "NETDEV %p processing %p (%p+%zx)\n",
517                                netdev, iobuf, iobuf->data,
518                                iob_len ( iobuf ) );
519
520                         /* Remove link-layer header */
521                         ll_protocol = netdev->ll_protocol;
522                         if ( ( rc = ll_protocol->pull ( iobuf, netdev,
523                                                         &net_proto,
524                                                         &ll_source ) ) != 0 ) {
525                                 free_iob ( iobuf );
526                                 continue;
527                         }
528
529                         net_rx ( iobuf, netdev, net_proto, ll_source );
530                 }
531         }
532 }
533
534 /** Networking stack process */
535 struct process net_process __permanent_process = {
536         .step = net_step,
537 };