2 * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
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.
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.
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.
25 #include <gpxe/if_ether.h>
26 #include <gpxe/pkbuff.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>
35 * Network device management
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 );
45 /** List of network devices */
46 struct list_head net_devices = LIST_HEAD_INIT ( net_devices );
49 * Transmit raw packet via network device
51 * @v netdev Network device
52 * @v pkb Packet buffer
53 * @ret rc Return status code
55 * Transmits the packet via the specified network device. This
56 * function takes ownership of the packet buffer.
58 int netdev_tx ( struct net_device *netdev, struct pk_buff *pkb ) {
61 DBGC ( netdev, "NETDEV %p transmitting %p (%p+%zx)\n",
62 netdev, pkb, pkb->data, pkb_len ( pkb ) );
64 list_add_tail ( &pkb->list, &netdev->tx_queue );
66 if ( ! ( netdev->state & NETDEV_OPEN ) ) {
71 if ( ( rc = netdev->transmit ( netdev, pkb ) ) != 0 )
77 DBGC ( netdev, "NETDEV %p transmission %p failed: %s\n",
78 netdev, pkb, strerror ( rc ) );
79 netdev_tx_complete ( netdev, pkb );
84 * Complete network transmission
86 * @v netdev Network device
87 * @v pkb Packet buffer
89 * The packet must currently be in the network device's TX queue.
91 void netdev_tx_complete ( struct net_device *netdev, struct pk_buff *pkb ) {
92 DBGC ( netdev, "NETDEV %p transmission %p complete\n", netdev, pkb );
94 list_del ( &pkb->list );
99 * Complete network transmission
101 * @v netdev Network device
103 * Completes the oldest outstanding packet in the TX queue.
105 void netdev_tx_complete_next ( struct net_device *netdev ) {
108 list_for_each_entry ( pkb, &netdev->tx_queue, list ) {
109 netdev_tx_complete ( netdev, pkb );
115 * Add packet to receive queue
117 * @v netdev Network device
118 * @v pkb Packet buffer
120 * The packet is added to the network device's RX queue. This
121 * function takes ownership of the packet buffer.
123 void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb ) {
124 DBGC ( netdev, "NETDEV %p received %p (%p+%zx)\n",
125 netdev, pkb, pkb->data, pkb_len ( pkb ) );
126 list_add_tail ( &pkb->list, &netdev->rx_queue );
130 * Poll for packet on network device
132 * @v netdev Network device
133 * @v rx_quota Maximum number of packets to receive
134 * @ret True There are packets present in the receive queue
135 * @ret False There are no packets present in the receive queue
137 * Polls the network device for received packets. Any received
138 * packets will be added to the RX packet queue via netdev_rx().
140 int netdev_poll ( struct net_device *netdev, unsigned int rx_quota ) {
142 if ( netdev->state & NETDEV_OPEN )
143 netdev->poll ( netdev, rx_quota );
145 return ( ! list_empty ( &netdev->rx_queue ) );
149 * Remove packet from device's receive queue
151 * @v netdev Network device
152 * @ret pkb Packet buffer, or NULL
154 * Removes the first packet from the device's RX queue and returns it.
155 * Ownership of the packet is transferred to the caller.
157 struct pk_buff * netdev_rx_dequeue ( struct net_device *netdev ) {
160 list_for_each_entry ( pkb, &netdev->rx_queue, list ) {
161 list_del ( &pkb->list );
168 * Allocate network device
170 * @v priv_size Size of private data area (net_device::priv)
171 * @ret netdev Network device, or NULL
173 * Allocates space for a network device and its private data area.
175 struct net_device * alloc_netdev ( size_t priv_size ) {
176 struct net_device *netdev;
178 netdev = calloc ( 1, sizeof ( *netdev ) + priv_size );
180 INIT_LIST_HEAD ( &netdev->references );
181 INIT_LIST_HEAD ( &netdev->tx_queue );
182 INIT_LIST_HEAD ( &netdev->rx_queue );
183 netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
189 * Register network device
191 * @v netdev Network device
192 * @ret rc Return status code
194 * Gives the network device a name and adds it to the list of network
197 int register_netdev ( struct net_device *netdev ) {
198 static unsigned int ifindex = 0;
200 /* Create device name */
201 snprintf ( netdev->name, sizeof ( netdev->name ), "net%d",
204 /* Add to device list */
205 list_add_tail ( &netdev->list, &net_devices );
206 DBGC ( netdev, "NETDEV %p registered as %s (phys %s hwaddr %s)\n",
207 netdev, netdev->name, netdev->dev->name,
208 netdev_hwaddr ( netdev ) );
214 * Open network device
216 * @v netdev Network device
217 * @ret rc Return status code
219 int netdev_open ( struct net_device *netdev ) {
222 /* Do nothing if device is already open */
223 if ( netdev->state & NETDEV_OPEN )
226 DBGC ( netdev, "NETDEV %p opening\n", netdev );
228 /* Open the device */
229 if ( ( rc = netdev->open ( netdev ) ) != 0 )
233 netdev->state |= NETDEV_OPEN;
238 * Close network device
240 * @v netdev Network device
242 void netdev_close ( struct net_device *netdev ) {
245 /* Do nothing if device is already closed */
246 if ( ! ( netdev->state & NETDEV_OPEN ) )
249 DBGC ( netdev, "NETDEV %p closing\n", netdev );
251 /* Close the device */
252 netdev->close ( netdev );
254 /* Discard any packets in the TX queue */
255 while ( ! list_empty ( &netdev->tx_queue ) ) {
256 netdev_tx_complete_next ( netdev );
259 /* Discard any packets in the RX queue */
260 while ( ( pkb = netdev_rx_dequeue ( netdev ) ) ) {
261 DBGC ( netdev, "NETDEV %p discarding received %p\n",
267 netdev->state &= ~NETDEV_OPEN;
271 * Unregister network device
273 * @v netdev Network device
275 * Removes the network device from the list of network devices.
277 void unregister_netdev ( struct net_device *netdev ) {
279 /* Ensure device is closed */
280 netdev_close ( netdev );
282 /* Kill off any persistent references to this device */
283 forget_references ( &netdev->references );
285 /* Remove from device list */
286 list_del ( &netdev->list );
287 DBGC ( netdev, "NETDEV %p unregistered\n", netdev );
291 * Free network device
293 * @v netdev Network device
295 void free_netdev ( struct net_device *netdev ) {
300 * Get network device by name
302 * @v name Network device name
303 * @ret netdev Network device, or NULL
305 struct net_device * find_netdev ( const char *name ) {
306 struct net_device *netdev;
308 list_for_each_entry ( netdev, &net_devices, list ) {
309 if ( strcmp ( netdev->name, name ) == 0 )
317 * Transmit network-layer packet
319 * @v pkb Packet buffer
320 * @v netdev Network device
321 * @v net_protocol Network-layer protocol
322 * @v ll_dest Destination link-layer address
323 * @ret rc Return status code
325 * Prepends link-layer headers to the packet buffer and transmits the
326 * packet via the specified network device. This function takes
327 * ownership of the packet buffer.
329 int net_tx ( struct pk_buff *pkb, struct net_device *netdev,
330 struct net_protocol *net_protocol, const void *ll_dest ) {
331 return netdev->ll_protocol->tx ( pkb, netdev, net_protocol, ll_dest );
335 * Process received network-layer packet
337 * @v pkb Packet buffer
338 * @v netdev Network device
339 * @v net_proto Network-layer protocol, in network-byte order
340 * @v ll_source Source link-layer address
341 * @ret rc Return status code
343 int net_rx ( struct pk_buff *pkb, struct net_device *netdev,
344 uint16_t net_proto, const void *ll_source ) {
345 struct net_protocol *net_protocol;
347 /* Hand off to network-layer protocol, if any */
348 for ( net_protocol = net_protocols ; net_protocol < net_protocols_end ;
350 if ( net_protocol->net_proto == net_proto ) {
351 return net_protocol->rx ( pkb, netdev, ll_source );
359 * Single-step the network stack
361 * @v process Network stack process
363 * This polls all interfaces for received packets, and processes
364 * packets from the RX queue.
367 static void net_step ( struct process *process ) {
368 struct net_device *netdev;
371 /* Poll and process each network device */
372 list_for_each_entry ( netdev, &net_devices, list ) {
374 /* Poll for new packets. Limit RX queue size to a
375 * single packet, because otherwise most drivers are
376 * in serious danger of running out of memory and
377 * having to drop packets.
379 * This limitation isn't relevant to devices that
380 * preallocate packet buffers (i.e. devices with
381 * descriptor-based RX datapaths). We might at some
382 * point want to relax the quota for such devices.
384 netdev_poll ( netdev,
385 ( list_empty ( &netdev->rx_queue ) ? 1 : 0 ) );
387 /* Handle at most one received packet per poll. We
388 * avoid processing more than one packet per call to
389 * netdev_poll(), because processing the received
390 * packet can trigger transmission of a new packet
391 * (e.g. an ARP response). Since TX completions will
392 * be processed as part of the poll operation, it is
393 * easy to overflow small TX queues if multiple
394 * packets are processed per poll.
396 if ( ( pkb = netdev_rx_dequeue ( netdev ) ) ) {
397 DBGC ( netdev, "NETDEV %p processing %p\n",
399 netdev->ll_protocol->rx ( pkb, netdev );
403 /* Re-schedule ourself */
404 schedule ( process );
407 /** Networking stack process */
408 static struct process net_process = {
412 /** Initialise the networking stack process */
413 static void init_net ( void ) {
414 schedule ( &net_process );
417 INIT_FN ( INIT_PROCESS, init_net, NULL, NULL );