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.
97 if (mTcp4Timer
.RefCnt
== 0) {
99 Status
= gBS
->CreateEvent (
100 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
104 &mTcp4Timer
.TimerEvent
106 if (!EFI_ERROR (Status
)) {
108 Status
= gBS
->SetTimer (
109 mTcp4Timer
.TimerEvent
,
111 (UINT64
) (TICKS_PER_SECOND
/ TCP_TICK_HZ
)
116 if (!EFI_ERROR (Status
)) {
126 Stop and destroy the heartbeat timer for TCP driver.
139 ASSERT (mTcp4Timer
.RefCnt
> 0);
143 if (mTcp4Timer
.RefCnt
> 0) {
147 gBS
->SetTimer (mTcp4Timer
.TimerEvent
, TimerCancel
, 0);
148 gBS
->CloseEvent (mTcp4Timer
.TimerEvent
);
149 mTcp4Timer
.TimerEvent
= NULL
;
155 Tcp4DriverEntryPoint (
156 IN EFI_HANDLE ImageHandle
,
157 IN EFI_SYSTEM_TABLE
*SystemTable
163 The entry point for Tcp4 driver. used to install
164 Tcp4 driver on the ImageHandle.
168 ImageHandle - The firmware allocated handle for this
170 SystemTable - Pointer to the EFI system table.
174 EFI_SUCCESS - Driver loaded.
175 other - Driver not loaded.
183 // Install the TCP4 Driver Binding Protocol
185 Status
= EfiLibInstallDriverBindingComponentName2 (
193 ASSERT_EFI_ERROR (Status
);
195 // Initialize ISS and random port.
197 Seed
= NetRandomInitSeed ();
198 mTcpGlobalIss
= NET_RANDOM (Seed
) % mTcpGlobalIss
;
199 mTcp4RandomPort
= (UINT16
) ( TCP4_PORT_KNOWN
+
200 (UINT16
) (NET_RANDOM(Seed
) % TCP4_PORT_KNOWN
));
207 Test to see if this driver supports ControllerHandle.
209 @param This Protocol instance pointer.
210 @param ControllerHandle Handle of device to test.
211 @param RemainingDevicePath Optional parameter use to pick a specific child
214 @retval EFI_SUCCESS This driver supports this device.
215 @retval EFI_ALREADY_STARTED This driver is already running on this device.
216 @retval other This driver does not support this device.
221 Tcp4DriverBindingSupported (
222 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
223 IN EFI_HANDLE ControllerHandle
,
224 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath OPTIONAL
230 // Test for the Tcp4ServiceBinding Protocol
232 Status
= gBS
->OpenProtocol (
234 &gEfiTcp4ServiceBindingProtocolGuid
,
236 This
->DriverBindingHandle
,
238 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
240 if (!EFI_ERROR (Status
)) {
241 return EFI_ALREADY_STARTED
;
245 // Test for the Ip4 Protocol
247 Status
= gBS
->OpenProtocol (
249 &gEfiIp4ServiceBindingProtocolGuid
,
251 This
->DriverBindingHandle
,
253 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
261 Start this driver on ControllerHandle.
263 @param This Protocol instance pointer.
264 @param ControllerHandle Handle of device to bind driver to.
265 @param RemainingDevicePath Optional parameter use to pick a specific child
268 @retval EFI_SUCCESS The driver is added to ControllerHandle.
269 @retval EFI_OUT_OF_RESOURCES There are not enough resources to start the
271 @retval other The driver cannot be added to ControllerHandle.
276 Tcp4DriverBindingStart (
277 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
278 IN EFI_HANDLE ControllerHandle
,
279 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath OPTIONAL
283 TCP4_SERVICE_DATA
*TcpServiceData
;
284 IP_IO_OPEN_DATA OpenData
;
286 TcpServiceData
= NetAllocateZeroPool (sizeof (TCP4_SERVICE_DATA
));
288 if (NULL
== TcpServiceData
) {
289 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Have no enough"
290 " resource to create a Tcp Servcie Data!\n"));
292 return EFI_OUT_OF_RESOURCES
;
296 // Create a new IP IO to Consume it
298 TcpServiceData
->IpIo
= IpIoCreate (This
->DriverBindingHandle
, ControllerHandle
);
299 if (NULL
== TcpServiceData
->IpIo
) {
301 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Have no enough"
302 " resource to create an Ip Io!\n"));
304 Status
= EFI_OUT_OF_RESOURCES
;
309 // Configure and start IpIo.
311 NetZeroMem (&OpenData
, sizeof (IP_IO_OPEN_DATA
));
313 CopyMem (&OpenData
.IpConfigData
, &mIpIoDefaultIpConfigData
, sizeof (OpenData
.IpConfigData
));
314 OpenData
.IpConfigData
.DefaultProtocol
= EFI_IP_PROTO_TCP
;
316 OpenData
.PktRcvdNotify
= Tcp4RxCallback
;
317 Status
= IpIoOpen (TcpServiceData
->IpIo
, &OpenData
);
319 if (EFI_ERROR (Status
)) {
324 // Create the timer event used by TCP driver
326 Status
= Tcp4CreateTimer ();
327 if (EFI_ERROR (Status
)) {
329 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Create TcpTimer"
330 " Event failed with %r\n", Status
));
336 // Install the Tcp4ServiceBinding Protocol on the
339 TcpServiceData
->Tcp4ServiceBinding
= mTcp4ServiceBinding
;
341 Status
= gBS
->InstallMultipleProtocolInterfaces (
343 &gEfiTcp4ServiceBindingProtocolGuid
,
344 &TcpServiceData
->Tcp4ServiceBinding
,
347 if (EFI_ERROR (Status
)) {
349 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Install Tcp4 Service Binding"
350 " Protocol failed for %r\n", Status
));
357 // Initialize member in TcpServiceData
359 TcpServiceData
->ControllerHandle
= ControllerHandle
;
360 TcpServiceData
->Signature
= TCP4_DRIVER_SIGNATURE
;
361 TcpServiceData
->DriverBindingHandle
= This
->DriverBindingHandle
;
363 NetListInit (&TcpServiceData
->SocketList
);
365 TcpSetVariableData (TcpServiceData
);
371 if (TcpServiceData
->IpIo
!= NULL
) {
372 IpIoDestroy (TcpServiceData
->IpIo
);
375 NetFreePool (TcpServiceData
);
382 Stop this driver on ControllerHandle.
384 @param This Protocol instance pointer.
385 @param ControllerHandle Handle of device to stop driver on.
386 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number
387 of children is zero stop the entire bus driver.
388 @param ChildHandleBuffer List of Child Handles to Stop.
390 @retval EFI_SUCCESS This driver is removed from ControllerHandle.
391 @retval other This driver is not removed from ControllerHandle.
396 Tcp4DriverBindingStop (
397 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
398 IN EFI_HANDLE ControllerHandle
,
399 IN UINTN NumberOfChildren
,
400 IN EFI_HANDLE
*ChildHandleBuffer
404 EFI_HANDLE NicHandle
;
405 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
406 TCP4_SERVICE_DATA
*TcpServiceData
;
409 // Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.
411 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiIp4ProtocolGuid
);
412 if (NicHandle
== NULL
) {
413 return EFI_DEVICE_ERROR
;
417 // Retrieve the TCP driver Data Structure
419 Status
= gBS
->OpenProtocol (
421 &gEfiTcp4ServiceBindingProtocolGuid
,
422 (VOID
**) &ServiceBinding
,
423 This
->DriverBindingHandle
,
425 EFI_OPEN_PROTOCOL_GET_PROTOCOL
427 if (EFI_ERROR (Status
)) {
429 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Locate Tcp4 Service "
430 " Binding Protocol failed with %r\n", Status
));
432 return EFI_DEVICE_ERROR
;
435 TcpServiceData
= TCP4_FROM_THIS (ServiceBinding
);
437 if (NumberOfChildren
== 0) {
439 // Uninstall TCP servicebinding protocol
441 gBS
->UninstallMultipleProtocolInterfaces (
443 &gEfiTcp4ServiceBindingProtocolGuid
,
449 // Destroy the IpIO consumed by TCP driver
451 IpIoDestroy (TcpServiceData
->IpIo
);
454 // Destroy the heartbeat timer.
459 // Clear the variable.
461 TcpClearVariableData (TcpServiceData
);
464 // Release the TCP service data
466 NetFreePool (TcpServiceData
);
469 while (!NetListIsEmpty (&TcpServiceData
->SocketList
)) {
470 Sock
= NET_LIST_HEAD (&TcpServiceData
->SocketList
, SOCKET
, Link
);
472 ServiceBinding
->DestroyChild (ServiceBinding
, Sock
->SockHandle
);
480 Tcp4CreateSocketCallback (
486 TCP4_SERVICE_DATA
*TcpServiceData
;
487 EFI_IP4_PROTOCOL
*Ip4
;
489 TcpServiceData
= ((TCP4_PROTO_DATA
*) This
->ProtoReserved
)->TcpService
;
492 // Open the default Ip4 protocol of IP_IO BY_DRIVER.
494 Status
= gBS
->OpenProtocol (
495 TcpServiceData
->IpIo
->ChildHandle
,
496 &gEfiIp4ProtocolGuid
,
498 TcpServiceData
->DriverBindingHandle
,
500 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
502 if (EFI_ERROR (Status
)) {
507 // Open the device path on the handle where service binding resides on.
509 Status
= gBS
->OpenProtocol (
510 TcpServiceData
->ControllerHandle
,
511 &gEfiDevicePathProtocolGuid
,
512 (VOID
**) &This
->ParentDevicePath
,
513 TcpServiceData
->DriverBindingHandle
,
515 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
517 if (EFI_ERROR (Status
)) {
519 TcpServiceData
->IpIo
->ChildHandle
,
520 &gEfiIp4ProtocolGuid
,
521 TcpServiceData
->DriverBindingHandle
,
526 // Insert this socket into the SocketList.
528 NetListInsertTail (&TcpServiceData
->SocketList
, &This
->Link
);
535 Tcp4DestroySocketCallback (
540 TCP4_SERVICE_DATA
*TcpServiceData
;
542 TcpServiceData
= ((TCP4_PROTO_DATA
*) This
->ProtoReserved
)->TcpService
;
545 // Remove this node from the list.
547 NetListRemoveEntry (&This
->Link
);
550 // Close the device path protocol
553 TcpServiceData
->ControllerHandle
,
554 &gEfiDevicePathProtocolGuid
,
555 TcpServiceData
->DriverBindingHandle
,
560 // Close the Ip4 protocol.
563 TcpServiceData
->IpIo
->ChildHandle
,
564 &gEfiIp4ProtocolGuid
,
565 TcpServiceData
->DriverBindingHandle
,
571 Creates a child handle with a set of TCP4 services.
573 @param This Protocol instance pointer.
574 @param ChildHandle Pointer to the handle of the child to create. If
575 it is NULL, then a new handle is created. If it is
576 not NULL, then the I/O services are added to the
577 existing child handle.
579 @retval EFI_SUCCESS The child handle is created.
580 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
581 @retval EFI_OUT_OF_RESOURCES There are not enough resources to create the
587 Tcp4ServiceBindingCreateChild (
588 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
589 IN EFI_HANDLE
*ChildHandle
593 TCP4_SERVICE_DATA
*TcpServiceData
;
594 TCP4_PROTO_DATA TcpProto
;
598 if (NULL
== This
|| NULL
== ChildHandle
) {
599 return EFI_INVALID_PARAMETER
;
602 OldTpl
= NET_RAISE_TPL (NET_TPL_LOCK
);
603 Status
= EFI_SUCCESS
;
604 TcpServiceData
= TCP4_FROM_THIS (This
);
605 TcpProto
.TcpService
= TcpServiceData
;
606 TcpProto
.TcpPcb
= NULL
;
609 // Create a tcp instance with defualt Tcp default
610 // sock init data and TcpProto
612 mTcp4DefaultSockData
.ProtoData
= &TcpProto
;
613 mTcp4DefaultSockData
.DataSize
= sizeof (TCP4_PROTO_DATA
);
614 mTcp4DefaultSockData
.DriverBinding
= TcpServiceData
->DriverBindingHandle
;
616 Sock
= SockCreateChild (&mTcp4DefaultSockData
);
618 TCP4_DEBUG_ERROR (("Tcp4DriverBindingCreateChild: "
619 "No resource to create a Tcp Child\n"));
621 Status
= EFI_OUT_OF_RESOURCES
;
623 *ChildHandle
= Sock
->SockHandle
;
626 NET_RESTORE_TPL (OldTpl
);
632 Destroys a child handle with a set of UDP4 services.
634 @param This Protocol instance pointer.
635 @param ChildHandle Handle of the child to be destroyed.
637 @retval EFI_SUCCESS The TCP4 services are removed from the child
639 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
640 @retval other The child handle is not destroyed.
645 Tcp4ServiceBindingDestroyChild (
646 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
647 IN EFI_HANDLE ChildHandle
651 EFI_TCP4_PROTOCOL
*Tcp4
;
655 if (NULL
== This
|| NULL
== ChildHandle
) {
656 return EFI_INVALID_PARAMETER
;
659 OldTpl
= NET_RAISE_TPL (NET_TPL_LOCK
);
662 // retrieve the Tcp4 protocol from ChildHandle
664 Status
= gBS
->OpenProtocol (
666 &gEfiTcp4ProtocolGuid
,
668 mTcp4DriverBinding
.DriverBindingHandle
,
670 EFI_OPEN_PROTOCOL_GET_PROTOCOL
672 if (EFI_ERROR (Status
)) {
673 Status
= EFI_UNSUPPORTED
;
676 // destroy this sock and related Tcp protocol control
679 Sock
= SOCK_FROM_THIS (Tcp4
);
681 SockDestroyChild (Sock
);
684 NET_RESTORE_TPL (OldTpl
);