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
,
58 EFI_DRIVER_BINDING_PROTOCOL mTcp4DriverBinding
= {
59 Tcp4DriverBindingSupported
,
60 Tcp4DriverBindingStart
,
61 Tcp4DriverBindingStop
,
67 EFI_SERVICE_BINDING_PROTOCOL mTcp4ServiceBinding
= {
68 Tcp4ServiceBindingCreateChild
,
69 Tcp4ServiceBindingDestroyChild
74 Create and start the heartbeat timer for TCP driver.
78 @retval EFI_SUCCESS The timer is successfully created and started.
79 @retval other The timer is not created.
92 if (mTcp4Timer
.RefCnt
== 0) {
94 Status
= gBS
->CreateEvent (
95 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
99 &mTcp4Timer
.TimerEvent
101 if (!EFI_ERROR (Status
)) {
103 Status
= gBS
->SetTimer (
104 mTcp4Timer
.TimerEvent
,
106 (UINT64
) (TICKS_PER_SECOND
/ TCP_TICK_HZ
)
111 if (!EFI_ERROR (Status
)) {
121 Stop and destroy the heartbeat timer for TCP driver.
134 ASSERT (mTcp4Timer
.RefCnt
> 0);
138 if (mTcp4Timer
.RefCnt
> 0) {
142 gBS
->SetTimer (mTcp4Timer
.TimerEvent
, TimerCancel
, 0);
143 gBS
->CloseEvent (mTcp4Timer
.TimerEvent
);
144 mTcp4Timer
.TimerEvent
= NULL
;
150 Tcp4DriverEntryPoint (
151 IN EFI_HANDLE ImageHandle
,
152 IN EFI_SYSTEM_TABLE
*SystemTable
158 The entry point for Tcp4 driver. used to install
159 Tcp4 driver on the ImageHandle.
163 ImageHandle - The firmware allocated handle for this
165 SystemTable - Pointer to the EFI system table.
169 EFI_SUCCESS - Driver loaded.
170 other - Driver not loaded.
178 // Install the TCP4 Driver Binding Protocol
180 Status
= EfiLibInstallDriverBindingComponentName2 (
188 ASSERT_EFI_ERROR (Status
);
190 // Initialize ISS and random port.
192 Seed
= NetRandomInitSeed ();
193 mTcpGlobalIss
= NET_RANDOM (Seed
) % mTcpGlobalIss
;
194 mTcp4RandomPort
= (UINT16
) ( TCP4_PORT_KNOWN
+
195 (UINT16
) (NET_RANDOM(Seed
) % TCP4_PORT_KNOWN
));
202 Test to see if this driver supports ControllerHandle.
204 @param This Protocol instance pointer.
205 @param ControllerHandle Handle of device to test.
206 @param RemainingDevicePath Optional parameter use to pick a specific child
209 @retval EFI_SUCCESS This driver supports this device.
210 @retval EFI_ALREADY_STARTED This driver is already running on this device.
211 @retval other This driver does not support this device.
216 Tcp4DriverBindingSupported (
217 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
218 IN EFI_HANDLE ControllerHandle
,
219 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath OPTIONAL
225 // Test for the Tcp4ServiceBinding Protocol
227 Status
= gBS
->OpenProtocol (
229 &gEfiTcp4ServiceBindingProtocolGuid
,
231 This
->DriverBindingHandle
,
233 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
235 if (!EFI_ERROR (Status
)) {
236 return EFI_ALREADY_STARTED
;
240 // Test for the Ip4 Protocol
242 Status
= gBS
->OpenProtocol (
244 &gEfiIp4ServiceBindingProtocolGuid
,
246 This
->DriverBindingHandle
,
248 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
256 Start this driver on ControllerHandle.
258 @param This Protocol instance pointer.
259 @param ControllerHandle Handle of device to bind driver to.
260 @param RemainingDevicePath Optional parameter use to pick a specific child
263 @retval EFI_SUCCESS The driver is added to ControllerHandle.
264 @retval EFI_OUT_OF_RESOURCES There are not enough resources to start the
266 @retval other The driver cannot be added to ControllerHandle.
271 Tcp4DriverBindingStart (
272 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
273 IN EFI_HANDLE ControllerHandle
,
274 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath OPTIONAL
278 TCP4_SERVICE_DATA
*TcpServiceData
;
279 IP_IO_OPEN_DATA OpenData
;
281 TcpServiceData
= NetAllocateZeroPool (sizeof (TCP4_SERVICE_DATA
));
283 if (NULL
== TcpServiceData
) {
284 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Have no enough"
285 " resource to create a Tcp Servcie Data!\n"));
287 return EFI_OUT_OF_RESOURCES
;
291 // Create a new IP IO to Consume it
293 TcpServiceData
->IpIo
= IpIoCreate (This
->DriverBindingHandle
, ControllerHandle
);
294 if (NULL
== TcpServiceData
->IpIo
) {
296 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Have no enough"
297 " resource to create an Ip Io!\n"));
299 Status
= EFI_OUT_OF_RESOURCES
;
300 goto ReleaseServiceData
;
304 // Configure and start IpIo.
306 NetZeroMem (&OpenData
, sizeof (IP_IO_OPEN_DATA
));
308 CopyMem (&OpenData
.IpConfigData
, &mIpIoDefaultIpConfigData
, sizeof (OpenData
.IpConfigData
));
309 OpenData
.IpConfigData
.DefaultProtocol
= EFI_IP_PROTO_TCP
;
311 OpenData
.PktRcvdNotify
= Tcp4RxCallback
;
312 Status
= IpIoOpen (TcpServiceData
->IpIo
, &OpenData
);
314 if (EFI_ERROR (Status
)) {
315 goto ReleaseServiceData
;
319 // Create the timer event used by TCP driver
321 Status
= Tcp4CreateTimer ();
322 if (EFI_ERROR (Status
)) {
324 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Create TcpTimer"
325 " Event failed with %r\n", Status
));
331 // Install the Tcp4ServiceBinding Protocol on the
334 TcpServiceData
->Tcp4ServiceBinding
= mTcp4ServiceBinding
;
336 Status
= gBS
->InstallMultipleProtocolInterfaces (
338 &gEfiTcp4ServiceBindingProtocolGuid
,
339 &TcpServiceData
->Tcp4ServiceBinding
,
342 if (EFI_ERROR (Status
)) {
344 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Install Tcp4 Service Binding"
345 " Protocol failed for %r\n", Status
));
351 // Initialize member in TcpServiceData
353 TcpServiceData
->ControllerHandle
= ControllerHandle
;
354 TcpServiceData
->Signature
= TCP4_DRIVER_SIGNATURE
;
355 TcpServiceData
->DriverBindingHandle
= This
->DriverBindingHandle
;
357 TcpSetVariableData (TcpServiceData
);
367 IpIoDestroy (TcpServiceData
->IpIo
);
371 NetFreePool (TcpServiceData
);
378 Stop this driver on ControllerHandle.
380 @param This Protocol instance pointer.
381 @param ControllerHandle Handle of device to stop driver on.
382 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number
383 of children is zero stop the entire bus driver.
384 @param ChildHandleBuffer List of Child Handles to Stop.
386 @retval EFI_SUCCESS This driver is removed from ControllerHandle.
387 @retval other This driver is not removed from ControllerHandle.
392 Tcp4DriverBindingStop (
393 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
394 IN EFI_HANDLE ControllerHandle
,
395 IN UINTN NumberOfChildren
,
396 IN EFI_HANDLE
*ChildHandleBuffer
400 EFI_HANDLE NicHandle
;
401 EFI_SERVICE_BINDING_PROTOCOL
*Tcp4ServiceBinding
;
402 TCP4_SERVICE_DATA
*TcpServiceData
;
405 TCP4_PROTO_DATA
*TcpProto
;
406 NET_LIST_ENTRY
*Entry
;
407 NET_LIST_ENTRY
*NextEntry
;
409 // Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.
411 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiIp4ProtocolGuid
);
412 if (NicHandle
== NULL
) {
417 // Retrieve the TCP driver Data Structure
419 Status
= gBS
->OpenProtocol (
421 &gEfiTcp4ServiceBindingProtocolGuid
,
422 (VOID
**) &Tcp4ServiceBinding
,
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
));
435 TcpServiceData
= TCP4_FROM_THIS (Tcp4ServiceBinding
);
440 NET_LIST_FOR_EACH_SAFE (Entry
, NextEntry
, &mTcpRunQue
) {
441 TcpPcb
= NET_LIST_USER_STRUCT (Entry
, TCP_CB
, List
);
444 // Try to destroy this child
447 TcpProto
= (TCP4_PROTO_DATA
*) Sock
->ProtoReserved
;
449 if (TcpProto
->TcpService
== TcpServiceData
) {
450 Status
= SockDestroyChild (Sock
);
452 if (EFI_ERROR (Status
)) {
454 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Destroy Tcp "
455 "instance failed with %r\n", Status
));
461 NET_LIST_FOR_EACH_SAFE (Entry
, NextEntry
, &mTcpListenQue
) {
462 TcpPcb
= NET_LIST_USER_STRUCT (Entry
, TCP_CB
, List
);
465 // Try to destroy this child
468 TcpProto
= (TCP4_PROTO_DATA
*) Sock
->ProtoReserved
;
470 if (TcpProto
->TcpService
== TcpServiceData
) {
471 Status
= SockDestroyChild (TcpPcb
->Sk
);
472 if (EFI_ERROR (Status
)) {
474 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Destroy Tcp "
475 "instance failed with %r\n", Status
));
482 // Uninstall TCP servicebinding protocol
484 Status
= gBS
->UninstallMultipleProtocolInterfaces (
486 &gEfiTcp4ServiceBindingProtocolGuid
,
490 if (EFI_ERROR (Status
)) {
492 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Uninstall TCP service "
493 "binding protocol failed with %r\n", Status
));
498 // Destroy the IpIO consumed by TCP driver
500 Status
= IpIoDestroy (TcpServiceData
->IpIo
);
503 // Destroy the heartbeat timer.
508 // Clear the variable.
510 TcpClearVariableData (TcpServiceData
);
513 // Release the TCP service data
515 NetFreePool (TcpServiceData
);
522 Creates a child handle with a set of TCP4 services.
524 @param This Protocol instance pointer.
525 @param ChildHandle Pointer to the handle of the child to create. If
526 it is NULL, then a new handle is created. If it is
527 not NULL, then the I/O services are added to the
528 existing child handle.
530 @retval EFI_SUCCESS The child handle is created.
531 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
532 @retval EFI_OUT_OF_RESOURCES There are not enough resources to create the
538 Tcp4ServiceBindingCreateChild (
539 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
540 IN EFI_HANDLE
*ChildHandle
544 TCP4_SERVICE_DATA
*TcpServiceData
;
545 TCP4_PROTO_DATA TcpProto
;
550 if (NULL
== This
|| NULL
== ChildHandle
) {
551 return EFI_INVALID_PARAMETER
;
554 OldTpl
= NET_RAISE_TPL (NET_TPL_LOCK
);
555 TcpServiceData
= TCP4_FROM_THIS (This
);
556 TcpProto
.TcpService
= TcpServiceData
;
557 TcpProto
.TcpPcb
= NULL
;
560 // Create a tcp instance with defualt Tcp default
561 // sock init data and TcpProto
563 mTcp4DefaultSockData
.DriverBinding
= TcpServiceData
->DriverBindingHandle
;
565 Sock
= SockCreateChild (&mTcp4DefaultSockData
, &TcpProto
, sizeof (TCP4_PROTO_DATA
));
567 TCP4_DEBUG_ERROR (("Tcp4DriverBindingCreateChild: "
568 "No resource to create a Tcp Child\n"));
570 Status
= EFI_OUT_OF_RESOURCES
;
574 *ChildHandle
= Sock
->SockHandle
;
577 // Open the default Ip4 protocol of IP_IO BY_DRIVER.
579 Status
= gBS
->OpenProtocol (
580 TcpServiceData
->IpIo
->ChildHandle
,
581 &gEfiIp4ProtocolGuid
,
583 TcpServiceData
->DriverBindingHandle
,
585 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
587 if (EFI_ERROR (Status
)) {
588 SockDestroyChild (Sock
);
593 // Open the device path on the handle where service binding resides on.
595 Status
= gBS
->OpenProtocol (
596 TcpServiceData
->ControllerHandle
,
597 &gEfiDevicePathProtocolGuid
,
598 (VOID
**) &Sock
->ParentDevicePath
,
599 TcpServiceData
->DriverBindingHandle
,
601 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
603 if (EFI_ERROR (Status
)) {
605 TcpServiceData
->IpIo
->ChildHandle
,
606 &gEfiIp4ProtocolGuid
,
607 TcpServiceData
->DriverBindingHandle
,
610 SockDestroyChild (Sock
);
614 NET_RESTORE_TPL (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
;
641 TCP4_PROTO_DATA
*TcpProtoData
;
642 TCP4_SERVICE_DATA
*TcpServiceData
;
645 if (NULL
== This
|| NULL
== ChildHandle
) {
646 return EFI_INVALID_PARAMETER
;
649 OldTpl
= NET_RAISE_TPL (NET_TPL_LOCK
);
652 // retrieve the Tcp4 protocol from ChildHandle
654 Status
= gBS
->OpenProtocol (
656 &gEfiTcp4ProtocolGuid
,
658 mTcp4DriverBinding
.DriverBindingHandle
,
660 EFI_OPEN_PROTOCOL_GET_PROTOCOL
662 if (EFI_ERROR (Status
)) {
663 Status
= EFI_UNSUPPORTED
;
668 // destroy this sock and related Tcp protocol control
671 Sock
= SOCK_FROM_THIS (Tcp4
);
672 TcpProtoData
= (TCP4_PROTO_DATA
*) Sock
->ProtoReserved
;
673 TcpServiceData
= TcpProtoData
->TcpService
;
675 Status
= SockDestroyChild (Sock
);
678 // Close the device path protocol
681 TcpServiceData
->ControllerHandle
,
682 &gEfiDevicePathProtocolGuid
,
683 TcpServiceData
->DriverBindingHandle
,
688 // Close the Ip4 protocol.
691 TcpServiceData
->IpIo
->ChildHandle
,
692 &gEfiIp4ProtocolGuid
,
693 TcpServiceData
->DriverBindingHandle
,
698 NET_RESTORE_TPL (OldTpl
);