3 Copyright (c) 2005 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
24 UINT16 mTcp4RandomPort
;
25 extern EFI_COMPONENT_NAME_PROTOCOL gTcp4ComponentName
;
26 extern EFI_COMPONENT_NAME2_PROTOCOL gTcp4ComponentName2
;
28 TCP4_HEARTBEAT_TIMER mTcp4Timer
= {
33 EFI_TCP4_PROTOCOL mTcp4ProtocolTemplate
= {
46 SOCK_INIT_DATA mTcp4DefaultSockData
= {
53 &mTcp4ProtocolTemplate
,
54 Tcp4CreateSocketCallback
,
55 Tcp4DestroySocketCallback
,
63 EFI_DRIVER_BINDING_PROTOCOL mTcp4DriverBinding
= {
64 Tcp4DriverBindingSupported
,
65 Tcp4DriverBindingStart
,
66 Tcp4DriverBindingStop
,
72 EFI_SERVICE_BINDING_PROTOCOL mTcp4ServiceBinding
= {
73 Tcp4ServiceBindingCreateChild
,
74 Tcp4ServiceBindingDestroyChild
79 Create and start the heartbeat timer for TCP driver.
83 @retval EFI_SUCCESS The timer is successfully created and started.
84 @retval other The timer is not created.
96 if (mTcp4Timer
.RefCnt
== 0) {
98 Status
= gBS
->CreateEvent (
99 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
103 &mTcp4Timer
.TimerEvent
105 if (!EFI_ERROR (Status
)) {
107 Status
= gBS
->SetTimer (
108 mTcp4Timer
.TimerEvent
,
110 (UINT64
) (TICKS_PER_SECOND
/ TCP_TICK_HZ
)
115 if (!EFI_ERROR (Status
)) {
125 Stop and destroy the heartbeat timer for TCP driver.
135 ASSERT (mTcp4Timer
.RefCnt
> 0);
139 if (mTcp4Timer
.RefCnt
> 0) {
143 gBS
->SetTimer (mTcp4Timer
.TimerEvent
, TimerCancel
, 0);
144 gBS
->CloseEvent (mTcp4Timer
.TimerEvent
);
145 mTcp4Timer
.TimerEvent
= NULL
;
149 The entry point for Tcp4 driver.
150 Used to install Tcp4 driver on the ImageHandle.
152 @param ImageHandle The firmware allocated handle for this
154 @param SystemTable Pointer to the EFI system table.
156 @retval EFI_SUCCESS Driver loaded.
157 @retval other Driver not loaded.
162 Tcp4DriverEntryPoint (
163 IN EFI_HANDLE ImageHandle
,
164 IN EFI_SYSTEM_TABLE
*SystemTable
171 // Install the TCP4 Driver Binding Protocol
173 Status
= EfiLibInstallDriverBindingComponentName2 (
181 ASSERT_EFI_ERROR (Status
);
183 // Initialize ISS and random port.
185 Seed
= NetRandomInitSeed ();
186 mTcpGlobalIss
= NET_RANDOM (Seed
) % mTcpGlobalIss
;
187 mTcp4RandomPort
= (UINT16
) ( TCP4_PORT_KNOWN
+
188 (UINT16
) (NET_RANDOM(Seed
) % TCP4_PORT_KNOWN
));
195 Test to see if this driver supports ControllerHandle.
197 @param This Protocol instance pointer.
198 @param ControllerHandle Handle of device to test.
199 @param RemainingDevicePath Optional parameter use to pick a specific child
202 @retval EFI_SUCCESS This driver supports this device.
203 @retval EFI_ALREADY_STARTED This driver is already running on this device.
204 @retval other This driver does not support this device.
209 Tcp4DriverBindingSupported (
210 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
211 IN EFI_HANDLE ControllerHandle
,
212 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath OPTIONAL
218 // Test for the Tcp4ServiceBinding Protocol
220 Status
= gBS
->OpenProtocol (
222 &gEfiTcp4ServiceBindingProtocolGuid
,
224 This
->DriverBindingHandle
,
226 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
228 if (!EFI_ERROR (Status
)) {
229 return EFI_ALREADY_STARTED
;
233 // Test for the Ip4 Protocol
235 Status
= gBS
->OpenProtocol (
237 &gEfiIp4ServiceBindingProtocolGuid
,
239 This
->DriverBindingHandle
,
241 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
249 Start this driver on ControllerHandle.
251 @param This Protocol instance pointer.
252 @param ControllerHandle Handle of device to bind driver to.
253 @param RemainingDevicePath Optional parameter use to pick a specific child
256 @retval EFI_SUCCESS The driver is added to ControllerHandle.
257 @retval EFI_OUT_OF_RESOURCES There are not enough resources to start the
259 @retval other The driver cannot be added to ControllerHandle.
264 Tcp4DriverBindingStart (
265 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
266 IN EFI_HANDLE ControllerHandle
,
267 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath OPTIONAL
271 TCP4_SERVICE_DATA
*TcpServiceData
;
272 IP_IO_OPEN_DATA OpenData
;
274 TcpServiceData
= AllocateZeroPool (sizeof (TCP4_SERVICE_DATA
));
276 if (NULL
== TcpServiceData
) {
277 DEBUG ((EFI_D_ERROR
, "Tcp4DriverBindingStart: Have no enough"
278 " resource to create a Tcp Servcie Data!\n"));
280 return EFI_OUT_OF_RESOURCES
;
284 // Create a new IP IO to Consume it
286 TcpServiceData
->IpIo
= IpIoCreate (This
->DriverBindingHandle
, ControllerHandle
);
287 if (NULL
== TcpServiceData
->IpIo
) {
289 DEBUG ((EFI_D_ERROR
, "Tcp4DriverBindingStart: Have no enough"
290 " resource to create an Ip Io!\n"));
292 Status
= EFI_OUT_OF_RESOURCES
;
297 // Configure and start IpIo.
299 ZeroMem (&OpenData
, sizeof (IP_IO_OPEN_DATA
));
301 CopyMem (&OpenData
.IpConfigData
, &mIpIoDefaultIpConfigData
, sizeof (OpenData
.IpConfigData
));
302 OpenData
.IpConfigData
.DefaultProtocol
= EFI_IP_PROTO_TCP
;
304 OpenData
.PktRcvdNotify
= Tcp4RxCallback
;
305 Status
= IpIoOpen (TcpServiceData
->IpIo
, &OpenData
);
307 if (EFI_ERROR (Status
)) {
312 // Create the timer event used by TCP driver
314 Status
= Tcp4CreateTimer ();
315 if (EFI_ERROR (Status
)) {
317 DEBUG ((EFI_D_ERROR
, "Tcp4DriverBindingStart: Create TcpTimer"
318 " Event failed with %r\n", Status
));
324 // Install the Tcp4ServiceBinding Protocol on the
327 TcpServiceData
->Tcp4ServiceBinding
= mTcp4ServiceBinding
;
329 Status
= gBS
->InstallMultipleProtocolInterfaces (
331 &gEfiTcp4ServiceBindingProtocolGuid
,
332 &TcpServiceData
->Tcp4ServiceBinding
,
335 if (EFI_ERROR (Status
)) {
337 DEBUG ((EFI_D_ERROR
, "Tcp4DriverBindingStart: Install Tcp4 Service Binding"
338 " Protocol failed for %r\n", Status
));
345 // Initialize member in TcpServiceData
347 TcpServiceData
->ControllerHandle
= ControllerHandle
;
348 TcpServiceData
->Signature
= TCP4_DRIVER_SIGNATURE
;
349 TcpServiceData
->DriverBindingHandle
= This
->DriverBindingHandle
;
351 InitializeListHead (&TcpServiceData
->SocketList
);
353 TcpSetVariableData (TcpServiceData
);
359 if (TcpServiceData
->IpIo
!= NULL
) {
360 IpIoDestroy (TcpServiceData
->IpIo
);
363 gBS
->FreePool (TcpServiceData
);
370 Stop this driver on ControllerHandle.
372 @param This Protocol instance pointer.
373 @param ControllerHandle Handle of device to stop driver on.
374 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number
375 of children is zero stop the entire bus driver.
376 @param ChildHandleBuffer List of Child Handles to Stop.
378 @retval EFI_SUCCESS This driver is removed from ControllerHandle.
379 @retval other This driver is not removed from ControllerHandle.
384 Tcp4DriverBindingStop (
385 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
386 IN EFI_HANDLE ControllerHandle
,
387 IN UINTN NumberOfChildren
,
388 IN EFI_HANDLE
*ChildHandleBuffer
392 EFI_HANDLE NicHandle
;
393 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
394 TCP4_SERVICE_DATA
*TcpServiceData
;
397 // Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.
399 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiIp4ProtocolGuid
);
400 if (NicHandle
== NULL
) {
401 return EFI_DEVICE_ERROR
;
405 // Retrieve the TCP driver Data Structure
407 Status
= gBS
->OpenProtocol (
409 &gEfiTcp4ServiceBindingProtocolGuid
,
410 (VOID
**) &ServiceBinding
,
411 This
->DriverBindingHandle
,
413 EFI_OPEN_PROTOCOL_GET_PROTOCOL
415 if (EFI_ERROR (Status
)) {
417 DEBUG ((EFI_D_ERROR
, "Tcp4DriverBindingStop: Locate Tcp4 Service "
418 " Binding Protocol failed with %r\n", Status
));
420 return EFI_DEVICE_ERROR
;
423 TcpServiceData
= TCP4_FROM_THIS (ServiceBinding
);
425 if (NumberOfChildren
== 0) {
427 // Uninstall TCP servicebinding protocol
429 gBS
->UninstallMultipleProtocolInterfaces (
431 &gEfiTcp4ServiceBindingProtocolGuid
,
437 // Destroy the IpIO consumed by TCP driver
439 IpIoDestroy (TcpServiceData
->IpIo
);
442 // Destroy the heartbeat timer.
447 // Clear the variable.
449 TcpClearVariableData (TcpServiceData
);
452 // Release the TCP service data
454 gBS
->FreePool (TcpServiceData
);
457 while (!IsListEmpty (&TcpServiceData
->SocketList
)) {
458 Sock
= NET_LIST_HEAD (&TcpServiceData
->SocketList
, SOCKET
, Link
);
460 ServiceBinding
->DestroyChild (ServiceBinding
, Sock
->SockHandle
);
468 Tcp4CreateSocketCallback (
474 TCP4_SERVICE_DATA
*TcpServiceData
;
475 EFI_IP4_PROTOCOL
*Ip4
;
477 TcpServiceData
= ((TCP4_PROTO_DATA
*) This
->ProtoReserved
)->TcpService
;
480 // Open the default Ip4 protocol of IP_IO BY_DRIVER.
482 Status
= gBS
->OpenProtocol (
483 TcpServiceData
->IpIo
->ChildHandle
,
484 &gEfiIp4ProtocolGuid
,
486 TcpServiceData
->DriverBindingHandle
,
488 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
490 if (EFI_ERROR (Status
)) {
495 // Open the device path on the handle where service binding resides on.
497 Status
= gBS
->OpenProtocol (
498 TcpServiceData
->ControllerHandle
,
499 &gEfiDevicePathProtocolGuid
,
500 (VOID
**) &This
->ParentDevicePath
,
501 TcpServiceData
->DriverBindingHandle
,
503 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
505 if (EFI_ERROR (Status
)) {
507 TcpServiceData
->IpIo
->ChildHandle
,
508 &gEfiIp4ProtocolGuid
,
509 TcpServiceData
->DriverBindingHandle
,
514 // Insert this socket into the SocketList.
516 InsertTailList (&TcpServiceData
->SocketList
, &This
->Link
);
523 Tcp4DestroySocketCallback (
528 TCP4_SERVICE_DATA
*TcpServiceData
;
530 TcpServiceData
= ((TCP4_PROTO_DATA
*) This
->ProtoReserved
)->TcpService
;
533 // Remove this node from the list.
535 RemoveEntryList (&This
->Link
);
538 // Close the device path protocol
541 TcpServiceData
->ControllerHandle
,
542 &gEfiDevicePathProtocolGuid
,
543 TcpServiceData
->DriverBindingHandle
,
548 // Close the Ip4 protocol.
551 TcpServiceData
->IpIo
->ChildHandle
,
552 &gEfiIp4ProtocolGuid
,
553 TcpServiceData
->DriverBindingHandle
,
559 Creates a child handle with a set of TCP4 services.
561 @param This Protocol instance pointer.
562 @param ChildHandle Pointer to the handle of the child to create. If
563 it is NULL, then a new handle is created. If it is
564 not NULL, then the I/O services are added to the
565 existing child handle.
567 @retval EFI_SUCCESS The child handle is created.
568 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
569 @retval EFI_OUT_OF_RESOURCES There are not enough resources to create the
575 Tcp4ServiceBindingCreateChild (
576 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
577 IN EFI_HANDLE
*ChildHandle
581 TCP4_SERVICE_DATA
*TcpServiceData
;
582 TCP4_PROTO_DATA TcpProto
;
586 if (NULL
== This
|| NULL
== ChildHandle
) {
587 return EFI_INVALID_PARAMETER
;
590 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
591 Status
= EFI_SUCCESS
;
592 TcpServiceData
= TCP4_FROM_THIS (This
);
593 TcpProto
.TcpService
= TcpServiceData
;
594 TcpProto
.TcpPcb
= NULL
;
597 // Create a tcp instance with defualt Tcp default
598 // sock init data and TcpProto
600 mTcp4DefaultSockData
.ProtoData
= &TcpProto
;
601 mTcp4DefaultSockData
.DataSize
= sizeof (TCP4_PROTO_DATA
);
602 mTcp4DefaultSockData
.DriverBinding
= TcpServiceData
->DriverBindingHandle
;
604 Sock
= SockCreateChild (&mTcp4DefaultSockData
);
606 DEBUG ((EFI_D_ERROR
, "Tcp4DriverBindingCreateChild: "
607 "No resource to create a Tcp Child\n"));
609 Status
= EFI_OUT_OF_RESOURCES
;
611 *ChildHandle
= Sock
->SockHandle
;
614 gBS
->RestoreTPL (OldTpl
);
620 Destroys a child handle with a set of UDP4 services.
622 @param This Protocol instance pointer.
623 @param ChildHandle Handle of the child to be destroyed.
625 @retval EFI_SUCCESS The TCP4 services are removed from the child
627 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
628 @retval other The child handle is not destroyed.
633 Tcp4ServiceBindingDestroyChild (
634 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
635 IN EFI_HANDLE ChildHandle
639 EFI_TCP4_PROTOCOL
*Tcp4
;
643 if (NULL
== This
|| NULL
== ChildHandle
) {
644 return EFI_INVALID_PARAMETER
;
647 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
650 // retrieve the Tcp4 protocol from ChildHandle
652 Status
= gBS
->OpenProtocol (
654 &gEfiTcp4ProtocolGuid
,
656 mTcp4DriverBinding
.DriverBindingHandle
,
658 EFI_OPEN_PROTOCOL_GET_PROTOCOL
660 if (EFI_ERROR (Status
)) {
661 Status
= EFI_UNSUPPORTED
;
664 // destroy this sock and related Tcp protocol control
667 Sock
= SOCK_FROM_THIS (Tcp4
);
669 SockDestroyChild (Sock
);
672 gBS
->RestoreTPL (OldTpl
);