Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

efi_snp.c 53KB

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