2 The driver binding and service binding protocol for the TCP driver.
4 Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The 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.
18 UINT16 mTcp4RandomPort
;
19 UINT16 mTcp6RandomPort
;
21 TCP_HEARTBEAT_TIMER mTcpTimer
= {
26 EFI_TCP4_PROTOCOL gTcp4ProtocolTemplate
= {
39 EFI_TCP6_PROTOCOL gTcp6ProtocolTemplate
= {
51 SOCK_INIT_DATA mTcpDefaultSockData
= {
60 TcpCreateSocketCallback
,
61 TcpDestroySocketCallback
,
69 EFI_DRIVER_BINDING_PROTOCOL gTcpDriverBinding
= {
70 TcpDriverBindingSupported
,
71 TcpDriverBindingStart
,
78 EFI_SERVICE_BINDING_PROTOCOL gTcpServiceBinding
= {
79 TcpServiceBindingCreateChild
,
80 TcpServiceBindingDestroyChild
85 Create and start the heartbeat timer for the TCP driver.
87 @retval EFI_SUCCESS The timer was successfully created and started.
88 @retval other The timer was not created.
100 if (mTcpTimer
.RefCnt
== 0) {
102 Status
= gBS
->CreateEvent (
103 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
107 &mTcpTimer
.TimerEvent
109 if (!EFI_ERROR (Status
)) {
111 Status
= gBS
->SetTimer (
112 mTcpTimer
.TimerEvent
,
114 (UINT64
) (TICKS_PER_SECOND
/ TCP_TICK_HZ
)
119 if (!EFI_ERROR (Status
)) {
128 Stop and destroy the heartbeat timer for TCP driver.
136 ASSERT (mTcpTimer
.RefCnt
> 0);
140 if (mTcpTimer
.RefCnt
> 0) {
144 gBS
->SetTimer (mTcpTimer
.TimerEvent
, TimerCancel
, 0);
145 gBS
->CloseEvent (mTcpTimer
.TimerEvent
);
146 mTcpTimer
.TimerEvent
= NULL
;
150 The entry point for Tcp driver, which is used to install Tcp driver on the ImageHandle.
152 @param[in] ImageHandle The firmware allocated handle for this driver image.
153 @param[in] SystemTable Pointer to the EFI system table.
155 @retval EFI_SUCCESS The driver loaded.
156 @retval other The driver did not load.
161 TcpDriverEntryPoint (
162 IN EFI_HANDLE ImageHandle
,
163 IN EFI_SYSTEM_TABLE
*SystemTable
170 // Install the TCP Driver Binding Protocol
172 Status
= EfiLibInstallDriverBindingComponentName2 (
180 if (EFI_ERROR (Status
)) {
185 // Initialize ISS and random port.
187 Seed
= NetRandomInitSeed ();
188 mTcpGlobalIss
= NET_RANDOM (Seed
) % mTcpGlobalIss
;
189 mTcp4RandomPort
= (UINT16
) (TCP_PORT_KNOWN
+ (NET_RANDOM (Seed
) % TCP_PORT_KNOWN
));
190 mTcp6RandomPort
= mTcp4RandomPort
;
196 Create a new TCP4 or TCP6 driver service binding protocol
198 @param[in] Controller Controller handle of device to bind driver to.
199 @param[in] Image The TCP driver's image handle.
200 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
202 @retval EFI_OUT_OF_RESOURCES Failed to allocate some resources.
203 @retval EFI_SUCCESS A new IP6 service binding private was created.
208 IN EFI_HANDLE Controller
,
214 EFI_GUID
*IpServiceBindingGuid
;
215 EFI_GUID
*TcpServiceBindingGuid
;
216 TCP_SERVICE_DATA
*TcpServiceData
;
217 IP_IO_OPEN_DATA OpenData
;
219 if (IpVersion
== IP_VERSION_4
) {
220 IpServiceBindingGuid
= &gEfiIp4ServiceBindingProtocolGuid
;
221 TcpServiceBindingGuid
= &gEfiTcp4ServiceBindingProtocolGuid
;
223 IpServiceBindingGuid
= &gEfiIp6ServiceBindingProtocolGuid
;
224 TcpServiceBindingGuid
= &gEfiTcp6ServiceBindingProtocolGuid
;
227 Status
= gBS
->OpenProtocol (
229 TcpServiceBindingGuid
,
233 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
235 if (!EFI_ERROR (Status
)) {
236 return EFI_ALREADY_STARTED
;
239 Status
= gBS
->OpenProtocol (
241 IpServiceBindingGuid
,
245 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
247 if (EFI_ERROR (Status
)) {
248 return EFI_UNSUPPORTED
;
252 // Create the TCP service data.
254 TcpServiceData
= AllocateZeroPool (sizeof (TCP_SERVICE_DATA
));
255 if (TcpServiceData
== NULL
) {
256 return EFI_OUT_OF_RESOURCES
;
259 TcpServiceData
->Signature
= TCP_DRIVER_SIGNATURE
;
260 TcpServiceData
->ControllerHandle
= Controller
;
261 TcpServiceData
->DriverBindingHandle
= Image
;
262 TcpServiceData
->IpVersion
= IpVersion
;
264 &TcpServiceData
->ServiceBinding
,
266 sizeof (EFI_SERVICE_BINDING_PROTOCOL
)
269 TcpServiceData
->IpIo
= IpIoCreate (Image
, Controller
, IpVersion
);
270 if (TcpServiceData
->IpIo
== NULL
) {
271 Status
= EFI_OUT_OF_RESOURCES
;
276 InitializeListHead (&TcpServiceData
->SocketList
);
277 ZeroMem (&OpenData
, sizeof (IP_IO_OPEN_DATA
));
279 if (IpVersion
== IP_VERSION_4
) {
281 &OpenData
.IpConfigData
.Ip4CfgData
,
282 &mIp4IoDefaultIpConfigData
,
283 sizeof (EFI_IP4_CONFIG_DATA
)
285 OpenData
.IpConfigData
.Ip4CfgData
.DefaultProtocol
= EFI_IP_PROTO_TCP
;
288 &OpenData
.IpConfigData
.Ip6CfgData
,
289 &mIp6IoDefaultIpConfigData
,
290 sizeof (EFI_IP6_CONFIG_DATA
)
292 OpenData
.IpConfigData
.Ip6CfgData
.DefaultProtocol
= EFI_IP_PROTO_TCP
;
295 OpenData
.PktRcvdNotify
= TcpRxCallback
;
296 Status
= IpIoOpen (TcpServiceData
->IpIo
, &OpenData
);
297 if (EFI_ERROR (Status
)) {
301 Status
= TcpCreateTimer ();
302 if (EFI_ERROR (Status
)) {
306 Status
= gBS
->InstallMultipleProtocolInterfaces (
308 TcpServiceBindingGuid
,
309 &TcpServiceData
->ServiceBinding
,
312 if (EFI_ERROR (Status
)) {
318 TcpSetVariableData (TcpServiceData
);
324 if (TcpServiceData
->IpIo
!= NULL
) {
325 IpIoDestroy (TcpServiceData
->IpIo
);
326 TcpServiceData
->IpIo
= NULL
;
329 FreePool (TcpServiceData
);
335 Callback function which provided by user to remove one node in NetDestroyLinkList process.
337 @param[in] Entry The entry to be removed.
338 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
340 @retval EFI_SUCCESS The entry has been removed successfully.
341 @retval Others Fail to remove the entry.
345 TcpDestroyChildEntryInHandleBuffer (
346 IN LIST_ENTRY
*Entry
,
351 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
352 UINTN NumberOfChildren
;
353 EFI_HANDLE
*ChildHandleBuffer
;
355 if (Entry
== NULL
|| Context
== NULL
) {
356 return EFI_INVALID_PARAMETER
;
359 Sock
= NET_LIST_USER_STRUCT_S (Entry
, SOCKET
, Link
, SOCK_SIGNATURE
);
360 ServiceBinding
= ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->ServiceBinding
;
361 NumberOfChildren
= ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->NumberOfChildren
;
362 ChildHandleBuffer
= ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->ChildHandleBuffer
;
364 if (!NetIsInHandleBuffer (Sock
->SockHandle
, NumberOfChildren
, ChildHandleBuffer
)) {
368 return ServiceBinding
->DestroyChild (ServiceBinding
, Sock
->SockHandle
);
372 Destroy a TCP6 or TCP4 service binding instance. It will release all
373 the resources allocated by the instance.
375 @param[in] Controller Controller handle of device to bind driver to.
376 @param[in] ImageHandle The TCP driver's image handle.
377 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number
378 of children is zero stop the entire bus driver.
379 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
380 if NumberOfChildren is 0.
381 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6
383 @retval EFI_SUCCESS The resources used by the instance were cleaned up.
384 @retval Others Failed to clean up some of the resources.
389 IN EFI_HANDLE Controller
,
390 IN EFI_HANDLE ImageHandle
,
391 IN UINTN NumberOfChildren
,
392 IN EFI_HANDLE
*ChildHandleBuffer
, OPTIONAL
396 EFI_HANDLE NicHandle
;
397 EFI_GUID
*IpProtocolGuid
;
398 EFI_GUID
*ServiceBindingGuid
;
399 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
400 TCP_SERVICE_DATA
*TcpServiceData
;
403 TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context
;
405 ASSERT ((IpVersion
== IP_VERSION_4
) || (IpVersion
== IP_VERSION_6
));
407 if (IpVersion
== IP_VERSION_4
) {
408 IpProtocolGuid
= &gEfiIp4ProtocolGuid
;
409 ServiceBindingGuid
= &gEfiTcp4ServiceBindingProtocolGuid
;
411 IpProtocolGuid
= &gEfiIp6ProtocolGuid
;
412 ServiceBindingGuid
= &gEfiTcp6ServiceBindingProtocolGuid
;
415 NicHandle
= NetLibGetNicHandle (Controller
, IpProtocolGuid
);
416 if (NicHandle
== NULL
) {
420 Status
= gBS
->OpenProtocol (
423 (VOID
**) &ServiceBinding
,
426 EFI_OPEN_PROTOCOL_GET_PROTOCOL
428 if (EFI_ERROR (Status
)) {
429 return EFI_DEVICE_ERROR
;
432 TcpServiceData
= TCP_SERVICE_FROM_THIS (ServiceBinding
);
434 if (NumberOfChildren
!= 0) {
435 List
= &TcpServiceData
->SocketList
;
436 Context
.ServiceBinding
= ServiceBinding
;
437 Context
.NumberOfChildren
= NumberOfChildren
;
438 Context
.ChildHandleBuffer
= ChildHandleBuffer
;
439 Status
= NetDestroyLinkList (
441 TcpDestroyChildEntryInHandleBuffer
,
445 } else if (IsListEmpty (&TcpServiceData
->SocketList
)) {
447 // Uninstall TCP servicebinding protocol
449 gBS
->UninstallMultipleProtocolInterfaces (
457 // Destroy the IpIO consumed by TCP driver
459 IpIoDestroy (TcpServiceData
->IpIo
);
460 TcpServiceData
->IpIo
= NULL
;
463 // Destroy the heartbeat timer.
468 // Clear the variable.
470 TcpClearVariableData (TcpServiceData
);
473 // Release the TCP service data
475 FreePool (TcpServiceData
);
477 Status
= EFI_SUCCESS
;
484 Test to see if this driver supports ControllerHandle.
486 @param[in] This Protocol instance pointer.
487 @param[in] ControllerHandle Handle of device to test.
488 @param[in] RemainingDevicePath Optional parameter use to pick a specific
489 child device to start.
491 @retval EFI_SUCCESS This driver supports this device.
492 @retval EFI_ALREADY_STARTED This driver is already running on this device.
493 @retval other This driver does not support this device.
498 TcpDriverBindingSupported (
499 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
500 IN EFI_HANDLE ControllerHandle
,
501 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
505 BOOLEAN IsTcp4Started
;
508 // Test for the Tcp4ServiceBinding Protocol
510 Status
= gBS
->OpenProtocol (
512 &gEfiTcp4ServiceBindingProtocolGuid
,
514 This
->DriverBindingHandle
,
516 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
518 if (EFI_ERROR (Status
)) {
520 // Test for the Ip4ServiceBinding Protocol
522 Status
= gBS
->OpenProtocol (
524 &gEfiIp4ServiceBindingProtocolGuid
,
526 This
->DriverBindingHandle
,
528 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
530 if (!EFI_ERROR (Status
)) {
534 IsTcp4Started
= FALSE
;
536 IsTcp4Started
= TRUE
;
540 // Check the Tcp6ServiceBinding Protocol
542 Status
= gBS
->OpenProtocol (
544 &gEfiTcp6ServiceBindingProtocolGuid
,
546 This
->DriverBindingHandle
,
548 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
550 if (EFI_ERROR (Status
)) {
552 // Test for the Ip6ServiceBinding Protocol
554 Status
= gBS
->OpenProtocol (
556 &gEfiIp6ServiceBindingProtocolGuid
,
558 This
->DriverBindingHandle
,
560 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
562 if (!EFI_ERROR (Status
)) {
565 } else if (IsTcp4Started
) {
566 return EFI_ALREADY_STARTED
;
569 return EFI_UNSUPPORTED
;
573 Start this driver on ControllerHandle.
575 @param[in] This Protocol instance pointer.
576 @param[in] ControllerHandle Handle of device to bind driver to.
577 @param[in] RemainingDevicePath Optional parameter use to pick a specific child
580 @retval EFI_SUCCESS The driver is added to ControllerHandle.
581 @retval EFI_OUT_OF_RESOURCES There are not enough resources to start the
583 @retval other The driver cannot be added to ControllerHandle.
588 TcpDriverBindingStart (
589 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
590 IN EFI_HANDLE ControllerHandle
,
591 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
594 EFI_STATUS Tcp4Status
;
595 EFI_STATUS Tcp6Status
;
597 Tcp4Status
= TcpCreateService (ControllerHandle
, This
->DriverBindingHandle
, IP_VERSION_4
);
598 if ((Tcp4Status
== EFI_ALREADY_STARTED
) || (Tcp4Status
== EFI_UNSUPPORTED
)) {
599 Tcp4Status
= EFI_SUCCESS
;
602 Tcp6Status
= TcpCreateService (ControllerHandle
, This
->DriverBindingHandle
, IP_VERSION_6
);
603 if ((Tcp6Status
== EFI_ALREADY_STARTED
) || (Tcp6Status
== EFI_UNSUPPORTED
)) {
604 Tcp6Status
= EFI_SUCCESS
;
607 if (!EFI_ERROR (Tcp4Status
) || !EFI_ERROR (Tcp6Status
)) {
609 } else if (EFI_ERROR (Tcp4Status
)) {
617 Stop this driver on ControllerHandle.
619 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
620 @param[in] ControllerHandle A handle to the device being stopped. The handle must
621 support a bus specific I/O protocol for the driver
622 to use to stop the device.
623 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
624 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
625 if NumberOfChildren is 0.
627 @retval EFI_SUCCESS The device was stopped.
628 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
633 TcpDriverBindingStop (
634 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
635 IN EFI_HANDLE ControllerHandle
,
636 IN UINTN NumberOfChildren
,
637 IN EFI_HANDLE
*ChildHandleBuffer OPTIONAL
640 EFI_STATUS Tcp4Status
;
641 EFI_STATUS Tcp6Status
;
643 Tcp4Status
= TcpDestroyService (
645 This
->DriverBindingHandle
,
651 Tcp6Status
= TcpDestroyService (
653 This
->DriverBindingHandle
,
659 if (EFI_ERROR (Tcp4Status
) && EFI_ERROR (Tcp6Status
)) {
660 return EFI_DEVICE_ERROR
;
667 The Callback funtion called after the TCP socket was created.
669 @param[in] This Pointer to the socket just created
670 @param[in] Context Context of the socket
672 @retval EFI_SUCCESS This protocol installed successfully.
673 @retval other An error occured.
677 TcpCreateSocketCallback (
683 TCP_SERVICE_DATA
*TcpServiceData
;
684 EFI_GUID
*IpProtocolGuid
;
687 if (This
->IpVersion
== IP_VERSION_4
) {
688 IpProtocolGuid
= &gEfiIp4ProtocolGuid
;
690 IpProtocolGuid
= &gEfiIp6ProtocolGuid
;
693 TcpServiceData
= ((TCP_PROTO_DATA
*) This
->ProtoReserved
)->TcpService
;
696 // Open the default IP protocol of IP_IO BY_DRIVER.
698 Status
= gBS
->OpenProtocol (
699 TcpServiceData
->IpIo
->ChildHandle
,
702 TcpServiceData
->DriverBindingHandle
,
704 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
706 if (EFI_ERROR (Status
)) {
711 // Open the device path on the handle where service binding resides on.
713 Status
= gBS
->OpenProtocol (
714 TcpServiceData
->ControllerHandle
,
715 &gEfiDevicePathProtocolGuid
,
716 (VOID
**) &This
->ParentDevicePath
,
717 TcpServiceData
->DriverBindingHandle
,
719 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
721 if (EFI_ERROR (Status
)) {
723 TcpServiceData
->IpIo
->ChildHandle
,
725 TcpServiceData
->DriverBindingHandle
,
730 // Insert this socket into the SocketList.
732 InsertTailList (&TcpServiceData
->SocketList
, &This
->Link
);
739 The callback function called before the TCP socket was to be destroyed.
741 @param[in] This The TCP socket to be destroyed.
742 @param[in] Context The context of the socket.
746 TcpDestroySocketCallback (
751 TCP_SERVICE_DATA
*TcpServiceData
;
752 EFI_GUID
*IpProtocolGuid
;
754 if (This
->IpVersion
== IP_VERSION_4
) {
755 IpProtocolGuid
= &gEfiIp4ProtocolGuid
;
757 IpProtocolGuid
= &gEfiIp6ProtocolGuid
;
760 TcpServiceData
= ((TCP_PROTO_DATA
*) This
->ProtoReserved
)->TcpService
;
763 // Remove this node from the list.
765 RemoveEntryList (&This
->Link
);
768 // Close the device path protocol
771 TcpServiceData
->ControllerHandle
,
772 &gEfiDevicePathProtocolGuid
,
773 TcpServiceData
->DriverBindingHandle
,
778 // Close the IP protocol.
781 TcpServiceData
->IpIo
->ChildHandle
,
783 TcpServiceData
->DriverBindingHandle
,
789 Creates a child handle with a set of TCP services.
791 The CreateChild() function installs a protocol on ChildHandle.
792 If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
793 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
795 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
796 @param[in, out] ChildHandle Pointer to the handle of the child to create.
797 If it is NULL, then a new handle is created.
798 If it is a pointer to an existing UEFI handle,
799 then the protocol is added to the existing UEFI handle.
801 @retval EFI_SUCCES The protocol was added to ChildHandle.
802 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
803 @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create
805 @retval other The child handle was not created.
810 TcpServiceBindingCreateChild (
811 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
812 IN OUT EFI_HANDLE
*ChildHandle
816 TCP_SERVICE_DATA
*TcpServiceData
;
817 TCP_PROTO_DATA TcpProto
;
821 if (NULL
== This
|| NULL
== ChildHandle
) {
822 return EFI_INVALID_PARAMETER
;
825 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
827 Status
= EFI_SUCCESS
;
828 TcpServiceData
= TCP_SERVICE_FROM_THIS (This
);
829 TcpProto
.TcpService
= TcpServiceData
;
830 TcpProto
.TcpPcb
= NULL
;
833 // Create a tcp instance with defualt Tcp default
834 // sock init data and TcpProto
836 mTcpDefaultSockData
.ProtoData
= &TcpProto
;
837 mTcpDefaultSockData
.DataSize
= sizeof (TCP_PROTO_DATA
);
838 mTcpDefaultSockData
.DriverBinding
= TcpServiceData
->DriverBindingHandle
;
839 mTcpDefaultSockData
.IpVersion
= TcpServiceData
->IpVersion
;
841 if (TcpServiceData
->IpVersion
== IP_VERSION_4
) {
842 mTcpDefaultSockData
.Protocol
= &gTcp4ProtocolTemplate
;
844 mTcpDefaultSockData
.Protocol
= &gTcp6ProtocolTemplate
;
847 Sock
= SockCreateChild (&mTcpDefaultSockData
);
851 "TcpDriverBindingCreateChild: No resource to create a Tcp Child\n")
854 Status
= EFI_OUT_OF_RESOURCES
;
856 *ChildHandle
= Sock
->SockHandle
;
859 mTcpDefaultSockData
.ProtoData
= NULL
;
861 gBS
->RestoreTPL (OldTpl
);
866 Destroys a child handle with a set of TCP services.
868 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
869 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
870 last protocol on ChildHandle, then ChildHandle is destroyed.
872 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
873 @param ChildHandle Handle of the child to be destroyed.
875 @retval EFI_SUCCES The protocol was removed from ChildHandle.
876 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
877 @retval EFI_INVALID_PARAMETER Child handle is NULL.
878 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
879 because its services are being used.
880 @retval other The child handle was not destroyed.
885 TcpServiceBindingDestroyChild (
886 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
887 IN EFI_HANDLE ChildHandle
894 if (NULL
== This
|| NULL
== ChildHandle
) {
895 return EFI_INVALID_PARAMETER
;
899 // retrieve the Tcp4 protocol from ChildHandle
901 Status
= gBS
->OpenProtocol (
903 &gEfiTcp4ProtocolGuid
,
905 gTcpDriverBinding
.DriverBindingHandle
,
907 EFI_OPEN_PROTOCOL_GET_PROTOCOL
909 if (EFI_ERROR (Status
)) {
911 // No Tcp4, try the Tcp6 protocol
913 Status
= gBS
->OpenProtocol (
915 &gEfiTcp6ProtocolGuid
,
917 gTcpDriverBinding
.DriverBindingHandle
,
919 EFI_OPEN_PROTOCOL_GET_PROTOCOL
921 if (EFI_ERROR (Status
)) {
922 Status
= EFI_UNSUPPORTED
;
926 if (!EFI_ERROR (Status
)) {
928 // destroy this sock and related Tcp protocol control
931 Sock
= SOCK_FROM_THIS (Tcp
);
933 SockDestroyChild (Sock
);