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
;
27 TCP4_HEARTBEAT_TIMER mTcp4Timer
= {
32 EFI_TCP4_PROTOCOL mTcp4ProtocolTemplate
= {
45 SOCK_INIT_DATA mTcp4DefaultSockData
= {
52 &mTcp4ProtocolTemplate
,
57 EFI_DRIVER_BINDING_PROTOCOL mTcp4DriverBinding
= {
58 Tcp4DriverBindingSupported
,
59 Tcp4DriverBindingStart
,
60 Tcp4DriverBindingStop
,
66 EFI_SERVICE_BINDING_PROTOCOL mTcp4ServiceBinding
= {
67 Tcp4ServiceBindingCreateChild
,
68 Tcp4ServiceBindingDestroyChild
73 Create and start the heartbeat timer for TCP driver.
77 @retval EFI_SUCCESS The timer is successfully created and started.
78 @retval other The timer is not created.
91 if (mTcp4Timer
.RefCnt
== 0) {
93 Status
= gBS
->CreateEvent (
94 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
98 &mTcp4Timer
.TimerEvent
100 if (!EFI_ERROR (Status
)) {
102 Status
= gBS
->SetTimer (
103 mTcp4Timer
.TimerEvent
,
105 (UINT64
) (TICKS_PER_SECOND
/ TCP_TICK_HZ
)
110 if (!EFI_ERROR (Status
)) {
120 Stop and destroy the heartbeat timer for TCP driver.
133 ASSERT (mTcp4Timer
.RefCnt
> 0);
137 if (mTcp4Timer
.RefCnt
> 0) {
141 gBS
->SetTimer (mTcp4Timer
.TimerEvent
, TimerCancel
, 0);
142 gBS
->CloseEvent (mTcp4Timer
.TimerEvent
);
143 mTcp4Timer
.TimerEvent
= NULL
;
146 //@MT: EFI_DRIVER_ENTRY_POINT (Tcp4DriverEntryPoint)
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
= NetLibInstallAllDriverProtocols (
191 // Initialize ISS and random port.
193 Seed
= NetRandomInitSeed ();
194 mTcpGlobalIss
= NET_RANDOM (Seed
) % mTcpGlobalIss
;
195 mTcp4RandomPort
= TCP4_PORT_KNOWN
+
196 (UINT16
) (NET_RANDOM(Seed
) % TCP4_PORT_KNOWN
);
203 Test to see if this driver supports ControllerHandle.
205 @param This Protocol instance pointer.
206 @param ControllerHandle Handle of device to test.
207 @param RemainingDevicePath Optional parameter use to pick a specific child
210 @retval EFI_SUCCESS This driver supports this device.
211 @retval EFI_ALREADY_STARTED This driver is already running on this device.
212 @retval other This driver does not support this device.
217 Tcp4DriverBindingSupported (
218 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
219 IN EFI_HANDLE ControllerHandle
,
220 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath OPTIONAL
226 // Test for the Tcp4ServiceBinding Protocol
228 Status
= gBS
->OpenProtocol (
230 &gEfiTcp4ServiceBindingProtocolGuid
,
232 This
->DriverBindingHandle
,
234 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
236 if (!EFI_ERROR (Status
)) {
237 return EFI_ALREADY_STARTED
;
241 // Test for the Ip4 Protocol
243 Status
= gBS
->OpenProtocol (
245 &gEfiIp4ServiceBindingProtocolGuid
,
247 This
->DriverBindingHandle
,
249 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
257 Start this driver on ControllerHandle.
259 @param This Protocol instance pointer.
260 @param ControllerHandle Handle of device to bind driver to.
261 @param RemainingDevicePath Optional parameter use to pick a specific child
264 @retval EFI_SUCCESS The driver is added to ControllerHandle.
265 @retval EFI_OUT_OF_RESOURCES There are not enough resources to start the
267 @retval other The driver cannot be added to ControllerHandle.
272 Tcp4DriverBindingStart (
273 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
274 IN EFI_HANDLE ControllerHandle
,
275 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath OPTIONAL
279 TCP4_SERVICE_DATA
*TcpServiceData
;
280 IP_IO_OPEN_DATA OpenData
;
282 TcpServiceData
= NetAllocateZeroPool (sizeof (TCP4_SERVICE_DATA
));
284 if (NULL
== TcpServiceData
) {
285 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Have no enough"
286 " resource to create a Tcp Servcie Data!\n"));
288 return EFI_OUT_OF_RESOURCES
;
292 // Create a new IP IO to Consume it
294 TcpServiceData
->IpIo
= IpIoCreate (This
->DriverBindingHandle
, ControllerHandle
);
295 if (NULL
== TcpServiceData
->IpIo
) {
297 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Have no enough"
298 " resource to create an Ip Io!\n"));
300 Status
= EFI_OUT_OF_RESOURCES
;
301 goto ReleaseServiceData
;
305 // Configure and start IpIo.
307 NetZeroMem (&OpenData
, sizeof (IP_IO_OPEN_DATA
));
309 OpenData
.IpConfigData
= mIpIoDefaultIpConfigData
;
310 OpenData
.IpConfigData
.DefaultProtocol
= EFI_IP_PROTO_TCP
;
312 OpenData
.PktRcvdNotify
= Tcp4RxCallback
;
313 Status
= IpIoOpen (TcpServiceData
->IpIo
, &OpenData
);
315 if (EFI_ERROR (Status
)) {
316 goto ReleaseServiceData
;
320 // Create the timer event used by TCP driver
322 Status
= Tcp4CreateTimer ();
323 if (EFI_ERROR (Status
)) {
325 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Create TcpTimer"
326 " Event failed with %r\n", Status
));
332 // Install the Tcp4ServiceBinding Protocol on the
335 TcpServiceData
->Tcp4ServiceBinding
= mTcp4ServiceBinding
;
337 Status
= gBS
->InstallMultipleProtocolInterfaces (
339 &gEfiTcp4ServiceBindingProtocolGuid
,
340 &TcpServiceData
->Tcp4ServiceBinding
,
343 if (EFI_ERROR (Status
)) {
345 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Install Tcp4 Service Binding"
346 " Protocol failed for %r\n", Status
));
352 // Initialize member in TcpServiceData
354 TcpServiceData
->ControllerHandle
= ControllerHandle
;
355 TcpServiceData
->Signature
= TCP4_DRIVER_SIGNATURE
;
356 TcpServiceData
->DriverBindingHandle
= This
->DriverBindingHandle
;
358 TcpSetVariableData (TcpServiceData
);
368 IpIoDestroy (TcpServiceData
->IpIo
);
372 NetFreePool (TcpServiceData
);
379 Stop this driver on ControllerHandle.
381 @param This Protocol instance pointer.
382 @param ControllerHandle Handle of device to stop driver on.
383 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number
384 of children is zero stop the entire bus driver.
385 @param ChildHandleBuffer List of Child Handles to Stop.
387 @retval EFI_SUCCESS This driver is removed from ControllerHandle.
388 @retval other This driver is not removed from ControllerHandle.
393 Tcp4DriverBindingStop (
394 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
395 IN EFI_HANDLE ControllerHandle
,
396 IN UINTN NumberOfChildren
,
397 IN EFI_HANDLE
*ChildHandleBuffer
401 EFI_HANDLE NicHandle
;
402 EFI_SERVICE_BINDING_PROTOCOL
*Tcp4ServiceBinding
;
403 TCP4_SERVICE_DATA
*TcpServiceData
;
406 TCP4_PROTO_DATA
*TcpProto
;
407 NET_LIST_ENTRY
*Entry
;
408 NET_LIST_ENTRY
*NextEntry
;
410 // Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.
412 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiIp4ProtocolGuid
);
413 if (NicHandle
== NULL
) {
418 // Retrieve the TCP driver Data Structure
420 Status
= gBS
->OpenProtocol (
422 &gEfiTcp4ServiceBindingProtocolGuid
,
423 (VOID
**) &Tcp4ServiceBinding
,
424 This
->DriverBindingHandle
,
426 EFI_OPEN_PROTOCOL_GET_PROTOCOL
428 if (EFI_ERROR (Status
)) {
430 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Locate Tcp4 Service "
431 " Binding Protocol failed with %r\n", Status
));
436 TcpServiceData
= TCP4_FROM_THIS (Tcp4ServiceBinding
);
441 NET_LIST_FOR_EACH_SAFE (Entry
, NextEntry
, &mTcpRunQue
) {
442 TcpPcb
= NET_LIST_USER_STRUCT (Entry
, TCP_CB
, List
);
445 // Try to destroy this child
448 TcpProto
= (TCP4_PROTO_DATA
*) Sock
->ProtoReserved
;
450 if (TcpProto
->TcpService
== TcpServiceData
) {
451 Status
= SockDestroyChild (Sock
);
453 if (EFI_ERROR (Status
)) {
455 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Destroy Tcp "
456 "instance failed with %r\n", Status
));
462 NET_LIST_FOR_EACH_SAFE (Entry
, NextEntry
, &mTcpListenQue
) {
463 TcpPcb
= NET_LIST_USER_STRUCT (Entry
, TCP_CB
, List
);
466 // Try to destroy this child
469 TcpProto
= (TCP4_PROTO_DATA
*) Sock
->ProtoReserved
;
471 if (TcpProto
->TcpService
== TcpServiceData
) {
472 Status
= SockDestroyChild (TcpPcb
->Sk
);
473 if (EFI_ERROR (Status
)) {
475 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Destroy Tcp "
476 "instance failed with %r\n", Status
));
483 // Uninstall TCP servicebinding protocol
485 Status
= gBS
->UninstallMultipleProtocolInterfaces (
487 &gEfiTcp4ServiceBindingProtocolGuid
,
491 if (EFI_ERROR (Status
)) {
493 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Uninstall TCP service "
494 "binding protocol failed with %r\n", Status
));
499 // Destroy the IpIO consumed by TCP driver
501 Status
= IpIoDestroy (TcpServiceData
->IpIo
);
504 // Destroy the heartbeat timer.
509 // Clear the variable.
511 TcpClearVariableData (TcpServiceData
);
514 // Release the TCP service data
516 NetFreePool (TcpServiceData
);
523 Creates a child handle with a set of TCP4 services.
525 @param This Protocol instance pointer.
526 @param ChildHandle Pointer to the handle of the child to create. If
527 it is NULL, then a new handle is created. If it is
528 not NULL, then the I/O services are added to the
529 existing child handle.
531 @retval EFI_SUCCESS The child handle is created.
532 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
533 @retval EFI_OUT_OF_RESOURCES There are not enough resources to create the
539 Tcp4ServiceBindingCreateChild (
540 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
541 IN EFI_HANDLE
*ChildHandle
545 TCP4_SERVICE_DATA
*TcpServiceData
;
546 TCP4_PROTO_DATA TcpProto
;
551 if (NULL
== This
|| NULL
== ChildHandle
) {
552 return EFI_INVALID_PARAMETER
;
555 OldTpl
= NET_RAISE_TPL (NET_TPL_LOCK
);
556 TcpServiceData
= TCP4_FROM_THIS (This
);
557 TcpProto
.TcpService
= TcpServiceData
;
558 TcpProto
.TcpPcb
= NULL
;
561 // Create a tcp instance with defualt Tcp default
562 // sock init data and TcpProto
564 mTcp4DefaultSockData
.DriverBinding
= TcpServiceData
->DriverBindingHandle
;
566 Sock
= SockCreateChild (&mTcp4DefaultSockData
, &TcpProto
, sizeof (TCP4_PROTO_DATA
));
568 TCP4_DEBUG_ERROR (("Tcp4DriverBindingCreateChild: "
569 "No resource to create a Tcp Child\n"));
571 Status
= EFI_OUT_OF_RESOURCES
;
575 *ChildHandle
= Sock
->SockHandle
;
578 // Open the default Ip4 protocol of IP_IO BY_DRIVER.
580 Status
= gBS
->OpenProtocol (
581 TcpServiceData
->IpIo
->ChildHandle
,
582 &gEfiIp4ProtocolGuid
,
584 TcpServiceData
->DriverBindingHandle
,
586 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
588 if (EFI_ERROR (Status
)) {
589 SockDestroyChild (Sock
);
593 NET_RESTORE_TPL (OldTpl
);
599 Destroys a child handle with a set of UDP4 services.
601 @param This Protocol instance pointer.
602 @param ChildHandle Handle of the child to be destroyed.
604 @retval EFI_SUCCESS The TCP4 services are removed from the child
606 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
607 @retval other The child handle is not destroyed.
612 Tcp4ServiceBindingDestroyChild (
613 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
614 IN EFI_HANDLE ChildHandle
618 EFI_TCP4_PROTOCOL
*Tcp4
;
620 TCP4_PROTO_DATA
*TcpProtoData
;
621 TCP4_SERVICE_DATA
*TcpServiceData
;
624 if (NULL
== This
|| NULL
== ChildHandle
) {
625 return EFI_INVALID_PARAMETER
;
628 OldTpl
= NET_RAISE_TPL (NET_TPL_LOCK
);
631 // retrieve the Tcp4 protocol from ChildHandle
633 Status
= gBS
->OpenProtocol (
635 &gEfiTcp4ProtocolGuid
,
637 mTcp4DriverBinding
.DriverBindingHandle
,
639 EFI_OPEN_PROTOCOL_GET_PROTOCOL
641 if (EFI_ERROR (Status
)) {
642 Status
= EFI_UNSUPPORTED
;
647 // destroy this sock and related Tcp protocol control
650 Sock
= SOCK_FROM_THIS (Tcp4
);
651 TcpProtoData
= (TCP4_PROTO_DATA
*) Sock
->ProtoReserved
;
652 TcpServiceData
= TcpProtoData
->TcpService
;
654 Status
= SockDestroyChild (Sock
);
657 // Close the Ip4 protocol.
660 TcpServiceData
->IpIo
->ChildHandle
,
661 &gEfiIp4ProtocolGuid
,
662 TcpServiceData
->DriverBindingHandle
,
667 NET_RESTORE_TPL (OldTpl
);