2 Implementation of driver entry point and driver binding protocol.
4 Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
12 One notified function to stop UNDI device when gBS->ExitBootServices() called.
14 @param Event Pointer to this event
15 @param Context Event handler private data
20 SnpNotifyExitBootServices (
27 Snp
= (SNP_DRIVER
*)Context
;
30 // Shutdown and stop UNDI driver
37 Send command to UNDI. It does nothing currently.
39 @param Cdb command to be sent to UNDI.
41 @retval EFI_INVALID_PARAMETER The command is 0.
42 @retval EFI_UNSUPPORTED Default return status because it's not
52 DEBUG ((EFI_D_ERROR
, "\nIssueHwUndiCommand() - This should not be called!"));
55 return EFI_INVALID_PARAMETER
;
59 // %%TBD - For now, nothing is done.
61 return EFI_UNSUPPORTED
;
66 Compute 8-bit checksum of a buffer.
68 @param Buffer Pointer to buffer.
69 @param Length Length of buffer in bytes.
71 @return 8-bit checksum of all bytes in buffer, or zero if ptr is NULL or len
87 if (Ptr
== NULL
|| Length
== 0) {
91 while (Length
-- != 0) {
92 Cksum
= (UINT8
) (Cksum
+ *Ptr
++);
99 Test to see if this driver supports ControllerHandle. This service
100 is called by the EFI boot service ConnectController(). In
101 order to make drivers as small as possible, there are a few calling
102 restrictions for this service. ConnectController() must
103 follow these calling restrictions. If any other agent wishes to call
104 Supported() it must also follow these calling restrictions.
106 @param This Protocol instance pointer.
107 @param ControllerHandle Handle of device to test.
108 @param RemainingDevicePath Optional parameter use to pick a specific child
111 @retval EFI_SUCCESS This driver supports this device.
112 @retval EFI_ALREADY_STARTED This driver is already running on this device.
113 @retval other This driver does not support this device.
118 SimpleNetworkDriverSupported (
119 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
120 IN EFI_HANDLE Controller
,
121 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
125 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
*NiiProtocol
;
128 Status
= gBS
->OpenProtocol (
130 &gEfiDevicePathProtocolGuid
,
132 This
->DriverBindingHandle
,
134 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
136 if (EFI_ERROR (Status
)) {
140 Status
= gBS
->OpenProtocol (
142 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
143 (VOID
**) &NiiProtocol
,
144 This
->DriverBindingHandle
,
146 EFI_OPEN_PROTOCOL_BY_DRIVER
149 if (EFI_ERROR (Status
)) {
150 if (Status
== EFI_ALREADY_STARTED
) {
151 DEBUG ((EFI_D_INFO
, "Support(): Already Started. on handle %p\n", Controller
));
156 DEBUG ((EFI_D_INFO
, "Support(): UNDI3.1 found on handle %p\n", Controller
));
159 // check the version, we don't want to connect to the undi16
161 if (NiiProtocol
->Type
!= EfiNetworkInterfaceUndi
) {
162 Status
= EFI_UNSUPPORTED
;
166 // Check to see if !PXE structure is valid. Paragraph alignment of !PXE structure is required.
168 if ((NiiProtocol
->Id
& 0x0F) != 0) {
169 DEBUG ((EFI_D_NET
, "\n!PXE structure is not paragraph aligned.\n"));
170 Status
= EFI_UNSUPPORTED
;
174 Pxe
= (PXE_UNDI
*) (UINTN
) (NiiProtocol
->Id
);
177 // Verify !PXE revisions.
179 if (Pxe
->hw
.Signature
!= PXE_ROMID_SIGNATURE
) {
180 DEBUG ((EFI_D_NET
, "\n!PXE signature is not valid.\n"));
181 Status
= EFI_UNSUPPORTED
;
185 if (Pxe
->hw
.Rev
< PXE_ROMID_REV
) {
186 DEBUG ((EFI_D_NET
, "\n!PXE.Rev is not supported.\n"));
187 Status
= EFI_UNSUPPORTED
;
191 if (Pxe
->hw
.MajorVer
< PXE_ROMID_MAJORVER
) {
193 DEBUG ((EFI_D_NET
, "\n!PXE.MajorVer is not supported.\n"));
194 Status
= EFI_UNSUPPORTED
;
197 } else if (Pxe
->hw
.MajorVer
== PXE_ROMID_MAJORVER
&& Pxe
->hw
.MinorVer
< PXE_ROMID_MINORVER
) {
198 DEBUG ((EFI_D_NET
, "\n!PXE.MinorVer is not supported."));
199 Status
= EFI_UNSUPPORTED
;
203 // Do S/W UNDI specific checks.
205 if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_HW_UNDI
) == 0) {
206 if (Pxe
->sw
.EntryPoint
< Pxe
->sw
.Len
) {
207 DEBUG ((EFI_D_NET
, "\n!PXE S/W entry point is not valid."));
208 Status
= EFI_UNSUPPORTED
;
212 if (Pxe
->sw
.BusCnt
== 0) {
213 DEBUG ((EFI_D_NET
, "\n!PXE.BusCnt is zero."));
214 Status
= EFI_UNSUPPORTED
;
219 Status
= EFI_SUCCESS
;
220 DEBUG ((EFI_D_INFO
, "Support(): supported on %p\n", Controller
));
225 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
226 This
->DriverBindingHandle
,
234 Start this driver on ControllerHandle. This service is called by the
235 EFI boot service ConnectController(). In order to make
236 drivers as small as possible, there are a few calling restrictions for
237 this service. ConnectController() must follow these
238 calling restrictions. If any other agent wishes to call Start() it
239 must also follow these calling restrictions.
241 @param This Protocol instance pointer.
242 @param ControllerHandle Handle of device to bind driver to.
243 @param RemainingDevicePath Optional parameter use to pick a specific child
246 @retval EFI_SUCCESS This driver is added to ControllerHandle
247 @retval EFI_DEVICE_ERROR This driver could not be started due to a device error
248 @retval other This driver does not support this device
253 SimpleNetworkDriverStart (
254 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
255 IN EFI_HANDLE Controller
,
256 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
259 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
*Nii
;
260 EFI_DEVICE_PATH_PROTOCOL
*NiiDevicePath
;
267 PXE_STATFLAGS InitStatFlags
;
268 EFI_PCI_IO_PROTOCOL
*PciIo
;
269 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*BarDesc
;
271 BOOLEAN FoundMemoryBar
;
273 DEBUG ((EFI_D_NET
, "\nSnpNotifyNetworkInterfaceIdentifier() "));
275 Status
= gBS
->OpenProtocol (
277 &gEfiDevicePathProtocolGuid
,
278 (VOID
**) &NiiDevicePath
,
279 This
->DriverBindingHandle
,
281 EFI_OPEN_PROTOCOL_BY_DRIVER
284 if (EFI_ERROR (Status
)) {
288 Status
= gBS
->LocateDevicePath (
289 &gEfiPciIoProtocolGuid
,
294 if (EFI_ERROR (Status
)) {
298 Status
= gBS
->OpenProtocol (
300 &gEfiPciIoProtocolGuid
,
302 This
->DriverBindingHandle
,
304 EFI_OPEN_PROTOCOL_GET_PROTOCOL
306 if (EFI_ERROR (Status
)) {
310 // Get the NII interface.
312 Status
= gBS
->OpenProtocol (
314 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
316 This
->DriverBindingHandle
,
318 EFI_OPEN_PROTOCOL_BY_DRIVER
320 if (EFI_ERROR (Status
)) {
323 &gEfiDevicePathProtocolGuid
,
324 This
->DriverBindingHandle
,
330 DEBUG ((EFI_D_INFO
, "Start(): UNDI3.1 found\n"));
332 Pxe
= (PXE_UNDI
*) (UINTN
) (Nii
->Id
);
334 if (Calc8BitCksum (Pxe
, Pxe
->hw
.Len
) != 0) {
335 DEBUG ((EFI_D_NET
, "\n!PXE checksum is not correct.\n"));
339 if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED
) != 0) {
341 // We can get any packets.
343 } else if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED
) != 0) {
345 // We need to be able to get broadcast packets for DHCP.
346 // If we do not have promiscuous support, we must at least have
347 // broadcast support or we cannot do DHCP!
350 DEBUG ((EFI_D_NET
, "\nUNDI does not have promiscuous or broadcast support."));
354 // OK, we like this UNDI, and we know snp is not already there on this handle
355 // Allocate and initialize a new simple network protocol structure.
357 Status
= PciIo
->AllocateBuffer (
361 SNP_MEM_PAGES (sizeof (SNP_DRIVER
)),
366 if (Status
!= EFI_SUCCESS
) {
367 DEBUG ((EFI_D_NET
, "\nCould not allocate SNP_DRIVER structure.\n"));
371 Snp
= (SNP_DRIVER
*) (UINTN
) Address
;
373 ZeroMem (Snp
, sizeof (SNP_DRIVER
));
376 Snp
->Signature
= SNP_DRIVER_SIGNATURE
;
378 EfiInitializeLock (&Snp
->Lock
, TPL_NOTIFY
);
380 Snp
->Snp
.Revision
= EFI_SIMPLE_NETWORK_PROTOCOL_REVISION
;
381 Snp
->Snp
.Start
= SnpUndi32Start
;
382 Snp
->Snp
.Stop
= SnpUndi32Stop
;
383 Snp
->Snp
.Initialize
= SnpUndi32Initialize
;
384 Snp
->Snp
.Reset
= SnpUndi32Reset
;
385 Snp
->Snp
.Shutdown
= SnpUndi32Shutdown
;
386 Snp
->Snp
.ReceiveFilters
= SnpUndi32ReceiveFilters
;
387 Snp
->Snp
.StationAddress
= SnpUndi32StationAddress
;
388 Snp
->Snp
.Statistics
= SnpUndi32Statistics
;
389 Snp
->Snp
.MCastIpToMac
= SnpUndi32McastIpToMac
;
390 Snp
->Snp
.NvData
= SnpUndi32NvData
;
391 Snp
->Snp
.GetStatus
= SnpUndi32GetStatus
;
392 Snp
->Snp
.Transmit
= SnpUndi32Transmit
;
393 Snp
->Snp
.Receive
= SnpUndi32Receive
;
394 Snp
->Snp
.WaitForPacket
= NULL
;
396 Snp
->Snp
.Mode
= &Snp
->Mode
;
398 Snp
->TxRxBufferSize
= 0;
399 Snp
->TxRxBuffer
= NULL
;
401 Snp
->RecycledTxBuf
= AllocatePool (sizeof (UINT64
) * SNP_TX_BUFFER_INCREASEMENT
);
402 if (Snp
->RecycledTxBuf
== NULL
) {
403 Status
= EFI_OUT_OF_RESOURCES
;
404 goto Error_DeleteSNP
;
406 Snp
->MaxRecycledTxBuf
= SNP_TX_BUFFER_INCREASEMENT
;
407 Snp
->RecycledTxBufCount
= 0;
409 if (Nii
->Revision
>= EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION
) {
410 Snp
->IfNum
= Nii
->IfNum
;
413 Snp
->IfNum
= (UINT8
) (Nii
->IfNum
& 0xFF);
416 if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_HW_UNDI
) != 0) {
417 Snp
->IsSwUndi
= FALSE
;
418 Snp
->IssueUndi32Command
= &IssueHwUndiCommand
;
420 Snp
->IsSwUndi
= TRUE
;
422 if ((Pxe
->sw
.Implementation
& PXE_ROMID_IMP_SW_VIRT_ADDR
) != 0) {
423 Snp
->IssueUndi32Command
= (ISSUE_UNDI32_COMMAND
) (UINTN
) Pxe
->sw
.EntryPoint
;
425 Snp
->IssueUndi32Command
= (ISSUE_UNDI32_COMMAND
) (UINTN
) ((UINT8
) (UINTN
) Pxe
+ Pxe
->sw
.EntryPoint
);
429 // Allocate a global CPB and DB buffer for this UNDI interface.
430 // we do this because:
432 // -UNDI 3.0 wants all the addresses passed to it (even the cpb and db) to be
433 // within 2GB limit, create them here and map them so that when undi calls
434 // v2p callback to check if the physical address is < 2gb, we will pass.
436 // -This is not a requirement for 3.1 or later UNDIs but the code looks
437 // simpler if we use the same cpb, db variables for both old and new undi
438 // interfaces from all the SNP interface calls (we don't map the buffers
439 // for the newer undi interfaces though)
441 // -it is OK to allocate one global set of CPB, DB pair for each UNDI
442 // interface as EFI does not multi-task and so SNP will not be re-entered!
444 Status
= PciIo
->AllocateBuffer (
448 SNP_MEM_PAGES (4096),
453 if (Status
!= EFI_SUCCESS
) {
454 DEBUG ((EFI_D_NET
, "\nCould not allocate CPB and DB structures.\n"));
455 goto Error_DeleteSNP
;
458 Snp
->Cpb
= (VOID
*) (UINTN
) Address
;
459 Snp
->Db
= (VOID
*) ((UINTN
) Address
+ 2048);
462 // Find the correct BAR to do IO.
464 // Enumerate through the PCI BARs for the device to determine which one is
465 // the IO BAR. Save the index of the BAR into the adapter info structure.
466 // for regular 32bit BARs, 0 is memory mapped, 1 is io mapped
468 Snp
->MemoryBarIndex
= 0;
470 FoundMemoryBar
= FALSE
;
472 for (BarIndex
= 0; BarIndex
< PCI_MAX_BAR
; BarIndex
++) {
473 Status
= PciIo
->GetBarAttributes (
479 if (Status
== EFI_UNSUPPORTED
) {
481 } else if (EFI_ERROR (Status
)) {
482 goto Error_DeleteSNP
;
485 if ((!FoundMemoryBar
) && (BarDesc
->ResType
== ACPI_ADDRESS_SPACE_TYPE_MEM
)) {
486 Snp
->MemoryBarIndex
= BarIndex
;
487 FoundMemoryBar
= TRUE
;
488 } else if ((!FoundIoBar
) && (BarDesc
->ResType
== ACPI_ADDRESS_SPACE_TYPE_IO
)) {
489 Snp
->IoBarIndex
= BarIndex
;
495 if (FoundMemoryBar
&& FoundIoBar
) {
500 Status
= PxeStart (Snp
);
502 if (Status
!= EFI_SUCCESS
) {
503 goto Error_DeleteSNP
;
506 Snp
->Cdb
.OpCode
= PXE_OPCODE_GET_INIT_INFO
;
507 Snp
->Cdb
.OpFlags
= PXE_OPFLAGS_NOT_USED
;
509 Snp
->Cdb
.CPBsize
= PXE_CPBSIZE_NOT_USED
;
510 Snp
->Cdb
.CPBaddr
= PXE_DBADDR_NOT_USED
;
512 Snp
->Cdb
.DBsize
= (UINT16
) sizeof (Snp
->InitInfo
);
513 Snp
->Cdb
.DBaddr
= (UINT64
)(UINTN
) (&Snp
->InitInfo
);
515 Snp
->Cdb
.StatCode
= PXE_STATCODE_INITIALIZE
;
516 Snp
->Cdb
.StatFlags
= PXE_STATFLAGS_INITIALIZE
;
518 Snp
->Cdb
.IFnum
= Snp
->IfNum
;
519 Snp
->Cdb
.Control
= PXE_CONTROL_LAST_CDB_IN_LIST
;
521 DEBUG ((EFI_D_NET
, "\nSnp->undi.get_init_info() "));
523 (*Snp
->IssueUndi32Command
) ((UINT64
)(UINTN
) &Snp
->Cdb
);
526 // Save the INIT Stat Code...
528 InitStatFlags
= Snp
->Cdb
.StatFlags
;
530 if (Snp
->Cdb
.StatCode
!= PXE_STATCODE_SUCCESS
) {
531 DEBUG ((EFI_D_NET
, "\nSnp->undi.init_info() %xh:%xh\n", Snp
->Cdb
.StatFlags
, Snp
->Cdb
.StatCode
));
533 goto Error_DeleteSNP
;
537 // Initialize simple network protocol mode structure
539 Snp
->Mode
.State
= EfiSimpleNetworkStopped
;
540 Snp
->Mode
.HwAddressSize
= Snp
->InitInfo
.HWaddrLen
;
541 Snp
->Mode
.MediaHeaderSize
= Snp
->InitInfo
.MediaHeaderLen
;
542 Snp
->Mode
.MaxPacketSize
= Snp
->InitInfo
.FrameDataLen
;
543 Snp
->Mode
.NvRamAccessSize
= Snp
->InitInfo
.NvWidth
;
544 Snp
->Mode
.NvRamSize
= Snp
->InitInfo
.NvCount
* Snp
->Mode
.NvRamAccessSize
;
545 Snp
->Mode
.IfType
= Snp
->InitInfo
.IFtype
;
546 Snp
->Mode
.MaxMCastFilterCount
= Snp
->InitInfo
.MCastFilterCnt
;
547 Snp
->Mode
.MCastFilterCount
= 0;
549 switch (InitStatFlags
& PXE_STATFLAGS_CABLE_DETECT_MASK
) {
550 case PXE_STATFLAGS_CABLE_DETECT_SUPPORTED
:
551 Snp
->CableDetectSupported
= TRUE
;
554 case PXE_STATFLAGS_CABLE_DETECT_NOT_SUPPORTED
:
556 Snp
->CableDetectSupported
= FALSE
;
559 switch (InitStatFlags
& PXE_STATFLAGS_GET_STATUS_NO_MEDIA_MASK
) {
560 case PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED
:
561 Snp
->MediaStatusSupported
= TRUE
;
564 case PXE_STATFLAGS_GET_STATUS_NO_MEDIA_NOT_SUPPORTED
:
566 Snp
->MediaStatusSupported
= FALSE
;
569 if (Snp
->CableDetectSupported
|| Snp
->MediaStatusSupported
) {
570 Snp
->Mode
.MediaPresentSupported
= TRUE
;
573 if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_STATION_ADDR_SETTABLE
) != 0) {
574 Snp
->Mode
.MacAddressChangeable
= TRUE
;
576 Snp
->Mode
.MacAddressChangeable
= FALSE
;
579 if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_MULTI_FRAME_SUPPORTED
) != 0) {
580 Snp
->Mode
.MultipleTxSupported
= TRUE
;
582 Snp
->Mode
.MultipleTxSupported
= FALSE
;
585 Snp
->Mode
.ReceiveFilterMask
= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
;
587 if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED
) != 0) {
588 Snp
->Mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
592 if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED
) != 0) {
593 Snp
->Mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
;
597 if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED
) != 0) {
598 Snp
->Mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
;
602 if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED
) != 0) {
603 Snp
->Mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
;
607 if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED
) != 0) {
608 Snp
->Mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
612 Snp
->Mode
.ReceiveFilterSetting
= 0;
615 // need to get the station address to save in the mode structure. we need to
616 // initialize the UNDI first for this.
618 Snp
->TxRxBufferSize
= Snp
->InitInfo
.MemoryRequired
;
619 Status
= PxeInit (Snp
, PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE
);
621 if (EFI_ERROR (Status
)) {
623 goto Error_DeleteSNP
;
626 Status
= PxeGetStnAddr (Snp
);
628 if (Status
!= EFI_SUCCESS
) {
629 DEBUG ((EFI_D_ERROR
, "\nSnp->undi.get_station_addr() failed.\n"));
632 goto Error_DeleteSNP
;
635 Snp
->Mode
.MediaPresent
= FALSE
;
638 // We should not leave UNDI started and initialized here. this DriverStart()
639 // routine must only find and attach the SNP interface to UNDI layer that it
640 // finds on the given handle!
641 // The UNDI layer will be started when upper layers call Snp->start.
642 // How ever, this DriverStart() must fill up the snp mode structure which
643 // contains the MAC address of the NIC. For this reason we started and
644 // initialized UNDI here, now we are done, do a shutdown and stop of the
650 if (PcdGetBool (PcdSnpCreateExitBootServicesEvent
)) {
652 // Create EXIT_BOOT_SERIVES Event
654 Status
= gBS
->CreateEventEx (
657 SnpNotifyExitBootServices
,
659 &gEfiEventExitBootServicesGuid
,
660 &Snp
->ExitBootServicesEvent
662 if (EFI_ERROR (Status
)) {
663 goto Error_DeleteSNP
;
668 // add SNP to the undi handle
670 Status
= gBS
->InstallProtocolInterface (
672 &gEfiSimpleNetworkProtocolGuid
,
673 EFI_NATIVE_INTERFACE
,
677 if (!EFI_ERROR (Status
)) {
683 SNP_MEM_PAGES (4096),
689 if (Snp
->RecycledTxBuf
!= NULL
) {
690 FreePool (Snp
->RecycledTxBuf
);
695 SNP_MEM_PAGES (sizeof (SNP_DRIVER
)),
701 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
702 This
->DriverBindingHandle
,
708 &gEfiDevicePathProtocolGuid
,
709 This
->DriverBindingHandle
,
714 // If we got here that means we are in error state.
716 if (!EFI_ERROR (Status
)) {
717 Status
= EFI_DEVICE_ERROR
;
724 Stop this driver on ControllerHandle. This service is called by the
725 EFI boot service DisconnectController(). In order to
726 make drivers as small as possible, there are a few calling
727 restrictions for this service. DisconnectController()
728 must follow these calling restrictions. If any other agent wishes
729 to call Stop() it must also follow these calling restrictions.
731 @param This Protocol instance pointer.
732 @param ControllerHandle Handle of device to stop driver on
733 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
734 children is zero stop the entire bus driver.
735 @param ChildHandleBuffer List of Child Handles to Stop.
737 @retval EFI_SUCCESS This driver is removed ControllerHandle
738 @retval other This driver was not removed from this device
743 SimpleNetworkDriverStop (
744 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
745 IN EFI_HANDLE Controller
,
746 IN UINTN NumberOfChildren
,
747 IN EFI_HANDLE
*ChildHandleBuffer
751 EFI_SIMPLE_NETWORK_PROTOCOL
*SnpProtocol
;
753 EFI_PCI_IO_PROTOCOL
*PciIo
;
756 // Get our context back.
758 Status
= gBS
->OpenProtocol (
760 &gEfiSimpleNetworkProtocolGuid
,
761 (VOID
**) &SnpProtocol
,
762 This
->DriverBindingHandle
,
764 EFI_OPEN_PROTOCOL_GET_PROTOCOL
767 if (EFI_ERROR (Status
)) {
768 return EFI_UNSUPPORTED
;
771 Snp
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (SnpProtocol
);
773 Status
= gBS
->UninstallProtocolInterface (
775 &gEfiSimpleNetworkProtocolGuid
,
779 if (EFI_ERROR (Status
)) {
783 if (PcdGetBool (PcdSnpCreateExitBootServicesEvent
)) {
785 // Close EXIT_BOOT_SERIVES Event
787 gBS
->CloseEvent (Snp
->ExitBootServicesEvent
);
790 Status
= gBS
->CloseProtocol (
792 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
793 This
->DriverBindingHandle
,
797 Status
= gBS
->CloseProtocol (
799 &gEfiDevicePathProtocolGuid
,
800 This
->DriverBindingHandle
,
807 FreePool (Snp
->RecycledTxBuf
);
812 SNP_MEM_PAGES (4096),
818 SNP_MEM_PAGES (sizeof (SNP_DRIVER
)),
826 // Simple Network Protocol Driver Global Variables
828 EFI_DRIVER_BINDING_PROTOCOL gSimpleNetworkDriverBinding
= {
829 SimpleNetworkDriverSupported
,
830 SimpleNetworkDriverStart
,
831 SimpleNetworkDriverStop
,
838 The SNP driver entry point.
840 @param ImageHandle The driver image handle.
841 @param SystemTable The system table.
843 @retval EFI_SUCEESS Initialization routine has found UNDI hardware,
844 loaded it's ROM, and installed a notify event for
845 the Network Indentifier Interface Protocol
847 @retval Other Return value from HandleProtocol for
848 DeviceIoProtocol or LoadedImageProtocol
853 InitializeSnpNiiDriver (
854 IN EFI_HANDLE ImageHandle
,
855 IN EFI_SYSTEM_TABLE
*SystemTable
858 return EfiLibInstallDriverBindingComponentName2 (
861 &gSimpleNetworkDriverBinding
,
863 &gSimpleNetworkComponentName
,
864 &gSimpleNetworkComponentName2