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.
22 #include <gpxe/if_ether.h>
23 #include <gpxe/pkbuff.h>
24 #include <gpxe/netdevice.h>
28 * Network devices and network interfaces
32 /** List of all registered network devices */
33 static LIST_HEAD ( net_devices );
36 * Register network device
38 * @v netdev Network device
39 * @ret rc Return status code
41 * Adds the network device to the list of network devices.
43 int register_netdevice ( struct net_device *netdev ) {
44 list_add ( &netdev->devices, &net_devices );
49 * Unregister network device
51 * @v netdev Network device
53 * Removes the network device from the list of network devices.
55 void unregister_netdevice ( struct net_device *netdev ) {
56 list_del ( &netdev->devices );
60 * Transmit packet via network device
62 * @v netdev Network device
63 * @v pkb Packet buffer
64 * @ret rc Return status code
66 * Transmits the packet via the network device. The @c pkb link-layer
67 * metadata must already have been filled in, and space for the
68 * link-layer header must already be present in the packet buffer.
70 int netdev_send ( struct net_device *netdev, struct pk_buff *pkb ) {
73 if ( pkb->net_proto != ETH_P_RAW ) {
74 if ( ( rc = netdev->build_llh ( netdev, pkb ) ) != 0 )
77 return netdev->transmit ( netdev, pkb );
81 * Poll for packet on network device
83 * @v netdev Network device
84 * @v pkb Packet buffer
85 * @ret rc Return status code
87 * Polls the network device for a packet. If a packet is available,
88 * it will be added to the packet buffer, and the link-layer metadata
89 * fields in @c pkb will be filled in.
91 int netdev_poll ( struct net_device *netdev, struct pk_buff *pkb ) {
94 if ( ( rc = netdev->poll ( netdev, pkb ) ) != 0 )
96 return netdev->parse_llh ( netdev, pkb );
100 * Transmit packet via network interface
102 * @v netif Network interface
103 * @v pkb Packet buffer
104 * @ret rc Return status code
106 * Transmits the packet via the network interface. The packet must
107 * start with a network-layer header (e.g. an IP header, for an IP
108 * interface). The packet contents are undefined on return.
110 int netif_send ( struct net_interface *netif, struct pk_buff *pkb ) {
111 struct net_device *netdev = netif->netdev;
114 if ( ( rc = netif->add_llh_metadata ( netif, pkb ) ) != 0 )
116 pkb_push ( pkb, netdev->ll_hlen );
117 return netdev_send ( netdev, pkb );
121 * Process received packet
123 * @v netif Network interface
124 * @v pkb Packet buffer
125 * @ret rc Return status code
127 * Processes a packet received via netdev_poll(). The interface
128 * corresponding to the network-layer protocol is identified, the
129 * link-layer header is stripped from the packet and the packet is
130 * passed to the net_interface::rx_packet() method.
132 int netdev_rx_packet ( struct net_device *netdev, struct pk_buff *pkb ) {
133 struct net_interface *netif;
135 netif = netdev_find_netif ( netdev, pkb->net_proto );
137 return -EAFNOSUPPORT;
139 pkb_pull ( pkb, netdev->ll_hlen );
140 return netif->rx_packet ( netif, pkb );
144 * Poll for packet on all network devices
146 * @v pkb Packet buffer
147 * @ret netdev Network device
148 * @ret rc Return status code
150 * Polls all network devices for a packet. If a packet is available
151 * on any interface, @c netdev will be filled in and the packet will
152 * be received as per netdev_poll().
154 int net_poll ( struct pk_buff *pkb, struct net_device **netdev ) {
157 list_for_each_entry ( (*netdev), &net_devices, devices ) {
158 if ( ( rc = netdev_poll ( *netdev, pkb ) ) == 0 )