3 Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions
7 of the BSD License which accompanies this distribution. The
8 full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "BiosSnp16.h"
20 /// EFI Driver Binding Protocol Instance
22 EFI_DRIVER_BINDING_PROTOCOL gBiosSnp16DriverBinding
= {
23 BiosSnp16DriverBindingSupported
,
24 BiosSnp16DriverBindingStart
,
25 BiosSnp16DriverBindingStop
,
32 /// This boolean is used to determine if we should release the cached vector during an error condition.
34 BOOLEAN mCachedInt1A
= FALSE
;
37 // Private worker functions;
41 Start the UNDI interface.
43 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.
44 @param Ax PCI address of Undi device.
46 @retval EFI_DEVICE_ERROR Fail to start 16 bit UNDI ROM.
47 @retval Others Status of start 16 bit UNDI ROM.
50 Undi16SimpleNetworkStartUndi (
51 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
,
56 Start the UNDI interface
58 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.
60 @retval EFI_DEVICE_ERROR Fail to start 16 bit UNDI ROM.
61 @retval Others Status of start 16 bit UNDI ROM.
64 Undi16SimpleNetworkStopUndi (
65 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
69 Stop the UNDI interface
71 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.
73 @retval EFI_DEVICE_ERROR Fail to stop 16 bit UNDI ROM.
74 @retval Others Status of stop 16 bit UNDI ROM.
77 Undi16SimpleNetworkCleanupUndi (
78 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
82 Get runtime information for Undi network interface
84 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
86 @retval EFI_SUCCESS Sucess operation.
87 @retval Others Fail to get runtime information for Undi network interface.
90 Undi16SimpleNetworkGetInformation (
91 IN EFI_SIMPLE_NETWORK_PROTOCOL
*This
97 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
99 @retval EFI_SUCCESS Sucess operation.
100 @retval Others Fail to get NIC type.
103 Undi16SimpleNetworkGetNicType (
104 IN EFI_SIMPLE_NETWORK_PROTOCOL
*This
110 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
112 @retval EFI_SUCCESS Sucess operation.
113 @retval Others Fail to get NDIS information.
116 Undi16SimpleNetworkGetNdisInfo (
117 IN EFI_SIMPLE_NETWORK_PROTOCOL
*This
121 Signal handlers for ExitBootServices event.
123 Clean up any Real-mode UNDI residue from the system
125 @param Event ExitBootServices event
130 Undi16SimpleNetworkEvent (
136 Loads the undi driver.
138 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.
140 @retval EFI_SUCCESS - Successfully loads undi driver.
141 @retval EFI_NOT_FOUND - Doesn't find undi driver or undi driver load failure.
144 Undi16SimpleNetworkLoadUndi (
145 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
149 Unload 16 bit UNDI Option ROM from memory
151 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.
156 Undi16SimpleNetworkUnloadUndi (
157 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
161 Entry point for EFI drivers.
163 @param ImageHandle Handle that identifies the loaded image.
164 @param SystemTable System Table for this image.
166 @return EFI_STATUS Return status from EfiLibInstallAllDriverProtocols.
170 BiosSnp16DriverEntryPoint (
171 IN EFI_HANDLE ImageHandle
,
172 IN EFI_SYSTEM_TABLE
*SystemTable
175 return EfiLibInstallDriverBindingComponentName2 (
178 &gBiosSnp16DriverBinding
,
180 &gBiosSnp16ComponentName
,
181 &gBiosSnp16ComponentName2
186 // EFI Driver Binding Protocol Functions
189 Tests to see if this driver supports a given controller.
191 @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
192 @param Controller The handle of the controller to test.
193 @param RemainingDevicePath A pointer to the remaining portion of a device path.
195 @retval EFI_SUCCESS The driver supports given controller.
196 @retval EFI_UNSUPPORT The driver doesn't support given controller.
197 @retval Other Other errors prevent driver finishing to test
198 if the driver supports given controller.
202 BiosSnp16DriverBindingSupported (
203 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
204 IN EFI_HANDLE Controller
,
205 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
209 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
210 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
211 EFI_PCI_IO_PROTOCOL
*PciIo
;
215 // See if the Legacy BIOS Protocol is available
217 Status
= gBS
->LocateProtocol (&gEfiLegacyBiosProtocolGuid
, NULL
, (VOID
**) &LegacyBios
);
218 if (EFI_ERROR (Status
)) {
222 // Open the IO Abstraction(s) needed to perform the supported test
224 Status
= gBS
->OpenProtocol (
226 &gEfiDevicePathProtocolGuid
,
227 (VOID
**) &DevicePath
,
228 This
->DriverBindingHandle
,
230 EFI_OPEN_PROTOCOL_BY_DRIVER
232 if (EFI_ERROR (Status
)) {
238 &gEfiDevicePathProtocolGuid
,
239 This
->DriverBindingHandle
,
244 // Open the IO Abstraction(s) needed to perform the supported test
246 Status
= gBS
->OpenProtocol (
248 &gEfiPciIoProtocolGuid
,
250 This
->DriverBindingHandle
,
252 EFI_OPEN_PROTOCOL_BY_DRIVER
254 if (EFI_ERROR (Status
)) {
258 // See if this is a PCI Network Controller by looking at the Command register and
259 // Class Code Register
261 Status
= PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint32
, 0, sizeof (Pci
) / sizeof (UINT32
), &Pci
);
262 if (EFI_ERROR (Status
)) {
263 Status
= EFI_UNSUPPORTED
;
267 Status
= EFI_UNSUPPORTED
;
268 if (Pci
.Hdr
.ClassCode
[2] == PCI_CLASS_NETWORK
) {
269 Status
= EFI_SUCCESS
;
275 &gEfiPciIoProtocolGuid
,
276 This
->DriverBindingHandle
,
284 Starts the Snp device controller
286 @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
287 @param Controller The handle of the controller to test.
288 @param RemainingDevicePath A pointer to the remaining portion of a device path.
290 @retval EFI_SUCCESS - The device was started.
291 @retval EFI_DEVICE_ERROR - The device could not be started due to a device error.
292 @retval EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources.
296 BiosSnp16DriverBindingStart (
297 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
298 IN EFI_HANDLE Controller
,
299 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
303 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
304 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
305 EFI_PCI_IO_PROTOCOL
*PciIo
;
306 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
;
317 SimpleNetworkDevice
= NULL
;
321 // See if the Legacy BIOS Protocol is available
323 Status
= gBS
->LocateProtocol (&gEfiLegacyBiosProtocolGuid
, NULL
, (VOID
**) &LegacyBios
);
324 if (EFI_ERROR (Status
)) {
328 // Open the IO Abstraction(s) needed
330 Status
= gBS
->OpenProtocol (
332 &gEfiDevicePathProtocolGuid
,
333 (VOID
**) &DevicePath
,
334 This
->DriverBindingHandle
,
336 EFI_OPEN_PROTOCOL_BY_DRIVER
338 if (EFI_ERROR (Status
)) {
342 Status
= gBS
->OpenProtocol (
344 &gEfiPciIoProtocolGuid
,
346 This
->DriverBindingHandle
,
348 EFI_OPEN_PROTOCOL_BY_DRIVER
350 if (EFI_ERROR (Status
)) {
354 Status
= PciIo
->Attributes (
356 EfiPciIoAttributeOperationSupported
,
360 if (!EFI_ERROR (Status
)) {
361 Supports
&= EFI_PCI_DEVICE_ENABLE
;
362 Status
= PciIo
->Attributes (
364 EfiPciIoAttributeOperationEnable
,
370 if (EFI_ERROR (Status
)) {
374 // Check to see if there is a legacy option ROM image associated with this PCI device
376 Status
= LegacyBios
->CheckPciRom (
383 if (EFI_ERROR (Status
)) {
387 // Post the legacy option ROM if it is available.
389 Status
= LegacyBios
->InstallPciRom (
399 if (EFI_ERROR (Status
)) {
403 // Allocate memory for this SimpleNetwork device instance
405 Status
= gBS
->AllocatePool (
407 sizeof (EFI_SIMPLE_NETWORK_DEV
),
408 (VOID
**) &SimpleNetworkDevice
410 if (EFI_ERROR (Status
)) {
411 Status
= EFI_OUT_OF_RESOURCES
;
415 ZeroMem (SimpleNetworkDevice
, sizeof (EFI_SIMPLE_NETWORK_DEV
));
418 // Initialize the SimpleNetwork device instance
420 SimpleNetworkDevice
->Signature
= EFI_SIMPLE_NETWORK_DEV_SIGNATURE
;
421 SimpleNetworkDevice
->LegacyBios
= LegacyBios
;
422 SimpleNetworkDevice
->BaseDevicePath
= DevicePath
;
423 SimpleNetworkDevice
->PciIo
= PciIo
;
426 // Initialize the Nii Protocol
428 SimpleNetworkDevice
->Nii
.Revision
= EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION
;
429 SimpleNetworkDevice
->Nii
.Type
= EfiNetworkInterfaceUndi
;
431 CopyMem (&SimpleNetworkDevice
->Nii
.StringId
, "UNDI", 4);
434 // Load 16 bit UNDI Option ROM into Memory
436 Status
= Undi16SimpleNetworkLoadUndi (SimpleNetworkDevice
);
437 if (EFI_ERROR (Status
)) {
438 DEBUG ((DEBUG_NET
, "ERROR : Could not load UNDI. Status = %r\n", Status
));
442 SimpleNetworkDevice
->UndiLoaded
= TRUE
;
445 // Call PXENV_START_UNDI - Initilizes the UNID interface for use.
447 PciIo
->GetLocation (PciIo
, &Segment
, &Bus
, &Device
, &Function
);
448 Status
= Undi16SimpleNetworkStartUndi (
450 (UINT16
) ((Bus
<< 0x8) | (Device
<< 0x3) | (Function
))
452 if (EFI_ERROR (Status
)) {
453 DEBUG ((DEBUG_NET
, "ERROR : Could not StartUndi. Status = %r\n", Status
));
457 // Initialize the Simple Network Protocol
459 DEBUG ((DEBUG_NET
, "Initialize SimpleNetworkDevice instance\n"));
461 SimpleNetworkDevice
->SimpleNetwork
.Revision
= EFI_SIMPLE_NETWORK_PROTOCOL_REVISION
;
462 SimpleNetworkDevice
->SimpleNetwork
.Start
= Undi16SimpleNetworkStart
;
463 SimpleNetworkDevice
->SimpleNetwork
.Stop
= Undi16SimpleNetworkStop
;
464 SimpleNetworkDevice
->SimpleNetwork
.Initialize
= Undi16SimpleNetworkInitialize
;
465 SimpleNetworkDevice
->SimpleNetwork
.Reset
= Undi16SimpleNetworkReset
;
466 SimpleNetworkDevice
->SimpleNetwork
.Shutdown
= Undi16SimpleNetworkShutdown
;
467 SimpleNetworkDevice
->SimpleNetwork
.ReceiveFilters
= Undi16SimpleNetworkReceiveFilters
;
468 SimpleNetworkDevice
->SimpleNetwork
.StationAddress
= Undi16SimpleNetworkStationAddress
;
469 SimpleNetworkDevice
->SimpleNetwork
.Statistics
= Undi16SimpleNetworkStatistics
;
470 SimpleNetworkDevice
->SimpleNetwork
.MCastIpToMac
= Undi16SimpleNetworkMCastIpToMac
;
471 SimpleNetworkDevice
->SimpleNetwork
.NvData
= Undi16SimpleNetworkNvData
;
472 SimpleNetworkDevice
->SimpleNetwork
.GetStatus
= Undi16SimpleNetworkGetStatus
;
473 SimpleNetworkDevice
->SimpleNetwork
.Transmit
= Undi16SimpleNetworkTransmit
;
474 SimpleNetworkDevice
->SimpleNetwork
.Receive
= Undi16SimpleNetworkReceive
;
475 SimpleNetworkDevice
->SimpleNetwork
.Mode
= &(SimpleNetworkDevice
->SimpleNetworkMode
);
477 Status
= gBS
->CreateEvent (
480 Undi16SimpleNetworkWaitForPacket
,
481 &SimpleNetworkDevice
->SimpleNetwork
,
482 &SimpleNetworkDevice
->SimpleNetwork
.WaitForPacket
484 if (EFI_ERROR (Status
)) {
485 DEBUG ((DEBUG_ERROR
, "ERROR : Could not create event. Status = %r\n", Status
));
489 // Create an event to be signalled when ExitBootServices occurs in order
490 // to clean up nicely
492 Status
= gBS
->CreateEventEx (
495 Undi16SimpleNetworkEvent
,
497 &gEfiEventExitBootServicesGuid
,
498 &SimpleNetworkDevice
->EfiBootEvent
500 if (EFI_ERROR (Status
)) {
501 DEBUG ((DEBUG_ERROR
, "ERROR : Could not create event. Status = %r\n", Status
));
506 // Create an event to be signalled when Legacy Boot occurs to clean up the IVT
508 Status
= EfiCreateEventLegacyBootEx(
510 Undi16SimpleNetworkEvent
,
512 &SimpleNetworkDevice
->LegacyBootEvent
515 if (EFI_ERROR(Status
)) {
516 DEBUG ((DEBUG_ERROR
,"ERROR : Could not create event. Status = %r\n",Status
));
521 // Initialize the SimpleNetwork Mode Information
523 DEBUG ((DEBUG_NET
, "Initialize Mode Information\n"));
525 SimpleNetworkDevice
->SimpleNetworkMode
.State
= EfiSimpleNetworkStopped
;
526 SimpleNetworkDevice
->SimpleNetworkMode
.MediaHeaderSize
= 14;
527 SimpleNetworkDevice
->SimpleNetworkMode
.MacAddressChangeable
= TRUE
;
528 SimpleNetworkDevice
->SimpleNetworkMode
.MultipleTxSupported
= TRUE
;
529 SimpleNetworkDevice
->SimpleNetworkMode
.ReceiveFilterMask
= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
|
530 EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
|
531 EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
|
532 EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
|
533 EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
534 SimpleNetworkDevice
->SimpleNetworkMode
.MaxMCastFilterCount
= MAXNUM_MCADDR
;
537 // Initialize the SimpleNetwork Private Information
539 DEBUG ((DEBUG_NET
, "Initialize Private Information\n"));
541 Status
= BiosSnp16AllocatePagesBelowOneMb (
542 sizeof (PXENV_UNDI_TBD_T
) / EFI_PAGE_SIZE
+ 1,
543 (VOID
**) &SimpleNetworkDevice
->Xmit
545 if (EFI_ERROR (Status
)) {
549 Status
= BiosSnp16AllocatePagesBelowOneMb (
551 &SimpleNetworkDevice
->TxRealModeMediaHeader
553 if (EFI_ERROR (Status
)) {
557 Status
= BiosSnp16AllocatePagesBelowOneMb (
559 &SimpleNetworkDevice
->TxRealModeDataBuffer
561 if (EFI_ERROR (Status
)) {
565 Status
= BiosSnp16AllocatePagesBelowOneMb (
567 &SimpleNetworkDevice
->TxDestAddr
569 if (EFI_ERROR (Status
)) {
573 SimpleNetworkDevice
->Xmit
->XmitOffset
= (UINT16
) (((UINT32
)(UINTN
) SimpleNetworkDevice
->TxRealModeMediaHeader
) & 0x000f);
575 SimpleNetworkDevice
->Xmit
->XmitSegment
= (UINT16
) (((UINT32
)(UINTN
) SimpleNetworkDevice
->TxRealModeMediaHeader
) >> 4);
577 SimpleNetworkDevice
->Xmit
->DataBlkCount
= 1;
579 SimpleNetworkDevice
->Xmit
->DataBlock
[0].TDPtrType
= 1;
580 SimpleNetworkDevice
->Xmit
->DataBlock
[0].TDRsvdByte
= 0;
582 SimpleNetworkDevice
->Xmit
->DataBlock
[0].TDDataPtrOffset
= (UINT16
) (((UINT32
)(UINTN
) SimpleNetworkDevice
->TxRealModeDataBuffer
) & 0x000f);
584 SimpleNetworkDevice
->Xmit
->DataBlock
[0].TDDataPtrSegment
= (UINT16
) (((UINT32
)(UINTN
) SimpleNetworkDevice
->TxRealModeDataBuffer
) >> 4);
586 SimpleNetworkDevice
->TxBufferFifo
.First
= 0;
587 SimpleNetworkDevice
->TxBufferFifo
.Last
= 0;
590 // Start() the SimpleNetwork device
592 DEBUG ((DEBUG_NET
, "Start()\n"));
594 Status
= Undi16SimpleNetworkStart (&SimpleNetworkDevice
->SimpleNetwork
);
595 if (EFI_ERROR (Status
)) {
599 // GetInformation() the SimpleNetwork device
601 DEBUG ((DEBUG_NET
, "GetInformation()\n"));
603 Status
= Undi16SimpleNetworkGetInformation (&SimpleNetworkDevice
->SimpleNetwork
);
604 if (EFI_ERROR (Status
)) {
608 // Build the device path for the child device
610 ZeroMem (&Node
, sizeof (Node
));
611 Node
.DevPath
.Type
= MESSAGING_DEVICE_PATH
;
612 Node
.DevPath
.SubType
= MSG_MAC_ADDR_DP
;
613 SetDevicePathNodeLength (&Node
.DevPath
, sizeof (MAC_ADDR_DEVICE_PATH
));
615 &Node
.MacAddr
.MacAddress
,
616 &SimpleNetworkDevice
->SimpleNetworkMode
.CurrentAddress
,
617 sizeof (EFI_MAC_ADDRESS
)
619 SimpleNetworkDevice
->DevicePath
= AppendDevicePathNode (
620 SimpleNetworkDevice
->BaseDevicePath
,
625 // GetNicType() the SimpleNetwork device
627 DEBUG ((DEBUG_NET
, "GetNicType()\n"));
629 Status
= Undi16SimpleNetworkGetNicType (&SimpleNetworkDevice
->SimpleNetwork
);
630 if (EFI_ERROR (Status
)) {
634 // GetNdisInfo() the SimpleNetwork device
636 DEBUG ((DEBUG_NET
, "GetNdisInfo()\n"));
638 Status
= Undi16SimpleNetworkGetNdisInfo (&SimpleNetworkDevice
->SimpleNetwork
);
639 if (EFI_ERROR (Status
)) {
643 // Stop() the SimpleNetwork device
645 DEBUG ((DEBUG_NET
, "Stop()\n"));
647 Status
= SimpleNetworkDevice
->SimpleNetwork
.Stop (&SimpleNetworkDevice
->SimpleNetwork
);
648 if (EFI_ERROR (Status
)) {
652 // Print Mode information
654 DEBUG ((DEBUG_NET
, "Mode->State = %d\n", SimpleNetworkDevice
->SimpleNetworkMode
.State
));
655 DEBUG ((DEBUG_NET
, "Mode->HwAddressSize = %d\n", SimpleNetworkDevice
->SimpleNetworkMode
.HwAddressSize
));
656 DEBUG ((DEBUG_NET
, "Mode->MacAddressChangeable = %d\n", SimpleNetworkDevice
->SimpleNetworkMode
.MacAddressChangeable
));
657 DEBUG ((DEBUG_NET
, "Mode->MultiplTxSupported = %d\n", SimpleNetworkDevice
->SimpleNetworkMode
.MultipleTxSupported
));
658 DEBUG ((DEBUG_NET
, "Mode->NvRamSize = %d\n", SimpleNetworkDevice
->SimpleNetworkMode
.NvRamSize
));
659 DEBUG ((DEBUG_NET
, "Mode->NvRamAccessSize = %d\n", SimpleNetworkDevice
->SimpleNetworkMode
.NvRamAccessSize
));
660 DEBUG ((DEBUG_NET
, "Mode->ReceiveFilterSetting = %d\n", SimpleNetworkDevice
->SimpleNetworkMode
.ReceiveFilterSetting
));
661 DEBUG ((DEBUG_NET
, "Mode->IfType = %d\n", SimpleNetworkDevice
->SimpleNetworkMode
.IfType
));
662 DEBUG ((DEBUG_NET
, "Mode->MCastFilterCount = %d\n", SimpleNetworkDevice
->SimpleNetworkMode
.MCastFilterCount
));
663 for (Index
= 0; Index
< SimpleNetworkDevice
->SimpleNetworkMode
.MCastFilterCount
; Index
++) {
664 DEBUG ((DEBUG_NET
, " Filter[%02d] = ", Index
));
665 for (Index2
= 0; Index2
< 16; Index2
++) {
666 DEBUG ((DEBUG_NET
, "%02x ", SimpleNetworkDevice
->SimpleNetworkMode
.MCastFilter
[Index
].Addr
[Index2
]));
669 DEBUG ((DEBUG_NET
, "\n"));
672 DEBUG ((DEBUG_NET
, "CurrentAddress = "));
673 for (Index2
= 0; Index2
< 16; Index2
++) {
674 DEBUG ((DEBUG_NET
, "%02x ", SimpleNetworkDevice
->SimpleNetworkMode
.CurrentAddress
.Addr
[Index2
]));
677 DEBUG ((DEBUG_NET
, "\n"));
679 DEBUG ((DEBUG_NET
, "BroadcastAddress = "));
680 for (Index2
= 0; Index2
< 16; Index2
++) {
681 DEBUG ((DEBUG_NET
, "%02x ", SimpleNetworkDevice
->SimpleNetworkMode
.BroadcastAddress
.Addr
[Index2
]));
684 DEBUG ((DEBUG_NET
, "\n"));
686 DEBUG ((DEBUG_NET
, "PermanentAddress = "));
687 for (Index2
= 0; Index2
< 16; Index2
++) {
688 DEBUG ((DEBUG_NET
, "%02x ", SimpleNetworkDevice
->SimpleNetworkMode
.PermanentAddress
.Addr
[Index2
]));
691 DEBUG ((DEBUG_NET
, "\n"));
694 // The network device was started, information collected, and stopped.
695 // Install protocol interfaces for the SimpleNetwork device.
697 DEBUG ((DEBUG_NET
, "Install Protocol Interfaces on network interface\n"));
699 Status
= gBS
->InstallMultipleProtocolInterfaces (
700 &SimpleNetworkDevice
->Handle
,
701 &gEfiSimpleNetworkProtocolGuid
,
702 &SimpleNetworkDevice
->SimpleNetwork
,
703 &gEfiNetworkInterfaceIdentifierProtocolGuid
,
704 &SimpleNetworkDevice
->Nii
,
705 &gEfiDevicePathProtocolGuid
,
706 SimpleNetworkDevice
->DevicePath
,
709 if (EFI_ERROR (Status
)) {
713 // Open PCI I/O from the newly created child handle
715 Status
= gBS
->OpenProtocol (
717 &gEfiPciIoProtocolGuid
,
719 This
->DriverBindingHandle
,
720 SimpleNetworkDevice
->Handle
,
721 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
724 DEBUG ((DEBUG_INIT
, "UNDI16 Driver : EFI_SUCCESS\n"));
727 if (EFI_ERROR (Status
)) {
728 if (SimpleNetworkDevice
!= NULL
) {
730 Undi16SimpleNetworkShutdown (&SimpleNetworkDevice
->SimpleNetwork
);
734 Undi16SimpleNetworkCleanupUndi (SimpleNetworkDevice
);
738 Undi16SimpleNetworkStopUndi (SimpleNetworkDevice
);
742 if (SimpleNetworkDevice
->UndiLoaded
) {
743 Undi16SimpleNetworkUnloadUndi (SimpleNetworkDevice
);
746 if (SimpleNetworkDevice
->SimpleNetwork
.WaitForPacket
!= NULL
) {
747 gBS
->CloseEvent (SimpleNetworkDevice
->SimpleNetwork
.WaitForPacket
);
750 if (SimpleNetworkDevice
->LegacyBootEvent
!= NULL
) {
751 gBS
->CloseEvent (SimpleNetworkDevice
->LegacyBootEvent
);
754 if (SimpleNetworkDevice
->EfiBootEvent
!= NULL
) {
755 gBS
->CloseEvent (SimpleNetworkDevice
->EfiBootEvent
);
758 if (SimpleNetworkDevice
->Xmit
!= NULL
) {
760 (EFI_PHYSICAL_ADDRESS
) (UINTN
) SimpleNetworkDevice
->Xmit
,
761 sizeof (PXENV_UNDI_TBD_T
) / EFI_PAGE_SIZE
+ 1
765 if (SimpleNetworkDevice
->TxRealModeMediaHeader
!= NULL
) {
766 gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) SimpleNetworkDevice
->TxRealModeMediaHeader
, 1);
769 if (SimpleNetworkDevice
->TxRealModeDataBuffer
!= NULL
) {
770 gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) SimpleNetworkDevice
->TxRealModeDataBuffer
, 1);
773 if (SimpleNetworkDevice
->TxDestAddr
!= NULL
) {
774 gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) SimpleNetworkDevice
->TxDestAddr
, 1);
777 gBS
->FreePool (SimpleNetworkDevice
);
780 // Only restore the vector if it was cached.
783 RestoreCachedVectorAddress (0x1A);
784 mCachedInt1A
= FALSE
;
789 Status
= PciIo
->Attributes (
791 EfiPciIoAttributeOperationSupported
,
795 if (!EFI_ERROR (Status
)) {
796 Supports
&= EFI_PCI_DEVICE_ENABLE
;
797 Status
= PciIo
->Attributes (
799 EfiPciIoAttributeOperationDisable
,
808 &gEfiPciIoProtocolGuid
,
809 This
->DriverBindingHandle
,
815 &gEfiDevicePathProtocolGuid
,
816 This
->DriverBindingHandle
,
819 if (Status
!= EFI_OUT_OF_RESOURCES
) {
820 Status
= EFI_DEVICE_ERROR
;
827 Stops the device by given device controller.
829 @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
830 @param Controller The handle of the controller to test.
831 @param NumberOfChildren The number of child device handles in ChildHandleBuffer.
832 @param ChildHandleBuffer An array of child handles to be freed. May be NULL if
833 NumberOfChildren is 0.
835 @retval EFI_SUCCESS - The device was stopped.
836 @retval EFI_DEVICE_ERROR - The device could not be stopped due to a device error.
840 BiosSnp16DriverBindingStop (
841 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
842 IN EFI_HANDLE Controller
,
843 IN UINTN NumberOfChildren
,
844 IN EFI_HANDLE
*ChildHandleBuffer
849 BOOLEAN AllChildrenStopped
;
850 EFI_SIMPLE_NETWORK_PROTOCOL
*SimpleNetwork
;
851 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
;
852 EFI_PCI_IO_PROTOCOL
*PciIo
;
856 // Complete all outstanding transactions to Controller.
857 // Don't allow any new transaction to Controller to be started.
859 if (NumberOfChildren
== 0) {
861 // Close the bus driver
863 Status
= gBS
->OpenProtocol (
865 &gEfiPciIoProtocolGuid
,
867 This
->DriverBindingHandle
,
869 EFI_OPEN_PROTOCOL_GET_PROTOCOL
871 if (!EFI_ERROR (Status
)) {
872 Status
= PciIo
->Attributes (
874 EfiPciIoAttributeOperationSupported
,
878 if (!EFI_ERROR (Status
)) {
879 Supports
&= EFI_PCI_DEVICE_ENABLE
;
880 Status
= PciIo
->Attributes (
882 EfiPciIoAttributeOperationDisable
,
889 Status
= gBS
->CloseProtocol (
891 &gEfiPciIoProtocolGuid
,
892 This
->DriverBindingHandle
,
896 Status
= gBS
->CloseProtocol (
898 &gEfiDevicePathProtocolGuid
,
899 This
->DriverBindingHandle
,
903 if (EFI_ERROR (Status
)) {
904 Status
= EFI_DEVICE_ERROR
;
909 AllChildrenStopped
= TRUE
;
911 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
913 Status
= gBS
->OpenProtocol (
914 ChildHandleBuffer
[Index
],
915 &gEfiSimpleNetworkProtocolGuid
,
916 (VOID
**) &SimpleNetwork
,
917 This
->DriverBindingHandle
,
919 EFI_OPEN_PROTOCOL_GET_PROTOCOL
921 if (!EFI_ERROR (Status
)) {
923 SimpleNetworkDevice
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (SimpleNetwork
);
925 Status
= gBS
->CloseProtocol (
927 &gEfiPciIoProtocolGuid
,
928 This
->DriverBindingHandle
,
929 ChildHandleBuffer
[Index
]
932 Status
= gBS
->UninstallMultipleProtocolInterfaces (
933 SimpleNetworkDevice
->Handle
,
934 &gEfiSimpleNetworkProtocolGuid
,
935 &SimpleNetworkDevice
->SimpleNetwork
,
936 &gEfiNetworkInterfaceIdentifierProtocolGuid
,
937 &SimpleNetworkDevice
->Nii
,
938 &gEfiDevicePathProtocolGuid
,
939 SimpleNetworkDevice
->DevicePath
,
942 if (EFI_ERROR (Status
)) {
945 &gEfiPciIoProtocolGuid
,
947 This
->DriverBindingHandle
,
948 ChildHandleBuffer
[Index
],
949 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
953 Undi16SimpleNetworkShutdown (&SimpleNetworkDevice
->SimpleNetwork
);
957 Undi16SimpleNetworkCleanupUndi (SimpleNetworkDevice
);
961 Undi16SimpleNetworkStopUndi (SimpleNetworkDevice
);
965 if (SimpleNetworkDevice
->UndiLoaded
) {
966 Undi16SimpleNetworkUnloadUndi (SimpleNetworkDevice
);
969 if (SimpleNetworkDevice
->SimpleNetwork
.WaitForPacket
!= NULL
) {
970 gBS
->CloseEvent (SimpleNetworkDevice
->SimpleNetwork
.WaitForPacket
);
973 if (SimpleNetworkDevice
->LegacyBootEvent
!= NULL
) {
974 gBS
->CloseEvent (SimpleNetworkDevice
->LegacyBootEvent
);
977 if (SimpleNetworkDevice
->EfiBootEvent
!= NULL
) {
978 gBS
->CloseEvent (SimpleNetworkDevice
->EfiBootEvent
);
981 if (SimpleNetworkDevice
->Xmit
!= NULL
) {
983 (EFI_PHYSICAL_ADDRESS
) (UINTN
) SimpleNetworkDevice
->Xmit
,
984 sizeof (PXENV_UNDI_TBD_T
) / EFI_PAGE_SIZE
+ 1
988 if (SimpleNetworkDevice
->TxRealModeMediaHeader
!= NULL
) {
989 gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) SimpleNetworkDevice
->TxRealModeMediaHeader
, 1);
992 if (SimpleNetworkDevice
->TxRealModeDataBuffer
!= NULL
) {
993 gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) SimpleNetworkDevice
->TxRealModeDataBuffer
, 1);
996 if (SimpleNetworkDevice
->TxDestAddr
!= NULL
) {
997 gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) SimpleNetworkDevice
->TxDestAddr
, 1);
1000 gBS
->FreePool (SimpleNetworkDevice
);
1005 if (EFI_ERROR (Status
)) {
1006 AllChildrenStopped
= FALSE
;
1010 if (!AllChildrenStopped
) {
1011 return EFI_DEVICE_ERROR
;
1018 // FIFO Support Functions
1021 Judge whether transmit FIFO is full.
1023 @param Fifo Point to trasmit FIFO structure.
1025 @return BOOLEAN whether transmit FIFO is full.
1028 SimpleNetworkTransmitFifoFull (
1029 EFI_SIMPLE_NETWORK_DEV_FIFO
*Fifo
1032 if (((Fifo
->Last
+ 1) % EFI_SIMPLE_NETWORK_MAX_TX_FIFO_SIZE
) == Fifo
->First
) {
1040 Judge whether transmit FIFO is empty.
1042 @param Fifo Point to trasmit FIFO structure.
1044 @return BOOLEAN whether transmit FIFO is empty.
1047 SimpleNetworkTransmitFifoEmpty (
1048 EFI_SIMPLE_NETWORK_DEV_FIFO
*Fifo
1051 if (Fifo
->Last
== Fifo
->First
) {
1060 Add data into transmit buffer.
1062 @param Fifo Point to trasmit FIFO structure.
1063 @param Data The data point want to be added.
1065 @retval EFI_OUT_OF_RESOURCES FIFO is full
1066 @retval EFI_SUCCESS Success operation.
1069 SimpleNetworkTransmitFifoAdd (
1070 EFI_SIMPLE_NETWORK_DEV_FIFO
*Fifo
,
1074 if (SimpleNetworkTransmitFifoFull (Fifo
)) {
1075 return EFI_OUT_OF_RESOURCES
;
1078 Fifo
->Data
[Fifo
->Last
] = Data
;
1079 Fifo
->Last
= (Fifo
->Last
+ 1) % EFI_SIMPLE_NETWORK_MAX_TX_FIFO_SIZE
;
1084 Get a data and remove it from network transmit FIFO.
1086 @param Fifo Point to trasmit FIFO structure.
1087 @param Data On return, point to the data point want to be got and removed.
1089 @retval EFI_OUT_OF_RESOURCES network transmit buffer is empty.
1090 @retval EFI_SUCCESS Success operation.
1093 SimpleNetworkTransmitFifoRemove (
1094 EFI_SIMPLE_NETWORK_DEV_FIFO
*Fifo
,
1098 if (SimpleNetworkTransmitFifoEmpty (Fifo
)) {
1099 return EFI_OUT_OF_RESOURCES
;
1102 *Data
= Fifo
->Data
[Fifo
->First
];
1103 Fifo
->First
= (Fifo
->First
+ 1) % EFI_SIMPLE_NETWORK_MAX_TX_FIFO_SIZE
;
1108 Get recive filter setting according to EFI mask value.
1110 @param ReceiveFilterSetting filter setting EFI mask value.
1112 @return UINT16 Undi filter setting value.
1115 Undi16GetPacketFilterSetting (
1116 UINTN ReceiveFilterSetting
1122 if ((ReceiveFilterSetting
& EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
) != 0) {
1123 PktFilter
|= FLTR_DIRECTED
;
1126 if ((ReceiveFilterSetting
& EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
) != 0) {
1127 PktFilter
|= FLTR_DIRECTED
;
1130 if ((ReceiveFilterSetting
& EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
) != 0) {
1131 PktFilter
|= FLTR_BRDCST
;
1134 if ((ReceiveFilterSetting
& EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
) != 0) {
1135 PktFilter
|= FLTR_PRMSCS
;
1138 if ((ReceiveFilterSetting
& EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
) != 0) {
1139 PktFilter
|= FLTR_PRMSCS
;
1141 // @bug : Do not know if this is right????
1145 // @bug : What is FLTR_SRC_RTG?
1151 Get filter setting from multi cast buffer .
1153 @param Mode Point to mode structure.
1154 @param McastBuffer The multi cast buffer
1155 @param HwAddressSize Size of filter value.
1159 Undi16GetMCastFilters (
1160 IN EFI_SIMPLE_NETWORK_MODE
*Mode
,
1161 IN OUT PXENV_UNDI_MCAST_ADDR_T
*McastBuffer
,
1162 IN UINTN HwAddressSize
1168 // @bug : What if Mode->MCastFilterCount > MAXNUM_MCADDR?
1170 McastBuffer
->MCastAddrCount
= (UINT16
) Mode
->MCastFilterCount
;
1171 for (Index
= 0; Index
< MAXNUM_MCADDR
; Index
++) {
1172 if (Index
< McastBuffer
->MCastAddrCount
) {
1173 CopyMem (&McastBuffer
->MCastAddr
[Index
], &Mode
->MCastFilter
[Index
], HwAddressSize
);
1175 ZeroMem (&McastBuffer
->MCastAddr
[Index
], HwAddressSize
);
1180 // Load 16 bit UNDI Option ROM into memory
1183 Loads the undi driver.
1185 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.
1187 @retval EFI_SUCCESS - Successfully loads undi driver.
1188 @retval EFI_NOT_FOUND - Doesn't find undi driver or undi driver load failure.
1191 Undi16SimpleNetworkLoadUndi (
1192 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
1196 EFI_PCI_IO_PROTOCOL
*PciIo
;
1198 PCI_EXPANSION_ROM_HEADER
*PciExpansionRomHeader
;
1199 PCI_DATA_STRUCTURE
*PciDataStructure
;
1202 if (!mCachedInt1A
) {
1203 Status
= CacheVectorAddress (0x1A);
1204 if (!EFI_ERROR (Status
)) {
1205 mCachedInt1A
= TRUE
;
1209 PciIo
= SimpleNetworkDevice
->PciIo
;
1213 EfiPciIoWidthUint32
,
1215 sizeof (Pci
) / sizeof (UINT32
),
1219 for (RomAddress
= 0xc0000; RomAddress
< 0xfffff; RomAddress
+= 0x800) {
1221 PciExpansionRomHeader
= (PCI_EXPANSION_ROM_HEADER
*) RomAddress
;
1223 if (PciExpansionRomHeader
->Signature
!= PCI_EXPANSION_ROM_HEADER_SIGNATURE
) {
1227 DEBUG ((DEBUG_INIT
, "Option ROM found at %X\n", RomAddress
));
1230 // If the pointer to the PCI Data Structure is invalid, no further images can be located.
1231 // The PCI Data Structure must be DWORD aligned.
1233 if (PciExpansionRomHeader
->PcirOffset
== 0 ||
1234 (PciExpansionRomHeader
->PcirOffset
& 3) != 0 ||
1235 RomAddress
+ PciExpansionRomHeader
->PcirOffset
+ sizeof (PCI_DATA_STRUCTURE
) > 0x100000) {
1239 PciDataStructure
= (PCI_DATA_STRUCTURE
*) (RomAddress
+ PciExpansionRomHeader
->PcirOffset
);
1241 if (PciDataStructure
->Signature
!= PCI_DATA_STRUCTURE_SIGNATURE
) {
1245 DEBUG ((DEBUG_INIT
, "PCI Data Structure found at %X\n", PciDataStructure
));
1247 if (PciDataStructure
->VendorId
!= Pci
.Hdr
.VendorId
|| PciDataStructure
->DeviceId
!= Pci
.Hdr
.DeviceId
) {
1253 "PCI device with matchinng VendorId and DeviceId (%d,%d)\n",
1254 (UINTN
) PciDataStructure
->VendorId
,
1255 (UINTN
) PciDataStructure
->DeviceId
)
1258 Status
= LaunchBaseCode (SimpleNetworkDevice
, RomAddress
);
1260 if (!EFI_ERROR (Status
)) {
1265 // Free resources allocated in LaunchBaseCode
1267 Undi16SimpleNetworkUnloadUndi (SimpleNetworkDevice
);
1270 return EFI_NOT_FOUND
;
1274 Unload 16 bit UNDI Option ROM from memory
1276 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.
1281 Undi16SimpleNetworkUnloadUndi (
1282 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
1285 if (SimpleNetworkDevice
->UndiLoaderTable
!= NULL
) {
1286 ZeroMem (SimpleNetworkDevice
->UndiLoaderTable
, SimpleNetworkDevice
->UndiLoaderTablePages
<< EFI_PAGE_SHIFT
);
1288 (EFI_PHYSICAL_ADDRESS
) (UINTN
) SimpleNetworkDevice
->UndiLoaderTable
,
1289 SimpleNetworkDevice
->UndiLoaderTablePages
1293 if (SimpleNetworkDevice
->DestinationDataSegment
!= NULL
) {
1295 SimpleNetworkDevice
->DestinationDataSegment
,
1296 SimpleNetworkDevice
->DestinationDataSegmentPages
<< EFI_PAGE_SHIFT
1299 (EFI_PHYSICAL_ADDRESS
) (UINTN
) SimpleNetworkDevice
->DestinationDataSegment
,
1300 SimpleNetworkDevice
->DestinationDataSegmentPages
1304 if (SimpleNetworkDevice
->DestinationStackSegment
!= NULL
) {
1306 SimpleNetworkDevice
->DestinationStackSegment
,
1307 SimpleNetworkDevice
->DestinationStackSegmentPages
<< EFI_PAGE_SHIFT
1310 (EFI_PHYSICAL_ADDRESS
) (UINTN
) SimpleNetworkDevice
->DestinationStackSegment
,
1311 SimpleNetworkDevice
->DestinationStackSegmentPages
1315 if (SimpleNetworkDevice
->DestinationCodeSegment
!= NULL
) {
1317 SimpleNetworkDevice
->DestinationCodeSegment
,
1318 SimpleNetworkDevice
->DestinationCodeSegmentPages
<< EFI_PAGE_SHIFT
1321 (EFI_PHYSICAL_ADDRESS
) (UINTN
) SimpleNetworkDevice
->DestinationCodeSegment
,
1322 SimpleNetworkDevice
->DestinationCodeSegmentPages
1330 Start the UNDI interface.
1332 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.
1333 @param Ax PCI address of Undi device.
1335 @retval EFI_DEVICE_ERROR Fail to start 16 bit UNDI ROM.
1336 @retval Others Status of start 16 bit UNDI ROM.
1339 Undi16SimpleNetworkStartUndi (
1340 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
,
1345 PXENV_START_UNDI_T Start
;
1348 // Call 16 bit UNDI ROM to start the network interface
1351 // @bug : What is this state supposed to be???
1353 Start
.Status
= INIT_PXE_STATUS
;
1360 Status
= PxeStartUndi (SimpleNetworkDevice
, &Start
);
1361 if (EFI_ERROR (Status
)) {
1365 // Check the status code from the 16 bit UNDI ROM
1367 if (Start
.Status
!= PXENV_STATUS_SUCCESS
) {
1368 return EFI_DEVICE_ERROR
;
1376 Stop the UNDI interface
1378 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.
1380 @retval EFI_DEVICE_ERROR Fail to stop 16 bit UNDI ROM.
1381 @retval Others Status of stop 16 bit UNDI ROM.
1384 Undi16SimpleNetworkStopUndi (
1385 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
1389 PXENV_STOP_UNDI_T Stop
;
1392 // Call 16 bit UNDI ROM to start the network interface
1394 Stop
.Status
= INIT_PXE_STATUS
;
1396 Status
= PxeUndiStop (SimpleNetworkDevice
, &Stop
);
1397 if (EFI_ERROR (Status
)) {
1401 // Check the status code from the 16 bit UNDI ROM
1403 if (Stop
.Status
!= PXENV_STATUS_SUCCESS
) {
1404 return EFI_DEVICE_ERROR
;
1411 Cleanup Unid network interface
1413 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.
1415 @retval EFI_DEVICE_ERROR Fail to cleanup 16 bit UNDI ROM.
1416 @retval Others Status of cleanup 16 bit UNDI ROM.
1419 Undi16SimpleNetworkCleanupUndi (
1420 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
1424 PXENV_UNDI_CLEANUP_T Cleanup
;
1427 // Call 16 bit UNDI ROM to cleanup the network interface
1429 Cleanup
.Status
= INIT_PXE_STATUS
;
1431 Status
= PxeUndiCleanup (SimpleNetworkDevice
, &Cleanup
);
1432 if (EFI_ERROR (Status
)) {
1436 // Check the status code from the 16 bit UNDI ROM
1438 if (Cleanup
.Status
!= PXENV_STATUS_SUCCESS
) {
1439 return EFI_DEVICE_ERROR
;
1446 Get runtime information for Undi network interface
1448 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
1450 @retval EFI_SUCCESS Sucess operation.
1451 @retval Others Fail to get runtime information for Undi network interface.
1454 Undi16SimpleNetworkGetInformation (
1455 IN EFI_SIMPLE_NETWORK_PROTOCOL
*This
1459 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
;
1463 return EFI_INVALID_PARAMETER
;
1466 Status
= EFI_SUCCESS
;
1467 SimpleNetworkDevice
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This
);
1469 if (SimpleNetworkDevice
== NULL
) {
1470 return EFI_DEVICE_ERROR
;
1473 // Verify that the current state of the adapter is valid for this call.
1475 switch (SimpleNetworkDevice
->SimpleNetworkMode
.State
) {
1476 case EfiSimpleNetworkStarted
:
1477 case EfiSimpleNetworkInitialized
:
1480 case EfiSimpleNetworkStopped
:
1481 return EFI_NOT_STARTED
;
1484 return EFI_DEVICE_ERROR
;
1487 // Call 16 bit UNDI ROM to start the network interface
1489 ZeroMem (&SimpleNetworkDevice
->GetInformation
, sizeof (PXENV_UNDI_GET_INFORMATION_T
));
1491 SimpleNetworkDevice
->GetInformation
.Status
= INIT_PXE_STATUS
;
1493 Status
= PxeUndiGetInformation (SimpleNetworkDevice
, &SimpleNetworkDevice
->GetInformation
);
1494 if (EFI_ERROR (Status
)) {
1498 DEBUG ((DEBUG_NET
, " GetInformation.Status = %d\n", SimpleNetworkDevice
->GetInformation
.Status
));
1499 DEBUG ((DEBUG_NET
, " GetInformation.BaseIo = %d\n", SimpleNetworkDevice
->GetInformation
.BaseIo
));
1500 DEBUG ((DEBUG_NET
, " GetInformation.IntNumber = %d\n", SimpleNetworkDevice
->GetInformation
.IntNumber
));
1501 DEBUG ((DEBUG_NET
, " GetInformation.MaxTranUnit = %d\n", SimpleNetworkDevice
->GetInformation
.MaxTranUnit
));
1502 DEBUG ((DEBUG_NET
, " GetInformation.HwType = %d\n", SimpleNetworkDevice
->GetInformation
.HwType
));
1503 DEBUG ((DEBUG_NET
, " GetInformation.HwAddrLen = %d\n", SimpleNetworkDevice
->GetInformation
.HwAddrLen
));
1504 DEBUG ((DEBUG_NET
, " GetInformation.ROMAddress = %d\n", SimpleNetworkDevice
->GetInformation
.ROMAddress
));
1505 DEBUG ((DEBUG_NET
, " GetInformation.RxBufCt = %d\n", SimpleNetworkDevice
->GetInformation
.RxBufCt
));
1506 DEBUG ((DEBUG_NET
, " GetInformation.TxBufCt = %d\n", SimpleNetworkDevice
->GetInformation
.TxBufCt
));
1508 DEBUG ((DEBUG_NET
, " GetInformation.CurNodeAddr ="));
1509 for (Index
= 0; Index
< 16; Index
++) {
1510 DEBUG ((DEBUG_NET
, "%02x ", SimpleNetworkDevice
->GetInformation
.CurrentNodeAddress
[Index
]));
1513 DEBUG ((DEBUG_NET
, "\n"));
1515 DEBUG ((DEBUG_NET
, " GetInformation.PermNodeAddr ="));
1516 for (Index
= 0; Index
< 16; Index
++) {
1517 DEBUG ((DEBUG_NET
, "%02x ", SimpleNetworkDevice
->GetInformation
.PermNodeAddress
[Index
]));
1520 DEBUG ((DEBUG_NET
, "\n"));
1523 // Check the status code from the 16 bit UNDI ROM
1525 if (SimpleNetworkDevice
->GetInformation
.Status
!= PXENV_STATUS_SUCCESS
) {
1526 return EFI_DEVICE_ERROR
;
1529 // The information has been retrieved. Fill in Mode data.
1531 SimpleNetworkDevice
->SimpleNetworkMode
.HwAddressSize
= SimpleNetworkDevice
->GetInformation
.HwAddrLen
;
1533 SimpleNetworkDevice
->SimpleNetworkMode
.MaxPacketSize
= SimpleNetworkDevice
->GetInformation
.MaxTranUnit
;
1535 SimpleNetworkDevice
->SimpleNetworkMode
.IfType
= (UINT8
) SimpleNetworkDevice
->GetInformation
.HwType
;
1538 &SimpleNetworkDevice
->SimpleNetworkMode
.CurrentAddress
,
1539 sizeof SimpleNetworkDevice
->SimpleNetworkMode
.CurrentAddress
1543 &SimpleNetworkDevice
->SimpleNetworkMode
.CurrentAddress
,
1544 &SimpleNetworkDevice
->GetInformation
.CurrentNodeAddress
,
1545 SimpleNetworkDevice
->SimpleNetworkMode
.HwAddressSize
1549 &SimpleNetworkDevice
->SimpleNetworkMode
.PermanentAddress
,
1550 sizeof SimpleNetworkDevice
->SimpleNetworkMode
.PermanentAddress
1554 &SimpleNetworkDevice
->SimpleNetworkMode
.PermanentAddress
,
1555 &SimpleNetworkDevice
->GetInformation
.PermNodeAddress
,
1556 SimpleNetworkDevice
->SimpleNetworkMode
.HwAddressSize
1560 // hard code broadcast address - not avail in PXE2.1
1563 &SimpleNetworkDevice
->SimpleNetworkMode
.BroadcastAddress
,
1564 sizeof SimpleNetworkDevice
->SimpleNetworkMode
.BroadcastAddress
1568 &SimpleNetworkDevice
->SimpleNetworkMode
.BroadcastAddress
,
1569 SimpleNetworkDevice
->SimpleNetworkMode
.HwAddressSize
,
1579 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
1581 @retval EFI_SUCCESS Sucess operation.
1582 @retval Others Fail to get NIC type.
1585 Undi16SimpleNetworkGetNicType (
1586 IN EFI_SIMPLE_NETWORK_PROTOCOL
*This
1590 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
;
1593 return EFI_INVALID_PARAMETER
;
1596 Status
= EFI_SUCCESS
;
1597 SimpleNetworkDevice
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This
);
1599 if (SimpleNetworkDevice
== NULL
) {
1600 return EFI_DEVICE_ERROR
;
1603 ZeroMem (&SimpleNetworkDevice
->GetNicType
, sizeof (PXENV_UNDI_GET_NIC_TYPE_T
));
1605 SimpleNetworkDevice
->GetNicType
.Status
= INIT_PXE_STATUS
;
1607 Status
= PxeUndiGetNicType (SimpleNetworkDevice
, &SimpleNetworkDevice
->GetNicType
);
1609 if (EFI_ERROR (Status
)) {
1613 DEBUG ((DEBUG_NET
, " GetNicType.Status = %d\n", SimpleNetworkDevice
->GetNicType
.Status
));
1614 DEBUG ((DEBUG_NET
, " GetNicType.NicType = %d\n", SimpleNetworkDevice
->GetNicType
.NicType
));
1616 // Check the status code from the 16 bit UNDI ROM
1618 if (SimpleNetworkDevice
->GetNicType
.Status
!= PXENV_STATUS_SUCCESS
) {
1619 return EFI_DEVICE_ERROR
;
1622 // The information has been retrieved. Fill in Mode data.
1628 Get NDIS information
1630 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
1632 @retval EFI_SUCCESS Sucess operation.
1633 @retval Others Fail to get NDIS information.
1636 Undi16SimpleNetworkGetNdisInfo (
1637 IN EFI_SIMPLE_NETWORK_PROTOCOL
*This
1641 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
;
1644 return EFI_INVALID_PARAMETER
;
1647 Status
= EFI_SUCCESS
;
1648 SimpleNetworkDevice
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This
);
1650 if (SimpleNetworkDevice
== NULL
) {
1651 return EFI_DEVICE_ERROR
;
1654 ZeroMem (&SimpleNetworkDevice
->GetNdisInfo
, sizeof (PXENV_UNDI_GET_NDIS_INFO_T
));
1656 SimpleNetworkDevice
->GetNdisInfo
.Status
= INIT_PXE_STATUS
;
1658 Status
= PxeUndiGetNdisInfo (SimpleNetworkDevice
, &SimpleNetworkDevice
->GetNdisInfo
);
1660 if (EFI_ERROR (Status
)) {
1664 DEBUG ((DEBUG_NET
, " GetNdisInfo.Status = %d\n", SimpleNetworkDevice
->GetNdisInfo
.Status
));
1665 DEBUG ((DEBUG_NET
, " GetNdisInfo.IfaceType = %a\n", SimpleNetworkDevice
->GetNdisInfo
.IfaceType
));
1666 DEBUG ((DEBUG_NET
, " GetNdisInfo.LinkSpeed = %d\n", SimpleNetworkDevice
->GetNdisInfo
.LinkSpeed
));
1667 DEBUG ((DEBUG_NET
, " GetNdisInfo.ServiceFlags = %08x\n", SimpleNetworkDevice
->GetNdisInfo
.ServiceFlags
));
1670 // Check the status code from the 16 bit UNDI ROM
1672 if (SimpleNetworkDevice
->GetNdisInfo
.Status
!= PXENV_STATUS_SUCCESS
) {
1673 return EFI_DEVICE_ERROR
;
1676 // The information has been retrieved. Fill in Mode data.
1682 Call Undi ROM 16bit ISR() to check interrupt cause.
1684 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
1685 @param FrameLength The length of frame buffer.
1686 @param FrameHeaderLength The length of frame buffer's header if has.
1687 @param Frame The frame buffer to process network interrupt.
1688 @param ProtType The type network transmit protocol
1689 @param PktType The type of package.
1691 @retval EFI_DEVICE_ERROR Fail to execute 16 bit ROM's ISR, or status is invalid.
1692 @retval EFI_SUCCESS Success operation.
1695 Undi16SimpleNetworkIsr (
1696 IN EFI_SIMPLE_NETWORK_PROTOCOL
* This
,
1697 IN UINTN
*FrameLength
,
1698 IN UINTN
*FrameHeaderLength
, OPTIONAL
1699 IN UINT8
*Frame
, OPTIONAL
1700 IN UINT8
*ProtType
, OPTIONAL
1701 IN UINT8
*PktType OPTIONAL
1705 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
;
1706 BOOLEAN FrameReceived
;
1709 return EFI_INVALID_PARAMETER
;
1712 Status
= EFI_SUCCESS
;
1713 SimpleNetworkDevice
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This
);
1715 if (SimpleNetworkDevice
== NULL
) {
1716 return EFI_DEVICE_ERROR
;
1719 FrameReceived
= FALSE
;
1722 // Verify that the current state of the adapter is valid for this call.
1724 switch (SimpleNetworkDevice
->SimpleNetworkMode
.State
) {
1725 case EfiSimpleNetworkInitialized
:
1728 case EfiSimpleNetworkStopped
:
1729 return EFI_NOT_STARTED
;
1731 case EfiSimpleNetworkStarted
:
1733 return EFI_DEVICE_ERROR
;
1736 DEBUG ((DEBUG_NET
, "Isr() IsrValid = %d\n", SimpleNetworkDevice
->IsrValid
));
1738 if (!SimpleNetworkDevice
->IsrValid
) {
1740 // Call 16 bit UNDI ROM to open the network interface
1742 ZeroMem (&SimpleNetworkDevice
->Isr
, sizeof (PXENV_UNDI_ISR_T
));
1743 SimpleNetworkDevice
->Isr
.Status
= INIT_PXE_STATUS
;
1744 SimpleNetworkDevice
->Isr
.FuncFlag
= PXENV_UNDI_ISR_IN_START
;
1746 DEBUG ((DEBUG_NET
, "Isr() START\n"));
1748 Status
= PxeUndiIsr (SimpleNetworkDevice
, &SimpleNetworkDevice
->Isr
);
1749 if (EFI_ERROR (Status
)) {
1753 // Check the status code from the 16 bit UNDI ROM
1755 if (SimpleNetworkDevice
->Isr
.Status
!= PXENV_STATUS_SUCCESS
) {
1756 return EFI_DEVICE_ERROR
;
1759 // There have been no events on this UNDI interface, so return EFI_NOT_READY
1761 if (SimpleNetworkDevice
->Isr
.FuncFlag
== PXENV_UNDI_ISR_OUT_NOT_OURS
) {
1765 // There is data to process, so call until all events processed.
1767 ZeroMem (&SimpleNetworkDevice
->Isr
, sizeof (PXENV_UNDI_ISR_T
));
1768 SimpleNetworkDevice
->Isr
.Status
= INIT_PXE_STATUS
;
1769 SimpleNetworkDevice
->Isr
.FuncFlag
= PXENV_UNDI_ISR_IN_PROCESS
;
1771 DEBUG ((DEBUG_NET
, "Isr() PROCESS\n"));
1773 Status
= PxeUndiIsr (SimpleNetworkDevice
, &SimpleNetworkDevice
->Isr
);
1774 if (EFI_ERROR (Status
)) {
1778 SimpleNetworkDevice
->IsrValid
= TRUE
;
1781 // Call UNDI GET_NEXT until DONE
1783 while (SimpleNetworkDevice
->Isr
.FuncFlag
!= PXENV_UNDI_ISR_OUT_DONE
) {
1785 // Check the status code from the 16 bit UNDI ROM
1787 if (SimpleNetworkDevice
->Isr
.Status
!= PXENV_STATUS_SUCCESS
) {
1788 return EFI_DEVICE_ERROR
;
1791 // UNDI is busy. Caller will have to call again.
1792 // This should never happen with a polled mode driver.
1794 if (SimpleNetworkDevice
->Isr
.FuncFlag
== PXENV_UNDI_ISR_OUT_BUSY
) {
1795 DEBUG ((DEBUG_NET
, " BUSY\n"));
1799 // Check for invalud UNDI FuncFlag
1801 if (SimpleNetworkDevice
->Isr
.FuncFlag
!= PXENV_UNDI_ISR_OUT_RECEIVE
&&
1802 SimpleNetworkDevice
->Isr
.FuncFlag
!= PXENV_UNDI_ISR_OUT_TRANSMIT
1804 DEBUG ((DEBUG_NET
, " Invalid SimpleNetworkDevice->Isr.FuncFlag value %d\n", SimpleNetworkDevice
->Isr
.FuncFlag
));
1805 return EFI_DEVICE_ERROR
;
1808 // Check for Transmit Event
1810 if (SimpleNetworkDevice
->Isr
.FuncFlag
== PXENV_UNDI_ISR_OUT_TRANSMIT
) {
1811 DEBUG ((DEBUG_NET
, " TRANSMIT\n"));
1812 SimpleNetworkDevice
->InterruptStatus
|= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT
;
1815 // Check for Receive Event
1817 else if (SimpleNetworkDevice
->Isr
.FuncFlag
== PXENV_UNDI_ISR_OUT_RECEIVE
) {
1819 // note - this code will hang on a receive interrupt in a GetStatus loop
1821 DEBUG ((DEBUG_NET
, " RECEIVE\n"));
1822 SimpleNetworkDevice
->InterruptStatus
|= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT
;
1824 DEBUG ((DEBUG_NET
, "SimpleNetworkDevice->Isr.BufferLength = %d\n", SimpleNetworkDevice
->Isr
.BufferLength
));
1825 DEBUG ((DEBUG_NET
, "SimpleNetworkDevice->Isr.FrameLength = %d\n", SimpleNetworkDevice
->Isr
.FrameLength
));
1826 DEBUG ((DEBUG_NET
, "SimpleNetworkDevice->Isr.FrameHeaderLength = %d\n", SimpleNetworkDevice
->Isr
.FrameHeaderLength
));
1829 DEBUG_NET
, "SimpleNetworkDevice->Isr.Frame = %04x:%04x\n", SimpleNetworkDevice
->Isr
.FrameSegSel
,
1830 SimpleNetworkDevice
->Isr
.FrameOffset
1833 DEBUG ((DEBUG_NET
, "SimpleNetworkDevice->Isr.ProtType = 0x%02x\n", SimpleNetworkDevice
->Isr
.BufferLength
));
1834 DEBUG ((DEBUG_NET
, "SimpleNetworkDevice->Isr.PktType = 0x%02x\n", SimpleNetworkDevice
->Isr
.BufferLength
));
1836 if (FrameReceived
) {
1840 if ((Frame
== NULL
) || (SimpleNetworkDevice
->Isr
.FrameLength
> *FrameLength
)) {
1841 DEBUG ((DEBUG_NET
, "return EFI_BUFFER_TOO_SMALL *FrameLength = %08x\n", *FrameLength
));
1842 *FrameLength
= SimpleNetworkDevice
->Isr
.FrameLength
;
1843 return EFI_BUFFER_TOO_SMALL
;
1846 *FrameLength
= SimpleNetworkDevice
->Isr
.FrameLength
;
1847 if (FrameHeaderLength
!= NULL
) {
1848 *FrameHeaderLength
= SimpleNetworkDevice
->Isr
.FrameHeaderLength
;
1851 if (ProtType
!= NULL
) {
1852 *ProtType
= SimpleNetworkDevice
->Isr
.ProtType
;
1855 if (PktType
!= NULL
) {
1856 *PktType
= SimpleNetworkDevice
->Isr
.PktType
;
1861 (VOID
*)(UINTN
) ((SimpleNetworkDevice
->Isr
.FrameSegSel
<< 4) + SimpleNetworkDevice
->Isr
.FrameOffset
),
1862 SimpleNetworkDevice
->Isr
.BufferLength
1864 Frame
= Frame
+ SimpleNetworkDevice
->Isr
.BufferLength
;
1865 if (SimpleNetworkDevice
->Isr
.BufferLength
== SimpleNetworkDevice
->Isr
.FrameLength
) {
1866 FrameReceived
= TRUE
;
1870 // There is data to process, so call until all events processed.
1872 ZeroMem (&SimpleNetworkDevice
->Isr
, sizeof (PXENV_UNDI_ISR_T
));
1873 SimpleNetworkDevice
->Isr
.Status
= INIT_PXE_STATUS
;
1874 SimpleNetworkDevice
->Isr
.FuncFlag
= PXENV_UNDI_ISR_IN_GET_NEXT
;
1876 DEBUG ((DEBUG_NET
, "Isr() GET NEXT\n"));
1878 Status
= PxeUndiIsr (SimpleNetworkDevice
, &SimpleNetworkDevice
->Isr
);
1879 if (EFI_ERROR (Status
)) {
1883 // Check the status code from the 16 bit UNDI ROM
1885 // if (SimpleNetworkDevice->Isr.Status != PXENV_STATUS_SUCCESS) {
1886 // return EFI_DEVICE_ERROR;
1891 SimpleNetworkDevice
->IsrValid
= FALSE
;
1895 // ///////////////////////////////////////////////////////////////////////////////////////
1896 // Simple Network Protocol Interface Functions using 16 bit UNDI Option ROMs
1897 /////////////////////////////////////////////////////////////////////////////////////////
1902 Call 16 bit UNDI ROM to start the network interface
1904 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
1906 @retval EFI_DEVICE_ERROR Network interface has not be initialized.
1907 @retval EFI_DEVICE_ERROR Fail to execute 16 bit ROM call.
1908 @retval EFI_SUCESS Success operation.
1912 Undi16SimpleNetworkStart (
1913 IN EFI_SIMPLE_NETWORK_PROTOCOL
*This
1917 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
;
1918 PXENV_UNDI_STARTUP_T Startup
;
1921 return EFI_INVALID_PARAMETER
;
1924 Status
= EFI_SUCCESS
;
1925 SimpleNetworkDevice
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This
);
1927 if (SimpleNetworkDevice
== NULL
) {
1928 return EFI_DEVICE_ERROR
;
1931 // Verify that the current state of the adapter is valid for this call.
1933 switch (SimpleNetworkDevice
->SimpleNetworkMode
.State
) {
1934 case EfiSimpleNetworkStopped
:
1937 case EfiSimpleNetworkStarted
:
1938 case EfiSimpleNetworkInitialized
:
1939 return EFI_ALREADY_STARTED
;
1942 return EFI_DEVICE_ERROR
;
1945 // Call 16 bit UNDI ROM to start the network interface
1947 Startup
.Status
= INIT_PXE_STATUS
;
1949 Status
= PxeUndiStartup (SimpleNetworkDevice
, &Startup
);
1950 if (EFI_ERROR (Status
)) {
1954 // Check the status code from the 16 bit UNDI ROM
1956 if (Startup
.Status
!= PXENV_STATUS_SUCCESS
) {
1957 return EFI_DEVICE_ERROR
;
1960 // The UNDI interface has been started, so update the State.
1962 SimpleNetworkDevice
->SimpleNetworkMode
.State
= EfiSimpleNetworkStarted
;
1967 SimpleNetworkDevice
->SimpleNetworkMode
.ReceiveFilterSetting
= 0;
1968 SimpleNetworkDevice
->SimpleNetworkMode
.MCastFilterCount
= 0;
1976 Call 16 bit UNDI ROM to stop the network interface
1978 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
1980 @retval EFI_DEVICE_ERROR Network interface has not be initialized.
1981 @retval EFI_DEVICE_ERROR Fail to execute 16 bit ROM call.
1982 @retval EFI_SUCESS Success operation.
1986 Undi16SimpleNetworkStop (
1987 IN EFI_SIMPLE_NETWORK_PROTOCOL
*This
1991 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
;
1994 return EFI_INVALID_PARAMETER
;
1997 Status
= EFI_SUCCESS
;
1998 SimpleNetworkDevice
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This
);
2000 if (SimpleNetworkDevice
== NULL
) {
2001 return EFI_DEVICE_ERROR
;
2004 // Verify that the current state of the adapter is valid for this call.
2006 switch (SimpleNetworkDevice
->SimpleNetworkMode
.State
) {
2007 case EfiSimpleNetworkStarted
:
2010 case EfiSimpleNetworkStopped
:
2011 return EFI_NOT_STARTED
;
2013 case EfiSimpleNetworkInitialized
:
2015 return EFI_DEVICE_ERROR
;
2018 SimpleNetworkDevice
->SimpleNetworkMode
.State
= EfiSimpleNetworkStopped
;
2027 Initialize network interface
2029 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
2030 @param ExtraRxBufferSize The size of extra request receive buffer.
2031 @param ExtraTxBufferSize The size of extra request transmit buffer.
2033 @retval EFI_DEVICE_ERROR Fail to execute 16 bit ROM call.
2034 @retval EFI_SUCESS Success operation.
2038 Undi16SimpleNetworkInitialize (
2039 IN EFI_SIMPLE_NETWORK_PROTOCOL
*This
,
2040 IN UINTN ExtraRxBufferSize OPTIONAL
,
2041 IN UINTN ExtraTxBufferSize OPTIONAL
2045 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
;
2046 PXENV_UNDI_INITIALIZE_T Initialize
;
2047 PXENV_UNDI_OPEN_T Open
;
2050 return EFI_INVALID_PARAMETER
;
2053 Status
= EFI_SUCCESS
;
2054 SimpleNetworkDevice
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This
);
2056 if (SimpleNetworkDevice
== NULL
) {
2057 return EFI_DEVICE_ERROR
;
2060 // Verify that the current state of the adapter is valid for this call.
2062 switch (SimpleNetworkDevice
->SimpleNetworkMode
.State
) {
2063 case EfiSimpleNetworkStopped
:
2064 return EFI_NOT_STARTED
;
2066 case EfiSimpleNetworkStarted
:
2069 case EfiSimpleNetworkInitialized
:
2071 return EFI_DEVICE_ERROR
;
2074 // Call 16 bit UNDI ROM to start the network interface
2076 Initialize
.Status
= INIT_PXE_STATUS
;
2077 Initialize
.ProtocolIni
= 0;
2079 Status
= PxeUndiInitialize (SimpleNetworkDevice
, &Initialize
);
2081 if (EFI_ERROR (Status
)) {
2082 DEBUG ((DEBUG_ERROR
, "ERROR : PxeUndiInitialize() - Status = %r\n", Status
));
2083 DEBUG ((DEBUG_ERROR
, "Initialize.Status == %xh\n", Initialize
.Status
));
2085 if (Initialize
.Status
== PXENV_STATUS_UNDI_MEDIATEST_FAILED
) {
2086 Status
= EFI_NO_MEDIA
;
2092 // Check the status code from the 16 bit UNDI ROM
2094 if (Initialize
.Status
!= PXENV_STATUS_SUCCESS
) {
2095 DEBUG ((DEBUG_ERROR
, "ERROR : PxeUndiInitialize() - Initialize.Status = %04x\n", Initialize
.Status
));
2096 return EFI_DEVICE_ERROR
;
2099 // Call 16 bit UNDI ROM to open the network interface
2101 Open
.Status
= INIT_PXE_STATUS
;
2103 Open
.PktFilter
= Undi16GetPacketFilterSetting (SimpleNetworkDevice
->SimpleNetworkMode
.ReceiveFilterSetting
);
2104 Undi16GetMCastFilters (
2105 &SimpleNetworkDevice
->SimpleNetworkMode
,
2107 SimpleNetworkDevice
->SimpleNetworkMode
.HwAddressSize
2110 Status
= PxeUndiOpen (SimpleNetworkDevice
, &Open
);
2112 if (EFI_ERROR (Status
)) {
2113 DEBUG ((DEBUG_ERROR
, "ERROR : PxeUndiOpen() - Status = %r\n", Status
));
2117 // Check the status code from the 16 bit UNDI ROM
2119 if (Open
.Status
!= PXENV_STATUS_SUCCESS
) {
2120 DEBUG ((DEBUG_ERROR
, "ERROR : PxeUndiOpen() - Open.Status = %04x\n", Open
.Status
));
2121 return EFI_DEVICE_ERROR
;
2124 // The UNDI interface has been initialized, so update the State.
2126 SimpleNetworkDevice
->SimpleNetworkMode
.State
= EfiSimpleNetworkInitialized
;
2129 // If initialize succeeds, then assume that media is present.
2131 SimpleNetworkDevice
->SimpleNetworkMode
.MediaPresent
= TRUE
;
2134 // Reset the recycled transmit buffer FIFO
2136 SimpleNetworkDevice
->TxBufferFifo
.First
= 0;
2137 SimpleNetworkDevice
->TxBufferFifo
.Last
= 0;
2138 SimpleNetworkDevice
->IsrValid
= FALSE
;
2146 Reset network interface.
2148 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
2149 @param ExtendedVerification Need extended verfication.
2151 @retval EFI_INVALID_PARAMETER Invalid This paramter.
2152 @retval EFI_DEVICE_ERROR Network device has not been initialized.
2153 @retval EFI_NOT_STARTED Network device has been stopped.
2154 @retval EFI_DEVICE_ERROR Invalid status for network device
2155 @retval EFI_SUCCESS Success operation.
2159 Undi16SimpleNetworkReset (
2160 IN EFI_SIMPLE_NETWORK_PROTOCOL
*This
,
2161 IN BOOLEAN ExtendedVerification
2165 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
;
2166 PXENV_UNDI_RESET_T Reset
;
2170 return EFI_INVALID_PARAMETER
;
2173 Status
= EFI_SUCCESS
;
2174 SimpleNetworkDevice
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This
);
2176 if (SimpleNetworkDevice
== NULL
) {
2177 return EFI_DEVICE_ERROR
;
2180 // Verify that the current state of the adapter is valid for this call.
2182 switch (SimpleNetworkDevice
->SimpleNetworkMode
.State
) {
2183 case EfiSimpleNetworkStopped
:
2184 return EFI_NOT_STARTED
;
2186 case EfiSimpleNetworkInitialized
:
2189 case EfiSimpleNetworkStarted
:
2191 return EFI_DEVICE_ERROR
;
2194 Reset
.Status
= INIT_PXE_STATUS
;
2196 Rx_filter
= Undi16GetPacketFilterSetting (SimpleNetworkDevice
->SimpleNetworkMode
.ReceiveFilterSetting
);
2198 Undi16GetMCastFilters (
2199 &SimpleNetworkDevice
->SimpleNetworkMode
,
2201 SimpleNetworkDevice
->SimpleNetworkMode
.HwAddressSize
2204 Status
= PxeUndiResetNic (SimpleNetworkDevice
, &Reset
, Rx_filter
);
2206 if (EFI_ERROR (Status
)) {
2210 // Check the status code from the 16 bit UNDI ROM
2212 if (Reset
.Status
!= PXENV_STATUS_SUCCESS
) {
2213 return EFI_DEVICE_ERROR
;
2216 // Reset the recycled transmit buffer FIFO
2218 SimpleNetworkDevice
->TxBufferFifo
.First
= 0;
2219 SimpleNetworkDevice
->TxBufferFifo
.Last
= 0;
2220 SimpleNetworkDevice
->IsrValid
= FALSE
;
2228 Shutdown network interface.
2230 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
2232 @retval EFI_INVALID_PARAMETER Invalid This paramter.
2233 @retval EFI_DEVICE_ERROR Network device has not been initialized.
2234 @retval EFI_NOT_STARTED Network device has been stopped.
2235 @retval EFI_DEVICE_ERROR Invalid status for network device
2236 @retval EFI_SUCCESS Success operation.
2240 Undi16SimpleNetworkShutdown (
2241 IN EFI_SIMPLE_NETWORK_PROTOCOL
*This
2245 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
;
2246 PXENV_UNDI_CLOSE_T Close
;
2247 PXENV_UNDI_SHUTDOWN_T Shutdown
;
2250 return EFI_INVALID_PARAMETER
;
2253 Status
= EFI_SUCCESS
;
2254 SimpleNetworkDevice
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This
);
2256 if (SimpleNetworkDevice
== NULL
) {
2257 return EFI_DEVICE_ERROR
;
2260 // Verify that the current state of the adapter is valid for this call.
2262 switch (SimpleNetworkDevice
->SimpleNetworkMode
.State
) {
2263 case EfiSimpleNetworkStopped
:
2264 return EFI_NOT_STARTED
;
2266 case EfiSimpleNetworkInitialized
:
2269 case EfiSimpleNetworkStarted
:
2271 return EFI_DEVICE_ERROR
;
2274 SimpleNetworkDevice
->IsrValid
= FALSE
;
2277 // Call 16 bit UNDI ROM to start the network interface
2279 Close
.Status
= INIT_PXE_STATUS
;
2281 Status
= PxeUndiClose (SimpleNetworkDevice
, &Close
);
2283 if (EFI_ERROR (Status
)) {
2287 // Check the status code from the 16 bit UNDI ROM
2289 if (Close
.Status
!= PXENV_STATUS_SUCCESS
) {
2290 return EFI_DEVICE_ERROR
;
2293 // Call 16 bit UNDI ROM to open the network interface
2295 Shutdown
.Status
= INIT_PXE_STATUS
;
2297 Status
= PxeUndiShutdown (SimpleNetworkDevice
, &Shutdown
);
2299 if (EFI_ERROR (Status
)) {
2303 // Check the status code from the 16 bit UNDI ROM
2305 if (Shutdown
.Status
!= PXENV_STATUS_SUCCESS
) {
2306 return EFI_DEVICE_ERROR
;
2309 // The UNDI interface has been initialized, so update the State.
2311 SimpleNetworkDevice
->SimpleNetworkMode
.State
= EfiSimpleNetworkStarted
;
2314 // If shutdown succeeds, then assume that media is not present.
2316 SimpleNetworkDevice
->SimpleNetworkMode
.MediaPresent
= FALSE
;
2319 // Reset the recycled transmit buffer FIFO
2321 SimpleNetworkDevice
->TxBufferFifo
.First
= 0;
2322 SimpleNetworkDevice
->TxBufferFifo
.Last
= 0;
2325 // A short delay. Without this an initialize immediately following
2326 // a shutdown will cause some versions of UNDI-16 to stop operating.
2328 gBS
->Stall (250000);
2336 Reset network interface.
2338 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
2339 @param Enable Enable mask value
2340 @param Disable Disable mask value
2341 @param ResetMCastFilter Whether reset multi cast filter or not
2342 @param MCastFilterCnt Count of mutli cast filter for different MAC address
2343 @param MCastFilter Buffer for mustli cast filter for different MAC address.
2345 @retval EFI_INVALID_PARAMETER Invalid This paramter.
2346 @retval EFI_DEVICE_ERROR Network device has not been initialized.
2347 @retval EFI_NOT_STARTED Network device has been stopped.
2348 @retval EFI_DEVICE_ERROR Invalid status for network device
2349 @retval EFI_SUCCESS Success operation.
2353 Undi16SimpleNetworkReceiveFilters (
2354 IN EFI_SIMPLE_NETWORK_PROTOCOL
* This
,
2357 IN BOOLEAN ResetMCastFilter
,
2358 IN UINTN MCastFilterCnt OPTIONAL
,
2359 IN EFI_MAC_ADDRESS
* MCastFilter OPTIONAL
2365 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
;
2366 PXENV_UNDI_CLOSE_T Close
;
2367 PXENV_UNDI_OPEN_T Open
;
2370 return EFI_INVALID_PARAMETER
;
2373 Status
= EFI_SUCCESS
;
2374 SimpleNetworkDevice
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This
);
2376 if (SimpleNetworkDevice
== NULL
) {
2377 return EFI_DEVICE_ERROR
;
2380 // Verify that the current state of the adapter is valid for this call.
2382 switch (SimpleNetworkDevice
->SimpleNetworkMode
.State
) {
2383 case EfiSimpleNetworkStopped
:
2384 return EFI_NOT_STARTED
;
2386 case EfiSimpleNetworkInitialized
:
2389 case EfiSimpleNetworkStarted
:
2391 return EFI_DEVICE_ERROR
;
2394 // First deal with possible filter setting changes
2396 if ((Enable
== 0) && (Disable
== 0) && !ResetMCastFilter
) {
2400 NewFilter
= (SimpleNetworkDevice
->SimpleNetworkMode
.ReceiveFilterSetting
| Enable
) &~Disable
;
2402 if ((NewFilter
& EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
) != 0) {
2403 if ((MCastFilterCnt
== 0) || (MCastFilter
== 0) || MCastFilterCnt
> SimpleNetworkDevice
->SimpleNetworkMode
.MaxMCastFilterCount
) {
2404 return EFI_INVALID_PARAMETER
;
2408 // Call 16 bit UNDI ROM to close the network interface
2410 Close
.Status
= INIT_PXE_STATUS
;
2412 Status
= PxeUndiClose (SimpleNetworkDevice
, &Close
);
2414 if (EFI_ERROR (Status
)) {
2418 // Check the status code from the 16 bit UNDI ROM
2420 if (Close
.Status
!= PXENV_STATUS_SUCCESS
) {
2421 return EFI_DEVICE_ERROR
;
2424 // Call 16 bit UNDI ROM to open the network interface
2427 // Reset the recycled transmit buffer FIFO
2429 SimpleNetworkDevice
->TxBufferFifo
.First
= 0;
2430 SimpleNetworkDevice
->TxBufferFifo
.Last
= 0;
2433 // Call 16 bit UNDI ROM to open the network interface
2435 ZeroMem (&Open
, sizeof Open
);
2437 Open
.Status
= INIT_PXE_STATUS
;
2438 Open
.PktFilter
= Undi16GetPacketFilterSetting (NewFilter
);
2440 if ((NewFilter
& EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
) != 0) {
2442 // Copy the MAC addresses into the UNDI open parameter structure
2444 Open
.McastBuffer
.MCastAddrCount
= (UINT16
) MCastFilterCnt
;
2445 for (Index
= 0; Index
< MCastFilterCnt
; ++Index
) {
2447 Open
.McastBuffer
.MCastAddr
[Index
],
2448 &MCastFilter
[Index
],
2449 sizeof Open
.McastBuffer
.MCastAddr
[Index
]
2452 } else if (!ResetMCastFilter
) {
2453 for (Index
= 0; Index
< SimpleNetworkDevice
->SimpleNetworkMode
.MCastFilterCount
; ++Index
) {
2455 Open
.McastBuffer
.MCastAddr
[Index
],
2456 &SimpleNetworkDevice
->SimpleNetworkMode
.MCastFilter
[Index
],
2457 sizeof Open
.McastBuffer
.MCastAddr
[Index
]
2462 Status
= PxeUndiOpen (SimpleNetworkDevice
, &Open
);
2464 if (EFI_ERROR (Status
)) {
2468 // Check the status code from the 16 bit UNDI ROM
2470 if (Open
.Status
!= PXENV_STATUS_SUCCESS
) {
2471 return EFI_DEVICE_ERROR
;
2474 SimpleNetworkDevice
->IsrValid
= FALSE
;
2475 SimpleNetworkDevice
->SimpleNetworkMode
.ReceiveFilterSetting
= NewFilter
;
2477 if ((NewFilter
& EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
) != 0) {
2478 SimpleNetworkDevice
->SimpleNetworkMode
.MCastFilterCount
= (UINT32
) MCastFilterCnt
;
2479 for (Index
= 0; Index
< MCastFilterCnt
; ++Index
) {
2481 &SimpleNetworkDevice
->SimpleNetworkMode
.MCastFilter
[Index
],
2482 &MCastFilter
[Index
],
2483 sizeof (EFI_MAC_ADDRESS
)
2488 // Read back multicast addresses.
2496 Set new MAC address.
2498 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
2499 @param Reset Whether reset station MAC address to permenent address
2500 @param New A pointer to New address
2502 @retval EFI_INVALID_PARAMETER Invalid This paramter.
2503 @retval EFI_DEVICE_ERROR Network device has not been initialized.
2504 @retval EFI_NOT_STARTED Network device has been stopped.
2505 @retval EFI_DEVICE_ERROR Invalid status for network device
2506 @retval EFI_SUCCESS Success operation.
2510 Undi16SimpleNetworkStationAddress (
2511 IN EFI_SIMPLE_NETWORK_PROTOCOL
* This
,
2513 IN EFI_MAC_ADDRESS
* New OPTIONAL
2517 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
;
2518 PXENV_UNDI_SET_STATION_ADDR_T SetStationAddr
;
2520 // EFI_DEVICE_PATH_PROTOCOL *OldDevicePath;
2522 PXENV_UNDI_CLOSE_T Close
;
2523 PXENV_UNDI_OPEN_T Open
;
2526 return EFI_INVALID_PARAMETER
;
2529 Status
= EFI_SUCCESS
;
2531 SimpleNetworkDevice
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This
);
2533 if (SimpleNetworkDevice
== NULL
) {
2534 return EFI_DEVICE_ERROR
;
2537 // Verify that the current state of the adapter is valid for this call.
2539 switch (SimpleNetworkDevice
->SimpleNetworkMode
.State
) {
2540 case EfiSimpleNetworkInitialized
:
2543 case EfiSimpleNetworkStopped
:
2544 return EFI_NOT_STARTED
;
2546 case EfiSimpleNetworkStarted
:
2548 return EFI_DEVICE_ERROR
;
2551 // Call 16 bit UNDI ROM to open the network interface
2553 SetStationAddr
.Status
= INIT_PXE_STATUS
;
2557 // If we are reseting the Station Address to the permanent address, and the
2558 // Station Address is not programmable, then just return EFI_SUCCESS.
2560 if (!SimpleNetworkDevice
->SimpleNetworkMode
.MacAddressChangeable
) {
2564 // If the address is already the permanent address, then just return success.
2567 &SimpleNetworkDevice
->SimpleNetworkMode
.CurrentAddress
,
2568 &SimpleNetworkDevice
->SimpleNetworkMode
.PermanentAddress
,
2569 SimpleNetworkDevice
->SimpleNetworkMode
.HwAddressSize
2574 // Copy the adapters permanent address to the new station address
2577 &SetStationAddr
.StationAddress
,
2578 &SimpleNetworkDevice
->SimpleNetworkMode
.PermanentAddress
,
2579 SimpleNetworkDevice
->SimpleNetworkMode
.HwAddressSize
2583 // If we are setting the Station Address, and the
2584 // Station Address is not programmable, return invalid parameter.
2586 if (!SimpleNetworkDevice
->SimpleNetworkMode
.MacAddressChangeable
) {
2587 return EFI_INVALID_PARAMETER
;
2590 // If the address is already the new address, then just return success.
2593 &SimpleNetworkDevice
->SimpleNetworkMode
.CurrentAddress
,
2595 SimpleNetworkDevice
->SimpleNetworkMode
.HwAddressSize
2600 // Copy New to the new station address
2603 &SetStationAddr
.StationAddress
,
2605 SimpleNetworkDevice
->SimpleNetworkMode
.HwAddressSize
2610 // Call 16 bit UNDI ROM to stop the network interface
2612 Close
.Status
= INIT_PXE_STATUS
;
2614 PxeUndiClose (SimpleNetworkDevice
, &Close
);
2617 // Call 16-bit UNDI ROM to set the station address
2619 SetStationAddr
.Status
= PXENV_STATUS_SUCCESS
;
2621 Status
= PxeUndiSetStationAddr (SimpleNetworkDevice
, &SetStationAddr
);
2624 // Call 16-bit UNDI ROM to start the network interface
2626 Open
.Status
= PXENV_STATUS_SUCCESS
;
2628 Open
.PktFilter
= Undi16GetPacketFilterSetting (SimpleNetworkDevice
->SimpleNetworkMode
.ReceiveFilterSetting
);
2629 Undi16GetMCastFilters (
2630 &SimpleNetworkDevice
->SimpleNetworkMode
,
2632 SimpleNetworkDevice
->SimpleNetworkMode
.HwAddressSize
2635 PxeUndiOpen (SimpleNetworkDevice
, &Open
);
2638 // Check status from station address change
2640 if (EFI_ERROR (Status
)) {
2644 // Check the status code from the 16 bit UNDI ROM
2646 if (SetStationAddr
.Status
!= PXENV_STATUS_SUCCESS
) {
2647 return EFI_DEVICE_ERROR
;
2651 &SimpleNetworkDevice
->SimpleNetworkMode
.CurrentAddress
,
2652 &SetStationAddr
.StationAddress
,
2653 SimpleNetworkDevice
->SimpleNetworkMode
.HwAddressSize
2656 #if 0 /* The device path is based on the permanent address not the current address. */
2658 // The station address was changed, so update the device path with the new MAC address.
2660 OldDevicePath
= SimpleNetworkDevice
->DevicePath
;
2661 SimpleNetworkDevice
->DevicePath
= DuplicateDevicePath (SimpleNetworkDevice
->BaseDevicePath
);
2662 SimpleNetworkAppendMacAddressDevicePath (
2663 &SimpleNetworkDevice
->DevicePath
,
2664 &SimpleNetworkDevice
->SimpleNetworkMode
.CurrentAddress
2667 Status
= LibReinstallProtocolInterfaces (
2668 SimpleNetworkDevice
->Handle
,
2669 &DevicePathProtocol
,
2671 SimpleNetworkDevice
->DevicePath
,
2675 if (EFI_ERROR (Status
)) {
2676 DEBUG ((DEBUG_ERROR
, "Failed to reinstall the DevicePath protocol for the Simple Network Device\n"));
2677 DEBUG ((DEBUG_ERROR
, " Status = %r\n", Status
));
2680 FreePool (OldDevicePath
);
2689 Resets or collects the statistics on a network interface.
2691 @param This Protocol instance pointer.
2692 @param Reset Set to TRUE to reset the statistics for the network interface.
2693 @param StatisticsSize On input the size, in bytes, of StatisticsTable. On
2694 output the size, in bytes, of the resulting table of
2696 @param StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
2697 contains the statistics.
2699 @retval EFI_SUCCESS The statistics were collected from the network interface.
2700 @retval EFI_NOT_STARTED The network interface has not been started.
2701 @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer
2702 size needed to hold the statistics is returned in
2704 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
2705 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
2706 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
2711 Undi16SimpleNetworkStatistics (
2712 IN EFI_SIMPLE_NETWORK_PROTOCOL
* This
,
2714 IN OUT UINTN
*StatisticsSize OPTIONAL
,
2715 OUT EFI_NETWORK_STATISTICS
* StatisticsTable OPTIONAL
2719 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
;
2720 PXENV_UNDI_CLEAR_STATISTICS_T ClearStatistics
;
2721 PXENV_UNDI_GET_STATISTICS_T GetStatistics
;
2724 return EFI_INVALID_PARAMETER
;
2727 Status
= EFI_SUCCESS
;
2728 SimpleNetworkDevice
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This
);
2730 if (SimpleNetworkDevice
== NULL
) {
2731 return EFI_DEVICE_ERROR
;
2734 // Verify that the current state of the adapter is valid for this call.
2736 switch (SimpleNetworkDevice
->SimpleNetworkMode
.State
) {
2737 case EfiSimpleNetworkInitialized
:
2740 case EfiSimpleNetworkStopped
:
2741 return EFI_NOT_STARTED
;
2743 case EfiSimpleNetworkStarted
:
2745 return EFI_DEVICE_ERROR
;
2748 if ((StatisticsSize
!= NULL
) && (*StatisticsSize
!= 0) && (StatisticsTable
== NULL
)) {
2749 return EFI_INVALID_PARAMETER
;
2753 // If Reset is TRUE, then clear all the statistics.
2757 DEBUG ((DEBUG_NET
, " RESET Statistics\n"));
2760 // Call 16 bit UNDI ROM to open the network interface
2762 ClearStatistics
.Status
= INIT_PXE_STATUS
;
2764 Status
= PxeUndiClearStatistics (SimpleNetworkDevice
, &ClearStatistics
);
2766 if (EFI_ERROR (Status
)) {
2770 // Check the status code from the 16 bit UNDI ROM
2772 if (ClearStatistics
.Status
!= PXENV_STATUS_SUCCESS
) {
2773 return EFI_DEVICE_ERROR
;
2776 DEBUG ((DEBUG_NET
, " RESET Statistics Complete"));
2779 if (StatisticsSize
!= NULL
) {
2780 EFI_NETWORK_STATISTICS LocalStatisticsTable
;
2782 DEBUG ((DEBUG_NET
, " GET Statistics\n"));
2785 // If the size if valid, then see if the table is valid
2787 if (StatisticsTable
== NULL
) {
2788 DEBUG ((DEBUG_NET
, " StatisticsTable is NULL\n"));
2789 return EFI_INVALID_PARAMETER
;
2792 // Call 16 bit UNDI ROM to open the network interface
2794 GetStatistics
.Status
= INIT_PXE_STATUS
;
2795 GetStatistics
.XmtGoodFrames
= 0;
2796 GetStatistics
.RcvGoodFrames
= 0;
2797 GetStatistics
.RcvCRCErrors
= 0;
2798 GetStatistics
.RcvResourceErrors
= 0;
2800 Status
= PxeUndiGetStatistics (SimpleNetworkDevice
, &GetStatistics
);
2802 if (EFI_ERROR (Status
)) {
2806 // Check the status code from the 16 bit UNDI ROM
2808 if (GetStatistics
.Status
!= PXENV_STATUS_SUCCESS
) {
2809 return EFI_DEVICE_ERROR
;
2812 // Fill in the Statistics Table with the collected values.
2814 SetMem (&LocalStatisticsTable
, sizeof LocalStatisticsTable
, 0xff);
2816 LocalStatisticsTable
.TxGoodFrames
= GetStatistics
.XmtGoodFrames
;
2817 LocalStatisticsTable
.RxGoodFrames
= GetStatistics
.RcvGoodFrames
;
2818 LocalStatisticsTable
.RxCrcErrorFrames
= GetStatistics
.RcvCRCErrors
;
2819 LocalStatisticsTable
.RxDroppedFrames
= GetStatistics
.RcvResourceErrors
;
2821 CopyMem (StatisticsTable
, &LocalStatisticsTable
, *StatisticsSize
);
2825 " Statistics Collected : Size=%d Buf=%08x\n",
2830 DEBUG ((DEBUG_NET
, " GET Statistics Complete"));
2832 if (*StatisticsSize
< sizeof LocalStatisticsTable
) {
2833 DEBUG ((DEBUG_NET
, " BUFFER TOO SMALL\n"));
2834 Status
= EFI_BUFFER_TOO_SMALL
;
2837 *StatisticsSize
= sizeof LocalStatisticsTable
;
2849 Translate IP address to MAC address.
2851 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
2852 @param IPv6 IPv6 or IPv4
2853 @param IP A pointer to given Ip address.
2854 @param MAC On return, translated MAC address.
2856 @retval EFI_INVALID_PARAMETER Invalid This paramter.
2857 @retval EFI_INVALID_PARAMETER Invalid IP address.
2858 @retval EFI_INVALID_PARAMETER Invalid return buffer for holding MAC address.
2859 @retval EFI_UNSUPPORTED Do not support IPv6
2860 @retval EFI_DEVICE_ERROR Network device has not been initialized.
2861 @retval EFI_NOT_STARTED Network device has been stopped.
2862 @retval EFI_DEVICE_ERROR Invalid status for network device
2863 @retval EFI_SUCCESS Success operation.
2867 Undi16SimpleNetworkMCastIpToMac (
2868 IN EFI_SIMPLE_NETWORK_PROTOCOL
*This
,
2870 IN EFI_IP_ADDRESS
*IP
,
2871 OUT EFI_MAC_ADDRESS
*MAC
2875 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
;
2876 PXENV_UNDI_GET_MCAST_ADDR_T GetMcastAddr
;
2878 if (This
== NULL
|| IP
== NULL
|| MAC
== NULL
) {
2879 return EFI_INVALID_PARAMETER
;
2882 Status
= EFI_SUCCESS
;
2883 SimpleNetworkDevice
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This
);
2885 if (SimpleNetworkDevice
== NULL
) {
2886 return EFI_DEVICE_ERROR
;
2889 // Verify that the current state of the adapter is valid for this call.
2891 switch (SimpleNetworkDevice
->SimpleNetworkMode
.State
) {
2892 case EfiSimpleNetworkStopped
:
2893 return EFI_NOT_STARTED
;
2895 case EfiSimpleNetworkInitialized
:
2898 case EfiSimpleNetworkStarted
:
2900 return EFI_DEVICE_ERROR
;
2903 // 16 bit UNDI Option ROMS do not support IPv6. Check for IPv6 usage.
2906 return EFI_UNSUPPORTED
;
2909 // Call 16 bit UNDI ROM to open the network interface
2911 GetMcastAddr
.Status
= INIT_PXE_STATUS
;
2912 CopyMem (&GetMcastAddr
.InetAddr
, IP
, 4);
2914 Status
= PxeUndiGetMcastAddr (SimpleNetworkDevice
, &GetMcastAddr
);
2916 if (EFI_ERROR (Status
)) {
2920 // Check the status code from the 16 bit UNDI ROM
2922 if (GetMcastAddr
.Status
!= PXENV_STATUS_SUCCESS
) {
2923 return EFI_DEVICE_ERROR
;
2926 // Copy the MAC address from the returned data structure.
2930 &GetMcastAddr
.MediaAddr
,
2931 SimpleNetworkDevice
->SimpleNetworkMode
.HwAddressSize
2940 Performs read and write operations on the NVRAM device attached to a
2943 @param This The protocol instance pointer.
2944 @param ReadWrite TRUE for read operations, FALSE for write operations.
2945 @param Offset Byte offset in the NVRAM device at which to start the read or
2946 write operation. This must be a multiple of NvRamAccessSize and
2947 less than NvRamSize.
2948 @param BufferSize The number of bytes to read or write from the NVRAM device.
2949 This must also be a multiple of NvramAccessSize.
2950 @param Buffer A pointer to the data buffer.
2952 @retval EFI_SUCCESS The NVRAM access was performed.
2953 @retval EFI_NOT_STARTED The network interface has not been started.
2954 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
2955 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
2956 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
2961 Undi16SimpleNetworkNvData (
2962 IN EFI_SIMPLE_NETWORK_PROTOCOL
*This
,
2963 IN BOOLEAN ReadWrite
,
2965 IN UINTN BufferSize
,
2969 return EFI_UNSUPPORTED
;
2975 Reads the current interrupt status and recycled transmit buffer status from
2976 a network interface.
2978 @param This The protocol instance pointer.
2979 @param InterruptStatus A pointer to the bit mask of the currently active interrupts
2980 If this is NULL, the interrupt status will not be read from
2981 the device. If this is not NULL, the interrupt status will
2982 be read from the device. When the interrupt status is read,
2983 it will also be cleared. Clearing the transmit interrupt
2984 does not empty the recycled transmit buffer array.
2985 @param TxBuf Recycled transmit buffer address. The network interface will
2986 not transmit if its internal recycled transmit buffer array
2987 is full. Reading the transmit buffer does not clear the
2988 transmit interrupt. If this is NULL, then the transmit buffer
2989 status will not be read. If there are no transmit buffers to
2990 recycle and TxBuf is not NULL, * TxBuf will be set to NULL.
2992 @retval EFI_SUCCESS The status of the network interface was retrieved.
2993 @retval EFI_NOT_STARTED The network interface has not been started.
2994 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
2995 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
2996 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
3001 Undi16SimpleNetworkGetStatus (
3002 IN EFI_SIMPLE_NETWORK_PROTOCOL
* This
,
3003 OUT UINT32
*InterruptStatus OPTIONAL
,
3004 OUT VOID
**TxBuf OPTIONAL
3008 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
;
3012 return EFI_INVALID_PARAMETER
;
3015 Status
= EFI_SUCCESS
;
3016 SimpleNetworkDevice
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This
);
3018 if (SimpleNetworkDevice
== NULL
) {
3019 return EFI_DEVICE_ERROR
;
3022 // Verify that the current state of the adapter is valid for this call.
3024 switch (SimpleNetworkDevice
->SimpleNetworkMode
.State
) {
3025 case EfiSimpleNetworkInitialized
:
3028 case EfiSimpleNetworkStopped
:
3029 return EFI_NOT_STARTED
;
3031 case EfiSimpleNetworkStarted
:
3033 return EFI_DEVICE_ERROR
;
3036 if (InterruptStatus
== NULL
&& TxBuf
== NULL
) {
3037 return EFI_INVALID_PARAMETER
;
3041 Status
= Undi16SimpleNetworkIsr (This
, &FrameLength
, NULL
, NULL
, NULL
, NULL
);
3043 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
3044 if (EFI_ERROR (Status
)) {
3049 // See if the caller wants interrupt info.
3051 if (InterruptStatus
!= NULL
) {
3052 *InterruptStatus
= SimpleNetworkDevice
->InterruptStatus
;
3053 SimpleNetworkDevice
->InterruptStatus
= 0;
3056 // See if the caller wants transmit buffer status info.
3058 if (TxBuf
!= NULL
) {
3060 SimpleNetworkTransmitFifoRemove (&(SimpleNetworkDevice
->TxBufferFifo
), TxBuf
);
3067 Places a packet in the transmit queue of a network interface.
3069 @param This The protocol instance pointer.
3070 @param HeaderSize The size, in bytes, of the media header to be filled in by
3071 the Transmit() function. If HeaderSize is non-zero, then it
3072 must be equal to This->Mode->MediaHeaderSize and the DestAddr
3073 and Protocol parameters must not be NULL.
3074 @param BufferSize The size, in bytes, of the entire packet (media header and
3075 data) to be transmitted through the network interface.
3076 @param Buffer A pointer to the packet (media header followed by data) to be
3077 transmitted. This parameter cannot be NULL. If HeaderSize is zero,
3078 then the media header in Buffer must already be filled in by the
3079 caller. If HeaderSize is non-zero, then the media header will be
3080 filled in by the Transmit() function.
3081 @param SrcAddr The source HW MAC address. If HeaderSize is zero, then this parameter
3082 is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then
3083 This->Mode->CurrentAddress is used for the source HW MAC address.
3084 @param DestAddr The destination HW MAC address. If HeaderSize is zero, then this
3085 parameter is ignored.
3086 @param Protocol The type of header to build. If HeaderSize is zero, then this
3087 parameter is ignored. See RFC 1700, section "Ether Types", for
3090 @retval EFI_SUCCESS The packet was placed on the transmit queue.
3091 @retval EFI_NOT_STARTED The network interface has not been started.
3092 @retval EFI_NOT_READY The network interface is too busy to accept this transmit request.
3093 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
3094 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
3095 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
3096 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
3101 Undi16SimpleNetworkTransmit (
3102 IN EFI_SIMPLE_NETWORK_PROTOCOL
*This
,
3103 IN UINTN HeaderSize
,
3104 IN UINTN BufferSize
,
3106 IN EFI_MAC_ADDRESS
*SrcAddr OPTIONAL
,
3107 IN EFI_MAC_ADDRESS
*DestAddr OPTIONAL
,
3108 IN UINT16
*Protocol OPTIONAL
3112 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
;
3113 PXENV_UNDI_TRANSMIT_T XmitInfo
;
3116 return EFI_INVALID_PARAMETER
;
3119 Status
= EFI_SUCCESS
;
3120 SimpleNetworkDevice
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This
);
3122 if (SimpleNetworkDevice
== NULL
) {
3123 return EFI_DEVICE_ERROR
;
3126 // Verify that the current state of the adapter is valid for this call.
3128 switch (SimpleNetworkDevice
->SimpleNetworkMode
.State
) {
3129 case EfiSimpleNetworkInitialized
:
3132 case EfiSimpleNetworkStopped
:
3133 return EFI_NOT_STARTED
;
3135 case EfiSimpleNetworkStarted
:
3137 return EFI_DEVICE_ERROR
;
3140 if (Buffer
== NULL
) {
3141 return EFI_INVALID_PARAMETER
;
3144 if (BufferSize
< SimpleNetworkDevice
->SimpleNetworkMode
.MediaHeaderSize
) {
3145 return EFI_BUFFER_TOO_SMALL
;
3148 if (HeaderSize
!= 0) {
3149 if (HeaderSize
!= SimpleNetworkDevice
->SimpleNetworkMode
.MediaHeaderSize
) {
3150 return EFI_INVALID_PARAMETER
;
3153 if (DestAddr
== NULL
|| Protocol
== NULL
) {
3154 return EFI_INVALID_PARAMETER
;
3157 if (DestAddr
!= NULL
) {
3161 SimpleNetworkDevice
->SimpleNetworkMode
.HwAddressSize
3165 if (SrcAddr
== NULL
) {
3166 SrcAddr
= &SimpleNetworkDevice
->SimpleNetworkMode
.CurrentAddress
;
3170 (UINT8
*) Buffer
+ SimpleNetworkDevice
->SimpleNetworkMode
.HwAddressSize
,
3172 SimpleNetworkDevice
->SimpleNetworkMode
.HwAddressSize
3175 if (Protocol
!= NULL
) {
3176 *(UINT16
*) ((UINT8
*) Buffer
+ 2 * SimpleNetworkDevice
->SimpleNetworkMode
.HwAddressSize
) = (UINT16
) (((*Protocol
& 0xFF) << 8) | ((*Protocol
>> 8) & 0xFF));
3180 // See if the recycled transmit buffer FIFO is full.
3181 // If it is full, then we can not transmit until the caller calls GetStatus() to pull
3182 // off recycled transmit buffers.
3184 if (SimpleNetworkTransmitFifoFull (&(SimpleNetworkDevice
->TxBufferFifo
))) {
3185 return EFI_NOT_READY
;
3188 // Output debug trace message.
3190 DEBUG ((DEBUG_NET
, "Undi16SimpleNetworkTransmit\n\r "));
3193 // Initialize UNDI WRITE parameter structure.
3195 XmitInfo
.Status
= INIT_PXE_STATUS
;
3196 XmitInfo
.Protocol
= P_UNKNOWN
;
3197 XmitInfo
.XmitFlag
= XMT_DESTADDR
;
3198 XmitInfo
.DestAddrOffset
= (UINT16
) ((UINT32
)(UINTN
) SimpleNetworkDevice
->TxDestAddr
& 0x000f);
3199 XmitInfo
.DestAddrSegment
= (UINT16
) ((UINT32
)(UINTN
) SimpleNetworkDevice
->TxDestAddr
>> 4);
3200 XmitInfo
.TBDOffset
= (UINT16
) ((UINT32
)(UINTN
) SimpleNetworkDevice
->Xmit
& 0x000f);
3201 XmitInfo
.TBDSegment
= (UINT16
) ((UINT32
)(UINTN
) SimpleNetworkDevice
->Xmit
>> 4);
3202 XmitInfo
.Reserved
[0] = 0;
3203 XmitInfo
.Reserved
[1] = 0;
3206 SimpleNetworkDevice
->TxDestAddr
,
3208 SimpleNetworkDevice
->SimpleNetworkMode
.HwAddressSize
3212 SimpleNetworkDevice
->TxRealModeMediaHeader
,
3214 SimpleNetworkDevice
->SimpleNetworkMode
.MediaHeaderSize
3217 SimpleNetworkDevice
->Xmit
->ImmedLength
= (UINT16
) SimpleNetworkDevice
->SimpleNetworkMode
.MediaHeaderSize
;
3219 SimpleNetworkDevice
->Xmit
->DataBlock
[0].TDDataLen
= (UINT16
) (BufferSize
- SimpleNetworkDevice
->Xmit
->ImmedLength
);
3222 SimpleNetworkDevice
->TxRealModeDataBuffer
,
3223 (UINT8
*) Buffer
+ SimpleNetworkDevice
->SimpleNetworkMode
.MediaHeaderSize
,
3224 SimpleNetworkDevice
->Xmit
->DataBlock
[0].TDDataLen
3228 // Make API call to UNDI TRANSMIT
3230 XmitInfo
.Status
= 0;
3232 Status
= PxeUndiTransmit (SimpleNetworkDevice
, &XmitInfo
);
3234 if (EFI_ERROR (Status
)) {
3238 // Check the status code from the 16 bit UNDI ROM
3240 switch (XmitInfo
.Status
) {
3241 case PXENV_STATUS_OUT_OF_RESOURCES
:
3242 return EFI_NOT_READY
;
3244 case PXENV_STATUS_SUCCESS
:
3248 return EFI_DEVICE_ERROR
;
3251 // Add address of Buffer to the recycled transmit buffer FIFO
3253 SimpleNetworkTransmitFifoAdd (&(SimpleNetworkDevice
->TxBufferFifo
), Buffer
);
3259 Receives a packet from a network interface.
3261 @param This The protocol instance pointer.
3262 @param HeaderSize The size, in bytes, of the media header received on the network
3263 interface. If this parameter is NULL, then the media header size
3264 will not be returned.
3265 @param BufferSize On entry, the size, in bytes, of Buffer. On exit, the size, in
3266 bytes, of the packet that was received on the network interface.
3267 @param Buffer A pointer to the data buffer to receive both the media header and
3269 @param SrcAddr The source HW MAC address. If this parameter is NULL, the
3270 HW MAC source address will not be extracted from the media
3272 @param DestAddr The destination HW MAC address. If this parameter is NULL,
3273 the HW MAC destination address will not be extracted from the
3275 @param Protocol The media header type. If this parameter is NULL, then the
3276 protocol will not be extracted from the media header. See
3277 RFC 1700 section "Ether Types" for examples.
3279 @retval EFI_SUCCESS The received data was stored in Buffer, and BufferSize has
3280 been updated to the number of bytes received.
3281 @retval EFI_NOT_STARTED The network interface has not been started.
3282 @retval EFI_NOT_READY The network interface is too busy to accept this transmit
3284 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
3285 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
3286 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
3287 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
3292 Undi16SimpleNetworkReceive (
3293 IN EFI_SIMPLE_NETWORK_PROTOCOL
*This
,
3294 OUT UINTN
*HeaderSize OPTIONAL
,
3295 IN OUT UINTN
*BufferSize
,
3297 OUT EFI_MAC_ADDRESS
*SrcAddr OPTIONAL
,
3298 OUT EFI_MAC_ADDRESS
*DestAddr OPTIONAL
,
3299 OUT UINT16
*Protocol OPTIONAL
3303 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
;
3304 UINTN MediaAddrSize
;
3307 if (This
== NULL
|| BufferSize
== NULL
|| Buffer
== NULL
) {
3308 return EFI_INVALID_PARAMETER
;
3311 Status
= EFI_SUCCESS
;
3312 SimpleNetworkDevice
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This
);
3314 if (SimpleNetworkDevice
== NULL
) {
3315 return EFI_DEVICE_ERROR
;
3318 // Verify that the current state of the adapter is valid for this call.
3320 switch (SimpleNetworkDevice
->SimpleNetworkMode
.State
) {
3321 case EfiSimpleNetworkInitialized
:
3324 case EfiSimpleNetworkStopped
:
3325 return EFI_NOT_STARTED
;
3327 case EfiSimpleNetworkStarted
:
3329 return EFI_DEVICE_ERROR
;
3332 Status
= Undi16SimpleNetworkIsr (
3341 if (EFI_ERROR (Status
)) {
3345 if ((SimpleNetworkDevice
->InterruptStatus
& EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT
) == 0) {
3346 return EFI_NOT_READY
;
3350 SimpleNetworkDevice
->InterruptStatus
&= ~EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT
;
3352 MediaAddrSize
= This
->Mode
->HwAddressSize
;
3354 if (SrcAddr
!= NULL
) {
3355 CopyMem (SrcAddr
, (UINT8
*) Buffer
+ MediaAddrSize
, MediaAddrSize
);
3358 if (DestAddr
!= NULL
) {
3359 CopyMem (DestAddr
, Buffer
, MediaAddrSize
);
3362 if (Protocol
!= NULL
) {
3363 *((UINT8
*) Protocol
) = *((UINT8
*) Buffer
+ (2 * MediaAddrSize
) + 1);
3364 *((UINT8
*) Protocol
+ 1) = *((UINT8
*) Buffer
+ (2 * MediaAddrSize
));
3367 DEBUG ((DEBUG_NET
, "Packet Received: BufferSize=%d HeaderSize = %d\n", *BufferSize
, *HeaderSize
));
3376 wait for a packet to be received.
3378 @param Event Event used with WaitForEvent() to wait for a packet to be received.
3379 @param Context Event Context
3384 Undi16SimpleNetworkWaitForPacket (
3390 // Someone is waiting on the receive packet event, if there's
3391 // a packet pending, signal the event
3393 if (!EFI_ERROR (Undi16SimpleNetworkCheckForPacket (Context
))) {
3394 gBS
->SignalEvent (Event
);
3401 Check whether packet is ready for receive.
3403 @param This The protocol instance pointer.
3405 @retval EFI_SUCCESS Receive data is ready.
3406 @retval EFI_NOT_STARTED The network interface has not been started.
3407 @retval EFI_NOT_READY The network interface is too busy to accept this transmit
3409 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
3410 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
3411 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
3412 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
3415 Undi16SimpleNetworkCheckForPacket (
3416 IN EFI_SIMPLE_NETWORK_PROTOCOL
*This
3420 EFI_SIMPLE_NETWORK_DEV
*SimpleNetworkDevice
;
3424 return EFI_INVALID_PARAMETER
;
3427 Status
= EFI_SUCCESS
;
3428 SimpleNetworkDevice
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This
);
3430 if (SimpleNetworkDevice
== NULL
) {
3431 return EFI_DEVICE_ERROR
;
3434 // Verify that the current state of the adapter is valid for this call.
3436 switch (SimpleNetworkDevice
->SimpleNetworkMode
.State
) {
3437 case EfiSimpleNetworkInitialized
:
3440 case EfiSimpleNetworkStopped
:
3441 return EFI_NOT_STARTED
;
3443 case EfiSimpleNetworkStarted
:
3445 return EFI_DEVICE_ERROR
;
3449 Status
= Undi16SimpleNetworkIsr (
3458 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
3459 if (EFI_ERROR (Status
)) {
3464 return ((SimpleNetworkDevice
->InterruptStatus
& EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT
) != 0) ? EFI_SUCCESS
: EFI_NOT_READY
;
3468 Signal handlers for ExitBootServices event.
3470 Clean up any Real-mode UNDI residue from the system
3472 @param Event ExitBootServices event
3477 Undi16SimpleNetworkEvent (
3483 // NOTE: This is not the only way to effect this cleanup. The prescribed mechanism
3484 // would be to perform an UNDI STOP command. This strategam has been attempted
3485 // but results in problems making some of the EFI core services from TPL_CALLBACK.
3486 // This issue needs to be resolved, but the other alternative has been to perform
3487 // the unchain logic explicitly, as done below.
3489 RestoreCachedVectorAddress (0x1A);
3493 Allocate buffer below 1M for real mode.
3495 @param NumPages The number pages want to be allocated.
3496 @param Buffer On return, allocated buffer.
3498 @return Status of allocating pages.
3501 BiosSnp16AllocatePagesBelowOneMb (
3507 EFI_PHYSICAL_ADDRESS PhysicalAddress
;
3509 PhysicalAddress
= 0x000fffff;
3510 Status
= gBS
->AllocatePages (
3512 EfiRuntimeServicesData
,
3516 if (EFI_ERROR (Status
)) {
3520 *Buffer
= (VOID
*) (UINTN
) PhysicalAddress
;