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.
81 @retval EFI_SUCCESS The timer is successfully created and started.
82 @retval other The timer is not created.
94 if (mTcp4Timer
.RefCnt
== 0) {
96 Status
= gBS
->CreateEvent (
97 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
101 &mTcp4Timer
.TimerEvent
103 if (!EFI_ERROR (Status
)) {
105 Status
= gBS
->SetTimer (
106 mTcp4Timer
.TimerEvent
,
108 (UINT64
) (TICKS_PER_SECOND
/ TCP_TICK_HZ
)
113 if (!EFI_ERROR (Status
)) {
123 Stop and destroy the heartbeat timer for TCP driver.
131 ASSERT (mTcp4Timer
.RefCnt
> 0);
135 if (mTcp4Timer
.RefCnt
> 0) {
139 gBS
->SetTimer (mTcp4Timer
.TimerEvent
, TimerCancel
, 0);
140 gBS
->CloseEvent (mTcp4Timer
.TimerEvent
);
141 mTcp4Timer
.TimerEvent
= NULL
;
145 The entry point for Tcp4 driver, used to install Tcp4 driver on the ImageHandle.
147 @param ImageHandle The firmware allocated handle for this
149 @param SystemTable Pointer to the EFI system table.
151 @retval EFI_SUCCESS Driver loaded.
152 @retval other Driver not loaded.
157 Tcp4DriverEntryPoint (
158 IN EFI_HANDLE ImageHandle
,
159 IN EFI_SYSTEM_TABLE
*SystemTable
166 // Install the TCP4 Driver Binding Protocol
168 Status
= EfiLibInstallDriverBindingComponentName2 (
176 ASSERT_EFI_ERROR (Status
);
178 // Initialize ISS and random port.
180 Seed
= NetRandomInitSeed ();
181 mTcpGlobalIss
= NET_RANDOM (Seed
) % mTcpGlobalIss
;
182 mTcp4RandomPort
= (UINT16
) (TCP4_PORT_KNOWN
+
183 (UINT16
) (NET_RANDOM(Seed
) % TCP4_PORT_KNOWN
));
190 Test to see if this driver supports ControllerHandle.
192 @param This Protocol instance pointer.
193 @param ControllerHandle Handle of device to test.
194 @param RemainingDevicePath Optional parameter use to pick a specific child
197 @retval EFI_SUCCESS This driver supports this device.
198 @retval EFI_ALREADY_STARTED This driver is already running on this device.
199 @retval other This driver does not support this device.
204 Tcp4DriverBindingSupported (
205 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
206 IN EFI_HANDLE ControllerHandle
,
207 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
213 // Test for the Tcp4ServiceBinding Protocol
215 Status
= gBS
->OpenProtocol (
217 &gEfiTcp4ServiceBindingProtocolGuid
,
219 This
->DriverBindingHandle
,
221 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
223 if (!EFI_ERROR (Status
)) {
224 return EFI_ALREADY_STARTED
;
228 // Test for the Ip4 Protocol
230 Status
= gBS
->OpenProtocol (
232 &gEfiIp4ServiceBindingProtocolGuid
,
234 This
->DriverBindingHandle
,
236 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
244 Start this driver on ControllerHandle.
246 @param This Protocol instance pointer.
247 @param ControllerHandle Handle of device to bind driver to.
248 @param RemainingDevicePath Optional parameter use to pick a specific child
251 @retval EFI_SUCCESS The driver is added to ControllerHandle.
252 @retval EFI_OUT_OF_RESOURCES There are not enough resources to start the
254 @retval other The driver cannot be added to ControllerHandle.
259 Tcp4DriverBindingStart (
260 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
261 IN EFI_HANDLE ControllerHandle
,
262 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
266 TCP4_SERVICE_DATA
*TcpServiceData
;
267 IP_IO_OPEN_DATA OpenData
;
269 TcpServiceData
= AllocateZeroPool (sizeof (TCP4_SERVICE_DATA
));
271 if (NULL
== TcpServiceData
) {
272 DEBUG ((EFI_D_ERROR
, "Tcp4DriverBindingStart: Have no enough"
273 " resource to create a Tcp Servcie Data!\n"));
275 return EFI_OUT_OF_RESOURCES
;
279 // Create a new IP IO to Consume it
281 TcpServiceData
->IpIo
= IpIoCreate (This
->DriverBindingHandle
, ControllerHandle
);
282 if (NULL
== TcpServiceData
->IpIo
) {
284 DEBUG ((EFI_D_ERROR
, "Tcp4DriverBindingStart: Have no enough"
285 " resource to create an Ip Io!\n"));
287 Status
= EFI_OUT_OF_RESOURCES
;
292 // Configure and start IpIo.
294 ZeroMem (&OpenData
, sizeof (IP_IO_OPEN_DATA
));
296 CopyMem (&OpenData
.IpConfigData
, &mIpIoDefaultIpConfigData
, sizeof (OpenData
.IpConfigData
));
297 OpenData
.IpConfigData
.DefaultProtocol
= EFI_IP_PROTO_TCP
;
299 OpenData
.PktRcvdNotify
= Tcp4RxCallback
;
300 Status
= IpIoOpen (TcpServiceData
->IpIo
, &OpenData
);
302 if (EFI_ERROR (Status
)) {
307 // Create the timer event used by TCP driver
309 Status
= Tcp4CreateTimer ();
310 if (EFI_ERROR (Status
)) {
312 DEBUG ((EFI_D_ERROR
, "Tcp4DriverBindingStart: Create TcpTimer"
313 " Event failed with %r\n", Status
));
319 // Install the Tcp4ServiceBinding Protocol on the
322 TcpServiceData
->Tcp4ServiceBinding
= mTcp4ServiceBinding
;
324 Status
= gBS
->InstallMultipleProtocolInterfaces (
326 &gEfiTcp4ServiceBindingProtocolGuid
,
327 &TcpServiceData
->Tcp4ServiceBinding
,
330 if (EFI_ERROR (Status
)) {
332 DEBUG ((EFI_D_ERROR
, "Tcp4DriverBindingStart: Install Tcp4 Service Binding"
333 " Protocol failed for %r\n", Status
));
340 // Initialize member in TcpServiceData
342 TcpServiceData
->ControllerHandle
= ControllerHandle
;
343 TcpServiceData
->Signature
= TCP4_DRIVER_SIGNATURE
;
344 TcpServiceData
->DriverBindingHandle
= This
->DriverBindingHandle
;
346 InitializeListHead (&TcpServiceData
->SocketList
);
348 TcpSetVariableData (TcpServiceData
);
354 if (TcpServiceData
->IpIo
!= NULL
) {
355 IpIoDestroy (TcpServiceData
->IpIo
);
358 gBS
->FreePool (TcpServiceData
);
365 Stop this driver on ControllerHandle.
367 @param This Protocol instance pointer.
368 @param ControllerHandle Handle of device to stop driver on.
369 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number
370 of children is zero stop the entire bus driver.
371 @param ChildHandleBuffer List of Child Handles to Stop.
373 @retval EFI_SUCCESS This driver is removed from ControllerHandle.
374 @retval other This driver is not removed from ControllerHandle.
379 Tcp4DriverBindingStop (
380 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
381 IN EFI_HANDLE ControllerHandle
,
382 IN UINTN NumberOfChildren
,
383 IN EFI_HANDLE
*ChildHandleBuffer
387 EFI_HANDLE NicHandle
;
388 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
389 TCP4_SERVICE_DATA
*TcpServiceData
;
392 // Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.
394 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiIp4ProtocolGuid
);
395 if (NicHandle
== NULL
) {
396 return EFI_DEVICE_ERROR
;
400 // Retrieve the TCP driver Data Structure
402 Status
= gBS
->OpenProtocol (
404 &gEfiTcp4ServiceBindingProtocolGuid
,
405 (VOID
**) &ServiceBinding
,
406 This
->DriverBindingHandle
,
408 EFI_OPEN_PROTOCOL_GET_PROTOCOL
410 if (EFI_ERROR (Status
)) {
412 DEBUG ((EFI_D_ERROR
, "Tcp4DriverBindingStop: Locate Tcp4 Service "
413 " Binding Protocol failed with %r\n", Status
));
415 return EFI_DEVICE_ERROR
;
418 TcpServiceData
= TCP4_FROM_THIS (ServiceBinding
);
420 if (NumberOfChildren
== 0) {
422 // Uninstall TCP servicebinding protocol
424 gBS
->UninstallMultipleProtocolInterfaces (
426 &gEfiTcp4ServiceBindingProtocolGuid
,
432 // Destroy the IpIO consumed by TCP driver
434 IpIoDestroy (TcpServiceData
->IpIo
);
437 // Destroy the heartbeat timer.
442 // Clear the variable.
444 TcpClearVariableData (TcpServiceData
);
447 // Release the TCP service data
449 gBS
->FreePool (TcpServiceData
);
452 while (!IsListEmpty (&TcpServiceData
->SocketList
)) {
453 Sock
= NET_LIST_HEAD (&TcpServiceData
->SocketList
, SOCKET
, Link
);
455 ServiceBinding
->DestroyChild (ServiceBinding
, Sock
->SockHandle
);
463 Open Ip4 and device path protocols for a created socket, and insert it in
466 @param This Pointer to the socket just created
467 @param Context Context of the socket
469 @retval EFI_SUCCESS This protocol is installed successfully.
470 @retval other Some error occured.
474 Tcp4CreateSocketCallback (
480 TCP4_SERVICE_DATA
*TcpServiceData
;
481 EFI_IP4_PROTOCOL
*Ip4
;
483 TcpServiceData
= ((TCP4_PROTO_DATA
*) This
->ProtoReserved
)->TcpService
;
486 // Open the default Ip4 protocol of IP_IO BY_DRIVER.
488 Status
= gBS
->OpenProtocol (
489 TcpServiceData
->IpIo
->ChildHandle
,
490 &gEfiIp4ProtocolGuid
,
492 TcpServiceData
->DriverBindingHandle
,
494 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
496 if (EFI_ERROR (Status
)) {
501 // Open the device path on the handle where service binding resides on.
503 Status
= gBS
->OpenProtocol (
504 TcpServiceData
->ControllerHandle
,
505 &gEfiDevicePathProtocolGuid
,
506 (VOID
**) &This
->ParentDevicePath
,
507 TcpServiceData
->DriverBindingHandle
,
509 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
511 if (EFI_ERROR (Status
)) {
513 TcpServiceData
->IpIo
->ChildHandle
,
514 &gEfiIp4ProtocolGuid
,
515 TcpServiceData
->DriverBindingHandle
,
520 // Insert this socket into the SocketList.
522 InsertTailList (&TcpServiceData
->SocketList
, &This
->Link
);
529 Close Ip4 and device path protocols for a socket, and remove it from socket list.
531 @param This Pointer to the socket to be removed
532 @param Context Context of the socket
536 Tcp4DestroySocketCallback (
541 TCP4_SERVICE_DATA
*TcpServiceData
;
543 TcpServiceData
= ((TCP4_PROTO_DATA
*) This
->ProtoReserved
)->TcpService
;
546 // Remove this node from the list.
548 RemoveEntryList (&This
->Link
);
551 // Close the device path protocol
554 TcpServiceData
->ControllerHandle
,
555 &gEfiDevicePathProtocolGuid
,
556 TcpServiceData
->DriverBindingHandle
,
561 // Close the Ip4 protocol.
564 TcpServiceData
->IpIo
->ChildHandle
,
565 &gEfiIp4ProtocolGuid
,
566 TcpServiceData
->DriverBindingHandle
,
572 Creates a child handle with a set of TCP4 services.
574 @param This Protocol instance pointer.
575 @param ChildHandle Pointer to the handle of the child to create. If
576 it is NULL, then a new handle is created. If it is
577 not NULL, then the I/O services are added to the
578 existing child handle.
580 @retval EFI_SUCCESS The child handle is created.
581 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
582 @retval EFI_OUT_OF_RESOURCES There are not enough resources to create the
588 Tcp4ServiceBindingCreateChild (
589 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
590 IN EFI_HANDLE
*ChildHandle
594 TCP4_SERVICE_DATA
*TcpServiceData
;
595 TCP4_PROTO_DATA TcpProto
;
599 if (NULL
== This
|| NULL
== ChildHandle
) {
600 return EFI_INVALID_PARAMETER
;
603 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
604 Status
= EFI_SUCCESS
;
605 TcpServiceData
= TCP4_FROM_THIS (This
);
606 TcpProto
.TcpService
= TcpServiceData
;
607 TcpProto
.TcpPcb
= NULL
;
610 // Create a tcp instance with defualt Tcp default
611 // sock init data and TcpProto
613 mTcp4DefaultSockData
.ProtoData
= &TcpProto
;
614 mTcp4DefaultSockData
.DataSize
= sizeof (TCP4_PROTO_DATA
);
615 mTcp4DefaultSockData
.DriverBinding
= TcpServiceData
->DriverBindingHandle
;
617 Sock
= SockCreateChild (&mTcp4DefaultSockData
);
619 DEBUG ((EFI_D_ERROR
, "Tcp4DriverBindingCreateChild: "
620 "No resource to create a Tcp Child\n"));
622 Status
= EFI_OUT_OF_RESOURCES
;
624 *ChildHandle
= Sock
->SockHandle
;
627 gBS
->RestoreTPL (OldTpl
);
633 Destroys a child handle with a set of UDP4 services.
635 @param This Protocol instance pointer.
636 @param ChildHandle Handle of the child to be destroyed.
638 @retval EFI_SUCCESS The TCP4 services are removed from the child
640 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
641 @retval other The child handle is not destroyed.
646 Tcp4ServiceBindingDestroyChild (
647 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
648 IN EFI_HANDLE ChildHandle
652 EFI_TCP4_PROTOCOL
*Tcp4
;
656 if (NULL
== This
|| NULL
== ChildHandle
) {
657 return EFI_INVALID_PARAMETER
;
660 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
663 // retrieve the Tcp4 protocol from ChildHandle
665 Status
= gBS
->OpenProtocol (
667 &gEfiTcp4ProtocolGuid
,
669 mTcp4DriverBinding
.DriverBindingHandle
,
671 EFI_OPEN_PROTOCOL_GET_PROTOCOL
673 if (EFI_ERROR (Status
)) {
674 Status
= EFI_UNSUPPORTED
;
677 // destroy this sock and related Tcp protocol control
680 Sock
= SOCK_FROM_THIS (Tcp4
);
682 SockDestroyChild (Sock
);
685 gBS
->RestoreTPL (OldTpl
);