2 The driver binding and service binding protocol for the TCP driver.
4 Copyright (c) 2009 - 2013, 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.
346 TcpDestroyChildEntryInHandleBuffer (
347 IN LIST_ENTRY
*Entry
,
352 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
353 UINTN NumberOfChildren
;
354 EFI_HANDLE
*ChildHandleBuffer
;
356 if (Entry
== NULL
|| Context
== NULL
) {
357 return EFI_INVALID_PARAMETER
;
360 Sock
= NET_LIST_USER_STRUCT_S (Entry
, SOCKET
, Link
, SOCK_SIGNATURE
);
361 ServiceBinding
= ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->ServiceBinding
;
362 NumberOfChildren
= ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->NumberOfChildren
;
363 ChildHandleBuffer
= ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->ChildHandleBuffer
;
365 if (!NetIsInHandleBuffer (Sock
->SockHandle
, NumberOfChildren
, ChildHandleBuffer
)) {
369 return ServiceBinding
->DestroyChild (ServiceBinding
, Sock
->SockHandle
);
373 Destroy a TCP6 or TCP4 service binding instance. It will release all
374 the resources allocated by the instance.
376 @param[in] Controller Controller handle of device to bind driver to.
377 @param[in] ImageHandle The TCP driver's image handle.
378 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number
379 of children is zero stop the entire bus driver.
380 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
381 if NumberOfChildren is 0.
382 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6
384 @retval EFI_SUCCESS The resources used by the instance were cleaned up.
385 @retval Others Failed to clean up some of the resources.
390 IN EFI_HANDLE Controller
,
391 IN EFI_HANDLE ImageHandle
,
392 IN UINTN NumberOfChildren
,
393 IN EFI_HANDLE
*ChildHandleBuffer
, OPTIONAL
397 EFI_HANDLE NicHandle
;
398 EFI_GUID
*IpProtocolGuid
;
399 EFI_GUID
*ServiceBindingGuid
;
400 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
401 TCP_SERVICE_DATA
*TcpServiceData
;
404 TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context
;
406 ASSERT ((IpVersion
== IP_VERSION_4
) || (IpVersion
== IP_VERSION_6
));
408 if (IpVersion
== IP_VERSION_4
) {
409 IpProtocolGuid
= &gEfiIp4ProtocolGuid
;
410 ServiceBindingGuid
= &gEfiTcp4ServiceBindingProtocolGuid
;
412 IpProtocolGuid
= &gEfiIp6ProtocolGuid
;
413 ServiceBindingGuid
= &gEfiTcp6ServiceBindingProtocolGuid
;
416 NicHandle
= NetLibGetNicHandle (Controller
, IpProtocolGuid
);
417 if (NicHandle
== NULL
) {
421 Status
= gBS
->OpenProtocol (
424 (VOID
**) &ServiceBinding
,
427 EFI_OPEN_PROTOCOL_GET_PROTOCOL
429 if (EFI_ERROR (Status
)) {
430 return EFI_DEVICE_ERROR
;
433 TcpServiceData
= TCP_SERVICE_FROM_THIS (ServiceBinding
);
435 if (NumberOfChildren
!= 0) {
436 List
= &TcpServiceData
->SocketList
;
437 Context
.ServiceBinding
= ServiceBinding
;
438 Context
.NumberOfChildren
= NumberOfChildren
;
439 Context
.ChildHandleBuffer
= ChildHandleBuffer
;
440 Status
= NetDestroyLinkList (
442 TcpDestroyChildEntryInHandleBuffer
,
446 } else if (IsListEmpty (&TcpServiceData
->SocketList
)) {
448 // Uninstall TCP servicebinding protocol
450 gBS
->UninstallMultipleProtocolInterfaces (
458 // Destroy the IpIO consumed by TCP driver
460 IpIoDestroy (TcpServiceData
->IpIo
);
461 TcpServiceData
->IpIo
= NULL
;
464 // Destroy the heartbeat timer.
469 // Clear the variable.
471 TcpClearVariableData (TcpServiceData
);
474 // Release the TCP service data
476 FreePool (TcpServiceData
);
478 Status
= EFI_SUCCESS
;
485 Test to see if this driver supports ControllerHandle.
487 @param[in] This Protocol instance pointer.
488 @param[in] ControllerHandle Handle of device to test.
489 @param[in] RemainingDevicePath Optional parameter use to pick a specific
490 child device to start.
492 @retval EFI_SUCCESS This driver supports this device.
493 @retval EFI_ALREADY_STARTED This driver is already running on this device.
494 @retval other This driver does not support this device.
499 TcpDriverBindingSupported (
500 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
501 IN EFI_HANDLE ControllerHandle
,
502 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
506 BOOLEAN IsTcp4Started
;
509 // Test for the Tcp4ServiceBinding Protocol
511 Status
= gBS
->OpenProtocol (
513 &gEfiTcp4ServiceBindingProtocolGuid
,
515 This
->DriverBindingHandle
,
517 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
519 if (EFI_ERROR (Status
)) {
521 // Test for the Ip4ServiceBinding Protocol
523 Status
= gBS
->OpenProtocol (
525 &gEfiIp4ServiceBindingProtocolGuid
,
527 This
->DriverBindingHandle
,
529 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
531 if (!EFI_ERROR (Status
)) {
535 IsTcp4Started
= FALSE
;
537 IsTcp4Started
= TRUE
;
541 // Check the Tcp6ServiceBinding Protocol
543 Status
= gBS
->OpenProtocol (
545 &gEfiTcp6ServiceBindingProtocolGuid
,
547 This
->DriverBindingHandle
,
549 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
551 if (EFI_ERROR (Status
)) {
553 // Test for the Ip6ServiceBinding Protocol
555 Status
= gBS
->OpenProtocol (
557 &gEfiIp6ServiceBindingProtocolGuid
,
559 This
->DriverBindingHandle
,
561 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
563 if (!EFI_ERROR (Status
)) {
566 } else if (IsTcp4Started
) {
567 return EFI_ALREADY_STARTED
;
570 return EFI_UNSUPPORTED
;
574 Start this driver on ControllerHandle.
576 @param[in] This Protocol instance pointer.
577 @param[in] ControllerHandle Handle of device to bind driver to.
578 @param[in] RemainingDevicePath Optional parameter use to pick a specific child
581 @retval EFI_SUCCESS The driver is added to ControllerHandle.
582 @retval EFI_OUT_OF_RESOURCES There are not enough resources to start the
584 @retval other The driver cannot be added to ControllerHandle.
589 TcpDriverBindingStart (
590 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
591 IN EFI_HANDLE ControllerHandle
,
592 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
595 EFI_STATUS Tcp4Status
;
596 EFI_STATUS Tcp6Status
;
598 Tcp4Status
= TcpCreateService (ControllerHandle
, This
->DriverBindingHandle
, IP_VERSION_4
);
599 if ((Tcp4Status
== EFI_ALREADY_STARTED
) || (Tcp4Status
== EFI_UNSUPPORTED
)) {
600 Tcp4Status
= EFI_SUCCESS
;
603 Tcp6Status
= TcpCreateService (ControllerHandle
, This
->DriverBindingHandle
, IP_VERSION_6
);
604 if ((Tcp6Status
== EFI_ALREADY_STARTED
) || (Tcp6Status
== EFI_UNSUPPORTED
)) {
605 Tcp6Status
= EFI_SUCCESS
;
608 if (!EFI_ERROR (Tcp4Status
) || !EFI_ERROR (Tcp6Status
)) {
610 } else if (EFI_ERROR (Tcp4Status
)) {
618 Stop this driver on ControllerHandle.
620 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
621 @param[in] ControllerHandle A handle to the device being stopped. The handle must
622 support a bus specific I/O protocol for the driver
623 to use to stop the device.
624 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
625 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
626 if NumberOfChildren is 0.
628 @retval EFI_SUCCESS The device was stopped.
629 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
634 TcpDriverBindingStop (
635 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
636 IN EFI_HANDLE ControllerHandle
,
637 IN UINTN NumberOfChildren
,
638 IN EFI_HANDLE
*ChildHandleBuffer OPTIONAL
641 EFI_STATUS Tcp4Status
;
642 EFI_STATUS Tcp6Status
;
644 Tcp4Status
= TcpDestroyService (
646 This
->DriverBindingHandle
,
652 Tcp6Status
= TcpDestroyService (
654 This
->DriverBindingHandle
,
660 if (EFI_ERROR (Tcp4Status
) && EFI_ERROR (Tcp6Status
)) {
661 return EFI_DEVICE_ERROR
;
668 The Callback funtion called after the TCP socket was created.
670 @param[in] This Pointer to the socket just created
671 @param[in] Context Context of the socket
673 @retval EFI_SUCCESS This protocol installed successfully.
674 @retval other An error occured.
678 TcpCreateSocketCallback (
684 TCP_SERVICE_DATA
*TcpServiceData
;
685 EFI_GUID
*IpProtocolGuid
;
688 if (This
->IpVersion
== IP_VERSION_4
) {
689 IpProtocolGuid
= &gEfiIp4ProtocolGuid
;
691 IpProtocolGuid
= &gEfiIp6ProtocolGuid
;
694 TcpServiceData
= ((TCP_PROTO_DATA
*) This
->ProtoReserved
)->TcpService
;
697 // Open the default IP protocol of IP_IO BY_DRIVER.
699 Status
= gBS
->OpenProtocol (
700 TcpServiceData
->IpIo
->ChildHandle
,
703 TcpServiceData
->DriverBindingHandle
,
705 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
707 if (EFI_ERROR (Status
)) {
712 // Open the device path on the handle where service binding resides on.
714 Status
= gBS
->OpenProtocol (
715 TcpServiceData
->ControllerHandle
,
716 &gEfiDevicePathProtocolGuid
,
717 (VOID
**) &This
->ParentDevicePath
,
718 TcpServiceData
->DriverBindingHandle
,
720 EFI_OPEN_PROTOCOL_GET_PROTOCOL
722 if (EFI_ERROR (Status
)) {
724 TcpServiceData
->IpIo
->ChildHandle
,
726 TcpServiceData
->DriverBindingHandle
,
731 // Insert this socket into the SocketList.
733 InsertTailList (&TcpServiceData
->SocketList
, &This
->Link
);
740 The callback function called before the TCP socket was to be destroyed.
742 @param[in] This The TCP socket to be destroyed.
743 @param[in] Context The context of the socket.
747 TcpDestroySocketCallback (
752 TCP_SERVICE_DATA
*TcpServiceData
;
753 EFI_GUID
*IpProtocolGuid
;
755 if (This
->IpVersion
== IP_VERSION_4
) {
756 IpProtocolGuid
= &gEfiIp4ProtocolGuid
;
758 IpProtocolGuid
= &gEfiIp6ProtocolGuid
;
761 TcpServiceData
= ((TCP_PROTO_DATA
*) This
->ProtoReserved
)->TcpService
;
764 // Remove this node from the list.
766 RemoveEntryList (&This
->Link
);
769 // Close the IP protocol.
772 TcpServiceData
->IpIo
->ChildHandle
,
774 TcpServiceData
->DriverBindingHandle
,
780 Creates a child handle with a set of TCP services.
782 The CreateChild() function installs a protocol on ChildHandle.
783 If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
784 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
786 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
787 @param[in, out] ChildHandle Pointer to the handle of the child to create.
788 If it is NULL, then a new handle is created.
789 If it is a pointer to an existing UEFI handle,
790 then the protocol is added to the existing UEFI handle.
792 @retval EFI_SUCCES The protocol was added to ChildHandle.
793 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
794 @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create
796 @retval other The child handle was not created.
801 TcpServiceBindingCreateChild (
802 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
803 IN OUT EFI_HANDLE
*ChildHandle
807 TCP_SERVICE_DATA
*TcpServiceData
;
808 TCP_PROTO_DATA TcpProto
;
812 if (NULL
== This
|| NULL
== ChildHandle
) {
813 return EFI_INVALID_PARAMETER
;
816 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
818 Status
= EFI_SUCCESS
;
819 TcpServiceData
= TCP_SERVICE_FROM_THIS (This
);
820 TcpProto
.TcpService
= TcpServiceData
;
821 TcpProto
.TcpPcb
= NULL
;
824 // Create a tcp instance with defualt Tcp default
825 // sock init data and TcpProto
827 mTcpDefaultSockData
.ProtoData
= &TcpProto
;
828 mTcpDefaultSockData
.DataSize
= sizeof (TCP_PROTO_DATA
);
829 mTcpDefaultSockData
.DriverBinding
= TcpServiceData
->DriverBindingHandle
;
830 mTcpDefaultSockData
.IpVersion
= TcpServiceData
->IpVersion
;
832 if (TcpServiceData
->IpVersion
== IP_VERSION_4
) {
833 mTcpDefaultSockData
.Protocol
= &gTcp4ProtocolTemplate
;
835 mTcpDefaultSockData
.Protocol
= &gTcp6ProtocolTemplate
;
838 Sock
= SockCreateChild (&mTcpDefaultSockData
);
842 "TcpDriverBindingCreateChild: No resource to create a Tcp Child\n")
845 Status
= EFI_OUT_OF_RESOURCES
;
847 *ChildHandle
= Sock
->SockHandle
;
850 mTcpDefaultSockData
.ProtoData
= NULL
;
852 gBS
->RestoreTPL (OldTpl
);
857 Destroys a child handle with a set of TCP services.
859 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
860 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
861 last protocol on ChildHandle, then ChildHandle is destroyed.
863 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
864 @param ChildHandle Handle of the child to be destroyed.
866 @retval EFI_SUCCES The protocol was removed from ChildHandle.
867 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
868 @retval EFI_INVALID_PARAMETER Child handle is NULL.
869 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
870 because its services are being used.
871 @retval other The child handle was not destroyed.
876 TcpServiceBindingDestroyChild (
877 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
878 IN EFI_HANDLE ChildHandle
885 if (NULL
== This
|| NULL
== ChildHandle
) {
886 return EFI_INVALID_PARAMETER
;
890 // retrieve the Tcp4 protocol from ChildHandle
892 Status
= gBS
->OpenProtocol (
894 &gEfiTcp4ProtocolGuid
,
896 gTcpDriverBinding
.DriverBindingHandle
,
898 EFI_OPEN_PROTOCOL_GET_PROTOCOL
900 if (EFI_ERROR (Status
)) {
902 // No Tcp4, try the Tcp6 protocol
904 Status
= gBS
->OpenProtocol (
906 &gEfiTcp6ProtocolGuid
,
908 gTcpDriverBinding
.DriverBindingHandle
,
910 EFI_OPEN_PROTOCOL_GET_PROTOCOL
912 if (EFI_ERROR (Status
)) {
913 Status
= EFI_UNSUPPORTED
;
917 if (!EFI_ERROR (Status
)) {
919 // destroy this sock and related Tcp protocol control
922 Sock
= SOCK_FROM_THIS (Tcp
);
924 SockDestroyChild (Sock
);