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.

snpnet.c 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  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 <stdlib.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <errno.h>
  24. #include <ipxe/iobuf.h>
  25. #include <ipxe/netdevice.h>
  26. #include <ipxe/ethernet.h>
  27. #include <ipxe/vsprintf.h>
  28. #include <ipxe/efi/efi.h>
  29. #include <ipxe/efi/Protocol/SimpleNetwork.h>
  30. #include <ipxe/efi/efi_driver.h>
  31. #include <ipxe/efi/efi_utils.h>
  32. #include "snpnet.h"
  33. /** @file
  34. *
  35. * SNP NIC driver
  36. *
  37. */
  38. /** An SNP NIC */
  39. struct snp_nic {
  40. /** EFI device */
  41. struct efi_device *efidev;
  42. /** Simple network protocol */
  43. EFI_SIMPLE_NETWORK_PROTOCOL *snp;
  44. /** Generic device */
  45. struct device dev;
  46. /** Maximum packet size
  47. *
  48. * This is calculated as the sum of MediaHeaderSize and
  49. * MaxPacketSize, and may therefore be an overestimate.
  50. */
  51. size_t mtu;
  52. /** Current transmit buffer */
  53. struct io_buffer *txbuf;
  54. /** Current receive buffer */
  55. struct io_buffer *rxbuf;
  56. };
  57. /** Maximum number of received packets per poll */
  58. #define SNP_RX_QUOTA 4
  59. /**
  60. * Format SNP MAC address (for debugging)
  61. *
  62. * @v mac MAC address
  63. * @v len Length of MAC address
  64. * @ret text MAC address as text
  65. */
  66. static const char * snpnet_mac_text ( EFI_MAC_ADDRESS *mac, size_t len ) {
  67. static char buf[ sizeof ( *mac ) * 3 /* "xx:" or "xx\0" */ ];
  68. size_t used = 0;
  69. unsigned int i;
  70. for ( i = 0 ; i < len ; i++ ) {
  71. used += ssnprintf ( &buf[used], ( sizeof ( buf ) - used ),
  72. "%s%02x", ( used ? ":" : "" ),
  73. mac->Addr[i] );
  74. }
  75. return buf;
  76. }
  77. /**
  78. * Dump SNP mode information (for debugging)
  79. *
  80. * @v netdev Network device
  81. */
  82. static void snpnet_dump_mode ( struct net_device *netdev ) {
  83. struct snp_nic *snp = netdev_priv ( netdev );
  84. EFI_SIMPLE_NETWORK_MODE *mode = snp->snp->Mode;
  85. size_t mac_len = mode->HwAddressSize;
  86. unsigned int i;
  87. /* Do nothing unless debugging is enabled */
  88. if ( ! DBG_EXTRA )
  89. return;
  90. DBGC2 ( snp, "SNP %s st %d type %d hdr %d pkt %d rxflt %#x/%#x%s "
  91. "nvram %d acc %d mcast %d/%d\n", netdev->name, mode->State,
  92. mode->IfType, mode->MediaHeaderSize, mode->MaxPacketSize,
  93. mode->ReceiveFilterSetting, mode->ReceiveFilterMask,
  94. ( mode->MultipleTxSupported ? " multitx" : "" ),
  95. mode->NvRamSize, mode->NvRamAccessSize,
  96. mode->MCastFilterCount, mode->MaxMCastFilterCount );
  97. DBGC2 ( snp, "SNP %s hw %s", netdev->name,
  98. snpnet_mac_text ( &mode->PermanentAddress, mac_len ) );
  99. DBGC2 ( snp, " addr %s%s",
  100. snpnet_mac_text ( &mode->CurrentAddress, mac_len ),
  101. ( mode->MacAddressChangeable ? "" : "(f)" ) );
  102. DBGC2 ( snp, " bcast %s\n",
  103. snpnet_mac_text ( &mode->BroadcastAddress, mac_len ) );
  104. for ( i = 0 ; i < mode->MCastFilterCount ; i++ ) {
  105. DBGC2 ( snp, "SNP %s mcast %s\n", netdev->name,
  106. snpnet_mac_text ( &mode->MCastFilter[i], mac_len ) );
  107. }
  108. DBGC2 ( snp, "SNP %s media %s\n", netdev->name,
  109. ( mode->MediaPresentSupported ?
  110. ( mode->MediaPresent ? "present" : "not present" ) :
  111. "presence not supported" ) );
  112. }
  113. /**
  114. * Check link state
  115. *
  116. * @v netdev Network device
  117. */
  118. static void snpnet_check_link ( struct net_device *netdev ) {
  119. struct snp_nic *snp = netdev_priv ( netdev );
  120. EFI_SIMPLE_NETWORK_MODE *mode = snp->snp->Mode;
  121. /* Do nothing unless media presence detection is supported */
  122. if ( ! mode->MediaPresentSupported )
  123. return;
  124. /* Report any link status change */
  125. if ( mode->MediaPresent && ( ! netdev_link_ok ( netdev ) ) ) {
  126. netdev_link_up ( netdev );
  127. } else if ( ( ! mode->MediaPresent ) && netdev_link_ok ( netdev ) ) {
  128. netdev_link_down ( netdev );
  129. }
  130. }
  131. /**
  132. * Transmit packet
  133. *
  134. * @v netdev Network device
  135. * @v iobuf I/O buffer
  136. * @ret rc Return status code
  137. */
  138. static int snpnet_transmit ( struct net_device *netdev,
  139. struct io_buffer *iobuf ) {
  140. struct snp_nic *snp = netdev_priv ( netdev );
  141. EFI_STATUS efirc;
  142. int rc;
  143. /* Defer the packet if there is already a transmission in progress */
  144. if ( snp->txbuf ) {
  145. netdev_tx_defer ( netdev, iobuf );
  146. return 0;
  147. }
  148. /* Transmit packet */
  149. if ( ( efirc = snp->snp->Transmit ( snp->snp, 0, iob_len ( iobuf ),
  150. iobuf->data, NULL, NULL,
  151. NULL ) ) != 0 ) {
  152. rc = -EEFI ( efirc );
  153. DBGC ( snp, "SNP %s could not transmit: %s\n",
  154. netdev->name, strerror ( rc ) );
  155. return rc;
  156. }
  157. snp->txbuf = iobuf;
  158. return 0;
  159. }
  160. /**
  161. * Poll for completed packets
  162. *
  163. * @v netdev Network device
  164. */
  165. static void snpnet_poll_tx ( struct net_device *netdev ) {
  166. struct snp_nic *snp = netdev->priv;
  167. struct io_buffer *iobuf;
  168. UINT32 irq;
  169. VOID *txbuf;
  170. EFI_STATUS efirc;
  171. int rc;
  172. /* Get status */
  173. txbuf = NULL;
  174. if ( ( efirc = snp->snp->GetStatus ( snp->snp, &irq, &txbuf ) ) != 0 ) {
  175. rc = -EEFI ( efirc );
  176. DBGC ( snp, "SNP %s could not get status: %s\n",
  177. netdev->name, strerror ( rc ) );
  178. netdev_rx_err ( netdev, NULL, rc );
  179. return;
  180. }
  181. /* Do nothing unless we have a completion */
  182. if ( ! txbuf )
  183. return;
  184. /* Sanity check */
  185. if ( ! snp->txbuf ) {
  186. DBGC ( snp, "SNP %s reported spurious TX completion\n",
  187. netdev->name );
  188. netdev_tx_err ( netdev, NULL, -EPIPE );
  189. return;
  190. }
  191. /* Complete transmission */
  192. iobuf = snp->txbuf;
  193. snp->txbuf = NULL;
  194. netdev_tx_complete ( netdev, iobuf );
  195. }
  196. /**
  197. * Poll for received packets
  198. *
  199. * @v netdev Network device
  200. */
  201. static void snpnet_poll_rx ( struct net_device *netdev ) {
  202. struct snp_nic *snp = netdev->priv;
  203. UINTN len;
  204. unsigned int quota;
  205. EFI_STATUS efirc;
  206. int rc;
  207. /* Retrieve up to SNP_RX_QUOTA packets */
  208. for ( quota = SNP_RX_QUOTA ; quota ; quota-- ) {
  209. /* Allocate buffer, if required */
  210. if ( ! snp->rxbuf ) {
  211. snp->rxbuf = alloc_iob ( snp->mtu );
  212. if ( ! snp->rxbuf ) {
  213. /* Leave for next poll */
  214. break;
  215. }
  216. }
  217. /* Receive packet */
  218. len = iob_tailroom ( snp->rxbuf );
  219. if ( ( efirc = snp->snp->Receive ( snp->snp, NULL, &len,
  220. snp->rxbuf->data, NULL,
  221. NULL, NULL ) ) != 0 ) {
  222. /* EFI_NOT_READY is just the usual "no packet"
  223. * status indication; ignore it.
  224. */
  225. if ( efirc == EFI_NOT_READY )
  226. break;
  227. /* Anything else is an error */
  228. rc = -EEFI ( efirc );
  229. DBGC ( snp, "SNP %s could not receive: %s\n",
  230. netdev->name, strerror ( rc ) );
  231. netdev_rx_err ( netdev, NULL, rc );
  232. break;
  233. }
  234. /* Hand off to network stack */
  235. iob_put ( snp->rxbuf, len );
  236. netdev_rx ( netdev, snp->rxbuf );
  237. snp->rxbuf = NULL;
  238. }
  239. }
  240. /**
  241. * Poll for completed packets
  242. *
  243. * @v netdev Network device
  244. */
  245. static void snpnet_poll ( struct net_device *netdev ) {
  246. /* Process any TX completions */
  247. snpnet_poll_tx ( netdev );
  248. /* Process any RX completions */
  249. snpnet_poll_rx ( netdev );
  250. /* Check for link state changes */
  251. snpnet_check_link ( netdev );
  252. }
  253. /**
  254. * Set receive filters
  255. *
  256. * @v netdev Network device
  257. * @ret rc Return status code
  258. */
  259. static int snpnet_rx_filters ( struct net_device *netdev ) {
  260. struct snp_nic *snp = netdev->priv;
  261. UINT32 filters[] = {
  262. snp->snp->Mode->ReceiveFilterMask,
  263. ( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
  264. EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST |
  265. EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST ),
  266. ( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
  267. EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST |
  268. EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST ),
  269. ( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
  270. EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST ),
  271. ( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST ),
  272. };
  273. unsigned int i;
  274. EFI_STATUS efirc;
  275. int rc;
  276. /* Try possible receive filters in turn */
  277. for ( i = 0; i < ( sizeof ( filters ) / sizeof ( filters[0] ) ); i++ ) {
  278. efirc = snp->snp->ReceiveFilters ( snp->snp, filters[i],
  279. EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST, TRUE,
  280. 0, NULL );
  281. if ( efirc == 0 )
  282. return 0;
  283. rc = -EEFI ( efirc );
  284. DBGC ( snp, "SNP %s could not set receive filters %#02x (have "
  285. "%#02x): %s\n", netdev->name, filters[i],
  286. snp->snp->Mode->ReceiveFilterSetting, strerror ( rc ) );
  287. }
  288. return rc;
  289. }
  290. /**
  291. * Open network device
  292. *
  293. * @v netdev Network device
  294. * @ret rc Return status code
  295. */
  296. static int snpnet_open ( struct net_device *netdev ) {
  297. struct snp_nic *snp = netdev->priv;
  298. EFI_MAC_ADDRESS *mac = ( ( void * ) netdev->ll_addr );
  299. EFI_STATUS efirc;
  300. int rc;
  301. /* Try setting MAC address (before initialising) */
  302. if ( ( efirc = snp->snp->StationAddress ( snp->snp, FALSE, mac ) ) !=0){
  303. rc = -EEFI ( efirc );
  304. DBGC ( snp, "SNP %s could not set station address before "
  305. "initialising: %s\n", netdev->name, strerror ( rc ) );
  306. /* Ignore error */
  307. }
  308. /* Initialise NIC */
  309. if ( ( efirc = snp->snp->Initialize ( snp->snp, 0, 0 ) ) != 0 ) {
  310. rc = -EEFI ( efirc );
  311. snpnet_dump_mode ( netdev );
  312. DBGC ( snp, "SNP %s could not initialise: %s\n",
  313. netdev->name, strerror ( rc ) );
  314. return rc;
  315. }
  316. /* Try setting MAC address (after initialising) */
  317. if ( ( efirc = snp->snp->StationAddress ( snp->snp, FALSE, mac ) ) !=0){
  318. rc = -EEFI ( efirc );
  319. DBGC ( snp, "SNP %s could not set station address after "
  320. "initialising: %s\n", netdev->name, strerror ( rc ) );
  321. /* Ignore error */
  322. }
  323. /* Set receive filters */
  324. if ( ( rc = snpnet_rx_filters ( netdev ) ) != 0 ) {
  325. /* Ignore error */
  326. }
  327. /* Dump mode information (for debugging) */
  328. snpnet_dump_mode ( netdev );
  329. return 0;
  330. }
  331. /**
  332. * Close network device
  333. *
  334. * @v netdev Network device
  335. */
  336. static void snpnet_close ( struct net_device *netdev ) {
  337. struct snp_nic *snp = netdev->priv;
  338. EFI_STATUS efirc;
  339. int rc;
  340. /* Shut down NIC */
  341. if ( ( efirc = snp->snp->Shutdown ( snp->snp ) ) != 0 ) {
  342. rc = -EEFI ( efirc );
  343. DBGC ( snp, "SNP %s could not shut down: %s\n",
  344. netdev->name, strerror ( rc ) );
  345. /* Nothing we can do about this */
  346. }
  347. /* Discard transmit buffer, if applicable */
  348. if ( snp->txbuf ) {
  349. netdev_tx_complete_err ( netdev, snp->txbuf, -ECANCELED );
  350. snp->txbuf = NULL;
  351. }
  352. /* Discard receive buffer, if applicable */
  353. if ( snp->rxbuf ) {
  354. free_iob ( snp->rxbuf );
  355. snp->rxbuf = NULL;
  356. }
  357. }
  358. /** SNP network device operations */
  359. static struct net_device_operations snpnet_operations = {
  360. .open = snpnet_open,
  361. .close = snpnet_close,
  362. .transmit = snpnet_transmit,
  363. .poll = snpnet_poll,
  364. };
  365. /**
  366. * Attach driver to device
  367. *
  368. * @v efidev EFI device
  369. * @ret rc Return status code
  370. */
  371. int snpnet_start ( struct efi_device *efidev ) {
  372. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  373. EFI_HANDLE device = efidev->device;
  374. EFI_SIMPLE_NETWORK_MODE *mode;
  375. struct net_device *netdev;
  376. struct snp_nic *snp;
  377. void *interface;
  378. EFI_STATUS efirc;
  379. int rc;
  380. /* Open SNP protocol */
  381. if ( ( efirc = bs->OpenProtocol ( device,
  382. &efi_simple_network_protocol_guid,
  383. &interface, efi_image_handle, device,
  384. ( EFI_OPEN_PROTOCOL_BY_DRIVER |
  385. EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
  386. rc = -EEFI ( efirc );
  387. DBGC ( device, "SNP %s cannot open SNP protocol: %s\n",
  388. efi_handle_name ( device ), strerror ( rc ) );
  389. DBGC_EFI_OPENERS ( device, device,
  390. &efi_simple_network_protocol_guid );
  391. goto err_open_protocol;
  392. }
  393. /* Allocate and initialise structure */
  394. netdev = alloc_etherdev ( sizeof ( *snp ) );
  395. if ( ! netdev ) {
  396. rc = -ENOMEM;
  397. goto err_alloc;
  398. }
  399. netdev_init ( netdev, &snpnet_operations );
  400. snp = netdev->priv;
  401. snp->efidev = efidev;
  402. snp->snp = interface;
  403. mode = snp->snp->Mode;
  404. efidev_set_drvdata ( efidev, netdev );
  405. /* Populate underlying device information */
  406. efi_device_info ( device, "SNP", &snp->dev );
  407. snp->dev.driver_name = "SNP";
  408. snp->dev.parent = &efidev->dev;
  409. list_add ( &snp->dev.siblings, &efidev->dev.children );
  410. INIT_LIST_HEAD ( &snp->dev.children );
  411. netdev->dev = &snp->dev;
  412. /* Bring to the Started state */
  413. if ( ( mode->State == EfiSimpleNetworkStopped ) &&
  414. ( ( efirc = snp->snp->Start ( snp->snp ) ) != 0 ) ) {
  415. rc = -EEFI ( efirc );
  416. DBGC ( device, "SNP %s could not start: %s\n",
  417. efi_handle_name ( device ), strerror ( rc ) );
  418. goto err_start;
  419. }
  420. if ( ( mode->State == EfiSimpleNetworkInitialized ) &&
  421. ( ( efirc = snp->snp->Shutdown ( snp->snp ) ) != 0 ) ) {
  422. rc = -EEFI ( efirc );
  423. DBGC ( device, "SNP %s could not shut down: %s\n",
  424. efi_handle_name ( device ), strerror ( rc ) );
  425. goto err_shutdown;
  426. }
  427. /* Populate network device parameters */
  428. if ( mode->HwAddressSize != netdev->ll_protocol->hw_addr_len ) {
  429. DBGC ( device, "SNP %s has invalid hardware address length "
  430. "%d\n", efi_handle_name ( device ), mode->HwAddressSize);
  431. rc = -ENOTSUP;
  432. goto err_hw_addr_len;
  433. }
  434. memcpy ( netdev->hw_addr, &mode->PermanentAddress,
  435. netdev->ll_protocol->hw_addr_len );
  436. if ( mode->HwAddressSize != netdev->ll_protocol->ll_addr_len ) {
  437. DBGC ( device, "SNP %s has invalid link-layer address length "
  438. "%d\n", efi_handle_name ( device ), mode->HwAddressSize);
  439. rc = -ENOTSUP;
  440. goto err_ll_addr_len;
  441. }
  442. memcpy ( netdev->ll_addr, &mode->CurrentAddress,
  443. netdev->ll_protocol->ll_addr_len );
  444. snp->mtu = ( snp->snp->Mode->MaxPacketSize +
  445. snp->snp->Mode->MediaHeaderSize );
  446. /* Register network device */
  447. if ( ( rc = register_netdev ( netdev ) ) != 0 )
  448. goto err_register_netdev;
  449. DBGC ( device, "SNP %s registered as %s\n",
  450. efi_handle_name ( device ), netdev->name );
  451. /* Set initial link state */
  452. if ( snp->snp->Mode->MediaPresentSupported ) {
  453. snpnet_check_link ( netdev );
  454. } else {
  455. netdev_link_up ( netdev );
  456. }
  457. return 0;
  458. unregister_netdev ( netdev );
  459. err_register_netdev:
  460. err_ll_addr_len:
  461. err_hw_addr_len:
  462. err_shutdown:
  463. err_start:
  464. list_del ( &snp->dev.siblings );
  465. netdev_nullify ( netdev );
  466. netdev_put ( netdev );
  467. err_alloc:
  468. bs->CloseProtocol ( device, &efi_simple_network_protocol_guid,
  469. efi_image_handle, device );
  470. err_open_protocol:
  471. return rc;
  472. }
  473. /**
  474. * Detach driver from device
  475. *
  476. * @v efidev EFI device
  477. */
  478. void snpnet_stop ( struct efi_device *efidev ) {
  479. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  480. struct net_device *netdev = efidev_get_drvdata ( efidev );
  481. struct snp_nic *snp = netdev->priv;
  482. EFI_HANDLE device = efidev->device;
  483. EFI_STATUS efirc;
  484. int rc;
  485. /* Unregister network device */
  486. unregister_netdev ( netdev );
  487. /* Stop SNP protocol */
  488. if ( ( efirc = snp->snp->Stop ( snp->snp ) ) != 0 ) {
  489. rc = -EEFI ( efirc );
  490. DBGC ( device, "SNP %s could not stop: %s\n",
  491. efi_handle_name ( device ), strerror ( rc ) );
  492. /* Nothing we can do about this */
  493. }
  494. /* Free network device */
  495. list_del ( &snp->dev.siblings );
  496. netdev_nullify ( netdev );
  497. netdev_put ( netdev );
  498. /* Close SNP protocol */
  499. bs->CloseProtocol ( device, &efi_simple_network_protocol_guid,
  500. efi_image_handle, device );
  501. }