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.
137 ASSERT (mTcp4Timer
.RefCnt
> 0);
141 if (mTcp4Timer
.RefCnt
> 0) {
145 gBS
->SetTimer (mTcp4Timer
.TimerEvent
, TimerCancel
, 0);
146 gBS
->CloseEvent (mTcp4Timer
.TimerEvent
);
147 mTcp4Timer
.TimerEvent
= NULL
;
153 Tcp4DriverEntryPoint (
154 IN EFI_HANDLE ImageHandle
,
155 IN EFI_SYSTEM_TABLE
*SystemTable
161 The entry point for Tcp4 driver. used to install
162 Tcp4 driver on the ImageHandle.
166 ImageHandle - The firmware allocated handle for this
168 SystemTable - Pointer to the EFI system table.
172 EFI_SUCCESS - Driver loaded.
173 other - Driver not loaded.
181 // Install the TCP4 Driver Binding Protocol
183 Status
= EfiLibInstallDriverBindingComponentName2 (
191 ASSERT_EFI_ERROR (Status
);
193 // Initialize ISS and random port.
195 Seed
= NetRandomInitSeed ();
196 mTcpGlobalIss
= NET_RANDOM (Seed
) % mTcpGlobalIss
;
197 mTcp4RandomPort
= (UINT16
) ( TCP4_PORT_KNOWN
+
198 (UINT16
) (NET_RANDOM(Seed
) % TCP4_PORT_KNOWN
));
205 Test to see if this driver supports ControllerHandle.
207 @param This Protocol instance pointer.
208 @param ControllerHandle Handle of device to test.
209 @param RemainingDevicePath Optional parameter use to pick a specific child
212 @retval EFI_SUCCESS This driver supports this device.
213 @retval EFI_ALREADY_STARTED This driver is already running on this device.
214 @retval other This driver does not support this device.
219 Tcp4DriverBindingSupported (
220 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
221 IN EFI_HANDLE ControllerHandle
,
222 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath OPTIONAL
228 // Test for the Tcp4ServiceBinding Protocol
230 Status
= gBS
->OpenProtocol (
232 &gEfiTcp4ServiceBindingProtocolGuid
,
234 This
->DriverBindingHandle
,
236 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
238 if (!EFI_ERROR (Status
)) {
239 return EFI_ALREADY_STARTED
;
243 // Test for the Ip4 Protocol
245 Status
= gBS
->OpenProtocol (
247 &gEfiIp4ServiceBindingProtocolGuid
,
249 This
->DriverBindingHandle
,
251 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
259 Start this driver on ControllerHandle.
261 @param This Protocol instance pointer.
262 @param ControllerHandle Handle of device to bind driver to.
263 @param RemainingDevicePath Optional parameter use to pick a specific child
266 @retval EFI_SUCCESS The driver is added to ControllerHandle.
267 @retval EFI_OUT_OF_RESOURCES There are not enough resources to start the
269 @retval other The driver cannot be added to ControllerHandle.
274 Tcp4DriverBindingStart (
275 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
276 IN EFI_HANDLE ControllerHandle
,
277 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath OPTIONAL
281 TCP4_SERVICE_DATA
*TcpServiceData
;
282 IP_IO_OPEN_DATA OpenData
;
284 TcpServiceData
= AllocateZeroPool (sizeof (TCP4_SERVICE_DATA
));
286 if (NULL
== TcpServiceData
) {
287 DEBUG ((EFI_D_ERROR
, "Tcp4DriverBindingStart: Have no enough"
288 " resource to create a Tcp Servcie Data!\n"));
290 return EFI_OUT_OF_RESOURCES
;
294 // Create a new IP IO to Consume it
296 TcpServiceData
->IpIo
= IpIoCreate (This
->DriverBindingHandle
, ControllerHandle
);
297 if (NULL
== TcpServiceData
->IpIo
) {
299 DEBUG ((EFI_D_ERROR
, "Tcp4DriverBindingStart: Have no enough"
300 " resource to create an Ip Io!\n"));
302 Status
= EFI_OUT_OF_RESOURCES
;
307 // Configure and start IpIo.
309 ZeroMem (&OpenData
, sizeof (IP_IO_OPEN_DATA
));
311 CopyMem (&OpenData
.IpConfigData
, &mIpIoDefaultIpConfigData
, sizeof (OpenData
.IpConfigData
));
312 OpenData
.IpConfigData
.DefaultProtocol
= EFI_IP_PROTO_TCP
;
314 OpenData
.PktRcvdNotify
= Tcp4RxCallback
;
315 Status
= IpIoOpen (TcpServiceData
->IpIo
, &OpenData
);
317 if (EFI_ERROR (Status
)) {
322 // Create the timer event used by TCP driver
324 Status
= Tcp4CreateTimer ();
325 if (EFI_ERROR (Status
)) {
327 DEBUG ((EFI_D_ERROR
, "Tcp4DriverBindingStart: Create TcpTimer"
328 " Event failed with %r\n", Status
));
334 // Install the Tcp4ServiceBinding Protocol on the
337 TcpServiceData
->Tcp4ServiceBinding
= mTcp4ServiceBinding
;
339 Status
= gBS
->InstallMultipleProtocolInterfaces (
341 &gEfiTcp4ServiceBindingProtocolGuid
,
342 &TcpServiceData
->Tcp4ServiceBinding
,
345 if (EFI_ERROR (Status
)) {
347 DEBUG ((EFI_D_ERROR
, "Tcp4DriverBindingStart: Install Tcp4 Service Binding"
348 " Protocol failed for %r\n", Status
));
355 // Initialize member in TcpServiceData
357 TcpServiceData
->ControllerHandle
= ControllerHandle
;
358 TcpServiceData
->Signature
= TCP4_DRIVER_SIGNATURE
;
359 TcpServiceData
->DriverBindingHandle
= This
->DriverBindingHandle
;
361 InitializeListHead (&TcpServiceData
->SocketList
);
363 TcpSetVariableData (TcpServiceData
);
369 if (TcpServiceData
->IpIo
!= NULL
) {
370 IpIoDestroy (TcpServiceData
->IpIo
);
373 gBS
->FreePool (TcpServiceData
);
380 Stop this driver on ControllerHandle.
382 @param This Protocol instance pointer.
383 @param ControllerHandle Handle of device to stop driver on.
384 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number
385 of children is zero stop the entire bus driver.
386 @param ChildHandleBuffer List of Child Handles to Stop.
388 @retval EFI_SUCCESS This driver is removed from ControllerHandle.
389 @retval other This driver is not removed from ControllerHandle.
394 Tcp4DriverBindingStop (
395 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
396 IN EFI_HANDLE ControllerHandle
,
397 IN UINTN NumberOfChildren
,
398 IN EFI_HANDLE
*ChildHandleBuffer
402 EFI_HANDLE NicHandle
;
403 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
404 TCP4_SERVICE_DATA
*TcpServiceData
;
407 // Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.
409 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiIp4ProtocolGuid
);
410 if (NicHandle
== NULL
) {
411 return EFI_DEVICE_ERROR
;
415 // Retrieve the TCP driver Data Structure
417 Status
= gBS
->OpenProtocol (
419 &gEfiTcp4ServiceBindingProtocolGuid
,
420 (VOID
**) &ServiceBinding
,
421 This
->DriverBindingHandle
,
423 EFI_OPEN_PROTOCOL_GET_PROTOCOL
425 if (EFI_ERROR (Status
)) {
427 DEBUG ((EFI_D_ERROR
, "Tcp4DriverBindingStop: Locate Tcp4 Service "
428 " Binding Protocol failed with %r\n", Status
));
430 return EFI_DEVICE_ERROR
;
433 TcpServiceData
= TCP4_FROM_THIS (ServiceBinding
);
435 if (NumberOfChildren
== 0) {
437 // Uninstall TCP servicebinding protocol
439 gBS
->UninstallMultipleProtocolInterfaces (
441 &gEfiTcp4ServiceBindingProtocolGuid
,
447 // Destroy the IpIO consumed by TCP driver
449 IpIoDestroy (TcpServiceData
->IpIo
);
452 // Destroy the heartbeat timer.
457 // Clear the variable.
459 TcpClearVariableData (TcpServiceData
);
462 // Release the TCP service data
464 gBS
->FreePool (TcpServiceData
);
467 while (!IsListEmpty (&TcpServiceData
->SocketList
)) {
468 Sock
= NET_LIST_HEAD (&TcpServiceData
->SocketList
, SOCKET
, Link
);
470 ServiceBinding
->DestroyChild (ServiceBinding
, Sock
->SockHandle
);
478 Tcp4CreateSocketCallback (
484 TCP4_SERVICE_DATA
*TcpServiceData
;
485 EFI_IP4_PROTOCOL
*Ip4
;
487 TcpServiceData
= ((TCP4_PROTO_DATA
*) This
->ProtoReserved
)->TcpService
;
490 // Open the default Ip4 protocol of IP_IO BY_DRIVER.
492 Status
= gBS
->OpenProtocol (
493 TcpServiceData
->IpIo
->ChildHandle
,
494 &gEfiIp4ProtocolGuid
,
496 TcpServiceData
->DriverBindingHandle
,
498 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
500 if (EFI_ERROR (Status
)) {
505 // Open the device path on the handle where service binding resides on.
507 Status
= gBS
->OpenProtocol (
508 TcpServiceData
->ControllerHandle
,
509 &gEfiDevicePathProtocolGuid
,
510 (VOID
**) &This
->ParentDevicePath
,
511 TcpServiceData
->DriverBindingHandle
,
513 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
515 if (EFI_ERROR (Status
)) {
517 TcpServiceData
->IpIo
->ChildHandle
,
518 &gEfiIp4ProtocolGuid
,
519 TcpServiceData
->DriverBindingHandle
,
524 // Insert this socket into the SocketList.
526 InsertTailList (&TcpServiceData
->SocketList
, &This
->Link
);
533 Tcp4DestroySocketCallback (
538 TCP4_SERVICE_DATA
*TcpServiceData
;
540 TcpServiceData
= ((TCP4_PROTO_DATA
*) This
->ProtoReserved
)->TcpService
;
543 // Remove this node from the list.
545 RemoveEntryList (&This
->Link
);
548 // Close the device path protocol
551 TcpServiceData
->ControllerHandle
,
552 &gEfiDevicePathProtocolGuid
,
553 TcpServiceData
->DriverBindingHandle
,
558 // Close the Ip4 protocol.
561 TcpServiceData
->IpIo
->ChildHandle
,
562 &gEfiIp4ProtocolGuid
,
563 TcpServiceData
->DriverBindingHandle
,
569 Creates a child handle with a set of TCP4 services.
571 @param This Protocol instance pointer.
572 @param ChildHandle Pointer to the handle of the child to create. If
573 it is NULL, then a new handle is created. If it is
574 not NULL, then the I/O services are added to the
575 existing child handle.
577 @retval EFI_SUCCESS The child handle is created.
578 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
579 @retval EFI_OUT_OF_RESOURCES There are not enough resources to create the
585 Tcp4ServiceBindingCreateChild (
586 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
587 IN EFI_HANDLE
*ChildHandle
591 TCP4_SERVICE_DATA
*TcpServiceData
;
592 TCP4_PROTO_DATA TcpProto
;
596 if (NULL
== This
|| NULL
== ChildHandle
) {
597 return EFI_INVALID_PARAMETER
;
600 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
601 Status
= EFI_SUCCESS
;
602 TcpServiceData
= TCP4_FROM_THIS (This
);
603 TcpProto
.TcpService
= TcpServiceData
;
604 TcpProto
.TcpPcb
= NULL
;
607 // Create a tcp instance with defualt Tcp default
608 // sock init data and TcpProto
610 mTcp4DefaultSockData
.ProtoData
= &TcpProto
;
611 mTcp4DefaultSockData
.DataSize
= sizeof (TCP4_PROTO_DATA
);
612 mTcp4DefaultSockData
.DriverBinding
= TcpServiceData
->DriverBindingHandle
;
614 Sock
= SockCreateChild (&mTcp4DefaultSockData
);
616 DEBUG ((EFI_D_ERROR
, "Tcp4DriverBindingCreateChild: "
617 "No resource to create a Tcp Child\n"));
619 Status
= EFI_OUT_OF_RESOURCES
;
621 *ChildHandle
= Sock
->SockHandle
;
624 gBS
->RestoreTPL (OldTpl
);
630 Destroys a child handle with a set of UDP4 services.
632 @param This Protocol instance pointer.
633 @param ChildHandle Handle of the child to be destroyed.
635 @retval EFI_SUCCESS The TCP4 services are removed from the child
637 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
638 @retval other The child handle is not destroyed.
643 Tcp4ServiceBindingDestroyChild (
644 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
645 IN EFI_HANDLE ChildHandle
649 EFI_TCP4_PROTOCOL
*Tcp4
;
653 if (NULL
== This
|| NULL
== ChildHandle
) {
654 return EFI_INVALID_PARAMETER
;
657 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
660 // retrieve the Tcp4 protocol from ChildHandle
662 Status
= gBS
->OpenProtocol (
664 &gEfiTcp4ProtocolGuid
,
666 mTcp4DriverBinding
.DriverBindingHandle
,
668 EFI_OPEN_PROTOCOL_GET_PROTOCOL
670 if (EFI_ERROR (Status
)) {
671 Status
= EFI_UNSUPPORTED
;
674 // destroy this sock and related Tcp protocol control
677 Sock
= SOCK_FROM_THIS (Tcp4
);
679 SockDestroyChild (Sock
);
682 gBS
->RestoreTPL (OldTpl
);