Kill off hotplug.h and just make net devices normal reference-counted
[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->transmit ( netdev, iobuf ) ) != 0 )
72                 goto err;
73
74         return 0;
75
76  err:
77         DBGC ( netdev, "NETDEV %p transmission %p failed: %s\n",
78                netdev, iobuf, strerror ( rc ) );
79         netdev_tx_complete ( netdev, iobuf );
80         return rc;
81 }
82
83 /**
84  * Complete network transmission
85  *
86  * @v netdev            Network device
87  * @v iobuf             I/O buffer
88  *
89  * The packet must currently be in the network device's TX queue.
90  */
91 void netdev_tx_complete ( struct net_device *netdev, struct io_buffer *iobuf ) {
92         DBGC ( netdev, "NETDEV %p transmission %p complete\n", netdev, iobuf );
93
94         /* Catch data corruption as early as possible */
95         assert ( iobuf->list.next != NULL );
96         assert ( iobuf->list.prev != NULL );
97
98         list_del ( &iobuf->list );
99         free_iob ( iobuf );
100 }
101
102 /**
103  * Complete network transmission
104  *
105  * @v netdev            Network device
106  *
107  * Completes the oldest outstanding packet in the TX queue.
108  */
109 void netdev_tx_complete_next ( struct net_device *netdev ) {
110         struct io_buffer *iobuf;
111
112         list_for_each_entry ( iobuf, &netdev->tx_queue, list ) {
113                 netdev_tx_complete ( netdev, iobuf );
114                 return;
115         }
116 }
117
118 /**
119  * Flush device's transmit queue
120  *
121  * @v netdev            Network device
122  */
123 static void netdev_tx_flush ( struct net_device *netdev ) {
124
125         /* Discard any packets in the TX queue */
126         while ( ! list_empty ( &netdev->tx_queue ) ) {
127                 netdev_tx_complete_next ( netdev );
128         }
129 }
130
131 /**
132  * Add packet to receive queue
133  *
134  * @v netdev            Network device
135  * @v iobuf             I/O buffer
136  *
137  * The packet is added to the network device's RX queue.  This
138  * function takes ownership of the I/O buffer.
139  */
140 void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf ) {
141         DBGC ( netdev, "NETDEV %p received %p (%p+%zx)\n",
142                netdev, iobuf, iobuf->data, iob_len ( iobuf ) );
143         list_add_tail ( &iobuf->list, &netdev->rx_queue );
144 }
145
146 /**
147  * Poll for packet on network device
148  *
149  * @v netdev            Network device
150  * @v rx_quota          Maximum number of packets to receive
151  * @ret True            There are packets present in the receive queue
152  * @ret False           There are no packets present in the receive queue
153  *
154  * Polls the network device for received packets.  Any received
155  * packets will be added to the RX packet queue via netdev_rx().
156  */
157 int netdev_poll ( struct net_device *netdev, unsigned int rx_quota ) {
158
159         if ( netdev->state & NETDEV_OPEN )
160                 netdev->poll ( netdev, rx_quota );
161
162         return ( ! list_empty ( &netdev->rx_queue ) );
163 }
164
165 /**
166  * Remove packet from device's receive queue
167  *
168  * @v netdev            Network device
169  * @ret iobuf           I/O buffer, or NULL
170  *
171  * Removes the first packet from the device's RX queue and returns it.
172  * Ownership of the packet is transferred to the caller.
173  */
174 struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev ) {
175         struct io_buffer *iobuf;
176
177         list_for_each_entry ( iobuf, &netdev->rx_queue, list ) {
178                 list_del ( &iobuf->list );
179                 return iobuf;
180         }
181         return NULL;
182 }
183
184 /**
185  * Flush device's receive queue
186  *
187  * @v netdev            Network device
188  */
189 static void netdev_rx_flush ( struct net_device *netdev ) {
190         struct io_buffer *iobuf;
191
192         /* Discard any packets in the RX queue */
193         while ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) {
194                 DBGC ( netdev, "NETDEV %p discarding received %p\n",
195                        netdev, iobuf );
196                 free_iob ( iobuf );
197         }
198 }
199
200 /**
201  * Free network device
202  *
203  * @v refcnt            Network device reference counter
204  */
205 static void free_netdev ( struct refcnt *refcnt ) {
206         struct net_device *netdev =
207                 container_of ( refcnt, struct net_device, refcnt );
208         
209         netdev_tx_flush ( netdev );
210         netdev_rx_flush ( netdev );
211         free ( netdev );
212 }
213
214 /**
215  * Allocate network device
216  *
217  * @v priv_size         Size of private data area (net_device::priv)
218  * @ret netdev          Network device, or NULL
219  *
220  * Allocates space for a network device and its private data area.
221  */
222 struct net_device * alloc_netdev ( size_t priv_size ) {
223         struct net_device *netdev;
224         size_t total_len;
225
226         total_len = ( sizeof ( *netdev ) + priv_size );
227         netdev = malloc ( total_len );
228         if ( netdev ) {
229                 memset ( netdev, 0, total_len );
230                 netdev->refcnt.free = free_netdev;
231                 INIT_LIST_HEAD ( &netdev->tx_queue );
232                 INIT_LIST_HEAD ( &netdev->rx_queue );
233                 netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
234         }
235         return netdev;
236 }
237
238 /**
239  * Register network device
240  *
241  * @v netdev            Network device
242  * @ret rc              Return status code
243  *
244  * Gives the network device a name and adds it to the list of network
245  * devices.
246  */
247 int register_netdev ( struct net_device *netdev ) {
248         static unsigned int ifindex = 0;
249
250         /* Create device name */
251         snprintf ( netdev->name, sizeof ( netdev->name ), "net%d",
252                    ifindex++ );
253
254         /* Add to device list */
255         netdev_get ( netdev );
256         list_add_tail ( &netdev->list, &net_devices );
257         DBGC ( netdev, "NETDEV %p registered as %s (phys %s hwaddr %s)\n",
258                netdev, netdev->name, netdev->dev->name,
259                netdev_hwaddr ( netdev ) );
260
261         return 0;
262 }
263
264 /**
265  * Open network device
266  *
267  * @v netdev            Network device
268  * @ret rc              Return status code
269  */
270 int netdev_open ( struct net_device *netdev ) {
271         int rc;
272
273         /* Do nothing if device is already open */
274         if ( netdev->state & NETDEV_OPEN )
275                 return 0;
276
277         DBGC ( netdev, "NETDEV %p opening\n", netdev );
278
279         /* Open the device */
280         if ( ( rc = netdev->open ( netdev ) ) != 0 )
281                 return rc;
282
283         /* Mark as opened */
284         netdev->state |= NETDEV_OPEN;
285         return 0;
286 }
287
288 /**
289  * Close network device
290  *
291  * @v netdev            Network device
292  */
293 void netdev_close ( struct net_device *netdev ) {
294
295         /* Do nothing if device is already closed */
296         if ( ! ( netdev->state & NETDEV_OPEN ) )
297                 return;
298
299         DBGC ( netdev, "NETDEV %p closing\n", netdev );
300
301         /* Close the device */
302         netdev->close ( netdev );
303
304         /* Flush TX and RX queues */
305         netdev_tx_flush ( netdev );
306         netdev_rx_flush ( netdev );
307
308         /* Mark as closed */
309         netdev->state &= ~NETDEV_OPEN;
310 }
311
312 /**
313  * Unregister network device
314  *
315  * @v netdev            Network device
316  *
317  * Removes the network device from the list of network devices.
318  */
319 void unregister_netdev ( struct net_device *netdev ) {
320
321         /* Ensure device is closed */
322         netdev_close ( netdev );
323
324         /* Remove from device list */
325         list_del ( &netdev->list );
326         netdev_put ( netdev );
327         DBGC ( netdev, "NETDEV %p unregistered\n", netdev );
328 }
329
330 /**
331  * Get network device by name
332  *
333  * @v name              Network device name
334  * @ret netdev          Network device, or NULL
335  */
336 struct net_device * find_netdev ( const char *name ) {
337         struct net_device *netdev;
338
339         list_for_each_entry ( netdev, &net_devices, list ) {
340                 if ( strcmp ( netdev->name, name ) == 0 )
341                         return netdev;
342         }
343
344         return NULL;
345 }
346
347 /**
348  * Get network device by PCI bus:dev.fn address
349  *
350  * @v busdevfn          PCI bus:dev.fn address
351  * @ret netdev          Network device, or NULL
352  */
353 struct net_device * find_pci_netdev ( unsigned int busdevfn ) {
354         struct net_device *netdev;
355
356         list_for_each_entry ( netdev, &net_devices, list ) {
357                 if ( ( netdev->dev->desc.bus_type == BUS_TYPE_PCI ) &&
358                      ( netdev->dev->desc.location == busdevfn ) )
359                         return netdev;
360         }
361
362         return NULL;    
363 }
364
365 /**
366  * Transmit network-layer packet
367  *
368  * @v iobuf             I/O buffer
369  * @v netdev            Network device
370  * @v net_protocol      Network-layer protocol
371  * @v ll_dest           Destination link-layer address
372  * @ret rc              Return status code
373  *
374  * Prepends link-layer headers to the I/O buffer and transmits the
375  * packet via the specified network device.  This function takes
376  * ownership of the I/O buffer.
377  */
378 int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
379              struct net_protocol *net_protocol, const void *ll_dest ) {
380         return netdev->ll_protocol->tx ( iobuf, netdev, net_protocol, ll_dest );
381 }
382
383 /**
384  * Process received network-layer packet
385  *
386  * @v iobuf             I/O buffer
387  * @v netdev            Network device
388  * @v net_proto         Network-layer protocol, in network-byte order
389  * @v ll_source         Source link-layer address
390  * @ret rc              Return status code
391  */
392 int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
393              uint16_t net_proto, const void *ll_source ) {
394         struct net_protocol *net_protocol;
395
396         /* Hand off to network-layer protocol, if any */
397         for ( net_protocol = net_protocols ; net_protocol < net_protocols_end ;
398               net_protocol++ ) {
399                 if ( net_protocol->net_proto == net_proto ) {
400                         return net_protocol->rx ( iobuf, netdev, ll_source );
401                 }
402         }
403         free_iob ( iobuf );
404         return 0;
405 }
406
407 /**
408  * Single-step the network stack
409  *
410  * @v process           Network stack process
411  *
412  * This polls all interfaces for received packets, and processes
413  * packets from the RX queue.
414  */
415 static void net_step ( struct process *process __unused ) {
416         struct net_device *netdev;
417         struct io_buffer *iobuf;
418
419         /* Poll and process each network device */
420         list_for_each_entry ( netdev, &net_devices, list ) {
421
422                 /* Poll for new packets */
423                 netdev_poll ( netdev, -1U );
424
425                 /* Process at most one received packet.  Give priority
426                  * to getting packets out of the NIC over processing
427                  * the received packets, because we advertise a window
428                  * that assumes that we can receive packets from the
429                  * NIC faster than they arrive.
430                  */
431                 if ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) {
432                         DBGC ( netdev, "NETDEV %p processing %p\n",
433                                netdev, iobuf );
434                         netdev->ll_protocol->rx ( iobuf, netdev );
435                 }
436         }
437 }
438
439 /** Networking stack process */
440 static struct process net_process = {
441         .step = net_step,
442 };
443
444 /** Initialise the networking stack process */
445 static void init_net ( void ) {
446         process_add ( &net_process );
447 }
448
449 INIT_FN ( INIT_PROCESS, init_net, NULL, NULL );