SimpleNetwork.c 55 KB

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