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

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900
  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. int rc;
  632. DBGC2 ( snpdev, "SNPDEV %p RECEIVE %p(+%lx)", snpdev, data,
  633. ( ( unsigned long ) *len ) );
  634. /* Fail if net device is currently claimed for use by iPXE */
  635. if ( efi_snp_claimed )
  636. return EFI_NOT_READY;
  637. /* Poll the network device */
  638. efi_snp_poll ( snpdev );
  639. /* Dequeue a packet, if one is available */
  640. iobuf = list_first_entry ( &snpdev->rx, struct io_buffer, list );
  641. if ( ! iobuf ) {
  642. DBGC2 ( snpdev, "\n" );
  643. rc = -EAGAIN;
  644. goto out_no_packet;
  645. }
  646. list_del ( &iobuf->list );
  647. DBGC2 ( snpdev, "+%zx\n", iob_len ( iobuf ) );
  648. /* Return packet to caller */
  649. memcpy ( data, iobuf->data, iob_len ( iobuf ) );
  650. *len = iob_len ( iobuf );
  651. /* Attempt to decode link-layer header */
  652. if ( ( rc = ll_protocol->pull ( snpdev->netdev, iobuf, &iob_ll_dest,
  653. &iob_ll_src, &iob_net_proto,
  654. &iob_flags ) ) != 0 ) {
  655. DBGC ( snpdev, "SNPDEV %p could not parse header: %s\n",
  656. snpdev, strerror ( rc ) );
  657. goto out_bad_ll_header;
  658. }
  659. /* Return link-layer header parameters to caller, if required */
  660. if ( ll_header_len )
  661. *ll_header_len = ll_protocol->ll_header_len;
  662. if ( ll_src )
  663. memcpy ( ll_src, iob_ll_src, ll_protocol->ll_addr_len );
  664. if ( ll_dest )
  665. memcpy ( ll_dest, iob_ll_dest, ll_protocol->ll_addr_len );
  666. if ( net_proto )
  667. *net_proto = ntohs ( iob_net_proto );
  668. rc = 0;
  669. out_bad_ll_header:
  670. free_iob ( iobuf );
  671. out_no_packet:
  672. return EFIRC ( rc );
  673. }
  674. /**
  675. * Poll event
  676. *
  677. * @v event Event
  678. * @v context Event context
  679. */
  680. static VOID EFIAPI efi_snp_wait_for_packet ( EFI_EVENT event __unused,
  681. VOID *context ) {
  682. struct efi_snp_device *snpdev = context;
  683. DBGCP ( snpdev, "SNPDEV %p WAIT_FOR_PACKET\n", snpdev );
  684. /* Do nothing unless the net device is open */
  685. if ( ! netdev_is_open ( snpdev->netdev ) )
  686. return;
  687. /* Do nothing if net device is currently claimed for use by iPXE */
  688. if ( efi_snp_claimed )
  689. return;
  690. /* Poll the network device */
  691. efi_snp_poll ( snpdev );
  692. }
  693. /** SNP interface */
  694. static EFI_SIMPLE_NETWORK_PROTOCOL efi_snp_device_snp = {
  695. .Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION,
  696. .Start = efi_snp_start,
  697. .Stop = efi_snp_stop,
  698. .Initialize = efi_snp_initialize,
  699. .Reset = efi_snp_reset,
  700. .Shutdown = efi_snp_shutdown,
  701. .ReceiveFilters = efi_snp_receive_filters,
  702. .StationAddress = efi_snp_station_address,
  703. .Statistics = efi_snp_statistics,
  704. .MCastIpToMac = efi_snp_mcast_ip_to_mac,
  705. .NvData = efi_snp_nvdata,
  706. .GetStatus = efi_snp_get_status,
  707. .Transmit = efi_snp_transmit,
  708. .Receive = efi_snp_receive,
  709. };
  710. /******************************************************************************
  711. *
  712. * UNDI protocol
  713. *
  714. ******************************************************************************
  715. */
  716. /** Union type for command parameter blocks */
  717. typedef union {
  718. PXE_CPB_STATION_ADDRESS station_address;
  719. PXE_CPB_FILL_HEADER fill_header;
  720. PXE_CPB_FILL_HEADER_FRAGMENTED fill_header_fragmented;
  721. PXE_CPB_TRANSMIT transmit;
  722. PXE_CPB_RECEIVE receive;
  723. } PXE_CPB_ANY;
  724. /** Union type for data blocks */
  725. typedef union {
  726. PXE_DB_GET_INIT_INFO get_init_info;
  727. PXE_DB_STATION_ADDRESS station_address;
  728. PXE_DB_GET_STATUS get_status;
  729. PXE_DB_RECEIVE receive;
  730. } PXE_DB_ANY;
  731. /**
  732. * Calculate UNDI byte checksum
  733. *
  734. * @v data Data
  735. * @v len Length of data
  736. * @ret sum Checksum
  737. */
  738. static uint8_t efi_undi_checksum ( void *data, size_t len ) {
  739. uint8_t *bytes = data;
  740. uint8_t sum = 0;
  741. while ( len-- )
  742. sum += *bytes++;
  743. return sum;
  744. }
  745. /**
  746. * Get UNDI SNP device interface number
  747. *
  748. * @v snpdev SNP device
  749. * @ret ifnum UNDI interface number
  750. */
  751. static unsigned int efi_undi_ifnum ( struct efi_snp_device *snpdev ) {
  752. /* iPXE network device indexes are one-based (leaving zero
  753. * meaning "unspecified"). UNDI interface numbers are
  754. * zero-based.
  755. */
  756. return ( snpdev->netdev->index - 1 );
  757. }
  758. /**
  759. * Identify UNDI SNP device
  760. *
  761. * @v ifnum Interface number
  762. * @ret snpdev SNP device, or NULL if not found
  763. */
  764. static struct efi_snp_device * efi_undi_snpdev ( unsigned int ifnum ) {
  765. struct efi_snp_device *snpdev;
  766. list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
  767. if ( efi_undi_ifnum ( snpdev ) == ifnum )
  768. return snpdev;
  769. }
  770. return NULL;
  771. }
  772. /**
  773. * Convert EFI status code to UNDI status code
  774. *
  775. * @v efirc EFI status code
  776. * @ret statcode UNDI status code
  777. */
  778. static PXE_STATCODE efi_undi_statcode ( EFI_STATUS efirc ) {
  779. switch ( efirc ) {
  780. case EFI_INVALID_PARAMETER: return PXE_STATCODE_INVALID_PARAMETER;
  781. case EFI_UNSUPPORTED: return PXE_STATCODE_UNSUPPORTED;
  782. case EFI_OUT_OF_RESOURCES: return PXE_STATCODE_BUFFER_FULL;
  783. case EFI_PROTOCOL_ERROR: return PXE_STATCODE_DEVICE_FAILURE;
  784. case EFI_NOT_READY: return PXE_STATCODE_NO_DATA;
  785. default:
  786. return PXE_STATCODE_INVALID_CDB;
  787. }
  788. }
  789. /**
  790. * Get state
  791. *
  792. * @v snpdev SNP device
  793. * @v cdb Command description block
  794. * @ret efirc EFI status code
  795. */
  796. static EFI_STATUS efi_undi_get_state ( struct efi_snp_device *snpdev,
  797. PXE_CDB *cdb ) {
  798. EFI_SIMPLE_NETWORK_MODE *mode = &snpdev->mode;
  799. DBGC ( snpdev, "UNDI %p GET STATE\n", snpdev );
  800. /* Return current state */
  801. if ( mode->State == EfiSimpleNetworkInitialized ) {
  802. cdb->StatFlags |= PXE_STATFLAGS_GET_STATE_INITIALIZED;
  803. } else if ( mode->State == EfiSimpleNetworkStarted ) {
  804. cdb->StatFlags |= PXE_STATFLAGS_GET_STATE_STARTED;
  805. } else {
  806. cdb->StatFlags |= PXE_STATFLAGS_GET_STATE_STOPPED;
  807. }
  808. return 0;
  809. }
  810. /**
  811. * Start
  812. *
  813. * @v snpdev SNP device
  814. * @ret efirc EFI status code
  815. */
  816. static EFI_STATUS efi_undi_start ( struct efi_snp_device *snpdev ) {
  817. EFI_STATUS efirc;
  818. DBGC ( snpdev, "UNDI %p START\n", snpdev );
  819. /* Start SNP device */
  820. if ( ( efirc = efi_snp_start ( &snpdev->snp ) ) != 0 )
  821. return efirc;
  822. return 0;
  823. }
  824. /**
  825. * Stop
  826. *
  827. * @v snpdev SNP device
  828. * @ret efirc EFI status code
  829. */
  830. static EFI_STATUS efi_undi_stop ( struct efi_snp_device *snpdev ) {
  831. EFI_STATUS efirc;
  832. DBGC ( snpdev, "UNDI %p STOP\n", snpdev );
  833. /* Stop SNP device */
  834. if ( ( efirc = efi_snp_stop ( &snpdev->snp ) ) != 0 )
  835. return efirc;
  836. return 0;
  837. }
  838. /**
  839. * Get initialisation information
  840. *
  841. * @v snpdev SNP device
  842. * @v cdb Command description block
  843. * @v db Data block
  844. * @ret efirc EFI status code
  845. */
  846. static EFI_STATUS efi_undi_get_init_info ( struct efi_snp_device *snpdev,
  847. PXE_CDB *cdb,
  848. PXE_DB_GET_INIT_INFO *db ) {
  849. struct net_device *netdev = snpdev->netdev;
  850. struct ll_protocol *ll_protocol = netdev->ll_protocol;
  851. DBGC ( snpdev, "UNDI %p GET INIT INFO\n", snpdev );
  852. /* Populate structure */
  853. memset ( db, 0, sizeof ( *db ) );
  854. db->FrameDataLen = ( netdev->max_pkt_len - ll_protocol->ll_header_len );
  855. db->MediaHeaderLen = ll_protocol->ll_header_len;
  856. db->HWaddrLen = ll_protocol->ll_addr_len;
  857. db->IFtype = ntohs ( ll_protocol->ll_proto );
  858. cdb->StatFlags |= ( PXE_STATFLAGS_CABLE_DETECT_SUPPORTED |
  859. PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED );
  860. return 0;
  861. }
  862. /**
  863. * Initialise
  864. *
  865. * @v snpdev SNP device
  866. * @v cdb Command description block
  867. * @v efirc EFI status code
  868. */
  869. static EFI_STATUS efi_undi_initialize ( struct efi_snp_device *snpdev,
  870. PXE_CDB *cdb ) {
  871. struct net_device *netdev = snpdev->netdev;
  872. EFI_STATUS efirc;
  873. DBGC ( snpdev, "UNDI %p INITIALIZE\n", snpdev );
  874. /* Reset SNP device */
  875. if ( ( efirc = efi_snp_initialize ( &snpdev->snp, 0, 0 ) ) != 0 )
  876. return efirc;
  877. /* Report link state */
  878. if ( ! netdev_link_ok ( netdev ) )
  879. cdb->StatFlags |= PXE_STATFLAGS_INITIALIZED_NO_MEDIA;
  880. return 0;
  881. }
  882. /**
  883. * Reset
  884. *
  885. * @v snpdev SNP device
  886. * @v efirc EFI status code
  887. */
  888. static EFI_STATUS efi_undi_reset ( struct efi_snp_device *snpdev ) {
  889. EFI_STATUS efirc;
  890. DBGC ( snpdev, "UNDI %p RESET\n", snpdev );
  891. /* Reset SNP device */
  892. if ( ( efirc = efi_snp_reset ( &snpdev->snp, 0 ) ) != 0 )
  893. return efirc;
  894. return 0;
  895. }
  896. /**
  897. * Shutdown
  898. *
  899. * @v snpdev SNP device
  900. * @v efirc EFI status code
  901. */
  902. static EFI_STATUS efi_undi_shutdown ( struct efi_snp_device *snpdev ) {
  903. EFI_STATUS efirc;
  904. DBGC ( snpdev, "UNDI %p SHUTDOWN\n", snpdev );
  905. /* Reset SNP device */
  906. if ( ( efirc = efi_snp_shutdown ( &snpdev->snp ) ) != 0 )
  907. return efirc;
  908. return 0;
  909. }
  910. /**
  911. * Get/set receive filters
  912. *
  913. * @v snpdev SNP device
  914. * @v cdb Command description block
  915. * @v efirc EFI status code
  916. */
  917. static EFI_STATUS efi_undi_receive_filters ( struct efi_snp_device *snpdev,
  918. PXE_CDB *cdb ) {
  919. DBGC ( snpdev, "UNDI %p RECEIVE FILTERS\n", snpdev );
  920. /* Mark everything as supported */
  921. cdb->StatFlags |= ( PXE_STATFLAGS_RECEIVE_FILTER_UNICAST |
  922. PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST |
  923. PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS |
  924. PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST );
  925. return 0;
  926. }
  927. /**
  928. * Get/set station address
  929. *
  930. * @v snpdev SNP device
  931. * @v cdb Command description block
  932. * @v cpb Command parameter block
  933. * @v efirc EFI status code
  934. */
  935. static EFI_STATUS efi_undi_station_address ( struct efi_snp_device *snpdev,
  936. PXE_CDB *cdb,
  937. PXE_CPB_STATION_ADDRESS *cpb,
  938. PXE_DB_STATION_ADDRESS *db ) {
  939. struct net_device *netdev = snpdev->netdev;
  940. struct ll_protocol *ll_protocol = netdev->ll_protocol;
  941. void *mac;
  942. int reset;
  943. EFI_STATUS efirc;
  944. DBGC ( snpdev, "UNDI %p STATION ADDRESS\n", snpdev );
  945. /* Update address if applicable */
  946. reset = ( cdb->OpFlags & PXE_OPFLAGS_STATION_ADDRESS_RESET );
  947. mac = ( cpb ? &cpb->StationAddr : NULL );
  948. if ( ( reset || mac ) &&
  949. ( ( efirc = efi_snp_station_address ( &snpdev->snp, reset,
  950. mac ) ) != 0 ) )
  951. return efirc;
  952. /* Fill in current addresses, if applicable */
  953. if ( db ) {
  954. memset ( db, 0, sizeof ( *db ) );
  955. memcpy ( &db->StationAddr, netdev->ll_addr,
  956. ll_protocol->ll_addr_len );
  957. memcpy ( &db->BroadcastAddr, netdev->ll_broadcast,
  958. ll_protocol->ll_addr_len );
  959. memcpy ( &db->PermanentAddr, netdev->hw_addr,
  960. ll_protocol->hw_addr_len );
  961. }
  962. return 0;
  963. }
  964. /**
  965. * Get interrupt status
  966. *
  967. * @v snpdev SNP device
  968. * @v cdb Command description block
  969. * @v db Data block
  970. * @v efirc EFI status code
  971. */
  972. static EFI_STATUS efi_undi_get_status ( struct efi_snp_device *snpdev,
  973. PXE_CDB *cdb, PXE_DB_GET_STATUS *db ) {
  974. UINT32 interrupts;
  975. VOID *txbuf;
  976. struct io_buffer *rxbuf;
  977. EFI_STATUS efirc;
  978. DBGC2 ( snpdev, "UNDI %p GET STATUS\n", snpdev );
  979. /* Get status */
  980. if ( ( efirc = efi_snp_get_status ( &snpdev->snp, &interrupts,
  981. &txbuf ) ) != 0 )
  982. return efirc;
  983. /* Report status */
  984. memset ( db, 0, sizeof ( *db ) );
  985. if ( interrupts & EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT )
  986. cdb->StatFlags |= PXE_STATFLAGS_GET_STATUS_RECEIVE;
  987. if ( interrupts & EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT )
  988. cdb->StatFlags |= PXE_STATFLAGS_GET_STATUS_TRANSMIT;
  989. if ( txbuf ) {
  990. db->TxBuffer[0] = ( ( intptr_t ) txbuf );
  991. } else {
  992. cdb->StatFlags |= PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN;
  993. /* The specification states clearly that UNDI drivers
  994. * should set TXBUF_QUEUE_EMPTY if all completed
  995. * buffer addresses are written into the returned data
  996. * block. However, SnpDxe chooses to interpret
  997. * TXBUF_QUEUE_EMPTY as a synonym for
  998. * NO_TXBUFS_WRITTEN, thereby rendering it entirely
  999. * pointless. Work around this UEFI stupidity, as per
  1000. * usual.
  1001. */
  1002. if ( snpdev->tx_prod == snpdev->tx_cons )
  1003. cdb->StatFlags |=
  1004. PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY;
  1005. }
  1006. rxbuf = list_first_entry ( &snpdev->rx, struct io_buffer, list );
  1007. if ( rxbuf )
  1008. db->RxFrameLen = iob_len ( rxbuf );
  1009. if ( ! netdev_link_ok ( snpdev->netdev ) )
  1010. cdb->StatFlags |= PXE_STATFLAGS_GET_STATUS_NO_MEDIA;
  1011. return 0;
  1012. }
  1013. /**
  1014. * Fill header
  1015. *
  1016. * @v snpdev SNP device
  1017. * @v cdb Command description block
  1018. * @v cpb Command parameter block
  1019. * @v efirc EFI status code
  1020. */
  1021. static EFI_STATUS efi_undi_fill_header ( struct efi_snp_device *snpdev,
  1022. PXE_CDB *cdb, PXE_CPB_ANY *cpb ) {
  1023. struct net_device *netdev = snpdev->netdev;
  1024. struct ll_protocol *ll_protocol = netdev->ll_protocol;
  1025. PXE_CPB_FILL_HEADER *whole = &cpb->fill_header;
  1026. PXE_CPB_FILL_HEADER_FRAGMENTED *fragged = &cpb->fill_header_fragmented;
  1027. VOID *data;
  1028. void *dest;
  1029. void *src;
  1030. uint16_t proto;
  1031. struct io_buffer iobuf;
  1032. int rc;
  1033. /* SnpDxe will (pointlessly) use PXE_CPB_FILL_HEADER_FRAGMENTED
  1034. * even though we choose to explicitly not claim support for
  1035. * fragments via PXE_ROMID_IMP_FRAG_SUPPORTED.
  1036. */
  1037. if ( cdb->OpFlags & PXE_OPFLAGS_FILL_HEADER_FRAGMENTED ) {
  1038. data = ( ( void * ) ( intptr_t ) fragged->FragDesc[0].FragAddr);
  1039. dest = &fragged->DestAddr;
  1040. src = &fragged->SrcAddr;
  1041. proto = fragged->Protocol;
  1042. } else {
  1043. data = ( ( void * ) ( intptr_t ) whole->MediaHeader );
  1044. dest = &whole->DestAddr;
  1045. src = &whole->SrcAddr;
  1046. proto = whole->Protocol;
  1047. }
  1048. /* Construct link-layer header */
  1049. iob_populate ( &iobuf, data, 0, ll_protocol->ll_header_len );
  1050. iob_reserve ( &iobuf, ll_protocol->ll_header_len );
  1051. if ( ( rc = ll_protocol->push ( netdev, &iobuf, dest, src,
  1052. proto ) ) != 0 )
  1053. return EFIRC ( rc );
  1054. return 0;
  1055. }
  1056. /**
  1057. * Transmit
  1058. *
  1059. * @v snpdev SNP device
  1060. * @v cpb Command parameter block
  1061. * @v efirc EFI status code
  1062. */
  1063. static EFI_STATUS efi_undi_transmit ( struct efi_snp_device *snpdev,
  1064. PXE_CPB_TRANSMIT *cpb ) {
  1065. VOID *data = ( ( void * ) ( intptr_t ) cpb->FrameAddr );
  1066. EFI_STATUS efirc;
  1067. DBGC2 ( snpdev, "UNDI %p TRANSMIT\n", snpdev );
  1068. /* Transmit packet */
  1069. if ( ( efirc = efi_snp_transmit ( &snpdev->snp, 0, cpb->DataLen,
  1070. data, NULL, NULL, NULL ) ) != 0 )
  1071. return efirc;
  1072. return 0;
  1073. }
  1074. /**
  1075. * Receive
  1076. *
  1077. * @v snpdev SNP device
  1078. * @v cpb Command parameter block
  1079. * @v efirc EFI status code
  1080. */
  1081. static EFI_STATUS efi_undi_receive ( struct efi_snp_device *snpdev,
  1082. PXE_CPB_RECEIVE *cpb,
  1083. PXE_DB_RECEIVE *db ) {
  1084. struct net_device *netdev = snpdev->netdev;
  1085. struct ll_protocol *ll_protocol = netdev->ll_protocol;
  1086. VOID *data = ( ( void * ) ( intptr_t ) cpb->BufferAddr );
  1087. UINTN hdr_len;
  1088. UINTN len = cpb->BufferLen;
  1089. EFI_MAC_ADDRESS src;
  1090. EFI_MAC_ADDRESS dest;
  1091. UINT16 proto;
  1092. EFI_STATUS efirc;
  1093. DBGC2 ( snpdev, "UNDI %p RECEIVE\n", snpdev );
  1094. /* Receive packet */
  1095. if ( ( efirc = efi_snp_receive ( &snpdev->snp, &hdr_len, &len, data,
  1096. &src, &dest, &proto ) ) != 0 )
  1097. return efirc;
  1098. /* Describe frame */
  1099. memset ( db, 0, sizeof ( *db ) );
  1100. memcpy ( &db->SrcAddr, &src, ll_protocol->ll_addr_len );
  1101. memcpy ( &db->DestAddr, &dest, ll_protocol->ll_addr_len );
  1102. db->FrameLen = len;
  1103. db->Protocol = proto;
  1104. db->MediaHeaderLen = ll_protocol->ll_header_len;
  1105. db->Type = PXE_FRAME_TYPE_PROMISCUOUS;
  1106. return 0;
  1107. }
  1108. /** UNDI entry point */
  1109. static EFIAPI VOID efi_undi_issue ( UINT64 cdb_phys ) {
  1110. PXE_CDB *cdb = ( ( void * ) ( intptr_t ) cdb_phys );
  1111. PXE_CPB_ANY *cpb = ( ( void * ) ( intptr_t ) cdb->CPBaddr );
  1112. PXE_DB_ANY *db = ( ( void * ) ( intptr_t ) cdb->DBaddr );
  1113. struct efi_snp_device *snpdev;
  1114. EFI_STATUS efirc;
  1115. /* Identify device */
  1116. snpdev = efi_undi_snpdev ( cdb->IFnum );
  1117. if ( ! snpdev ) {
  1118. DBGC ( cdb, "UNDI invalid interface number %d\n", cdb->IFnum );
  1119. cdb->StatCode = PXE_STATCODE_INVALID_CDB;
  1120. cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
  1121. return;
  1122. }
  1123. /* Fail if net device is currently claimed for use by iPXE */
  1124. if ( efi_snp_claimed ) {
  1125. cdb->StatCode = PXE_STATCODE_BUSY;
  1126. cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
  1127. return;
  1128. }
  1129. /* Handle opcode */
  1130. cdb->StatCode = PXE_STATCODE_SUCCESS;
  1131. cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
  1132. switch ( cdb->OpCode ) {
  1133. case PXE_OPCODE_GET_STATE:
  1134. efirc = efi_undi_get_state ( snpdev, cdb );
  1135. break;
  1136. case PXE_OPCODE_START:
  1137. efirc = efi_undi_start ( snpdev );
  1138. break;
  1139. case PXE_OPCODE_STOP:
  1140. efirc = efi_undi_stop ( snpdev );
  1141. break;
  1142. case PXE_OPCODE_GET_INIT_INFO:
  1143. efirc = efi_undi_get_init_info ( snpdev, cdb,
  1144. &db->get_init_info );
  1145. break;
  1146. case PXE_OPCODE_INITIALIZE:
  1147. efirc = efi_undi_initialize ( snpdev, cdb );
  1148. break;
  1149. case PXE_OPCODE_RESET:
  1150. efirc = efi_undi_reset ( snpdev );
  1151. break;
  1152. case PXE_OPCODE_SHUTDOWN:
  1153. efirc = efi_undi_shutdown ( snpdev );
  1154. break;
  1155. case PXE_OPCODE_RECEIVE_FILTERS:
  1156. efirc = efi_undi_receive_filters ( snpdev, cdb );
  1157. break;
  1158. case PXE_OPCODE_STATION_ADDRESS:
  1159. efirc = efi_undi_station_address ( snpdev, cdb,
  1160. &cpb->station_address,
  1161. &db->station_address );
  1162. break;
  1163. case PXE_OPCODE_GET_STATUS:
  1164. efirc = efi_undi_get_status ( snpdev, cdb, &db->get_status );
  1165. break;
  1166. case PXE_OPCODE_FILL_HEADER:
  1167. efirc = efi_undi_fill_header ( snpdev, cdb, cpb );
  1168. break;
  1169. case PXE_OPCODE_TRANSMIT:
  1170. efirc = efi_undi_transmit ( snpdev, &cpb->transmit );
  1171. break;
  1172. case PXE_OPCODE_RECEIVE:
  1173. efirc = efi_undi_receive ( snpdev, &cpb->receive,
  1174. &db->receive );
  1175. break;
  1176. default:
  1177. DBGC ( snpdev, "UNDI %p unsupported opcode %#04x\n",
  1178. snpdev, cdb->OpCode );
  1179. efirc = EFI_UNSUPPORTED;
  1180. break;
  1181. }
  1182. /* Convert EFI status code to UNDI status code */
  1183. if ( efirc != 0 ) {
  1184. cdb->StatFlags &= ~PXE_STATFLAGS_STATUS_MASK;
  1185. cdb->StatFlags |= PXE_STATFLAGS_COMMAND_FAILED;
  1186. cdb->StatCode = efi_undi_statcode ( efirc );
  1187. }
  1188. }
  1189. /** UNDI interface
  1190. *
  1191. * Must be aligned on a 16-byte boundary, for no particularly good
  1192. * reason.
  1193. */
  1194. static PXE_SW_UNDI efi_snp_undi __attribute__ (( aligned ( 16 ) )) = {
  1195. .Signature = PXE_ROMID_SIGNATURE,
  1196. .Len = sizeof ( efi_snp_undi ),
  1197. .Rev = PXE_ROMID_REV,
  1198. .MajorVer = PXE_ROMID_MAJORVER,
  1199. .MinorVer = PXE_ROMID_MINORVER,
  1200. .Implementation = ( PXE_ROMID_IMP_SW_VIRT_ADDR |
  1201. PXE_ROMID_IMP_STATION_ADDR_SETTABLE |
  1202. PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED |
  1203. PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED |
  1204. PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED |
  1205. PXE_ROMID_IMP_TX_COMPLETE_INT_SUPPORTED |
  1206. PXE_ROMID_IMP_PACKET_RX_INT_SUPPORTED ),
  1207. /* SnpDxe checks that BusCnt is non-zero. It makes no further
  1208. * use of BusCnt, and never looks as BusType[]. As with much
  1209. * of the EDK2 code, this check seems to serve no purpose
  1210. * whatsoever but must nonetheless be humoured.
  1211. */
  1212. .BusCnt = 1,
  1213. .BusType[0] = PXE_BUSTYPE ( 'i', 'P', 'X', 'E' ),
  1214. };
  1215. /** Network Identification Interface (NII) */
  1216. static EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL efi_snp_device_nii = {
  1217. .Revision = EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION,
  1218. .StringId = "UNDI",
  1219. .Type = EfiNetworkInterfaceUndi,
  1220. .MajorVer = 3,
  1221. .MinorVer = 1,
  1222. .Ipv6Supported = TRUE, /* This is a raw packet interface, FFS! */
  1223. };
  1224. /******************************************************************************
  1225. *
  1226. * Component name protocol
  1227. *
  1228. ******************************************************************************
  1229. */
  1230. /**
  1231. * Look up driver name
  1232. *
  1233. * @v name2 Component name protocol
  1234. * @v language Language to use
  1235. * @v driver_name Driver name to fill in
  1236. * @ret efirc EFI status code
  1237. */
  1238. static EFI_STATUS EFIAPI
  1239. efi_snp_get_driver_name ( EFI_COMPONENT_NAME2_PROTOCOL *name2,
  1240. CHAR8 *language __unused, CHAR16 **driver_name ) {
  1241. struct efi_snp_device *snpdev =
  1242. container_of ( name2, struct efi_snp_device, name2 );
  1243. *driver_name = snpdev->driver_name;
  1244. return 0;
  1245. }
  1246. /**
  1247. * Look up controller name
  1248. *
  1249. * @v name2 Component name protocol
  1250. * @v device Device
  1251. * @v child Child device, or NULL
  1252. * @v language Language to use
  1253. * @v driver_name Device name to fill in
  1254. * @ret efirc EFI status code
  1255. */
  1256. static EFI_STATUS EFIAPI
  1257. efi_snp_get_controller_name ( EFI_COMPONENT_NAME2_PROTOCOL *name2,
  1258. EFI_HANDLE device __unused,
  1259. EFI_HANDLE child __unused,
  1260. CHAR8 *language __unused,
  1261. CHAR16 **controller_name ) {
  1262. struct efi_snp_device *snpdev =
  1263. container_of ( name2, struct efi_snp_device, name2 );
  1264. *controller_name = snpdev->controller_name;
  1265. return 0;
  1266. }
  1267. /******************************************************************************
  1268. *
  1269. * Load file protocol
  1270. *
  1271. ******************************************************************************
  1272. */
  1273. /**
  1274. * Load file
  1275. *
  1276. * @v loadfile Load file protocol
  1277. * @v path File path
  1278. * @v booting Loading as part of a boot attempt
  1279. * @ret efirc EFI status code
  1280. */
  1281. static EFI_STATUS EFIAPI
  1282. efi_snp_load_file ( EFI_LOAD_FILE_PROTOCOL *load_file,
  1283. EFI_DEVICE_PATH_PROTOCOL *path __unused,
  1284. BOOLEAN booting, UINTN *len __unused,
  1285. VOID *data __unused ) {
  1286. struct efi_snp_device *snpdev =
  1287. container_of ( load_file, struct efi_snp_device, load_file );
  1288. struct net_device *netdev = snpdev->netdev;
  1289. int rc;
  1290. /* Fail unless this is a boot attempt */
  1291. if ( ! booting ) {
  1292. DBGC ( snpdev, "SNPDEV %p cannot load non-boot file\n",
  1293. snpdev );
  1294. return EFI_UNSUPPORTED;
  1295. }
  1296. /* Claim network devices for use by iPXE */
  1297. efi_snp_claim();
  1298. /* Start watchdog holdoff timer */
  1299. efi_watchdog_start();
  1300. /* Boot from network device */
  1301. if ( ( rc = ipxe ( netdev ) ) != 0 )
  1302. goto err_ipxe;
  1303. /* Reset console */
  1304. console_reset();
  1305. err_ipxe:
  1306. efi_watchdog_stop();
  1307. efi_snp_release();
  1308. return EFIRC ( rc );
  1309. }
  1310. /** Load file protocol */
  1311. static EFI_LOAD_FILE_PROTOCOL efi_snp_load_file_protocol = {
  1312. .LoadFile = efi_snp_load_file,
  1313. };
  1314. /******************************************************************************
  1315. *
  1316. * iPXE network driver
  1317. *
  1318. ******************************************************************************
  1319. */
  1320. /**
  1321. * Locate SNP device corresponding to network device
  1322. *
  1323. * @v netdev Network device
  1324. * @ret snp SNP device, or NULL if not found
  1325. */
  1326. static struct efi_snp_device * efi_snp_demux ( struct net_device *netdev ) {
  1327. struct efi_snp_device *snpdev;
  1328. list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
  1329. if ( snpdev->netdev == netdev )
  1330. return snpdev;
  1331. }
  1332. return NULL;
  1333. }
  1334. /**
  1335. * Create SNP device
  1336. *
  1337. * @v netdev Network device
  1338. * @ret rc Return status code
  1339. */
  1340. static int efi_snp_probe ( struct net_device *netdev ) {
  1341. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  1342. struct efi_device *efidev;
  1343. struct efi_snp_device *snpdev;
  1344. EFI_DEVICE_PATH_PROTOCOL *path_end;
  1345. MAC_ADDR_DEVICE_PATH *macpath;
  1346. VLAN_DEVICE_PATH *vlanpath;
  1347. size_t path_prefix_len = 0;
  1348. unsigned int ifcnt;
  1349. unsigned int tag;
  1350. void *interface;
  1351. EFI_STATUS efirc;
  1352. int rc;
  1353. /* Find parent EFI device */
  1354. efidev = efidev_parent ( netdev->dev );
  1355. if ( ! efidev ) {
  1356. DBG ( "SNP skipping non-EFI device %s\n", netdev->name );
  1357. rc = 0;
  1358. goto err_no_efidev;
  1359. }
  1360. /* Allocate the SNP device */
  1361. snpdev = zalloc ( sizeof ( *snpdev ) );
  1362. if ( ! snpdev ) {
  1363. rc = -ENOMEM;
  1364. goto err_alloc_snp;
  1365. }
  1366. snpdev->netdev = netdev_get ( netdev );
  1367. snpdev->efidev = efidev;
  1368. INIT_LIST_HEAD ( &snpdev->rx );
  1369. /* Sanity check */
  1370. if ( netdev->ll_protocol->ll_addr_len > sizeof ( EFI_MAC_ADDRESS ) ) {
  1371. DBGC ( snpdev, "SNPDEV %p cannot support link-layer address "
  1372. "length %d for %s\n", snpdev,
  1373. netdev->ll_protocol->ll_addr_len, netdev->name );
  1374. rc = -ENOTSUP;
  1375. goto err_ll_addr_len;
  1376. }
  1377. /* Populate the SNP structure */
  1378. memcpy ( &snpdev->snp, &efi_snp_device_snp, sizeof ( snpdev->snp ) );
  1379. snpdev->snp.Mode = &snpdev->mode;
  1380. if ( ( efirc = bs->CreateEvent ( EVT_NOTIFY_WAIT, TPL_NOTIFY,
  1381. efi_snp_wait_for_packet, snpdev,
  1382. &snpdev->snp.WaitForPacket ) ) != 0 ){
  1383. rc = -EEFI ( efirc );
  1384. DBGC ( snpdev, "SNPDEV %p could not create event: %s\n",
  1385. snpdev, strerror ( rc ) );
  1386. goto err_create_event;
  1387. }
  1388. /* Populate the SNP mode structure */
  1389. snpdev->mode.State = EfiSimpleNetworkStopped;
  1390. efi_snp_set_mode ( snpdev );
  1391. /* Populate the NII structure */
  1392. memcpy ( &snpdev->nii, &efi_snp_device_nii, sizeof ( snpdev->nii ) );
  1393. snpdev->nii.Id = ( ( intptr_t ) &efi_snp_undi );
  1394. snpdev->nii.IfNum = efi_undi_ifnum ( snpdev );
  1395. efi_snp_undi.EntryPoint = ( ( intptr_t ) efi_undi_issue );
  1396. ifcnt = ( ( efi_snp_undi.IFcntExt << 8 ) | efi_snp_undi.IFcnt );
  1397. if ( ifcnt < snpdev->nii.IfNum )
  1398. ifcnt = snpdev->nii.IfNum;
  1399. efi_snp_undi.IFcnt = ( ifcnt & 0xff );
  1400. efi_snp_undi.IFcntExt = ( ifcnt >> 8 );
  1401. efi_snp_undi.Fudge -= efi_undi_checksum ( &efi_snp_undi,
  1402. sizeof ( efi_snp_undi ) );
  1403. /* Populate the component name structure */
  1404. efi_snprintf ( snpdev->driver_name,
  1405. ( sizeof ( snpdev->driver_name ) /
  1406. sizeof ( snpdev->driver_name[0] ) ),
  1407. "%s %s", product_short_name, netdev->dev->driver_name );
  1408. efi_snprintf ( snpdev->controller_name,
  1409. ( sizeof ( snpdev->controller_name ) /
  1410. sizeof ( snpdev->controller_name[0] ) ),
  1411. "%s %s (%s, %s)", product_short_name,
  1412. netdev->dev->driver_name, netdev->dev->name,
  1413. netdev_addr ( netdev ) );
  1414. snpdev->name2.GetDriverName = efi_snp_get_driver_name;
  1415. snpdev->name2.GetControllerName = efi_snp_get_controller_name;
  1416. snpdev->name2.SupportedLanguages = "en";
  1417. /* Populate the load file protocol structure */
  1418. memcpy ( &snpdev->load_file, &efi_snp_load_file_protocol,
  1419. sizeof ( snpdev->load_file ) );
  1420. /* Populate the device name */
  1421. efi_snprintf ( snpdev->name, ( sizeof ( snpdev->name ) /
  1422. sizeof ( snpdev->name[0] ) ),
  1423. "%s", netdev->name );
  1424. /* Allocate the new device path */
  1425. path_prefix_len = efi_devpath_len ( efidev->path );
  1426. snpdev->path = zalloc ( path_prefix_len + sizeof ( *macpath ) +
  1427. sizeof ( *vlanpath ) + sizeof ( *path_end ) );
  1428. if ( ! snpdev->path ) {
  1429. rc = -ENOMEM;
  1430. goto err_alloc_device_path;
  1431. }
  1432. /* Populate the device path */
  1433. memcpy ( snpdev->path, efidev->path, path_prefix_len );
  1434. macpath = ( ( ( void * ) snpdev->path ) + path_prefix_len );
  1435. memset ( macpath, 0, sizeof ( *macpath ) );
  1436. macpath->Header.Type = MESSAGING_DEVICE_PATH;
  1437. macpath->Header.SubType = MSG_MAC_ADDR_DP;
  1438. macpath->Header.Length[0] = sizeof ( *macpath );
  1439. memcpy ( &macpath->MacAddress, netdev->ll_addr,
  1440. netdev->ll_protocol->ll_addr_len );
  1441. macpath->IfType = ntohs ( netdev->ll_protocol->ll_proto );
  1442. if ( ( tag = vlan_tag ( netdev ) ) ) {
  1443. vlanpath = ( ( ( void * ) macpath ) + sizeof ( *macpath ) );
  1444. memset ( vlanpath, 0, sizeof ( *vlanpath ) );
  1445. vlanpath->Header.Type = MESSAGING_DEVICE_PATH;
  1446. vlanpath->Header.SubType = MSG_VLAN_DP;
  1447. vlanpath->Header.Length[0] = sizeof ( *vlanpath );
  1448. vlanpath->VlanId = tag;
  1449. path_end = ( ( ( void * ) vlanpath ) + sizeof ( *vlanpath ) );
  1450. } else {
  1451. path_end = ( ( ( void * ) macpath ) + sizeof ( *macpath ) );
  1452. }
  1453. memset ( path_end, 0, sizeof ( *path_end ) );
  1454. path_end->Type = END_DEVICE_PATH_TYPE;
  1455. path_end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
  1456. path_end->Length[0] = sizeof ( *path_end );
  1457. /* Install the SNP */
  1458. if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
  1459. &snpdev->handle,
  1460. &efi_simple_network_protocol_guid, &snpdev->snp,
  1461. &efi_device_path_protocol_guid, snpdev->path,
  1462. &efi_nii_protocol_guid, &snpdev->nii,
  1463. &efi_nii31_protocol_guid, &snpdev->nii,
  1464. &efi_component_name2_protocol_guid, &snpdev->name2,
  1465. &efi_load_file_protocol_guid, &snpdev->load_file,
  1466. NULL ) ) != 0 ) {
  1467. rc = -EEFI ( efirc );
  1468. DBGC ( snpdev, "SNPDEV %p could not install protocols: %s\n",
  1469. snpdev, strerror ( rc ) );
  1470. goto err_install_protocol_interface;
  1471. }
  1472. /* SnpDxe will repeatedly start up and shut down our NII/UNDI
  1473. * interface (in order to obtain the MAC address) before
  1474. * discovering that it cannot install another SNP on the same
  1475. * handle. This causes the underlying network device to be
  1476. * unexpectedly closed.
  1477. *
  1478. * Prevent this by opening our own NII (and NII31) protocol
  1479. * instances to prevent SnpDxe from attempting to bind to
  1480. * them.
  1481. */
  1482. if ( ( efirc = bs->OpenProtocol ( snpdev->handle,
  1483. &efi_nii_protocol_guid, &interface,
  1484. efi_image_handle, snpdev->handle,
  1485. ( EFI_OPEN_PROTOCOL_BY_DRIVER |
  1486. EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
  1487. rc = -EEFI ( efirc );
  1488. DBGC ( snpdev, "SNPDEV %p could not open NII protocol: %s\n",
  1489. snpdev, strerror ( rc ) );
  1490. goto err_open_nii;
  1491. }
  1492. if ( ( efirc = bs->OpenProtocol ( snpdev->handle,
  1493. &efi_nii31_protocol_guid, &interface,
  1494. efi_image_handle, snpdev->handle,
  1495. ( EFI_OPEN_PROTOCOL_BY_DRIVER |
  1496. EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
  1497. rc = -EEFI ( efirc );
  1498. DBGC ( snpdev, "SNPDEV %p could not open NII31 protocol: %s\n",
  1499. snpdev, strerror ( rc ) );
  1500. goto err_open_nii31;
  1501. }
  1502. /* Add as child of EFI parent device */
  1503. if ( ( rc = efi_child_add ( efidev->device, snpdev->handle ) ) != 0 ) {
  1504. DBGC ( snpdev, "SNPDEV %p could not become child of %s: %s\n",
  1505. snpdev, efi_handle_name ( efidev->device ),
  1506. strerror ( rc ) );
  1507. goto err_efi_child_add;
  1508. }
  1509. /* Install HII */
  1510. if ( ( rc = efi_snp_hii_install ( snpdev ) ) != 0 ) {
  1511. DBGC ( snpdev, "SNPDEV %p could not install HII: %s\n",
  1512. snpdev, strerror ( rc ) );
  1513. /* HII fails on several platforms. It's
  1514. * non-essential, so treat this as a non-fatal
  1515. * error.
  1516. */
  1517. }
  1518. /* Add to list of SNP devices */
  1519. list_add ( &snpdev->list, &efi_snp_devices );
  1520. /* Close device path */
  1521. bs->CloseProtocol ( efidev->device, &efi_device_path_protocol_guid,
  1522. efi_image_handle, efidev->device );
  1523. DBGC ( snpdev, "SNPDEV %p installed for %s as device %s\n",
  1524. snpdev, netdev->name, efi_handle_name ( snpdev->handle ) );
  1525. return 0;
  1526. list_del ( &snpdev->list );
  1527. if ( snpdev->package_list )
  1528. efi_snp_hii_uninstall ( snpdev );
  1529. efi_child_del ( efidev->device, snpdev->handle );
  1530. err_efi_child_add:
  1531. bs->CloseProtocol ( snpdev->handle, &efi_nii_protocol_guid,
  1532. efi_image_handle, snpdev->handle );
  1533. err_open_nii:
  1534. bs->CloseProtocol ( snpdev->handle, &efi_nii31_protocol_guid,
  1535. efi_image_handle, snpdev->handle );
  1536. err_open_nii31:
  1537. bs->UninstallMultipleProtocolInterfaces (
  1538. snpdev->handle,
  1539. &efi_simple_network_protocol_guid, &snpdev->snp,
  1540. &efi_device_path_protocol_guid, snpdev->path,
  1541. &efi_nii_protocol_guid, &snpdev->nii,
  1542. &efi_nii31_protocol_guid, &snpdev->nii,
  1543. &efi_component_name2_protocol_guid, &snpdev->name2,
  1544. &efi_load_file_protocol_guid, &snpdev->load_file,
  1545. NULL );
  1546. err_install_protocol_interface:
  1547. free ( snpdev->path );
  1548. err_alloc_device_path:
  1549. bs->CloseEvent ( snpdev->snp.WaitForPacket );
  1550. err_create_event:
  1551. err_ll_addr_len:
  1552. netdev_put ( netdev );
  1553. free ( snpdev );
  1554. err_alloc_snp:
  1555. err_no_efidev:
  1556. return rc;
  1557. }
  1558. /**
  1559. * Handle SNP device or link state change
  1560. *
  1561. * @v netdev Network device
  1562. */
  1563. static void efi_snp_notify ( struct net_device *netdev ) {
  1564. struct efi_snp_device *snpdev;
  1565. /* Locate SNP device */
  1566. snpdev = efi_snp_demux ( netdev );
  1567. if ( ! snpdev ) {
  1568. DBG ( "SNP skipping non-SNP device %s\n", netdev->name );
  1569. return;
  1570. }
  1571. /* Update link state */
  1572. snpdev->mode.MediaPresent =
  1573. ( netdev_link_ok ( netdev ) ? TRUE : FALSE );
  1574. DBGC ( snpdev, "SNPDEV %p link is %s\n", snpdev,
  1575. ( snpdev->mode.MediaPresent ? "up" : "down" ) );
  1576. /* Update mode state */
  1577. efi_snp_set_state ( snpdev );
  1578. }
  1579. /**
  1580. * Destroy SNP device
  1581. *
  1582. * @v netdev Network device
  1583. */
  1584. static void efi_snp_remove ( struct net_device *netdev ) {
  1585. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  1586. struct efi_snp_device *snpdev;
  1587. /* Locate SNP device */
  1588. snpdev = efi_snp_demux ( netdev );
  1589. if ( ! snpdev ) {
  1590. DBG ( "SNP skipping non-SNP device %s\n", netdev->name );
  1591. return;
  1592. }
  1593. /* Uninstall the SNP */
  1594. list_del ( &snpdev->list );
  1595. if ( snpdev->package_list )
  1596. efi_snp_hii_uninstall ( snpdev );
  1597. efi_child_del ( snpdev->efidev->device, snpdev->handle );
  1598. bs->CloseProtocol ( snpdev->handle, &efi_nii_protocol_guid,
  1599. efi_image_handle, snpdev->handle );
  1600. bs->CloseProtocol ( snpdev->handle, &efi_nii31_protocol_guid,
  1601. efi_image_handle, snpdev->handle );
  1602. bs->UninstallMultipleProtocolInterfaces (
  1603. snpdev->handle,
  1604. &efi_simple_network_protocol_guid, &snpdev->snp,
  1605. &efi_device_path_protocol_guid, snpdev->path,
  1606. &efi_nii_protocol_guid, &snpdev->nii,
  1607. &efi_nii31_protocol_guid, &snpdev->nii,
  1608. &efi_component_name2_protocol_guid, &snpdev->name2,
  1609. &efi_load_file_protocol_guid, &snpdev->load_file,
  1610. NULL );
  1611. free ( snpdev->path );
  1612. bs->CloseEvent ( snpdev->snp.WaitForPacket );
  1613. netdev_put ( snpdev->netdev );
  1614. free ( snpdev );
  1615. }
  1616. /** SNP driver */
  1617. struct net_driver efi_snp_driver __net_driver = {
  1618. .name = "SNP",
  1619. .probe = efi_snp_probe,
  1620. .notify = efi_snp_notify,
  1621. .remove = efi_snp_remove,
  1622. };
  1623. /**
  1624. * Find SNP device by EFI device handle
  1625. *
  1626. * @v handle EFI device handle
  1627. * @ret snpdev SNP device, or NULL
  1628. */
  1629. struct efi_snp_device * find_snpdev ( EFI_HANDLE handle ) {
  1630. struct efi_snp_device *snpdev;
  1631. list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
  1632. if ( snpdev->handle == handle )
  1633. return snpdev;
  1634. }
  1635. return NULL;
  1636. }
  1637. /**
  1638. * Get most recently opened SNP device
  1639. *
  1640. * @ret snpdev Most recently opened SNP device, or NULL
  1641. */
  1642. struct efi_snp_device * last_opened_snpdev ( void ) {
  1643. struct net_device *netdev;
  1644. netdev = last_opened_netdev();
  1645. if ( ! netdev )
  1646. return NULL;
  1647. return efi_snp_demux ( netdev );
  1648. }
  1649. /**
  1650. * Add to SNP claimed/released count
  1651. *
  1652. * @v delta Claim count change
  1653. */
  1654. void efi_snp_add_claim ( int delta ) {
  1655. struct efi_snp_device *snpdev;
  1656. /* Claim SNP devices */
  1657. efi_snp_claimed += delta;
  1658. assert ( efi_snp_claimed >= 0 );
  1659. /* Update SNP mode state for each interface */
  1660. list_for_each_entry ( snpdev, &efi_snp_devices, list )
  1661. efi_snp_set_state ( snpdev );
  1662. }