SimpleNetwork.c 58 KB

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