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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887
  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/version.h>
  29. #include <ipxe/console.h>
  30. #include <ipxe/efi/efi.h>
  31. #include <ipxe/efi/efi_driver.h>
  32. #include <ipxe/efi/efi_strings.h>
  33. #include <ipxe/efi/efi_utils.h>
  34. #include <ipxe/efi/efi_watchdog.h>
  35. #include <ipxe/efi/efi_snp.h>
  36. #include <usr/autoboot.h>
  37. #include <config/general.h>
  38. /** List of SNP devices */
  39. static LIST_HEAD ( efi_snp_devices );
  40. /** Network devices are currently claimed for use by iPXE */
  41. static int efi_snp_claimed;
  42. /* Downgrade user experience if configured to do so
  43. *
  44. * The default UEFI user experience for network boot is somewhat
  45. * excremental: only TFTP is available as a download protocol, and if
  46. * anything goes wrong the user will be shown just a dot on an
  47. * otherwise blank screen. (Some programmer was clearly determined to
  48. * win a bet that they could outshine Apple at producing uninformative
  49. * error messages.)
  50. *
  51. * For comparison, the default iPXE user experience provides the
  52. * option to use protocols designed more recently than 1980 (such as
  53. * HTTP and iSCSI), and if anything goes wrong the the user will be
  54. * shown one of over 1200 different error messages, complete with a
  55. * link to a wiki page describing that specific error.
  56. *
  57. * We default to upgrading the user experience to match that available
  58. * in a "legacy" BIOS environment, by installing our own instance of
  59. * EFI_LOAD_FILE_PROTOCOL.
  60. *
  61. * Note that unfortunately we can't sensibly provide the choice of
  62. * both options to the user in the same build, because the UEFI boot
  63. * menu ignores the multitude of ways in which a network device handle
  64. * can be described and opaquely labels both menu entries as just "EFI
  65. * Network".
  66. */
  67. #ifdef EFI_DOWNGRADE_UX
  68. static EFI_GUID dummy_load_file_protocol_guid = {
  69. 0x6f6c7323, 0x2077, 0x7523,
  70. { 0x6e, 0x68, 0x65, 0x6c, 0x70, 0x66, 0x75, 0x6c }
  71. };
  72. #define efi_load_file_protocol_guid dummy_load_file_protocol_guid
  73. #endif
  74. /**
  75. * Set EFI SNP mode state
  76. *
  77. * @v snp SNP interface
  78. */
  79. static void efi_snp_set_state ( struct efi_snp_device *snpdev ) {
  80. struct net_device *netdev = snpdev->netdev;
  81. EFI_SIMPLE_NETWORK_MODE *mode = &snpdev->mode;
  82. /* Calculate state */
  83. if ( ! snpdev->started ) {
  84. /* Start() method not called; report as Stopped */
  85. mode->State = EfiSimpleNetworkStopped;
  86. } else if ( ! netdev_is_open ( netdev ) ) {
  87. /* Network device not opened; report as Started */
  88. mode->State = EfiSimpleNetworkStarted;
  89. } else if ( efi_snp_claimed ) {
  90. /* Network device opened but claimed for use by iPXE; report
  91. * as Started to inhibit receive polling.
  92. */
  93. mode->State = EfiSimpleNetworkStarted;
  94. } else {
  95. /* Network device opened and available for use via SNP; report
  96. * as Initialized.
  97. */
  98. mode->State = EfiSimpleNetworkInitialized;
  99. }
  100. }
  101. /**
  102. * Set EFI SNP mode based on iPXE net device parameters
  103. *
  104. * @v snp SNP interface
  105. */
  106. static void efi_snp_set_mode ( struct efi_snp_device *snpdev ) {
  107. struct net_device *netdev = snpdev->netdev;
  108. EFI_SIMPLE_NETWORK_MODE *mode = &snpdev->mode;
  109. struct ll_protocol *ll_protocol = netdev->ll_protocol;
  110. unsigned int ll_addr_len = ll_protocol->ll_addr_len;
  111. mode->HwAddressSize = ll_addr_len;
  112. mode->MediaHeaderSize = ll_protocol->ll_header_len;
  113. mode->MaxPacketSize = netdev->max_pkt_len;
  114. mode->ReceiveFilterMask = ( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
  115. EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST |
  116. EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST );
  117. assert ( ll_addr_len <= sizeof ( mode->CurrentAddress ) );
  118. memcpy ( &mode->CurrentAddress, netdev->ll_addr, ll_addr_len );
  119. memcpy ( &mode->BroadcastAddress, netdev->ll_broadcast, ll_addr_len );
  120. ll_protocol->init_addr ( netdev->hw_addr, &mode->PermanentAddress );
  121. mode->IfType = ntohs ( ll_protocol->ll_proto );
  122. mode->MacAddressChangeable = TRUE;
  123. mode->MediaPresentSupported = TRUE;
  124. mode->MediaPresent = ( netdev_link_ok ( netdev ) ? TRUE : FALSE );
  125. }
  126. /**
  127. * Flush transmit ring and receive queue
  128. *
  129. * @v snpdev SNP device
  130. */
  131. static void efi_snp_flush ( struct efi_snp_device *snpdev ) {
  132. struct io_buffer *iobuf;
  133. struct io_buffer *tmp;
  134. /* Reset transmit completion ring */
  135. snpdev->tx_prod = 0;
  136. snpdev->tx_cons = 0;
  137. /* Discard any queued receive buffers */
  138. list_for_each_entry_safe ( iobuf, tmp, &snpdev->rx, list ) {
  139. list_del ( &iobuf->list );
  140. free_iob ( iobuf );
  141. }
  142. }
  143. /**
  144. * Poll net device and count received packets
  145. *
  146. * @v snpdev SNP device
  147. */
  148. static void efi_snp_poll ( struct efi_snp_device *snpdev ) {
  149. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  150. struct io_buffer *iobuf;
  151. /* Poll network device */
  152. netdev_poll ( snpdev->netdev );
  153. /* Retrieve any received packets */
  154. while ( ( iobuf = netdev_rx_dequeue ( snpdev->netdev ) ) ) {
  155. list_add_tail ( &iobuf->list, &snpdev->rx );
  156. snpdev->interrupts |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
  157. bs->SignalEvent ( &snpdev->snp.WaitForPacket );
  158. }
  159. }
  160. /**
  161. * Change SNP state from "stopped" to "started"
  162. *
  163. * @v snp SNP interface
  164. * @ret efirc EFI status code
  165. */
  166. static EFI_STATUS EFIAPI
  167. efi_snp_start ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
  168. struct efi_snp_device *snpdev =
  169. container_of ( snp, struct efi_snp_device, snp );
  170. DBGC ( snpdev, "SNPDEV %p START\n", snpdev );
  171. /* Fail if net device is currently claimed for use by iPXE */
  172. if ( efi_snp_claimed )
  173. return EFI_NOT_READY;
  174. snpdev->started = 1;
  175. efi_snp_set_state ( snpdev );
  176. return 0;
  177. }
  178. /**
  179. * Change SNP state from "started" to "stopped"
  180. *
  181. * @v snp SNP interface
  182. * @ret efirc EFI status code
  183. */
  184. static EFI_STATUS EFIAPI
  185. efi_snp_stop ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
  186. struct efi_snp_device *snpdev =
  187. container_of ( snp, struct efi_snp_device, snp );
  188. DBGC ( snpdev, "SNPDEV %p STOP\n", snpdev );
  189. /* Fail if net device is currently claimed for use by iPXE */
  190. if ( efi_snp_claimed )
  191. return EFI_NOT_READY;
  192. snpdev->started = 0;
  193. efi_snp_set_state ( snpdev );
  194. return 0;
  195. }
  196. /**
  197. * Open the network device
  198. *
  199. * @v snp SNP interface
  200. * @v extra_rx_bufsize Extra RX buffer size, in bytes
  201. * @v extra_tx_bufsize Extra TX buffer size, in bytes
  202. * @ret efirc EFI status code
  203. */
  204. static EFI_STATUS EFIAPI
  205. efi_snp_initialize ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
  206. UINTN extra_rx_bufsize, UINTN extra_tx_bufsize ) {
  207. struct efi_snp_device *snpdev =
  208. container_of ( snp, struct efi_snp_device, snp );
  209. int rc;
  210. DBGC ( snpdev, "SNPDEV %p INITIALIZE (%ld extra RX, %ld extra TX)\n",
  211. snpdev, ( ( unsigned long ) extra_rx_bufsize ),
  212. ( ( unsigned long ) extra_tx_bufsize ) );
  213. /* Fail if net device is currently claimed for use by iPXE */
  214. if ( efi_snp_claimed )
  215. return EFI_NOT_READY;
  216. if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
  217. DBGC ( snpdev, "SNPDEV %p could not open %s: %s\n",
  218. snpdev, snpdev->netdev->name, strerror ( rc ) );
  219. return EFIRC ( rc );
  220. }
  221. efi_snp_set_state ( snpdev );
  222. return 0;
  223. }
  224. /**
  225. * Reset the network device
  226. *
  227. * @v snp SNP interface
  228. * @v ext_verify Extended verification required
  229. * @ret efirc EFI status code
  230. */
  231. static EFI_STATUS EFIAPI
  232. efi_snp_reset ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify ) {
  233. struct efi_snp_device *snpdev =
  234. container_of ( snp, struct efi_snp_device, snp );
  235. int rc;
  236. DBGC ( snpdev, "SNPDEV %p RESET (%s extended verification)\n",
  237. snpdev, ( ext_verify ? "with" : "without" ) );
  238. /* Fail if net device is currently claimed for use by iPXE */
  239. if ( efi_snp_claimed )
  240. return EFI_NOT_READY;
  241. netdev_close ( snpdev->netdev );
  242. efi_snp_set_state ( snpdev );
  243. efi_snp_flush ( snpdev );
  244. if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
  245. DBGC ( snpdev, "SNPDEV %p could not reopen %s: %s\n",
  246. snpdev, snpdev->netdev->name, strerror ( rc ) );
  247. return EFIRC ( rc );
  248. }
  249. efi_snp_set_state ( snpdev );
  250. return 0;
  251. }
  252. /**
  253. * Shut down the network device
  254. *
  255. * @v snp SNP interface
  256. * @ret efirc EFI status code
  257. */
  258. static EFI_STATUS EFIAPI
  259. efi_snp_shutdown ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
  260. struct efi_snp_device *snpdev =
  261. container_of ( snp, struct efi_snp_device, snp );
  262. DBGC ( snpdev, "SNPDEV %p SHUTDOWN\n", snpdev );
  263. /* Fail if net device is currently claimed for use by iPXE */
  264. if ( efi_snp_claimed )
  265. return EFI_NOT_READY;
  266. netdev_close ( snpdev->netdev );
  267. efi_snp_set_state ( snpdev );
  268. efi_snp_flush ( snpdev );
  269. return 0;
  270. }
  271. /**
  272. * Manage receive filters
  273. *
  274. * @v snp SNP interface
  275. * @v enable Receive filters to enable
  276. * @v disable Receive filters to disable
  277. * @v mcast_reset Reset multicast filters
  278. * @v mcast_count Number of multicast filters
  279. * @v mcast Multicast filters
  280. * @ret efirc EFI status code
  281. */
  282. static EFI_STATUS EFIAPI
  283. efi_snp_receive_filters ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, UINT32 enable,
  284. UINT32 disable, BOOLEAN mcast_reset,
  285. UINTN mcast_count, EFI_MAC_ADDRESS *mcast ) {
  286. struct efi_snp_device *snpdev =
  287. container_of ( snp, struct efi_snp_device, snp );
  288. unsigned int i;
  289. DBGC ( snpdev, "SNPDEV %p RECEIVE_FILTERS %08x&~%08x%s %ld mcast\n",
  290. snpdev, enable, disable, ( mcast_reset ? " reset" : "" ),
  291. ( ( unsigned long ) mcast_count ) );
  292. for ( i = 0 ; i < mcast_count ; i++ ) {
  293. DBGC2_HDA ( snpdev, i, &mcast[i],
  294. snpdev->netdev->ll_protocol->ll_addr_len );
  295. }
  296. /* Lie through our teeth, otherwise MNP refuses to accept us.
  297. *
  298. * Return success even if the SNP device is currently claimed
  299. * for use by iPXE, since otherwise Windows Deployment
  300. * Services refuses to attempt to receive further packets via
  301. * our EFI PXE Base Code protocol.
  302. */
  303. return 0;
  304. }
  305. /**
  306. * Set station address
  307. *
  308. * @v snp SNP interface
  309. * @v reset Reset to permanent address
  310. * @v new New station address
  311. * @ret efirc EFI status code
  312. */
  313. static EFI_STATUS EFIAPI
  314. efi_snp_station_address ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN reset,
  315. EFI_MAC_ADDRESS *new ) {
  316. struct efi_snp_device *snpdev =
  317. container_of ( snp, struct efi_snp_device, snp );
  318. struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
  319. DBGC ( snpdev, "SNPDEV %p STATION_ADDRESS %s\n", snpdev,
  320. ( reset ? "reset" : ll_protocol->ntoa ( new ) ) );
  321. /* Fail if net device is currently claimed for use by iPXE */
  322. if ( efi_snp_claimed )
  323. return EFI_NOT_READY;
  324. /* Set the MAC address */
  325. if ( reset )
  326. new = &snpdev->mode.PermanentAddress;
  327. memcpy ( snpdev->netdev->ll_addr, new, ll_protocol->ll_addr_len );
  328. /* MAC address changes take effect only on netdev_open() */
  329. if ( netdev_is_open ( snpdev->netdev ) ) {
  330. DBGC ( snpdev, "SNPDEV %p MAC address changed while net "
  331. "device open\n", snpdev );
  332. }
  333. return 0;
  334. }
  335. /**
  336. * Get (or reset) statistics
  337. *
  338. * @v snp SNP interface
  339. * @v reset Reset statistics
  340. * @v stats_len Size of statistics table
  341. * @v stats Statistics table
  342. * @ret efirc EFI status code
  343. */
  344. static EFI_STATUS EFIAPI
  345. efi_snp_statistics ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN reset,
  346. UINTN *stats_len, EFI_NETWORK_STATISTICS *stats ) {
  347. struct efi_snp_device *snpdev =
  348. container_of ( snp, struct efi_snp_device, snp );
  349. EFI_NETWORK_STATISTICS stats_buf;
  350. DBGC ( snpdev, "SNPDEV %p STATISTICS%s", snpdev,
  351. ( reset ? " reset" : "" ) );
  352. /* Fail if net device is currently claimed for use by iPXE */
  353. if ( efi_snp_claimed )
  354. return EFI_NOT_READY;
  355. /* Gather statistics */
  356. memset ( &stats_buf, 0, sizeof ( stats_buf ) );
  357. stats_buf.TxGoodFrames = snpdev->netdev->tx_stats.good;
  358. stats_buf.TxDroppedFrames = snpdev->netdev->tx_stats.bad;
  359. stats_buf.TxTotalFrames = ( snpdev->netdev->tx_stats.good +
  360. snpdev->netdev->tx_stats.bad );
  361. stats_buf.RxGoodFrames = snpdev->netdev->rx_stats.good;
  362. stats_buf.RxDroppedFrames = snpdev->netdev->rx_stats.bad;
  363. stats_buf.RxTotalFrames = ( snpdev->netdev->rx_stats.good +
  364. snpdev->netdev->rx_stats.bad );
  365. if ( *stats_len > sizeof ( stats_buf ) )
  366. *stats_len = sizeof ( stats_buf );
  367. if ( stats )
  368. memcpy ( stats, &stats_buf, *stats_len );
  369. /* Reset statistics if requested to do so */
  370. if ( reset ) {
  371. memset ( &snpdev->netdev->tx_stats, 0,
  372. sizeof ( snpdev->netdev->tx_stats ) );
  373. memset ( &snpdev->netdev->rx_stats, 0,
  374. sizeof ( snpdev->netdev->rx_stats ) );
  375. }
  376. return 0;
  377. }
  378. /**
  379. * Convert multicast IP address to MAC address
  380. *
  381. * @v snp SNP interface
  382. * @v ipv6 Address is IPv6
  383. * @v ip IP address
  384. * @v mac MAC address
  385. * @ret efirc EFI status code
  386. */
  387. static EFI_STATUS EFIAPI
  388. efi_snp_mcast_ip_to_mac ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ipv6,
  389. EFI_IP_ADDRESS *ip, EFI_MAC_ADDRESS *mac ) {
  390. struct efi_snp_device *snpdev =
  391. container_of ( snp, struct efi_snp_device, snp );
  392. struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
  393. const char *ip_str;
  394. int rc;
  395. ip_str = ( ipv6 ? "(IPv6)" /* FIXME when we have inet6_ntoa() */ :
  396. inet_ntoa ( *( ( struct in_addr * ) ip ) ) );
  397. DBGC ( snpdev, "SNPDEV %p MCAST_IP_TO_MAC %s\n", snpdev, ip_str );
  398. /* Fail if net device is currently claimed for use by iPXE */
  399. if ( efi_snp_claimed )
  400. return EFI_NOT_READY;
  401. /* Try to hash the address */
  402. if ( ( rc = ll_protocol->mc_hash ( ( ipv6 ? AF_INET6 : AF_INET ),
  403. ip, mac ) ) != 0 ) {
  404. DBGC ( snpdev, "SNPDEV %p could not hash %s: %s\n",
  405. snpdev, ip_str, strerror ( rc ) );
  406. return EFIRC ( rc );
  407. }
  408. return 0;
  409. }
  410. /**
  411. * Read or write non-volatile storage
  412. *
  413. * @v snp SNP interface
  414. * @v read Operation is a read
  415. * @v offset Starting offset within NVRAM
  416. * @v len Length of data buffer
  417. * @v data Data buffer
  418. * @ret efirc EFI status code
  419. */
  420. static EFI_STATUS EFIAPI
  421. efi_snp_nvdata ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN read,
  422. UINTN offset, UINTN len, VOID *data ) {
  423. struct efi_snp_device *snpdev =
  424. container_of ( snp, struct efi_snp_device, snp );
  425. DBGC ( snpdev, "SNPDEV %p NVDATA %s %lx+%lx\n", snpdev,
  426. ( read ? "read" : "write" ), ( ( unsigned long ) offset ),
  427. ( ( unsigned long ) len ) );
  428. if ( ! read )
  429. DBGC2_HDA ( snpdev, offset, data, len );
  430. /* Fail if net device is currently claimed for use by iPXE */
  431. if ( efi_snp_claimed )
  432. return EFI_NOT_READY;
  433. return EFI_UNSUPPORTED;
  434. }
  435. /**
  436. * Read interrupt status and TX recycled buffer status
  437. *
  438. * @v snp SNP interface
  439. * @v interrupts Interrupt status, or NULL
  440. * @v txbuf Recycled transmit buffer address, or NULL
  441. * @ret efirc EFI status code
  442. */
  443. static EFI_STATUS EFIAPI
  444. efi_snp_get_status ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
  445. UINT32 *interrupts, VOID **txbuf ) {
  446. struct efi_snp_device *snpdev =
  447. container_of ( snp, struct efi_snp_device, snp );
  448. DBGC2 ( snpdev, "SNPDEV %p GET_STATUS", snpdev );
  449. /* Fail if net device is currently claimed for use by iPXE */
  450. if ( efi_snp_claimed ) {
  451. DBGC2 ( snpdev, "\n" );
  452. return EFI_NOT_READY;
  453. }
  454. /* Poll the network device */
  455. efi_snp_poll ( snpdev );
  456. /* Interrupt status. In practice, this seems to be used only
  457. * to detect TX completions.
  458. */
  459. if ( interrupts ) {
  460. *interrupts = snpdev->interrupts;
  461. DBGC2 ( snpdev, " INTS:%02x", *interrupts );
  462. snpdev->interrupts = 0;
  463. }
  464. /* TX completions */
  465. if ( txbuf ) {
  466. if ( snpdev->tx_prod != snpdev->tx_cons ) {
  467. *txbuf = snpdev->tx[snpdev->tx_cons++ % EFI_SNP_NUM_TX];
  468. } else {
  469. *txbuf = NULL;
  470. }
  471. DBGC2 ( snpdev, " TX:%p", *txbuf );
  472. }
  473. DBGC2 ( snpdev, "\n" );
  474. return 0;
  475. }
  476. /**
  477. * Start packet transmission
  478. *
  479. * @v snp SNP interface
  480. * @v ll_header_len Link-layer header length, if to be filled in
  481. * @v len Length of data buffer
  482. * @v data Data buffer
  483. * @v ll_src Link-layer source address, if specified
  484. * @v ll_dest Link-layer destination address, if specified
  485. * @v net_proto Network-layer protocol (in host order)
  486. * @ret efirc EFI status code
  487. */
  488. static EFI_STATUS EFIAPI
  489. efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
  490. UINTN ll_header_len, UINTN len, VOID *data,
  491. EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
  492. UINT16 *net_proto ) {
  493. struct efi_snp_device *snpdev =
  494. container_of ( snp, struct efi_snp_device, snp );
  495. struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
  496. struct io_buffer *iobuf;
  497. size_t payload_len;
  498. unsigned int tx_fill;
  499. int rc;
  500. DBGC2 ( snpdev, "SNPDEV %p TRANSMIT %p+%lx", snpdev, data,
  501. ( ( unsigned long ) len ) );
  502. if ( ll_header_len ) {
  503. if ( ll_src ) {
  504. DBGC2 ( snpdev, " src %s",
  505. ll_protocol->ntoa ( ll_src ) );
  506. }
  507. if ( ll_dest ) {
  508. DBGC2 ( snpdev, " dest %s",
  509. ll_protocol->ntoa ( ll_dest ) );
  510. }
  511. if ( net_proto ) {
  512. DBGC2 ( snpdev, " proto %04x", *net_proto );
  513. }
  514. }
  515. DBGC2 ( snpdev, "\n" );
  516. /* Fail if net device is currently claimed for use by iPXE */
  517. if ( efi_snp_claimed )
  518. return EFI_NOT_READY;
  519. /* Sanity checks */
  520. if ( ll_header_len ) {
  521. if ( ll_header_len != ll_protocol->ll_header_len ) {
  522. DBGC ( snpdev, "SNPDEV %p TX invalid header length "
  523. "%ld\n", snpdev,
  524. ( ( unsigned long ) ll_header_len ) );
  525. rc = -EINVAL;
  526. goto err_sanity;
  527. }
  528. if ( len < ll_header_len ) {
  529. DBGC ( snpdev, "SNPDEV %p invalid packet length %ld\n",
  530. snpdev, ( ( unsigned long ) len ) );
  531. rc = -EINVAL;
  532. goto err_sanity;
  533. }
  534. if ( ! ll_dest ) {
  535. DBGC ( snpdev, "SNPDEV %p TX missing destination "
  536. "address\n", snpdev );
  537. rc = -EINVAL;
  538. goto err_sanity;
  539. }
  540. if ( ! net_proto ) {
  541. DBGC ( snpdev, "SNPDEV %p TX missing network "
  542. "protocol\n", snpdev );
  543. rc = -EINVAL;
  544. goto err_sanity;
  545. }
  546. if ( ! ll_src )
  547. ll_src = &snpdev->mode.CurrentAddress;
  548. }
  549. /* Allocate buffer */
  550. payload_len = ( len - ll_protocol->ll_header_len );
  551. iobuf = alloc_iob ( MAX_LL_HEADER_LEN + ( ( payload_len > IOB_ZLEN ) ?
  552. payload_len : IOB_ZLEN ) );
  553. if ( ! iobuf ) {
  554. DBGC ( snpdev, "SNPDEV %p TX could not allocate %ld-byte "
  555. "buffer\n", snpdev, ( ( unsigned long ) len ) );
  556. rc = -ENOMEM;
  557. goto err_alloc_iob;
  558. }
  559. iob_reserve ( iobuf, ( MAX_LL_HEADER_LEN -
  560. ll_protocol->ll_header_len ) );
  561. memcpy ( iob_put ( iobuf, len ), data, len );
  562. /* Create link-layer header, if specified */
  563. if ( ll_header_len ) {
  564. iob_pull ( iobuf, ll_protocol->ll_header_len );
  565. if ( ( rc = ll_protocol->push ( snpdev->netdev,
  566. iobuf, ll_dest, ll_src,
  567. htons ( *net_proto ) )) != 0 ){
  568. DBGC ( snpdev, "SNPDEV %p TX could not construct "
  569. "header: %s\n", snpdev, strerror ( rc ) );
  570. goto err_ll_push;
  571. }
  572. }
  573. /* Transmit packet */
  574. if ( ( rc = netdev_tx ( snpdev->netdev, iob_disown ( iobuf ) ) ) != 0){
  575. DBGC ( snpdev, "SNPDEV %p TX could not transmit: %s\n",
  576. snpdev, strerror ( rc ) );
  577. goto err_tx;
  578. }
  579. /* Record in transmit completion ring. If we run out of
  580. * space, report the failure even though we have already
  581. * transmitted the packet.
  582. *
  583. * This allows us to report completions only for packets for
  584. * which we had reported successfully initiating transmission,
  585. * while continuing to support clients that never poll for
  586. * transmit completions.
  587. */
  588. tx_fill = ( snpdev->tx_prod - snpdev->tx_cons );
  589. if ( tx_fill >= EFI_SNP_NUM_TX ) {
  590. DBGC ( snpdev, "SNPDEV %p TX completion ring full\n", snpdev );
  591. rc = -ENOBUFS;
  592. goto err_ring_full;
  593. }
  594. snpdev->tx[ snpdev->tx_prod++ % EFI_SNP_NUM_TX ] = data;
  595. snpdev->interrupts |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
  596. return 0;
  597. err_ring_full:
  598. err_tx:
  599. err_ll_push:
  600. free_iob ( iobuf );
  601. err_alloc_iob:
  602. err_sanity:
  603. return EFIRC ( rc );
  604. }
  605. /**
  606. * Receive packet
  607. *
  608. * @v snp SNP interface
  609. * @v ll_header_len Link-layer header length, if to be filled in
  610. * @v len Length of data buffer
  611. * @v data Data buffer
  612. * @v ll_src Link-layer source address, if specified
  613. * @v ll_dest Link-layer destination address, if specified
  614. * @v net_proto Network-layer protocol (in host order)
  615. * @ret efirc EFI status code
  616. */
  617. static EFI_STATUS EFIAPI
  618. efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
  619. UINTN *ll_header_len, UINTN *len, VOID *data,
  620. EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
  621. UINT16 *net_proto ) {
  622. struct efi_snp_device *snpdev =
  623. container_of ( snp, struct efi_snp_device, snp );
  624. struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
  625. struct io_buffer *iobuf;
  626. const void *iob_ll_dest;
  627. const void *iob_ll_src;
  628. uint16_t iob_net_proto;
  629. unsigned int iob_flags;
  630. int rc;
  631. DBGC2 ( snpdev, "SNPDEV %p RECEIVE %p(+%lx)", snpdev, data,
  632. ( ( unsigned long ) *len ) );
  633. /* Fail if net device is currently claimed for use by iPXE */
  634. if ( efi_snp_claimed )
  635. return EFI_NOT_READY;
  636. /* Poll the network device */
  637. efi_snp_poll ( snpdev );
  638. /* Dequeue a packet, if one is available */
  639. iobuf = list_first_entry ( &snpdev->rx, struct io_buffer, list );
  640. if ( ! iobuf ) {
  641. DBGC2 ( snpdev, "\n" );
  642. rc = -EAGAIN;
  643. goto out_no_packet;
  644. }
  645. list_del ( &iobuf->list );
  646. DBGC2 ( snpdev, "+%zx\n", iob_len ( iobuf ) );
  647. /* Return packet to caller */
  648. memcpy ( data, iobuf->data, iob_len ( iobuf ) );
  649. *len = iob_len ( iobuf );
  650. /* Attempt to decode link-layer header */
  651. if ( ( rc = ll_protocol->pull ( snpdev->netdev, iobuf, &iob_ll_dest,
  652. &iob_ll_src, &iob_net_proto,
  653. &iob_flags ) ) != 0 ) {
  654. DBGC ( snpdev, "SNPDEV %p could not parse header: %s\n",
  655. snpdev, strerror ( rc ) );
  656. goto out_bad_ll_header;
  657. }
  658. /* Return link-layer header parameters to caller, if required */
  659. if ( ll_header_len )
  660. *ll_header_len = ll_protocol->ll_header_len;
  661. if ( ll_src )
  662. memcpy ( ll_src, iob_ll_src, ll_protocol->ll_addr_len );
  663. if ( ll_dest )
  664. memcpy ( ll_dest, iob_ll_dest, ll_protocol->ll_addr_len );
  665. if ( net_proto )
  666. *net_proto = ntohs ( iob_net_proto );
  667. rc = 0;
  668. out_bad_ll_header:
  669. free_iob ( iobuf );
  670. out_no_packet:
  671. return EFIRC ( rc );
  672. }
  673. /**
  674. * Poll event
  675. *
  676. * @v event Event
  677. * @v context Event context
  678. */
  679. static VOID EFIAPI efi_snp_wait_for_packet ( EFI_EVENT event __unused,
  680. VOID *context ) {
  681. struct efi_snp_device *snpdev = context;
  682. DBGCP ( snpdev, "SNPDEV %p WAIT_FOR_PACKET\n", snpdev );
  683. /* Do nothing unless the net device is open */
  684. if ( ! netdev_is_open ( snpdev->netdev ) )
  685. return;
  686. /* Do nothing if net device is currently claimed for use by iPXE */
  687. if ( efi_snp_claimed )
  688. return;
  689. /* Poll the network device */
  690. efi_snp_poll ( snpdev );
  691. }
  692. /** SNP interface */
  693. static EFI_SIMPLE_NETWORK_PROTOCOL efi_snp_device_snp = {
  694. .Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION,
  695. .Start = efi_snp_start,
  696. .Stop = efi_snp_stop,
  697. .Initialize = efi_snp_initialize,
  698. .Reset = efi_snp_reset,
  699. .Shutdown = efi_snp_shutdown,
  700. .ReceiveFilters = efi_snp_receive_filters,
  701. .StationAddress = efi_snp_station_address,
  702. .Statistics = efi_snp_statistics,
  703. .MCastIpToMac = efi_snp_mcast_ip_to_mac,
  704. .NvData = efi_snp_nvdata,
  705. .GetStatus = efi_snp_get_status,
  706. .Transmit = efi_snp_transmit,
  707. .Receive = efi_snp_receive,
  708. };
  709. /******************************************************************************
  710. *
  711. * UNDI protocol
  712. *
  713. ******************************************************************************
  714. */
  715. /** Union type for command parameter blocks */
  716. typedef union {
  717. PXE_CPB_STATION_ADDRESS station_address;
  718. PXE_CPB_FILL_HEADER fill_header;
  719. PXE_CPB_FILL_HEADER_FRAGMENTED fill_header_fragmented;
  720. PXE_CPB_TRANSMIT transmit;
  721. PXE_CPB_RECEIVE receive;
  722. } PXE_CPB_ANY;
  723. /** Union type for data blocks */
  724. typedef union {
  725. PXE_DB_GET_INIT_INFO get_init_info;
  726. PXE_DB_STATION_ADDRESS station_address;
  727. PXE_DB_GET_STATUS get_status;
  728. PXE_DB_RECEIVE receive;
  729. } PXE_DB_ANY;
  730. /**
  731. * Calculate UNDI byte checksum
  732. *
  733. * @v data Data
  734. * @v len Length of data
  735. * @ret sum Checksum
  736. */
  737. static uint8_t efi_undi_checksum ( void *data, size_t len ) {
  738. uint8_t *bytes = data;
  739. uint8_t sum = 0;
  740. while ( len-- )
  741. sum += *bytes++;
  742. return sum;
  743. }
  744. /**
  745. * Get UNDI SNP device interface number
  746. *
  747. * @v snpdev SNP device
  748. * @ret ifnum UNDI interface number
  749. */
  750. static unsigned int efi_undi_ifnum ( struct efi_snp_device *snpdev ) {
  751. /* iPXE network device indexes are one-based (leaving zero
  752. * meaning "unspecified"). UNDI interface numbers are
  753. * zero-based.
  754. */
  755. return ( snpdev->netdev->index - 1 );
  756. }
  757. /**
  758. * Identify UNDI SNP device
  759. *
  760. * @v ifnum Interface number
  761. * @ret snpdev SNP device, or NULL if not found
  762. */
  763. static struct efi_snp_device * efi_undi_snpdev ( unsigned int ifnum ) {
  764. struct efi_snp_device *snpdev;
  765. list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
  766. if ( efi_undi_ifnum ( snpdev ) == ifnum )
  767. return snpdev;
  768. }
  769. return NULL;
  770. }
  771. /**
  772. * Convert EFI status code to UNDI status code
  773. *
  774. * @v efirc EFI status code
  775. * @ret statcode UNDI status code
  776. */
  777. static PXE_STATCODE efi_undi_statcode ( EFI_STATUS efirc ) {
  778. switch ( efirc ) {
  779. case EFI_INVALID_PARAMETER: return PXE_STATCODE_INVALID_PARAMETER;
  780. case EFI_UNSUPPORTED: return PXE_STATCODE_UNSUPPORTED;
  781. case EFI_OUT_OF_RESOURCES: return PXE_STATCODE_BUFFER_FULL;
  782. case EFI_PROTOCOL_ERROR: return PXE_STATCODE_DEVICE_FAILURE;
  783. case EFI_NOT_READY: return PXE_STATCODE_NO_DATA;
  784. default:
  785. return PXE_STATCODE_INVALID_CDB;
  786. }
  787. }
  788. /**
  789. * Get state
  790. *
  791. * @v snpdev SNP device
  792. * @v cdb Command description block
  793. * @ret efirc EFI status code
  794. */
  795. static EFI_STATUS efi_undi_get_state ( struct efi_snp_device *snpdev,
  796. PXE_CDB *cdb ) {
  797. EFI_SIMPLE_NETWORK_MODE *mode = &snpdev->mode;
  798. DBGC ( snpdev, "UNDI %p GET STATE\n", snpdev );
  799. /* Return current state */
  800. if ( mode->State == EfiSimpleNetworkInitialized ) {
  801. cdb->StatFlags |= PXE_STATFLAGS_GET_STATE_INITIALIZED;
  802. } else if ( mode->State == EfiSimpleNetworkStarted ) {
  803. cdb->StatFlags |= PXE_STATFLAGS_GET_STATE_STARTED;
  804. } else {
  805. cdb->StatFlags |= PXE_STATFLAGS_GET_STATE_STOPPED;
  806. }
  807. return 0;
  808. }
  809. /**
  810. * Start
  811. *
  812. * @v snpdev SNP device
  813. * @ret efirc EFI status code
  814. */
  815. static EFI_STATUS efi_undi_start ( struct efi_snp_device *snpdev ) {
  816. EFI_STATUS efirc;
  817. DBGC ( snpdev, "UNDI %p START\n", snpdev );
  818. /* Start SNP device */
  819. if ( ( efirc = efi_snp_start ( &snpdev->snp ) ) != 0 )
  820. return efirc;
  821. return 0;
  822. }
  823. /**
  824. * Stop
  825. *
  826. * @v snpdev SNP device
  827. * @ret efirc EFI status code
  828. */
  829. static EFI_STATUS efi_undi_stop ( struct efi_snp_device *snpdev ) {
  830. EFI_STATUS efirc;
  831. DBGC ( snpdev, "UNDI %p STOP\n", snpdev );
  832. /* Stop SNP device */
  833. if ( ( efirc = efi_snp_stop ( &snpdev->snp ) ) != 0 )
  834. return efirc;
  835. return 0;
  836. }
  837. /**
  838. * Get initialisation information
  839. *
  840. * @v snpdev SNP device
  841. * @v cdb Command description block
  842. * @v db Data block
  843. * @ret efirc EFI status code
  844. */
  845. static EFI_STATUS efi_undi_get_init_info ( struct efi_snp_device *snpdev,
  846. PXE_CDB *cdb,
  847. PXE_DB_GET_INIT_INFO *db ) {
  848. struct net_device *netdev = snpdev->netdev;
  849. struct ll_protocol *ll_protocol = netdev->ll_protocol;
  850. DBGC ( snpdev, "UNDI %p GET INIT INFO\n", snpdev );
  851. /* Populate structure */
  852. memset ( db, 0, sizeof ( *db ) );
  853. db->FrameDataLen = ( netdev->max_pkt_len - ll_protocol->ll_header_len );
  854. db->MediaHeaderLen = ll_protocol->ll_header_len;
  855. db->HWaddrLen = ll_protocol->ll_addr_len;
  856. db->IFtype = ntohs ( ll_protocol->ll_proto );
  857. cdb->StatFlags |= ( PXE_STATFLAGS_CABLE_DETECT_SUPPORTED |
  858. PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED );
  859. return 0;
  860. }
  861. /**
  862. * Initialise
  863. *
  864. * @v snpdev SNP device
  865. * @v cdb Command description block
  866. * @v efirc EFI status code
  867. */
  868. static EFI_STATUS efi_undi_initialize ( struct efi_snp_device *snpdev,
  869. PXE_CDB *cdb ) {
  870. struct net_device *netdev = snpdev->netdev;
  871. EFI_STATUS efirc;
  872. DBGC ( snpdev, "UNDI %p INITIALIZE\n", snpdev );
  873. /* Reset SNP device */
  874. if ( ( efirc = efi_snp_initialize ( &snpdev->snp, 0, 0 ) ) != 0 )
  875. return efirc;
  876. /* Report link state */
  877. if ( ! netdev_link_ok ( netdev ) )
  878. cdb->StatFlags |= PXE_STATFLAGS_INITIALIZED_NO_MEDIA;
  879. return 0;
  880. }
  881. /**
  882. * Reset
  883. *
  884. * @v snpdev SNP device
  885. * @v efirc EFI status code
  886. */
  887. static EFI_STATUS efi_undi_reset ( struct efi_snp_device *snpdev ) {
  888. EFI_STATUS efirc;
  889. DBGC ( snpdev, "UNDI %p RESET\n", snpdev );
  890. /* Reset SNP device */
  891. if ( ( efirc = efi_snp_reset ( &snpdev->snp, 0 ) ) != 0 )
  892. return efirc;
  893. return 0;
  894. }
  895. /**
  896. * Shutdown
  897. *
  898. * @v snpdev SNP device
  899. * @v efirc EFI status code
  900. */
  901. static EFI_STATUS efi_undi_shutdown ( struct efi_snp_device *snpdev ) {
  902. EFI_STATUS efirc;
  903. DBGC ( snpdev, "UNDI %p SHUTDOWN\n", snpdev );
  904. /* Reset SNP device */
  905. if ( ( efirc = efi_snp_shutdown ( &snpdev->snp ) ) != 0 )
  906. return efirc;
  907. return 0;
  908. }
  909. /**
  910. * Get/set receive filters
  911. *
  912. * @v snpdev SNP device
  913. * @v cdb Command description block
  914. * @v efirc EFI status code
  915. */
  916. static EFI_STATUS efi_undi_receive_filters ( struct efi_snp_device *snpdev,
  917. PXE_CDB *cdb ) {
  918. DBGC ( snpdev, "UNDI %p RECEIVE FILTERS\n", snpdev );
  919. /* Mark everything as supported */
  920. cdb->StatFlags |= ( PXE_STATFLAGS_RECEIVE_FILTER_UNICAST |
  921. PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST |
  922. PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS |
  923. PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST );
  924. return 0;
  925. }
  926. /**
  927. * Get/set station address
  928. *
  929. * @v snpdev SNP device
  930. * @v cdb Command description block
  931. * @v cpb Command parameter block
  932. * @v efirc EFI status code
  933. */
  934. static EFI_STATUS efi_undi_station_address ( struct efi_snp_device *snpdev,
  935. PXE_CDB *cdb,
  936. PXE_CPB_STATION_ADDRESS *cpb,
  937. PXE_DB_STATION_ADDRESS *db ) {
  938. struct net_device *netdev = snpdev->netdev;
  939. struct ll_protocol *ll_protocol = netdev->ll_protocol;
  940. void *mac;
  941. int reset;
  942. EFI_STATUS efirc;
  943. DBGC ( snpdev, "UNDI %p STATION ADDRESS\n", snpdev );
  944. /* Update address if applicable */
  945. reset = ( cdb->OpFlags & PXE_OPFLAGS_STATION_ADDRESS_RESET );
  946. mac = ( cpb ? &cpb->StationAddr : NULL );
  947. if ( ( reset || mac ) &&
  948. ( ( efirc = efi_snp_station_address ( &snpdev->snp, reset,
  949. mac ) ) != 0 ) )
  950. return efirc;
  951. /* Fill in current addresses, if applicable */
  952. if ( db ) {
  953. memset ( db, 0, sizeof ( *db ) );
  954. memcpy ( &db->StationAddr, netdev->ll_addr,
  955. ll_protocol->ll_addr_len );
  956. memcpy ( &db->BroadcastAddr, netdev->ll_broadcast,
  957. ll_protocol->ll_addr_len );
  958. memcpy ( &db->PermanentAddr, netdev->hw_addr,
  959. ll_protocol->hw_addr_len );
  960. }
  961. return 0;
  962. }
  963. /**
  964. * Get interrupt status
  965. *
  966. * @v snpdev SNP device
  967. * @v cdb Command description block
  968. * @v db Data block
  969. * @v efirc EFI status code
  970. */
  971. static EFI_STATUS efi_undi_get_status ( struct efi_snp_device *snpdev,
  972. PXE_CDB *cdb, PXE_DB_GET_STATUS *db ) {
  973. UINT32 interrupts;
  974. VOID *txbuf;
  975. struct io_buffer *rxbuf;
  976. EFI_STATUS efirc;
  977. DBGC2 ( snpdev, "UNDI %p GET STATUS\n", snpdev );
  978. /* Get status */
  979. if ( ( efirc = efi_snp_get_status ( &snpdev->snp, &interrupts,
  980. &txbuf ) ) != 0 )
  981. return efirc;
  982. /* Report status */
  983. memset ( db, 0, sizeof ( *db ) );
  984. if ( interrupts & EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT )
  985. cdb->StatFlags |= PXE_STATFLAGS_GET_STATUS_RECEIVE;
  986. if ( interrupts & EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT )
  987. cdb->StatFlags |= PXE_STATFLAGS_GET_STATUS_TRANSMIT;
  988. if ( txbuf ) {
  989. db->TxBuffer[0] = ( ( intptr_t ) txbuf );
  990. } else {
  991. cdb->StatFlags |= PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN;
  992. /* The specification states clearly that UNDI drivers
  993. * should set TXBUF_QUEUE_EMPTY if all completed
  994. * buffer addresses are written into the returned data
  995. * block. However, SnpDxe chooses to interpret
  996. * TXBUF_QUEUE_EMPTY as a synonym for
  997. * NO_TXBUFS_WRITTEN, thereby rendering it entirely
  998. * pointless. Work around this UEFI stupidity, as per
  999. * usual.
  1000. */
  1001. if ( snpdev->tx_prod == snpdev->tx_cons )
  1002. cdb->StatFlags |=
  1003. PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY;
  1004. }
  1005. rxbuf = list_first_entry ( &snpdev->rx, struct io_buffer, list );
  1006. if ( rxbuf )
  1007. db->RxFrameLen = iob_len ( rxbuf );
  1008. if ( ! netdev_link_ok ( snpdev->netdev ) )
  1009. cdb->StatFlags |= PXE_STATFLAGS_GET_STATUS_NO_MEDIA;
  1010. return 0;
  1011. }
  1012. /**
  1013. * Fill header
  1014. *
  1015. * @v snpdev SNP device
  1016. * @v cdb Command description block
  1017. * @v cpb Command parameter block
  1018. * @v efirc EFI status code
  1019. */
  1020. static EFI_STATUS efi_undi_fill_header ( struct efi_snp_device *snpdev,
  1021. PXE_CDB *cdb, PXE_CPB_ANY *cpb ) {
  1022. struct net_device *netdev = snpdev->netdev;
  1023. struct ll_protocol *ll_protocol = netdev->ll_protocol;
  1024. PXE_CPB_FILL_HEADER *whole = &cpb->fill_header;
  1025. PXE_CPB_FILL_HEADER_FRAGMENTED *fragged = &cpb->fill_header_fragmented;
  1026. VOID *data;
  1027. void *dest;
  1028. void *src;
  1029. uint16_t proto;
  1030. struct io_buffer iobuf;
  1031. int rc;
  1032. /* SnpDxe will (pointlessly) use PXE_CPB_FILL_HEADER_FRAGMENTED
  1033. * even though we choose to explicitly not claim support for
  1034. * fragments via PXE_ROMID_IMP_FRAG_SUPPORTED.
  1035. */
  1036. if ( cdb->OpFlags & PXE_OPFLAGS_FILL_HEADER_FRAGMENTED ) {
  1037. data = ( ( void * ) ( intptr_t ) fragged->FragDesc[0].FragAddr);
  1038. dest = &fragged->DestAddr;
  1039. src = &fragged->SrcAddr;
  1040. proto = fragged->Protocol;
  1041. } else {
  1042. data = ( ( void * ) ( intptr_t ) whole->MediaHeader );
  1043. dest = &whole->DestAddr;
  1044. src = &whole->SrcAddr;
  1045. proto = whole->Protocol;
  1046. }
  1047. /* Construct link-layer header */
  1048. iob_populate ( &iobuf, data, 0, ll_protocol->ll_header_len );
  1049. iob_reserve ( &iobuf, ll_protocol->ll_header_len );
  1050. if ( ( rc = ll_protocol->push ( netdev, &iobuf, dest, src,
  1051. proto ) ) != 0 )
  1052. return EFIRC ( rc );
  1053. return 0;
  1054. }
  1055. /**
  1056. * Transmit
  1057. *
  1058. * @v snpdev SNP device
  1059. * @v cpb Command parameter block
  1060. * @v efirc EFI status code
  1061. */
  1062. static EFI_STATUS efi_undi_transmit ( struct efi_snp_device *snpdev,
  1063. PXE_CPB_TRANSMIT *cpb ) {
  1064. VOID *data = ( ( void * ) ( intptr_t ) cpb->FrameAddr );
  1065. EFI_STATUS efirc;
  1066. DBGC2 ( snpdev, "UNDI %p TRANSMIT\n", snpdev );
  1067. /* Transmit packet */
  1068. if ( ( efirc = efi_snp_transmit ( &snpdev->snp, 0, cpb->DataLen,
  1069. data, NULL, NULL, NULL ) ) != 0 )
  1070. return efirc;
  1071. return 0;
  1072. }
  1073. /**
  1074. * Receive
  1075. *
  1076. * @v snpdev SNP device
  1077. * @v cpb Command parameter block
  1078. * @v efirc EFI status code
  1079. */
  1080. static EFI_STATUS efi_undi_receive ( struct efi_snp_device *snpdev,
  1081. PXE_CPB_RECEIVE *cpb,
  1082. PXE_DB_RECEIVE *db ) {
  1083. struct net_device *netdev = snpdev->netdev;
  1084. struct ll_protocol *ll_protocol = netdev->ll_protocol;
  1085. VOID *data = ( ( void * ) ( intptr_t ) cpb->BufferAddr );
  1086. UINTN hdr_len;
  1087. UINTN len = cpb->BufferLen;
  1088. EFI_MAC_ADDRESS src;
  1089. EFI_MAC_ADDRESS dest;
  1090. UINT16 proto;
  1091. EFI_STATUS efirc;
  1092. DBGC2 ( snpdev, "UNDI %p RECEIVE\n", snpdev );
  1093. /* Receive packet */
  1094. if ( ( efirc = efi_snp_receive ( &snpdev->snp, &hdr_len, &len, data,
  1095. &src, &dest, &proto ) ) != 0 )
  1096. return efirc;
  1097. /* Describe frame */
  1098. memset ( db, 0, sizeof ( *db ) );
  1099. memcpy ( &db->SrcAddr, &src, ll_protocol->ll_addr_len );
  1100. memcpy ( &db->DestAddr, &dest, ll_protocol->ll_addr_len );
  1101. db->FrameLen = len;
  1102. db->Protocol = proto;
  1103. db->MediaHeaderLen = ll_protocol->ll_header_len;
  1104. db->Type = PXE_FRAME_TYPE_PROMISCUOUS;
  1105. return 0;
  1106. }
  1107. /** UNDI entry point */
  1108. static EFIAPI VOID efi_undi_issue ( UINT64 cdb_phys ) {
  1109. PXE_CDB *cdb = ( ( void * ) ( intptr_t ) cdb_phys );
  1110. PXE_CPB_ANY *cpb = ( ( void * ) ( intptr_t ) cdb->CPBaddr );
  1111. PXE_DB_ANY *db = ( ( void * ) ( intptr_t ) cdb->DBaddr );
  1112. struct efi_snp_device *snpdev;
  1113. EFI_STATUS efirc;
  1114. /* Identify device */
  1115. snpdev = efi_undi_snpdev ( cdb->IFnum );
  1116. if ( ! snpdev ) {
  1117. DBGC ( cdb, "UNDI invalid interface number %d\n", cdb->IFnum );
  1118. cdb->StatCode = PXE_STATCODE_INVALID_CDB;
  1119. cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
  1120. return;
  1121. }
  1122. /* Fail if net device is currently claimed for use by iPXE */
  1123. if ( efi_snp_claimed ) {
  1124. cdb->StatCode = PXE_STATCODE_BUSY;
  1125. cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
  1126. return;
  1127. }
  1128. /* Handle opcode */
  1129. cdb->StatCode = PXE_STATCODE_SUCCESS;
  1130. cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
  1131. switch ( cdb->OpCode ) {
  1132. case PXE_OPCODE_GET_STATE:
  1133. efirc = efi_undi_get_state ( snpdev, cdb );
  1134. break;
  1135. case PXE_OPCODE_START:
  1136. efirc = efi_undi_start ( snpdev );
  1137. break;
  1138. case PXE_OPCODE_STOP:
  1139. efirc = efi_undi_stop ( snpdev );
  1140. break;
  1141. case PXE_OPCODE_GET_INIT_INFO:
  1142. efirc = efi_undi_get_init_info ( snpdev, cdb,
  1143. &db->get_init_info );
  1144. break;
  1145. case PXE_OPCODE_INITIALIZE:
  1146. efirc = efi_undi_initialize ( snpdev, cdb );
  1147. break;
  1148. case PXE_OPCODE_RESET:
  1149. efirc = efi_undi_reset ( snpdev );
  1150. break;
  1151. case PXE_OPCODE_SHUTDOWN:
  1152. efirc = efi_undi_shutdown ( snpdev );
  1153. break;
  1154. case PXE_OPCODE_RECEIVE_FILTERS:
  1155. efirc = efi_undi_receive_filters ( snpdev, cdb );
  1156. break;
  1157. case PXE_OPCODE_STATION_ADDRESS:
  1158. efirc = efi_undi_station_address ( snpdev, cdb,
  1159. &cpb->station_address,
  1160. &db->station_address );
  1161. break;
  1162. case PXE_OPCODE_GET_STATUS:
  1163. efirc = efi_undi_get_status ( snpdev, cdb, &db->get_status );
  1164. break;
  1165. case PXE_OPCODE_FILL_HEADER:
  1166. efirc = efi_undi_fill_header ( snpdev, cdb, cpb );
  1167. break;
  1168. case PXE_OPCODE_TRANSMIT:
  1169. efirc = efi_undi_transmit ( snpdev, &cpb->transmit );
  1170. break;
  1171. case PXE_OPCODE_RECEIVE:
  1172. efirc = efi_undi_receive ( snpdev, &cpb->receive,
  1173. &db->receive );
  1174. break;
  1175. default:
  1176. DBGC ( snpdev, "UNDI %p unsupported opcode %#04x\n",
  1177. snpdev, cdb->OpCode );
  1178. efirc = EFI_UNSUPPORTED;
  1179. break;
  1180. }
  1181. /* Convert EFI status code to UNDI status code */
  1182. if ( efirc != 0 ) {
  1183. cdb->StatFlags &= ~PXE_STATFLAGS_STATUS_MASK;
  1184. cdb->StatFlags |= PXE_STATFLAGS_COMMAND_FAILED;
  1185. cdb->StatCode = efi_undi_statcode ( efirc );
  1186. }
  1187. }
  1188. /** UNDI interface
  1189. *
  1190. * Must be aligned on a 16-byte boundary, for no particularly good
  1191. * reason.
  1192. */
  1193. static PXE_SW_UNDI efi_snp_undi __attribute__ (( aligned ( 16 ) )) = {
  1194. .Signature = PXE_ROMID_SIGNATURE,
  1195. .Len = sizeof ( efi_snp_undi ),
  1196. .Rev = PXE_ROMID_REV,
  1197. .MajorVer = PXE_ROMID_MAJORVER,
  1198. .MinorVer = PXE_ROMID_MINORVER,
  1199. .Implementation = ( PXE_ROMID_IMP_SW_VIRT_ADDR |
  1200. PXE_ROMID_IMP_STATION_ADDR_SETTABLE |
  1201. PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED |
  1202. PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED |
  1203. PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED |
  1204. PXE_ROMID_IMP_TX_COMPLETE_INT_SUPPORTED |
  1205. PXE_ROMID_IMP_PACKET_RX_INT_SUPPORTED ),
  1206. /* SnpDxe checks that BusCnt is non-zero. It makes no further
  1207. * use of BusCnt, and never looks as BusType[]. As with much
  1208. * of the EDK2 code, this check seems to serve no purpose
  1209. * whatsoever but must nonetheless be humoured.
  1210. */
  1211. .BusCnt = 1,
  1212. .BusType[0] = PXE_BUSTYPE ( 'i', 'P', 'X', 'E' ),
  1213. };
  1214. /** Network Identification Interface (NII) */
  1215. static EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL efi_snp_device_nii = {
  1216. .Revision = EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION,
  1217. .StringId = "UNDI",
  1218. .Type = EfiNetworkInterfaceUndi,
  1219. .MajorVer = 3,
  1220. .MinorVer = 1,
  1221. .Ipv6Supported = TRUE, /* This is a raw packet interface, FFS! */
  1222. };
  1223. /******************************************************************************
  1224. *
  1225. * Component name protocol
  1226. *
  1227. ******************************************************************************
  1228. */
  1229. /**
  1230. * Look up driver name
  1231. *
  1232. * @v name2 Component name protocol
  1233. * @v language Language to use
  1234. * @v driver_name Driver name to fill in
  1235. * @ret efirc EFI status code
  1236. */
  1237. static EFI_STATUS EFIAPI
  1238. efi_snp_get_driver_name ( EFI_COMPONENT_NAME2_PROTOCOL *name2,
  1239. CHAR8 *language __unused, CHAR16 **driver_name ) {
  1240. struct efi_snp_device *snpdev =
  1241. container_of ( name2, struct efi_snp_device, name2 );
  1242. *driver_name = snpdev->driver_name;
  1243. return 0;
  1244. }
  1245. /**
  1246. * Look up controller name
  1247. *
  1248. * @v name2 Component name protocol
  1249. * @v device Device
  1250. * @v child Child device, or NULL
  1251. * @v language Language to use
  1252. * @v driver_name Device name to fill in
  1253. * @ret efirc EFI status code
  1254. */
  1255. static EFI_STATUS EFIAPI
  1256. efi_snp_get_controller_name ( EFI_COMPONENT_NAME2_PROTOCOL *name2,
  1257. EFI_HANDLE device __unused,
  1258. EFI_HANDLE child __unused,
  1259. CHAR8 *language __unused,
  1260. CHAR16 **controller_name ) {
  1261. struct efi_snp_device *snpdev =
  1262. container_of ( name2, struct efi_snp_device, name2 );
  1263. *controller_name = snpdev->controller_name;
  1264. return 0;
  1265. }
  1266. /******************************************************************************
  1267. *
  1268. * Load file protocol
  1269. *
  1270. ******************************************************************************
  1271. */
  1272. /**
  1273. * Load file
  1274. *
  1275. * @v loadfile Load file protocol
  1276. * @v path File path
  1277. * @v booting Loading as part of a boot attempt
  1278. * @ret efirc EFI status code
  1279. */
  1280. static EFI_STATUS EFIAPI
  1281. efi_snp_load_file ( EFI_LOAD_FILE_PROTOCOL *load_file,
  1282. EFI_DEVICE_PATH_PROTOCOL *path __unused,
  1283. BOOLEAN booting, UINTN *len __unused,
  1284. VOID *data __unused ) {
  1285. struct efi_snp_device *snpdev =
  1286. container_of ( load_file, struct efi_snp_device, load_file );
  1287. struct net_device *netdev = snpdev->netdev;
  1288. int rc;
  1289. /* Fail unless this is a boot attempt */
  1290. if ( ! booting ) {
  1291. DBGC ( snpdev, "SNPDEV %p cannot load non-boot file\n",
  1292. snpdev );
  1293. return EFI_UNSUPPORTED;
  1294. }
  1295. /* Claim network devices for use by iPXE */
  1296. efi_snp_claim();
  1297. /* Start watchdog holdoff timer */
  1298. efi_watchdog_start();
  1299. /* Boot from network device */
  1300. if ( ( rc = ipxe ( netdev ) ) != 0 )
  1301. goto err_ipxe;
  1302. /* Reset console */
  1303. console_reset();
  1304. err_ipxe:
  1305. efi_watchdog_stop();
  1306. efi_snp_release();
  1307. return EFIRC ( rc );
  1308. }
  1309. /** Load file protocol */
  1310. static EFI_LOAD_FILE_PROTOCOL efi_snp_load_file_protocol = {
  1311. .LoadFile = efi_snp_load_file,
  1312. };
  1313. /******************************************************************************
  1314. *
  1315. * iPXE network driver
  1316. *
  1317. ******************************************************************************
  1318. */
  1319. /**
  1320. * Locate SNP device corresponding to network device
  1321. *
  1322. * @v netdev Network device
  1323. * @ret snp SNP device, or NULL if not found
  1324. */
  1325. static struct efi_snp_device * efi_snp_demux ( struct net_device *netdev ) {
  1326. struct efi_snp_device *snpdev;
  1327. list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
  1328. if ( snpdev->netdev == netdev )
  1329. return snpdev;
  1330. }
  1331. return NULL;
  1332. }
  1333. /**
  1334. * Create SNP device
  1335. *
  1336. * @v netdev Network device
  1337. * @ret rc Return status code
  1338. */
  1339. static int efi_snp_probe ( struct net_device *netdev ) {
  1340. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  1341. struct efi_device *efidev;
  1342. struct efi_snp_device *snpdev;
  1343. EFI_DEVICE_PATH_PROTOCOL *path_end;
  1344. MAC_ADDR_DEVICE_PATH *macpath;
  1345. size_t path_prefix_len = 0;
  1346. unsigned int ifcnt;
  1347. void *interface;
  1348. EFI_STATUS efirc;
  1349. int rc;
  1350. /* Find parent EFI device */
  1351. efidev = efidev_parent ( netdev->dev );
  1352. if ( ! efidev ) {
  1353. DBG ( "SNP skipping non-EFI device %s\n", netdev->name );
  1354. rc = 0;
  1355. goto err_no_efidev;
  1356. }
  1357. /* Allocate the SNP device */
  1358. snpdev = zalloc ( sizeof ( *snpdev ) );
  1359. if ( ! snpdev ) {
  1360. rc = -ENOMEM;
  1361. goto err_alloc_snp;
  1362. }
  1363. snpdev->netdev = netdev_get ( netdev );
  1364. snpdev->efidev = efidev;
  1365. INIT_LIST_HEAD ( &snpdev->rx );
  1366. /* Sanity check */
  1367. if ( netdev->ll_protocol->ll_addr_len > sizeof ( EFI_MAC_ADDRESS ) ) {
  1368. DBGC ( snpdev, "SNPDEV %p cannot support link-layer address "
  1369. "length %d for %s\n", snpdev,
  1370. netdev->ll_protocol->ll_addr_len, netdev->name );
  1371. rc = -ENOTSUP;
  1372. goto err_ll_addr_len;
  1373. }
  1374. /* Populate the SNP structure */
  1375. memcpy ( &snpdev->snp, &efi_snp_device_snp, sizeof ( snpdev->snp ) );
  1376. snpdev->snp.Mode = &snpdev->mode;
  1377. if ( ( efirc = bs->CreateEvent ( EVT_NOTIFY_WAIT, TPL_NOTIFY,
  1378. efi_snp_wait_for_packet, snpdev,
  1379. &snpdev->snp.WaitForPacket ) ) != 0 ){
  1380. rc = -EEFI ( efirc );
  1381. DBGC ( snpdev, "SNPDEV %p could not create event: %s\n",
  1382. snpdev, strerror ( rc ) );
  1383. goto err_create_event;
  1384. }
  1385. /* Populate the SNP mode structure */
  1386. snpdev->mode.State = EfiSimpleNetworkStopped;
  1387. efi_snp_set_mode ( snpdev );
  1388. /* Populate the NII structure */
  1389. memcpy ( &snpdev->nii, &efi_snp_device_nii, sizeof ( snpdev->nii ) );
  1390. snpdev->nii.Id = ( ( intptr_t ) &efi_snp_undi );
  1391. snpdev->nii.IfNum = efi_undi_ifnum ( snpdev );
  1392. efi_snp_undi.EntryPoint = ( ( intptr_t ) efi_undi_issue );
  1393. ifcnt = ( ( efi_snp_undi.IFcntExt << 8 ) | efi_snp_undi.IFcnt );
  1394. if ( ifcnt < snpdev->nii.IfNum )
  1395. ifcnt = snpdev->nii.IfNum;
  1396. efi_snp_undi.IFcnt = ( ifcnt & 0xff );
  1397. efi_snp_undi.IFcntExt = ( ifcnt >> 8 );
  1398. efi_snp_undi.Fudge -= efi_undi_checksum ( &efi_snp_undi,
  1399. sizeof ( efi_snp_undi ) );
  1400. /* Populate the component name structure */
  1401. efi_snprintf ( snpdev->driver_name,
  1402. ( sizeof ( snpdev->driver_name ) /
  1403. sizeof ( snpdev->driver_name[0] ) ),
  1404. "%s %s", product_short_name, netdev->dev->driver_name );
  1405. efi_snprintf ( snpdev->controller_name,
  1406. ( sizeof ( snpdev->controller_name ) /
  1407. sizeof ( snpdev->controller_name[0] ) ),
  1408. "%s %s (%s, %s)", product_short_name,
  1409. netdev->dev->driver_name, netdev->dev->name,
  1410. netdev_addr ( netdev ) );
  1411. snpdev->name2.GetDriverName = efi_snp_get_driver_name;
  1412. snpdev->name2.GetControllerName = efi_snp_get_controller_name;
  1413. snpdev->name2.SupportedLanguages = "en";
  1414. /* Populate the load file protocol structure */
  1415. memcpy ( &snpdev->load_file, &efi_snp_load_file_protocol,
  1416. sizeof ( snpdev->load_file ) );
  1417. /* Populate the device name */
  1418. efi_snprintf ( snpdev->name, ( sizeof ( snpdev->name ) /
  1419. sizeof ( snpdev->name[0] ) ),
  1420. "%s", netdev->name );
  1421. /* Allocate the new device path */
  1422. path_prefix_len = efi_devpath_len ( efidev->path );
  1423. snpdev->path = zalloc ( path_prefix_len + sizeof ( *macpath ) +
  1424. sizeof ( *path_end ) );
  1425. if ( ! snpdev->path ) {
  1426. rc = -ENOMEM;
  1427. goto err_alloc_device_path;
  1428. }
  1429. /* Populate the device path */
  1430. memcpy ( snpdev->path, efidev->path, path_prefix_len );
  1431. macpath = ( ( ( void * ) snpdev->path ) + path_prefix_len );
  1432. path_end = ( ( void * ) ( macpath + 1 ) );
  1433. memset ( macpath, 0, sizeof ( *macpath ) );
  1434. macpath->Header.Type = MESSAGING_DEVICE_PATH;
  1435. macpath->Header.SubType = MSG_MAC_ADDR_DP;
  1436. macpath->Header.Length[0] = sizeof ( *macpath );
  1437. memcpy ( &macpath->MacAddress, netdev->ll_addr,
  1438. sizeof ( macpath->MacAddress ) );
  1439. macpath->IfType = ntohs ( netdev->ll_protocol->ll_proto );
  1440. memset ( path_end, 0, sizeof ( *path_end ) );
  1441. path_end->Type = END_DEVICE_PATH_TYPE;
  1442. path_end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
  1443. path_end->Length[0] = sizeof ( *path_end );
  1444. /* Install the SNP */
  1445. if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
  1446. &snpdev->handle,
  1447. &efi_simple_network_protocol_guid, &snpdev->snp,
  1448. &efi_device_path_protocol_guid, snpdev->path,
  1449. &efi_nii_protocol_guid, &snpdev->nii,
  1450. &efi_nii31_protocol_guid, &snpdev->nii,
  1451. &efi_component_name2_protocol_guid, &snpdev->name2,
  1452. &efi_load_file_protocol_guid, &snpdev->load_file,
  1453. NULL ) ) != 0 ) {
  1454. rc = -EEFI ( efirc );
  1455. DBGC ( snpdev, "SNPDEV %p could not install protocols: %s\n",
  1456. snpdev, strerror ( rc ) );
  1457. goto err_install_protocol_interface;
  1458. }
  1459. /* SnpDxe will repeatedly start up and shut down our NII/UNDI
  1460. * interface (in order to obtain the MAC address) before
  1461. * discovering that it cannot install another SNP on the same
  1462. * handle. This causes the underlying network device to be
  1463. * unexpectedly closed.
  1464. *
  1465. * Prevent this by opening our own NII (and NII31) protocol
  1466. * instances to prevent SnpDxe from attempting to bind to
  1467. * them.
  1468. */
  1469. if ( ( efirc = bs->OpenProtocol ( snpdev->handle,
  1470. &efi_nii_protocol_guid, &interface,
  1471. efi_image_handle, snpdev->handle,
  1472. ( EFI_OPEN_PROTOCOL_BY_DRIVER |
  1473. EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
  1474. rc = -EEFI ( efirc );
  1475. DBGC ( snpdev, "SNPDEV %p could not open NII protocol: %s\n",
  1476. snpdev, strerror ( rc ) );
  1477. goto err_open_nii;
  1478. }
  1479. if ( ( efirc = bs->OpenProtocol ( snpdev->handle,
  1480. &efi_nii31_protocol_guid, &interface,
  1481. efi_image_handle, snpdev->handle,
  1482. ( EFI_OPEN_PROTOCOL_BY_DRIVER |
  1483. EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
  1484. rc = -EEFI ( efirc );
  1485. DBGC ( snpdev, "SNPDEV %p could not open NII31 protocol: %s\n",
  1486. snpdev, strerror ( rc ) );
  1487. goto err_open_nii31;
  1488. }
  1489. /* Add as child of EFI parent device */
  1490. if ( ( rc = efi_child_add ( efidev->device, snpdev->handle ) ) != 0 ) {
  1491. DBGC ( snpdev, "SNPDEV %p could not become child of %s: %s\n",
  1492. snpdev, efi_handle_name ( efidev->device ),
  1493. strerror ( rc ) );
  1494. goto err_efi_child_add;
  1495. }
  1496. /* Install HII */
  1497. if ( ( rc = efi_snp_hii_install ( snpdev ) ) != 0 ) {
  1498. DBGC ( snpdev, "SNPDEV %p could not install HII: %s\n",
  1499. snpdev, strerror ( rc ) );
  1500. /* HII fails on several platforms. It's
  1501. * non-essential, so treat this as a non-fatal
  1502. * error.
  1503. */
  1504. }
  1505. /* Add to list of SNP devices */
  1506. list_add ( &snpdev->list, &efi_snp_devices );
  1507. /* Close device path */
  1508. bs->CloseProtocol ( efidev->device, &efi_device_path_protocol_guid,
  1509. efi_image_handle, efidev->device );
  1510. DBGC ( snpdev, "SNPDEV %p installed for %s as device %s\n",
  1511. snpdev, netdev->name, efi_handle_name ( snpdev->handle ) );
  1512. return 0;
  1513. list_del ( &snpdev->list );
  1514. if ( snpdev->package_list )
  1515. efi_snp_hii_uninstall ( snpdev );
  1516. efi_child_del ( efidev->device, snpdev->handle );
  1517. err_efi_child_add:
  1518. bs->CloseProtocol ( snpdev->handle, &efi_nii_protocol_guid,
  1519. efi_image_handle, snpdev->handle );
  1520. err_open_nii:
  1521. bs->CloseProtocol ( snpdev->handle, &efi_nii31_protocol_guid,
  1522. efi_image_handle, snpdev->handle );
  1523. err_open_nii31:
  1524. bs->UninstallMultipleProtocolInterfaces (
  1525. snpdev->handle,
  1526. &efi_simple_network_protocol_guid, &snpdev->snp,
  1527. &efi_device_path_protocol_guid, snpdev->path,
  1528. &efi_nii_protocol_guid, &snpdev->nii,
  1529. &efi_nii31_protocol_guid, &snpdev->nii,
  1530. &efi_component_name2_protocol_guid, &snpdev->name2,
  1531. &efi_load_file_protocol_guid, &snpdev->load_file,
  1532. NULL );
  1533. err_install_protocol_interface:
  1534. free ( snpdev->path );
  1535. err_alloc_device_path:
  1536. bs->CloseEvent ( snpdev->snp.WaitForPacket );
  1537. err_create_event:
  1538. err_ll_addr_len:
  1539. netdev_put ( netdev );
  1540. free ( snpdev );
  1541. err_alloc_snp:
  1542. err_no_efidev:
  1543. return rc;
  1544. }
  1545. /**
  1546. * Handle SNP device or link state change
  1547. *
  1548. * @v netdev Network device
  1549. */
  1550. static void efi_snp_notify ( struct net_device *netdev ) {
  1551. struct efi_snp_device *snpdev;
  1552. /* Locate SNP device */
  1553. snpdev = efi_snp_demux ( netdev );
  1554. if ( ! snpdev ) {
  1555. DBG ( "SNP skipping non-SNP device %s\n", netdev->name );
  1556. return;
  1557. }
  1558. /* Update link state */
  1559. snpdev->mode.MediaPresent =
  1560. ( netdev_link_ok ( netdev ) ? TRUE : FALSE );
  1561. DBGC ( snpdev, "SNPDEV %p link is %s\n", snpdev,
  1562. ( snpdev->mode.MediaPresent ? "up" : "down" ) );
  1563. /* Update mode state */
  1564. efi_snp_set_state ( snpdev );
  1565. }
  1566. /**
  1567. * Destroy SNP device
  1568. *
  1569. * @v netdev Network device
  1570. */
  1571. static void efi_snp_remove ( struct net_device *netdev ) {
  1572. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  1573. struct efi_snp_device *snpdev;
  1574. /* Locate SNP device */
  1575. snpdev = efi_snp_demux ( netdev );
  1576. if ( ! snpdev ) {
  1577. DBG ( "SNP skipping non-SNP device %s\n", netdev->name );
  1578. return;
  1579. }
  1580. /* Uninstall the SNP */
  1581. list_del ( &snpdev->list );
  1582. if ( snpdev->package_list )
  1583. efi_snp_hii_uninstall ( snpdev );
  1584. efi_child_del ( snpdev->efidev->device, snpdev->handle );
  1585. bs->CloseProtocol ( snpdev->handle, &efi_nii_protocol_guid,
  1586. efi_image_handle, snpdev->handle );
  1587. bs->CloseProtocol ( snpdev->handle, &efi_nii31_protocol_guid,
  1588. efi_image_handle, snpdev->handle );
  1589. bs->UninstallMultipleProtocolInterfaces (
  1590. snpdev->handle,
  1591. &efi_simple_network_protocol_guid, &snpdev->snp,
  1592. &efi_device_path_protocol_guid, snpdev->path,
  1593. &efi_nii_protocol_guid, &snpdev->nii,
  1594. &efi_nii31_protocol_guid, &snpdev->nii,
  1595. &efi_component_name2_protocol_guid, &snpdev->name2,
  1596. &efi_load_file_protocol_guid, &snpdev->load_file,
  1597. NULL );
  1598. free ( snpdev->path );
  1599. bs->CloseEvent ( snpdev->snp.WaitForPacket );
  1600. netdev_put ( snpdev->netdev );
  1601. free ( snpdev );
  1602. }
  1603. /** SNP driver */
  1604. struct net_driver efi_snp_driver __net_driver = {
  1605. .name = "SNP",
  1606. .probe = efi_snp_probe,
  1607. .notify = efi_snp_notify,
  1608. .remove = efi_snp_remove,
  1609. };
  1610. /**
  1611. * Find SNP device by EFI device handle
  1612. *
  1613. * @v handle EFI device handle
  1614. * @ret snpdev SNP device, or NULL
  1615. */
  1616. struct efi_snp_device * find_snpdev ( EFI_HANDLE handle ) {
  1617. struct efi_snp_device *snpdev;
  1618. list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
  1619. if ( snpdev->handle == handle )
  1620. return snpdev;
  1621. }
  1622. return NULL;
  1623. }
  1624. /**
  1625. * Get most recently opened SNP device
  1626. *
  1627. * @ret snpdev Most recently opened SNP device, or NULL
  1628. */
  1629. struct efi_snp_device * last_opened_snpdev ( void ) {
  1630. struct net_device *netdev;
  1631. netdev = last_opened_netdev();
  1632. if ( ! netdev )
  1633. return NULL;
  1634. return efi_snp_demux ( netdev );
  1635. }
  1636. /**
  1637. * Add to SNP claimed/released count
  1638. *
  1639. * @v delta Claim count change
  1640. */
  1641. void efi_snp_add_claim ( int delta ) {
  1642. struct efi_snp_device *snpdev;
  1643. /* Claim SNP devices */
  1644. efi_snp_claimed += delta;
  1645. assert ( efi_snp_claimed >= 0 );
  1646. /* Update SNP mode state for each interface */
  1647. list_for_each_entry ( snpdev, &efi_snp_devices, list )
  1648. efi_snp_set_state ( snpdev );
  1649. }