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

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