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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  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. FILE_LICENCE ( GPL2_OR_LATER );
  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 <config/general.h>
  26. #include <ipxe/if_ether.h>
  27. #include <ipxe/iobuf.h>
  28. #include <ipxe/tables.h>
  29. #include <ipxe/process.h>
  30. #include <ipxe/init.h>
  31. #include <ipxe/device.h>
  32. #include <ipxe/errortab.h>
  33. #include <ipxe/netdevice.h>
  34. /** @file
  35. *
  36. * Network device management
  37. *
  38. */
  39. /** List of network devices */
  40. struct list_head net_devices = LIST_HEAD_INIT ( net_devices );
  41. /** List of open network devices, in reverse order of opening */
  42. static struct list_head open_net_devices = LIST_HEAD_INIT ( open_net_devices );
  43. /** Default unknown link status code */
  44. #define EUNKNOWN_LINK_STATUS __einfo_error ( EINFO_EUNKNOWN_LINK_STATUS )
  45. #define EINFO_EUNKNOWN_LINK_STATUS \
  46. __einfo_uniqify ( EINFO_EINPROGRESS, 0x01, "Unknown" )
  47. /** Default link-down status code */
  48. #define ENOTCONN_LINK_DOWN __einfo_error ( EINFO_ENOTCONN_LINK_DOWN )
  49. #define EINFO_ENOTCONN_LINK_DOWN \
  50. __einfo_uniqify ( EINFO_ENOTCONN, 0x01, "Down" )
  51. /** Human-readable message for the default link statuses */
  52. struct errortab netdev_errors[] __errortab = {
  53. __einfo_errortab ( EINFO_EUNKNOWN_LINK_STATUS ),
  54. __einfo_errortab ( EINFO_ENOTCONN_LINK_DOWN ),
  55. };
  56. /**
  57. * Notify drivers of network device or link state change
  58. *
  59. * @v netdev Network device
  60. */
  61. static void netdev_notify ( struct net_device *netdev ) {
  62. struct net_driver *driver;
  63. for_each_table_entry ( driver, NET_DRIVERS )
  64. driver->notify ( netdev );
  65. }
  66. /**
  67. * Mark network device as having a specific link state
  68. *
  69. * @v netdev Network device
  70. * @v rc Link status code
  71. */
  72. void netdev_link_err ( struct net_device *netdev, int rc ) {
  73. /* Record link state */
  74. netdev->link_rc = rc;
  75. if ( netdev->link_rc == 0 ) {
  76. DBGC ( netdev, "NETDEV %s link is up\n", netdev->name );
  77. } else {
  78. DBGC ( netdev, "NETDEV %s link is down: %s\n",
  79. netdev->name, strerror ( netdev->link_rc ) );
  80. }
  81. /* Notify drivers of link state change */
  82. netdev_notify ( netdev );
  83. }
  84. /**
  85. * Mark network device as having link down
  86. *
  87. * @v netdev Network device
  88. */
  89. void netdev_link_down ( struct net_device *netdev ) {
  90. /* Avoid clobbering a more detailed link status code, if one
  91. * is already set.
  92. */
  93. if ( ( netdev->link_rc == 0 ) ||
  94. ( netdev->link_rc == -EUNKNOWN_LINK_STATUS ) ) {
  95. netdev_link_err ( netdev, -ENOTCONN_LINK_DOWN );
  96. }
  97. }
  98. /**
  99. * Record network device statistic
  100. *
  101. * @v stats Network device statistics
  102. * @v rc Status code
  103. */
  104. static void netdev_record_stat ( struct net_device_stats *stats, int rc ) {
  105. struct net_device_error *error;
  106. struct net_device_error *least_common_error;
  107. unsigned int i;
  108. /* If this is not an error, just update the good counter */
  109. if ( rc == 0 ) {
  110. stats->good++;
  111. return;
  112. }
  113. /* Update the bad counter */
  114. stats->bad++;
  115. /* Locate the appropriate error record */
  116. least_common_error = &stats->errors[0];
  117. for ( i = 0 ; i < ( sizeof ( stats->errors ) /
  118. sizeof ( stats->errors[0] ) ) ; i++ ) {
  119. error = &stats->errors[i];
  120. /* Update matching record, if found */
  121. if ( error->rc == rc ) {
  122. error->count++;
  123. return;
  124. }
  125. if ( error->count < least_common_error->count )
  126. least_common_error = error;
  127. }
  128. /* Overwrite the least common error record */
  129. least_common_error->rc = rc;
  130. least_common_error->count = 1;
  131. }
  132. /**
  133. * Transmit raw packet via network device
  134. *
  135. * @v netdev Network device
  136. * @v iobuf I/O buffer
  137. * @ret rc Return status code
  138. *
  139. * Transmits the packet via the specified network device. This
  140. * function takes ownership of the I/O buffer.
  141. */
  142. int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf ) {
  143. int rc;
  144. DBGC2 ( netdev, "NETDEV %s transmitting %p (%p+%zx)\n",
  145. netdev->name, iobuf, iobuf->data, iob_len ( iobuf ) );
  146. /* Enqueue packet */
  147. list_add_tail ( &iobuf->list, &netdev->tx_queue );
  148. /* Avoid calling transmit() on unopened network devices */
  149. if ( ! netdev_is_open ( netdev ) ) {
  150. rc = -ENETUNREACH;
  151. goto err;
  152. }
  153. /* Discard packet (for test purposes) if applicable */
  154. if ( ( NETDEV_DISCARD_RATE > 0 ) &&
  155. ( ( random() % NETDEV_DISCARD_RATE ) == 0 ) ) {
  156. rc = -EAGAIN;
  157. goto err;
  158. }
  159. /* Transmit packet */
  160. if ( ( rc = netdev->op->transmit ( netdev, iobuf ) ) != 0 )
  161. goto err;
  162. return 0;
  163. err:
  164. netdev_tx_complete_err ( netdev, iobuf, rc );
  165. return rc;
  166. }
  167. /**
  168. * Discard transmitted packet
  169. *
  170. * @v netdev Network device
  171. * @v iobuf I/O buffer, or NULL
  172. * @v rc Packet status code
  173. *
  174. * The packet is discarded and a TX error is recorded. This function
  175. * takes ownership of the I/O buffer.
  176. */
  177. void netdev_tx_err ( struct net_device *netdev,
  178. struct io_buffer *iobuf, int rc ) {
  179. /* Update statistics counter */
  180. netdev_record_stat ( &netdev->tx_stats, rc );
  181. if ( rc == 0 ) {
  182. DBGC2 ( netdev, "NETDEV %s transmission %p complete\n",
  183. netdev->name, iobuf );
  184. } else {
  185. DBGC ( netdev, "NETDEV %s transmission %p failed: %s\n",
  186. netdev->name, iobuf, strerror ( rc ) );
  187. }
  188. /* Discard packet */
  189. free_iob ( iobuf );
  190. }
  191. /**
  192. * Complete network transmission
  193. *
  194. * @v netdev Network device
  195. * @v iobuf I/O buffer
  196. * @v rc Packet status code
  197. *
  198. * The packet must currently be in the network device's TX queue.
  199. */
  200. void netdev_tx_complete_err ( struct net_device *netdev,
  201. struct io_buffer *iobuf, int rc ) {
  202. /* Catch data corruption as early as possible */
  203. list_check_contains ( iobuf, &netdev->tx_queue, list );
  204. /* Dequeue and free I/O buffer */
  205. list_del ( &iobuf->list );
  206. netdev_tx_err ( netdev, iobuf, rc );
  207. }
  208. /**
  209. * Complete network transmission
  210. *
  211. * @v netdev Network device
  212. * @v rc Packet status code
  213. *
  214. * Completes the oldest outstanding packet in the TX queue.
  215. */
  216. void netdev_tx_complete_next_err ( struct net_device *netdev, int rc ) {
  217. struct io_buffer *iobuf;
  218. list_for_each_entry ( iobuf, &netdev->tx_queue, list ) {
  219. netdev_tx_complete_err ( netdev, iobuf, rc );
  220. return;
  221. }
  222. }
  223. /**
  224. * Flush device's transmit queue
  225. *
  226. * @v netdev Network device
  227. */
  228. static void netdev_tx_flush ( struct net_device *netdev ) {
  229. /* Discard any packets in the TX queue */
  230. while ( ! list_empty ( &netdev->tx_queue ) ) {
  231. netdev_tx_complete_next_err ( netdev, -ECANCELED );
  232. }
  233. }
  234. /**
  235. * Add packet to receive queue
  236. *
  237. * @v netdev Network device
  238. * @v iobuf I/O buffer, or NULL
  239. *
  240. * The packet is added to the network device's RX queue. This
  241. * function takes ownership of the I/O buffer.
  242. */
  243. void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf ) {
  244. DBGC2 ( netdev, "NETDEV %s received %p (%p+%zx)\n",
  245. netdev->name, iobuf, iobuf->data, iob_len ( iobuf ) );
  246. /* Discard packet (for test purposes) if applicable */
  247. if ( ( NETDEV_DISCARD_RATE > 0 ) &&
  248. ( ( random() % NETDEV_DISCARD_RATE ) == 0 ) ) {
  249. netdev_rx_err ( netdev, iobuf, -EAGAIN );
  250. return;
  251. }
  252. /* Enqueue packet */
  253. list_add_tail ( &iobuf->list, &netdev->rx_queue );
  254. /* Update statistics counter */
  255. netdev_record_stat ( &netdev->rx_stats, 0 );
  256. }
  257. /**
  258. * Discard received packet
  259. *
  260. * @v netdev Network device
  261. * @v iobuf I/O buffer, or NULL
  262. * @v rc Packet status code
  263. *
  264. * The packet is discarded and an RX error is recorded. This function
  265. * takes ownership of the I/O buffer. @c iobuf may be NULL if, for
  266. * example, the net device wishes to report an error due to being
  267. * unable to allocate an I/O buffer.
  268. */
  269. void netdev_rx_err ( struct net_device *netdev,
  270. struct io_buffer *iobuf, int rc ) {
  271. DBGC ( netdev, "NETDEV %s failed to receive %p: %s\n",
  272. netdev->name, iobuf, strerror ( rc ) );
  273. /* Discard packet */
  274. free_iob ( iobuf );
  275. /* Update statistics counter */
  276. netdev_record_stat ( &netdev->rx_stats, rc );
  277. }
  278. /**
  279. * Poll for completed and received packets on network device
  280. *
  281. * @v netdev Network device
  282. *
  283. * Polls the network device for completed transmissions and received
  284. * packets. Any received packets will be added to the RX packet queue
  285. * via netdev_rx().
  286. */
  287. void netdev_poll ( struct net_device *netdev ) {
  288. if ( netdev_is_open ( netdev ) )
  289. netdev->op->poll ( netdev );
  290. }
  291. /**
  292. * Remove packet from device's receive queue
  293. *
  294. * @v netdev Network device
  295. * @ret iobuf I/O buffer, or NULL
  296. *
  297. * Removes the first packet from the device's RX queue and returns it.
  298. * Ownership of the packet is transferred to the caller.
  299. */
  300. struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev ) {
  301. struct io_buffer *iobuf;
  302. iobuf = list_first_entry ( &netdev->rx_queue, struct io_buffer, list );
  303. if ( ! iobuf )
  304. return NULL;
  305. list_del ( &iobuf->list );
  306. return iobuf;
  307. }
  308. /**
  309. * Flush device's receive queue
  310. *
  311. * @v netdev Network device
  312. */
  313. static void netdev_rx_flush ( struct net_device *netdev ) {
  314. struct io_buffer *iobuf;
  315. /* Discard any packets in the RX queue */
  316. while ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) {
  317. netdev_rx_err ( netdev, iobuf, -ECANCELED );
  318. }
  319. }
  320. /**
  321. * Free network device
  322. *
  323. * @v refcnt Network device reference counter
  324. */
  325. static void free_netdev ( struct refcnt *refcnt ) {
  326. struct net_device *netdev =
  327. container_of ( refcnt, struct net_device, refcnt );
  328. netdev_tx_flush ( netdev );
  329. netdev_rx_flush ( netdev );
  330. clear_settings ( netdev_settings ( netdev ) );
  331. free ( netdev );
  332. }
  333. /**
  334. * Allocate network device
  335. *
  336. * @v priv_size Size of private data area (net_device::priv)
  337. * @ret netdev Network device, or NULL
  338. *
  339. * Allocates space for a network device and its private data area.
  340. */
  341. struct net_device * alloc_netdev ( size_t priv_size ) {
  342. struct net_device *netdev;
  343. size_t total_len;
  344. total_len = ( sizeof ( *netdev ) + priv_size );
  345. netdev = zalloc ( total_len );
  346. if ( netdev ) {
  347. ref_init ( &netdev->refcnt, free_netdev );
  348. netdev->link_rc = -EUNKNOWN_LINK_STATUS;
  349. INIT_LIST_HEAD ( &netdev->tx_queue );
  350. INIT_LIST_HEAD ( &netdev->rx_queue );
  351. netdev_settings_init ( netdev );
  352. netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
  353. }
  354. return netdev;
  355. }
  356. /**
  357. * Register network device
  358. *
  359. * @v netdev Network device
  360. * @ret rc Return status code
  361. *
  362. * Gives the network device a name and adds it to the list of network
  363. * devices.
  364. */
  365. int register_netdev ( struct net_device *netdev ) {
  366. static unsigned int ifindex = 0;
  367. struct net_driver *driver;
  368. int rc;
  369. /* Create device name */
  370. if ( netdev->name[0] == '\0' ) {
  371. snprintf ( netdev->name, sizeof ( netdev->name ), "net%d",
  372. ifindex++ );
  373. }
  374. /* Set initial link-layer address */
  375. netdev->ll_protocol->init_addr ( netdev->hw_addr, netdev->ll_addr );
  376. /* Add to device list */
  377. netdev_get ( netdev );
  378. list_add_tail ( &netdev->list, &net_devices );
  379. DBGC ( netdev, "NETDEV %s registered (phys %s hwaddr %s)\n",
  380. netdev->name, netdev->dev->name,
  381. netdev_addr ( netdev ) );
  382. /* Register per-netdev configuration settings */
  383. if ( ( rc = register_settings ( netdev_settings ( netdev ),
  384. NULL, netdev->name ) ) != 0 ) {
  385. DBGC ( netdev, "NETDEV %s could not register settings: %s\n",
  386. netdev->name, strerror ( rc ) );
  387. goto err_register_settings;
  388. }
  389. /* Probe device */
  390. for_each_table_entry ( driver, NET_DRIVERS ) {
  391. if ( ( rc = driver->probe ( netdev ) ) != 0 ) {
  392. DBGC ( netdev, "NETDEV %s could not add %s device: "
  393. "%s\n", netdev->name, driver->name,
  394. strerror ( rc ) );
  395. goto err_probe;
  396. }
  397. }
  398. return 0;
  399. err_probe:
  400. for_each_table_entry_continue_reverse ( driver, NET_DRIVERS )
  401. driver->remove ( netdev );
  402. unregister_settings ( netdev_settings ( netdev ) );
  403. err_register_settings:
  404. return rc;
  405. }
  406. /**
  407. * Open network device
  408. *
  409. * @v netdev Network device
  410. * @ret rc Return status code
  411. */
  412. int netdev_open ( struct net_device *netdev ) {
  413. int rc;
  414. /* Do nothing if device is already open */
  415. if ( netdev->state & NETDEV_OPEN )
  416. return 0;
  417. DBGC ( netdev, "NETDEV %s opening\n", netdev->name );
  418. /* Open the device */
  419. if ( ( rc = netdev->op->open ( netdev ) ) != 0 )
  420. return rc;
  421. /* Mark as opened */
  422. netdev->state |= NETDEV_OPEN;
  423. /* Add to head of open devices list */
  424. list_add ( &netdev->open_list, &open_net_devices );
  425. /* Notify drivers of device state change */
  426. netdev_notify ( netdev );
  427. return 0;
  428. }
  429. /**
  430. * Close network device
  431. *
  432. * @v netdev Network device
  433. */
  434. void netdev_close ( struct net_device *netdev ) {
  435. /* Do nothing if device is already closed */
  436. if ( ! ( netdev->state & NETDEV_OPEN ) )
  437. return;
  438. DBGC ( netdev, "NETDEV %s closing\n", netdev->name );
  439. /* Remove from open devices list */
  440. list_del ( &netdev->open_list );
  441. /* Mark as closed */
  442. netdev->state &= ~NETDEV_OPEN;
  443. /* Notify drivers of device state change */
  444. netdev_notify ( netdev );
  445. /* Close the device */
  446. netdev->op->close ( netdev );
  447. /* Flush TX and RX queues */
  448. netdev_tx_flush ( netdev );
  449. netdev_rx_flush ( netdev );
  450. }
  451. /**
  452. * Unregister network device
  453. *
  454. * @v netdev Network device
  455. *
  456. * Removes the network device from the list of network devices.
  457. */
  458. void unregister_netdev ( struct net_device *netdev ) {
  459. struct net_driver *driver;
  460. /* Ensure device is closed */
  461. netdev_close ( netdev );
  462. /* Remove device */
  463. for_each_table_entry_reverse ( driver, NET_DRIVERS )
  464. driver->remove ( netdev );
  465. /* Unregister per-netdev configuration settings */
  466. unregister_settings ( netdev_settings ( netdev ) );
  467. /* Remove from device list */
  468. list_del ( &netdev->list );
  469. netdev_put ( netdev );
  470. DBGC ( netdev, "NETDEV %s unregistered\n", netdev->name );
  471. }
  472. /** Enable or disable interrupts
  473. *
  474. * @v netdev Network device
  475. * @v enable Interrupts should be enabled
  476. */
  477. void netdev_irq ( struct net_device *netdev, int enable ) {
  478. /* Do nothing if device does not support interrupts */
  479. if ( ! netdev_irq_supported ( netdev ) )
  480. return;
  481. /* Enable or disable device interrupts */
  482. netdev->op->irq ( netdev, enable );
  483. /* Record interrupt enabled state */
  484. netdev->state &= ~NETDEV_IRQ_ENABLED;
  485. if ( enable )
  486. netdev->state |= NETDEV_IRQ_ENABLED;
  487. }
  488. /**
  489. * Get network device by name
  490. *
  491. * @v name Network device name
  492. * @ret netdev Network device, or NULL
  493. */
  494. struct net_device * find_netdev ( const char *name ) {
  495. struct net_device *netdev;
  496. list_for_each_entry ( netdev, &net_devices, list ) {
  497. if ( strcmp ( netdev->name, name ) == 0 )
  498. return netdev;
  499. }
  500. return NULL;
  501. }
  502. /**
  503. * Get network device by PCI bus:dev.fn address
  504. *
  505. * @v bus_type Bus type
  506. * @v location Bus location
  507. * @ret netdev Network device, or NULL
  508. */
  509. struct net_device * find_netdev_by_location ( unsigned int bus_type,
  510. unsigned int location ) {
  511. struct net_device *netdev;
  512. list_for_each_entry ( netdev, &net_devices, list ) {
  513. if ( ( netdev->dev->desc.bus_type == bus_type ) &&
  514. ( netdev->dev->desc.location == location ) )
  515. return netdev;
  516. }
  517. return NULL;
  518. }
  519. /**
  520. * Get most recently opened network device
  521. *
  522. * @ret netdev Most recently opened network device, or NULL
  523. */
  524. struct net_device * last_opened_netdev ( void ) {
  525. struct net_device *netdev;
  526. netdev = list_first_entry ( &open_net_devices, struct net_device,
  527. open_list );
  528. if ( ! netdev )
  529. return NULL;
  530. assert ( netdev_is_open ( netdev ) );
  531. return netdev;
  532. }
  533. /**
  534. * Transmit network-layer packet
  535. *
  536. * @v iobuf I/O buffer
  537. * @v netdev Network device
  538. * @v net_protocol Network-layer protocol
  539. * @v ll_dest Destination link-layer address
  540. * @v ll_source Source link-layer address
  541. * @ret rc Return status code
  542. *
  543. * Prepends link-layer headers to the I/O buffer and transmits the
  544. * packet via the specified network device. This function takes
  545. * ownership of the I/O buffer.
  546. */
  547. int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
  548. struct net_protocol *net_protocol, const void *ll_dest,
  549. const void *ll_source ) {
  550. struct ll_protocol *ll_protocol = netdev->ll_protocol;
  551. int rc;
  552. /* Force a poll on the netdevice to (potentially) clear any
  553. * backed-up TX completions. This is needed on some network
  554. * devices to avoid excessive losses due to small TX ring
  555. * sizes.
  556. */
  557. netdev_poll ( netdev );
  558. /* Add link-layer header */
  559. if ( ( rc = ll_protocol->push ( netdev, iobuf, ll_dest, ll_source,
  560. net_protocol->net_proto ) ) != 0 ) {
  561. /* Record error for diagnosis */
  562. netdev_tx_err ( netdev, iobuf, rc );
  563. return rc;
  564. }
  565. /* Transmit packet */
  566. return netdev_tx ( netdev, iobuf );
  567. }
  568. /**
  569. * Process received network-layer packet
  570. *
  571. * @v iobuf I/O buffer
  572. * @v netdev Network device
  573. * @v net_proto Network-layer protocol, in network-byte order
  574. * @v ll_dest Destination link-layer address
  575. * @v ll_source Source link-layer address
  576. * @ret rc Return status code
  577. */
  578. int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
  579. uint16_t net_proto, const void *ll_dest, const void *ll_source ) {
  580. struct net_protocol *net_protocol;
  581. /* Hand off to network-layer protocol, if any */
  582. for_each_table_entry ( net_protocol, NET_PROTOCOLS ) {
  583. if ( net_protocol->net_proto == net_proto )
  584. return net_protocol->rx ( iobuf, netdev, ll_dest,
  585. ll_source );
  586. }
  587. DBGC ( netdev, "NETDEV %s unknown network protocol %04x\n",
  588. netdev->name, ntohs ( net_proto ) );
  589. free_iob ( iobuf );
  590. return -ENOTSUP;
  591. }
  592. /**
  593. * Poll the network stack
  594. *
  595. * This polls all interfaces for received packets, and processes
  596. * packets from the RX queue.
  597. */
  598. void net_poll ( void ) {
  599. struct net_device *netdev;
  600. struct io_buffer *iobuf;
  601. struct ll_protocol *ll_protocol;
  602. const void *ll_dest;
  603. const void *ll_source;
  604. uint16_t net_proto;
  605. int rc;
  606. /* Poll and process each network device */
  607. list_for_each_entry ( netdev, &net_devices, list ) {
  608. /* Poll for new packets */
  609. netdev_poll ( netdev );
  610. /* Leave received packets on the queue if receive
  611. * queue processing is currently frozen. This will
  612. * happen when the raw packets are to be manually
  613. * dequeued using netdev_rx_dequeue(), rather than
  614. * processed via the usual networking stack.
  615. */
  616. if ( netdev_rx_frozen ( netdev ) )
  617. continue;
  618. /* Process at most one received packet. Give priority
  619. * to getting packets out of the NIC over processing
  620. * the received packets, because we advertise a window
  621. * that assumes that we can receive packets from the
  622. * NIC faster than they arrive.
  623. */
  624. if ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) {
  625. DBGC2 ( netdev, "NETDEV %s processing %p (%p+%zx)\n",
  626. netdev->name, iobuf, iobuf->data,
  627. iob_len ( iobuf ) );
  628. /* Remove link-layer header */
  629. ll_protocol = netdev->ll_protocol;
  630. if ( ( rc = ll_protocol->pull ( netdev, iobuf,
  631. &ll_dest, &ll_source,
  632. &net_proto ) ) != 0 ) {
  633. free_iob ( iobuf );
  634. continue;
  635. }
  636. /* Hand packet to network layer */
  637. if ( ( rc = net_rx ( iob_disown ( iobuf ), netdev,
  638. net_proto, ll_dest,
  639. ll_source ) ) != 0 ) {
  640. /* Record error for diagnosis */
  641. netdev_rx_err ( netdev, NULL, rc );
  642. }
  643. }
  644. }
  645. }
  646. /**
  647. * Single-step the network stack
  648. *
  649. * @v process Network stack process
  650. */
  651. static void net_step ( struct process *process __unused ) {
  652. net_poll();
  653. }
  654. /** Networking stack process */
  655. PERMANENT_PROCESS ( net_process, net_step );