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 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  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 <stdlib.h>
  20. #include <stdio.h>
  21. #include <byteswap.h>
  22. #include <string.h>
  23. #include <errno.h>
  24. #include <gpxe/if_ether.h>
  25. #include <gpxe/pkbuff.h>
  26. #include <gpxe/tables.h>
  27. #include <gpxe/process.h>
  28. #include <gpxe/init.h>
  29. #include <gpxe/device.h>
  30. #include <gpxe/netdevice.h>
  31. /** @file
  32. *
  33. * Network device management
  34. *
  35. */
  36. /** Registered network-layer protocols */
  37. static struct net_protocol net_protocols[0]
  38. __table_start ( struct net_protocol, net_protocols );
  39. static struct net_protocol net_protocols_end[0]
  40. __table_end ( struct net_protocol, net_protocols );
  41. /** List of network devices */
  42. struct list_head net_devices = LIST_HEAD_INIT ( net_devices );
  43. /**
  44. * Transmit raw packet via network device
  45. *
  46. * @v netdev Network device
  47. * @v pkb Packet buffer
  48. * @ret rc Return status code
  49. *
  50. * Transmits the packet via the specified network device. This
  51. * function takes ownership of the packet buffer.
  52. */
  53. int netdev_tx ( struct net_device *netdev, struct pk_buff *pkb ) {
  54. int rc;
  55. DBGC ( netdev, "NETDEV %p transmitting %p (%p+%zx)\n",
  56. netdev, pkb, pkb->data, pkb_len ( pkb ) );
  57. list_add_tail ( &pkb->list, &netdev->tx_queue );
  58. if ( ! ( netdev->state & NETDEV_OPEN ) ) {
  59. rc = -ENETUNREACH;
  60. goto err;
  61. }
  62. if ( ( rc = netdev->transmit ( netdev, pkb ) ) != 0 )
  63. goto err;
  64. return 0;
  65. err:
  66. DBGC ( netdev, "NETDEV %p transmission %p failed: %s\n",
  67. netdev, pkb, strerror ( rc ) );
  68. netdev_tx_complete ( netdev, pkb );
  69. return rc;
  70. }
  71. /**
  72. * Complete network transmission
  73. *
  74. * @v netdev Network device
  75. * @v pkb Packet buffer
  76. *
  77. * The packet must currently be in the network device's TX queue.
  78. */
  79. void netdev_tx_complete ( struct net_device *netdev, struct pk_buff *pkb ) {
  80. DBGC ( netdev, "NETDEV %p transmission %p complete\n", netdev, pkb );
  81. /* Catch data corruption as early as possible */
  82. assert ( pkb->list.next != NULL );
  83. assert ( pkb->list.prev != NULL );
  84. list_del ( &pkb->list );
  85. free_pkb ( pkb );
  86. }
  87. /**
  88. * Complete network transmission
  89. *
  90. * @v netdev Network device
  91. *
  92. * Completes the oldest outstanding packet in the TX queue.
  93. */
  94. void netdev_tx_complete_next ( struct net_device *netdev ) {
  95. struct pk_buff *pkb;
  96. list_for_each_entry ( pkb, &netdev->tx_queue, list ) {
  97. netdev_tx_complete ( netdev, pkb );
  98. return;
  99. }
  100. }
  101. /**
  102. * Add packet to receive queue
  103. *
  104. * @v netdev Network device
  105. * @v pkb Packet buffer
  106. *
  107. * The packet is added to the network device's RX queue. This
  108. * function takes ownership of the packet buffer.
  109. */
  110. void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb ) {
  111. DBGC ( netdev, "NETDEV %p received %p (%p+%zx)\n",
  112. netdev, pkb, pkb->data, pkb_len ( pkb ) );
  113. list_add_tail ( &pkb->list, &netdev->rx_queue );
  114. }
  115. /**
  116. * Poll for packet on network device
  117. *
  118. * @v netdev Network device
  119. * @v rx_quota Maximum number of packets to receive
  120. * @ret True There are packets present in the receive queue
  121. * @ret False There are no packets present in the receive queue
  122. *
  123. * Polls the network device for received packets. Any received
  124. * packets will be added to the RX packet queue via netdev_rx().
  125. */
  126. int netdev_poll ( struct net_device *netdev, unsigned int rx_quota ) {
  127. if ( netdev->state & NETDEV_OPEN )
  128. netdev->poll ( netdev, rx_quota );
  129. return ( ! list_empty ( &netdev->rx_queue ) );
  130. }
  131. /**
  132. * Remove packet from device's receive queue
  133. *
  134. * @v netdev Network device
  135. * @ret pkb Packet buffer, or NULL
  136. *
  137. * Removes the first packet from the device's RX queue and returns it.
  138. * Ownership of the packet is transferred to the caller.
  139. */
  140. struct pk_buff * netdev_rx_dequeue ( struct net_device *netdev ) {
  141. struct pk_buff *pkb;
  142. list_for_each_entry ( pkb, &netdev->rx_queue, list ) {
  143. list_del ( &pkb->list );
  144. return pkb;
  145. }
  146. return NULL;
  147. }
  148. /**
  149. * Allocate network device
  150. *
  151. * @v priv_size Size of private data area (net_device::priv)
  152. * @ret netdev Network device, or NULL
  153. *
  154. * Allocates space for a network device and its private data area.
  155. */
  156. struct net_device * alloc_netdev ( size_t priv_size ) {
  157. struct net_device *netdev;
  158. size_t total_len;
  159. total_len = ( sizeof ( *netdev ) + priv_size );
  160. netdev = malloc ( total_len );
  161. if ( netdev ) {
  162. memset ( netdev, 0, total_len );
  163. INIT_LIST_HEAD ( &netdev->references );
  164. INIT_LIST_HEAD ( &netdev->tx_queue );
  165. INIT_LIST_HEAD ( &netdev->rx_queue );
  166. netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
  167. }
  168. return netdev;
  169. }
  170. /**
  171. * Register network device
  172. *
  173. * @v netdev Network device
  174. * @ret rc Return status code
  175. *
  176. * Gives the network device a name and adds it to the list of network
  177. * devices.
  178. */
  179. int register_netdev ( struct net_device *netdev ) {
  180. static unsigned int ifindex = 0;
  181. /* Create device name */
  182. snprintf ( netdev->name, sizeof ( netdev->name ), "net%d",
  183. ifindex++ );
  184. /* Add to device list */
  185. list_add_tail ( &netdev->list, &net_devices );
  186. DBGC ( netdev, "NETDEV %p registered as %s (phys %s hwaddr %s)\n",
  187. netdev, netdev->name, netdev->dev->name,
  188. netdev_hwaddr ( netdev ) );
  189. return 0;
  190. }
  191. /**
  192. * Open network device
  193. *
  194. * @v netdev Network device
  195. * @ret rc Return status code
  196. */
  197. int netdev_open ( struct net_device *netdev ) {
  198. int rc;
  199. /* Do nothing if device is already open */
  200. if ( netdev->state & NETDEV_OPEN )
  201. return 0;
  202. DBGC ( netdev, "NETDEV %p opening\n", netdev );
  203. /* Open the device */
  204. if ( ( rc = netdev->open ( netdev ) ) != 0 )
  205. return rc;
  206. /* Mark as opened */
  207. netdev->state |= NETDEV_OPEN;
  208. return 0;
  209. }
  210. /**
  211. * Close network device
  212. *
  213. * @v netdev Network device
  214. */
  215. void netdev_close ( struct net_device *netdev ) {
  216. struct pk_buff *pkb;
  217. /* Do nothing if device is already closed */
  218. if ( ! ( netdev->state & NETDEV_OPEN ) )
  219. return;
  220. DBGC ( netdev, "NETDEV %p closing\n", netdev );
  221. /* Close the device */
  222. netdev->close ( netdev );
  223. /* Discard any packets in the TX queue */
  224. while ( ! list_empty ( &netdev->tx_queue ) ) {
  225. netdev_tx_complete_next ( netdev );
  226. }
  227. /* Discard any packets in the RX queue */
  228. while ( ( pkb = netdev_rx_dequeue ( netdev ) ) ) {
  229. DBGC ( netdev, "NETDEV %p discarding received %p\n",
  230. netdev, pkb );
  231. free_pkb ( pkb );
  232. }
  233. /* Mark as closed */
  234. netdev->state &= ~NETDEV_OPEN;
  235. }
  236. /**
  237. * Unregister network device
  238. *
  239. * @v netdev Network device
  240. *
  241. * Removes the network device from the list of network devices.
  242. */
  243. void unregister_netdev ( struct net_device *netdev ) {
  244. /* Ensure device is closed */
  245. netdev_close ( netdev );
  246. /* Kill off any persistent references to this device */
  247. forget_references ( &netdev->references );
  248. /* Remove from device list */
  249. list_del ( &netdev->list );
  250. DBGC ( netdev, "NETDEV %p unregistered\n", netdev );
  251. }
  252. /**
  253. * Free network device
  254. *
  255. * @v netdev Network device
  256. */
  257. void free_netdev ( struct net_device *netdev ) {
  258. free ( netdev );
  259. }
  260. /**
  261. * Get network device by name
  262. *
  263. * @v name Network device name
  264. * @ret netdev Network device, or NULL
  265. */
  266. struct net_device * find_netdev ( const char *name ) {
  267. struct net_device *netdev;
  268. list_for_each_entry ( netdev, &net_devices, list ) {
  269. if ( strcmp ( netdev->name, name ) == 0 )
  270. return netdev;
  271. }
  272. return NULL;
  273. }
  274. /**
  275. * Get network device by PCI bus:dev.fn address
  276. *
  277. * @v busdevfn PCI bus:dev.fn address
  278. * @ret netdev Network device, or NULL
  279. */
  280. struct net_device * find_pci_netdev ( unsigned int busdevfn ) {
  281. struct net_device *netdev;
  282. list_for_each_entry ( netdev, &net_devices, list ) {
  283. if ( ( netdev->dev->desc.bus_type == BUS_TYPE_PCI ) &&
  284. ( netdev->dev->desc.pci.busdevfn == busdevfn ) )
  285. return netdev;
  286. }
  287. return NULL;
  288. }
  289. /**
  290. * Transmit network-layer packet
  291. *
  292. * @v pkb Packet buffer
  293. * @v netdev Network device
  294. * @v net_protocol Network-layer protocol
  295. * @v ll_dest Destination link-layer address
  296. * @ret rc Return status code
  297. *
  298. * Prepends link-layer headers to the packet buffer and transmits the
  299. * packet via the specified network device. This function takes
  300. * ownership of the packet buffer.
  301. */
  302. int net_tx ( struct pk_buff *pkb, struct net_device *netdev,
  303. struct net_protocol *net_protocol, const void *ll_dest ) {
  304. return netdev->ll_protocol->tx ( pkb, netdev, net_protocol, ll_dest );
  305. }
  306. /**
  307. * Process received network-layer packet
  308. *
  309. * @v pkb Packet buffer
  310. * @v netdev Network device
  311. * @v net_proto Network-layer protocol, in network-byte order
  312. * @v ll_source Source link-layer address
  313. * @ret rc Return status code
  314. */
  315. int net_rx ( struct pk_buff *pkb, struct net_device *netdev,
  316. uint16_t net_proto, const void *ll_source ) {
  317. struct net_protocol *net_protocol;
  318. /* Hand off to network-layer protocol, if any */
  319. for ( net_protocol = net_protocols ; net_protocol < net_protocols_end ;
  320. net_protocol++ ) {
  321. if ( net_protocol->net_proto == net_proto ) {
  322. return net_protocol->rx ( pkb, netdev, ll_source );
  323. }
  324. }
  325. free_pkb ( pkb );
  326. return 0;
  327. }
  328. /**
  329. * Single-step the network stack
  330. *
  331. * @v process Network stack process
  332. *
  333. * This polls all interfaces for received packets, and processes
  334. * packets from the RX queue.
  335. */
  336. static void net_step ( struct process *process ) {
  337. struct net_device *netdev;
  338. struct pk_buff *pkb;
  339. /* Poll and process each network device */
  340. list_for_each_entry ( netdev, &net_devices, list ) {
  341. /* Poll for new packets */
  342. netdev_poll ( netdev, -1U );
  343. /* Process at most one received packet. Give priority
  344. * to getting packets out of the NIC over processing
  345. * the received packets, because we advertise a window
  346. * that assumes that we can receive packets from the
  347. * NIC faster than they arrive.
  348. */
  349. if ( ( pkb = netdev_rx_dequeue ( netdev ) ) ) {
  350. DBGC ( netdev, "NETDEV %p processing %p\n",
  351. netdev, pkb );
  352. netdev->ll_protocol->rx ( pkb, netdev );
  353. }
  354. }
  355. /* Re-schedule ourself */
  356. schedule ( process );
  357. }
  358. /** Networking stack process */
  359. static struct process net_process = {
  360. .step = net_step,
  361. };
  362. /** Initialise the networking stack process */
  363. static void init_net ( void ) {
  364. schedule ( &net_process );
  365. }
  366. INIT_FN ( INIT_PROCESS, init_net, NULL, NULL );