You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

netdevice.c 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  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. #include <stdint.h>
  19. #include <byteswap.h>
  20. #include <string.h>
  21. #include <errno.h>
  22. #include <malloc.h>
  23. #include <gpxe/if_ether.h>
  24. #include <gpxe/pkbuff.h>
  25. #include <gpxe/tables.h>
  26. #include <gpxe/process.h>
  27. #include <gpxe/init.h>
  28. #include <gpxe/netdevice.h>
  29. /** @file
  30. *
  31. * Network device management
  32. *
  33. */
  34. /** Registered network-layer protocols */
  35. static struct net_protocol net_protocols[0] __table_start ( net_protocols );
  36. static struct net_protocol net_protocols_end[0] __table_end ( net_protocols );
  37. /** List of network devices */
  38. static LIST_HEAD ( net_devices );
  39. #warning "Remove this static IP address hack"
  40. #include <ip.h>
  41. #include <gpxe/ip.h>
  42. /**
  43. * Transmit raw packet via network device
  44. *
  45. * @v netdev Network device
  46. * @v pkb Packet buffer
  47. * @ret rc Return status code
  48. *
  49. * Transmits the packet via the specified network device. This
  50. * function takes ownership of the packet buffer.
  51. */
  52. int netdev_tx ( struct net_device *netdev, struct pk_buff *pkb ) {
  53. DBG ( "%s transmitting %p+%zx\n", netdev_name ( netdev ),
  54. pkb->data, pkb_len ( pkb ) );
  55. return netdev->transmit ( netdev, pkb );
  56. }
  57. /**
  58. * Add packet to receive queue
  59. *
  60. * @v netdev Network device
  61. * @v pkb Packet buffer
  62. *
  63. * The packet is added to the network device's RX queue. This
  64. * function takes ownership of the packet buffer.
  65. */
  66. void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb ) {
  67. DBG ( "%s received %p+%zx\n", netdev_name ( netdev ),
  68. pkb->data, pkb_len ( pkb ) );
  69. list_add_tail ( &pkb->list, &netdev->rx_queue );
  70. }
  71. /**
  72. * Transmit network-layer packet
  73. *
  74. * @v pkb Packet buffer
  75. * @v netdev Network device
  76. * @v net_protocol Network-layer protocol
  77. * @v ll_dest Destination link-layer address
  78. * @ret rc Return status code
  79. *
  80. * Prepends link-layer headers to the packet buffer and transmits the
  81. * packet via the specified network device. This function takes
  82. * ownership of the packet buffer.
  83. */
  84. int net_tx ( struct pk_buff *pkb, struct net_device *netdev,
  85. struct net_protocol *net_protocol, const void *ll_dest ) {
  86. return netdev->ll_protocol->tx ( pkb, netdev, net_protocol, ll_dest );
  87. }
  88. /**
  89. * Process received network-layer packet
  90. *
  91. * @v pkb Packet buffer
  92. * @v netdev Network device
  93. * @v net_proto Network-layer protocol, in network-byte order
  94. * @v ll_source Source link-layer address
  95. */
  96. void net_rx ( struct pk_buff *pkb, struct net_device *netdev,
  97. uint16_t net_proto, const void *ll_source ) {
  98. struct net_protocol *net_protocol;
  99. /* Hand off to network-layer protocol, if any */
  100. for ( net_protocol = net_protocols ; net_protocol < net_protocols_end ;
  101. net_protocol++ ) {
  102. if ( net_protocol->net_proto == net_proto ) {
  103. net_protocol->rx ( pkb, netdev, ll_source );
  104. break;
  105. }
  106. }
  107. }
  108. /**
  109. * Poll for packet on network device
  110. *
  111. * @v netdev Network device
  112. * @ret True There are packets present in the receive queue
  113. * @ret False There are no packets present in the receive queue
  114. *
  115. * Polls the network device for received packets. Any received
  116. * packets will be added to the RX packet queue via netdev_rx().
  117. */
  118. int netdev_poll ( struct net_device *netdev ) {
  119. netdev->poll ( netdev );
  120. return ( ! list_empty ( &netdev->rx_queue ) );
  121. }
  122. /**
  123. * Remove packet from device's receive queue
  124. *
  125. * @v netdev Network device
  126. * @ret pkb Packet buffer, or NULL
  127. *
  128. * Removes the first packet from the device's RX queue and returns it.
  129. * Ownership of the packet is transferred to the caller.
  130. */
  131. struct pk_buff * netdev_rx_dequeue ( struct net_device *netdev ) {
  132. struct pk_buff *pkb;
  133. list_for_each_entry ( pkb, &netdev->rx_queue, list ) {
  134. list_del ( &pkb->list );
  135. return pkb;
  136. }
  137. return NULL;
  138. }
  139. /**
  140. * Allocate network device
  141. *
  142. * @v priv_size Size of private data area (net_device::priv)
  143. * @ret netdev Network device, or NULL
  144. *
  145. * Allocates space for a network device and its private data area.
  146. */
  147. struct net_device * alloc_netdev ( size_t priv_size ) {
  148. struct net_device *netdev;
  149. netdev = calloc ( 1, sizeof ( *netdev ) + priv_size );
  150. if ( netdev ) {
  151. INIT_LIST_HEAD ( &netdev->rx_queue );
  152. netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
  153. }
  154. return netdev;
  155. }
  156. /**
  157. * Register network device
  158. *
  159. * @v netdev Network device
  160. * @ret rc Return status code
  161. *
  162. * Adds the network device to the list of network devices.
  163. */
  164. int register_netdev ( struct net_device *netdev ) {
  165. #warning "Remove this static IP address hack"
  166. {
  167. const struct in_addr static_address = { htonl ( 0x0afefe01 ) };
  168. const struct in_addr static_netmask = { htonl ( 0xffffff00 ) };
  169. const struct in_addr static_gateway = { INADDR_NONE };
  170. int rc;
  171. if ( ( rc = add_ipv4_address ( netdev, static_address,
  172. static_netmask,
  173. static_gateway ) ) != 0 )
  174. return rc;
  175. }
  176. /* Add to device list */
  177. list_add_tail ( &netdev->list, &net_devices );
  178. DBG ( "%s registered\n", netdev_name ( netdev ) );
  179. return 0;
  180. }
  181. /**
  182. * Unregister network device
  183. *
  184. * @v netdev Network device
  185. *
  186. * Removes the network device from the list of network devices.
  187. */
  188. void unregister_netdev ( struct net_device *netdev ) {
  189. struct pk_buff *pkb;
  190. #warning "Remove this static IP address hack"
  191. del_ipv4_address ( netdev );
  192. /* Discard any packets in the RX queue */
  193. while ( ( pkb = netdev_rx_dequeue ( netdev ) ) ) {
  194. DBG ( "%s discarding %p+%zx\n", netdev_name ( netdev ),
  195. pkb->data, pkb_len ( pkb ) );
  196. free_pkb ( pkb );
  197. }
  198. /* Remove from device list */
  199. list_del ( &netdev->list );
  200. DBG ( "%s unregistered\n", netdev_name ( netdev ) );
  201. }
  202. /**
  203. * Free network device
  204. *
  205. * @v netdev Network device
  206. */
  207. void free_netdev ( struct net_device *netdev ) {
  208. free ( netdev );
  209. }
  210. /**
  211. * Iterate through network devices
  212. *
  213. * @ret netdev Network device, or NULL
  214. *
  215. * This returns the registered network devices in the order of
  216. * registration. If no network devices are registered, it will return
  217. * NULL.
  218. */
  219. struct net_device * next_netdev ( void ) {
  220. struct net_device *netdev;
  221. list_for_each_entry ( netdev, &net_devices, list ) {
  222. list_del ( &netdev->list );
  223. list_add_tail ( &netdev->list, &net_devices );
  224. return netdev;
  225. }
  226. return NULL;
  227. }
  228. /**
  229. * Single-step the network stack
  230. *
  231. * @v process Network stack process
  232. *
  233. * This polls all interfaces for any received packets, and processes
  234. * at most one packet from the RX queue.
  235. *
  236. * We avoid processing all received packets, because processing the
  237. * received packet can trigger transmission of a new packet (e.g. an
  238. * ARP response). Since TX completions will be processed as part of
  239. * the poll operation, it is easy to overflow small TX queues if
  240. * multiple packets are processed per poll.
  241. */
  242. static void net_step ( struct process *process ) {
  243. struct net_device *netdev;
  244. struct pk_buff *pkb;
  245. /* Poll and process each network device */
  246. list_for_each_entry ( netdev, &net_devices, list ) {
  247. /* Poll for new packets */
  248. netdev_poll ( netdev );
  249. /* Handle at most one received packet per poll */
  250. if ( ( pkb = netdev_rx_dequeue ( netdev ) ) ) {
  251. DBG ( "%s processing %p+%zx\n", netdev_name ( netdev ),
  252. pkb->data, pkb_len ( pkb ) );
  253. netdev->ll_protocol->rx ( pkb, netdev );
  254. }
  255. }
  256. /* Re-schedule ourself */
  257. schedule ( process );
  258. }
  259. /** Networking stack process */
  260. static struct process net_process = {
  261. .step = net_step,
  262. };
  263. /** Initialise the networking stack process */
  264. static void init_net ( void ) {
  265. schedule ( &net_process );
  266. }
  267. INIT_FN ( INIT_PROCESS, init_net, NULL, NULL );