3 Copyright (c) 2005 - 2007, Intel Corporation
\r
4 All rights reserved. This program and the accompanying materials
\r
5 are licensed and made available under the terms and conditions of the BSD License
\r
6 which accompanies this distribution. The full text of the license may be found at
\r
7 http://opensource.org/licenses/bsd-license.php
\r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
\r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
\r
21 #include "Tcp4Main.h"
\r
24 UINT16 mTcp4RandomPort;
\r
25 extern EFI_COMPONENT_NAME_PROTOCOL gTcp4ComponentName;
\r
27 TCP4_HEARTBEAT_TIMER mTcp4Timer = {
\r
32 EFI_TCP4_PROTOCOL mTcp4ProtocolTemplate = {
\r
45 SOCK_INIT_DATA mTcp4DefaultSockData = {
\r
52 &mTcp4ProtocolTemplate,
\r
57 EFI_DRIVER_BINDING_PROTOCOL mTcp4DriverBinding = {
\r
58 Tcp4DriverBindingSupported,
\r
59 Tcp4DriverBindingStart,
\r
60 Tcp4DriverBindingStop,
\r
66 EFI_SERVICE_BINDING_PROTOCOL mTcp4ServiceBinding = {
\r
67 Tcp4ServiceBindingCreateChild,
\r
68 Tcp4ServiceBindingDestroyChild
\r
73 Create and start the heartbeat timer for TCP driver.
\r
77 @retval EFI_SUCCESS The timer is successfully created and started.
\r
78 @retval other The timer is not created.
\r
89 Status = EFI_SUCCESS;
\r
91 if (mTcp4Timer.RefCnt == 0) {
\r
93 Status = gBS->CreateEvent (
\r
94 EVT_TIMER | EVT_NOTIFY_SIGNAL,
\r
98 &mTcp4Timer.TimerEvent
\r
100 if (!EFI_ERROR (Status)) {
\r
102 Status = gBS->SetTimer (
\r
103 mTcp4Timer.TimerEvent,
\r
105 (UINT64) (TICKS_PER_SECOND / TCP_TICK_HZ)
\r
110 if (!EFI_ERROR (Status)) {
\r
112 mTcp4Timer.RefCnt++;
\r
120 Stop and destroy the heartbeat timer for TCP driver.
\r
133 ASSERT (mTcp4Timer.RefCnt > 0);
\r
135 mTcp4Timer.RefCnt--;
\r
137 if (mTcp4Timer.RefCnt > 0) {
\r
141 gBS->SetTimer (mTcp4Timer.TimerEvent, TimerCancel, 0);
\r
142 gBS->CloseEvent (mTcp4Timer.TimerEvent);
\r
143 mTcp4Timer.TimerEvent = NULL;
\r
149 Tcp4DriverEntryPoint (
\r
150 IN EFI_HANDLE ImageHandle,
\r
151 IN EFI_SYSTEM_TABLE *SystemTable
\r
155 Routine Description:
\r
157 The entry point for Tcp4 driver. used to install
\r
158 Tcp4 driver on the ImageHandle.
\r
162 ImageHandle - The firmware allocated handle for this
\r
164 SystemTable - Pointer to the EFI system table.
\r
168 EFI_SUCCESS - Driver loaded.
\r
169 other - Driver not loaded.
\r
177 // Install the TCP4 Driver Binding Protocol
\r
179 Status = NetLibInstallAllDriverProtocols (
\r
182 &mTcp4DriverBinding,
\r
184 &gTcp4ComponentName,
\r
190 // Initialize ISS and random port.
\r
192 Seed = NetRandomInitSeed ();
\r
193 mTcpGlobalIss = NET_RANDOM (Seed) % mTcpGlobalIss;
\r
194 mTcp4RandomPort = (UINT16) ( TCP4_PORT_KNOWN +
\r
195 (UINT16) (NET_RANDOM(Seed) % TCP4_PORT_KNOWN));
\r
202 Test to see if this driver supports ControllerHandle.
\r
204 @param This Protocol instance pointer.
\r
205 @param ControllerHandle Handle of device to test.
\r
206 @param RemainingDevicePath Optional parameter use to pick a specific child
\r
209 @retval EFI_SUCCESS This driver supports this device.
\r
210 @retval EFI_ALREADY_STARTED This driver is already running on this device.
\r
211 @retval other This driver does not support this device.
\r
216 Tcp4DriverBindingSupported (
\r
217 IN EFI_DRIVER_BINDING_PROTOCOL * This,
\r
218 IN EFI_HANDLE ControllerHandle,
\r
219 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
\r
225 // Test for the Tcp4ServiceBinding Protocol
\r
227 Status = gBS->OpenProtocol (
\r
229 &gEfiTcp4ServiceBindingProtocolGuid,
\r
231 This->DriverBindingHandle,
\r
233 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
\r
235 if (!EFI_ERROR (Status)) {
\r
236 return EFI_ALREADY_STARTED;
\r
240 // Test for the Ip4 Protocol
\r
242 Status = gBS->OpenProtocol (
\r
244 &gEfiIp4ServiceBindingProtocolGuid,
\r
246 This->DriverBindingHandle,
\r
248 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
\r
256 Start this driver on ControllerHandle.
\r
258 @param This Protocol instance pointer.
\r
259 @param ControllerHandle Handle of device to bind driver to.
\r
260 @param RemainingDevicePath Optional parameter use to pick a specific child
\r
263 @retval EFI_SUCCESS The driver is added to ControllerHandle.
\r
264 @retval EFI_OUT_OF_RESOURCES There are not enough resources to start the
\r
266 @retval other The driver cannot be added to ControllerHandle.
\r
271 Tcp4DriverBindingStart (
\r
272 IN EFI_DRIVER_BINDING_PROTOCOL * This,
\r
273 IN EFI_HANDLE ControllerHandle,
\r
274 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
\r
278 TCP4_SERVICE_DATA *TcpServiceData;
\r
279 IP_IO_OPEN_DATA OpenData;
\r
281 TcpServiceData = NetAllocateZeroPool (sizeof (TCP4_SERVICE_DATA));
\r
283 if (NULL == TcpServiceData) {
\r
284 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Have no enough"
\r
285 " resource to create a Tcp Servcie Data!\n"));
\r
287 return EFI_OUT_OF_RESOURCES;
\r
291 // Create a new IP IO to Consume it
\r
293 TcpServiceData->IpIo = IpIoCreate (This->DriverBindingHandle, ControllerHandle);
\r
294 if (NULL == TcpServiceData->IpIo) {
\r
296 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Have no enough"
\r
297 " resource to create an Ip Io!\n"));
\r
299 Status = EFI_OUT_OF_RESOURCES;
\r
300 goto ReleaseServiceData;
\r
304 // Configure and start IpIo.
\r
306 NetZeroMem (&OpenData, sizeof (IP_IO_OPEN_DATA));
\r
308 CopyMem (&OpenData.IpConfigData, &mIpIoDefaultIpConfigData, sizeof (OpenData.IpConfigData));
\r
309 OpenData.IpConfigData.DefaultProtocol = EFI_IP_PROTO_TCP;
\r
311 OpenData.PktRcvdNotify = Tcp4RxCallback;
\r
312 Status = IpIoOpen (TcpServiceData->IpIo, &OpenData);
\r
314 if (EFI_ERROR (Status)) {
\r
315 goto ReleaseServiceData;
\r
319 // Create the timer event used by TCP driver
\r
321 Status = Tcp4CreateTimer ();
\r
322 if (EFI_ERROR (Status)) {
\r
324 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Create TcpTimer"
\r
325 " Event failed with %r\n", Status));
\r
331 // Install the Tcp4ServiceBinding Protocol on the
\r
332 // controller handle
\r
334 TcpServiceData->Tcp4ServiceBinding = mTcp4ServiceBinding;
\r
336 Status = gBS->InstallMultipleProtocolInterfaces (
\r
338 &gEfiTcp4ServiceBindingProtocolGuid,
\r
339 &TcpServiceData->Tcp4ServiceBinding,
\r
342 if (EFI_ERROR (Status)) {
\r
344 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Install Tcp4 Service Binding"
\r
345 " Protocol failed for %r\n", Status));
\r
351 // Initialize member in TcpServiceData
\r
353 TcpServiceData->ControllerHandle = ControllerHandle;
\r
354 TcpServiceData->Signature = TCP4_DRIVER_SIGNATURE;
\r
355 TcpServiceData->DriverBindingHandle = This->DriverBindingHandle;
\r
357 TcpSetVariableData (TcpServiceData);
\r
359 return EFI_SUCCESS;
\r
363 Tcp4DestroyTimer ();
\r
367 IpIoDestroy (TcpServiceData->IpIo);
\r
369 ReleaseServiceData:
\r
371 NetFreePool (TcpServiceData);
\r
378 Stop this driver on ControllerHandle.
\r
380 @param This Protocol instance pointer.
\r
381 @param ControllerHandle Handle of device to stop driver on.
\r
382 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number
\r
383 of children is zero stop the entire bus driver.
\r
384 @param ChildHandleBuffer List of Child Handles to Stop.
\r
386 @retval EFI_SUCCESS This driver is removed from ControllerHandle.
\r
387 @retval other This driver is not removed from ControllerHandle.
\r
392 Tcp4DriverBindingStop (
\r
393 IN EFI_DRIVER_BINDING_PROTOCOL *This,
\r
394 IN EFI_HANDLE ControllerHandle,
\r
395 IN UINTN NumberOfChildren,
\r
396 IN EFI_HANDLE *ChildHandleBuffer
\r
400 EFI_HANDLE NicHandle;
\r
401 EFI_SERVICE_BINDING_PROTOCOL *Tcp4ServiceBinding;
\r
402 TCP4_SERVICE_DATA *TcpServiceData;
\r
405 TCP4_PROTO_DATA *TcpProto;
\r
406 NET_LIST_ENTRY *Entry;
\r
407 NET_LIST_ENTRY *NextEntry;
\r
409 // Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.
\r
411 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);
\r
412 if (NicHandle == NULL) {
\r
413 return EFI_SUCCESS;
\r
417 // Retrieve the TCP driver Data Structure
\r
419 Status = gBS->OpenProtocol (
\r
421 &gEfiTcp4ServiceBindingProtocolGuid,
\r
422 (VOID **) &Tcp4ServiceBinding,
\r
423 This->DriverBindingHandle,
\r
425 EFI_OPEN_PROTOCOL_GET_PROTOCOL
\r
427 if (EFI_ERROR (Status)) {
\r
429 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Locate Tcp4 Service "
\r
430 " Binding Protocol failed with %r\n", Status));
\r
435 TcpServiceData = TCP4_FROM_THIS (Tcp4ServiceBinding);
\r
440 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mTcpRunQue) {
\r
441 TcpPcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);
\r
444 // Try to destroy this child
\r
447 TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
\r
449 if (TcpProto->TcpService == TcpServiceData) {
\r
450 Status = SockDestroyChild (Sock);
\r
452 if (EFI_ERROR (Status)) {
\r
454 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Destroy Tcp "
\r
455 "instance failed with %r\n", Status));
\r
461 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mTcpListenQue) {
\r
462 TcpPcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);
\r
465 // Try to destroy this child
\r
468 TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
\r
470 if (TcpProto->TcpService == TcpServiceData) {
\r
471 Status = SockDestroyChild (TcpPcb->Sk);
\r
472 if (EFI_ERROR (Status)) {
\r
474 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Destroy Tcp "
\r
475 "instance failed with %r\n", Status));
\r
482 // Uninstall TCP servicebinding protocol
\r
484 Status = gBS->UninstallMultipleProtocolInterfaces (
\r
486 &gEfiTcp4ServiceBindingProtocolGuid,
\r
487 Tcp4ServiceBinding,
\r
490 if (EFI_ERROR (Status)) {
\r
492 TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Uninstall TCP service "
\r
493 "binding protocol failed with %r\n", Status));
\r
498 // Destroy the IpIO consumed by TCP driver
\r
500 Status = IpIoDestroy (TcpServiceData->IpIo);
\r
503 // Destroy the heartbeat timer.
\r
505 Tcp4DestroyTimer ();
\r
508 // Clear the variable.
\r
510 TcpClearVariableData (TcpServiceData);
\r
513 // Release the TCP service data
\r
515 NetFreePool (TcpServiceData);
\r
522 Creates a child handle with a set of TCP4 services.
\r
524 @param This Protocol instance pointer.
\r
525 @param ChildHandle Pointer to the handle of the child to create. If
\r
526 it is NULL, then a new handle is created. If it is
\r
527 not NULL, then the I/O services are added to the
\r
528 existing child handle.
\r
530 @retval EFI_SUCCESS The child handle is created.
\r
531 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
\r
532 @retval EFI_OUT_OF_RESOURCES There are not enough resources to create the
\r
538 Tcp4ServiceBindingCreateChild (
\r
539 IN EFI_SERVICE_BINDING_PROTOCOL *This,
\r
540 IN EFI_HANDLE *ChildHandle
\r
544 TCP4_SERVICE_DATA *TcpServiceData;
\r
545 TCP4_PROTO_DATA TcpProto;
\r
550 if (NULL == This || NULL == ChildHandle) {
\r
551 return EFI_INVALID_PARAMETER;
\r
554 OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
\r
555 TcpServiceData = TCP4_FROM_THIS (This);
\r
556 TcpProto.TcpService = TcpServiceData;
\r
557 TcpProto.TcpPcb = NULL;
\r
560 // Create a tcp instance with defualt Tcp default
\r
561 // sock init data and TcpProto
\r
563 mTcp4DefaultSockData.DriverBinding = TcpServiceData->DriverBindingHandle;
\r
565 Sock = SockCreateChild (&mTcp4DefaultSockData, &TcpProto, sizeof (TCP4_PROTO_DATA));
\r
566 if (NULL == Sock) {
\r
567 TCP4_DEBUG_ERROR (("Tcp4DriverBindingCreateChild: "
\r
568 "No resource to create a Tcp Child\n"));
\r
570 Status = EFI_OUT_OF_RESOURCES;
\r
574 *ChildHandle = Sock->SockHandle;
\r
577 // Open the default Ip4 protocol of IP_IO BY_DRIVER.
\r
579 Status = gBS->OpenProtocol (
\r
580 TcpServiceData->IpIo->ChildHandle,
\r
581 &gEfiIp4ProtocolGuid,
\r
583 TcpServiceData->DriverBindingHandle,
\r
585 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
\r
587 if (EFI_ERROR (Status)) {
\r
588 SockDestroyChild (Sock);
\r
592 NET_RESTORE_TPL (OldTpl);
\r
598 Destroys a child handle with a set of UDP4 services.
\r
600 @param This Protocol instance pointer.
\r
601 @param ChildHandle Handle of the child to be destroyed.
\r
603 @retval EFI_SUCCESS The TCP4 services are removed from the child
\r
605 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
\r
606 @retval other The child handle is not destroyed.
\r
611 Tcp4ServiceBindingDestroyChild (
\r
612 IN EFI_SERVICE_BINDING_PROTOCOL *This,
\r
613 IN EFI_HANDLE ChildHandle
\r
617 EFI_TCP4_PROTOCOL *Tcp4;
\r
619 TCP4_PROTO_DATA *TcpProtoData;
\r
620 TCP4_SERVICE_DATA *TcpServiceData;
\r
623 if (NULL == This || NULL == ChildHandle) {
\r
624 return EFI_INVALID_PARAMETER;
\r
627 OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
\r
630 // retrieve the Tcp4 protocol from ChildHandle
\r
632 Status = gBS->OpenProtocol (
\r
634 &gEfiTcp4ProtocolGuid,
\r
636 mTcp4DriverBinding.DriverBindingHandle,
\r
638 EFI_OPEN_PROTOCOL_GET_PROTOCOL
\r
640 if (EFI_ERROR (Status)) {
\r
641 Status = EFI_UNSUPPORTED;
\r
646 // destroy this sock and related Tcp protocol control
\r
649 Sock = SOCK_FROM_THIS (Tcp4);
\r
650 TcpProtoData = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
\r
651 TcpServiceData = TcpProtoData->TcpService;
\r
653 Status = SockDestroyChild (Sock);
\r
656 // Close the Ip4 protocol.
\r
658 gBS->CloseProtocol (
\r
659 TcpServiceData->IpIo->ChildHandle,
\r
660 &gEfiIp4ProtocolGuid,
\r
661 TcpServiceData->DriverBindingHandle,
\r
666 NET_RESTORE_TPL (OldTpl);
\r