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.

nii.c 32KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189
  1. /*
  2. * Copyright (C) 2014 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. * You can also choose to distribute this program under the terms of
  20. * the Unmodified Binary Distribution Licence (as given in the file
  21. * COPYING.UBDL), provided that you have satisfied its requirements.
  22. */
  23. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  24. #include <string.h>
  25. #include <strings.h>
  26. #include <unistd.h>
  27. #include <errno.h>
  28. #include <ipxe/netdevice.h>
  29. #include <ipxe/ethernet.h>
  30. #include <ipxe/umalloc.h>
  31. #include <ipxe/efi/efi.h>
  32. #include <ipxe/efi/efi_driver.h>
  33. #include <ipxe/efi/efi_pci.h>
  34. #include <ipxe/efi/efi_utils.h>
  35. #include <ipxe/efi/Protocol/NetworkInterfaceIdentifier.h>
  36. #include <ipxe/efi/IndustryStandard/Acpi10.h>
  37. #include "nii.h"
  38. /** @file
  39. *
  40. * NII driver
  41. *
  42. */
  43. /* Error numbers generated by NII */
  44. #define EIO_INVALID_CDB __einfo_error ( EINFO_EIO_INVALID_CDB )
  45. #define EINFO_EIO_INVALID_CDB \
  46. __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_INVALID_CDB, \
  47. "Invalid CDB" )
  48. #define EIO_INVALID_CPB __einfo_error ( EINFO_EIO_INVALID_CPB )
  49. #define EINFO_EIO_INVALID_CPB \
  50. __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_INVALID_CPB, \
  51. "Invalid CPB" )
  52. #define EIO_BUSY __einfo_error ( EINFO_EIO_BUSY )
  53. #define EINFO_EIO_BUSY \
  54. __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_BUSY, \
  55. "Busy" )
  56. #define EIO_QUEUE_FULL __einfo_error ( EINFO_EIO_QUEUE_FULL )
  57. #define EINFO_EIO_QUEUE_FULL \
  58. __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_QUEUE_FULL, \
  59. "Queue full" )
  60. #define EIO_ALREADY_STARTED __einfo_error ( EINFO_EIO_ALREADY_STARTED )
  61. #define EINFO_EIO_ALREADY_STARTED \
  62. __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_ALREADY_STARTED, \
  63. "Already started" )
  64. #define EIO_NOT_STARTED __einfo_error ( EINFO_EIO_NOT_STARTED )
  65. #define EINFO_EIO_NOT_STARTED \
  66. __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NOT_STARTED, \
  67. "Not started" )
  68. #define EIO_NOT_SHUTDOWN __einfo_error ( EINFO_EIO_NOT_SHUTDOWN )
  69. #define EINFO_EIO_NOT_SHUTDOWN \
  70. __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NOT_SHUTDOWN, \
  71. "Not shutdown" )
  72. #define EIO_ALREADY_INITIALIZED __einfo_error ( EINFO_EIO_ALREADY_INITIALIZED )
  73. #define EINFO_EIO_ALREADY_INITIALIZED \
  74. __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_ALREADY_INITIALIZED, \
  75. "Already initialized" )
  76. #define EIO_NOT_INITIALIZED __einfo_error ( EINFO_EIO_NOT_INITIALIZED )
  77. #define EINFO_EIO_NOT_INITIALIZED \
  78. __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NOT_INITIALIZED, \
  79. "Not initialized" )
  80. #define EIO_DEVICE_FAILURE __einfo_error ( EINFO_EIO_DEVICE_FAILURE )
  81. #define EINFO_EIO_DEVICE_FAILURE \
  82. __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_DEVICE_FAILURE, \
  83. "Device failure" )
  84. #define EIO_NVDATA_FAILURE __einfo_error ( EINFO_EIO_NVDATA_FAILURE )
  85. #define EINFO_EIO_NVDATA_FAILURE \
  86. __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NVDATA_FAILURE, \
  87. "Non-volatile data failure" )
  88. #define EIO_UNSUPPORTED __einfo_error ( EINFO_EIO_UNSUPPORTED )
  89. #define EINFO_EIO_UNSUPPORTED \
  90. __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_UNSUPPORTED, \
  91. "Unsupported" )
  92. #define EIO_BUFFER_FULL __einfo_error ( EINFO_EIO_BUFFER_FULL )
  93. #define EINFO_EIO_BUFFER_FULL \
  94. __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_BUFFER_FULL, \
  95. "Buffer full" )
  96. #define EIO_INVALID_PARAMETER __einfo_error ( EINFO_EIO_INVALID_PARAMETER )
  97. #define EINFO_EIO_INVALID_PARAMETER \
  98. __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_INVALID_PARAMETER, \
  99. "Invalid parameter" )
  100. #define EIO_INVALID_UNDI __einfo_error ( EINFO_EIO_INVALID_UNDI )
  101. #define EINFO_EIO_INVALID_UNDI \
  102. __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_INVALID_UNDI, \
  103. "Invalid UNDI" )
  104. #define EIO_IPV4_NOT_SUPPORTED __einfo_error ( EINFO_EIO_IPV4_NOT_SUPPORTED )
  105. #define EINFO_EIO_IPV4_NOT_SUPPORTED \
  106. __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_IPV4_NOT_SUPPORTED, \
  107. "IPv4 not supported" )
  108. #define EIO_IPV6_NOT_SUPPORTED __einfo_error ( EINFO_EIO_IPV6_NOT_SUPPORTED )
  109. #define EINFO_EIO_IPV6_NOT_SUPPORTED \
  110. __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_IPV6_NOT_SUPPORTED, \
  111. "IPv6 not supported" )
  112. #define EIO_NOT_ENOUGH_MEMORY __einfo_error ( EINFO_EIO_NOT_ENOUGH_MEMORY )
  113. #define EINFO_EIO_NOT_ENOUGH_MEMORY \
  114. __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NOT_ENOUGH_MEMORY, \
  115. "Not enough memory" )
  116. #define EIO_NO_DATA __einfo_error ( EINFO_EIO_NO_DATA )
  117. #define EINFO_EIO_NO_DATA \
  118. __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NO_DATA, \
  119. "No data" )
  120. #define EIO_STAT( stat ) \
  121. EUNIQ ( EINFO_EIO, -(stat), EIO_INVALID_CDB, EIO_INVALID_CPB, \
  122. EIO_BUSY, EIO_QUEUE_FULL, EIO_ALREADY_STARTED, \
  123. EIO_NOT_STARTED, EIO_NOT_SHUTDOWN, EIO_ALREADY_INITIALIZED, \
  124. EIO_NOT_INITIALIZED, EIO_DEVICE_FAILURE, EIO_NVDATA_FAILURE, \
  125. EIO_UNSUPPORTED, EIO_BUFFER_FULL, EIO_INVALID_PARAMETER, \
  126. EIO_INVALID_UNDI, EIO_IPV4_NOT_SUPPORTED, \
  127. EIO_IPV6_NOT_SUPPORTED, EIO_NOT_ENOUGH_MEMORY, EIO_NO_DATA )
  128. /** Maximum PCI BAR
  129. *
  130. * This is defined in <ipxe/efi/IndustryStandard/Pci22.h>, but we
  131. * can't #include that since it collides with <ipxe/pci.h>.
  132. */
  133. #define PCI_MAX_BAR 6
  134. /** An NII NIC */
  135. struct nii_nic {
  136. /** EFI device */
  137. struct efi_device *efidev;
  138. /** Network interface identifier protocol */
  139. EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *nii;
  140. /** !PXE structure */
  141. PXE_SW_UNDI *undi;
  142. /** Entry point */
  143. EFIAPI VOID ( * issue ) ( UINT64 cdb );
  144. /** Generic device */
  145. struct device dev;
  146. /** PCI device */
  147. EFI_HANDLE pci_device;
  148. /** PCI I/O protocol */
  149. EFI_PCI_IO_PROTOCOL *pci_io;
  150. /** Memory BAR */
  151. unsigned int mem_bar;
  152. /** I/O BAR */
  153. unsigned int io_bar;
  154. /** Broadcast address */
  155. PXE_MAC_ADDR broadcast;
  156. /** Maximum packet length */
  157. size_t mtu;
  158. /** Hardware transmit/receive buffer */
  159. userptr_t buffer;
  160. /** Hardware transmit/receive buffer length */
  161. size_t buffer_len;
  162. /** Saved task priority level */
  163. EFI_TPL saved_tpl;
  164. /** Media status is supported */
  165. int media;
  166. /** Current transmit buffer */
  167. struct io_buffer *txbuf;
  168. /** Current receive buffer */
  169. struct io_buffer *rxbuf;
  170. };
  171. /** Maximum number of received packets per poll */
  172. #define NII_RX_QUOTA 4
  173. /**
  174. * Open PCI I/O protocol and identify BARs
  175. *
  176. * @v nii NII NIC
  177. * @ret rc Return status code
  178. */
  179. static int nii_pci_open ( struct nii_nic *nii ) {
  180. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  181. EFI_HANDLE device = nii->efidev->device;
  182. EFI_HANDLE pci_device;
  183. union {
  184. EFI_PCI_IO_PROTOCOL *pci_io;
  185. void *interface;
  186. } pci_io;
  187. union {
  188. EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *acpi;
  189. void *resource;
  190. } desc;
  191. int bar;
  192. EFI_STATUS efirc;
  193. int rc;
  194. /* Locate PCI I/O protocol */
  195. if ( ( rc = efi_locate_device ( device, &efi_pci_io_protocol_guid,
  196. &pci_device ) ) != 0 ) {
  197. DBGC ( nii, "NII %s could not locate PCI I/O protocol: %s\n",
  198. nii->dev.name, strerror ( rc ) );
  199. goto err_locate;
  200. }
  201. nii->pci_device = pci_device;
  202. /* Open PCI I/O protocol */
  203. if ( ( efirc = bs->OpenProtocol ( pci_device, &efi_pci_io_protocol_guid,
  204. &pci_io.interface, efi_image_handle,
  205. device,
  206. EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
  207. rc = -EEFI ( efirc );
  208. DBGC ( nii, "NII %s could not open PCI I/O protocol: %s\n",
  209. nii->dev.name, strerror ( rc ) );
  210. goto err_open;
  211. }
  212. nii->pci_io = pci_io.pci_io;
  213. /* Identify memory and I/O BARs */
  214. nii->mem_bar = PCI_MAX_BAR;
  215. nii->io_bar = PCI_MAX_BAR;
  216. for ( bar = ( PCI_MAX_BAR - 1 ) ; bar >= 0 ; bar-- ) {
  217. efirc = nii->pci_io->GetBarAttributes ( nii->pci_io, bar, NULL,
  218. &desc.resource );
  219. if ( efirc == EFI_UNSUPPORTED ) {
  220. /* BAR not present; ignore */
  221. continue;
  222. }
  223. if ( efirc != 0 ) {
  224. rc = -EEFI ( efirc );
  225. DBGC ( nii, "NII %s could not get BAR %d attributes: "
  226. "%s\n", nii->dev.name, bar, strerror ( rc ) );
  227. goto err_get_bar_attributes;
  228. }
  229. if ( desc.acpi->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM ) {
  230. nii->mem_bar = bar;
  231. } else if ( desc.acpi->ResType == ACPI_ADDRESS_SPACE_TYPE_IO ) {
  232. nii->io_bar = bar;
  233. }
  234. bs->FreePool ( desc.resource );
  235. }
  236. DBGC ( nii, "NII %s has ", nii->dev.name );
  237. if ( nii->mem_bar < PCI_MAX_BAR ) {
  238. DBGC ( nii, "memory BAR %d and ", nii->mem_bar );
  239. } else {
  240. DBGC ( nii, "no memory BAR and " );
  241. }
  242. if ( nii->io_bar < PCI_MAX_BAR ) {
  243. DBGC ( nii, "I/O BAR %d\n", nii->io_bar );
  244. } else {
  245. DBGC ( nii, "no I/O BAR\n" );
  246. }
  247. return 0;
  248. err_get_bar_attributes:
  249. bs->CloseProtocol ( pci_device, &efi_pci_io_protocol_guid,
  250. efi_image_handle, device );
  251. err_open:
  252. err_locate:
  253. return rc;
  254. }
  255. /**
  256. * Close PCI I/O protocol
  257. *
  258. * @v nii NII NIC
  259. * @ret rc Return status code
  260. */
  261. static void nii_pci_close ( struct nii_nic *nii ) {
  262. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  263. bs->CloseProtocol ( nii->pci_device, &efi_pci_io_protocol_guid,
  264. efi_image_handle, nii->efidev->device );
  265. }
  266. /**
  267. * I/O callback
  268. *
  269. * @v unique_id NII NIC
  270. * @v op Operations
  271. * @v len Length of data
  272. * @v addr Address
  273. * @v data Data buffer
  274. */
  275. static EFIAPI VOID nii_io ( UINT64 unique_id, UINT8 op, UINT8 len, UINT64 addr,
  276. UINT64 data ) {
  277. struct nii_nic *nii = ( ( void * ) ( intptr_t ) unique_id );
  278. EFI_PCI_IO_PROTOCOL_ACCESS *access;
  279. EFI_PCI_IO_PROTOCOL_IO_MEM io;
  280. EFI_PCI_IO_PROTOCOL_WIDTH width;
  281. unsigned int bar;
  282. EFI_STATUS efirc;
  283. int rc;
  284. /* Determine accessor and BAR */
  285. if ( op & ( PXE_MEM_READ | PXE_MEM_WRITE ) ) {
  286. access = &nii->pci_io->Mem;
  287. bar = nii->mem_bar;
  288. } else {
  289. access = &nii->pci_io->Io;
  290. bar = nii->io_bar;
  291. }
  292. /* Determine operaton */
  293. io = ( ( op & ( PXE_IO_WRITE | PXE_MEM_WRITE ) ) ?
  294. access->Write : access->Read );
  295. /* Determine width */
  296. width = ( fls ( len ) - 1 );
  297. /* Issue operation */
  298. if ( ( efirc = io ( nii->pci_io, width, bar, addr, 1,
  299. ( ( void * ) ( intptr_t ) data ) ) ) != 0 ) {
  300. rc = -EEFI ( efirc );
  301. DBGC ( nii, "NII %s I/O operation %#x failed: %s\n",
  302. nii->dev.name, op, strerror ( rc ) );
  303. /* No way to report failure */
  304. return;
  305. }
  306. }
  307. /**
  308. * Delay callback
  309. *
  310. * @v unique_id NII NIC
  311. * @v microseconds Delay in microseconds
  312. */
  313. static EFIAPI VOID nii_delay ( UINT64 unique_id __unused, UINTN microseconds ) {
  314. udelay ( microseconds );
  315. }
  316. /**
  317. * Block callback
  318. *
  319. * @v unique_id NII NIC
  320. * @v acquire Acquire lock
  321. */
  322. static EFIAPI VOID nii_block ( UINT64 unique_id, UINT32 acquire ) {
  323. struct nii_nic *nii = ( ( void * ) ( intptr_t ) unique_id );
  324. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  325. /* This functionality (which is copied verbatim from the
  326. * SnpDxe implementation of this function) appears to be
  327. * totally brain-dead, since it produces no actual blocking
  328. * behaviour.
  329. */
  330. if ( acquire ) {
  331. nii->saved_tpl = bs->RaiseTPL ( TPL_NOTIFY );
  332. } else {
  333. bs->RestoreTPL ( nii->saved_tpl );
  334. }
  335. }
  336. /**
  337. * Construct operation from opcode and flags
  338. *
  339. * @v opcode Opcode
  340. * @v opflags Flags
  341. * @ret op Operation
  342. */
  343. #define NII_OP( opcode, opflags ) ( (opcode) | ( (opflags) << 16 ) )
  344. /**
  345. * Extract opcode from operation
  346. *
  347. * @v op Operation
  348. * @ret opcode Opcode
  349. */
  350. #define NII_OPCODE( op ) ( (op) & 0xffff )
  351. /**
  352. * Extract flags from operation
  353. *
  354. * @v op Operation
  355. * @ret opflags Flags
  356. */
  357. #define NII_OPFLAGS( op ) ( (op) >> 16 )
  358. /**
  359. * Issue command with parameter block and data block
  360. *
  361. * @v nii NII NIC
  362. * @v op Operation
  363. * @v cpb Command parameter block, or NULL
  364. * @v cpb_len Command parameter block length
  365. * @v db Data block, or NULL
  366. * @v db_len Data block length
  367. * @ret stat Status flags, or negative status code
  368. */
  369. static int nii_issue_cpb_db ( struct nii_nic *nii, unsigned int op, void *cpb,
  370. size_t cpb_len, void *db, size_t db_len ) {
  371. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  372. PXE_CDB cdb;
  373. UINTN tpl;
  374. /* Prepare command descriptor block */
  375. memset ( &cdb, 0, sizeof ( cdb ) );
  376. cdb.OpCode = NII_OPCODE ( op );
  377. cdb.OpFlags = NII_OPFLAGS ( op );
  378. cdb.CPBaddr = ( ( intptr_t ) cpb );
  379. cdb.CPBsize = cpb_len;
  380. cdb.DBaddr = ( ( intptr_t ) db );
  381. cdb.DBsize = db_len;
  382. cdb.IFnum = nii->nii->IfNum;
  383. /* Raise task priority level */
  384. tpl = bs->RaiseTPL ( TPL_CALLBACK );
  385. /* Issue command */
  386. DBGC2 ( nii, "NII %s issuing %02x:%04x ifnum %d%s%s\n",
  387. nii->dev.name, cdb.OpCode, cdb.OpFlags, cdb.IFnum,
  388. ( cpb ? " cpb" : "" ), ( db ? " db" : "" ) );
  389. if ( cpb )
  390. DBGC2_HD ( nii, cpb, cpb_len );
  391. if ( db )
  392. DBGC2_HD ( nii, db, db_len );
  393. nii->issue ( ( intptr_t ) &cdb );
  394. /* Restore task priority level */
  395. bs->RestoreTPL ( tpl );
  396. /* Check completion status */
  397. if ( cdb.StatCode != PXE_STATCODE_SUCCESS )
  398. return -cdb.StatCode;
  399. /* Return command-specific status flags */
  400. return ( cdb.StatFlags & ~PXE_STATFLAGS_STATUS_MASK );
  401. }
  402. /**
  403. * Issue command with parameter block
  404. *
  405. * @v nii NII NIC
  406. * @v op Operation
  407. * @v cpb Command parameter block, or NULL
  408. * @v cpb_len Command parameter block length
  409. * @ret stat Status flags, or negative status code
  410. */
  411. static int nii_issue_cpb ( struct nii_nic *nii, unsigned int op, void *cpb,
  412. size_t cpb_len ) {
  413. return nii_issue_cpb_db ( nii, op, cpb, cpb_len, NULL, 0 );
  414. }
  415. /**
  416. * Issue command with data block
  417. *
  418. * @v nii NII NIC
  419. * @v op Operation
  420. * @v db Data block, or NULL
  421. * @v db_len Data block length
  422. * @ret stat Status flags, or negative status code
  423. */
  424. static int nii_issue_db ( struct nii_nic *nii, unsigned int op, void *db,
  425. size_t db_len ) {
  426. return nii_issue_cpb_db ( nii, op, NULL, 0, db, db_len );
  427. }
  428. /**
  429. * Issue command
  430. *
  431. *
  432. * @v nii NII NIC
  433. * @v op Operation
  434. * @ret stat Status flags, or negative status code
  435. */
  436. static int nii_issue ( struct nii_nic *nii, unsigned int op ) {
  437. return nii_issue_cpb_db ( nii, op, NULL, 0, NULL, 0 );
  438. }
  439. /**
  440. * Start UNDI
  441. *
  442. * @v nii NII NIC
  443. * @ret rc Return status code
  444. */
  445. static int nii_start_undi ( struct nii_nic *nii ) {
  446. PXE_CPB_START_31 cpb;
  447. int stat;
  448. int rc;
  449. /* Construct parameter block */
  450. memset ( &cpb, 0, sizeof ( cpb ) );
  451. cpb.Delay = ( ( intptr_t ) nii_delay );
  452. cpb.Block = ( ( intptr_t ) nii_block );
  453. cpb.Mem_IO = ( ( intptr_t ) nii_io );
  454. cpb.Unique_ID = ( ( intptr_t ) nii );
  455. /* Issue command */
  456. if ( ( stat = nii_issue_cpb ( nii, PXE_OPCODE_START, &cpb,
  457. sizeof ( cpb ) ) ) < 0 ) {
  458. rc = -EIO_STAT ( stat );
  459. DBGC ( nii, "NII %s could not start: %s\n",
  460. nii->dev.name, strerror ( rc ) );
  461. return rc;
  462. }
  463. return 0;
  464. }
  465. /**
  466. * Stop UNDI
  467. *
  468. * @v nii NII NIC
  469. */
  470. static void nii_stop_undi ( struct nii_nic *nii ) {
  471. int stat;
  472. int rc;
  473. /* Issue command */
  474. if ( ( stat = nii_issue ( nii, PXE_OPCODE_STOP ) ) < 0 ) {
  475. rc = -EIO_STAT ( stat );
  476. DBGC ( nii, "NII %s could not stop: %s\n",
  477. nii->dev.name, strerror ( rc ) );
  478. /* Nothing we can do about it */
  479. return;
  480. }
  481. }
  482. /**
  483. * Get initialisation information
  484. *
  485. * @v nii NII NIC
  486. * @v netdev Network device to fill in
  487. * @ret rc Return status code
  488. */
  489. static int nii_get_init_info ( struct nii_nic *nii,
  490. struct net_device *netdev ) {
  491. PXE_DB_GET_INIT_INFO db;
  492. int stat;
  493. int rc;
  494. /* Issue command */
  495. if ( ( stat = nii_issue_db ( nii, PXE_OPCODE_GET_INIT_INFO, &db,
  496. sizeof ( db ) ) ) < 0 ) {
  497. rc = -EIO_STAT ( stat );
  498. DBGC ( nii, "NII %s could not get initialisation info: %s\n",
  499. nii->dev.name, strerror ( rc ) );
  500. return rc;
  501. }
  502. /* Determine link layer protocol */
  503. switch ( db.IFtype ) {
  504. case PXE_IFTYPE_ETHERNET :
  505. netdev->ll_protocol = &ethernet_protocol;
  506. break;
  507. default:
  508. DBGC ( nii, "NII %s unknown interface type %#02x\n",
  509. nii->dev.name, db.IFtype );
  510. return -ENOTSUP;
  511. }
  512. /* Sanity checks */
  513. assert ( db.MediaHeaderLen == netdev->ll_protocol->ll_header_len );
  514. assert ( db.HWaddrLen == netdev->ll_protocol->hw_addr_len );
  515. assert ( db.HWaddrLen == netdev->ll_protocol->ll_addr_len );
  516. /* Extract parameters */
  517. nii->buffer_len = db.MemoryRequired;
  518. nii->mtu = ( db.FrameDataLen + db.MediaHeaderLen );
  519. netdev->max_pkt_len = nii->mtu;
  520. nii->media = ( stat & PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED );
  521. return 0;
  522. }
  523. /**
  524. * Initialise UNDI
  525. *
  526. * @v nii NII NIC
  527. * @v flags Flags
  528. * @ret rc Return status code
  529. */
  530. static int nii_initialise_flags ( struct nii_nic *nii, unsigned int flags ) {
  531. PXE_CPB_INITIALIZE cpb;
  532. PXE_DB_INITIALIZE db;
  533. unsigned int op;
  534. int stat;
  535. int rc;
  536. /* Allocate memory buffer */
  537. nii->buffer = umalloc ( nii->buffer_len );
  538. if ( ! nii->buffer ) {
  539. rc = -ENOMEM;
  540. goto err_alloc;
  541. }
  542. /* Construct parameter block */
  543. memset ( &cpb, 0, sizeof ( cpb ) );
  544. cpb.MemoryAddr = ( ( intptr_t ) nii->buffer );
  545. cpb.MemoryLength = nii->buffer_len;
  546. /* Construct data block */
  547. memset ( &db, 0, sizeof ( db ) );
  548. /* Issue command */
  549. op = NII_OP ( PXE_OPCODE_INITIALIZE, flags );
  550. if ( ( stat = nii_issue_cpb_db ( nii, op, &cpb, sizeof ( cpb ),
  551. &db, sizeof ( db ) ) ) < 0 ) {
  552. rc = -EIO_STAT ( stat );
  553. DBGC ( nii, "NII %s could not initialise: %s\n",
  554. nii->dev.name, strerror ( rc ) );
  555. goto err_initialize;
  556. }
  557. return 0;
  558. err_initialize:
  559. ufree ( nii->buffer );
  560. err_alloc:
  561. return rc;
  562. }
  563. /**
  564. * Initialise UNDI
  565. *
  566. * @v nii NII NIC
  567. * @ret rc Return status code
  568. */
  569. static int nii_initialise ( struct nii_nic *nii ) {
  570. unsigned int flags;
  571. /* Initialise UNDI */
  572. flags = PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE;
  573. return nii_initialise_flags ( nii, flags );
  574. }
  575. /**
  576. * Shut down UNDI
  577. *
  578. * @v nii NII NIC
  579. */
  580. static void nii_shutdown ( struct nii_nic *nii ) {
  581. int stat;
  582. int rc;
  583. /* Issue command */
  584. if ( ( stat = nii_issue ( nii, PXE_OPCODE_SHUTDOWN ) ) < 0 ) {
  585. rc = -EIO_STAT ( stat );
  586. DBGC ( nii, "NII %s could not shut down: %s\n",
  587. nii->dev.name, strerror ( rc ) );
  588. /* Leak memory to avoid corruption */
  589. return;
  590. }
  591. /* Free buffer */
  592. ufree ( nii->buffer );
  593. }
  594. /**
  595. * Get station addresses
  596. *
  597. * @v nii NII NIC
  598. * @v netdev Network device to fill in
  599. * @ret rc Return status code
  600. */
  601. static int nii_get_station_address ( struct nii_nic *nii,
  602. struct net_device *netdev ) {
  603. PXE_DB_STATION_ADDRESS db;
  604. unsigned int op;
  605. int stat;
  606. int rc;
  607. /* Initialise UNDI */
  608. if ( ( rc = nii_initialise ( nii ) ) != 0 )
  609. goto err_initialise;
  610. /* Issue command */
  611. op = NII_OP ( PXE_OPCODE_STATION_ADDRESS,
  612. PXE_OPFLAGS_STATION_ADDRESS_READ );
  613. if ( ( stat = nii_issue_db ( nii, op, &db, sizeof ( db ) ) ) < 0 ) {
  614. rc = -EIO_STAT ( stat );
  615. DBGC ( nii, "NII %s could not get station address: %s\n",
  616. nii->dev.name, strerror ( rc ) );
  617. goto err_station_address;
  618. }
  619. /* Copy MAC addresses */
  620. memcpy ( netdev->ll_addr, db.StationAddr,
  621. netdev->ll_protocol->ll_addr_len );
  622. memcpy ( netdev->hw_addr, db.PermanentAddr,
  623. netdev->ll_protocol->hw_addr_len );
  624. memcpy ( nii->broadcast, db.BroadcastAddr,
  625. sizeof ( nii->broadcast ) );
  626. err_station_address:
  627. nii_shutdown ( nii );
  628. err_initialise:
  629. return rc;
  630. }
  631. /**
  632. * Set station address
  633. *
  634. * @v nii NII NIC
  635. * @v netdev Network device
  636. * @ret rc Return status code
  637. */
  638. static int nii_set_station_address ( struct nii_nic *nii,
  639. struct net_device *netdev ) {
  640. uint32_t implementation = nii->undi->Implementation;
  641. PXE_CPB_STATION_ADDRESS cpb;
  642. unsigned int op;
  643. int stat;
  644. int rc;
  645. /* Fail if setting station address is unsupported */
  646. if ( ! ( implementation & PXE_ROMID_IMP_STATION_ADDR_SETTABLE ) )
  647. return -ENOTSUP;
  648. /* Construct parameter block */
  649. memset ( &cpb, 0, sizeof ( cpb ) );
  650. memcpy ( cpb.StationAddr, netdev->ll_addr,
  651. netdev->ll_protocol->ll_addr_len );
  652. /* Issue command */
  653. op = NII_OP ( PXE_OPCODE_STATION_ADDRESS,
  654. PXE_OPFLAGS_STATION_ADDRESS_WRITE );
  655. if ( ( stat = nii_issue_cpb ( nii, op, &cpb, sizeof ( cpb ) ) ) < 0 ) {
  656. rc = -EIO_STAT ( stat );
  657. DBGC ( nii, "NII %s could not set station address: %s\n",
  658. nii->dev.name, strerror ( rc ) );
  659. return rc;
  660. }
  661. return 0;
  662. }
  663. /**
  664. * Set receive filters
  665. *
  666. * @v nii NII NIC
  667. * @ret rc Return status code
  668. */
  669. static int nii_set_rx_filters ( struct nii_nic *nii ) {
  670. uint32_t implementation = nii->undi->Implementation;
  671. unsigned int flags;
  672. unsigned int op;
  673. int stat;
  674. int rc;
  675. /* Construct receive filter set */
  676. flags = ( PXE_OPFLAGS_RECEIVE_FILTER_ENABLE |
  677. PXE_OPFLAGS_RECEIVE_FILTER_UNICAST );
  678. if ( implementation & PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED )
  679. flags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
  680. if ( implementation & PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED )
  681. flags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;
  682. if ( implementation & PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED )
  683. flags |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;
  684. /* Issue command */
  685. op = NII_OP ( PXE_OPCODE_RECEIVE_FILTERS, flags );
  686. if ( ( stat = nii_issue ( nii, op ) ) < 0 ) {
  687. rc = -EIO_STAT ( stat );
  688. DBGC ( nii, "NII %s could not set receive filters %#04x: %s\n",
  689. nii->dev.name, flags, strerror ( rc ) );
  690. return rc;
  691. }
  692. return 0;
  693. }
  694. /**
  695. * Transmit packet
  696. *
  697. * @v netdev Network device
  698. * @v iobuf I/O buffer
  699. * @ret rc Return status code
  700. */
  701. static int nii_transmit ( struct net_device *netdev,
  702. struct io_buffer *iobuf ) {
  703. struct nii_nic *nii = netdev->priv;
  704. PXE_CPB_TRANSMIT cpb;
  705. unsigned int op;
  706. int stat;
  707. int rc;
  708. /* Defer the packet if there is already a transmission in progress */
  709. if ( nii->txbuf ) {
  710. netdev_tx_defer ( netdev, iobuf );
  711. return 0;
  712. }
  713. /* Construct parameter block */
  714. memset ( &cpb, 0, sizeof ( cpb ) );
  715. cpb.FrameAddr = virt_to_bus ( iobuf->data );
  716. cpb.DataLen = iob_len ( iobuf );
  717. cpb.MediaheaderLen = netdev->ll_protocol->ll_header_len;
  718. /* Transmit packet */
  719. op = NII_OP ( PXE_OPCODE_TRANSMIT,
  720. ( PXE_OPFLAGS_TRANSMIT_WHOLE |
  721. PXE_OPFLAGS_TRANSMIT_DONT_BLOCK ) );
  722. if ( ( stat = nii_issue_cpb ( nii, op, &cpb, sizeof ( cpb ) ) ) < 0 ) {
  723. rc = -EIO_STAT ( stat );
  724. DBGC ( nii, "NII %s could not transmit: %s\n",
  725. nii->dev.name, strerror ( rc ) );
  726. return rc;
  727. }
  728. nii->txbuf = iobuf;
  729. return 0;
  730. }
  731. /**
  732. * Poll for completed packets
  733. *
  734. * @v netdev Network device
  735. * @v stat Status flags
  736. */
  737. static void nii_poll_tx ( struct net_device *netdev, unsigned int stat ) {
  738. struct nii_nic *nii = netdev->priv;
  739. struct io_buffer *iobuf;
  740. /* Do nothing unless we have a completion */
  741. if ( stat & PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN )
  742. return;
  743. /* Sanity check */
  744. assert ( nii->txbuf != NULL );
  745. /* Complete transmission */
  746. iobuf = nii->txbuf;
  747. nii->txbuf = NULL;
  748. netdev_tx_complete ( netdev, iobuf );
  749. }
  750. /**
  751. * Poll for received packets
  752. *
  753. * @v netdev Network device
  754. */
  755. static void nii_poll_rx ( struct net_device *netdev ) {
  756. struct nii_nic *nii = netdev->priv;
  757. PXE_CPB_RECEIVE cpb;
  758. PXE_DB_RECEIVE db;
  759. unsigned int quota;
  760. int stat;
  761. int rc;
  762. /* Retrieve up to NII_RX_QUOTA packets */
  763. for ( quota = NII_RX_QUOTA ; quota ; quota-- ) {
  764. /* Allocate buffer, if required */
  765. if ( ! nii->rxbuf ) {
  766. nii->rxbuf = alloc_iob ( nii->mtu );
  767. if ( ! nii->rxbuf ) {
  768. /* Leave for next poll */
  769. break;
  770. }
  771. }
  772. /* Construct parameter block */
  773. memset ( &cpb, 0, sizeof ( cpb ) );
  774. cpb.BufferAddr = virt_to_bus ( nii->rxbuf->data );
  775. cpb.BufferLen = iob_tailroom ( nii->rxbuf );
  776. /* Issue command */
  777. if ( ( stat = nii_issue_cpb_db ( nii, PXE_OPCODE_RECEIVE,
  778. &cpb, sizeof ( cpb ),
  779. &db, sizeof ( db ) ) ) < 0 ) {
  780. /* PXE_STATCODE_NO_DATA is just the usual "no packet"
  781. * status indicator; ignore it.
  782. */
  783. if ( stat == -PXE_STATCODE_NO_DATA )
  784. break;
  785. /* Anything else is an error */
  786. rc = -EIO_STAT ( stat );
  787. DBGC ( nii, "NII %s could not receive: %s\n",
  788. nii->dev.name, strerror ( rc ) );
  789. netdev_rx_err ( netdev, NULL, rc );
  790. break;
  791. }
  792. /* Hand off to network stack */
  793. iob_put ( nii->rxbuf, db.FrameLen );
  794. netdev_rx ( netdev, nii->rxbuf );
  795. nii->rxbuf = NULL;
  796. }
  797. }
  798. /**
  799. * Check for link state changes
  800. *
  801. * @v netdev Network device
  802. * @v stat Status flags
  803. */
  804. static void nii_poll_link ( struct net_device *netdev, unsigned int stat ) {
  805. int no_media = ( stat & PXE_STATFLAGS_GET_STATUS_NO_MEDIA );
  806. if ( no_media && netdev_link_ok ( netdev ) ) {
  807. netdev_link_down ( netdev );
  808. } else if ( ( ! no_media ) && ( ! netdev_link_ok ( netdev ) ) ) {
  809. netdev_link_up ( netdev );
  810. }
  811. }
  812. /**
  813. * Poll for completed packets
  814. *
  815. * @v netdev Network device
  816. */
  817. static void nii_poll ( struct net_device *netdev ) {
  818. struct nii_nic *nii = netdev->priv;
  819. PXE_DB_GET_STATUS db;
  820. unsigned int op;
  821. int stat;
  822. int rc;
  823. /* Construct data block */
  824. memset ( &db, 0, sizeof ( db ) );
  825. /* Get status */
  826. op = NII_OP ( PXE_OPCODE_GET_STATUS,
  827. ( PXE_OPFLAGS_GET_INTERRUPT_STATUS |
  828. ( nii->txbuf ? PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS : 0)|
  829. ( nii->media ? PXE_OPFLAGS_GET_MEDIA_STATUS : 0 ) ) );
  830. if ( ( stat = nii_issue_db ( nii, op, &db, sizeof ( db ) ) ) < 0 ) {
  831. rc = -EIO_STAT ( stat );
  832. DBGC ( nii, "NII %s could not get status: %s\n",
  833. nii->dev.name, strerror ( rc ) );
  834. return;
  835. }
  836. /* Process any TX completions */
  837. if ( nii->txbuf )
  838. nii_poll_tx ( netdev, stat );
  839. /* Process any RX completions */
  840. nii_poll_rx ( netdev );
  841. /* Check for link state changes */
  842. if ( nii->media )
  843. nii_poll_link ( netdev, stat );
  844. }
  845. /**
  846. * Open network device
  847. *
  848. * @v netdev Network device
  849. * @ret rc Return status code
  850. */
  851. static int nii_open ( struct net_device *netdev ) {
  852. struct nii_nic *nii = netdev->priv;
  853. unsigned int flags;
  854. int rc;
  855. /* Initialise NIC
  856. *
  857. * We don't care about link state here, and would prefer to
  858. * have the NIC initialise even if no cable is present, to
  859. * match the behaviour of all other iPXE drivers.
  860. *
  861. * Some Emulex NII drivers have a bug which prevents packets
  862. * from being sent or received unless we specifically ask it
  863. * to detect cable presence during initialisation.
  864. *
  865. * Unfortunately, some other NII drivers (e.g. Mellanox) may
  866. * time out and report failure if asked to detect cable
  867. * presence during initialisation on links that are physically
  868. * slow to reach link-up.
  869. *
  870. * Attempt to work around both of these problems by requesting
  871. * cable detection at this point if any only if the driver is
  872. * not capable of reporting link status changes at runtime via
  873. * PXE_OPCODE_GET_STATUS.
  874. */
  875. flags = ( nii->media ? PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE
  876. : PXE_OPFLAGS_INITIALIZE_DETECT_CABLE );
  877. if ( ( rc = nii_initialise_flags ( nii, flags ) ) != 0 )
  878. goto err_initialise;
  879. /* Attempt to set station address */
  880. if ( ( rc = nii_set_station_address ( nii, netdev ) ) != 0 ) {
  881. DBGC ( nii, "NII %s could not set station address: %s\n",
  882. nii->dev.name, strerror ( rc ) );
  883. /* Treat as non-fatal */
  884. }
  885. /* Set receive filters */
  886. if ( ( rc = nii_set_rx_filters ( nii ) ) != 0 )
  887. goto err_set_rx_filters;
  888. return 0;
  889. err_set_rx_filters:
  890. nii_shutdown ( nii );
  891. err_initialise:
  892. return rc;
  893. }
  894. /**
  895. * Close network device
  896. *
  897. * @v netdev Network device
  898. */
  899. static void nii_close ( struct net_device *netdev ) {
  900. struct nii_nic *nii = netdev->priv;
  901. /* Shut down NIC */
  902. nii_shutdown ( nii );
  903. /* Discard transmit buffer, if applicable */
  904. if ( nii->txbuf ) {
  905. netdev_tx_complete_err ( netdev, nii->txbuf, -ECANCELED );
  906. nii->txbuf = NULL;
  907. }
  908. /* Discard receive buffer, if applicable */
  909. if ( nii->rxbuf ) {
  910. free_iob ( nii->rxbuf );
  911. nii->rxbuf = NULL;
  912. }
  913. }
  914. /** NII network device operations */
  915. static struct net_device_operations nii_operations = {
  916. .open = nii_open,
  917. .close = nii_close,
  918. .transmit = nii_transmit,
  919. .poll = nii_poll,
  920. };
  921. /**
  922. * Attach driver to device
  923. *
  924. * @v efidev EFI device
  925. * @ret rc Return status code
  926. */
  927. int nii_start ( struct efi_device *efidev ) {
  928. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  929. EFI_HANDLE device = efidev->device;
  930. struct net_device *netdev;
  931. struct nii_nic *nii;
  932. void *interface;
  933. EFI_STATUS efirc;
  934. int rc;
  935. /* Allocate and initialise structure */
  936. netdev = alloc_netdev ( sizeof ( *nii ) );
  937. if ( ! netdev ) {
  938. rc = -ENOMEM;
  939. goto err_alloc;
  940. }
  941. netdev_init ( netdev, &nii_operations );
  942. nii = netdev->priv;
  943. nii->efidev = efidev;
  944. netdev->ll_broadcast = nii->broadcast;
  945. efidev_set_drvdata ( efidev, netdev );
  946. /* Populate underlying device information */
  947. efi_device_info ( device, "NII", &nii->dev );
  948. nii->dev.driver_name = "NII";
  949. nii->dev.parent = &efidev->dev;
  950. list_add ( &nii->dev.siblings, &efidev->dev.children );
  951. INIT_LIST_HEAD ( &nii->dev.children );
  952. netdev->dev = &nii->dev;
  953. /* Open NII protocol */
  954. if ( ( efirc = bs->OpenProtocol ( device, &efi_nii31_protocol_guid,
  955. &interface, efi_image_handle, device,
  956. ( EFI_OPEN_PROTOCOL_BY_DRIVER |
  957. EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
  958. rc = -EEFI ( efirc );
  959. DBGC ( nii, "NII %s cannot open NII protocol: %s\n",
  960. nii->dev.name, strerror ( rc ) );
  961. DBGC_EFI_OPENERS ( device, device, &efi_nii31_protocol_guid );
  962. goto err_open_protocol;
  963. }
  964. nii->nii = interface;
  965. /* Locate UNDI and entry point */
  966. nii->undi = ( ( void * ) ( intptr_t ) nii->nii->Id );
  967. if ( ! nii->undi ) {
  968. DBGC ( nii, "NII %s has no UNDI\n", nii->dev.name );
  969. rc = -ENODEV;
  970. goto err_no_undi;
  971. }
  972. if ( nii->undi->Implementation & PXE_ROMID_IMP_HW_UNDI ) {
  973. DBGC ( nii, "NII %s is a mythical hardware UNDI\n",
  974. nii->dev.name );
  975. rc = -ENOTSUP;
  976. goto err_hw_undi;
  977. }
  978. if ( nii->undi->Implementation & PXE_ROMID_IMP_SW_VIRT_ADDR ) {
  979. nii->issue = ( ( void * ) ( intptr_t ) nii->undi->EntryPoint );
  980. } else {
  981. nii->issue = ( ( ( void * ) nii->undi ) +
  982. nii->undi->EntryPoint );
  983. }
  984. DBGC ( nii, "NII %s using UNDI v%x.%x at %p entry %p impl %#08x\n",
  985. nii->dev.name, nii->nii->MajorVer, nii->nii->MinorVer,
  986. nii->undi, nii->issue, nii->undi->Implementation );
  987. /* Open PCI I/O protocols and locate BARs */
  988. if ( ( rc = nii_pci_open ( nii ) ) != 0 )
  989. goto err_pci_open;
  990. /* Start UNDI */
  991. if ( ( rc = nii_start_undi ( nii ) ) != 0 )
  992. goto err_start_undi;
  993. /* Get initialisation information */
  994. if ( ( rc = nii_get_init_info ( nii, netdev ) ) != 0 )
  995. goto err_get_init_info;
  996. /* Get MAC addresses */
  997. if ( ( rc = nii_get_station_address ( nii, netdev ) ) != 0 )
  998. goto err_get_station_address;
  999. /* Register network device */
  1000. if ( ( rc = register_netdev ( netdev ) ) != 0 )
  1001. goto err_register_netdev;
  1002. DBGC ( nii, "NII %s registered as %s for %s\n", nii->dev.name,
  1003. netdev->name, efi_handle_name ( device ) );
  1004. /* Set initial link state (if media detection is not supported) */
  1005. if ( ! nii->media )
  1006. netdev_link_up ( netdev );
  1007. return 0;
  1008. unregister_netdev ( netdev );
  1009. err_register_netdev:
  1010. err_get_station_address:
  1011. err_get_init_info:
  1012. nii_stop_undi ( nii );
  1013. err_start_undi:
  1014. nii_pci_close ( nii );
  1015. err_pci_open:
  1016. err_hw_undi:
  1017. err_no_undi:
  1018. bs->CloseProtocol ( device, &efi_nii31_protocol_guid,
  1019. efi_image_handle, device );
  1020. err_open_protocol:
  1021. list_del ( &nii->dev.siblings );
  1022. netdev_nullify ( netdev );
  1023. netdev_put ( netdev );
  1024. err_alloc:
  1025. return rc;
  1026. }
  1027. /**
  1028. * Detach driver from device
  1029. *
  1030. * @v efidev EFI device
  1031. */
  1032. void nii_stop ( struct efi_device *efidev ) {
  1033. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  1034. struct net_device *netdev = efidev_get_drvdata ( efidev );
  1035. struct nii_nic *nii = netdev->priv;
  1036. EFI_HANDLE device = efidev->device;
  1037. /* Unregister network device */
  1038. unregister_netdev ( netdev );
  1039. /* Stop UNDI */
  1040. nii_stop_undi ( nii );
  1041. /* Close PCI I/O protocols */
  1042. nii_pci_close ( nii );
  1043. /* Close NII protocol */
  1044. bs->CloseProtocol ( device, &efi_nii31_protocol_guid,
  1045. efi_image_handle, device );
  1046. /* Free network device */
  1047. list_del ( &nii->dev.siblings );
  1048. netdev_nullify ( netdev );
  1049. netdev_put ( netdev );
  1050. }