]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Csm/BiosThunk/Snp16Dxe/BiosSnp16.c
Enhance the error handling.
[mirror_edk2.git] / IntelFrameworkModulePkg / Csm / BiosThunk / Snp16Dxe / BiosSnp16.c
CommitLineData
bcecde14 1/** @file\r
2\r
3Copyright (c) 1999 - 2010, Intel Corporation. All rights reserved.<BR>\r
4\r
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions\r
7of the BSD License which accompanies this distribution. The\r
8full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "BiosSnp16.h"\r
17\r
18\r
19///\r
20/// EFI Driver Binding Protocol Instance\r
21///\r
22EFI_DRIVER_BINDING_PROTOCOL gBiosSnp16DriverBinding = {\r
23 BiosSnp16DriverBindingSupported,\r
24 BiosSnp16DriverBindingStart,\r
25 BiosSnp16DriverBindingStop,\r
26 0x3,\r
27 NULL,\r
28 NULL\r
29};\r
30\r
31///\r
32/// This boolean is used to determine if we should release the cached vector during an error condition.\r
33///\r
34BOOLEAN mCachedInt1A = FALSE;\r
35\r
36//\r
37// Private worker functions;\r
38//\r
39\r
40/**\r
41 Start the UNDI interface.\r
42\r
43 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.\r
44 @param Ax PCI address of Undi device.\r
45 \r
46 @retval EFI_DEVICE_ERROR Fail to start 16 bit UNDI ROM. \r
47 @retval Others Status of start 16 bit UNDI ROM. \r
48**/\r
49EFI_STATUS\r
50Undi16SimpleNetworkStartUndi (\r
51 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice,\r
52 UINT16 Ax\r
53 );\r
54\r
55/**\r
56 Start the UNDI interface\r
57\r
58 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.\r
59 \r
60 @retval EFI_DEVICE_ERROR Fail to start 16 bit UNDI ROM. \r
61 @retval Others Status of start 16 bit UNDI ROM. \r
62**/\r
63EFI_STATUS\r
64Undi16SimpleNetworkStopUndi (\r
65 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice\r
66 );\r
67\r
68/**\r
69 Stop the UNDI interface\r
70\r
71 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.\r
72 \r
73 @retval EFI_DEVICE_ERROR Fail to stop 16 bit UNDI ROM. \r
74 @retval Others Status of stop 16 bit UNDI ROM. \r
75**/\r
76EFI_STATUS\r
77Undi16SimpleNetworkCleanupUndi (\r
78 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice\r
79 );\r
80\r
81/**\r
82 Get runtime information for Undi network interface\r
83\r
84 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
85 \r
86 @retval EFI_SUCCESS Sucess operation. \r
87 @retval Others Fail to get runtime information for Undi network interface. \r
88**/\r
89EFI_STATUS\r
90Undi16SimpleNetworkGetInformation (\r
91 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
92 );\r
93\r
94/**\r
95 Get NIC type\r
96\r
97 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
98 \r
99 @retval EFI_SUCCESS Sucess operation. \r
100 @retval Others Fail to get NIC type.\r
101**/\r
102EFI_STATUS\r
103Undi16SimpleNetworkGetNicType (\r
104 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
105 );\r
106\r
107/**\r
108 Get NDIS information\r
109\r
110 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
111 \r
112 @retval EFI_SUCCESS Sucess operation. \r
113 @retval Others Fail to get NDIS information.\r
114**/\r
115EFI_STATUS\r
116Undi16SimpleNetworkGetNdisInfo (\r
117 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
118 );\r
119\r
120/**\r
121 Signal handlers for ExitBootServices event.\r
122 \r
123 Clean up any Real-mode UNDI residue from the system \r
124 \r
125 @param Event ExitBootServices event\r
126 @param Context \r
127**/\r
128VOID\r
129EFIAPI\r
130Undi16SimpleNetworkEvent (\r
131 IN EFI_EVENT Event,\r
132 IN VOID *Context\r
133 );\r
134\r
135/**\r
136 Loads the undi driver.\r
137\r
138 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.\r
139 \r
140 @retval EFI_SUCCESS - Successfully loads undi driver.\r
141 @retval EFI_NOT_FOUND - Doesn't find undi driver or undi driver load failure.\r
142**/\r
143EFI_STATUS\r
144Undi16SimpleNetworkLoadUndi (\r
145 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice\r
146 );\r
147\r
148/**\r
149 Unload 16 bit UNDI Option ROM from memory\r
150\r
151 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.\r
152 \r
153 @return EFI_STATUS \r
154**/\r
155EFI_STATUS\r
156Undi16SimpleNetworkUnloadUndi (\r
157 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice\r
158 );\r
159\r
160/**\r
161 Entry point for EFI drivers.\r
162\r
163 @param ImageHandle Handle that identifies the loaded image.\r
164 @param SystemTable System Table for this image.\r
165 \r
166 @return EFI_STATUS Return status from EfiLibInstallAllDriverProtocols. \r
167**/\r
168EFI_STATUS\r
169EFIAPI\r
170BiosSnp16DriverEntryPoint (\r
171 IN EFI_HANDLE ImageHandle,\r
172 IN EFI_SYSTEM_TABLE *SystemTable\r
173 )\r
174{\r
175 return EfiLibInstallDriverBindingComponentName2 (\r
176 ImageHandle,\r
177 SystemTable,\r
178 &gBiosSnp16DriverBinding,\r
179 ImageHandle,\r
180 &gBiosSnp16ComponentName,\r
181 &gBiosSnp16ComponentName2\r
182 );\r
183}\r
184\r
185//\r
186// EFI Driver Binding Protocol Functions\r
187//\r
188/**\r
189 Tests to see if this driver supports a given controller.\r
190\r
191 @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
192 @param Controller The handle of the controller to test.\r
193 @param RemainingDevicePath A pointer to the remaining portion of a device path.\r
194 \r
195 @retval EFI_SUCCESS The driver supports given controller.\r
196 @retval EFI_UNSUPPORT The driver doesn't support given controller.\r
197 @retval Other Other errors prevent driver finishing to test\r
198 if the driver supports given controller.\r
199**/\r
200EFI_STATUS\r
201EFIAPI\r
202BiosSnp16DriverBindingSupported (\r
203 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
204 IN EFI_HANDLE Controller,\r
205 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
206 )\r
207{\r
208 EFI_STATUS Status;\r
209 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;\r
210 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
211 EFI_PCI_IO_PROTOCOL *PciIo;\r
212 PCI_TYPE00 Pci;\r
213\r
214 //\r
215 // See if the Legacy BIOS Protocol is available\r
216 //\r
217 Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);\r
218 if (EFI_ERROR (Status)) {\r
219 return Status;\r
220 }\r
221 //\r
222 // Open the IO Abstraction(s) needed to perform the supported test\r
223 //\r
224 Status = gBS->OpenProtocol (\r
225 Controller,\r
226 &gEfiDevicePathProtocolGuid,\r
227 (VOID **) &DevicePath,\r
228 This->DriverBindingHandle,\r
229 Controller,\r
230 EFI_OPEN_PROTOCOL_BY_DRIVER\r
231 );\r
232 if (EFI_ERROR (Status)) {\r
233 return Status;\r
234 }\r
235\r
236 gBS->CloseProtocol (\r
237 Controller,\r
238 &gEfiDevicePathProtocolGuid,\r
239 This->DriverBindingHandle,\r
240 Controller\r
241 );\r
242\r
243 //\r
244 // Open the IO Abstraction(s) needed to perform the supported test\r
245 //\r
246 Status = gBS->OpenProtocol (\r
247 Controller,\r
248 &gEfiPciIoProtocolGuid,\r
249 (VOID **) &PciIo,\r
250 This->DriverBindingHandle,\r
251 Controller,\r
252 EFI_OPEN_PROTOCOL_BY_DRIVER\r
253 );\r
254 if (EFI_ERROR (Status)) {\r
255 return Status;\r
256 }\r
257 //\r
258 // See if this is a PCI Network Controller by looking at the Command register and\r
259 // Class Code Register\r
260 //\r
261 Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0, sizeof (Pci) / sizeof (UINT32), &Pci);\r
262 if (EFI_ERROR (Status)) {\r
263 Status = EFI_UNSUPPORTED;\r
264 goto Done;\r
265 }\r
266\r
267 Status = EFI_UNSUPPORTED;\r
268 if (Pci.Hdr.ClassCode[2] == PCI_CLASS_NETWORK) {\r
269 Status = EFI_SUCCESS;\r
270 }\r
271\r
272Done:\r
273 gBS->CloseProtocol (\r
274 Controller,\r
275 &gEfiPciIoProtocolGuid,\r
276 This->DriverBindingHandle,\r
277 Controller\r
278 );\r
279\r
280 return Status;\r
281}\r
282\r
283/**\r
284 Starts the Snp device controller\r
285\r
286 @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
287 @param Controller The handle of the controller to test.\r
288 @param RemainingDevicePath A pointer to the remaining portion of a device path.\r
289 \r
290 @retval EFI_SUCCESS - The device was started. \r
291 @retval EFI_DEVICE_ERROR - The device could not be started due to a device error.\r
292 @retval EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources.\r
293**/\r
294EFI_STATUS\r
295EFIAPI\r
296BiosSnp16DriverBindingStart (\r
297 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
298 IN EFI_HANDLE Controller,\r
299 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
300 )\r
301{\r
302 EFI_STATUS Status;\r
303 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;\r
304 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
305 EFI_PCI_IO_PROTOCOL *PciIo;\r
306 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
307 EFI_DEV_PATH Node;\r
308 UINTN Index;\r
309 UINTN Index2;\r
310 UINTN Segment;\r
311 UINTN Bus;\r
312 UINTN Device;\r
313 UINTN Function;\r
314 UINTN Flags;\r
315 UINT64 Supports;\r
316\r
317 SimpleNetworkDevice = NULL;\r
318 PciIo = NULL;\r
319\r
320 //\r
321 // See if the Legacy BIOS Protocol is available\r
322 //\r
323 Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);\r
324 if (EFI_ERROR (Status)) {\r
325 return Status;\r
326 }\r
327 //\r
328 // Open the IO Abstraction(s) needed\r
329 //\r
330 Status = gBS->OpenProtocol (\r
331 Controller,\r
332 &gEfiDevicePathProtocolGuid,\r
333 (VOID **) &DevicePath,\r
334 This->DriverBindingHandle,\r
335 Controller,\r
336 EFI_OPEN_PROTOCOL_BY_DRIVER\r
337 );\r
338 if (EFI_ERROR (Status)) {\r
339 goto Done;\r
340 }\r
341\r
342 Status = gBS->OpenProtocol (\r
343 Controller,\r
344 &gEfiPciIoProtocolGuid,\r
345 (VOID **) &PciIo,\r
346 This->DriverBindingHandle,\r
347 Controller,\r
348 EFI_OPEN_PROTOCOL_BY_DRIVER\r
349 );\r
350 if (EFI_ERROR (Status)) {\r
351 goto Done;\r
352 }\r
353\r
354 Status = PciIo->Attributes (\r
355 PciIo,\r
356 EfiPciIoAttributeOperationSupported,\r
357 0,\r
358 &Supports\r
359 );\r
360 if (!EFI_ERROR (Status)) {\r
361 Supports &= EFI_PCI_DEVICE_ENABLE;\r
362 Status = PciIo->Attributes (\r
363 PciIo,\r
364 EfiPciIoAttributeOperationEnable,\r
365 Supports,\r
366 NULL\r
367 );\r
368 }\r
369\r
370 if (EFI_ERROR (Status)) {\r
371 goto Done;\r
372 }\r
373 //\r
374 // Check to see if there is a legacy option ROM image associated with this PCI device\r
375 //\r
376 Status = LegacyBios->CheckPciRom (\r
377 LegacyBios,\r
378 Controller,\r
379 NULL,\r
380 NULL,\r
381 &Flags\r
382 );\r
383 if (EFI_ERROR (Status)) {\r
384 goto Done;\r
385 }\r
386 //\r
387 // Post the legacy option ROM if it is available.\r
388 //\r
389 Status = LegacyBios->InstallPciRom (\r
390 LegacyBios,\r
391 Controller,\r
392 NULL,\r
393 &Flags,\r
394 NULL,\r
395 NULL,\r
396 NULL,\r
397 NULL\r
398 );\r
399 if (EFI_ERROR (Status)) {\r
400 goto Done;\r
401 }\r
402 //\r
403 // Allocate memory for this SimpleNetwork device instance\r
404 //\r
405 Status = gBS->AllocatePool (\r
406 EfiBootServicesData,\r
407 sizeof (EFI_SIMPLE_NETWORK_DEV),\r
408 (VOID **) &SimpleNetworkDevice\r
409 );\r
410 if (EFI_ERROR (Status)) {\r
411 Status = EFI_OUT_OF_RESOURCES;\r
412 goto Done;\r
413 }\r
414\r
415 ZeroMem (SimpleNetworkDevice, sizeof (EFI_SIMPLE_NETWORK_DEV));\r
416\r
417 //\r
418 // Initialize the SimpleNetwork device instance\r
419 //\r
420 SimpleNetworkDevice->Signature = EFI_SIMPLE_NETWORK_DEV_SIGNATURE;\r
421 SimpleNetworkDevice->LegacyBios = LegacyBios;\r
422 SimpleNetworkDevice->BaseDevicePath = DevicePath;\r
423 SimpleNetworkDevice->PciIo = PciIo;\r
424\r
425 //\r
426 // Initialize the Nii Protocol\r
427 //\r
428 SimpleNetworkDevice->Nii.Revision = EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION;\r
429 SimpleNetworkDevice->Nii.Type = EfiNetworkInterfaceUndi;\r
430\r
431 CopyMem (&SimpleNetworkDevice->Nii.StringId, "UNDI", 4);\r
432\r
433 //\r
434 // Load 16 bit UNDI Option ROM into Memory\r
435 //\r
436 Status = Undi16SimpleNetworkLoadUndi (SimpleNetworkDevice);\r
437 if (EFI_ERROR (Status)) {\r
438 DEBUG ((DEBUG_NET, "ERROR : Could not load UNDI. Status = %r\n", Status));\r
439 goto Done;\r
440 }\r
441\r
442 SimpleNetworkDevice->UndiLoaded = TRUE;\r
443\r
444 //\r
445 // Call PXENV_START_UNDI - Initilizes the UNID interface for use.\r
446 //\r
447 PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);\r
448 Status = Undi16SimpleNetworkStartUndi (\r
449 SimpleNetworkDevice,\r
450 (UINT16) ((Bus << 0x8) | (Device << 0x3) | (Function))\r
451 );\r
452 if (EFI_ERROR (Status)) {\r
453 DEBUG ((DEBUG_NET, "ERROR : Could not StartUndi. Status = %r\n", Status));\r
454 goto Done;\r
455 }\r
456 //\r
457 // Initialize the Simple Network Protocol\r
458 //\r
459 DEBUG ((DEBUG_NET, "Initialize SimpleNetworkDevice instance\n"));\r
460\r
461 SimpleNetworkDevice->SimpleNetwork.Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;\r
462 SimpleNetworkDevice->SimpleNetwork.Start = Undi16SimpleNetworkStart;\r
463 SimpleNetworkDevice->SimpleNetwork.Stop = Undi16SimpleNetworkStop;\r
464 SimpleNetworkDevice->SimpleNetwork.Initialize = Undi16SimpleNetworkInitialize;\r
465 SimpleNetworkDevice->SimpleNetwork.Reset = Undi16SimpleNetworkReset;\r
466 SimpleNetworkDevice->SimpleNetwork.Shutdown = Undi16SimpleNetworkShutdown;\r
467 SimpleNetworkDevice->SimpleNetwork.ReceiveFilters = Undi16SimpleNetworkReceiveFilters;\r
468 SimpleNetworkDevice->SimpleNetwork.StationAddress = Undi16SimpleNetworkStationAddress;\r
469 SimpleNetworkDevice->SimpleNetwork.Statistics = Undi16SimpleNetworkStatistics;\r
470 SimpleNetworkDevice->SimpleNetwork.MCastIpToMac = Undi16SimpleNetworkMCastIpToMac;\r
471 SimpleNetworkDevice->SimpleNetwork.NvData = Undi16SimpleNetworkNvData;\r
472 SimpleNetworkDevice->SimpleNetwork.GetStatus = Undi16SimpleNetworkGetStatus;\r
473 SimpleNetworkDevice->SimpleNetwork.Transmit = Undi16SimpleNetworkTransmit;\r
474 SimpleNetworkDevice->SimpleNetwork.Receive = Undi16SimpleNetworkReceive;\r
475 SimpleNetworkDevice->SimpleNetwork.Mode = &(SimpleNetworkDevice->SimpleNetworkMode);\r
476\r
477 Status = gBS->CreateEvent (\r
478 EVT_NOTIFY_WAIT,\r
479 TPL_NOTIFY,\r
480 Undi16SimpleNetworkWaitForPacket,\r
481 &SimpleNetworkDevice->SimpleNetwork,\r
482 &SimpleNetworkDevice->SimpleNetwork.WaitForPacket\r
483 );\r
484 if (EFI_ERROR (Status)) {\r
485 DEBUG ((DEBUG_ERROR, "ERROR : Could not create event. Status = %r\n", Status));\r
486 goto Done;\r
487 }\r
488 //\r
489 // Create an event to be signalled when ExitBootServices occurs in order\r
490 // to clean up nicely\r
491 //\r
492 Status = gBS->CreateEventEx (\r
493 EVT_NOTIFY_SIGNAL,\r
494 TPL_NOTIFY,\r
495 Undi16SimpleNetworkEvent,\r
496 NULL,\r
497 &gEfiEventExitBootServicesGuid,\r
498 &SimpleNetworkDevice->EfiBootEvent\r
499 );\r
500 if (EFI_ERROR (Status)) {\r
501 DEBUG ((DEBUG_ERROR, "ERROR : Could not create event. Status = %r\n", Status));\r
502 goto Done;\r
503 }\r
504\r
505 //\r
506 // Create an event to be signalled when Legacy Boot occurs to clean up the IVT\r
507 //\r
508 Status = EfiCreateEventLegacyBootEx(\r
509 TPL_NOTIFY, \r
510 Undi16SimpleNetworkEvent, \r
511 NULL, \r
512 &SimpleNetworkDevice->LegacyBootEvent\r
513 );\r
514 \r
515 if (EFI_ERROR(Status)) {\r
516 DEBUG ((DEBUG_ERROR,"ERROR : Could not create event. Status = %r\n",Status));\r
517 goto Done;\r
518 }\r
519\r
520 //\r
521 // Initialize the SimpleNetwork Mode Information\r
522 //\r
523 DEBUG ((DEBUG_NET, "Initialize Mode Information\n"));\r
524\r
525 SimpleNetworkDevice->SimpleNetworkMode.State = EfiSimpleNetworkStopped;\r
526 SimpleNetworkDevice->SimpleNetworkMode.MediaHeaderSize = 14;\r
527 SimpleNetworkDevice->SimpleNetworkMode.MacAddressChangeable = TRUE;\r
528 SimpleNetworkDevice->SimpleNetworkMode.MultipleTxSupported = TRUE;\r
529 SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |\r
530 EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST |\r
531 EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST |\r
532 EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS |\r
533 EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;\r
534 SimpleNetworkDevice->SimpleNetworkMode.MaxMCastFilterCount = MAXNUM_MCADDR;\r
535\r
536 //\r
537 // Initialize the SimpleNetwork Private Information\r
538 //\r
539 DEBUG ((DEBUG_NET, "Initialize Private Information\n"));\r
540\r
541 Status = BiosSnp16AllocatePagesBelowOneMb (\r
542 sizeof (PXENV_UNDI_TBD_T) / EFI_PAGE_SIZE + 1,\r
543 (VOID **) &SimpleNetworkDevice->Xmit\r
544 );\r
545 if (EFI_ERROR (Status)) {\r
546 goto Done;\r
547 }\r
548\r
549 Status = BiosSnp16AllocatePagesBelowOneMb (\r
550 1,\r
551 &SimpleNetworkDevice->TxRealModeMediaHeader\r
552 );\r
553 if (EFI_ERROR (Status)) {\r
554 goto Done;\r
555 }\r
556\r
557 Status = BiosSnp16AllocatePagesBelowOneMb (\r
558 1,\r
559 &SimpleNetworkDevice->TxRealModeDataBuffer\r
560 );\r
561 if (EFI_ERROR (Status)) {\r
562 goto Done;\r
563 }\r
564\r
565 Status = BiosSnp16AllocatePagesBelowOneMb (\r
566 1,\r
567 &SimpleNetworkDevice->TxDestAddr\r
568 );\r
569 if (EFI_ERROR (Status)) {\r
570 goto Done;\r
571 }\r
572\r
573 SimpleNetworkDevice->Xmit->XmitOffset = (UINT16) (((UINT32)(UINTN) SimpleNetworkDevice->TxRealModeMediaHeader) & 0x000f);\r
574\r
575 SimpleNetworkDevice->Xmit->XmitSegment = (UINT16) (((UINT32)(UINTN) SimpleNetworkDevice->TxRealModeMediaHeader) >> 4);\r
576\r
577 SimpleNetworkDevice->Xmit->DataBlkCount = 1;\r
578\r
579 SimpleNetworkDevice->Xmit->DataBlock[0].TDPtrType = 1;\r
580 SimpleNetworkDevice->Xmit->DataBlock[0].TDRsvdByte = 0;\r
581\r
582 SimpleNetworkDevice->Xmit->DataBlock[0].TDDataPtrOffset = (UINT16) (((UINT32)(UINTN) SimpleNetworkDevice->TxRealModeDataBuffer) & 0x000f);\r
583\r
584 SimpleNetworkDevice->Xmit->DataBlock[0].TDDataPtrSegment = (UINT16) (((UINT32)(UINTN) SimpleNetworkDevice->TxRealModeDataBuffer) >> 4);\r
585\r
586 SimpleNetworkDevice->TxBufferFifo.First = 0;\r
587 SimpleNetworkDevice->TxBufferFifo.Last = 0;\r
588\r
589 //\r
590 // Start() the SimpleNetwork device\r
591 //\r
592 DEBUG ((DEBUG_NET, "Start()\n"));\r
593\r
594 Status = Undi16SimpleNetworkStart (&SimpleNetworkDevice->SimpleNetwork);\r
595 if (EFI_ERROR (Status)) {\r
596 goto Done;\r
597 }\r
598 //\r
599 // GetInformation() the SimpleNetwork device\r
600 //\r
601 DEBUG ((DEBUG_NET, "GetInformation()\n"));\r
602\r
603 Status = Undi16SimpleNetworkGetInformation (&SimpleNetworkDevice->SimpleNetwork);\r
604 if (EFI_ERROR (Status)) {\r
605 goto Done;\r
606 }\r
607 //\r
608 // Build the device path for the child device\r
609 //\r
610 ZeroMem (&Node, sizeof (Node));\r
611 Node.DevPath.Type = MESSAGING_DEVICE_PATH;\r
612 Node.DevPath.SubType = MSG_MAC_ADDR_DP;\r
613 SetDevicePathNodeLength (&Node.DevPath, sizeof (MAC_ADDR_DEVICE_PATH));\r
614 CopyMem (\r
615 &Node.MacAddr.MacAddress,\r
616 &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,\r
617 sizeof (EFI_MAC_ADDRESS)\r
618 );\r
619 SimpleNetworkDevice->DevicePath = AppendDevicePathNode (\r
620 SimpleNetworkDevice->BaseDevicePath,\r
621 &Node.DevPath\r
622 );\r
623\r
624 //\r
625 // GetNicType() the SimpleNetwork device\r
626 //\r
627 DEBUG ((DEBUG_NET, "GetNicType()\n"));\r
628\r
629 Status = Undi16SimpleNetworkGetNicType (&SimpleNetworkDevice->SimpleNetwork);\r
630 if (EFI_ERROR (Status)) {\r
631 goto Done;\r
632 }\r
633 //\r
634 // GetNdisInfo() the SimpleNetwork device\r
635 //\r
636 DEBUG ((DEBUG_NET, "GetNdisInfo()\n"));\r
637\r
638 Status = Undi16SimpleNetworkGetNdisInfo (&SimpleNetworkDevice->SimpleNetwork);\r
639 if (EFI_ERROR (Status)) {\r
640 goto Done;\r
641 }\r
642 //\r
643 // Stop() the SimpleNetwork device\r
644 //\r
645 DEBUG ((DEBUG_NET, "Stop()\n"));\r
646\r
647 Status = SimpleNetworkDevice->SimpleNetwork.Stop (&SimpleNetworkDevice->SimpleNetwork);\r
648 if (EFI_ERROR (Status)) {\r
649 goto Done;\r
650 }\r
651 //\r
652 // Print Mode information\r
653 //\r
654 DEBUG ((DEBUG_NET, "Mode->State = %d\n", SimpleNetworkDevice->SimpleNetworkMode.State));\r
655 DEBUG ((DEBUG_NET, "Mode->HwAddressSize = %d\n", SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize));\r
656 DEBUG ((DEBUG_NET, "Mode->MacAddressChangeable = %d\n", SimpleNetworkDevice->SimpleNetworkMode.MacAddressChangeable));\r
657 DEBUG ((DEBUG_NET, "Mode->MultiplTxSupported = %d\n", SimpleNetworkDevice->SimpleNetworkMode.MultipleTxSupported));\r
658 DEBUG ((DEBUG_NET, "Mode->NvRamSize = %d\n", SimpleNetworkDevice->SimpleNetworkMode.NvRamSize));\r
659 DEBUG ((DEBUG_NET, "Mode->NvRamAccessSize = %d\n", SimpleNetworkDevice->SimpleNetworkMode.NvRamAccessSize));\r
660 DEBUG ((DEBUG_NET, "Mode->ReceiveFilterSetting = %d\n", SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting));\r
661 DEBUG ((DEBUG_NET, "Mode->IfType = %d\n", SimpleNetworkDevice->SimpleNetworkMode.IfType));\r
662 DEBUG ((DEBUG_NET, "Mode->MCastFilterCount = %d\n", SimpleNetworkDevice->SimpleNetworkMode.MCastFilterCount));\r
663 for (Index = 0; Index < SimpleNetworkDevice->SimpleNetworkMode.MCastFilterCount; Index++) {\r
664 DEBUG ((DEBUG_NET, " Filter[%02d] = ", Index));\r
665 for (Index2 = 0; Index2 < 16; Index2++) {\r
666 DEBUG ((DEBUG_NET, "%02x ", SimpleNetworkDevice->SimpleNetworkMode.MCastFilter[Index].Addr[Index2]));\r
667 }\r
668\r
669 DEBUG ((DEBUG_NET, "\n"));\r
670 }\r
671\r
672 DEBUG ((DEBUG_NET, "CurrentAddress = "));\r
673 for (Index2 = 0; Index2 < 16; Index2++) {\r
674 DEBUG ((DEBUG_NET, "%02x ", SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress.Addr[Index2]));\r
675 }\r
676\r
677 DEBUG ((DEBUG_NET, "\n"));\r
678\r
679 DEBUG ((DEBUG_NET, "BroadcastAddress = "));\r
680 for (Index2 = 0; Index2 < 16; Index2++) {\r
681 DEBUG ((DEBUG_NET, "%02x ", SimpleNetworkDevice->SimpleNetworkMode.BroadcastAddress.Addr[Index2]));\r
682 }\r
683\r
684 DEBUG ((DEBUG_NET, "\n"));\r
685\r
686 DEBUG ((DEBUG_NET, "PermanentAddress = "));\r
687 for (Index2 = 0; Index2 < 16; Index2++) {\r
688 DEBUG ((DEBUG_NET, "%02x ", SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress.Addr[Index2]));\r
689 }\r
690\r
691 DEBUG ((DEBUG_NET, "\n"));\r
692\r
693 //\r
694 // The network device was started, information collected, and stopped.\r
695 // Install protocol interfaces for the SimpleNetwork device.\r
696 //\r
697 DEBUG ((DEBUG_NET, "Install Protocol Interfaces on network interface\n"));\r
698\r
699 Status = gBS->InstallMultipleProtocolInterfaces (\r
700 &SimpleNetworkDevice->Handle,\r
701 &gEfiSimpleNetworkProtocolGuid,\r
702 &SimpleNetworkDevice->SimpleNetwork,\r
703 &gEfiNetworkInterfaceIdentifierProtocolGuid,\r
704 &SimpleNetworkDevice->Nii,\r
705 &gEfiDevicePathProtocolGuid,\r
706 SimpleNetworkDevice->DevicePath,\r
707 NULL\r
708 );\r
709 if (EFI_ERROR (Status)) {\r
710 goto Done;\r
711 }\r
712 //\r
713 // Open PCI I/O from the newly created child handle\r
714 //\r
715 Status = gBS->OpenProtocol (\r
716 Controller,\r
717 &gEfiPciIoProtocolGuid,\r
718 (VOID **) &PciIo,\r
719 This->DriverBindingHandle,\r
720 SimpleNetworkDevice->Handle,\r
721 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
722 );\r
723\r
724 DEBUG ((DEBUG_INIT, "UNDI16 Driver : EFI_SUCCESS\n"));\r
725\r
726Done:\r
727 if (EFI_ERROR (Status)) {\r
728 if (SimpleNetworkDevice != NULL) {\r
729\r
730 Undi16SimpleNetworkShutdown (&SimpleNetworkDevice->SimpleNetwork);\r
731 //\r
732 // CLOSE + SHUTDOWN\r
733 //\r
734 Undi16SimpleNetworkCleanupUndi (SimpleNetworkDevice);\r
735 //\r
736 // CLEANUP\r
737 //\r
738 Undi16SimpleNetworkStopUndi (SimpleNetworkDevice);\r
739 //\r
740 // STOP\r
741 //\r
742 if (SimpleNetworkDevice->UndiLoaded) {\r
743 Undi16SimpleNetworkUnloadUndi (SimpleNetworkDevice);\r
744 }\r
745\r
746 if (SimpleNetworkDevice->SimpleNetwork.WaitForPacket != NULL) {\r
747 gBS->CloseEvent (SimpleNetworkDevice->SimpleNetwork.WaitForPacket);\r
748 }\r
749\r
750 if (SimpleNetworkDevice->LegacyBootEvent != NULL) {\r
751 gBS->CloseEvent (SimpleNetworkDevice->LegacyBootEvent);\r
752 }\r
753 \r
754 if (SimpleNetworkDevice->EfiBootEvent != NULL) {\r
755 gBS->CloseEvent (SimpleNetworkDevice->EfiBootEvent);\r
756 }\r
757\r
758 if (SimpleNetworkDevice->Xmit != NULL) {\r
759 gBS->FreePages (\r
760 (EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->Xmit,\r
761 sizeof (PXENV_UNDI_TBD_T) / EFI_PAGE_SIZE + 1\r
762 );\r
763 }\r
764\r
765 if (SimpleNetworkDevice->TxRealModeMediaHeader != NULL) {\r
766 gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->TxRealModeMediaHeader, 1);\r
767 }\r
768\r
769 if (SimpleNetworkDevice->TxRealModeDataBuffer != NULL) {\r
770 gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->TxRealModeDataBuffer, 1);\r
771 }\r
772\r
773 if (SimpleNetworkDevice->TxDestAddr != NULL) {\r
774 gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->TxDestAddr, 1);\r
775 }\r
776\r
777 gBS->FreePool (SimpleNetworkDevice);\r
778 \r
779 //\r
780 // Only restore the vector if it was cached.\r
781 //\r
782 if (mCachedInt1A) {\r
783 RestoreCachedVectorAddress (0x1A);\r
784 mCachedInt1A = FALSE;\r
785 }\r
786 }\r
787\r
788 if (PciIo != NULL) {\r
789 Status = PciIo->Attributes (\r
790 PciIo,\r
791 EfiPciIoAttributeOperationSupported,\r
792 0,\r
793 &Supports\r
794 );\r
795 if (!EFI_ERROR (Status)) {\r
796 Supports &= EFI_PCI_DEVICE_ENABLE;\r
797 Status = PciIo->Attributes (\r
798 PciIo,\r
799 EfiPciIoAttributeOperationDisable,\r
800 Supports,\r
801 NULL\r
802 );\r
803 }\r
804 }\r
805\r
806 gBS->CloseProtocol (\r
807 Controller,\r
808 &gEfiPciIoProtocolGuid,\r
809 This->DriverBindingHandle,\r
810 Controller\r
811 );\r
812\r
813 gBS->CloseProtocol (\r
814 Controller,\r
815 &gEfiDevicePathProtocolGuid,\r
816 This->DriverBindingHandle,\r
817 Controller\r
818 );\r
819 if (Status != EFI_OUT_OF_RESOURCES) {\r
820 Status = EFI_DEVICE_ERROR;\r
821 }\r
822 } \r
823 return Status;\r
824}\r
825\r
826/**\r
827 Stops the device by given device controller.\r
828\r
829 @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
830 @param Controller The handle of the controller to test.\r
831 @param NumberOfChildren The number of child device handles in ChildHandleBuffer.\r
832 @param ChildHandleBuffer An array of child handles to be freed. May be NULL if\r
833 NumberOfChildren is 0.\r
834 \r
835 @retval EFI_SUCCESS - The device was stopped.\r
836 @retval EFI_DEVICE_ERROR - The device could not be stopped due to a device error.\r
837**/\r
838EFI_STATUS\r
839EFIAPI\r
840BiosSnp16DriverBindingStop (\r
841 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
842 IN EFI_HANDLE Controller,\r
843 IN UINTN NumberOfChildren,\r
844 IN EFI_HANDLE *ChildHandleBuffer\r
845 )\r
846{\r
847 EFI_STATUS Status;\r
848 UINTN Index;\r
849 BOOLEAN AllChildrenStopped;\r
850 EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork;\r
851 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
852 EFI_PCI_IO_PROTOCOL *PciIo;\r
853 UINT64 Supports;\r
854\r
855 //\r
856 // Complete all outstanding transactions to Controller.\r
857 // Don't allow any new transaction to Controller to be started.\r
858 //\r
859 if (NumberOfChildren == 0) {\r
860 //\r
861 // Close the bus driver\r
862 //\r
863 Status = gBS->OpenProtocol (\r
864 Controller,\r
865 &gEfiPciIoProtocolGuid,\r
866 (VOID **) &PciIo,\r
867 This->DriverBindingHandle,\r
868 Controller,\r
869 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
870 );\r
871 if (!EFI_ERROR (Status)) {\r
872 Status = PciIo->Attributes (\r
873 PciIo,\r
874 EfiPciIoAttributeOperationSupported,\r
875 0,\r
876 &Supports\r
877 );\r
878 if (!EFI_ERROR (Status)) {\r
879 Supports &= EFI_PCI_DEVICE_ENABLE;\r
880 Status = PciIo->Attributes (\r
881 PciIo,\r
882 EfiPciIoAttributeOperationDisable,\r
883 Supports,\r
884 NULL\r
885 );\r
886 }\r
887 }\r
888\r
889 Status = gBS->CloseProtocol (\r
890 Controller,\r
891 &gEfiPciIoProtocolGuid,\r
892 This->DriverBindingHandle,\r
893 Controller\r
894 );\r
895\r
896 Status = gBS->CloseProtocol (\r
897 Controller,\r
898 &gEfiDevicePathProtocolGuid,\r
899 This->DriverBindingHandle,\r
900 Controller\r
901 );\r
902 \r
903 if (EFI_ERROR (Status)) {\r
904 Status = EFI_DEVICE_ERROR;\r
905 }\r
906 return Status;\r
907 }\r
908\r
909 AllChildrenStopped = TRUE;\r
910\r
911 for (Index = 0; Index < NumberOfChildren; Index++) {\r
912\r
913 Status = gBS->OpenProtocol (\r
914 ChildHandleBuffer[Index],\r
915 &gEfiSimpleNetworkProtocolGuid,\r
916 (VOID **) &SimpleNetwork,\r
917 This->DriverBindingHandle,\r
918 Controller,\r
919 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
920 );\r
921 if (!EFI_ERROR (Status)) {\r
922\r
923 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (SimpleNetwork);\r
924\r
925 Status = gBS->CloseProtocol (\r
926 Controller,\r
927 &gEfiPciIoProtocolGuid,\r
928 This->DriverBindingHandle,\r
929 ChildHandleBuffer[Index]\r
930 );\r
931\r
932 Status = gBS->UninstallMultipleProtocolInterfaces (\r
933 SimpleNetworkDevice->Handle,\r
934 &gEfiSimpleNetworkProtocolGuid,\r
935 &SimpleNetworkDevice->SimpleNetwork,\r
936 &gEfiNetworkInterfaceIdentifierProtocolGuid,\r
937 &SimpleNetworkDevice->Nii,\r
938 &gEfiDevicePathProtocolGuid,\r
939 SimpleNetworkDevice->DevicePath,\r
940 NULL\r
941 );\r
942 if (EFI_ERROR (Status)) {\r
943 gBS->OpenProtocol (\r
944 Controller,\r
945 &gEfiPciIoProtocolGuid,\r
946 (VOID **) &PciIo,\r
947 This->DriverBindingHandle,\r
948 ChildHandleBuffer[Index],\r
949 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
950 );\r
951 } else {\r
952\r
953 Undi16SimpleNetworkShutdown (&SimpleNetworkDevice->SimpleNetwork);\r
954 //\r
955 // CLOSE + SHUTDOWN\r
956 //\r
957 Undi16SimpleNetworkCleanupUndi (SimpleNetworkDevice);\r
958 //\r
959 // CLEANUP\r
960 //\r
961 Undi16SimpleNetworkStopUndi (SimpleNetworkDevice);\r
962 //\r
963 // STOP\r
964 //\r
965 if (SimpleNetworkDevice->UndiLoaded) {\r
966 Undi16SimpleNetworkUnloadUndi (SimpleNetworkDevice);\r
967 }\r
968\r
969 if (SimpleNetworkDevice->SimpleNetwork.WaitForPacket != NULL) {\r
970 gBS->CloseEvent (SimpleNetworkDevice->SimpleNetwork.WaitForPacket);\r
971 }\r
972\r
973 if (SimpleNetworkDevice->LegacyBootEvent != NULL) {\r
974 gBS->CloseEvent (SimpleNetworkDevice->LegacyBootEvent);\r
975 }\r
976 \r
977 if (SimpleNetworkDevice->EfiBootEvent != NULL) {\r
978 gBS->CloseEvent (SimpleNetworkDevice->EfiBootEvent);\r
979 }\r
980\r
981 if (SimpleNetworkDevice->Xmit != NULL) {\r
982 gBS->FreePages (\r
983 (EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->Xmit,\r
984 sizeof (PXENV_UNDI_TBD_T) / EFI_PAGE_SIZE + 1\r
985 );\r
986 }\r
987\r
988 if (SimpleNetworkDevice->TxRealModeMediaHeader != NULL) {\r
989 gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->TxRealModeMediaHeader, 1);\r
990 }\r
991\r
992 if (SimpleNetworkDevice->TxRealModeDataBuffer != NULL) {\r
993 gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->TxRealModeDataBuffer, 1);\r
994 }\r
995\r
996 if (SimpleNetworkDevice->TxDestAddr != NULL) {\r
997 gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->TxDestAddr, 1);\r
998 }\r
999\r
1000 gBS->FreePool (SimpleNetworkDevice);\r
1001 }\r
1002\r
1003 }\r
1004\r
1005 if (EFI_ERROR (Status)) {\r
1006 AllChildrenStopped = FALSE;\r
1007 }\r
1008 }\r
1009\r
1010 if (!AllChildrenStopped) {\r
1011 return EFI_DEVICE_ERROR;\r
1012 }\r
1013\r
1014 return EFI_SUCCESS;\r
1015}\r
1016\r
1017//\r
1018// FIFO Support Functions\r
1019//\r
1020/**\r
1021 Judge whether transmit FIFO is full.\r
1022\r
1023 @param Fifo Point to trasmit FIFO structure.\r
1024 \r
1025 @return BOOLEAN whether transmit FIFO is full.\r
1026**/\r
1027BOOLEAN\r
1028SimpleNetworkTransmitFifoFull (\r
1029 EFI_SIMPLE_NETWORK_DEV_FIFO *Fifo\r
1030 )\r
1031{\r
1032 if (((Fifo->Last + 1) % EFI_SIMPLE_NETWORK_MAX_TX_FIFO_SIZE) == Fifo->First) {\r
1033 return TRUE;\r
1034 }\r
1035\r
1036 return FALSE;\r
1037}\r
1038\r
1039/**\r
1040 Judge whether transmit FIFO is empty.\r
1041\r
1042 @param Fifo Point to trasmit FIFO structure.\r
1043 \r
1044 @return BOOLEAN whether transmit FIFO is empty.\r
1045**/\r
1046BOOLEAN\r
1047SimpleNetworkTransmitFifoEmpty (\r
1048 EFI_SIMPLE_NETWORK_DEV_FIFO *Fifo\r
1049 )\r
1050{\r
1051 if (Fifo->Last == Fifo->First) {\r
1052 return TRUE;\r
1053 }\r
1054\r
1055 return FALSE;\r
1056}\r
1057\r
1058\r
1059/**\r
1060 Add data into transmit buffer.\r
1061\r
1062 @param Fifo Point to trasmit FIFO structure.\r
1063 @param Data The data point want to be added.\r
1064 \r
1065 @retval EFI_OUT_OF_RESOURCES FIFO is full \r
1066 @retval EFI_SUCCESS Success operation. \r
1067**/\r
1068EFI_STATUS\r
1069SimpleNetworkTransmitFifoAdd (\r
1070 EFI_SIMPLE_NETWORK_DEV_FIFO *Fifo,\r
1071 VOID *Data\r
1072 )\r
1073{\r
1074 if (SimpleNetworkTransmitFifoFull (Fifo)) {\r
1075 return EFI_OUT_OF_RESOURCES;\r
1076 }\r
1077\r
1078 Fifo->Data[Fifo->Last] = Data;\r
1079 Fifo->Last = (Fifo->Last + 1) % EFI_SIMPLE_NETWORK_MAX_TX_FIFO_SIZE;\r
1080 return EFI_SUCCESS;\r
1081}\r
1082\r
1083/**\r
1084 Get a data and remove it from network transmit FIFO.\r
1085\r
1086 @param Fifo Point to trasmit FIFO structure.\r
1087 @param Data On return, point to the data point want to be got and removed.\r
1088 \r
1089 @retval EFI_OUT_OF_RESOURCES network transmit buffer is empty. \r
1090 @retval EFI_SUCCESS Success operation. \r
1091**/\r
1092EFI_STATUS\r
1093SimpleNetworkTransmitFifoRemove (\r
1094 EFI_SIMPLE_NETWORK_DEV_FIFO *Fifo,\r
1095 VOID **Data\r
1096 )\r
1097{\r
1098 if (SimpleNetworkTransmitFifoEmpty (Fifo)) {\r
1099 return EFI_OUT_OF_RESOURCES;\r
1100 }\r
1101\r
1102 *Data = Fifo->Data[Fifo->First];\r
1103 Fifo->First = (Fifo->First + 1) % EFI_SIMPLE_NETWORK_MAX_TX_FIFO_SIZE;\r
1104 return EFI_SUCCESS;\r
1105}\r
1106\r
1107/**\r
1108 Get recive filter setting according to EFI mask value.\r
1109\r
1110 @param ReceiveFilterSetting filter setting EFI mask value.\r
1111 \r
1112 @return UINT16 Undi filter setting value.\r
1113**/\r
1114UINT16\r
1115Undi16GetPacketFilterSetting (\r
1116 UINTN ReceiveFilterSetting\r
1117 )\r
1118{\r
1119 UINT16 PktFilter;\r
1120\r
1121 PktFilter = 0;\r
1122 if ((ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) != 0) {\r
1123 PktFilter |= FLTR_DIRECTED;\r
1124 }\r
1125\r
1126 if ((ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {\r
1127 PktFilter |= FLTR_DIRECTED;\r
1128 }\r
1129\r
1130 if ((ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {\r
1131 PktFilter |= FLTR_BRDCST;\r
1132 }\r
1133\r
1134 if ((ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {\r
1135 PktFilter |= FLTR_PRMSCS;\r
1136 }\r
1137\r
1138 if ((ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {\r
1139 PktFilter |= FLTR_PRMSCS;\r
1140 //\r
1141 // @bug : Do not know if this is right????\r
1142 //\r
1143 }\r
1144 //\r
1145 // @bug : What is FLTR_SRC_RTG?\r
1146 //\r
1147 return PktFilter;\r
1148}\r
1149\r
1150/**\r
1151 Get filter setting from multi cast buffer .\r
1152 \r
1153 @param Mode Point to mode structure.\r
1154 @param McastBuffer The multi cast buffer \r
1155 @param HwAddressSize Size of filter value.\r
1156 \r
1157**/\r
1158VOID\r
1159Undi16GetMCastFilters (\r
1160 IN EFI_SIMPLE_NETWORK_MODE *Mode,\r
1161 IN OUT PXENV_UNDI_MCAST_ADDR_T *McastBuffer,\r
1162 IN UINTN HwAddressSize\r
1163 )\r
1164{\r
1165 UINTN Index;\r
1166\r
1167 //\r
1168 // @bug : What if Mode->MCastFilterCount > MAXNUM_MCADDR?\r
1169 //\r
1170 McastBuffer->MCastAddrCount = (UINT16) Mode->MCastFilterCount;\r
1171 for (Index = 0; Index < MAXNUM_MCADDR; Index++) {\r
1172 if (Index < McastBuffer->MCastAddrCount) {\r
1173 CopyMem (&McastBuffer->MCastAddr[Index], &Mode->MCastFilter[Index], HwAddressSize);\r
1174 } else {\r
1175 ZeroMem (&McastBuffer->MCastAddr[Index], HwAddressSize);\r
1176 }\r
1177 }\r
1178}\r
1179//\r
1180// Load 16 bit UNDI Option ROM into memory\r
1181//\r
1182/**\r
1183 Loads the undi driver.\r
1184\r
1185 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.\r
1186 \r
1187 @retval EFI_SUCCESS - Successfully loads undi driver.\r
1188 @retval EFI_NOT_FOUND - Doesn't find undi driver or undi driver load failure.\r
1189**/\r
1190EFI_STATUS\r
1191Undi16SimpleNetworkLoadUndi (\r
1192 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice\r
1193 )\r
1194{\r
1195 EFI_STATUS Status;\r
1196 EFI_PCI_IO_PROTOCOL *PciIo;\r
1197 UINTN RomAddress;\r
1198 PCI_EXPANSION_ROM_HEADER *PciExpansionRomHeader;\r
1199 PCI_DATA_STRUCTURE *PciDataStructure;\r
1200 PCI_TYPE00 Pci;\r
1201 \r
1202 if (!mCachedInt1A) {\r
1203 Status = CacheVectorAddress (0x1A);\r
1204 if (!EFI_ERROR (Status)) {\r
1205 mCachedInt1A = TRUE; \r
1206 }\r
1207 }\r
1208\r
1209 PciIo = SimpleNetworkDevice->PciIo;\r
1210\r
1211 PciIo->Pci.Read (\r
1212 PciIo,\r
1213 EfiPciIoWidthUint32,\r
1214 0,\r
1215 sizeof (Pci) / sizeof (UINT32),\r
1216 &Pci\r
1217 );\r
1218\r
1219 for (RomAddress = 0xc0000; RomAddress < 0xfffff; RomAddress += 0x800) {\r
1220\r
1221 PciExpansionRomHeader = (PCI_EXPANSION_ROM_HEADER *) RomAddress;\r
1222\r
1223 if (PciExpansionRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
1224 continue;\r
1225 }\r
1226\r
1227 DEBUG ((DEBUG_INIT, "Option ROM found at %X\n", RomAddress));\r
1228\r
1229 PciDataStructure = (PCI_DATA_STRUCTURE *) (RomAddress + PciExpansionRomHeader->PcirOffset);\r
1230\r
1231 if (PciDataStructure->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {\r
1232 continue;\r
1233 }\r
1234\r
1235 DEBUG ((DEBUG_INIT, "PCI Data Structure found at %X\n", PciDataStructure));\r
1236\r
1237 if (PciDataStructure->VendorId != Pci.Hdr.VendorId || PciDataStructure->DeviceId != Pci.Hdr.DeviceId) {\r
1238 continue;\r
1239 }\r
1240\r
1241 DEBUG (\r
1242 (DEBUG_INIT, \r
1243 "PCI device with matchinng VendorId and DeviceId (%d,%d)\n",\r
1244 (UINTN) PciDataStructure->VendorId,\r
1245 (UINTN) PciDataStructure->DeviceId)\r
1246 );\r
1247\r
1248 Status = LaunchBaseCode (SimpleNetworkDevice, RomAddress);\r
1249\r
1250 if (!EFI_ERROR (Status)) {\r
1251 return EFI_SUCCESS;\r
1252 }\r
1253 }\r
1254\r
1255 return EFI_NOT_FOUND;\r
1256}\r
1257\r
1258/**\r
1259 Unload 16 bit UNDI Option ROM from memory\r
1260\r
1261 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.\r
1262 \r
1263 @return EFI_STATUS \r
1264**/\r
1265EFI_STATUS\r
1266Undi16SimpleNetworkUnloadUndi (\r
1267 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice\r
1268 )\r
1269{\r
1270 if (SimpleNetworkDevice->UndiLoaderTable != NULL) {\r
1271 ZeroMem (SimpleNetworkDevice->UndiLoaderTable, SimpleNetworkDevice->UndiLoaderTablePages << EFI_PAGE_SHIFT);\r
1272 gBS->FreePages (\r
1273 (EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->UndiLoaderTable,\r
1274 SimpleNetworkDevice->UndiLoaderTablePages\r
1275 );\r
1276 }\r
1277\r
1278 if (SimpleNetworkDevice->DestinationDataSegment != NULL) {\r
1279 ZeroMem (\r
1280 SimpleNetworkDevice->DestinationDataSegment,\r
1281 SimpleNetworkDevice->DestinationDataSegmentPages << EFI_PAGE_SHIFT\r
1282 );\r
1283 gBS->FreePages (\r
1284 (EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->DestinationDataSegment,\r
1285 SimpleNetworkDevice->DestinationDataSegmentPages\r
1286 );\r
1287 }\r
1288\r
1289 if (SimpleNetworkDevice->DestinationStackSegment != NULL) {\r
1290 ZeroMem (\r
1291 SimpleNetworkDevice->DestinationStackSegment,\r
1292 SimpleNetworkDevice->DestinationStackSegmentPages << EFI_PAGE_SHIFT\r
1293 );\r
1294 gBS->FreePages (\r
1295 (EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->DestinationStackSegment,\r
1296 SimpleNetworkDevice->DestinationStackSegmentPages\r
1297 );\r
1298 }\r
1299\r
1300 if (SimpleNetworkDevice->DestinationCodeSegment != NULL) {\r
1301 ZeroMem (\r
1302 SimpleNetworkDevice->DestinationCodeSegment,\r
1303 SimpleNetworkDevice->DestinationCodeSegmentPages << EFI_PAGE_SHIFT\r
1304 );\r
1305 gBS->FreePages (\r
1306 (EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->DestinationCodeSegment,\r
1307 SimpleNetworkDevice->DestinationCodeSegmentPages\r
1308 );\r
1309 }\r
1310\r
1311 return EFI_SUCCESS;\r
1312}\r
1313\r
1314/**\r
1315 Start the UNDI interface.\r
1316\r
1317 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.\r
1318 @param Ax PCI address of Undi device.\r
1319 \r
1320 @retval EFI_DEVICE_ERROR Fail to start 16 bit UNDI ROM. \r
1321 @retval Others Status of start 16 bit UNDI ROM. \r
1322**/\r
1323EFI_STATUS\r
1324Undi16SimpleNetworkStartUndi (\r
1325 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice,\r
1326 UINT16 Ax\r
1327 )\r
1328{\r
1329 EFI_STATUS Status;\r
1330 PXENV_START_UNDI_T Start;\r
1331\r
1332 //\r
1333 // Call 16 bit UNDI ROM to start the network interface\r
1334 //\r
1335 //\r
1336 // @bug : What is this state supposed to be???\r
1337 //\r
1338 Start.Status = INIT_PXE_STATUS;\r
1339 Start.Ax = Ax;\r
1340 Start.Bx = 0x0000;\r
1341 Start.Dx = 0x0000;\r
1342 Start.Di = 0x0000;\r
1343 Start.Es = 0x0000;\r
1344\r
1345 Status = PxeStartUndi (SimpleNetworkDevice, &Start);\r
1346 if (EFI_ERROR (Status)) {\r
1347 return Status;\r
1348 }\r
1349 //\r
1350 // Check the status code from the 16 bit UNDI ROM\r
1351 //\r
1352 if (Start.Status != PXENV_STATUS_SUCCESS) {\r
1353 return EFI_DEVICE_ERROR;\r
1354 }\r
1355\r
1356 return Status;\r
1357}\r
1358\r
1359\r
1360/**\r
1361 Stop the UNDI interface\r
1362\r
1363 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.\r
1364 \r
1365 @retval EFI_DEVICE_ERROR Fail to stop 16 bit UNDI ROM. \r
1366 @retval Others Status of stop 16 bit UNDI ROM. \r
1367**/\r
1368EFI_STATUS\r
1369Undi16SimpleNetworkStopUndi (\r
1370 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice\r
1371 )\r
1372{\r
1373 EFI_STATUS Status;\r
1374 PXENV_STOP_UNDI_T Stop;\r
1375\r
1376 //\r
1377 // Call 16 bit UNDI ROM to start the network interface\r
1378 //\r
1379 Stop.Status = INIT_PXE_STATUS;\r
1380\r
1381 Status = PxeUndiStop (SimpleNetworkDevice, &Stop);\r
1382 if (EFI_ERROR (Status)) {\r
1383 return Status;\r
1384 }\r
1385 //\r
1386 // Check the status code from the 16 bit UNDI ROM\r
1387 //\r
1388 if (Stop.Status != PXENV_STATUS_SUCCESS) {\r
1389 return EFI_DEVICE_ERROR;\r
1390 }\r
1391\r
1392 return Status;\r
1393}\r
1394\r
1395/**\r
1396 Cleanup Unid network interface\r
1397\r
1398 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.\r
1399 \r
1400 @retval EFI_DEVICE_ERROR Fail to cleanup 16 bit UNDI ROM. \r
1401 @retval Others Status of cleanup 16 bit UNDI ROM. \r
1402**/\r
1403EFI_STATUS\r
1404Undi16SimpleNetworkCleanupUndi (\r
1405 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice\r
1406 )\r
1407{\r
1408 EFI_STATUS Status;\r
1409 PXENV_UNDI_CLEANUP_T Cleanup;\r
1410\r
1411 //\r
1412 // Call 16 bit UNDI ROM to cleanup the network interface\r
1413 //\r
1414 Cleanup.Status = INIT_PXE_STATUS;\r
1415\r
1416 Status = PxeUndiCleanup (SimpleNetworkDevice, &Cleanup);\r
1417 if (EFI_ERROR (Status)) {\r
1418 return Status;\r
1419 }\r
1420 //\r
1421 // Check the status code from the 16 bit UNDI ROM\r
1422 //\r
1423 if (Cleanup.Status != PXENV_STATUS_SUCCESS) {\r
1424 return EFI_DEVICE_ERROR;\r
1425 }\r
1426\r
1427 return Status;\r
1428}\r
1429\r
1430/**\r
1431 Get runtime information for Undi network interface\r
1432\r
1433 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
1434 \r
1435 @retval EFI_SUCCESS Sucess operation. \r
1436 @retval Others Fail to get runtime information for Undi network interface. \r
1437**/\r
1438EFI_STATUS\r
1439Undi16SimpleNetworkGetInformation (\r
1440 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
1441 )\r
1442{\r
1443 EFI_STATUS Status;\r
1444 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
1445 UINTN Index;\r
1446\r
1447 if (This == NULL) {\r
1448 return EFI_INVALID_PARAMETER;\r
1449 }\r
1450\r
1451 Status = EFI_SUCCESS;\r
1452 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
1453\r
1454 if (SimpleNetworkDevice == NULL) {\r
1455 return EFI_DEVICE_ERROR;\r
1456 }\r
1457 //\r
1458 // Verify that the current state of the adapter is valid for this call.\r
1459 //\r
1460 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
1461 case EfiSimpleNetworkStarted:\r
1462 case EfiSimpleNetworkInitialized:\r
1463 break;\r
1464\r
1465 case EfiSimpleNetworkStopped:\r
1466 return EFI_NOT_STARTED;\r
1467\r
1468 default:\r
1469 return EFI_DEVICE_ERROR;\r
1470 }\r
1471 //\r
1472 // Call 16 bit UNDI ROM to start the network interface\r
1473 //\r
1474 ZeroMem (&SimpleNetworkDevice->GetInformation, sizeof (PXENV_UNDI_GET_INFORMATION_T));\r
1475\r
1476 SimpleNetworkDevice->GetInformation.Status = INIT_PXE_STATUS;\r
1477\r
1478 Status = PxeUndiGetInformation (SimpleNetworkDevice, &SimpleNetworkDevice->GetInformation);\r
1479 if (EFI_ERROR (Status)) {\r
1480 return Status;\r
1481 }\r
1482\r
1483 DEBUG ((DEBUG_NET, " GetInformation.Status = %d\n", SimpleNetworkDevice->GetInformation.Status));\r
1484 DEBUG ((DEBUG_NET, " GetInformation.BaseIo = %d\n", SimpleNetworkDevice->GetInformation.BaseIo));\r
1485 DEBUG ((DEBUG_NET, " GetInformation.IntNumber = %d\n", SimpleNetworkDevice->GetInformation.IntNumber));\r
1486 DEBUG ((DEBUG_NET, " GetInformation.MaxTranUnit = %d\n", SimpleNetworkDevice->GetInformation.MaxTranUnit));\r
1487 DEBUG ((DEBUG_NET, " GetInformation.HwType = %d\n", SimpleNetworkDevice->GetInformation.HwType));\r
1488 DEBUG ((DEBUG_NET, " GetInformation.HwAddrLen = %d\n", SimpleNetworkDevice->GetInformation.HwAddrLen));\r
1489 DEBUG ((DEBUG_NET, " GetInformation.ROMAddress = %d\n", SimpleNetworkDevice->GetInformation.ROMAddress));\r
1490 DEBUG ((DEBUG_NET, " GetInformation.RxBufCt = %d\n", SimpleNetworkDevice->GetInformation.RxBufCt));\r
1491 DEBUG ((DEBUG_NET, " GetInformation.TxBufCt = %d\n", SimpleNetworkDevice->GetInformation.TxBufCt));\r
1492\r
1493 DEBUG ((DEBUG_NET, " GetInformation.CurNodeAddr ="));\r
1494 for (Index = 0; Index < 16; Index++) {\r
1495 DEBUG ((DEBUG_NET, "%02x ", SimpleNetworkDevice->GetInformation.CurrentNodeAddress[Index]));\r
1496 }\r
1497\r
1498 DEBUG ((DEBUG_NET, "\n"));\r
1499\r
1500 DEBUG ((DEBUG_NET, " GetInformation.PermNodeAddr ="));\r
1501 for (Index = 0; Index < 16; Index++) {\r
1502 DEBUG ((DEBUG_NET, "%02x ", SimpleNetworkDevice->GetInformation.PermNodeAddress[Index]));\r
1503 }\r
1504\r
1505 DEBUG ((DEBUG_NET, "\n"));\r
1506\r
1507 //\r
1508 // Check the status code from the 16 bit UNDI ROM\r
1509 //\r
1510 if (SimpleNetworkDevice->GetInformation.Status != PXENV_STATUS_SUCCESS) {\r
1511 return EFI_DEVICE_ERROR;\r
1512 }\r
1513 //\r
1514 // The information has been retrieved. Fill in Mode data.\r
1515 //\r
1516 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize = SimpleNetworkDevice->GetInformation.HwAddrLen;\r
1517\r
1518 SimpleNetworkDevice->SimpleNetworkMode.MaxPacketSize = SimpleNetworkDevice->GetInformation.MaxTranUnit;\r
1519\r
1520 SimpleNetworkDevice->SimpleNetworkMode.IfType = (UINT8) SimpleNetworkDevice->GetInformation.HwType;\r
1521\r
1522 ZeroMem (\r
1523 &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,\r
1524 sizeof SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress\r
1525 );\r
1526\r
1527 CopyMem (\r
1528 &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,\r
1529 &SimpleNetworkDevice->GetInformation.CurrentNodeAddress,\r
1530 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
1531 );\r
1532\r
1533 ZeroMem (\r
1534 &SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress,\r
1535 sizeof SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress\r
1536 );\r
1537\r
1538 CopyMem (\r
1539 &SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress,\r
1540 &SimpleNetworkDevice->GetInformation.PermNodeAddress,\r
1541 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
1542 );\r
1543\r
1544 //\r
1545 // hard code broadcast address - not avail in PXE2.1\r
1546 //\r
1547 ZeroMem (\r
1548 &SimpleNetworkDevice->SimpleNetworkMode.BroadcastAddress,\r
1549 sizeof SimpleNetworkDevice->SimpleNetworkMode.BroadcastAddress\r
1550 );\r
1551\r
1552 SetMem (\r
1553 &SimpleNetworkDevice->SimpleNetworkMode.BroadcastAddress,\r
1554 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize,\r
1555 0xff\r
1556 );\r
1557\r
1558 return Status;\r
1559}\r
1560\r
1561/**\r
1562 Get NIC type\r
1563\r
1564 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
1565 \r
1566 @retval EFI_SUCCESS Sucess operation. \r
1567 @retval Others Fail to get NIC type.\r
1568**/\r
1569EFI_STATUS\r
1570Undi16SimpleNetworkGetNicType (\r
1571 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
1572 )\r
1573{\r
1574 EFI_STATUS Status;\r
1575 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
1576\r
1577 if (This == NULL) {\r
1578 return EFI_INVALID_PARAMETER;\r
1579 }\r
1580\r
1581 Status = EFI_SUCCESS;\r
1582 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
1583\r
1584 if (SimpleNetworkDevice == NULL) {\r
1585 return EFI_DEVICE_ERROR;\r
1586 }\r
1587\r
1588 ZeroMem (&SimpleNetworkDevice->GetNicType, sizeof (PXENV_UNDI_GET_NIC_TYPE_T));\r
1589\r
1590 SimpleNetworkDevice->GetNicType.Status = INIT_PXE_STATUS;\r
1591\r
1592 Status = PxeUndiGetNicType (SimpleNetworkDevice, &SimpleNetworkDevice->GetNicType);\r
1593\r
1594 if (EFI_ERROR (Status)) {\r
1595 return Status;\r
1596 }\r
1597\r
1598 DEBUG ((DEBUG_NET, " GetNicType.Status = %d\n", SimpleNetworkDevice->GetNicType.Status));\r
1599 DEBUG ((DEBUG_NET, " GetNicType.NicType = %d\n", SimpleNetworkDevice->GetNicType.NicType));\r
1600 //\r
1601 // Check the status code from the 16 bit UNDI ROM\r
1602 //\r
1603 if (SimpleNetworkDevice->GetNicType.Status != PXENV_STATUS_SUCCESS) {\r
1604 return EFI_DEVICE_ERROR;\r
1605 }\r
1606 //\r
1607 // The information has been retrieved. Fill in Mode data.\r
1608 //\r
1609 return Status;\r
1610}\r
1611\r
1612/**\r
1613 Get NDIS information\r
1614\r
1615 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
1616 \r
1617 @retval EFI_SUCCESS Sucess operation. \r
1618 @retval Others Fail to get NDIS information.\r
1619**/\r
1620EFI_STATUS\r
1621Undi16SimpleNetworkGetNdisInfo (\r
1622 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
1623 )\r
1624{\r
1625 EFI_STATUS Status;\r
1626 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
1627\r
1628 if (This == NULL) {\r
1629 return EFI_INVALID_PARAMETER;\r
1630 }\r
1631\r
1632 Status = EFI_SUCCESS;\r
1633 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
1634\r
1635 if (SimpleNetworkDevice == NULL) {\r
1636 return EFI_DEVICE_ERROR;\r
1637 }\r
1638\r
1639 ZeroMem (&SimpleNetworkDevice->GetNdisInfo, sizeof (PXENV_UNDI_GET_NDIS_INFO_T));\r
1640\r
1641 SimpleNetworkDevice->GetNdisInfo.Status = INIT_PXE_STATUS;\r
1642\r
1643 Status = PxeUndiGetNdisInfo (SimpleNetworkDevice, &SimpleNetworkDevice->GetNdisInfo);\r
1644\r
1645 if (EFI_ERROR (Status)) {\r
1646 return Status;\r
1647 }\r
1648\r
1649 DEBUG ((DEBUG_NET, " GetNdisInfo.Status = %d\n", SimpleNetworkDevice->GetNdisInfo.Status));\r
1650 DEBUG ((DEBUG_NET, " GetNdisInfo.IfaceType = %a\n", SimpleNetworkDevice->GetNdisInfo.IfaceType));\r
1651 DEBUG ((DEBUG_NET, " GetNdisInfo.LinkSpeed = %d\n", SimpleNetworkDevice->GetNdisInfo.LinkSpeed));\r
1652 DEBUG ((DEBUG_NET, " GetNdisInfo.ServiceFlags = %08x\n", SimpleNetworkDevice->GetNdisInfo.ServiceFlags));\r
1653\r
1654 //\r
1655 // Check the status code from the 16 bit UNDI ROM\r
1656 //\r
1657 if (SimpleNetworkDevice->GetNdisInfo.Status != PXENV_STATUS_SUCCESS) {\r
1658 return EFI_DEVICE_ERROR;\r
1659 }\r
1660 //\r
1661 // The information has been retrieved. Fill in Mode data.\r
1662 //\r
1663 return Status;\r
1664}\r
1665\r
1666/**\r
1667 Call Undi ROM 16bit ISR() to check interrupt cause.\r
1668\r
1669 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
1670 @param FrameLength The length of frame buffer.\r
1671 @param FrameHeaderLength The length of frame buffer's header if has.\r
1672 @param Frame The frame buffer to process network interrupt.\r
1673 @param ProtType The type network transmit protocol\r
1674 @param PktType The type of package.\r
1675 \r
1676 @retval EFI_DEVICE_ERROR Fail to execute 16 bit ROM's ISR, or status is invalid. \r
1677 @retval EFI_SUCCESS Success operation. \r
1678**/\r
1679EFI_STATUS\r
1680Undi16SimpleNetworkIsr (\r
1681 IN EFI_SIMPLE_NETWORK_PROTOCOL * This,\r
1682 IN UINTN *FrameLength,\r
1683 IN UINTN *FrameHeaderLength, OPTIONAL\r
1684 IN UINT8 *Frame, OPTIONAL\r
1685 IN UINT8 *ProtType, OPTIONAL\r
1686 IN UINT8 *PktType OPTIONAL\r
1687 )\r
1688{\r
1689 EFI_STATUS Status;\r
1690 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
1691 BOOLEAN FrameReceived;\r
1692\r
1693 if (This == NULL) {\r
1694 return EFI_INVALID_PARAMETER;\r
1695 }\r
1696\r
1697 Status = EFI_SUCCESS;\r
1698 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
1699\r
1700 if (SimpleNetworkDevice == NULL) {\r
1701 return EFI_DEVICE_ERROR;\r
1702 }\r
1703\r
1704 FrameReceived = FALSE;\r
1705\r
1706 //\r
1707 // Verify that the current state of the adapter is valid for this call.\r
1708 //\r
1709 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
1710 case EfiSimpleNetworkInitialized:\r
1711 break;\r
1712\r
1713 case EfiSimpleNetworkStopped:\r
1714 return EFI_NOT_STARTED;\r
1715\r
1716 case EfiSimpleNetworkStarted:\r
1717 default:\r
1718 return EFI_DEVICE_ERROR;\r
1719 }\r
1720\r
1721 DEBUG ((DEBUG_NET, "Isr() IsrValid = %d\n", SimpleNetworkDevice->IsrValid));\r
1722\r
1723 if (!SimpleNetworkDevice->IsrValid) {\r
1724 //\r
1725 // Call 16 bit UNDI ROM to open the network interface\r
1726 //\r
1727 ZeroMem (&SimpleNetworkDevice->Isr, sizeof (PXENV_UNDI_ISR_T));\r
1728 SimpleNetworkDevice->Isr.Status = INIT_PXE_STATUS;\r
1729 SimpleNetworkDevice->Isr.FuncFlag = PXENV_UNDI_ISR_IN_START;\r
1730\r
1731 DEBUG ((DEBUG_NET, "Isr() START\n"));\r
1732\r
1733 Status = PxeUndiIsr (SimpleNetworkDevice, &SimpleNetworkDevice->Isr);\r
1734 if (EFI_ERROR (Status)) {\r
1735 return Status;\r
1736 }\r
1737 //\r
1738 // Check the status code from the 16 bit UNDI ROM\r
1739 //\r
1740 if (SimpleNetworkDevice->Isr.Status != PXENV_STATUS_SUCCESS) {\r
1741 return EFI_DEVICE_ERROR;\r
1742 }\r
1743 //\r
1744 // There have been no events on this UNDI interface, so return EFI_NOT_READY\r
1745 //\r
1746 if (SimpleNetworkDevice->Isr.FuncFlag == PXENV_UNDI_ISR_OUT_NOT_OURS) {\r
1747 return EFI_SUCCESS;\r
1748 }\r
1749 //\r
1750 // There is data to process, so call until all events processed.\r
1751 //\r
1752 ZeroMem (&SimpleNetworkDevice->Isr, sizeof (PXENV_UNDI_ISR_T));\r
1753 SimpleNetworkDevice->Isr.Status = INIT_PXE_STATUS;\r
1754 SimpleNetworkDevice->Isr.FuncFlag = PXENV_UNDI_ISR_IN_PROCESS;\r
1755\r
1756 DEBUG ((DEBUG_NET, "Isr() PROCESS\n"));\r
1757\r
1758 Status = PxeUndiIsr (SimpleNetworkDevice, &SimpleNetworkDevice->Isr);\r
1759 if (EFI_ERROR (Status)) {\r
1760 return Status;\r
1761 }\r
1762\r
1763 SimpleNetworkDevice->IsrValid = TRUE;\r
1764 }\r
1765 //\r
1766 // Call UNDI GET_NEXT until DONE\r
1767 //\r
1768 while (SimpleNetworkDevice->Isr.FuncFlag != PXENV_UNDI_ISR_OUT_DONE) {\r
1769 //\r
1770 // Check the status code from the 16 bit UNDI ROM\r
1771 //\r
1772 if (SimpleNetworkDevice->Isr.Status != PXENV_STATUS_SUCCESS) {\r
1773 return EFI_DEVICE_ERROR;\r
1774 }\r
1775 //\r
1776 // UNDI is busy. Caller will have to call again.\r
1777 // This should never happen with a polled mode driver.\r
1778 //\r
1779 if (SimpleNetworkDevice->Isr.FuncFlag == PXENV_UNDI_ISR_OUT_BUSY) {\r
1780 DEBUG ((DEBUG_NET, " BUSY\n"));\r
1781 return EFI_SUCCESS;\r
1782 }\r
1783 //\r
1784 // Check for invalud UNDI FuncFlag\r
1785 //\r
1786 if (SimpleNetworkDevice->Isr.FuncFlag != PXENV_UNDI_ISR_OUT_RECEIVE &&\r
1787 SimpleNetworkDevice->Isr.FuncFlag != PXENV_UNDI_ISR_OUT_TRANSMIT\r
1788 ) {\r
1789 DEBUG ((DEBUG_NET, " Invalid SimpleNetworkDevice->Isr.FuncFlag value %d\n", SimpleNetworkDevice->Isr.FuncFlag));\r
1790 return EFI_DEVICE_ERROR;\r
1791 }\r
1792 //\r
1793 // Check for Transmit Event\r
1794 //\r
1795 if (SimpleNetworkDevice->Isr.FuncFlag == PXENV_UNDI_ISR_OUT_TRANSMIT) {\r
1796 DEBUG ((DEBUG_NET, " TRANSMIT\n"));\r
1797 SimpleNetworkDevice->InterruptStatus |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;\r
1798 }\r
1799 //\r
1800 // Check for Receive Event\r
1801 //\r
1802 else if (SimpleNetworkDevice->Isr.FuncFlag == PXENV_UNDI_ISR_OUT_RECEIVE) {\r
1803 //\r
1804 // note - this code will hang on a receive interrupt in a GetStatus loop\r
1805 //\r
1806 DEBUG ((DEBUG_NET, " RECEIVE\n"));\r
1807 SimpleNetworkDevice->InterruptStatus |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;\r
1808\r
1809 DEBUG ((DEBUG_NET, "SimpleNetworkDevice->Isr.BufferLength = %d\n", SimpleNetworkDevice->Isr.BufferLength));\r
1810 DEBUG ((DEBUG_NET, "SimpleNetworkDevice->Isr.FrameLength = %d\n", SimpleNetworkDevice->Isr.FrameLength));\r
1811 DEBUG ((DEBUG_NET, "SimpleNetworkDevice->Isr.FrameHeaderLength = %d\n", SimpleNetworkDevice->Isr.FrameHeaderLength));\r
1812 DEBUG (\r
1813 (\r
1814 DEBUG_NET, "SimpleNetworkDevice->Isr.Frame = %04x:%04x\n", SimpleNetworkDevice->Isr.FrameSegSel,\r
1815 SimpleNetworkDevice->Isr.FrameOffset\r
1816 )\r
1817 );\r
1818 DEBUG ((DEBUG_NET, "SimpleNetworkDevice->Isr.ProtType = 0x%02x\n", SimpleNetworkDevice->Isr.BufferLength));\r
1819 DEBUG ((DEBUG_NET, "SimpleNetworkDevice->Isr.PktType = 0x%02x\n", SimpleNetworkDevice->Isr.BufferLength));\r
1820\r
1821 if (FrameReceived) {\r
1822 return EFI_SUCCESS;\r
1823 }\r
1824\r
1825 if ((Frame == NULL) || (SimpleNetworkDevice->Isr.FrameLength > *FrameLength)) {\r
1826 DEBUG ((DEBUG_NET, "return EFI_BUFFER_TOO_SMALL *FrameLength = %08x\n", *FrameLength));\r
1827 *FrameLength = SimpleNetworkDevice->Isr.FrameLength;\r
1828 return EFI_BUFFER_TOO_SMALL;\r
1829 }\r
1830\r
1831 *FrameLength = SimpleNetworkDevice->Isr.FrameLength;\r
1832 if (FrameHeaderLength != NULL) {\r
1833 *FrameHeaderLength = SimpleNetworkDevice->Isr.FrameHeaderLength;\r
1834 }\r
1835\r
1836 if (ProtType != NULL) {\r
1837 *ProtType = SimpleNetworkDevice->Isr.ProtType;\r
1838 }\r
1839\r
1840 if (PktType != NULL) {\r
1841 *PktType = SimpleNetworkDevice->Isr.PktType;\r
1842 }\r
1843\r
1844 CopyMem (\r
1845 Frame,\r
1846 (VOID *)(UINTN) ((SimpleNetworkDevice->Isr.FrameSegSel << 4) + SimpleNetworkDevice->Isr.FrameOffset),\r
1847 SimpleNetworkDevice->Isr.BufferLength\r
1848 );\r
1849 Frame = Frame + SimpleNetworkDevice->Isr.BufferLength;\r
1850 if (SimpleNetworkDevice->Isr.BufferLength == SimpleNetworkDevice->Isr.FrameLength) {\r
1851 FrameReceived = TRUE;\r
1852 }\r
1853 }\r
1854 //\r
1855 // There is data to process, so call until all events processed.\r
1856 //\r
1857 ZeroMem (&SimpleNetworkDevice->Isr, sizeof (PXENV_UNDI_ISR_T));\r
1858 SimpleNetworkDevice->Isr.Status = INIT_PXE_STATUS;\r
1859 SimpleNetworkDevice->Isr.FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT;\r
1860\r
1861 DEBUG ((DEBUG_NET, "Isr() GET NEXT\n"));\r
1862\r
1863 Status = PxeUndiIsr (SimpleNetworkDevice, &SimpleNetworkDevice->Isr);\r
1864 if (EFI_ERROR (Status)) {\r
1865 return Status;\r
1866 }\r
1867 //\r
1868 // Check the status code from the 16 bit UNDI ROM\r
1869 //\r
1870 // if (SimpleNetworkDevice->Isr.Status != PXENV_STATUS_SUCCESS) {\r
1871 // return EFI_DEVICE_ERROR;\r
1872 // }\r
1873 //\r
1874 }\r
1875\r
1876 SimpleNetworkDevice->IsrValid = FALSE;\r
1877 return EFI_SUCCESS;\r
1878}\r
1879//\r
1880// ///////////////////////////////////////////////////////////////////////////////////////\r
1881// Simple Network Protocol Interface Functions using 16 bit UNDI Option ROMs\r
1882/////////////////////////////////////////////////////////////////////////////////////////\r
1883//\r
1884// Start()\r
1885//\r
1886/**\r
1887 Call 16 bit UNDI ROM to start the network interface\r
1888\r
1889 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
1890 \r
1891 @retval EFI_DEVICE_ERROR Network interface has not be initialized.\r
1892 @retval EFI_DEVICE_ERROR Fail to execute 16 bit ROM call.\r
1893 @retval EFI_SUCESS Success operation.\r
1894**/\r
1895EFI_STATUS\r
1896EFIAPI\r
1897Undi16SimpleNetworkStart (\r
1898 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
1899 )\r
1900{\r
1901 EFI_STATUS Status;\r
1902 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
1903 PXENV_UNDI_STARTUP_T Startup;\r
1904\r
1905 if (This == NULL) {\r
1906 return EFI_INVALID_PARAMETER;\r
1907 }\r
1908\r
1909 Status = EFI_SUCCESS;\r
1910 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
1911\r
1912 if (SimpleNetworkDevice == NULL) {\r
1913 return EFI_DEVICE_ERROR;\r
1914 }\r
1915 //\r
1916 // Verify that the current state of the adapter is valid for this call.\r
1917 //\r
1918 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
1919 case EfiSimpleNetworkStopped:\r
1920 break;\r
1921\r
1922 case EfiSimpleNetworkStarted:\r
1923 case EfiSimpleNetworkInitialized:\r
1924 return EFI_ALREADY_STARTED;\r
1925\r
1926 default:\r
1927 return EFI_DEVICE_ERROR;\r
1928 }\r
1929 //\r
1930 // Call 16 bit UNDI ROM to start the network interface\r
1931 //\r
1932 Startup.Status = INIT_PXE_STATUS;\r
1933\r
1934 Status = PxeUndiStartup (SimpleNetworkDevice, &Startup);\r
1935 if (EFI_ERROR (Status)) {\r
1936 return Status;\r
1937 }\r
1938 //\r
1939 // Check the status code from the 16 bit UNDI ROM\r
1940 //\r
1941 if (Startup.Status != PXENV_STATUS_SUCCESS) {\r
1942 return EFI_DEVICE_ERROR;\r
1943 }\r
1944 //\r
1945 // The UNDI interface has been started, so update the State.\r
1946 //\r
1947 SimpleNetworkDevice->SimpleNetworkMode.State = EfiSimpleNetworkStarted;\r
1948\r
1949 //\r
1950 //\r
1951 //\r
1952 SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting = 0;\r
1953 SimpleNetworkDevice->SimpleNetworkMode.MCastFilterCount = 0;\r
1954\r
1955 return Status;\r
1956}\r
1957//\r
1958// Stop()\r
1959//\r
1960/**\r
1961 Call 16 bit UNDI ROM to stop the network interface\r
1962\r
1963 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
1964 \r
1965 @retval EFI_DEVICE_ERROR Network interface has not be initialized.\r
1966 @retval EFI_DEVICE_ERROR Fail to execute 16 bit ROM call.\r
1967 @retval EFI_SUCESS Success operation.\r
1968**/\r
1969EFI_STATUS\r
1970EFIAPI\r
1971Undi16SimpleNetworkStop (\r
1972 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
1973 )\r
1974{\r
1975 EFI_STATUS Status;\r
1976 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
1977\r
1978 if (This == NULL) {\r
1979 return EFI_INVALID_PARAMETER;\r
1980 }\r
1981\r
1982 Status = EFI_SUCCESS;\r
1983 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
1984\r
1985 if (SimpleNetworkDevice == NULL) {\r
1986 return EFI_DEVICE_ERROR;\r
1987 }\r
1988 //\r
1989 // Verify that the current state of the adapter is valid for this call.\r
1990 //\r
1991 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
1992 case EfiSimpleNetworkStarted:\r
1993 break;\r
1994\r
1995 case EfiSimpleNetworkStopped:\r
1996 return EFI_NOT_STARTED;\r
1997\r
1998 case EfiSimpleNetworkInitialized:\r
1999 default:\r
2000 return EFI_DEVICE_ERROR;\r
2001 }\r
2002\r
2003 SimpleNetworkDevice->SimpleNetworkMode.State = EfiSimpleNetworkStopped;\r
2004\r
2005 return Status;\r
2006}\r
2007\r
2008//\r
2009// Initialize()\r
2010//\r
2011/**\r
2012 Initialize network interface \r
2013\r
2014 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
2015 @param ExtraRxBufferSize The size of extra request receive buffer.\r
2016 @param ExtraTxBufferSize The size of extra request transmit buffer.\r
2017 \r
2018 @retval EFI_DEVICE_ERROR Fail to execute 16 bit ROM call.\r
2019 @retval EFI_SUCESS Success operation.\r
2020**/\r
2021EFI_STATUS\r
2022EFIAPI\r
2023Undi16SimpleNetworkInitialize (\r
2024 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
2025 IN UINTN ExtraRxBufferSize OPTIONAL,\r
2026 IN UINTN ExtraTxBufferSize OPTIONAL\r
2027 )\r
2028{\r
2029 EFI_STATUS Status;\r
2030 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
2031 PXENV_UNDI_INITIALIZE_T Initialize;\r
2032 PXENV_UNDI_OPEN_T Open;\r
2033\r
2034 if (This == NULL) {\r
2035 return EFI_INVALID_PARAMETER;\r
2036 }\r
2037\r
2038 Status = EFI_SUCCESS;\r
2039 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
2040\r
2041 if (SimpleNetworkDevice == NULL) {\r
2042 return EFI_DEVICE_ERROR;\r
2043 }\r
2044 //\r
2045 // Verify that the current state of the adapter is valid for this call.\r
2046 //\r
2047 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
2048 case EfiSimpleNetworkStopped:\r
2049 return EFI_NOT_STARTED;\r
2050\r
2051 case EfiSimpleNetworkStarted:\r
2052 break;\r
2053\r
2054 case EfiSimpleNetworkInitialized:\r
2055 default:\r
2056 return EFI_DEVICE_ERROR;\r
2057 }\r
2058 //\r
2059 // Call 16 bit UNDI ROM to start the network interface\r
2060 //\r
2061 Initialize.Status = INIT_PXE_STATUS;\r
2062 Initialize.ProtocolIni = 0;\r
2063\r
2064 Status = PxeUndiInitialize (SimpleNetworkDevice, &Initialize);\r
2065\r
2066 if (EFI_ERROR (Status)) {\r
2067 DEBUG ((DEBUG_ERROR, "ERROR : PxeUndiInitialize() - Status = %r\n", Status));\r
2068 DEBUG ((DEBUG_ERROR, "Initialize.Status == %xh\n", Initialize.Status));\r
2069\r
2070 if (Initialize.Status == PXENV_STATUS_UNDI_MEDIATEST_FAILED) {\r
2071 Status = EFI_NO_MEDIA;\r
2072 }\r
2073\r
2074 return Status;\r
2075 }\r
2076 //\r
2077 // Check the status code from the 16 bit UNDI ROM\r
2078 //\r
2079 if (Initialize.Status != PXENV_STATUS_SUCCESS) {\r
2080 DEBUG ((DEBUG_ERROR, "ERROR : PxeUndiInitialize() - Initialize.Status = %04x\n", Initialize.Status));\r
2081 return EFI_DEVICE_ERROR;\r
2082 }\r
2083 //\r
2084 // Call 16 bit UNDI ROM to open the network interface\r
2085 //\r
2086 Open.Status = INIT_PXE_STATUS;\r
2087 Open.OpenFlag = 0;\r
2088 Open.PktFilter = Undi16GetPacketFilterSetting (SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting);\r
2089 Undi16GetMCastFilters (\r
2090 &SimpleNetworkDevice->SimpleNetworkMode,\r
2091 &Open.McastBuffer,\r
2092 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
2093 );\r
2094\r
2095 Status = PxeUndiOpen (SimpleNetworkDevice, &Open);\r
2096\r
2097 if (EFI_ERROR (Status)) {\r
2098 DEBUG ((DEBUG_ERROR, "ERROR : PxeUndiOpen() - Status = %r\n", Status));\r
2099 return Status;\r
2100 }\r
2101 //\r
2102 // Check the status code from the 16 bit UNDI ROM\r
2103 //\r
2104 if (Open.Status != PXENV_STATUS_SUCCESS) {\r
2105 DEBUG ((DEBUG_ERROR, "ERROR : PxeUndiOpen() - Open.Status = %04x\n", Open.Status));\r
2106 return EFI_DEVICE_ERROR;\r
2107 }\r
2108 //\r
2109 // The UNDI interface has been initialized, so update the State.\r
2110 //\r
2111 SimpleNetworkDevice->SimpleNetworkMode.State = EfiSimpleNetworkInitialized;\r
2112\r
2113 //\r
2114 // If initialize succeeds, then assume that media is present.\r
2115 //\r
2116 SimpleNetworkDevice->SimpleNetworkMode.MediaPresent = TRUE;\r
2117\r
2118 //\r
2119 // Reset the recycled transmit buffer FIFO\r
2120 //\r
2121 SimpleNetworkDevice->TxBufferFifo.First = 0;\r
2122 SimpleNetworkDevice->TxBufferFifo.Last = 0;\r
2123 SimpleNetworkDevice->IsrValid = FALSE;\r
2124\r
2125 return Status;\r
2126}\r
2127//\r
2128// Reset()\r
2129//\r
2130/**\r
2131 Reset network interface.\r
2132\r
2133 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
2134 @param ExtendedVerification Need extended verfication.\r
2135 \r
2136 @retval EFI_INVALID_PARAMETER Invalid This paramter.\r
2137 @retval EFI_DEVICE_ERROR Network device has not been initialized.\r
2138 @retval EFI_NOT_STARTED Network device has been stopped.\r
2139 @retval EFI_DEVICE_ERROR Invalid status for network device\r
2140 @retval EFI_SUCCESS Success operation.\r
2141**/\r
2142EFI_STATUS\r
2143EFIAPI\r
2144Undi16SimpleNetworkReset (\r
2145 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
2146 IN BOOLEAN ExtendedVerification\r
2147 )\r
2148{\r
2149 EFI_STATUS Status;\r
2150 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
2151 PXENV_UNDI_RESET_T Reset;\r
2152 UINT16 Rx_filter;\r
2153\r
2154 if (This == NULL) {\r
2155 return EFI_INVALID_PARAMETER;\r
2156 }\r
2157\r
2158 Status = EFI_SUCCESS;\r
2159 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
2160\r
2161 if (SimpleNetworkDevice == NULL) {\r
2162 return EFI_DEVICE_ERROR;\r
2163 }\r
2164 //\r
2165 // Verify that the current state of the adapter is valid for this call.\r
2166 //\r
2167 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
2168 case EfiSimpleNetworkStopped:\r
2169 return EFI_NOT_STARTED;\r
2170\r
2171 case EfiSimpleNetworkInitialized:\r
2172 break;\r
2173\r
2174 case EfiSimpleNetworkStarted:\r
2175 default:\r
2176 return EFI_DEVICE_ERROR;\r
2177 }\r
2178\r
2179 Reset.Status = INIT_PXE_STATUS;\r
2180\r
2181 Rx_filter = Undi16GetPacketFilterSetting (SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting);\r
2182\r
2183 Undi16GetMCastFilters (\r
2184 &SimpleNetworkDevice->SimpleNetworkMode,\r
2185 &Reset.R_Mcast_Buf,\r
2186 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
2187 );\r
2188\r
2189 Status = PxeUndiResetNic (SimpleNetworkDevice, &Reset, Rx_filter);\r
2190\r
2191 if (EFI_ERROR (Status)) {\r
2192 return Status;\r
2193 }\r
2194 //\r
2195 // Check the status code from the 16 bit UNDI ROM\r
2196 //\r
2197 if (Reset.Status != PXENV_STATUS_SUCCESS) {\r
2198 return EFI_DEVICE_ERROR;\r
2199 }\r
2200 //\r
2201 // Reset the recycled transmit buffer FIFO\r
2202 //\r
2203 SimpleNetworkDevice->TxBufferFifo.First = 0;\r
2204 SimpleNetworkDevice->TxBufferFifo.Last = 0;\r
2205 SimpleNetworkDevice->IsrValid = FALSE;\r
2206\r
2207 return Status;\r
2208}\r
2209//\r
2210// Shutdown()\r
2211//\r
2212/**\r
2213 Shutdown network interface.\r
2214\r
2215 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
2216 \r
2217 @retval EFI_INVALID_PARAMETER Invalid This paramter.\r
2218 @retval EFI_DEVICE_ERROR Network device has not been initialized.\r
2219 @retval EFI_NOT_STARTED Network device has been stopped.\r
2220 @retval EFI_DEVICE_ERROR Invalid status for network device\r
2221 @retval EFI_SUCCESS Success operation.\r
2222**/\r
2223EFI_STATUS\r
2224EFIAPI\r
2225Undi16SimpleNetworkShutdown (\r
2226 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
2227 )\r
2228{\r
2229 EFI_STATUS Status;\r
2230 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
2231 PXENV_UNDI_CLOSE_T Close;\r
2232 PXENV_UNDI_SHUTDOWN_T Shutdown;\r
2233\r
2234 if (This == NULL) {\r
2235 return EFI_INVALID_PARAMETER;\r
2236 }\r
2237\r
2238 Status = EFI_SUCCESS;\r
2239 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
2240\r
2241 if (SimpleNetworkDevice == NULL) {\r
2242 return EFI_DEVICE_ERROR;\r
2243 }\r
2244 //\r
2245 // Verify that the current state of the adapter is valid for this call.\r
2246 //\r
2247 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
2248 case EfiSimpleNetworkStopped:\r
2249 return EFI_NOT_STARTED;\r
2250\r
2251 case EfiSimpleNetworkInitialized:\r
2252 break;\r
2253\r
2254 case EfiSimpleNetworkStarted:\r
2255 default:\r
2256 return EFI_DEVICE_ERROR;\r
2257 }\r
2258\r
2259 SimpleNetworkDevice->IsrValid = FALSE;\r
2260\r
2261 //\r
2262 // Call 16 bit UNDI ROM to start the network interface\r
2263 //\r
2264 Close.Status = INIT_PXE_STATUS;\r
2265\r
2266 Status = PxeUndiClose (SimpleNetworkDevice, &Close);\r
2267\r
2268 if (EFI_ERROR (Status)) {\r
2269 return Status;\r
2270 }\r
2271 //\r
2272 // Check the status code from the 16 bit UNDI ROM\r
2273 //\r
2274 if (Close.Status != PXENV_STATUS_SUCCESS) {\r
2275 return EFI_DEVICE_ERROR;\r
2276 }\r
2277 //\r
2278 // Call 16 bit UNDI ROM to open the network interface\r
2279 //\r
2280 Shutdown.Status = INIT_PXE_STATUS;\r
2281\r
2282 Status = PxeUndiShutdown (SimpleNetworkDevice, &Shutdown);\r
2283\r
2284 if (EFI_ERROR (Status)) {\r
2285 return Status;\r
2286 }\r
2287 //\r
2288 // Check the status code from the 16 bit UNDI ROM\r
2289 //\r
2290 if (Shutdown.Status != PXENV_STATUS_SUCCESS) {\r
2291 return EFI_DEVICE_ERROR;\r
2292 }\r
2293 //\r
2294 // The UNDI interface has been initialized, so update the State.\r
2295 //\r
2296 SimpleNetworkDevice->SimpleNetworkMode.State = EfiSimpleNetworkStarted;\r
2297\r
2298 //\r
2299 // If shutdown succeeds, then assume that media is not present.\r
2300 //\r
2301 SimpleNetworkDevice->SimpleNetworkMode.MediaPresent = FALSE;\r
2302\r
2303 //\r
2304 // Reset the recycled transmit buffer FIFO\r
2305 //\r
2306 SimpleNetworkDevice->TxBufferFifo.First = 0;\r
2307 SimpleNetworkDevice->TxBufferFifo.Last = 0;\r
2308\r
2309 //\r
2310 // A short delay. Without this an initialize immediately following\r
2311 // a shutdown will cause some versions of UNDI-16 to stop operating.\r
2312 //\r
2313 gBS->Stall (250000);\r
2314\r
2315 return Status;\r
2316}\r
2317//\r
2318// ReceiveFilters()\r
2319//\r
2320/**\r
2321 Reset network interface.\r
2322\r
2323 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
2324 @param Enable Enable mask value\r
2325 @param Disable Disable mask value\r
2326 @param ResetMCastFilter Whether reset multi cast filter or not\r
2327 @param MCastFilterCnt Count of mutli cast filter for different MAC address\r
2328 @param MCastFilter Buffer for mustli cast filter for different MAC address.\r
2329 \r
2330 @retval EFI_INVALID_PARAMETER Invalid This paramter.\r
2331 @retval EFI_DEVICE_ERROR Network device has not been initialized.\r
2332 @retval EFI_NOT_STARTED Network device has been stopped.\r
2333 @retval EFI_DEVICE_ERROR Invalid status for network device\r
2334 @retval EFI_SUCCESS Success operation.\r
2335**/\r
2336EFI_STATUS\r
2337EFIAPI\r
2338Undi16SimpleNetworkReceiveFilters (\r
2339 IN EFI_SIMPLE_NETWORK_PROTOCOL * This,\r
2340 IN UINT32 Enable,\r
2341 IN UINT32 Disable,\r
2342 IN BOOLEAN ResetMCastFilter,\r
2343 IN UINTN MCastFilterCnt OPTIONAL,\r
2344 IN EFI_MAC_ADDRESS * MCastFilter OPTIONAL\r
2345 )\r
2346{\r
2347 EFI_STATUS Status;\r
2348 UINTN Index;\r
2349 UINT32 NewFilter;\r
2350 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
2351 PXENV_UNDI_CLOSE_T Close;\r
2352 PXENV_UNDI_OPEN_T Open;\r
2353\r
2354 if (This == NULL) {\r
2355 return EFI_INVALID_PARAMETER;\r
2356 }\r
2357\r
2358 Status = EFI_SUCCESS;\r
2359 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
2360\r
2361 if (SimpleNetworkDevice == NULL) {\r
2362 return EFI_DEVICE_ERROR;\r
2363 }\r
2364 //\r
2365 // Verify that the current state of the adapter is valid for this call.\r
2366 //\r
2367 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
2368 case EfiSimpleNetworkStopped:\r
2369 return EFI_NOT_STARTED;\r
2370\r
2371 case EfiSimpleNetworkInitialized:\r
2372 break;\r
2373\r
2374 case EfiSimpleNetworkStarted:\r
2375 default:\r
2376 return EFI_DEVICE_ERROR;\r
2377 }\r
2378 //\r
2379 // First deal with possible filter setting changes\r
2380 //\r
2381 if ((Enable == 0) && (Disable == 0) && !ResetMCastFilter) {\r
2382 return EFI_SUCCESS;\r
2383 }\r
2384\r
2385 NewFilter = (SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting | Enable) &~Disable;\r
2386\r
2387 if ((NewFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {\r
2388 if ((MCastFilterCnt == 0) || (MCastFilter == 0) || MCastFilterCnt > SimpleNetworkDevice->SimpleNetworkMode.MaxMCastFilterCount) {\r
2389 return EFI_INVALID_PARAMETER;\r
2390 }\r
2391 }\r
2392 //\r
2393 // Call 16 bit UNDI ROM to close the network interface\r
2394 //\r
2395 Close.Status = INIT_PXE_STATUS;\r
2396\r
2397 Status = PxeUndiClose (SimpleNetworkDevice, &Close);\r
2398\r
2399 if (EFI_ERROR (Status)) {\r
2400 return Status;\r
2401 }\r
2402 //\r
2403 // Check the status code from the 16 bit UNDI ROM\r
2404 //\r
2405 if (Close.Status != PXENV_STATUS_SUCCESS) {\r
2406 return EFI_DEVICE_ERROR;\r
2407 }\r
2408 //\r
2409 // Call 16 bit UNDI ROM to open the network interface\r
2410 //\r
2411 //\r
2412 // Reset the recycled transmit buffer FIFO\r
2413 //\r
2414 SimpleNetworkDevice->TxBufferFifo.First = 0;\r
2415 SimpleNetworkDevice->TxBufferFifo.Last = 0;\r
2416\r
2417 //\r
2418 // Call 16 bit UNDI ROM to open the network interface\r
2419 //\r
2420 ZeroMem (&Open, sizeof Open);\r
2421\r
2422 Open.Status = INIT_PXE_STATUS;\r
2423 Open.PktFilter = Undi16GetPacketFilterSetting (NewFilter);\r
2424\r
2425 if ((NewFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {\r
2426 //\r
2427 // Copy the MAC addresses into the UNDI open parameter structure\r
2428 //\r
2429 Open.McastBuffer.MCastAddrCount = (UINT16) MCastFilterCnt;\r
2430 for (Index = 0; Index < MCastFilterCnt; ++Index) {\r
2431 CopyMem (\r
2432 Open.McastBuffer.MCastAddr[Index],\r
2433 &MCastFilter[Index],\r
2434 sizeof Open.McastBuffer.MCastAddr[Index]\r
2435 );\r
2436 }\r
2437 } else if (!ResetMCastFilter) {\r
2438 for (Index = 0; Index < SimpleNetworkDevice->SimpleNetworkMode.MCastFilterCount; ++Index) {\r
2439 CopyMem (\r
2440 Open.McastBuffer.MCastAddr[Index],\r
2441 &SimpleNetworkDevice->SimpleNetworkMode.MCastFilter[Index],\r
2442 sizeof Open.McastBuffer.MCastAddr[Index]\r
2443 );\r
2444 }\r
2445 }\r
2446\r
2447 Status = PxeUndiOpen (SimpleNetworkDevice, &Open);\r
2448\r
2449 if (EFI_ERROR (Status)) {\r
2450 return Status;\r
2451 }\r
2452 //\r
2453 // Check the status code from the 16 bit UNDI ROM\r
2454 //\r
2455 if (Open.Status != PXENV_STATUS_SUCCESS) {\r
2456 return EFI_DEVICE_ERROR;\r
2457 }\r
2458\r
2459 SimpleNetworkDevice->IsrValid = FALSE;\r
2460 SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting = NewFilter;\r
2461\r
2462 if ((NewFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {\r
2463 SimpleNetworkDevice->SimpleNetworkMode.MCastFilterCount = (UINT32) MCastFilterCnt;\r
2464 for (Index = 0; Index < MCastFilterCnt; ++Index) {\r
2465 CopyMem (\r
2466 &SimpleNetworkDevice->SimpleNetworkMode.MCastFilter[Index],\r
2467 &MCastFilter[Index],\r
2468 sizeof (EFI_MAC_ADDRESS)\r
2469 ); \r
2470 }\r
2471 }\r
2472 //\r
2473 // Read back multicast addresses.\r
2474 //\r
2475 return EFI_SUCCESS;\r
2476}\r
2477//\r
2478// StationAddress()\r
2479//\r
2480/**\r
2481 Set new MAC address.\r
2482\r
2483 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
2484 @param Reset Whether reset station MAC address to permenent address\r
2485 @param New A pointer to New address\r
2486 \r
2487 @retval EFI_INVALID_PARAMETER Invalid This paramter.\r
2488 @retval EFI_DEVICE_ERROR Network device has not been initialized.\r
2489 @retval EFI_NOT_STARTED Network device has been stopped.\r
2490 @retval EFI_DEVICE_ERROR Invalid status for network device\r
2491 @retval EFI_SUCCESS Success operation.\r
2492**/\r
2493EFI_STATUS\r
2494EFIAPI\r
2495Undi16SimpleNetworkStationAddress (\r
2496 IN EFI_SIMPLE_NETWORK_PROTOCOL * This,\r
2497 IN BOOLEAN Reset,\r
2498 IN EFI_MAC_ADDRESS * New OPTIONAL\r
2499 )\r
2500{\r
2501 EFI_STATUS Status;\r
2502 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
2503 PXENV_UNDI_SET_STATION_ADDR_T SetStationAddr;\r
2504 //\r
2505 // EFI_DEVICE_PATH_PROTOCOL *OldDevicePath;\r
2506 //\r
2507 PXENV_UNDI_CLOSE_T Close;\r
2508 PXENV_UNDI_OPEN_T Open;\r
2509\r
2510 if (This == NULL) {\r
2511 return EFI_INVALID_PARAMETER;\r
2512 }\r
2513\r
2514 Status = EFI_SUCCESS;\r
2515\r
2516 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
2517\r
2518 if (SimpleNetworkDevice == NULL) {\r
2519 return EFI_DEVICE_ERROR;\r
2520 }\r
2521 //\r
2522 // Verify that the current state of the adapter is valid for this call.\r
2523 //\r
2524 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
2525 case EfiSimpleNetworkInitialized:\r
2526 break;\r
2527\r
2528 case EfiSimpleNetworkStopped:\r
2529 return EFI_NOT_STARTED;\r
2530\r
2531 case EfiSimpleNetworkStarted:\r
2532 default:\r
2533 return EFI_DEVICE_ERROR;\r
2534 }\r
2535 //\r
2536 // Call 16 bit UNDI ROM to open the network interface\r
2537 //\r
2538 SetStationAddr.Status = INIT_PXE_STATUS;\r
2539\r
2540 if (Reset) {\r
2541 //\r
2542 // If we are reseting the Station Address to the permanent address, and the\r
2543 // Station Address is not programmable, then just return EFI_SUCCESS.\r
2544 //\r
2545 if (!SimpleNetworkDevice->SimpleNetworkMode.MacAddressChangeable) {\r
2546 return EFI_SUCCESS;\r
2547 }\r
2548 //\r
2549 // If the address is already the permanent address, then just return success.\r
2550 //\r
2551 if (CompareMem (\r
2552 &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,\r
2553 &SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress,\r
2554 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
2555 ) == 0) {\r
2556 return EFI_SUCCESS;\r
2557 }\r
2558 //\r
2559 // Copy the adapters permanent address to the new station address\r
2560 //\r
2561 CopyMem (\r
2562 &SetStationAddr.StationAddress,\r
2563 &SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress,\r
2564 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
2565 );\r
2566 } else {\r
2567 //\r
2568 // If we are setting the Station Address, and the\r
2569 // Station Address is not programmable, return invalid parameter.\r
2570 //\r
2571 if (!SimpleNetworkDevice->SimpleNetworkMode.MacAddressChangeable) {\r
2572 return EFI_INVALID_PARAMETER;\r
2573 }\r
2574 //\r
2575 // If the address is already the new address, then just return success.\r
2576 //\r
2577 if (CompareMem (\r
2578 &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,\r
2579 New,\r
2580 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
2581 ) == 0) {\r
2582 return EFI_SUCCESS;\r
2583 }\r
2584 //\r
2585 // Copy New to the new station address\r
2586 //\r
2587 CopyMem (\r
2588 &SetStationAddr.StationAddress,\r
2589 New,\r
2590 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
2591 );\r
2592\r
2593 }\r
2594 //\r
2595 // Call 16 bit UNDI ROM to stop the network interface\r
2596 //\r
2597 Close.Status = INIT_PXE_STATUS;\r
2598\r
2599 PxeUndiClose (SimpleNetworkDevice, &Close);\r
2600\r
2601 //\r
2602 // Call 16-bit UNDI ROM to set the station address\r
2603 //\r
2604 SetStationAddr.Status = PXENV_STATUS_SUCCESS;\r
2605\r
2606 Status = PxeUndiSetStationAddr (SimpleNetworkDevice, &SetStationAddr);\r
2607\r
2608 //\r
2609 // Call 16-bit UNDI ROM to start the network interface\r
2610 //\r
2611 Open.Status = PXENV_STATUS_SUCCESS;\r
2612 Open.OpenFlag = 0;\r
2613 Open.PktFilter = Undi16GetPacketFilterSetting (SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting);\r
2614 Undi16GetMCastFilters (\r
2615 &SimpleNetworkDevice->SimpleNetworkMode,\r
2616 &Open.McastBuffer,\r
2617 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
2618 );\r
2619\r
2620 PxeUndiOpen (SimpleNetworkDevice, &Open);\r
2621\r
2622 //\r
2623 // Check status from station address change\r
2624 //\r
2625 if (EFI_ERROR (Status)) {\r
2626 return Status;\r
2627 }\r
2628 //\r
2629 // Check the status code from the 16 bit UNDI ROM\r
2630 //\r
2631 if (SetStationAddr.Status != PXENV_STATUS_SUCCESS) {\r
2632 return EFI_DEVICE_ERROR;\r
2633 }\r
2634\r
2635 CopyMem (\r
2636 &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,\r
2637 &SetStationAddr.StationAddress,\r
2638 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
2639 );\r
2640\r
2641#if 0 /* The device path is based on the permanent address not the current address. */\r
2642 //\r
2643 // The station address was changed, so update the device path with the new MAC address.\r
2644 //\r
2645 OldDevicePath = SimpleNetworkDevice->DevicePath;\r
2646 SimpleNetworkDevice->DevicePath = DuplicateDevicePath (SimpleNetworkDevice->BaseDevicePath);\r
2647 SimpleNetworkAppendMacAddressDevicePath (\r
2648 &SimpleNetworkDevice->DevicePath,\r
2649 &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress\r
2650 );\r
2651\r
2652 Status = LibReinstallProtocolInterfaces (\r
2653 SimpleNetworkDevice->Handle,\r
2654 &DevicePathProtocol,\r
2655 OldDevicePath,\r
2656 SimpleNetworkDevice->DevicePath,\r
2657 NULL\r
2658 );\r
2659\r
2660 if (EFI_ERROR (Status)) {\r
2661 DEBUG ((DEBUG_ERROR, "Failed to reinstall the DevicePath protocol for the Simple Network Device\n"));\r
2662 DEBUG ((DEBUG_ERROR, " Status = %r\n", Status));\r
2663 }\r
2664\r
2665 FreePool (OldDevicePath);\r
2666#endif /* 0 */\r
2667\r
2668 return Status;\r
2669}\r
2670//\r
2671// Statistics()\r
2672//\r
2673/**\r
2674 Resets or collects the statistics on a network interface.\r
2675\r
2676 @param This Protocol instance pointer.\r
2677 @param Reset Set to TRUE to reset the statistics for the network interface.\r
2678 @param StatisticsSize On input the size, in bytes, of StatisticsTable. On\r
2679 output the size, in bytes, of the resulting table of\r
2680 statistics.\r
2681 @param StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that\r
2682 contains the statistics.\r
2683\r
2684 @retval EFI_SUCCESS The statistics were collected from the network interface.\r
2685 @retval EFI_NOT_STARTED The network interface has not been started.\r
2686 @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer\r
2687 size needed to hold the statistics is returned in\r
2688 StatisticsSize.\r
2689 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
2690 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
2691 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
2692\r
2693**/\r
2694EFI_STATUS\r
2695EFIAPI\r
2696Undi16SimpleNetworkStatistics (\r
2697 IN EFI_SIMPLE_NETWORK_PROTOCOL * This,\r
2698 IN BOOLEAN Reset,\r
2699 IN OUT UINTN *StatisticsSize OPTIONAL,\r
2700 OUT EFI_NETWORK_STATISTICS * StatisticsTable OPTIONAL\r
2701 )\r
2702{\r
2703 EFI_STATUS Status;\r
2704 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
2705 PXENV_UNDI_CLEAR_STATISTICS_T ClearStatistics;\r
2706 PXENV_UNDI_GET_STATISTICS_T GetStatistics;\r
2707\r
2708 if (This == NULL) {\r
2709 return EFI_INVALID_PARAMETER;\r
2710 }\r
2711\r
2712 Status = EFI_SUCCESS;\r
2713 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
2714\r
2715 if (SimpleNetworkDevice == NULL) {\r
2716 return EFI_DEVICE_ERROR;\r
2717 }\r
2718 //\r
2719 // Verify that the current state of the adapter is valid for this call.\r
2720 //\r
2721 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
2722 case EfiSimpleNetworkInitialized:\r
2723 break;\r
2724\r
2725 case EfiSimpleNetworkStopped:\r
2726 return EFI_NOT_STARTED;\r
2727\r
2728 case EfiSimpleNetworkStarted:\r
2729 default:\r
2730 return EFI_DEVICE_ERROR;\r
2731 }\r
2732\r
2733 if ((StatisticsSize != NULL) && (*StatisticsSize != 0) && (StatisticsTable == NULL)) {\r
2734 return EFI_INVALID_PARAMETER;\r
2735 }\r
2736\r
2737 //\r
2738 // If Reset is TRUE, then clear all the statistics.\r
2739 //\r
2740 if (Reset) {\r
2741\r
2742 DEBUG ((DEBUG_NET, " RESET Statistics\n"));\r
2743\r
2744 //\r
2745 // Call 16 bit UNDI ROM to open the network interface\r
2746 //\r
2747 ClearStatistics.Status = INIT_PXE_STATUS;\r
2748\r
2749 Status = PxeUndiClearStatistics (SimpleNetworkDevice, &ClearStatistics);\r
2750\r
2751 if (EFI_ERROR (Status)) {\r
2752 return Status;\r
2753 }\r
2754 //\r
2755 // Check the status code from the 16 bit UNDI ROM\r
2756 //\r
2757 if (ClearStatistics.Status != PXENV_STATUS_SUCCESS) {\r
2758 return EFI_DEVICE_ERROR;\r
2759 }\r
2760\r
2761 DEBUG ((DEBUG_NET, " RESET Statistics Complete"));\r
2762 }\r
2763\r
2764 if (StatisticsSize != NULL) {\r
2765 EFI_NETWORK_STATISTICS LocalStatisticsTable;\r
2766\r
2767 DEBUG ((DEBUG_NET, " GET Statistics\n"));\r
2768\r
2769 //\r
2770 // If the size if valid, then see if the table is valid\r
2771 //\r
2772 if (StatisticsTable == NULL) {\r
2773 DEBUG ((DEBUG_NET, " StatisticsTable is NULL\n"));\r
2774 return EFI_INVALID_PARAMETER;\r
2775 }\r
2776 //\r
2777 // Call 16 bit UNDI ROM to open the network interface\r
2778 //\r
2779 GetStatistics.Status = INIT_PXE_STATUS;\r
2780 GetStatistics.XmtGoodFrames = 0;\r
2781 GetStatistics.RcvGoodFrames = 0;\r
2782 GetStatistics.RcvCRCErrors = 0;\r
2783 GetStatistics.RcvResourceErrors = 0;\r
2784\r
2785 Status = PxeUndiGetStatistics (SimpleNetworkDevice, &GetStatistics);\r
2786\r
2787 if (EFI_ERROR (Status)) {\r
2788 return Status;\r
2789 }\r
2790 //\r
2791 // Check the status code from the 16 bit UNDI ROM\r
2792 //\r
2793 if (GetStatistics.Status != PXENV_STATUS_SUCCESS) {\r
2794 return EFI_DEVICE_ERROR;\r
2795 }\r
2796 //\r
2797 // Fill in the Statistics Table with the collected values.\r
2798 //\r
2799 SetMem (&LocalStatisticsTable, sizeof LocalStatisticsTable, 0xff);\r
2800\r
2801 LocalStatisticsTable.TxGoodFrames = GetStatistics.XmtGoodFrames;\r
2802 LocalStatisticsTable.RxGoodFrames = GetStatistics.RcvGoodFrames;\r
2803 LocalStatisticsTable.RxCrcErrorFrames = GetStatistics.RcvCRCErrors;\r
2804 LocalStatisticsTable.RxDroppedFrames = GetStatistics.RcvResourceErrors;\r
2805\r
2806 CopyMem (StatisticsTable, &LocalStatisticsTable, *StatisticsSize);\r
2807\r
2808 DEBUG (\r
2809 (DEBUG_NET,\r
2810 " Statistics Collected : Size=%d Buf=%08x\n",\r
2811 *StatisticsSize,\r
2812 StatisticsTable)\r
2813 );\r
2814\r
2815 DEBUG ((DEBUG_NET, " GET Statistics Complete"));\r
2816\r
2817 if (*StatisticsSize < sizeof LocalStatisticsTable) {\r
2818 DEBUG ((DEBUG_NET, " BUFFER TOO SMALL\n"));\r
2819 Status = EFI_BUFFER_TOO_SMALL;\r
2820 }\r
2821\r
2822 *StatisticsSize = sizeof LocalStatisticsTable;\r
2823\r
2824 return Status;\r
2825\r
2826 }\r
2827\r
2828 return EFI_SUCCESS;\r
2829}\r
2830//\r
2831// MCastIpToMac()\r
2832//\r
2833/**\r
2834 Translate IP address to MAC address.\r
2835\r
2836 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
2837 @param IPv6 IPv6 or IPv4\r
2838 @param IP A pointer to given Ip address.\r
2839 @param MAC On return, translated MAC address.\r
2840 \r
2841 @retval EFI_INVALID_PARAMETER Invalid This paramter.\r
2842 @retval EFI_INVALID_PARAMETER Invalid IP address.\r
2843 @retval EFI_INVALID_PARAMETER Invalid return buffer for holding MAC address.\r
2844 @retval EFI_UNSUPPORTED Do not support IPv6 \r
2845 @retval EFI_DEVICE_ERROR Network device has not been initialized.\r
2846 @retval EFI_NOT_STARTED Network device has been stopped.\r
2847 @retval EFI_DEVICE_ERROR Invalid status for network device\r
2848 @retval EFI_SUCCESS Success operation.\r
2849**/\r
2850EFI_STATUS\r
2851EFIAPI\r
2852Undi16SimpleNetworkMCastIpToMac (\r
2853 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
2854 IN BOOLEAN IPv6,\r
2855 IN EFI_IP_ADDRESS *IP,\r
2856 OUT EFI_MAC_ADDRESS *MAC\r
2857 )\r
2858{\r
2859 EFI_STATUS Status;\r
2860 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
2861 PXENV_UNDI_GET_MCAST_ADDR_T GetMcastAddr;\r
2862\r
2863 if (This == NULL || IP == NULL || MAC == NULL) {\r
2864 return EFI_INVALID_PARAMETER;\r
2865 }\r
2866\r
2867 Status = EFI_SUCCESS;\r
2868 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
2869\r
2870 if (SimpleNetworkDevice == NULL) {\r
2871 return EFI_DEVICE_ERROR;\r
2872 }\r
2873 //\r
2874 // Verify that the current state of the adapter is valid for this call.\r
2875 //\r
2876 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
2877 case EfiSimpleNetworkStopped:\r
2878 return EFI_NOT_STARTED;\r
2879\r
2880 case EfiSimpleNetworkInitialized:\r
2881 break;\r
2882\r
2883 case EfiSimpleNetworkStarted:\r
2884 default:\r
2885 return EFI_DEVICE_ERROR;\r
2886 }\r
2887 //\r
2888 // 16 bit UNDI Option ROMS do not support IPv6. Check for IPv6 usage.\r
2889 //\r
2890 if (IPv6) {\r
2891 return EFI_UNSUPPORTED;\r
2892 }\r
2893 //\r
2894 // Call 16 bit UNDI ROM to open the network interface\r
2895 //\r
2896 GetMcastAddr.Status = INIT_PXE_STATUS;\r
2897 CopyMem (&GetMcastAddr.InetAddr, IP, 4);\r
2898\r
2899 Status = PxeUndiGetMcastAddr (SimpleNetworkDevice, &GetMcastAddr);\r
2900\r
2901 if (EFI_ERROR (Status)) {\r
2902 return Status;\r
2903 }\r
2904 //\r
2905 // Check the status code from the 16 bit UNDI ROM\r
2906 //\r
2907 if (GetMcastAddr.Status != PXENV_STATUS_SUCCESS) {\r
2908 return EFI_DEVICE_ERROR;\r
2909 }\r
2910 //\r
2911 // Copy the MAC address from the returned data structure.\r
2912 //\r
2913 CopyMem (\r
2914 MAC,\r
2915 &GetMcastAddr.MediaAddr,\r
2916 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
2917 );\r
2918\r
2919 return Status;\r
2920}\r
2921//\r
2922// NvData()\r
2923//\r
2924/**\r
2925 Performs read and write operations on the NVRAM device attached to a \r
2926 network interface.\r
2927\r
2928 @param This The protocol instance pointer.\r
2929 @param ReadWrite TRUE for read operations, FALSE for write operations.\r
2930 @param Offset Byte offset in the NVRAM device at which to start the read or\r
2931 write operation. This must be a multiple of NvRamAccessSize and\r
2932 less than NvRamSize.\r
2933 @param BufferSize The number of bytes to read or write from the NVRAM device.\r
2934 This must also be a multiple of NvramAccessSize.\r
2935 @param Buffer A pointer to the data buffer.\r
2936\r
2937 @retval EFI_SUCCESS The NVRAM access was performed.\r
2938 @retval EFI_NOT_STARTED The network interface has not been started.\r
2939 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
2940 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
2941 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
2942\r
2943**/\r
2944EFI_STATUS\r
2945EFIAPI\r
2946Undi16SimpleNetworkNvData (\r
2947 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
2948 IN BOOLEAN ReadWrite,\r
2949 IN UINTN Offset,\r
2950 IN UINTN BufferSize,\r
2951 IN OUT VOID *Buffer\r
2952 )\r
2953{\r
2954 return EFI_UNSUPPORTED;\r
2955}\r
2956//\r
2957// GetStatus()\r
2958//\r
2959/**\r
2960 Reads the current interrupt status and recycled transmit buffer status from \r
2961 a network interface.\r
2962\r
2963 @param This The protocol instance pointer.\r
2964 @param InterruptStatus A pointer to the bit mask of the currently active interrupts\r
2965 If this is NULL, the interrupt status will not be read from\r
2966 the device. If this is not NULL, the interrupt status will\r
2967 be read from the device. When the interrupt status is read,\r
2968 it will also be cleared. Clearing the transmit interrupt\r
2969 does not empty the recycled transmit buffer array.\r
2970 @param TxBuf Recycled transmit buffer address. The network interface will\r
2971 not transmit if its internal recycled transmit buffer array\r
2972 is full. Reading the transmit buffer does not clear the\r
2973 transmit interrupt. If this is NULL, then the transmit buffer\r
2974 status will not be read. If there are no transmit buffers to\r
2975 recycle and TxBuf is not NULL, * TxBuf will be set to NULL.\r
2976\r
2977 @retval EFI_SUCCESS The status of the network interface was retrieved.\r
2978 @retval EFI_NOT_STARTED The network interface has not been started.\r
2979 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
2980 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
2981 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
2982\r
2983**/\r
2984EFI_STATUS\r
2985EFIAPI\r
2986Undi16SimpleNetworkGetStatus (\r
2987 IN EFI_SIMPLE_NETWORK_PROTOCOL * This,\r
2988 OUT UINT32 *InterruptStatus OPTIONAL,\r
2989 OUT VOID **TxBuf OPTIONAL\r
2990 )\r
2991{\r
2992 EFI_STATUS Status;\r
2993 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
2994 UINTN FrameLength;\r
2995\r
2996 if (This == NULL) {\r
2997 return EFI_INVALID_PARAMETER;\r
2998 }\r
2999\r
3000 Status = EFI_SUCCESS;\r
3001 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
3002\r
3003 if (SimpleNetworkDevice == NULL) {\r
3004 return EFI_DEVICE_ERROR;\r
3005 }\r
3006 //\r
3007 // Verify that the current state of the adapter is valid for this call.\r
3008 //\r
3009 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
3010 case EfiSimpleNetworkInitialized:\r
3011 break;\r
3012\r
3013 case EfiSimpleNetworkStopped:\r
3014 return EFI_NOT_STARTED;\r
3015\r
3016 case EfiSimpleNetworkStarted:\r
3017 default:\r
3018 return EFI_DEVICE_ERROR;\r
3019 }\r
3020\r
3021 if (InterruptStatus == NULL && TxBuf == NULL) {\r
3022 return EFI_INVALID_PARAMETER;\r
3023 }\r
3024\r
3025 FrameLength = 0;\r
3026 Status = Undi16SimpleNetworkIsr (This, &FrameLength, NULL, NULL, NULL, NULL);\r
3027\r
3028 if (Status != EFI_BUFFER_TOO_SMALL) {\r
3029 if (EFI_ERROR (Status)) {\r
3030 return Status;\r
3031 }\r
3032 }\r
3033 //\r
3034 // See if the caller wants interrupt info.\r
3035 //\r
3036 if (InterruptStatus != NULL) {\r
3037 *InterruptStatus = SimpleNetworkDevice->InterruptStatus;\r
3038 SimpleNetworkDevice->InterruptStatus = 0;\r
3039 }\r
3040 //\r
3041 // See if the caller wants transmit buffer status info.\r
3042 //\r
3043 if (TxBuf != NULL) {\r
3044 *TxBuf = 0;\r
3045 SimpleNetworkTransmitFifoRemove (&(SimpleNetworkDevice->TxBufferFifo), TxBuf);\r
3046 }\r
3047\r
3048 return EFI_SUCCESS;\r
3049}\r
3050\r
3051/**\r
3052 Places a packet in the transmit queue of a network interface.\r
3053\r
3054 @param This The protocol instance pointer.\r
3055 @param HeaderSize The size, in bytes, of the media header to be filled in by\r
3056 the Transmit() function. If HeaderSize is non-zero, then it\r
3057 must be equal to This->Mode->MediaHeaderSize and the DestAddr\r
3058 and Protocol parameters must not be NULL.\r
3059 @param BufferSize The size, in bytes, of the entire packet (media header and\r
3060 data) to be transmitted through the network interface.\r
3061 @param Buffer A pointer to the packet (media header followed by data) to be\r
3062 transmitted. This parameter cannot be NULL. If HeaderSize is zero,\r
3063 then the media header in Buffer must already be filled in by the\r
3064 caller. If HeaderSize is non-zero, then the media header will be\r
3065 filled in by the Transmit() function.\r
3066 @param SrcAddr The source HW MAC address. If HeaderSize is zero, then this parameter\r
3067 is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then\r
3068 This->Mode->CurrentAddress is used for the source HW MAC address.\r
3069 @param DestAddr The destination HW MAC address. If HeaderSize is zero, then this\r
3070 parameter is ignored.\r
3071 @param Protocol The type of header to build. If HeaderSize is zero, then this\r
3072 parameter is ignored. See RFC 1700, section "Ether Types", for\r
3073 examples.\r
3074\r
3075 @retval EFI_SUCCESS The packet was placed on the transmit queue.\r
3076 @retval EFI_NOT_STARTED The network interface has not been started.\r
3077 @retval EFI_NOT_READY The network interface is too busy to accept this transmit request. \r
3078 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.\r
3079 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
3080 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
3081 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
3082\r
3083**/\r
3084EFI_STATUS\r
3085EFIAPI\r
3086Undi16SimpleNetworkTransmit (\r
3087 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
3088 IN UINTN HeaderSize,\r
3089 IN UINTN BufferSize,\r
3090 IN VOID *Buffer,\r
3091 IN EFI_MAC_ADDRESS *SrcAddr OPTIONAL,\r
3092 IN EFI_MAC_ADDRESS *DestAddr OPTIONAL,\r
3093 IN UINT16 *Protocol OPTIONAL\r
3094 )\r
3095{\r
3096 EFI_STATUS Status;\r
3097 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
3098 PXENV_UNDI_TRANSMIT_T XmitInfo;\r
3099\r
3100 if (This == NULL) {\r
3101 return EFI_INVALID_PARAMETER;\r
3102 }\r
3103\r
3104 Status = EFI_SUCCESS;\r
3105 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
3106\r
3107 if (SimpleNetworkDevice == NULL) {\r
3108 return EFI_DEVICE_ERROR;\r
3109 }\r
3110 //\r
3111 // Verify that the current state of the adapter is valid for this call.\r
3112 //\r
3113 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
3114 case EfiSimpleNetworkInitialized:\r
3115 break;\r
3116\r
3117 case EfiSimpleNetworkStopped:\r
3118 return EFI_NOT_STARTED;\r
3119\r
3120 case EfiSimpleNetworkStarted:\r
3121 default:\r
3122 return EFI_DEVICE_ERROR;\r
3123 }\r
3124\r
3125 if (Buffer == NULL) {\r
3126 return EFI_INVALID_PARAMETER;\r
3127 }\r
3128\r
3129 if (BufferSize < SimpleNetworkDevice->SimpleNetworkMode.MediaHeaderSize) {\r
3130 return EFI_BUFFER_TOO_SMALL;\r
3131 }\r
3132\r
3133 if (HeaderSize != 0) {\r
3134 if (HeaderSize != SimpleNetworkDevice->SimpleNetworkMode.MediaHeaderSize) {\r
3135 return EFI_INVALID_PARAMETER;\r
3136 }\r
3137\r
3138 if (DestAddr == NULL || Protocol == NULL) {\r
3139 return EFI_INVALID_PARAMETER;\r
3140 }\r
3141\r
3142 if (DestAddr != NULL) {\r
3143 CopyMem (\r
3144 Buffer,\r
3145 DestAddr,\r
3146 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
3147 );\r
3148 }\r
3149\r
3150 if (SrcAddr == NULL) {\r
3151 SrcAddr = &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress;\r
3152 }\r
3153\r
3154 CopyMem (\r
3155 (UINT8 *) Buffer + SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize,\r
3156 SrcAddr,\r
3157 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
3158 );\r
3159\r
3160 if (Protocol != NULL) {\r
3161 *(UINT16 *) ((UINT8 *) Buffer + 2 * SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize) = (UINT16) (((*Protocol & 0xFF) << 8) | ((*Protocol >> 8) & 0xFF));\r
3162 }\r
3163 }\r
3164 //\r
3165 // See if the recycled transmit buffer FIFO is full.\r
3166 // If it is full, then we can not transmit until the caller calls GetStatus() to pull\r
3167 // off recycled transmit buffers.\r
3168 //\r
3169 if (SimpleNetworkTransmitFifoFull (&(SimpleNetworkDevice->TxBufferFifo))) {\r
3170 return EFI_NOT_READY;\r
3171 }\r
3172 //\r
3173 // Output debug trace message.\r
3174 //\r
3175 DEBUG ((DEBUG_NET, "Undi16SimpleNetworkTransmit\n\r "));\r
3176\r
3177 //\r
3178 // Initialize UNDI WRITE parameter structure.\r
3179 //\r
3180 XmitInfo.Status = INIT_PXE_STATUS;\r
3181 XmitInfo.Protocol = P_UNKNOWN;\r
3182 XmitInfo.XmitFlag = XMT_DESTADDR;\r
3183 XmitInfo.DestAddrOffset = (UINT16) ((UINT32)(UINTN) SimpleNetworkDevice->TxDestAddr & 0x000f);\r
3184 XmitInfo.DestAddrSegment = (UINT16) ((UINT32)(UINTN) SimpleNetworkDevice->TxDestAddr >> 4);\r
3185 XmitInfo.TBDOffset = (UINT16) ((UINT32)(UINTN) SimpleNetworkDevice->Xmit & 0x000f);\r
3186 XmitInfo.TBDSegment = (UINT16) ((UINT32)(UINTN) SimpleNetworkDevice->Xmit >> 4);\r
3187 XmitInfo.Reserved[0] = 0;\r
3188 XmitInfo.Reserved[1] = 0;\r
3189\r
3190 CopyMem (\r
3191 SimpleNetworkDevice->TxDestAddr,\r
3192 Buffer,\r
3193 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
3194 );\r
3195\r
3196 CopyMem (\r
3197 SimpleNetworkDevice->TxRealModeMediaHeader,\r
3198 Buffer,\r
3199 SimpleNetworkDevice->SimpleNetworkMode.MediaHeaderSize\r
3200 );\r
3201\r
3202 SimpleNetworkDevice->Xmit->ImmedLength = (UINT16) SimpleNetworkDevice->SimpleNetworkMode.MediaHeaderSize;\r
3203\r
3204 SimpleNetworkDevice->Xmit->DataBlock[0].TDDataLen = (UINT16) (BufferSize - SimpleNetworkDevice->Xmit->ImmedLength);\r
3205\r
3206 CopyMem (\r
3207 SimpleNetworkDevice->TxRealModeDataBuffer,\r
3208 (UINT8 *) Buffer + SimpleNetworkDevice->SimpleNetworkMode.MediaHeaderSize,\r
3209 SimpleNetworkDevice->Xmit->DataBlock[0].TDDataLen\r
3210 );\r
3211\r
3212 //\r
3213 // Make API call to UNDI TRANSMIT\r
3214 //\r
3215 XmitInfo.Status = 0;\r
3216\r
3217 Status = PxeUndiTransmit (SimpleNetworkDevice, &XmitInfo);\r
3218\r
3219 if (EFI_ERROR (Status)) {\r
3220 return Status;\r
3221 }\r
3222 //\r
3223 // Check the status code from the 16 bit UNDI ROM\r
3224 //\r
3225 switch (XmitInfo.Status) {\r
3226 case PXENV_STATUS_OUT_OF_RESOURCES:\r
3227 return EFI_NOT_READY;\r
3228\r
3229 case PXENV_STATUS_SUCCESS:\r
3230 break;\r
3231\r
3232 default:\r
3233 return EFI_DEVICE_ERROR;\r
3234 }\r
3235 //\r
3236 // Add address of Buffer to the recycled transmit buffer FIFO\r
3237 //\r
3238 SimpleNetworkTransmitFifoAdd (&(SimpleNetworkDevice->TxBufferFifo), Buffer);\r
3239\r
3240 return EFI_SUCCESS;\r
3241}\r
3242\r
3243/**\r
3244 Receives a packet from a network interface.\r
3245 \r
3246 @param This The protocol instance pointer.\r
3247 @param HeaderSize The size, in bytes, of the media header received on the network\r
3248 interface. If this parameter is NULL, then the media header size\r
3249 will not be returned.\r
3250 @param BufferSize On entry, the size, in bytes, of Buffer. On exit, the size, in\r
3251 bytes, of the packet that was received on the network interface.\r
3252 @param Buffer A pointer to the data buffer to receive both the media header and\r
3253 the data.\r
3254 @param SrcAddr The source HW MAC address. If this parameter is NULL, the\r
3255 HW MAC source address will not be extracted from the media\r
3256 header.\r
3257 @param DestAddr The destination HW MAC address. If this parameter is NULL,\r
3258 the HW MAC destination address will not be extracted from the\r
3259 media header.\r
3260 @param Protocol The media header type. If this parameter is NULL, then the\r
3261 protocol will not be extracted from the media header. See\r
3262 RFC 1700 section "Ether Types" for examples.\r
3263\r
3264 @retval EFI_SUCCESS The received data was stored in Buffer, and BufferSize has\r
3265 been updated to the number of bytes received.\r
3266 @retval EFI_NOT_STARTED The network interface has not been started.\r
3267 @retval EFI_NOT_READY The network interface is too busy to accept this transmit\r
3268 request.\r
3269 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.\r
3270 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
3271 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
3272 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
3273\r
3274**/\r
3275EFI_STATUS\r
3276EFIAPI\r
3277Undi16SimpleNetworkReceive (\r
3278 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
3279 OUT UINTN *HeaderSize OPTIONAL,\r
3280 IN OUT UINTN *BufferSize,\r
3281 OUT VOID *Buffer,\r
3282 OUT EFI_MAC_ADDRESS *SrcAddr OPTIONAL,\r
3283 OUT EFI_MAC_ADDRESS *DestAddr OPTIONAL,\r
3284 OUT UINT16 *Protocol OPTIONAL\r
3285 )\r
3286{\r
3287 EFI_STATUS Status;\r
3288 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
3289 UINTN MediaAddrSize;\r
3290 UINT8 ProtType;\r
3291\r
3292 if (This == NULL || BufferSize == NULL || Buffer == NULL) {\r
3293 return EFI_INVALID_PARAMETER;\r
3294 }\r
3295\r
3296 Status = EFI_SUCCESS;\r
3297 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
3298\r
3299 if (SimpleNetworkDevice == NULL) {\r
3300 return EFI_DEVICE_ERROR;\r
3301 }\r
3302 //\r
3303 // Verify that the current state of the adapter is valid for this call.\r
3304 //\r
3305 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
3306 case EfiSimpleNetworkInitialized:\r
3307 break;\r
3308\r
3309 case EfiSimpleNetworkStopped:\r
3310 return EFI_NOT_STARTED;\r
3311\r
3312 case EfiSimpleNetworkStarted:\r
3313 default:\r
3314 return EFI_DEVICE_ERROR;\r
3315 }\r
3316\r
3317 Status = Undi16SimpleNetworkIsr (\r
3318 This,\r
3319 BufferSize,\r
3320 HeaderSize,\r
3321 Buffer,\r
3322 &ProtType,\r
3323 NULL\r
3324 );\r
3325\r
3326 if (EFI_ERROR (Status)) {\r
3327 return Status;\r
3328 }\r
3329\r
3330 if ((SimpleNetworkDevice->InterruptStatus & EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT) == 0) {\r
3331 return EFI_NOT_READY;\r
3332\r
3333 }\r
3334\r
3335 SimpleNetworkDevice->InterruptStatus &= ~EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;\r
3336\r
3337 MediaAddrSize = This->Mode->HwAddressSize;\r
3338\r
3339 if (SrcAddr != NULL) {\r
3340 CopyMem (SrcAddr, (UINT8 *) Buffer + MediaAddrSize, MediaAddrSize);\r
3341 }\r
3342\r
3343 if (DestAddr != NULL) {\r
3344 CopyMem (DestAddr, Buffer, MediaAddrSize);\r
3345 }\r
3346\r
3347 if (Protocol != NULL) {\r
3348 *((UINT8 *) Protocol) = *((UINT8 *) Buffer + (2 * MediaAddrSize) + 1);\r
3349 *((UINT8 *) Protocol + 1) = *((UINT8 *) Buffer + (2 * MediaAddrSize));\r
3350 }\r
3351\r
3352 DEBUG ((DEBUG_NET, "Packet Received: BufferSize=%d HeaderSize = %d\n", *BufferSize, *HeaderSize));\r
3353\r
3354 return Status;\r
3355\r
3356}\r
3357//\r
3358// WaitForPacket()\r
3359//\r
3360/**\r
3361 wait for a packet to be received.\r
3362\r
3363 @param Event Event used with WaitForEvent() to wait for a packet to be received.\r
3364 @param Context Event Context\r
3365 \r
3366**/\r
3367VOID\r
3368EFIAPI\r
3369Undi16SimpleNetworkWaitForPacket (\r
3370 IN EFI_EVENT Event,\r
3371 IN VOID *Context\r
3372 )\r
3373{\r
3374 //\r
3375 // Someone is waiting on the receive packet event, if there's\r
3376 // a packet pending, signal the event\r
3377 //\r
3378 if (!EFI_ERROR (Undi16SimpleNetworkCheckForPacket (Context))) {\r
3379 gBS->SignalEvent (Event);\r
3380 }\r
3381}\r
3382//\r
3383// CheckForPacket()\r
3384//\r
3385/**\r
3386 Check whether packet is ready for receive.\r
3387\r
3388 @param This The protocol instance pointer.\r
3389 \r
3390 @retval EFI_SUCCESS Receive data is ready.\r
3391 @retval EFI_NOT_STARTED The network interface has not been started.\r
3392 @retval EFI_NOT_READY The network interface is too busy to accept this transmit\r
3393 request.\r
3394 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.\r
3395 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
3396 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
3397 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
3398**/\r
3399EFI_STATUS\r
3400Undi16SimpleNetworkCheckForPacket (\r
3401 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
3402 )\r
3403{\r
3404 EFI_STATUS Status;\r
3405 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
3406 UINTN FrameLength;\r
3407\r
3408 if (This == NULL) {\r
3409 return EFI_INVALID_PARAMETER;\r
3410 }\r
3411\r
3412 Status = EFI_SUCCESS;\r
3413 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
3414\r
3415 if (SimpleNetworkDevice == NULL) {\r
3416 return EFI_DEVICE_ERROR;\r
3417 }\r
3418 //\r
3419 // Verify that the current state of the adapter is valid for this call.\r
3420 //\r
3421 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
3422 case EfiSimpleNetworkInitialized:\r
3423 break;\r
3424\r
3425 case EfiSimpleNetworkStopped:\r
3426 return EFI_NOT_STARTED;\r
3427\r
3428 case EfiSimpleNetworkStarted:\r
3429 default:\r
3430 return EFI_DEVICE_ERROR;\r
3431 }\r
3432\r
3433 FrameLength = 0;\r
3434 Status = Undi16SimpleNetworkIsr (\r
3435 This,\r
3436 &FrameLength,\r
3437 NULL,\r
3438 NULL,\r
3439 NULL,\r
3440 NULL\r
3441 );\r
3442\r
3443 if (Status != EFI_BUFFER_TOO_SMALL) {\r
3444 if (EFI_ERROR (Status)) {\r
3445 return Status;\r
3446 }\r
3447 }\r
3448\r
3449 return ((SimpleNetworkDevice->InterruptStatus & EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT) != 0) ? EFI_SUCCESS : EFI_NOT_READY;\r
3450}\r
3451\r
3452/**\r
3453 Signal handlers for ExitBootServices event.\r
3454 \r
3455 Clean up any Real-mode UNDI residue from the system \r
3456 \r
3457 @param Event ExitBootServices event\r
3458 @param Context \r
3459**/\r
3460VOID\r
3461EFIAPI\r
3462Undi16SimpleNetworkEvent (\r
3463 IN EFI_EVENT Event,\r
3464 IN VOID *Context\r
3465 )\r
3466{\r
3467 //\r
3468 // NOTE: This is not the only way to effect this cleanup. The prescribed mechanism\r
3469 // would be to perform an UNDI STOP command. This strategam has been attempted\r
3470 // but results in problems making some of the EFI core services from TPL_CALLBACK.\r
3471 // This issue needs to be resolved, but the other alternative has been to perform\r
3472 // the unchain logic explicitly, as done below.\r
3473 //\r
3474 RestoreCachedVectorAddress (0x1A);\r
3475}\r
3476\r
3477/**\r
3478 Allocate buffer below 1M for real mode.\r
3479\r
3480 @param NumPages The number pages want to be allocated.\r
3481 @param Buffer On return, allocated buffer.\r
3482 \r
3483 @return Status of allocating pages.\r
3484**/\r
3485EFI_STATUS\r
3486BiosSnp16AllocatePagesBelowOneMb (\r
3487 UINTN NumPages,\r
3488 VOID **Buffer\r
3489 )\r
3490{\r
3491 EFI_STATUS Status;\r
3492 EFI_PHYSICAL_ADDRESS PhysicalAddress;\r
3493\r
3494 PhysicalAddress = 0x000fffff;\r
3495 Status = gBS->AllocatePages (\r
3496 AllocateMaxAddress,\r
3497 EfiRuntimeServicesData,\r
3498 NumPages,\r
3499 &PhysicalAddress\r
3500 );\r
3501 if (EFI_ERROR (Status)) {\r
3502 return Status;\r
3503 }\r
3504\r
3505 *Buffer = (VOID *) (UINTN) PhysicalAddress;\r
3506 return EFI_SUCCESS;\r
3507}\r