2 Implementation of driver entry point and driver binding protocol.
4 Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) Microsoft Corporation.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
13 One notified function to stop UNDI device when gBS->ExitBootServices() called.
15 @param Event Pointer to this event
16 @param Context Event handler private data
21 SnpNotifyExitBootServices (
28 Snp
= (SNP_DRIVER
*)Context
;
31 // Shutdown and stop UNDI driver
38 Send command to UNDI. It does nothing currently.
40 @param Cdb command to be sent to UNDI.
42 @retval EFI_INVALID_PARAMETER The command is 0.
43 @retval EFI_UNSUPPORTED Default return status because it's not
53 DEBUG ((DEBUG_ERROR
, "\nIssueHwUndiCommand() - This should not be called!"));
56 return EFI_INVALID_PARAMETER
;
60 // %%TBD - For now, nothing is done.
62 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 ((DEBUG_INFO
, "Support(): Already Started. on handle %p\n", Controller
));
157 DEBUG ((DEBUG_INFO
, "Support(): UNDI3.1 found on handle %p\n", Controller
));
160 // check the version, we don't want to connect to the undi16
162 if (NiiProtocol
->Type
!= EfiNetworkInterfaceUndi
) {
163 Status
= EFI_UNSUPPORTED
;
168 // Check to see if !PXE structure is valid. Paragraph alignment of !PXE structure is required.
170 if ((NiiProtocol
->Id
& 0x0F) != 0) {
171 DEBUG ((DEBUG_NET
, "\n!PXE structure is not paragraph aligned.\n"));
172 Status
= EFI_UNSUPPORTED
;
176 Pxe
= (PXE_UNDI
*)(UINTN
)(NiiProtocol
->Id
);
179 // Verify !PXE revisions.
181 if (Pxe
->hw
.Signature
!= PXE_ROMID_SIGNATURE
) {
182 DEBUG ((DEBUG_NET
, "\n!PXE signature is not valid.\n"));
183 Status
= EFI_UNSUPPORTED
;
187 if (Pxe
->hw
.Rev
< PXE_ROMID_REV
) {
188 DEBUG ((DEBUG_NET
, "\n!PXE.Rev is not supported.\n"));
189 Status
= EFI_UNSUPPORTED
;
193 if (Pxe
->hw
.MajorVer
< PXE_ROMID_MAJORVER
) {
194 DEBUG ((DEBUG_NET
, "\n!PXE.MajorVer is not supported.\n"));
195 Status
= EFI_UNSUPPORTED
;
197 } else if ((Pxe
->hw
.MajorVer
== PXE_ROMID_MAJORVER
) && (Pxe
->hw
.MinorVer
< PXE_ROMID_MINORVER
)) {
198 DEBUG ((DEBUG_NET
, "\n!PXE.MinorVer is not supported."));
199 Status
= EFI_UNSUPPORTED
;
204 // Do S/W UNDI specific checks.
206 if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_HW_UNDI
) == 0) {
207 if (Pxe
->sw
.EntryPoint
< Pxe
->sw
.Len
) {
208 DEBUG ((DEBUG_NET
, "\n!PXE S/W entry point is not valid."));
209 Status
= EFI_UNSUPPORTED
;
213 if (Pxe
->sw
.BusCnt
== 0) {
214 DEBUG ((DEBUG_NET
, "\n!PXE.BusCnt is zero."));
215 Status
= EFI_UNSUPPORTED
;
220 Status
= EFI_SUCCESS
;
221 DEBUG ((DEBUG_INFO
, "Support(): supported on %p\n", Controller
));
226 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
227 This
->DriverBindingHandle
,
235 Start this driver on ControllerHandle. This service is called by the
236 EFI boot service ConnectController(). In order to make
237 drivers as small as possible, there are a few calling restrictions for
238 this service. ConnectController() must follow these
239 calling restrictions. If any other agent wishes to call Start() it
240 must also follow these calling restrictions.
242 @param This Protocol instance pointer.
243 @param ControllerHandle Handle of device to bind driver to.
244 @param RemainingDevicePath Optional parameter use to pick a specific child
247 @retval EFI_SUCCESS This driver is added to ControllerHandle
248 @retval EFI_DEVICE_ERROR This driver could not be started due to a device error
249 @retval other This driver does not support this device
254 SimpleNetworkDriverStart (
255 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
256 IN EFI_HANDLE Controller
,
257 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
260 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
*Nii
;
261 EFI_DEVICE_PATH_PROTOCOL
*NiiDevicePath
;
268 PXE_STATFLAGS InitStatFlags
;
269 EFI_PCI_IO_PROTOCOL
*PciIo
;
270 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*BarDesc
;
272 BOOLEAN FoundMemoryBar
;
274 DEBUG ((DEBUG_NET
, "\nSnpNotifyNetworkInterfaceIdentifier() "));
276 Status
= gBS
->OpenProtocol (
278 &gEfiDevicePathProtocolGuid
,
279 (VOID
**)&NiiDevicePath
,
280 This
->DriverBindingHandle
,
282 EFI_OPEN_PROTOCOL_BY_DRIVER
285 if (EFI_ERROR (Status
)) {
289 Status
= gBS
->LocateDevicePath (
290 &gEfiPciIoProtocolGuid
,
295 if (EFI_ERROR (Status
)) {
299 Status
= gBS
->OpenProtocol (
301 &gEfiPciIoProtocolGuid
,
303 This
->DriverBindingHandle
,
305 EFI_OPEN_PROTOCOL_GET_PROTOCOL
307 if (EFI_ERROR (Status
)) {
312 // Get the NII interface.
314 Status
= gBS
->OpenProtocol (
316 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
318 This
->DriverBindingHandle
,
320 EFI_OPEN_PROTOCOL_BY_DRIVER
322 if (EFI_ERROR (Status
)) {
325 &gEfiDevicePathProtocolGuid
,
326 This
->DriverBindingHandle
,
332 DEBUG ((DEBUG_INFO
, "Start(): UNDI3.1 found\n"));
334 Pxe
= (PXE_UNDI
*)(UINTN
)(Nii
->Id
);
336 if (Calc8BitCksum (Pxe
, Pxe
->hw
.Len
) != 0) {
337 DEBUG ((DEBUG_NET
, "\n!PXE checksum is not correct.\n"));
341 if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED
) != 0) {
343 // We can get any packets.
345 } else if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED
) != 0) {
347 // We need to be able to get broadcast packets for DHCP.
348 // If we do not have promiscuous support, we must at least have
349 // broadcast support or we cannot do DHCP!
352 DEBUG ((DEBUG_NET
, "\nUNDI does not have promiscuous or broadcast support."));
357 // OK, we like this UNDI, and we know snp is not already there on this handle
358 // Allocate and initialize a new simple network protocol structure.
360 Status
= PciIo
->AllocateBuffer (
364 SNP_MEM_PAGES (sizeof (SNP_DRIVER
)),
369 if (Status
!= EFI_SUCCESS
) {
370 DEBUG ((DEBUG_NET
, "\nCould not allocate SNP_DRIVER structure.\n"));
374 Snp
= (SNP_DRIVER
*)(UINTN
)Address
;
376 ZeroMem (Snp
, sizeof (SNP_DRIVER
));
379 Snp
->Signature
= SNP_DRIVER_SIGNATURE
;
381 EfiInitializeLock (&Snp
->Lock
, TPL_NOTIFY
);
383 Snp
->Snp
.Revision
= EFI_SIMPLE_NETWORK_PROTOCOL_REVISION
;
384 Snp
->Snp
.Start
= SnpUndi32Start
;
385 Snp
->Snp
.Stop
= SnpUndi32Stop
;
386 Snp
->Snp
.Initialize
= SnpUndi32Initialize
;
387 Snp
->Snp
.Reset
= SnpUndi32Reset
;
388 Snp
->Snp
.Shutdown
= SnpUndi32Shutdown
;
389 Snp
->Snp
.ReceiveFilters
= SnpUndi32ReceiveFilters
;
390 Snp
->Snp
.StationAddress
= SnpUndi32StationAddress
;
391 Snp
->Snp
.Statistics
= SnpUndi32Statistics
;
392 Snp
->Snp
.MCastIpToMac
= SnpUndi32McastIpToMac
;
393 Snp
->Snp
.NvData
= SnpUndi32NvData
;
394 Snp
->Snp
.GetStatus
= SnpUndi32GetStatus
;
395 Snp
->Snp
.Transmit
= SnpUndi32Transmit
;
396 Snp
->Snp
.Receive
= SnpUndi32Receive
;
397 Snp
->Snp
.WaitForPacket
= NULL
;
399 Snp
->Snp
.Mode
= &Snp
->Mode
;
401 Snp
->TxRxBufferSize
= 0;
402 Snp
->TxRxBuffer
= NULL
;
404 Snp
->RecycledTxBuf
= AllocatePool (sizeof (UINT64
) * SNP_TX_BUFFER_INCREASEMENT
);
405 if (Snp
->RecycledTxBuf
== NULL
) {
406 Status
= EFI_OUT_OF_RESOURCES
;
407 goto Error_DeleteSNP
;
410 Snp
->MaxRecycledTxBuf
= SNP_TX_BUFFER_INCREASEMENT
;
411 Snp
->RecycledTxBufCount
= 0;
413 if (Nii
->Revision
>= EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION
) {
414 Snp
->IfNum
= Nii
->IfNum
;
416 Snp
->IfNum
= (UINT8
)(Nii
->IfNum
& 0xFF);
419 if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_HW_UNDI
) != 0) {
420 Snp
->IsSwUndi
= FALSE
;
421 Snp
->IssueUndi32Command
= &IssueHwUndiCommand
;
423 Snp
->IsSwUndi
= TRUE
;
425 if ((Pxe
->sw
.Implementation
& PXE_ROMID_IMP_SW_VIRT_ADDR
) != 0) {
426 Snp
->IssueUndi32Command
= (ISSUE_UNDI32_COMMAND
)(UINTN
)Pxe
->sw
.EntryPoint
;
428 Snp
->IssueUndi32Command
= (ISSUE_UNDI32_COMMAND
)(UINTN
)((UINT8
)(UINTN
)Pxe
+ Pxe
->sw
.EntryPoint
);
433 // Allocate a global CPB and DB buffer for this UNDI interface.
434 // we do this because:
436 // -UNDI 3.0 wants all the addresses passed to it (even the cpb and db) to be
437 // within 2GB limit, create them here and map them so that when undi calls
438 // v2p callback to check if the physical address is < 2gb, we will pass.
440 // -This is not a requirement for 3.1 or later UNDIs but the code looks
441 // simpler if we use the same cpb, db variables for both old and new undi
442 // interfaces from all the SNP interface calls (we don't map the buffers
443 // for the newer undi interfaces though)
445 // -it is OK to allocate one global set of CPB, DB pair for each UNDI
446 // interface as EFI does not multi-task and so SNP will not be re-entered!
448 Status
= PciIo
->AllocateBuffer (
452 SNP_MEM_PAGES (4096),
457 if (Status
!= EFI_SUCCESS
) {
458 DEBUG ((DEBUG_NET
, "\nCould not allocate CPB and DB structures.\n"));
459 goto Error_DeleteSNP
;
462 Snp
->Cpb
= (VOID
*)(UINTN
)Address
;
463 Snp
->Db
= (VOID
*)((UINTN
)Address
+ 2048);
466 // Find the correct BAR to do IO.
468 // Enumerate through the PCI BARs for the device to determine which one is
469 // the IO BAR. Save the index of the BAR into the adapter info structure.
470 // for regular 32bit BARs, 0 is memory mapped, 1 is io mapped
472 Snp
->MemoryBarIndex
= PCI_MAX_BAR
;
473 Snp
->IoBarIndex
= PCI_MAX_BAR
;
474 FoundMemoryBar
= FALSE
;
476 for (BarIndex
= 0; BarIndex
< PCI_MAX_BAR
; BarIndex
++) {
477 Status
= PciIo
->GetBarAttributes (
483 if (Status
== EFI_UNSUPPORTED
) {
485 } else if (EFI_ERROR (Status
)) {
486 goto Error_DeleteSNP
;
489 if ((!FoundMemoryBar
) && (BarDesc
->ResType
== ACPI_ADDRESS_SPACE_TYPE_MEM
)) {
490 Snp
->MemoryBarIndex
= BarIndex
;
491 FoundMemoryBar
= TRUE
;
492 } else if ((!FoundIoBar
) && (BarDesc
->ResType
== ACPI_ADDRESS_SPACE_TYPE_IO
)) {
493 Snp
->IoBarIndex
= BarIndex
;
499 if (FoundMemoryBar
&& FoundIoBar
) {
504 Status
= PxeStart (Snp
);
506 if (Status
!= EFI_SUCCESS
) {
507 goto Error_DeleteSNP
;
510 Snp
->Cdb
.OpCode
= PXE_OPCODE_GET_INIT_INFO
;
511 Snp
->Cdb
.OpFlags
= PXE_OPFLAGS_NOT_USED
;
513 Snp
->Cdb
.CPBsize
= PXE_CPBSIZE_NOT_USED
;
514 Snp
->Cdb
.CPBaddr
= PXE_DBADDR_NOT_USED
;
516 Snp
->Cdb
.DBsize
= (UINT16
)sizeof (Snp
->InitInfo
);
517 Snp
->Cdb
.DBaddr
= (UINT64
)(UINTN
)(&Snp
->InitInfo
);
519 Snp
->Cdb
.StatCode
= PXE_STATCODE_INITIALIZE
;
520 Snp
->Cdb
.StatFlags
= PXE_STATFLAGS_INITIALIZE
;
522 Snp
->Cdb
.IFnum
= Snp
->IfNum
;
523 Snp
->Cdb
.Control
= PXE_CONTROL_LAST_CDB_IN_LIST
;
525 DEBUG ((DEBUG_NET
, "\nSnp->undi.get_init_info() "));
527 (*Snp
->IssueUndi32Command
)((UINT64
)(UINTN
)&Snp
->Cdb
);
530 // Save the INIT Stat Code...
532 InitStatFlags
= Snp
->Cdb
.StatFlags
;
534 if (Snp
->Cdb
.StatCode
!= PXE_STATCODE_SUCCESS
) {
535 DEBUG ((DEBUG_NET
, "\nSnp->undi.init_info() %xh:%xh\n", Snp
->Cdb
.StatFlags
, Snp
->Cdb
.StatCode
));
537 goto Error_DeleteSNP
;
541 // Initialize simple network protocol mode structure
543 Snp
->Mode
.State
= EfiSimpleNetworkStopped
;
544 Snp
->Mode
.HwAddressSize
= Snp
->InitInfo
.HWaddrLen
;
545 Snp
->Mode
.MediaHeaderSize
= Snp
->InitInfo
.MediaHeaderLen
;
546 Snp
->Mode
.MaxPacketSize
= Snp
->InitInfo
.FrameDataLen
;
547 Snp
->Mode
.NvRamAccessSize
= Snp
->InitInfo
.NvWidth
;
548 Snp
->Mode
.NvRamSize
= Snp
->InitInfo
.NvCount
* Snp
->Mode
.NvRamAccessSize
;
549 Snp
->Mode
.IfType
= Snp
->InitInfo
.IFtype
;
550 Snp
->Mode
.MaxMCastFilterCount
= Snp
->InitInfo
.MCastFilterCnt
;
551 Snp
->Mode
.MCastFilterCount
= 0;
553 switch (InitStatFlags
& PXE_STATFLAGS_CABLE_DETECT_MASK
) {
554 case PXE_STATFLAGS_CABLE_DETECT_SUPPORTED
:
555 Snp
->CableDetectSupported
= TRUE
;
558 case PXE_STATFLAGS_CABLE_DETECT_NOT_SUPPORTED
:
560 Snp
->CableDetectSupported
= FALSE
;
563 switch (InitStatFlags
& PXE_STATFLAGS_GET_STATUS_NO_MEDIA_MASK
) {
564 case PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED
:
565 Snp
->MediaStatusSupported
= TRUE
;
568 case PXE_STATFLAGS_GET_STATUS_NO_MEDIA_NOT_SUPPORTED
:
570 Snp
->MediaStatusSupported
= FALSE
;
573 if (Snp
->CableDetectSupported
|| Snp
->MediaStatusSupported
) {
574 Snp
->Mode
.MediaPresentSupported
= TRUE
;
577 if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_STATION_ADDR_SETTABLE
) != 0) {
578 Snp
->Mode
.MacAddressChangeable
= TRUE
;
580 Snp
->Mode
.MacAddressChangeable
= FALSE
;
583 if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_MULTI_FRAME_SUPPORTED
) != 0) {
584 Snp
->Mode
.MultipleTxSupported
= TRUE
;
586 Snp
->Mode
.MultipleTxSupported
= FALSE
;
589 Snp
->Mode
.ReceiveFilterMask
= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
;
591 if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED
) != 0) {
592 Snp
->Mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
595 if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED
) != 0) {
596 Snp
->Mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
;
599 if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED
) != 0) {
600 Snp
->Mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
;
603 if ((Pxe
->hw
.Implementation
& PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED
) != 0) {
604 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
;
611 Snp
->Mode
.ReceiveFilterSetting
= 0;
614 // need to get the station address to save in the mode structure. we need to
615 // initialize the UNDI first for this.
617 Snp
->TxRxBufferSize
= Snp
->InitInfo
.MemoryRequired
;
618 Status
= PxeInit (Snp
, PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE
);
620 if (EFI_ERROR (Status
)) {
622 goto Error_DeleteSNP
;
625 Status
= PxeGetStnAddr (Snp
);
627 if (Status
!= EFI_SUCCESS
) {
628 DEBUG ((DEBUG_ERROR
, "\nSnp->undi.get_station_addr() failed.\n"));
631 goto Error_DeleteSNP
;
634 Snp
->Mode
.MediaPresent
= FALSE
;
637 // We should not leave UNDI started and initialized here. this DriverStart()
638 // routine must only find and attach the SNP interface to UNDI layer that it
639 // finds on the given handle!
640 // The UNDI layer will be started when upper layers call Snp->start.
641 // How ever, this DriverStart() must fill up the snp mode structure which
642 // contains the MAC address of the NIC. For this reason we started and
643 // initialized UNDI here, now we are done, do a shutdown and stop of the
649 if (PcdGetBool (PcdSnpCreateExitBootServicesEvent
)) {
651 // Create EXIT_BOOT_SERIVES Event
653 Status
= gBS
->CreateEventEx (
656 SnpNotifyExitBootServices
,
658 &gEfiEventExitBootServicesGuid
,
659 &Snp
->ExitBootServicesEvent
661 if (EFI_ERROR (Status
)) {
662 goto Error_DeleteSNP
;
667 // add SNP to the undi handle
669 Status
= gBS
->InstallProtocolInterface (
671 &gEfiSimpleNetworkProtocolGuid
,
672 EFI_NATIVE_INTERFACE
,
676 if (!EFI_ERROR (Status
)) {
682 SNP_MEM_PAGES (4096),
688 if (Snp
->RecycledTxBuf
!= NULL
) {
689 FreePool (Snp
->RecycledTxBuf
);
694 SNP_MEM_PAGES (sizeof (SNP_DRIVER
)),
700 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
701 This
->DriverBindingHandle
,
707 &gEfiDevicePathProtocolGuid
,
708 This
->DriverBindingHandle
,
713 // If we got here that means we are in error state.
715 if (!EFI_ERROR (Status
)) {
716 Status
= EFI_DEVICE_ERROR
;
723 Stop this driver on ControllerHandle. This service is called by the
724 EFI boot service DisconnectController(). In order to
725 make drivers as small as possible, there are a few calling
726 restrictions for this service. DisconnectController()
727 must follow these calling restrictions. If any other agent wishes
728 to call Stop() it must also follow these calling restrictions.
730 @param This Protocol instance pointer.
731 @param ControllerHandle Handle of device to stop driver on
732 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
733 children is zero stop the entire bus driver.
734 @param ChildHandleBuffer List of Child Handles to Stop.
736 @retval EFI_SUCCESS This driver is removed ControllerHandle
737 @retval other This driver was not removed from this device
742 SimpleNetworkDriverStop (
743 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
744 IN EFI_HANDLE Controller
,
745 IN UINTN NumberOfChildren
,
746 IN EFI_HANDLE
*ChildHandleBuffer
750 EFI_SIMPLE_NETWORK_PROTOCOL
*SnpProtocol
;
752 EFI_PCI_IO_PROTOCOL
*PciIo
;
755 // Get our context back.
757 Status
= gBS
->OpenProtocol (
759 &gEfiSimpleNetworkProtocolGuid
,
760 (VOID
**)&SnpProtocol
,
761 This
->DriverBindingHandle
,
763 EFI_OPEN_PROTOCOL_GET_PROTOCOL
766 if (EFI_ERROR (Status
)) {
767 return EFI_UNSUPPORTED
;
770 Snp
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (SnpProtocol
);
772 Status
= gBS
->UninstallProtocolInterface (
774 &gEfiSimpleNetworkProtocolGuid
,
778 if (EFI_ERROR (Status
)) {
782 if (PcdGetBool (PcdSnpCreateExitBootServicesEvent
)) {
784 // Close EXIT_BOOT_SERVICES Event
786 gBS
->CloseEvent (Snp
->ExitBootServicesEvent
);
789 Status
= gBS
->CloseProtocol (
791 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
792 This
->DriverBindingHandle
,
796 Status
= gBS
->CloseProtocol (
798 &gEfiDevicePathProtocolGuid
,
799 This
->DriverBindingHandle
,
806 FreePool (Snp
->RecycledTxBuf
);
811 SNP_MEM_PAGES (4096),
817 SNP_MEM_PAGES (sizeof (SNP_DRIVER
)),
825 // Simple Network Protocol Driver Global Variables
827 EFI_DRIVER_BINDING_PROTOCOL gSimpleNetworkDriverBinding
= {
828 SimpleNetworkDriverSupported
,
829 SimpleNetworkDriverStart
,
830 SimpleNetworkDriverStop
,
837 The SNP driver entry point.
839 @param ImageHandle The driver image handle.
840 @param SystemTable The system table.
842 @retval EFI_SUCCESS Initialization routine has found UNDI hardware,
843 loaded it's ROM, and installed a notify event for
844 the Network Identifier Interface Protocol
846 @retval Other Return value from HandleProtocol for
847 DeviceIoProtocol or LoadedImageProtocol
852 InitializeSnpNiiDriver (
853 IN EFI_HANDLE ImageHandle
,
854 IN EFI_SYSTEM_TABLE
*SystemTable
857 return EfiLibInstallDriverBindingComponentName2 (
860 &gSimpleNetworkDriverBinding
,
862 &gSimpleNetworkComponentName
,
863 &gSimpleNetworkComponentName2