SimpleNetwork.c 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503
  1. /** @file
  2. Provides the Simple Network functions.
  3. Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include "Ax88772.h"
  7. /**
  8. This function updates the filtering on the receiver.
  9. This support routine calls ::Ax88772MacAddressSet to update
  10. the MAC address. This routine then rebuilds the multicast
  11. hash by calling ::Ax88772MulticastClear and ::Ax88772MulticastSet.
  12. Finally this routine enables the receiver by calling
  13. ::Ax88772RxControl.
  14. @param [in] pSimpleNetwork Simple network mode pointer
  15. @retval EFI_SUCCESS This operation was successful.
  16. @retval EFI_NOT_STARTED The network interface was not started.
  17. @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
  18. EFI_SIMPLE_NETWORK_PROTOCOL structure.
  19. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
  20. @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
  21. **/
  22. EFI_STATUS
  23. ReceiveFilterUpdate (
  24. IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
  25. )
  26. {
  27. EFI_SIMPLE_NETWORK_MODE * pMode;
  28. NIC_DEVICE * pNicDevice;
  29. EFI_STATUS Status;
  30. UINT32 Index;
  31. DBG_ENTER ( );
  32. //
  33. // Set the MAC address
  34. //
  35. pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
  36. pMode = pSimpleNetwork->Mode;
  37. Status = Ax88772MacAddressSet ( pNicDevice,
  38. &pMode->CurrentAddress.Addr[0]);
  39. if ( !EFI_ERROR ( Status )) {
  40. //
  41. // Clear the multicast hash table
  42. //
  43. Ax88772MulticastClear ( pNicDevice );
  44. //
  45. // Load the multicast hash table
  46. //
  47. if ( 0 != ( pMode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
  48. for ( Index = 0;
  49. ( !EFI_ERROR ( Status )) && ( Index < pMode->MCastFilterCount );
  50. Index++ ) {
  51. //
  52. // Enable the next multicast address
  53. //
  54. Ax88772MulticastSet ( pNicDevice,
  55. &pMode->MCastFilter[ Index ].Addr[0]);
  56. }
  57. }
  58. //
  59. // Enable the receiver
  60. //
  61. if ( !EFI_ERROR ( Status )) {
  62. Status = Ax88772RxControl ( pNicDevice, pMode->ReceiveFilterSetting );
  63. }
  64. }
  65. //
  66. // Return the operation status
  67. //
  68. DBG_EXIT_STATUS ( Status );
  69. return Status;
  70. }
  71. /**
  72. This function updates the SNP driver status.
  73. This function gets the current interrupt and recycled transmit
  74. buffer status from the network interface. The interrupt status
  75. and the media status are returned as a bit mask in InterruptStatus.
  76. If InterruptStatus is NULL, the interrupt status will not be read.
  77. Upon successful return of the media status, the MediaPresent field
  78. of EFI_SIMPLE_NETWORK_MODE will be updated to reflect any change
  79. of media status. If TxBuf is not NULL, a recycled transmit buffer
  80. address will be retrived. If a recycled transmit buffer address
  81. is returned in TxBuf, then the buffer has been successfully
  82. transmitted, and the status for that buffer is cleared.
  83. This function calls ::Ax88772Rx to update the media status and
  84. queue any receive packets.
  85. @param [in] pSimpleNetwork Protocol instance pointer
  86. @param [in] pInterruptStatus A pointer to the bit mask of the current active interrupts.
  87. If this is NULL, the interrupt status will not be read from
  88. the device. If this is not NULL, the interrupt status will
  89. be read from teh device. When the interrupt status is read,
  90. it will also be cleared. Clearing the transmit interrupt
  91. does not empty the recycled transmit buffer array.
  92. @param [out] ppTxBuf Recycled transmit buffer address. The network interface will
  93. not transmit if its internal recycled transmit buffer array is
  94. full. Reading the transmit buffer does not clear the transmit
  95. interrupt. If this is NULL, then the transmit buffer status
  96. will not be read. If there are not transmit buffers to recycle
  97. and TxBuf is not NULL, *TxBuf will be set to NULL.
  98. @retval EFI_SUCCESS This operation was successful.
  99. @retval EFI_NOT_STARTED The network interface was not started.
  100. @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
  101. EFI_SIMPLE_NETWORK_PROTOCOL structure.
  102. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
  103. **/
  104. EFI_STATUS
  105. EFIAPI
  106. SN_GetStatus (
  107. IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
  108. OUT UINT32 * pInterruptStatus,
  109. OUT VOID ** ppTxBuf
  110. )
  111. {
  112. BOOLEAN bLinkIdle;
  113. EFI_SIMPLE_NETWORK_MODE * pMode;
  114. NIC_DEVICE * pNicDevice;
  115. EFI_STATUS Status;
  116. EFI_TPL TplPrevious;
  117. DBG_ENTER ( );
  118. //
  119. // Verify the parameters
  120. //
  121. if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
  122. //
  123. // Return the transmit buffer
  124. //
  125. pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
  126. if (( NULL != ppTxBuf ) && ( NULL != pNicDevice->pTxBuffer )) {
  127. *ppTxBuf = pNicDevice->pTxBuffer;
  128. pNicDevice->pTxBuffer = NULL;
  129. }
  130. //
  131. // Determine if interface is running
  132. //
  133. pMode = pSimpleNetwork->Mode;
  134. if ( EfiSimpleNetworkStopped != pMode->State ) {
  135. //
  136. // Synchronize with Ax88772Timer
  137. //
  138. VERIFY_TPL ( TPL_AX88772 );
  139. TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
  140. //
  141. // Update the link status
  142. //
  143. bLinkIdle = pNicDevice->bLinkIdle;
  144. pNicDevice->bLinkIdle = TRUE;
  145. Ax88772Rx ( pNicDevice, bLinkIdle );
  146. pMode->MediaPresent = pNicDevice->bLinkUp;
  147. //
  148. // Release the synchronization with Ax88772Timer
  149. //
  150. gBS->RestoreTPL ( TplPrevious );
  151. //
  152. // Return the interrupt status
  153. //
  154. if ( NULL != pInterruptStatus ) {
  155. *pInterruptStatus = 0;
  156. }
  157. Status = EFI_SUCCESS;
  158. }
  159. else {
  160. Status = EFI_NOT_STARTED;
  161. }
  162. }
  163. else {
  164. Status = EFI_INVALID_PARAMETER;
  165. }
  166. //
  167. // Return the operation status
  168. //
  169. DBG_EXIT_STATUS ( Status );
  170. return Status;
  171. }
  172. /**
  173. Resets the network adapter and allocates the transmit and receive buffers
  174. required by the network interface; optionally, also requests allocation of
  175. additional transmit and receive buffers. This routine must be called before
  176. any other routine in the Simple Network protocol is called.
  177. @param [in] pSimpleNetwork Protocol instance pointer
  178. @param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer allocation
  179. @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer allocation
  180. @retval EFI_SUCCESS This operation was successful.
  181. @retval EFI_NOT_STARTED The network interface was not started.
  182. @retval EFI_OUT_OF_RESOURCES There was not enough memory for the transmit and receive buffers
  183. @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
  184. EFI_SIMPLE_NETWORK_PROTOCOL structure.
  185. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
  186. @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
  187. **/
  188. EFI_STATUS
  189. EFIAPI
  190. SN_Initialize (
  191. IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
  192. IN UINTN ExtraRxBufferSize,
  193. IN UINTN ExtraTxBufferSize
  194. )
  195. {
  196. EFI_SIMPLE_NETWORK_MODE * pMode;
  197. EFI_STATUS Status;
  198. DBG_ENTER ( );
  199. //
  200. // Verify the parameters
  201. //
  202. if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
  203. //
  204. // Determine if the interface is already started
  205. //
  206. pMode = pSimpleNetwork->Mode;
  207. if ( EfiSimpleNetworkStarted == pMode->State ) {
  208. if (( 0 == ExtraRxBufferSize ) && ( 0 == ExtraTxBufferSize )) {
  209. //
  210. // Start the adapter
  211. //
  212. Status = SN_Reset ( pSimpleNetwork, FALSE );
  213. if ( !EFI_ERROR ( Status )) {
  214. //
  215. // Update the network state
  216. //
  217. pMode->State = EfiSimpleNetworkInitialized;
  218. }
  219. }
  220. else {
  221. Status = EFI_UNSUPPORTED;
  222. }
  223. }
  224. else {
  225. Status = EFI_NOT_STARTED;
  226. }
  227. }
  228. else {
  229. Status = EFI_INVALID_PARAMETER;
  230. }
  231. //
  232. // Return the operation status
  233. //
  234. DBG_EXIT_STATUS ( Status );
  235. return Status;
  236. }
  237. /**
  238. This function converts a multicast IP address to a multicast HW MAC address
  239. for all packet transactions.
  240. @param [in] pSimpleNetwork Protocol instance pointer
  241. @param [in] bIPv6 Set to TRUE if the multicast IP address is IPv6 [RFC2460].
  242. Set to FALSE if the multicast IP address is IPv4 [RFC 791].
  243. @param [in] pIP The multicast IP address that is to be converted to a
  244. multicast HW MAC address.
  245. @param [in] pMAC The multicast HW MAC address that is to be generated from IP.
  246. @retval EFI_SUCCESS This operation was successful.
  247. @retval EFI_NOT_STARTED The network interface was not started.
  248. @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
  249. EFI_SIMPLE_NETWORK_PROTOCOL structure.
  250. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
  251. @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
  252. **/
  253. EFI_STATUS
  254. EFIAPI
  255. SN_MCastIPtoMAC (
  256. IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
  257. IN BOOLEAN bIPv6,
  258. IN EFI_IP_ADDRESS * pIP,
  259. IN EFI_MAC_ADDRESS * pMAC
  260. )
  261. {
  262. EFI_STATUS Status;
  263. DBG_ENTER ( );
  264. //
  265. // This is not currently supported
  266. //
  267. Status = EFI_UNSUPPORTED;
  268. //
  269. // Return the operation status
  270. //
  271. DBG_EXIT_STATUS ( Status );
  272. return Status;
  273. }
  274. /**
  275. This function performs read and write operations on the NVRAM device
  276. attached to a network interface.
  277. @param [in] pSimpleNetwork Protocol instance pointer
  278. @param [in] ReadWrite TRUE for read operations, FALSE for write operations.
  279. @param [in] Offset Byte offset in the NVRAM device at which to start the
  280. read or write operation. This must be a multiple of
  281. NvRamAccessSize and less than NvRamSize.
  282. @param [in] BufferSize The number of bytes to read or write from the NVRAM device.
  283. This must also be a multiple of NvramAccessSize.
  284. @param [in, out] pBuffer A pointer to the data buffer.
  285. @retval EFI_SUCCESS This operation was successful.
  286. @retval EFI_NOT_STARTED The network interface was not started.
  287. @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
  288. EFI_SIMPLE_NETWORK_PROTOCOL structure.
  289. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
  290. @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
  291. **/
  292. EFI_STATUS
  293. EFIAPI
  294. SN_NvData (
  295. IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
  296. IN BOOLEAN ReadWrite,
  297. IN UINTN Offset,
  298. IN UINTN BufferSize,
  299. IN OUT VOID * pBuffer
  300. )
  301. {
  302. EFI_STATUS Status;
  303. DBG_ENTER ( );
  304. //
  305. // This is not currently supported
  306. //
  307. Status = EFI_UNSUPPORTED;
  308. //
  309. // Return the operation status
  310. //
  311. DBG_EXIT_STATUS ( Status );
  312. return Status;
  313. }
  314. /**
  315. Attempt to receive a packet from the network adapter.
  316. This function retrieves one packet from the receive queue of the network
  317. interface. If there are no packets on the receive queue, then EFI_NOT_READY
  318. will be returned. If there is a packet on the receive queue, and the size
  319. of the packet is smaller than BufferSize, then the contents of the packet
  320. will be placed in Buffer, and BufferSize will be udpated with the actual
  321. size of the packet. In addition, if SrcAddr, DestAddr, and Protocol are
  322. not NULL, then these values will be extracted from the media header and
  323. returned. If BufferSize is smaller than the received packet, then the
  324. size of the receive packet will be placed in BufferSize and
  325. EFI_BUFFER_TOO_SMALL will be returned.
  326. This routine calls ::Ax88772Rx to update the media status and
  327. empty the network adapter of receive packets.
  328. @param [in] pSimpleNetwork Protocol instance pointer
  329. @param [out] pHeaderSize The size, in bytes, of the media header to be filled in by
  330. the Transmit() function. If HeaderSize is non-zero, then
  331. it must be equal to SimpleNetwork->Mode->MediaHeaderSize
  332. and DestAddr and Protocol parameters must not be NULL.
  333. @param [out] pBufferSize The size, in bytes, of the entire packet (media header and
  334. data) to be transmitted through the network interface.
  335. @param [out] pBuffer A pointer to the packet (media header followed by data) to
  336. to be transmitted. This parameter can not be NULL. If
  337. HeaderSize is zero, then the media header is Buffer must
  338. already be filled in by the caller. If HeaderSize is nonzero,
  339. then the media header will be filled in by the Transmit()
  340. function.
  341. @param [out] pSrcAddr The source HW MAC address. If HeaderSize is zero, then
  342. this parameter is ignored. If HeaderSize is nonzero and
  343. SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
  344. is used for the source HW MAC address.
  345. @param [out] pDestAddr The destination HW MAC address. If HeaderSize is zero, then
  346. this parameter is ignored.
  347. @param [out] pProtocol The type of header to build. If HeaderSize is zero, then
  348. this parameter is ignored.
  349. @retval EFI_SUCCESS This operation was successful.
  350. @retval EFI_NOT_STARTED The network interface was not started.
  351. @retval EFI_NOT_READY No packets have been received on the network interface.
  352. @retval EFI_BUFFER_TOO_SMALL The packet is larger than BufferSize bytes.
  353. @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
  354. EFI_SIMPLE_NETWORK_PROTOCOL structure.
  355. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
  356. **/
  357. EFI_STATUS
  358. EFIAPI
  359. SN_Receive (
  360. IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
  361. OUT UINTN * pHeaderSize,
  362. OUT UINTN * pBufferSize,
  363. OUT VOID * pBuffer,
  364. OUT EFI_MAC_ADDRESS * pSrcAddr,
  365. OUT EFI_MAC_ADDRESS * pDestAddr,
  366. OUT UINT16 * pProtocol
  367. )
  368. {
  369. ETHERNET_HEADER * pHeader;
  370. EFI_SIMPLE_NETWORK_MODE * pMode;
  371. NIC_DEVICE * pNicDevice;
  372. RX_TX_PACKET * pRxPacket;
  373. EFI_STATUS Status;
  374. EFI_TPL TplPrevious;
  375. UINT16 Type;
  376. DBG_ENTER ( );
  377. //
  378. // Verify the parameters
  379. //
  380. if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
  381. //
  382. // The interface must be running
  383. //
  384. pMode = pSimpleNetwork->Mode;
  385. if ( EfiSimpleNetworkInitialized == pMode->State ) {
  386. //
  387. // Synchronize with Ax88772Timer
  388. //
  389. VERIFY_TPL ( TPL_AX88772 );
  390. TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
  391. //
  392. // Update the link status
  393. //
  394. pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
  395. Ax88772Rx ( pNicDevice, FALSE );
  396. pMode->MediaPresent = pNicDevice->bLinkUp;
  397. if ( pMode->MediaPresent ) {
  398. //
  399. // Attempt to receive a packet
  400. //
  401. pRxPacket = pNicDevice->pRxHead;
  402. if ( NULL != pRxPacket ) {
  403. pNicDevice->pRxHead = pRxPacket->pNext;
  404. if ( NULL == pNicDevice->pRxHead ) {
  405. pNicDevice->pRxTail = NULL;
  406. }
  407. //
  408. // Copy the received packet into the receive buffer
  409. //
  410. *pBufferSize = pRxPacket->Length;
  411. CopyMem ( pBuffer, &pRxPacket->Data[0], pRxPacket->Length );
  412. pHeader = (ETHERNET_HEADER *) &pRxPacket->Data[0];
  413. if ( NULL != pHeaderSize ) {
  414. *pHeaderSize = sizeof ( *pHeader );
  415. }
  416. if ( NULL != pDestAddr ) {
  417. CopyMem ( pDestAddr, &pHeader->dest_addr, PXE_HWADDR_LEN_ETHER );
  418. }
  419. if ( NULL != pSrcAddr ) {
  420. CopyMem ( pSrcAddr, &pHeader->src_addr, PXE_HWADDR_LEN_ETHER );
  421. }
  422. if ( NULL != pProtocol ) {
  423. Type = pHeader->type;
  424. Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
  425. *pProtocol = Type;
  426. }
  427. Status = EFI_SUCCESS;
  428. }
  429. else {
  430. //
  431. // No receive packets available
  432. //
  433. Status = EFI_NOT_READY;
  434. }
  435. }
  436. else {
  437. //
  438. // Link no up
  439. //
  440. Status = EFI_NOT_READY;
  441. }
  442. //
  443. // Release the synchronization with Ax88772Timer
  444. //
  445. gBS->RestoreTPL ( TplPrevious );
  446. }
  447. else {
  448. Status = EFI_NOT_STARTED;
  449. }
  450. }
  451. else {
  452. Status = EFI_INVALID_PARAMETER;
  453. }
  454. //
  455. // Return the operation status
  456. //
  457. DBG_EXIT_STATUS ( Status );
  458. return Status;
  459. }
  460. /**
  461. This function is used to enable and disable the hardware and software receive
  462. filters for the underlying network device.
  463. The receive filter change is broken down into three steps:
  464. 1. The filter mask bits that are set (ON) in the Enable parameter
  465. are added to the current receive filter settings.
  466. 2. The filter mask bits that are set (ON) in the Disable parameter
  467. are subtracted from the updated receive filter settins.
  468. 3. If the resulting filter settigns is not supported by the hardware
  469. a more liberal setting is selected.
  470. If the same bits are set in the Enable and Disable parameters, then the bits
  471. in the Disable parameter takes precedence.
  472. If the ResetMCastFilter parameter is TRUE, then the multicast address list
  473. filter is disabled (irregardless of what other multicast bits are set in
  474. the enable and Disable parameters). The SNP->Mode->MCastFilterCount field
  475. is set to zero. The SNP->Mode->MCastFilter contents are undefined.
  476. After enableing or disabling receive filter settings, software should
  477. verify the new settings by checking the SNP->Mode->ReceeiveFilterSettings,
  478. SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields.
  479. Note: Some network drivers and/or devices will automatically promote
  480. receive filter settings if the requested setting can not be honored.
  481. For example, if a request for four multicast addresses is made and
  482. the underlying hardware only supports two multicast addresses the
  483. driver might set the promiscuous or promiscuous multicast receive filters
  484. instead. The receiving software is responsible for discarding any extra
  485. packets that get through the hardware receive filters.
  486. If ResetMCastFilter is TRUE, then the multicast receive filter list
  487. on the network interface will be reset to the default multicast receive
  488. filter list. If ResetMCastFilter is FALSE, and this network interface
  489. allows the multicast receive filter list to be modified, then the
  490. MCastFilterCnt and MCastFilter are used to update the current multicast
  491. receive filter list. The modified receive filter list settings can be
  492. found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE.
  493. This routine calls ::ReceiveFilterUpdate to update the receive
  494. state in the network adapter.
  495. @param [in] pSimpleNetwork Protocol instance pointer
  496. @param [in] Enable A bit mask of receive filters to enable on the network interface.
  497. @param [in] Disable A bit mask of receive filters to disable on the network interface.
  498. For backward compatibility with EFI 1.1 platforms, the
  499. EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit must be set
  500. when the ResetMCastFilter parameter is TRUE.
  501. @param [in] bResetMCastFilter Set to TRUE to reset the contents of the multicast receive
  502. filters on the network interface to their default values.
  503. @param [in] MCastFilterCnt Number of multicast HW MAC address in the new MCastFilter list.
  504. This value must be less than or equal to the MaxMCastFilterCnt
  505. field of EFI_SIMPLE_NETWORK_MODE. This field is optional if
  506. ResetMCastFilter is TRUE.
  507. @param [in] pMCastFilter A pointer to a list of new multicast receive filter HW MAC
  508. addresses. This list will replace any existing multicast
  509. HW MAC address list. This field is optional if ResetMCastFilter
  510. is TRUE.
  511. @retval EFI_SUCCESS This operation was successful.
  512. @retval EFI_NOT_STARTED The network interface was not started.
  513. @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
  514. EFI_SIMPLE_NETWORK_PROTOCOL structure.
  515. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
  516. @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
  517. **/
  518. EFI_STATUS
  519. EFIAPI
  520. SN_ReceiveFilters (
  521. IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
  522. IN UINT32 Enable,
  523. IN UINT32 Disable,
  524. IN BOOLEAN bResetMCastFilter,
  525. IN UINTN MCastFilterCnt,
  526. IN EFI_MAC_ADDRESS * pMCastFilter
  527. )
  528. {
  529. EFI_SIMPLE_NETWORK_MODE * pMode;
  530. EFI_MAC_ADDRESS * pMulticastAddress;
  531. EFI_MAC_ADDRESS * pTableEnd;
  532. EFI_STATUS Status;
  533. DBG_ENTER ( );
  534. //
  535. // Verify the parameters
  536. //
  537. Status = EFI_INVALID_PARAMETER;
  538. if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
  539. pMode = pSimpleNetwork->Mode;
  540. //
  541. // Update the multicast list if necessary
  542. //
  543. if ( !bResetMCastFilter ) {
  544. if ( 0 != MCastFilterCnt ) {
  545. if (( MAX_MCAST_FILTER_CNT >= MCastFilterCnt )
  546. && ( NULL != pMCastFilter )) {
  547. //
  548. // Verify the multicast addresses
  549. //
  550. pMulticastAddress = pMCastFilter;
  551. pTableEnd = pMulticastAddress + MCastFilterCnt;
  552. while ( pTableEnd > pMulticastAddress ) {
  553. //
  554. // The first digit of the multicast address must have the LSB set
  555. //
  556. if ( 0 == ( pMulticastAddress->Addr[0] & 1 )) {
  557. //
  558. // Invalid multicast address
  559. //
  560. break;
  561. }
  562. pMulticastAddress += 1;
  563. }
  564. if ( pTableEnd == pMulticastAddress ) {
  565. //
  566. // Update the multicast filter list.
  567. //
  568. CopyMem (&pMode->MCastFilter[0],
  569. pMCastFilter,
  570. MCastFilterCnt * sizeof ( *pMCastFilter ));
  571. Status = EFI_SUCCESS;
  572. }
  573. }
  574. }
  575. else {
  576. Status = EFI_SUCCESS;
  577. }
  578. }
  579. else {
  580. //
  581. // No multicast address list is specified
  582. //
  583. MCastFilterCnt = 0;
  584. Status = EFI_SUCCESS;
  585. }
  586. if ( !EFI_ERROR ( Status )) {
  587. //
  588. // The parameters are valid!
  589. //
  590. pMode->ReceiveFilterSetting |= Enable;
  591. pMode->ReceiveFilterSetting &= ~Disable;
  592. pMode->MCastFilterCount = (UINT32)MCastFilterCnt;
  593. //
  594. // Update the receive filters in the adapter
  595. //
  596. Status = ReceiveFilterUpdate ( pSimpleNetwork );
  597. }
  598. }
  599. //
  600. // Return the operation status
  601. //
  602. DBG_EXIT_STATUS ( Status );
  603. return Status;
  604. }
  605. /**
  606. Reset the network adapter.
  607. Resets a network adapter and reinitializes it with the parameters that
  608. were provided in the previous call to Initialize (). The transmit and
  609. receive queues are cleared. Receive filters, the station address, the
  610. statistics, and the multicast-IP-to-HW MAC addresses are not reset by
  611. this call.
  612. This routine calls ::Ax88772Reset to perform the adapter specific
  613. reset operation. This routine also starts the link negotiation
  614. by calling ::Ax88772NegotiateLinkStart.
  615. @param [in] pSimpleNetwork Protocol instance pointer
  616. @param [in] bExtendedVerification Indicates that the driver may perform a more
  617. exhaustive verification operation of the device
  618. during reset.
  619. @retval EFI_SUCCESS This operation was successful.
  620. @retval EFI_NOT_STARTED The network interface was not started.
  621. @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
  622. EFI_SIMPLE_NETWORK_PROTOCOL structure.
  623. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
  624. @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
  625. **/
  626. EFI_STATUS
  627. EFIAPI
  628. SN_Reset (
  629. IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
  630. IN BOOLEAN bExtendedVerification
  631. )
  632. {
  633. EFI_SIMPLE_NETWORK_MODE * pMode;
  634. NIC_DEVICE * pNicDevice;
  635. RX_TX_PACKET * pRxPacket;
  636. EFI_STATUS Status;
  637. EFI_TPL TplPrevious;
  638. DBG_ENTER ( );
  639. //
  640. // Verify the parameters
  641. //
  642. if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
  643. //
  644. // Synchronize with Ax88772Timer
  645. //
  646. VERIFY_TPL ( TPL_AX88772 );
  647. TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
  648. //
  649. // Update the device state
  650. //
  651. pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
  652. pNicDevice->bComplete = FALSE;
  653. pNicDevice->bLinkUp = FALSE;
  654. pMode = pSimpleNetwork->Mode;
  655. pMode->MediaPresent = FALSE;
  656. //
  657. // Discard any received packets
  658. //
  659. while ( NULL != pNicDevice->pRxHead ) {
  660. //
  661. // Remove the packet from the received packet list
  662. //
  663. pRxPacket = pNicDevice->pRxHead;
  664. pNicDevice->pRxHead = pRxPacket->pNext;
  665. //
  666. // Queue the packet to the free list
  667. //
  668. pRxPacket->pNext = pNicDevice->pRxFree;
  669. pNicDevice->pRxFree = pRxPacket;
  670. }
  671. pNicDevice->pRxTail = NULL;
  672. //
  673. // Reset the device
  674. //
  675. Status = Ax88772Reset ( pNicDevice );
  676. if ( !EFI_ERROR ( Status )) {
  677. //
  678. // Update the receive filters in the adapter
  679. //
  680. Status = ReceiveFilterUpdate ( pSimpleNetwork );
  681. //
  682. // Try to get a connection to the network
  683. //
  684. if ( !EFI_ERROR ( Status )) {
  685. //
  686. // Start the autonegotiation
  687. //
  688. Status = Ax88772NegotiateLinkStart ( pNicDevice );
  689. }
  690. }
  691. //
  692. // Release the synchronization with Ax88772Timer
  693. //
  694. gBS->RestoreTPL ( TplPrevious );
  695. }
  696. else {
  697. Status = EFI_INVALID_PARAMETER;
  698. }
  699. //
  700. // Return the operation status
  701. //
  702. DBG_EXIT_STATUS ( Status );
  703. return Status;
  704. }
  705. /**
  706. Initialize the simple network protocol.
  707. This routine calls ::Ax88772MacAddressGet to obtain the
  708. MAC address.
  709. @param [in] pNicDevice NIC_DEVICE_INSTANCE pointer
  710. @retval EFI_SUCCESS Setup was successful
  711. **/
  712. EFI_STATUS
  713. SN_Setup (
  714. IN NIC_DEVICE * pNicDevice
  715. )
  716. {
  717. EFI_SIMPLE_NETWORK_MODE * pMode;
  718. EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork;
  719. EFI_STATUS Status;
  720. DBG_ENTER ( );
  721. //
  722. // Initialize the simple network protocol
  723. //
  724. pSimpleNetwork = &pNicDevice->SimpleNetwork;
  725. pSimpleNetwork->Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
  726. pSimpleNetwork->Start = (EFI_SIMPLE_NETWORK_START)SN_Start;
  727. pSimpleNetwork->Stop = (EFI_SIMPLE_NETWORK_STOP)SN_Stop;
  728. pSimpleNetwork->Initialize = (EFI_SIMPLE_NETWORK_INITIALIZE)SN_Initialize;
  729. pSimpleNetwork->Reset = (EFI_SIMPLE_NETWORK_RESET)SN_Reset;
  730. pSimpleNetwork->Shutdown = (EFI_SIMPLE_NETWORK_SHUTDOWN)SN_Shutdown;
  731. pSimpleNetwork->ReceiveFilters = (EFI_SIMPLE_NETWORK_RECEIVE_FILTERS)SN_ReceiveFilters;
  732. pSimpleNetwork->StationAddress = (EFI_SIMPLE_NETWORK_STATION_ADDRESS)SN_StationAddress;
  733. pSimpleNetwork->Statistics = (EFI_SIMPLE_NETWORK_STATISTICS)SN_Statistics;
  734. pSimpleNetwork->MCastIpToMac = (EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC)SN_MCastIPtoMAC;
  735. pSimpleNetwork->NvData = (EFI_SIMPLE_NETWORK_NVDATA)SN_NvData;
  736. pSimpleNetwork->GetStatus = (EFI_SIMPLE_NETWORK_GET_STATUS)SN_GetStatus;
  737. pSimpleNetwork->Transmit = (EFI_SIMPLE_NETWORK_TRANSMIT)SN_Transmit;
  738. pSimpleNetwork->Receive = (EFI_SIMPLE_NETWORK_RECEIVE)SN_Receive;
  739. pSimpleNetwork->WaitForPacket = NULL;
  740. pMode = &pNicDevice->SimpleNetworkData;
  741. pSimpleNetwork->Mode = pMode;
  742. pMode->State = EfiSimpleNetworkStopped;
  743. pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
  744. pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
  745. pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
  746. pMode->NvRamSize = 0;
  747. pMode->NvRamAccessSize = 0;
  748. pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
  749. | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
  750. | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
  751. | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
  752. | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
  753. pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
  754. | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
  755. pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
  756. pMode->MCastFilterCount = 0;
  757. SetMem ( &pMode->BroadcastAddress,
  758. PXE_HWADDR_LEN_ETHER,
  759. 0xff );
  760. pMode->IfType = EfiNetworkInterfaceUndi;
  761. pMode->MacAddressChangeable = TRUE;
  762. pMode->MultipleTxSupported = TRUE;
  763. pMode->MediaPresentSupported = TRUE;
  764. pMode->MediaPresent = FALSE;
  765. //
  766. // Read the MAC address
  767. //
  768. pNicDevice->PhyId = PHY_ID_INTERNAL;
  769. pNicDevice->b100Mbps = TRUE;
  770. pNicDevice->bFullDuplex = TRUE;
  771. Status = gBS->AllocatePool ( EfiRuntimeServicesData,
  772. MAX_BULKIN_SIZE,
  773. (VOID **) &pNicDevice->pBulkInBuff);
  774. if ( EFI_ERROR(Status)) {
  775. DEBUG (( EFI_D_ERROR, "Memory are not enough\n"));
  776. return Status;
  777. }
  778. Status = Ax88772MacAddressGet (
  779. pNicDevice,
  780. &pMode->PermanentAddress.Addr[0]);
  781. if ( !EFI_ERROR ( Status )) {
  782. //
  783. // Display the MAC address
  784. //
  785. DEBUG (( DEBUG_MAC_ADDRESS | DEBUG_INFO,
  786. "MAC: %02x-%02x-%02x-%02x-%02x-%02x\n",
  787. pMode->PermanentAddress.Addr[0],
  788. pMode->PermanentAddress.Addr[1],
  789. pMode->PermanentAddress.Addr[2],
  790. pMode->PermanentAddress.Addr[3],
  791. pMode->PermanentAddress.Addr[4],
  792. pMode->PermanentAddress.Addr[5]));
  793. //
  794. // Use the hardware address as the current address
  795. //
  796. CopyMem ( &pMode->CurrentAddress,
  797. &pMode->PermanentAddress,
  798. PXE_HWADDR_LEN_ETHER );
  799. }
  800. //
  801. // Return the setup status
  802. //
  803. DBG_EXIT_STATUS ( Status );
  804. return Status;
  805. }
  806. /**
  807. This routine starts the network interface.
  808. @param [in] pSimpleNetwork Protocol instance pointer
  809. @retval EFI_SUCCESS This operation was successful.
  810. @retval EFI_ALREADY_STARTED The network interface was already started.
  811. @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
  812. EFI_SIMPLE_NETWORK_PROTOCOL structure.
  813. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
  814. @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
  815. **/
  816. EFI_STATUS
  817. EFIAPI
  818. SN_Start (
  819. IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
  820. )
  821. {
  822. NIC_DEVICE * pNicDevice;
  823. EFI_SIMPLE_NETWORK_MODE * pMode;
  824. EFI_STATUS Status;
  825. DBG_ENTER ( );
  826. //
  827. // Verify the parameters
  828. //
  829. Status = EFI_INVALID_PARAMETER;
  830. if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
  831. pMode = pSimpleNetwork->Mode;
  832. if ( EfiSimpleNetworkStopped == pMode->State ) {
  833. //
  834. // Initialize the mode structure
  835. // NVRAM access is not supported
  836. //
  837. ZeroMem ( pMode, sizeof ( *pMode ));
  838. pMode->State = EfiSimpleNetworkStarted;
  839. pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
  840. pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
  841. pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
  842. pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
  843. | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
  844. | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
  845. | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
  846. | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
  847. pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
  848. pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
  849. pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
  850. Status = Ax88772MacAddressGet ( pNicDevice, &pMode->PermanentAddress.Addr[0]);
  851. CopyMem ( &pMode->CurrentAddress,
  852. &pMode->PermanentAddress,
  853. sizeof ( pMode->CurrentAddress ));
  854. pMode->BroadcastAddress.Addr[0] = 0xff;
  855. pMode->BroadcastAddress.Addr[1] = 0xff;
  856. pMode->BroadcastAddress.Addr[2] = 0xff;
  857. pMode->BroadcastAddress.Addr[3] = 0xff;
  858. pMode->BroadcastAddress.Addr[4] = 0xff;
  859. pMode->BroadcastAddress.Addr[5] = 0xff;
  860. pMode->IfType = 1;
  861. pMode->MacAddressChangeable = TRUE;
  862. pMode->MultipleTxSupported = TRUE;
  863. pMode->MediaPresentSupported = TRUE;
  864. pMode->MediaPresent = FALSE;
  865. }
  866. else {
  867. Status = EFI_ALREADY_STARTED;
  868. }
  869. }
  870. //
  871. // Return the operation status
  872. //
  873. DBG_EXIT_STATUS ( Status );
  874. return Status;
  875. }
  876. /**
  877. Set the MAC address.
  878. This function modifies or resets the current station address of a
  879. network interface. If Reset is TRUE, then the current station address
  880. is set ot the network interface's permanent address. If Reset if FALSE
  881. then the current station address is changed to the address specified by
  882. pNew.
  883. This routine calls ::Ax88772MacAddressSet to update the MAC address
  884. in the network adapter.
  885. @param [in] pSimpleNetwork Protocol instance pointer
  886. @param [in] bReset Flag used to reset the station address to the
  887. network interface's permanent address.
  888. @param [in] pNew New station address to be used for the network
  889. interface.
  890. @retval EFI_SUCCESS This operation was successful.
  891. @retval EFI_NOT_STARTED The network interface was not started.
  892. @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
  893. EFI_SIMPLE_NETWORK_PROTOCOL structure.
  894. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
  895. @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
  896. **/
  897. EFI_STATUS
  898. EFIAPI
  899. SN_StationAddress (
  900. IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
  901. IN BOOLEAN bReset,
  902. IN EFI_MAC_ADDRESS * pNew
  903. )
  904. {
  905. NIC_DEVICE * pNicDevice;
  906. EFI_SIMPLE_NETWORK_MODE * pMode;
  907. EFI_STATUS Status;
  908. DBG_ENTER ( );
  909. //
  910. // Verify the parameters
  911. //
  912. if (( NULL != pSimpleNetwork )
  913. && ( NULL != pSimpleNetwork->Mode )
  914. && (( !bReset ) || ( bReset && ( NULL != pNew )))) {
  915. //
  916. // Verify that the adapter is already started
  917. //
  918. pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
  919. pMode = pSimpleNetwork->Mode;
  920. if ( EfiSimpleNetworkStarted == pMode->State ) {
  921. //
  922. // Determine the adapter MAC address
  923. //
  924. if ( bReset ) {
  925. //
  926. // Use the permanent address
  927. //
  928. CopyMem ( &pMode->CurrentAddress,
  929. &pMode->PermanentAddress,
  930. sizeof ( pMode->CurrentAddress ));
  931. }
  932. else {
  933. //
  934. // Use the specified address
  935. //
  936. CopyMem ( &pMode->CurrentAddress,
  937. pNew,
  938. sizeof ( pMode->CurrentAddress ));
  939. }
  940. //
  941. // Update the address on the adapter
  942. //
  943. Status = Ax88772MacAddressSet ( pNicDevice, &pMode->CurrentAddress.Addr[0]);
  944. }
  945. else {
  946. Status = EFI_NOT_STARTED;
  947. }
  948. }
  949. else {
  950. Status = EFI_INVALID_PARAMETER;
  951. }
  952. //
  953. // Return the operation status
  954. //
  955. DBG_EXIT_STATUS ( Status );
  956. return Status;
  957. }
  958. /**
  959. This function resets or collects the statistics on a network interface.
  960. If the size of the statistics table specified by StatisticsSize is not
  961. big enough for all of the statistics that are collected by the network
  962. interface, then a partial buffer of statistics is returned in
  963. StatisticsTable.
  964. @param [in] pSimpleNetwork Protocol instance pointer
  965. @param [in] bReset Set to TRUE to reset the statistics for the network interface.
  966. @param [in, out] pStatisticsSize On input the size, in bytes, of StatisticsTable. On output
  967. the size, in bytes, of the resulting table of statistics.
  968. @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
  969. conains the statistics.
  970. @retval EFI_SUCCESS This operation was successful.
  971. @retval EFI_NOT_STARTED The network interface was not started.
  972. @retval EFI_BUFFER_TOO_SMALL The pStatisticsTable is NULL or the buffer is too small.
  973. @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
  974. EFI_SIMPLE_NETWORK_PROTOCOL structure.
  975. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
  976. @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
  977. **/
  978. EFI_STATUS
  979. EFIAPI
  980. SN_Statistics (
  981. IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
  982. IN BOOLEAN bReset,
  983. IN OUT UINTN * pStatisticsSize,
  984. OUT EFI_NETWORK_STATISTICS * pStatisticsTable
  985. )
  986. {
  987. EFI_STATUS Status;
  988. DBG_ENTER ( );
  989. //
  990. // This is not currently supported
  991. //
  992. Status = EFI_UNSUPPORTED;
  993. //
  994. // Return the operation status
  995. //
  996. DBG_EXIT_STATUS ( Status );
  997. return Status;
  998. }
  999. /**
  1000. This function stops a network interface. This call is only valid
  1001. if the network interface is in the started state.
  1002. @param [in] pSimpleNetwork Protocol instance pointer
  1003. @retval EFI_SUCCESS This operation was successful.
  1004. @retval EFI_NOT_STARTED The network interface was not started.
  1005. @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
  1006. EFI_SIMPLE_NETWORK_PROTOCOL structure.
  1007. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
  1008. @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
  1009. **/
  1010. EFI_STATUS
  1011. EFIAPI
  1012. SN_Stop (
  1013. IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
  1014. )
  1015. {
  1016. EFI_SIMPLE_NETWORK_MODE * pMode;
  1017. EFI_STATUS Status;
  1018. DBG_ENTER ( );
  1019. //
  1020. // Verify the parameters
  1021. //
  1022. if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
  1023. //
  1024. // Determine if the interface is started
  1025. //
  1026. pMode = pSimpleNetwork->Mode;
  1027. if ( EfiSimpleNetworkStopped != pMode->State ) {
  1028. if ( EfiSimpleNetworkStarted == pMode->State ) {
  1029. //
  1030. // Release the resources acquired in SN_Start
  1031. //
  1032. //
  1033. // Mark the adapter as stopped
  1034. //
  1035. pMode->State = EfiSimpleNetworkStopped;
  1036. Status = EFI_SUCCESS;
  1037. }
  1038. else {
  1039. Status = EFI_UNSUPPORTED;
  1040. }
  1041. }
  1042. else {
  1043. Status = EFI_NOT_STARTED;
  1044. }
  1045. }
  1046. else {
  1047. Status = EFI_INVALID_PARAMETER;
  1048. }
  1049. //
  1050. // Return the operation status
  1051. //
  1052. DBG_EXIT_STATUS ( Status );
  1053. return Status;
  1054. }
  1055. /**
  1056. This function releases the memory buffers assigned in the Initialize() call.
  1057. Pending transmits and receives are lost, and interrupts are cleared and disabled.
  1058. After this call, only Initialize() and Stop() calls may be used.
  1059. @param [in] pSimpleNetwork Protocol instance pointer
  1060. @retval EFI_SUCCESS This operation was successful.
  1061. @retval EFI_NOT_STARTED The network interface was not started.
  1062. @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
  1063. EFI_SIMPLE_NETWORK_PROTOCOL structure.
  1064. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
  1065. @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
  1066. **/
  1067. EFI_STATUS
  1068. EFIAPI
  1069. SN_Shutdown (
  1070. IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
  1071. )
  1072. {
  1073. EFI_SIMPLE_NETWORK_MODE * pMode;
  1074. UINT32 RxFilter;
  1075. EFI_STATUS Status;
  1076. DBG_ENTER ( );
  1077. //
  1078. // Verify the parameters
  1079. //
  1080. if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
  1081. //
  1082. // Determine if the interface is already started
  1083. //
  1084. pMode = pSimpleNetwork->Mode;
  1085. if ( EfiSimpleNetworkInitialized == pMode->State ) {
  1086. //
  1087. // Stop the adapter
  1088. //
  1089. RxFilter = pMode->ReceiveFilterSetting;
  1090. pMode->ReceiveFilterSetting = 0;
  1091. Status = SN_Reset ( pSimpleNetwork, FALSE );
  1092. pMode->ReceiveFilterSetting = RxFilter;
  1093. if ( !EFI_ERROR ( Status )) {
  1094. //
  1095. // Release the resources acquired by SN_Initialize
  1096. //
  1097. //
  1098. // Update the network state
  1099. //
  1100. pMode->State = EfiSimpleNetworkStarted;
  1101. }
  1102. }
  1103. else {
  1104. Status = EFI_NOT_STARTED;
  1105. }
  1106. }
  1107. else {
  1108. Status = EFI_INVALID_PARAMETER;
  1109. }
  1110. //
  1111. // Return the operation status
  1112. //
  1113. DBG_EXIT_STATUS ( Status );
  1114. return Status;
  1115. }
  1116. /**
  1117. Send a packet over the network.
  1118. This function places the packet specified by Header and Buffer on
  1119. the transmit queue. This function performs a non-blocking transmit
  1120. operation. When the transmit is complete, the buffer is returned
  1121. via the GetStatus() call.
  1122. This routine calls ::Ax88772Rx to empty the network adapter of
  1123. receive packets. The routine then passes the transmit packet
  1124. to the network adapter.
  1125. @param [in] pSimpleNetwork Protocol instance pointer
  1126. @param [in] HeaderSize The size, in bytes, of the media header to be filled in by
  1127. the Transmit() function. If HeaderSize is non-zero, then
  1128. it must be equal to SimpleNetwork->Mode->MediaHeaderSize
  1129. and DestAddr and Protocol parameters must not be NULL.
  1130. @param [in] BufferSize The size, in bytes, of the entire packet (media header and
  1131. data) to be transmitted through the network interface.
  1132. @param [in] pBuffer A pointer to the packet (media header followed by data) to
  1133. to be transmitted. This parameter can not be NULL. If
  1134. HeaderSize is zero, then the media header is Buffer must
  1135. already be filled in by the caller. If HeaderSize is nonzero,
  1136. then the media header will be filled in by the Transmit()
  1137. function.
  1138. @param [in] pSrcAddr The source HW MAC address. If HeaderSize is zero, then
  1139. this parameter is ignored. If HeaderSize is nonzero and
  1140. SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
  1141. is used for the source HW MAC address.
  1142. @param [in] pDestAddr The destination HW MAC address. If HeaderSize is zero, then
  1143. this parameter is ignored.
  1144. @param [in] pProtocol The type of header to build. If HeaderSize is zero, then
  1145. this parameter is ignored.
  1146. @retval EFI_SUCCESS This operation was successful.
  1147. @retval EFI_NOT_STARTED The network interface was not started.
  1148. @retval EFI_NOT_READY The network interface is too busy to accept this transmit request.
  1149. @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
  1150. @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
  1151. EFI_SIMPLE_NETWORK_PROTOCOL structure.
  1152. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
  1153. **/
  1154. EFI_STATUS
  1155. EFIAPI
  1156. SN_Transmit (
  1157. IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
  1158. IN UINTN HeaderSize,
  1159. IN UINTN BufferSize,
  1160. IN VOID * pBuffer,
  1161. IN EFI_MAC_ADDRESS * pSrcAddr,
  1162. IN EFI_MAC_ADDRESS * pDestAddr,
  1163. IN UINT16 * pProtocol
  1164. )
  1165. {
  1166. RX_TX_PACKET Packet;
  1167. ETHERNET_HEADER * pHeader;
  1168. EFI_SIMPLE_NETWORK_MODE * pMode;
  1169. NIC_DEVICE * pNicDevice;
  1170. EFI_USB_IO_PROTOCOL * pUsbIo;
  1171. EFI_STATUS Status;
  1172. EFI_TPL TplPrevious;
  1173. UINTN TransferLength;
  1174. UINT32 TransferStatus;
  1175. UINT16 Type;
  1176. DBG_ENTER ( );
  1177. //
  1178. // Verify the parameters
  1179. //
  1180. if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
  1181. //
  1182. // The interface must be running
  1183. //
  1184. pMode = pSimpleNetwork->Mode;
  1185. if ( EfiSimpleNetworkInitialized == pMode->State ) {
  1186. //
  1187. // Synchronize with Ax88772Timer
  1188. //
  1189. VERIFY_TPL ( TPL_AX88772 );
  1190. TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
  1191. //
  1192. // Update the link status
  1193. //
  1194. pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
  1195. //
  1196. //No need to call receive to receive packet
  1197. //
  1198. //Ax88772Rx ( pNicDevice, FALSE );
  1199. pMode->MediaPresent = pNicDevice->bLinkUp;
  1200. //
  1201. // Release the synchronization with Ax88772Timer
  1202. //
  1203. gBS->RestoreTPL ( TplPrevious );
  1204. if ( pMode->MediaPresent ) {
  1205. //
  1206. // Copy the packet into the USB buffer
  1207. //
  1208. CopyMem ( &Packet.Data[0], pBuffer, BufferSize );
  1209. Packet.Length = (UINT16) BufferSize;
  1210. //
  1211. // Transmit the packet
  1212. //
  1213. pHeader = (ETHERNET_HEADER *) &Packet.Data[0];
  1214. if ( 0 != HeaderSize ) {
  1215. if ( NULL != pDestAddr ) {
  1216. CopyMem ( &pHeader->dest_addr, pDestAddr, PXE_HWADDR_LEN_ETHER );
  1217. }
  1218. if ( NULL != pSrcAddr ) {
  1219. CopyMem ( &pHeader->src_addr, pSrcAddr, PXE_HWADDR_LEN_ETHER );
  1220. }
  1221. else {
  1222. CopyMem ( &pHeader->src_addr, &pMode->CurrentAddress.Addr[0], PXE_HWADDR_LEN_ETHER );
  1223. }
  1224. if ( NULL != pProtocol ) {
  1225. Type = *pProtocol;
  1226. }
  1227. else {
  1228. Type = Packet.Length;
  1229. }
  1230. Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
  1231. pHeader->type = Type;
  1232. }
  1233. if ( Packet.Length < MIN_ETHERNET_PKT_SIZE ) {
  1234. Packet.Length = MIN_ETHERNET_PKT_SIZE;
  1235. ZeroMem ( &Packet.Data[ BufferSize ],
  1236. Packet.Length - BufferSize );
  1237. }
  1238. DEBUG (( DEBUG_TX | DEBUG_INFO,
  1239. "TX: %02x-%02x-%02x-%02x-%02x-%02x %02x-%02x-%02x-%02x-%02x-%02x %02x-%02x %d bytes\r\n",
  1240. Packet.Data[0],
  1241. Packet.Data[1],
  1242. Packet.Data[2],
  1243. Packet.Data[3],
  1244. Packet.Data[4],
  1245. Packet.Data[5],
  1246. Packet.Data[6],
  1247. Packet.Data[7],
  1248. Packet.Data[8],
  1249. Packet.Data[9],
  1250. Packet.Data[10],
  1251. Packet.Data[11],
  1252. Packet.Data[12],
  1253. Packet.Data[13],
  1254. Packet.Length ));
  1255. Packet.LengthBar = ~Packet.Length;
  1256. TransferLength = sizeof ( Packet.Length )
  1257. + sizeof ( Packet.LengthBar )
  1258. + Packet.Length;
  1259. //
  1260. // Work around USB bus driver bug where a timeout set by receive
  1261. // succeeds but the timeout expires immediately after, causing the
  1262. // transmit operation to timeout.
  1263. //
  1264. pUsbIo = pNicDevice->pUsbIo;
  1265. Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
  1266. BULK_OUT_ENDPOINT,
  1267. &Packet.Length,
  1268. &TransferLength,
  1269. 0xfffffffe,
  1270. &TransferStatus );
  1271. if ( !EFI_ERROR ( Status )) {
  1272. Status = TransferStatus;
  1273. }
  1274. if (( !EFI_ERROR ( Status ))
  1275. && ( TransferLength != (UINTN)( Packet.Length + 4 ))) {
  1276. Status = EFI_WARN_WRITE_FAILURE;
  1277. }
  1278. if ( EFI_SUCCESS == Status ) {
  1279. pNicDevice->pTxBuffer = pBuffer;
  1280. }
  1281. else {
  1282. DEBUG (( DEBUG_ERROR | DEBUG_INFO,
  1283. "Ax88772 USB transmit error, TransferLength: %d, Status: %r\r\n",
  1284. sizeof ( Packet.Length ) + Packet.Length,
  1285. Status ));
  1286. //
  1287. // Reset the controller to fix the error
  1288. //
  1289. if ( EFI_DEVICE_ERROR == Status ) {
  1290. SN_Reset ( pSimpleNetwork, FALSE );
  1291. }
  1292. }
  1293. }
  1294. else {
  1295. //
  1296. // No packets available.
  1297. //
  1298. Status = EFI_NOT_READY;
  1299. }
  1300. }
  1301. else {
  1302. Status = EFI_NOT_STARTED;
  1303. }
  1304. }
  1305. else {
  1306. DEBUG (( DEBUG_ERROR | DEBUG_INFO,
  1307. "Ax88772 invalid transmit parameter\r\n"
  1308. " 0x%08x: HeaderSize\r\n"
  1309. " 0x%08x: BufferSize\r\n"
  1310. " 0x%08x: Buffer\r\n"
  1311. " 0x%08x: SrcAddr\r\n"
  1312. " 0x%08x: DestAddr\r\n"
  1313. " 0x%04x: Protocol\r\n",
  1314. HeaderSize,
  1315. BufferSize,
  1316. pBuffer,
  1317. pSrcAddr,
  1318. pDestAddr,
  1319. pProtocol ));
  1320. Status = EFI_INVALID_PARAMETER;
  1321. }
  1322. //
  1323. // Return the operation status
  1324. //
  1325. DBG_EXIT_STATUS ( Status );
  1326. return Status;
  1327. }