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.

efi_snp.c 31KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077
  1. /*
  2. * Copyright (C) 2008 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., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. */
  19. FILE_LICENCE ( GPL2_OR_LATER );
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <errno.h>
  23. #include <assert.h>
  24. #include <byteswap.h>
  25. #include <ipxe/netdevice.h>
  26. #include <ipxe/iobuf.h>
  27. #include <ipxe/in.h>
  28. #include <ipxe/pci.h>
  29. #include <ipxe/efi/efi.h>
  30. #include <ipxe/efi/efi_pci.h>
  31. #include <ipxe/efi/efi_driver.h>
  32. #include <ipxe/efi/efi_strings.h>
  33. #include <ipxe/efi/efi_snp.h>
  34. #include <config/general.h>
  35. #include <usr/autoboot.h>
  36. /** EFI simple network protocol GUID */
  37. static EFI_GUID efi_simple_network_protocol_guid
  38. = EFI_SIMPLE_NETWORK_PROTOCOL_GUID;
  39. /** EFI device path protocol GUID */
  40. static EFI_GUID efi_device_path_protocol_guid
  41. = EFI_DEVICE_PATH_PROTOCOL_GUID;
  42. /** EFI network interface identifier GUID */
  43. static EFI_GUID efi_nii_protocol_guid
  44. = EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID;
  45. /** EFI network interface identifier GUID (extra special version) */
  46. static EFI_GUID efi_nii31_protocol_guid = {
  47. /* At some point, it seems that someone decided to change the
  48. * GUID. Current EFI builds ignore the older GUID, older EFI
  49. * builds ignore the newer GUID, so we have to expose both.
  50. */
  51. 0x1ACED566, 0x76ED, 0x4218,
  52. { 0xBC, 0x81, 0x76, 0x7F, 0x1F, 0x97, 0x7A, 0x89 }
  53. };
  54. /** EFI component name protocol GUID */
  55. static EFI_GUID efi_component_name2_protocol_guid
  56. = EFI_COMPONENT_NAME2_PROTOCOL_GUID;
  57. /** EFI load file protocol GUID */
  58. static EFI_GUID efi_load_file_protocol_guid
  59. = EFI_LOAD_FILE_PROTOCOL_GUID;
  60. /** List of SNP devices */
  61. static LIST_HEAD ( efi_snp_devices );
  62. /**
  63. * Set EFI SNP mode based on iPXE net device parameters
  64. *
  65. * @v snp SNP interface
  66. */
  67. static void efi_snp_set_mode ( struct efi_snp_device *snpdev ) {
  68. struct net_device *netdev = snpdev->netdev;
  69. EFI_SIMPLE_NETWORK_MODE *mode = &snpdev->mode;
  70. struct ll_protocol *ll_protocol = netdev->ll_protocol;
  71. unsigned int ll_addr_len = ll_protocol->ll_addr_len;
  72. mode->HwAddressSize = ll_addr_len;
  73. mode->MediaHeaderSize = ll_protocol->ll_header_len;
  74. mode->MaxPacketSize = netdev->max_pkt_len;
  75. mode->ReceiveFilterMask = ( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
  76. EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST |
  77. EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST );
  78. assert ( ll_addr_len <= sizeof ( mode->CurrentAddress ) );
  79. memcpy ( &mode->CurrentAddress, netdev->ll_addr, ll_addr_len );
  80. memcpy ( &mode->BroadcastAddress, netdev->ll_broadcast, ll_addr_len );
  81. ll_protocol->init_addr ( netdev->hw_addr, &mode->PermanentAddress );
  82. mode->IfType = ntohs ( ll_protocol->ll_proto );
  83. mode->MacAddressChangeable = TRUE;
  84. mode->MediaPresentSupported = TRUE;
  85. mode->MediaPresent = ( netdev_link_ok ( netdev ) ? TRUE : FALSE );
  86. }
  87. /**
  88. * Poll net device and count received packets
  89. *
  90. * @v snpdev SNP device
  91. */
  92. static void efi_snp_poll ( struct efi_snp_device *snpdev ) {
  93. struct io_buffer *iobuf;
  94. unsigned int before = 0;
  95. unsigned int after = 0;
  96. unsigned int arrived;
  97. /* We have to report packet arrivals, and this is the easiest
  98. * way to fake it.
  99. */
  100. list_for_each_entry ( iobuf, &snpdev->netdev->rx_queue, list )
  101. before++;
  102. netdev_poll ( snpdev->netdev );
  103. list_for_each_entry ( iobuf, &snpdev->netdev->rx_queue, list )
  104. after++;
  105. arrived = ( after - before );
  106. snpdev->rx_count_interrupts += arrived;
  107. snpdev->rx_count_events += arrived;
  108. }
  109. /**
  110. * Change SNP state from "stopped" to "started"
  111. *
  112. * @v snp SNP interface
  113. * @ret efirc EFI status code
  114. */
  115. static EFI_STATUS EFIAPI
  116. efi_snp_start ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
  117. struct efi_snp_device *snpdev =
  118. container_of ( snp, struct efi_snp_device, snp );
  119. DBGC2 ( snpdev, "SNPDEV %p START\n", snpdev );
  120. snpdev->mode.State = EfiSimpleNetworkStarted;
  121. return 0;
  122. }
  123. /**
  124. * Change SNP state from "started" to "stopped"
  125. *
  126. * @v snp SNP interface
  127. * @ret efirc EFI status code
  128. */
  129. static EFI_STATUS EFIAPI
  130. efi_snp_stop ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
  131. struct efi_snp_device *snpdev =
  132. container_of ( snp, struct efi_snp_device, snp );
  133. DBGC2 ( snpdev, "SNPDEV %p STOP\n", snpdev );
  134. snpdev->mode.State = EfiSimpleNetworkStopped;
  135. return 0;
  136. }
  137. /**
  138. * Open the network device
  139. *
  140. * @v snp SNP interface
  141. * @v extra_rx_bufsize Extra RX buffer size, in bytes
  142. * @v extra_tx_bufsize Extra TX buffer size, in bytes
  143. * @ret efirc EFI status code
  144. */
  145. static EFI_STATUS EFIAPI
  146. efi_snp_initialize ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
  147. UINTN extra_rx_bufsize, UINTN extra_tx_bufsize ) {
  148. struct efi_snp_device *snpdev =
  149. container_of ( snp, struct efi_snp_device, snp );
  150. int rc;
  151. DBGC2 ( snpdev, "SNPDEV %p INITIALIZE (%ld extra RX, %ld extra TX)\n",
  152. snpdev, ( ( unsigned long ) extra_rx_bufsize ),
  153. ( ( unsigned long ) extra_tx_bufsize ) );
  154. if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
  155. DBGC ( snpdev, "SNPDEV %p could not open %s: %s\n",
  156. snpdev, snpdev->netdev->name, strerror ( rc ) );
  157. return RC_TO_EFIRC ( rc );
  158. }
  159. snpdev->mode.State = EfiSimpleNetworkInitialized;
  160. return 0;
  161. }
  162. /**
  163. * Reset the network device
  164. *
  165. * @v snp SNP interface
  166. * @v ext_verify Extended verification required
  167. * @ret efirc EFI status code
  168. */
  169. static EFI_STATUS EFIAPI
  170. efi_snp_reset ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify ) {
  171. struct efi_snp_device *snpdev =
  172. container_of ( snp, struct efi_snp_device, snp );
  173. int rc;
  174. DBGC2 ( snpdev, "SNPDEV %p RESET (%s extended verification)\n",
  175. snpdev, ( ext_verify ? "with" : "without" ) );
  176. netdev_close ( snpdev->netdev );
  177. snpdev->mode.State = EfiSimpleNetworkStarted;
  178. if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
  179. DBGC ( snpdev, "SNPDEV %p could not reopen %s: %s\n",
  180. snpdev, snpdev->netdev->name, strerror ( rc ) );
  181. return RC_TO_EFIRC ( rc );
  182. }
  183. snpdev->mode.State = EfiSimpleNetworkInitialized;
  184. return 0;
  185. }
  186. /**
  187. * Shut down the network device
  188. *
  189. * @v snp SNP interface
  190. * @ret efirc EFI status code
  191. */
  192. static EFI_STATUS EFIAPI
  193. efi_snp_shutdown ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
  194. struct efi_snp_device *snpdev =
  195. container_of ( snp, struct efi_snp_device, snp );
  196. DBGC2 ( snpdev, "SNPDEV %p SHUTDOWN\n", snpdev );
  197. netdev_close ( snpdev->netdev );
  198. snpdev->mode.State = EfiSimpleNetworkStarted;
  199. return 0;
  200. }
  201. /**
  202. * Manage receive filters
  203. *
  204. * @v snp SNP interface
  205. * @v enable Receive filters to enable
  206. * @v disable Receive filters to disable
  207. * @v mcast_reset Reset multicast filters
  208. * @v mcast_count Number of multicast filters
  209. * @v mcast Multicast filters
  210. * @ret efirc EFI status code
  211. */
  212. static EFI_STATUS EFIAPI
  213. efi_snp_receive_filters ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, UINT32 enable,
  214. UINT32 disable, BOOLEAN mcast_reset,
  215. UINTN mcast_count, EFI_MAC_ADDRESS *mcast ) {
  216. struct efi_snp_device *snpdev =
  217. container_of ( snp, struct efi_snp_device, snp );
  218. unsigned int i;
  219. DBGC2 ( snpdev, "SNPDEV %p RECEIVE_FILTERS %08x&~%08x%s %ld mcast\n",
  220. snpdev, enable, disable, ( mcast_reset ? " reset" : "" ),
  221. ( ( unsigned long ) mcast_count ) );
  222. for ( i = 0 ; i < mcast_count ; i++ ) {
  223. DBGC2_HDA ( snpdev, i, &mcast[i],
  224. snpdev->netdev->ll_protocol->ll_addr_len );
  225. }
  226. /* Lie through our teeth, otherwise MNP refuses to accept us */
  227. return 0;
  228. }
  229. /**
  230. * Set station address
  231. *
  232. * @v snp SNP interface
  233. * @v reset Reset to permanent address
  234. * @v new New station address
  235. * @ret efirc EFI status code
  236. */
  237. static EFI_STATUS EFIAPI
  238. efi_snp_station_address ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN reset,
  239. EFI_MAC_ADDRESS *new ) {
  240. struct efi_snp_device *snpdev =
  241. container_of ( snp, struct efi_snp_device, snp );
  242. struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
  243. DBGC2 ( snpdev, "SNPDEV %p STATION_ADDRESS %s\n", snpdev,
  244. ( reset ? "reset" : ll_protocol->ntoa ( new ) ) );
  245. /* Set the MAC address */
  246. if ( reset )
  247. new = &snpdev->mode.PermanentAddress;
  248. memcpy ( snpdev->netdev->ll_addr, new, ll_protocol->ll_addr_len );
  249. /* MAC address changes take effect only on netdev_open() */
  250. if ( netdev_is_open ( snpdev->netdev ) ) {
  251. DBGC ( snpdev, "SNPDEV %p MAC address changed while net "
  252. "devive open\n", snpdev );
  253. }
  254. return 0;
  255. }
  256. /**
  257. * Get (or reset) statistics
  258. *
  259. * @v snp SNP interface
  260. * @v reset Reset statistics
  261. * @v stats_len Size of statistics table
  262. * @v stats Statistics table
  263. * @ret efirc EFI status code
  264. */
  265. static EFI_STATUS EFIAPI
  266. efi_snp_statistics ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN reset,
  267. UINTN *stats_len, EFI_NETWORK_STATISTICS *stats ) {
  268. struct efi_snp_device *snpdev =
  269. container_of ( snp, struct efi_snp_device, snp );
  270. EFI_NETWORK_STATISTICS stats_buf;
  271. DBGC2 ( snpdev, "SNPDEV %p STATISTICS%s", snpdev,
  272. ( reset ? " reset" : "" ) );
  273. /* Gather statistics */
  274. memset ( &stats_buf, 0, sizeof ( stats_buf ) );
  275. stats_buf.TxGoodFrames = snpdev->netdev->tx_stats.good;
  276. stats_buf.TxDroppedFrames = snpdev->netdev->tx_stats.bad;
  277. stats_buf.TxTotalFrames = ( snpdev->netdev->tx_stats.good +
  278. snpdev->netdev->tx_stats.bad );
  279. stats_buf.RxGoodFrames = snpdev->netdev->rx_stats.good;
  280. stats_buf.RxDroppedFrames = snpdev->netdev->rx_stats.bad;
  281. stats_buf.RxTotalFrames = ( snpdev->netdev->rx_stats.good +
  282. snpdev->netdev->rx_stats.bad );
  283. if ( *stats_len > sizeof ( stats_buf ) )
  284. *stats_len = sizeof ( stats_buf );
  285. if ( stats )
  286. memcpy ( stats, &stats_buf, *stats_len );
  287. /* Reset statistics if requested to do so */
  288. if ( reset ) {
  289. memset ( &snpdev->netdev->tx_stats, 0,
  290. sizeof ( snpdev->netdev->tx_stats ) );
  291. memset ( &snpdev->netdev->rx_stats, 0,
  292. sizeof ( snpdev->netdev->rx_stats ) );
  293. }
  294. return 0;
  295. }
  296. /**
  297. * Convert multicast IP address to MAC address
  298. *
  299. * @v snp SNP interface
  300. * @v ipv6 Address is IPv6
  301. * @v ip IP address
  302. * @v mac MAC address
  303. * @ret efirc EFI status code
  304. */
  305. static EFI_STATUS EFIAPI
  306. efi_snp_mcast_ip_to_mac ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ipv6,
  307. EFI_IP_ADDRESS *ip, EFI_MAC_ADDRESS *mac ) {
  308. struct efi_snp_device *snpdev =
  309. container_of ( snp, struct efi_snp_device, snp );
  310. struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
  311. const char *ip_str;
  312. int rc;
  313. ip_str = ( ipv6 ? "(IPv6)" /* FIXME when we have inet6_ntoa() */ :
  314. inet_ntoa ( *( ( struct in_addr * ) ip ) ) );
  315. DBGC2 ( snpdev, "SNPDEV %p MCAST_IP_TO_MAC %s\n", snpdev, ip_str );
  316. /* Try to hash the address */
  317. if ( ( rc = ll_protocol->mc_hash ( ( ipv6 ? AF_INET6 : AF_INET ),
  318. ip, mac ) ) != 0 ) {
  319. DBGC ( snpdev, "SNPDEV %p could not hash %s: %s\n",
  320. snpdev, ip_str, strerror ( rc ) );
  321. return RC_TO_EFIRC ( rc );
  322. }
  323. return 0;
  324. }
  325. /**
  326. * Read or write non-volatile storage
  327. *
  328. * @v snp SNP interface
  329. * @v read Operation is a read
  330. * @v offset Starting offset within NVRAM
  331. * @v len Length of data buffer
  332. * @v data Data buffer
  333. * @ret efirc EFI status code
  334. */
  335. static EFI_STATUS EFIAPI
  336. efi_snp_nvdata ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN read,
  337. UINTN offset, UINTN len, VOID *data ) {
  338. struct efi_snp_device *snpdev =
  339. container_of ( snp, struct efi_snp_device, snp );
  340. DBGC2 ( snpdev, "SNPDEV %p NVDATA %s %lx+%lx\n", snpdev,
  341. ( read ? "read" : "write" ), ( ( unsigned long ) offset ),
  342. ( ( unsigned long ) len ) );
  343. if ( ! read )
  344. DBGC2_HDA ( snpdev, offset, data, len );
  345. return EFI_UNSUPPORTED;
  346. }
  347. /**
  348. * Read interrupt status and TX recycled buffer status
  349. *
  350. * @v snp SNP interface
  351. * @v interrupts Interrupt status, or NULL
  352. * @v txbufs Recycled transmit buffer address, or NULL
  353. * @ret efirc EFI status code
  354. */
  355. static EFI_STATUS EFIAPI
  356. efi_snp_get_status ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
  357. UINT32 *interrupts, VOID **txbufs ) {
  358. struct efi_snp_device *snpdev =
  359. container_of ( snp, struct efi_snp_device, snp );
  360. DBGC2 ( snpdev, "SNPDEV %p GET_STATUS", snpdev );
  361. /* Poll the network device */
  362. efi_snp_poll ( snpdev );
  363. /* Interrupt status. In practice, this seems to be used only
  364. * to detect TX completions.
  365. */
  366. if ( interrupts ) {
  367. *interrupts = 0;
  368. /* Report TX completions once queue is empty; this
  369. * avoids having to add hooks in the net device layer.
  370. */
  371. if ( snpdev->tx_count_interrupts &&
  372. list_empty ( &snpdev->netdev->tx_queue ) ) {
  373. *interrupts |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
  374. snpdev->tx_count_interrupts--;
  375. }
  376. /* Report RX */
  377. if ( snpdev->rx_count_interrupts ) {
  378. *interrupts |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
  379. snpdev->rx_count_interrupts--;
  380. }
  381. DBGC2 ( snpdev, " INTS:%02x", *interrupts );
  382. }
  383. /* TX completions. It would be possible to design a more
  384. * idiotic scheme for this, but it would be a challenge.
  385. * According to the UEFI header file, txbufs will be filled in
  386. * with a list of "recycled transmit buffers" (i.e. completed
  387. * TX buffers). Observant readers may care to note that
  388. * *txbufs is a void pointer. Precisely how a list of
  389. * completed transmit buffers is meant to be represented as an
  390. * array of voids is left as an exercise for the reader.
  391. *
  392. * The only users of this interface (MnpDxe/MnpIo.c and
  393. * PxeBcDxe/Bc.c within the EFI dev kit) both just poll until
  394. * seeing a non-NULL result return in txbufs. This is valid
  395. * provided that they do not ever attempt to transmit more
  396. * than one packet concurrently (and that TX never times out).
  397. */
  398. if ( txbufs ) {
  399. if ( snpdev->tx_count_txbufs &&
  400. list_empty ( &snpdev->netdev->tx_queue ) ) {
  401. *txbufs = "Which idiot designed this API?";
  402. snpdev->tx_count_txbufs--;
  403. } else {
  404. *txbufs = NULL;
  405. }
  406. DBGC2 ( snpdev, " TX:%s", ( *txbufs ? "some" : "none" ) );
  407. }
  408. DBGC2 ( snpdev, "\n" );
  409. return 0;
  410. }
  411. /**
  412. * Start packet transmission
  413. *
  414. * @v snp SNP interface
  415. * @v ll_header_len Link-layer header length, if to be filled in
  416. * @v len Length of data buffer
  417. * @v data Data buffer
  418. * @v ll_src Link-layer source address, if specified
  419. * @v ll_dest Link-layer destination address, if specified
  420. * @v net_proto Network-layer protocol (in host order)
  421. * @ret efirc EFI status code
  422. */
  423. static EFI_STATUS EFIAPI
  424. efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
  425. UINTN ll_header_len, UINTN len, VOID *data,
  426. EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
  427. UINT16 *net_proto ) {
  428. struct efi_snp_device *snpdev =
  429. container_of ( snp, struct efi_snp_device, snp );
  430. struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
  431. struct io_buffer *iobuf;
  432. size_t payload_len;
  433. int rc;
  434. EFI_STATUS efirc;
  435. DBGC2 ( snpdev, "SNPDEV %p TRANSMIT %p+%lx", snpdev, data,
  436. ( ( unsigned long ) len ) );
  437. if ( ll_header_len ) {
  438. if ( ll_src ) {
  439. DBGC2 ( snpdev, " src %s",
  440. ll_protocol->ntoa ( ll_src ) );
  441. }
  442. if ( ll_dest ) {
  443. DBGC2 ( snpdev, " dest %s",
  444. ll_protocol->ntoa ( ll_dest ) );
  445. }
  446. if ( net_proto ) {
  447. DBGC2 ( snpdev, " proto %04x", *net_proto );
  448. }
  449. }
  450. DBGC2 ( snpdev, "\n" );
  451. /* Sanity checks */
  452. if ( ll_header_len ) {
  453. if ( ll_header_len != ll_protocol->ll_header_len ) {
  454. DBGC ( snpdev, "SNPDEV %p TX invalid header length "
  455. "%ld\n", snpdev,
  456. ( ( unsigned long ) ll_header_len ) );
  457. efirc = EFI_INVALID_PARAMETER;
  458. goto err_sanity;
  459. }
  460. if ( len < ll_header_len ) {
  461. DBGC ( snpdev, "SNPDEV %p invalid packet length %ld\n",
  462. snpdev, ( ( unsigned long ) len ) );
  463. efirc = EFI_BUFFER_TOO_SMALL;
  464. goto err_sanity;
  465. }
  466. if ( ! ll_dest ) {
  467. DBGC ( snpdev, "SNPDEV %p TX missing destination "
  468. "address\n", snpdev );
  469. efirc = EFI_INVALID_PARAMETER;
  470. goto err_sanity;
  471. }
  472. if ( ! net_proto ) {
  473. DBGC ( snpdev, "SNPDEV %p TX missing network "
  474. "protocol\n", snpdev );
  475. efirc = EFI_INVALID_PARAMETER;
  476. goto err_sanity;
  477. }
  478. if ( ! ll_src )
  479. ll_src = &snpdev->mode.CurrentAddress;
  480. }
  481. /* Allocate buffer */
  482. payload_len = ( len - ll_protocol->ll_header_len );
  483. iobuf = alloc_iob ( MAX_LL_HEADER_LEN + ( ( payload_len > IOB_ZLEN ) ?
  484. payload_len : IOB_ZLEN ) );
  485. if ( ! iobuf ) {
  486. DBGC ( snpdev, "SNPDEV %p TX could not allocate %ld-byte "
  487. "buffer\n", snpdev, ( ( unsigned long ) len ) );
  488. efirc = EFI_DEVICE_ERROR;
  489. goto err_alloc_iob;
  490. }
  491. iob_reserve ( iobuf, ( MAX_LL_HEADER_LEN -
  492. ll_protocol->ll_header_len ) );
  493. memcpy ( iob_put ( iobuf, len ), data, len );
  494. /* Create link-layer header, if specified */
  495. if ( ll_header_len ) {
  496. iob_pull ( iobuf, ll_protocol->ll_header_len );
  497. if ( ( rc = ll_protocol->push ( snpdev->netdev,
  498. iobuf, ll_dest, ll_src,
  499. htons ( *net_proto ) )) != 0 ){
  500. DBGC ( snpdev, "SNPDEV %p TX could not construct "
  501. "header: %s\n", snpdev, strerror ( rc ) );
  502. efirc = RC_TO_EFIRC ( rc );
  503. goto err_ll_push;
  504. }
  505. }
  506. /* Transmit packet */
  507. if ( ( rc = netdev_tx ( snpdev->netdev, iob_disown ( iobuf ) ) ) != 0){
  508. DBGC ( snpdev, "SNPDEV %p TX could not transmit: %s\n",
  509. snpdev, strerror ( rc ) );
  510. efirc = RC_TO_EFIRC ( rc );
  511. goto err_tx;
  512. }
  513. /* Record transmission as outstanding */
  514. snpdev->tx_count_interrupts++;
  515. snpdev->tx_count_txbufs++;
  516. return 0;
  517. err_tx:
  518. err_ll_push:
  519. free_iob ( iobuf );
  520. err_alloc_iob:
  521. err_sanity:
  522. return efirc;
  523. }
  524. /**
  525. * Receive packet
  526. *
  527. * @v snp SNP interface
  528. * @v ll_header_len Link-layer header length, if to be filled in
  529. * @v len Length of data buffer
  530. * @v data Data buffer
  531. * @v ll_src Link-layer source address, if specified
  532. * @v ll_dest Link-layer destination address, if specified
  533. * @v net_proto Network-layer protocol (in host order)
  534. * @ret efirc EFI status code
  535. */
  536. static EFI_STATUS EFIAPI
  537. efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
  538. UINTN *ll_header_len, UINTN *len, VOID *data,
  539. EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
  540. UINT16 *net_proto ) {
  541. struct efi_snp_device *snpdev =
  542. container_of ( snp, struct efi_snp_device, snp );
  543. struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
  544. struct io_buffer *iobuf;
  545. const void *iob_ll_dest;
  546. const void *iob_ll_src;
  547. uint16_t iob_net_proto;
  548. unsigned int iob_flags;
  549. int rc;
  550. EFI_STATUS efirc;
  551. DBGC2 ( snpdev, "SNPDEV %p RECEIVE %p(+%lx)", snpdev, data,
  552. ( ( unsigned long ) *len ) );
  553. /* Poll the network device */
  554. efi_snp_poll ( snpdev );
  555. /* Dequeue a packet, if one is available */
  556. iobuf = netdev_rx_dequeue ( snpdev->netdev );
  557. if ( ! iobuf ) {
  558. DBGC2 ( snpdev, "\n" );
  559. efirc = EFI_NOT_READY;
  560. goto out_no_packet;
  561. }
  562. DBGC2 ( snpdev, "+%zx\n", iob_len ( iobuf ) );
  563. /* Return packet to caller */
  564. memcpy ( data, iobuf->data, iob_len ( iobuf ) );
  565. *len = iob_len ( iobuf );
  566. /* Attempt to decode link-layer header */
  567. if ( ( rc = ll_protocol->pull ( snpdev->netdev, iobuf, &iob_ll_dest,
  568. &iob_ll_src, &iob_net_proto,
  569. &iob_flags ) ) != 0 ) {
  570. DBGC ( snpdev, "SNPDEV %p could not parse header: %s\n",
  571. snpdev, strerror ( rc ) );
  572. efirc = RC_TO_EFIRC ( rc );
  573. goto out_bad_ll_header;
  574. }
  575. /* Return link-layer header parameters to caller, if required */
  576. if ( ll_header_len )
  577. *ll_header_len = ll_protocol->ll_header_len;
  578. if ( ll_src )
  579. memcpy ( ll_src, iob_ll_src, ll_protocol->ll_addr_len );
  580. if ( ll_dest )
  581. memcpy ( ll_dest, iob_ll_dest, ll_protocol->ll_addr_len );
  582. if ( net_proto )
  583. *net_proto = ntohs ( iob_net_proto );
  584. efirc = 0;
  585. out_bad_ll_header:
  586. free_iob ( iobuf );
  587. out_no_packet:
  588. return efirc;
  589. }
  590. /**
  591. * Poll event
  592. *
  593. * @v event Event
  594. * @v context Event context
  595. */
  596. static VOID EFIAPI efi_snp_wait_for_packet ( EFI_EVENT event,
  597. VOID *context ) {
  598. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  599. struct efi_snp_device *snpdev = context;
  600. DBGCP ( snpdev, "SNPDEV %p WAIT_FOR_PACKET\n", snpdev );
  601. /* Do nothing unless the net device is open */
  602. if ( ! netdev_is_open ( snpdev->netdev ) )
  603. return;
  604. /* Poll the network device */
  605. efi_snp_poll ( snpdev );
  606. /* Fire event if packets have been received */
  607. if ( snpdev->rx_count_events != 0 ) {
  608. DBGC2 ( snpdev, "SNPDEV %p firing WaitForPacket event\n",
  609. snpdev );
  610. bs->SignalEvent ( event );
  611. snpdev->rx_count_events--;
  612. }
  613. }
  614. /** SNP interface */
  615. static EFI_SIMPLE_NETWORK_PROTOCOL efi_snp_device_snp = {
  616. .Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION,
  617. .Start = efi_snp_start,
  618. .Stop = efi_snp_stop,
  619. .Initialize = efi_snp_initialize,
  620. .Reset = efi_snp_reset,
  621. .Shutdown = efi_snp_shutdown,
  622. .ReceiveFilters = efi_snp_receive_filters,
  623. .StationAddress = efi_snp_station_address,
  624. .Statistics = efi_snp_statistics,
  625. .MCastIpToMac = efi_snp_mcast_ip_to_mac,
  626. .NvData = efi_snp_nvdata,
  627. .GetStatus = efi_snp_get_status,
  628. .Transmit = efi_snp_transmit,
  629. .Receive = efi_snp_receive,
  630. };
  631. /******************************************************************************
  632. *
  633. * Component name protocol
  634. *
  635. ******************************************************************************
  636. */
  637. /**
  638. * Look up driver name
  639. *
  640. * @v name2 Component name protocol
  641. * @v language Language to use
  642. * @v driver_name Driver name to fill in
  643. * @ret efirc EFI status code
  644. */
  645. static EFI_STATUS EFIAPI
  646. efi_snp_get_driver_name ( EFI_COMPONENT_NAME2_PROTOCOL *name2,
  647. CHAR8 *language __unused, CHAR16 **driver_name ) {
  648. struct efi_snp_device *snpdev =
  649. container_of ( name2, struct efi_snp_device, name2 );
  650. *driver_name = snpdev->driver_name;
  651. return 0;
  652. }
  653. /**
  654. * Look up controller name
  655. *
  656. * @v name2 Component name protocol
  657. * @v device Device
  658. * @v child Child device, or NULL
  659. * @v language Language to use
  660. * @v driver_name Device name to fill in
  661. * @ret efirc EFI status code
  662. */
  663. static EFI_STATUS EFIAPI
  664. efi_snp_get_controller_name ( EFI_COMPONENT_NAME2_PROTOCOL *name2,
  665. EFI_HANDLE device __unused,
  666. EFI_HANDLE child __unused,
  667. CHAR8 *language __unused,
  668. CHAR16 **controller_name ) {
  669. struct efi_snp_device *snpdev =
  670. container_of ( name2, struct efi_snp_device, name2 );
  671. *controller_name = snpdev->controller_name;
  672. return 0;
  673. }
  674. /******************************************************************************
  675. *
  676. * Load file protocol
  677. *
  678. ******************************************************************************
  679. */
  680. /**
  681. * Load file
  682. *
  683. * @v loadfile Load file protocol
  684. * @v path File path
  685. * @v booting Loading as part of a boot attempt
  686. * @ret efirc EFI status code
  687. */
  688. static EFI_STATUS EFIAPI
  689. efi_snp_load_file ( EFI_LOAD_FILE_PROTOCOL *load_file,
  690. EFI_DEVICE_PATH_PROTOCOL *path __unused,
  691. BOOLEAN booting, UINTN *len __unused,
  692. VOID *data __unused ) {
  693. struct efi_snp_device *snpdev =
  694. container_of ( load_file, struct efi_snp_device, load_file );
  695. struct net_device *netdev = snpdev->netdev;
  696. /* Fail unless this is a boot attempt */
  697. if ( ! booting ) {
  698. DBGC ( snpdev, "SNPDEV %p cannot load non-boot file\n",
  699. snpdev );
  700. return EFI_UNSUPPORTED;
  701. }
  702. /* Boot from network device */
  703. ipxe ( netdev );
  704. /* Assume boot process was aborted */
  705. return EFI_ABORTED;
  706. }
  707. /** Load file protocol */
  708. static EFI_LOAD_FILE_PROTOCOL efi_snp_load_file_protocol = {
  709. .LoadFile = efi_snp_load_file,
  710. };
  711. /******************************************************************************
  712. *
  713. * iPXE network driver
  714. *
  715. ******************************************************************************
  716. */
  717. /**
  718. * Locate SNP device corresponding to network device
  719. *
  720. * @v netdev Network device
  721. * @ret snp SNP device, or NULL if not found
  722. */
  723. static struct efi_snp_device * efi_snp_demux ( struct net_device *netdev ) {
  724. struct efi_snp_device *snpdev;
  725. list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
  726. if ( snpdev->netdev == netdev )
  727. return snpdev;
  728. }
  729. return NULL;
  730. }
  731. /**
  732. * Create SNP device
  733. *
  734. * @v netdev Network device
  735. * @ret rc Return status code
  736. */
  737. static int efi_snp_probe ( struct net_device *netdev ) {
  738. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  739. struct efi_pci_device *efipci;
  740. struct efi_snp_device *snpdev;
  741. EFI_DEVICE_PATH_PROTOCOL *path_end;
  742. MAC_ADDR_DEVICE_PATH *macpath;
  743. size_t path_prefix_len = 0;
  744. EFI_STATUS efirc;
  745. int rc;
  746. /* Find EFI PCI device */
  747. efipci = efipci_find ( netdev->dev );
  748. if ( ! efipci ) {
  749. DBG ( "SNP skipping non-PCI device %s\n", netdev->name );
  750. rc = 0;
  751. goto err_no_pci;
  752. }
  753. /* Calculate device path prefix length */
  754. path_end = efi_devpath_end ( efipci->path );
  755. path_prefix_len = ( ( ( void * ) path_end ) -
  756. ( ( void * ) efipci->path ) );
  757. /* Allocate the SNP device */
  758. snpdev = zalloc ( sizeof ( *snpdev ) + path_prefix_len +
  759. sizeof ( *macpath ) );
  760. if ( ! snpdev ) {
  761. rc = -ENOMEM;
  762. goto err_alloc_snp;
  763. }
  764. snpdev->netdev = netdev_get ( netdev );
  765. snpdev->efipci = efipci;
  766. /* Sanity check */
  767. if ( netdev->ll_protocol->ll_addr_len > sizeof ( EFI_MAC_ADDRESS ) ) {
  768. DBGC ( snpdev, "SNPDEV %p cannot support link-layer address "
  769. "length %d for %s\n", snpdev,
  770. netdev->ll_protocol->ll_addr_len, netdev->name );
  771. rc = -ENOTSUP;
  772. goto err_ll_addr_len;
  773. }
  774. /* Populate the SNP structure */
  775. memcpy ( &snpdev->snp, &efi_snp_device_snp, sizeof ( snpdev->snp ) );
  776. snpdev->snp.Mode = &snpdev->mode;
  777. if ( ( efirc = bs->CreateEvent ( EVT_NOTIFY_WAIT, TPL_NOTIFY,
  778. efi_snp_wait_for_packet, snpdev,
  779. &snpdev->snp.WaitForPacket ) ) != 0 ){
  780. DBGC ( snpdev, "SNPDEV %p could not create event: %s\n",
  781. snpdev, efi_strerror ( efirc ) );
  782. rc = EFIRC_TO_RC ( efirc );
  783. goto err_create_event;
  784. }
  785. /* Populate the SNP mode structure */
  786. snpdev->mode.State = EfiSimpleNetworkStopped;
  787. efi_snp_set_mode ( snpdev );
  788. /* Populate the NII structure */
  789. snpdev->nii.Revision =
  790. EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION;
  791. strncpy ( snpdev->nii.StringId, "iPXE",
  792. sizeof ( snpdev->nii.StringId ) );
  793. /* Populate the component name structure */
  794. efi_snprintf ( snpdev->driver_name,
  795. ( sizeof ( snpdev->driver_name ) /
  796. sizeof ( snpdev->driver_name[0] ) ),
  797. PRODUCT_SHORT_NAME " %s", netdev->dev->driver_name );
  798. efi_snprintf ( snpdev->controller_name,
  799. ( sizeof ( snpdev->controller_name ) /
  800. sizeof ( snpdev->controller_name[0] ) ),
  801. PRODUCT_SHORT_NAME " %s (%s)",
  802. netdev->name, netdev_addr ( netdev ) );
  803. snpdev->name2.GetDriverName = efi_snp_get_driver_name;
  804. snpdev->name2.GetControllerName = efi_snp_get_controller_name;
  805. snpdev->name2.SupportedLanguages = "en";
  806. /* Populate the load file protocol structure */
  807. memcpy ( &snpdev->load_file, &efi_snp_load_file_protocol,
  808. sizeof ( snpdev->load_file ) );
  809. /* Populate the device name */
  810. efi_snprintf ( snpdev->name, ( sizeof ( snpdev->name ) /
  811. sizeof ( snpdev->name[0] ) ),
  812. "%s", netdev->name );
  813. /* Populate the device path */
  814. memcpy ( &snpdev->path, efipci->path, path_prefix_len );
  815. macpath = ( ( ( void * ) &snpdev->path ) + path_prefix_len );
  816. path_end = ( ( void * ) ( macpath + 1 ) );
  817. memset ( macpath, 0, sizeof ( *macpath ) );
  818. macpath->Header.Type = MESSAGING_DEVICE_PATH;
  819. macpath->Header.SubType = MSG_MAC_ADDR_DP;
  820. macpath->Header.Length[0] = sizeof ( *macpath );
  821. memcpy ( &macpath->MacAddress, netdev->ll_addr,
  822. sizeof ( macpath->MacAddress ) );
  823. macpath->IfType = ntohs ( netdev->ll_protocol->ll_proto );
  824. memset ( path_end, 0, sizeof ( *path_end ) );
  825. path_end->Type = END_DEVICE_PATH_TYPE;
  826. path_end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
  827. path_end->Length[0] = sizeof ( *path_end );
  828. /* Install the SNP */
  829. if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
  830. &snpdev->handle,
  831. &efi_simple_network_protocol_guid, &snpdev->snp,
  832. &efi_device_path_protocol_guid, &snpdev->path,
  833. &efi_nii_protocol_guid, &snpdev->nii,
  834. &efi_nii31_protocol_guid, &snpdev->nii,
  835. &efi_component_name2_protocol_guid, &snpdev->name2,
  836. &efi_load_file_protocol_guid, &snpdev->load_file,
  837. NULL ) ) != 0 ) {
  838. DBGC ( snpdev, "SNPDEV %p could not install protocols: "
  839. "%s\n", snpdev, efi_strerror ( efirc ) );
  840. rc = EFIRC_TO_RC ( efirc );
  841. goto err_install_protocol_interface;
  842. }
  843. /* Add as child of PCI device */
  844. if ( ( efirc = efipci_child_add ( efipci, snpdev->handle ) ) != 0 ) {
  845. DBGC ( snpdev, "SNPDEV %p could not become child of " PCI_FMT
  846. ": %s\n", snpdev, PCI_ARGS ( &efipci->pci ),
  847. efi_strerror ( efirc ) );
  848. rc = EFIRC_TO_RC ( efirc );
  849. goto err_efipci_child_add;
  850. }
  851. /* Install HII */
  852. if ( ( rc = efi_snp_hii_install ( snpdev ) ) != 0 ) {
  853. DBGC ( snpdev, "SNPDEV %p could not install HII: %s\n",
  854. snpdev, strerror ( rc ) );
  855. goto err_hii_install;
  856. }
  857. /* Add to list of SNP devices */
  858. list_add ( &snpdev->list, &efi_snp_devices );
  859. DBGC ( snpdev, "SNPDEV %p installed for %s as device %p\n",
  860. snpdev, netdev->name, snpdev->handle );
  861. return 0;
  862. efi_snp_hii_uninstall ( snpdev );
  863. err_hii_install:
  864. efipci_child_del ( efipci, snpdev->handle );
  865. err_efipci_child_add:
  866. bs->UninstallMultipleProtocolInterfaces (
  867. snpdev->handle,
  868. &efi_simple_network_protocol_guid, &snpdev->snp,
  869. &efi_device_path_protocol_guid, &snpdev->path,
  870. &efi_nii_protocol_guid, &snpdev->nii,
  871. &efi_nii31_protocol_guid, &snpdev->nii,
  872. &efi_component_name2_protocol_guid, &snpdev->name2,
  873. &efi_load_file_protocol_guid, &snpdev->load_file,
  874. NULL );
  875. err_install_protocol_interface:
  876. bs->CloseEvent ( snpdev->snp.WaitForPacket );
  877. err_create_event:
  878. err_ll_addr_len:
  879. netdev_put ( netdev );
  880. free ( snpdev );
  881. err_alloc_snp:
  882. err_no_pci:
  883. return rc;
  884. }
  885. /**
  886. * Handle SNP device or link state change
  887. *
  888. * @v netdev Network device
  889. */
  890. static void efi_snp_notify ( struct net_device *netdev ) {
  891. struct efi_snp_device *snpdev;
  892. /* Locate SNP device */
  893. snpdev = efi_snp_demux ( netdev );
  894. if ( ! snpdev ) {
  895. DBG ( "SNP skipping non-SNP device %s\n", netdev->name );
  896. return;
  897. }
  898. /* Update link state */
  899. snpdev->mode.MediaPresent =
  900. ( netdev_link_ok ( netdev ) ? TRUE : FALSE );
  901. DBGC ( snpdev, "SNPDEV %p link is %s\n", snpdev,
  902. ( snpdev->mode.MediaPresent ? "up" : "down" ) );
  903. }
  904. /**
  905. * Destroy SNP device
  906. *
  907. * @v netdev Network device
  908. */
  909. static void efi_snp_remove ( struct net_device *netdev ) {
  910. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  911. struct efi_snp_device *snpdev;
  912. /* Locate SNP device */
  913. snpdev = efi_snp_demux ( netdev );
  914. if ( ! snpdev ) {
  915. DBG ( "SNP skipping non-SNP device %s\n", netdev->name );
  916. return;
  917. }
  918. /* Uninstall the SNP */
  919. efi_snp_hii_uninstall ( snpdev );
  920. efipci_child_del ( snpdev->efipci, snpdev->handle );
  921. list_del ( &snpdev->list );
  922. bs->UninstallMultipleProtocolInterfaces (
  923. snpdev->handle,
  924. &efi_simple_network_protocol_guid, &snpdev->snp,
  925. &efi_device_path_protocol_guid, &snpdev->path,
  926. &efi_nii_protocol_guid, &snpdev->nii,
  927. &efi_nii31_protocol_guid, &snpdev->nii,
  928. &efi_component_name2_protocol_guid, &snpdev->name2,
  929. &efi_load_file_protocol_guid, &snpdev->load_file,
  930. NULL );
  931. bs->CloseEvent ( snpdev->snp.WaitForPacket );
  932. netdev_put ( snpdev->netdev );
  933. free ( snpdev );
  934. }
  935. /** SNP driver */
  936. struct net_driver efi_snp_driver __net_driver = {
  937. .name = "SNP",
  938. .probe = efi_snp_probe,
  939. .notify = efi_snp_notify,
  940. .remove = efi_snp_remove,
  941. };
  942. /**
  943. * Get most recently opened SNP device
  944. *
  945. * @ret snpdev Most recently opened SNP device, or NULL
  946. */
  947. struct efi_snp_device * last_opened_snpdev ( void ) {
  948. struct net_device *netdev;
  949. netdev = last_opened_netdev();
  950. if ( ! netdev )
  951. return NULL;
  952. return efi_snp_demux ( netdev );
  953. }