]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/TcpDxe/TcpDriver.c
NetworkPkg: Clean up source files
[mirror_edk2.git] / NetworkPkg / TcpDxe / TcpDriver.c
CommitLineData
a3bcde70
HT
1/** @file\r
2 The driver binding and service binding protocol for the TCP driver.\r
3\r
f75a7f56 4 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
a3bcde70
HT
5\r
6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php.\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "TcpMain.h"\r
17\r
18UINT16 mTcp4RandomPort;\r
19UINT16 mTcp6RandomPort;\r
20\r
21TCP_HEARTBEAT_TIMER mTcpTimer = {\r
22 NULL,\r
23 0\r
24};\r
25\r
26EFI_TCP4_PROTOCOL gTcp4ProtocolTemplate = {\r
27 Tcp4GetModeData,\r
28 Tcp4Configure,\r
29 Tcp4Routes,\r
30 Tcp4Connect,\r
31 Tcp4Accept,\r
32 Tcp4Transmit,\r
33 Tcp4Receive,\r
34 Tcp4Close,\r
35 Tcp4Cancel,\r
36 Tcp4Poll\r
37};\r
38\r
39EFI_TCP6_PROTOCOL gTcp6ProtocolTemplate = {\r
40 Tcp6GetModeData,\r
41 Tcp6Configure,\r
42 Tcp6Connect,\r
43 Tcp6Accept,\r
44 Tcp6Transmit,\r
45 Tcp6Receive,\r
46 Tcp6Close,\r
47 Tcp6Cancel,\r
48 Tcp6Poll\r
49};\r
50\r
51SOCK_INIT_DATA mTcpDefaultSockData = {\r
52 SockStream,\r
53 SO_CLOSED,\r
54 NULL,\r
55 TCP_BACKLOG,\r
56 TCP_SND_BUF_SIZE,\r
57 TCP_RCV_BUF_SIZE,\r
58 IP_VERSION_4,\r
59 NULL,\r
60 TcpCreateSocketCallback,\r
61 TcpDestroySocketCallback,\r
62 NULL,\r
63 NULL,\r
64 0,\r
65 TcpDispatcher,\r
66 NULL,\r
67};\r
68\r
6879581d 69EFI_DRIVER_BINDING_PROTOCOL gTcp4DriverBinding = {\r
70 Tcp4DriverBindingSupported,\r
71 Tcp4DriverBindingStart,\r
72 Tcp4DriverBindingStop,\r
73 0xa,\r
74 NULL,\r
75 NULL\r
76};\r
77\r
78EFI_DRIVER_BINDING_PROTOCOL gTcp6DriverBinding = {\r
79 Tcp6DriverBindingSupported,\r
80 Tcp6DriverBindingStart,\r
81 Tcp6DriverBindingStop,\r
a3bcde70
HT
82 0xa,\r
83 NULL,\r
84 NULL\r
85};\r
86\r
87EFI_SERVICE_BINDING_PROTOCOL gTcpServiceBinding = {\r
88 TcpServiceBindingCreateChild,\r
89 TcpServiceBindingDestroyChild\r
90};\r
91\r
92\r
93/**\r
94 Create and start the heartbeat timer for the TCP driver.\r
95\r
96 @retval EFI_SUCCESS The timer was successfully created and started.\r
97 @retval other The timer was not created.\r
98\r
99**/\r
100EFI_STATUS\r
101TcpCreateTimer (\r
102 VOID\r
103 )\r
104{\r
105 EFI_STATUS Status;\r
106\r
107 Status = EFI_SUCCESS;\r
108\r
109 if (mTcpTimer.RefCnt == 0) {\r
110\r
111 Status = gBS->CreateEvent (\r
112 EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
113 TPL_NOTIFY,\r
114 TcpTicking,\r
115 NULL,\r
116 &mTcpTimer.TimerEvent\r
117 );\r
118 if (!EFI_ERROR (Status)) {\r
119\r
120 Status = gBS->SetTimer (\r
121 mTcpTimer.TimerEvent,\r
122 TimerPeriodic,\r
123 (UINT64) (TICKS_PER_SECOND / TCP_TICK_HZ)\r
124 );\r
125 }\r
126 }\r
127\r
128 if (!EFI_ERROR (Status)) {\r
129\r
130 mTcpTimer.RefCnt++;\r
131 }\r
132\r
133 return Status;\r
134}\r
135\r
136/**\r
137 Stop and destroy the heartbeat timer for TCP driver.\r
138\r
139**/\r
140VOID\r
141TcpDestroyTimer (\r
142 VOID\r
143 )\r
144{\r
145 ASSERT (mTcpTimer.RefCnt > 0);\r
146\r
147 mTcpTimer.RefCnt--;\r
148\r
149 if (mTcpTimer.RefCnt > 0) {\r
150 return;\r
151 }\r
152\r
153 gBS->SetTimer (mTcpTimer.TimerEvent, TimerCancel, 0);\r
154 gBS->CloseEvent (mTcpTimer.TimerEvent);\r
155 mTcpTimer.TimerEvent = NULL;\r
156}\r
157\r
158/**\r
159 The entry point for Tcp driver, which is used to install Tcp driver on the ImageHandle.\r
160\r
161 @param[in] ImageHandle The firmware allocated handle for this driver image.\r
162 @param[in] SystemTable Pointer to the EFI system table.\r
163\r
164 @retval EFI_SUCCESS The driver loaded.\r
165 @retval other The driver did not load.\r
166\r
167**/\r
168EFI_STATUS\r
169EFIAPI\r
170TcpDriverEntryPoint (\r
171 IN EFI_HANDLE ImageHandle,\r
172 IN EFI_SYSTEM_TABLE *SystemTable\r
173 )\r
174{\r
175 EFI_STATUS Status;\r
176 UINT32 Seed;\r
177\r
178 //\r
179 // Install the TCP Driver Binding Protocol\r
180 //\r
181 Status = EfiLibInstallDriverBindingComponentName2 (\r
182 ImageHandle,\r
183 SystemTable,\r
6879581d 184 &gTcp4DriverBinding,\r
a3bcde70
HT
185 ImageHandle,\r
186 &gTcpComponentName,\r
187 &gTcpComponentName2\r
188 );\r
189 if (EFI_ERROR (Status)) {\r
190 return Status;\r
191 }\r
192\r
6879581d 193 //\r
194 // Install the TCP Driver Binding Protocol\r
195 //\r
196 Status = EfiLibInstallDriverBindingComponentName2 (\r
197 ImageHandle,\r
198 SystemTable,\r
199 &gTcp6DriverBinding,\r
200 NULL,\r
201 &gTcpComponentName,\r
202 &gTcpComponentName2\r
203 );\r
204 if (EFI_ERROR (Status)) {\r
205 gBS->UninstallMultipleProtocolInterfaces (\r
206 ImageHandle,\r
207 &gEfiDriverBindingProtocolGuid,\r
208 &gTcp4DriverBinding,\r
209 &gEfiComponentName2ProtocolGuid,\r
210 &gTcpComponentName2,\r
211 &gEfiComponentNameProtocolGuid,\r
212 &gTcpComponentName,\r
213 NULL\r
214 );\r
215 return Status;\r
216 }\r
217\r
a3bcde70
HT
218 //\r
219 // Initialize ISS and random port.\r
220 //\r
221 Seed = NetRandomInitSeed ();\r
222 mTcpGlobalIss = NET_RANDOM (Seed) % mTcpGlobalIss;\r
223 mTcp4RandomPort = (UINT16) (TCP_PORT_KNOWN + (NET_RANDOM (Seed) % TCP_PORT_KNOWN));\r
224 mTcp6RandomPort = mTcp4RandomPort;\r
225\r
226 return EFI_SUCCESS;\r
227}\r
228\r
229/**\r
230 Create a new TCP4 or TCP6 driver service binding protocol\r
231\r
232 @param[in] Controller Controller handle of device to bind driver to.\r
76389e18 233 @param[in] Image The TCP driver's image handle.\r
a3bcde70
HT
234 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.\r
235\r
236 @retval EFI_OUT_OF_RESOURCES Failed to allocate some resources.\r
237 @retval EFI_SUCCESS A new IP6 service binding private was created.\r
238\r
239**/\r
240EFI_STATUS\r
241TcpCreateService (\r
242 IN EFI_HANDLE Controller,\r
243 IN EFI_HANDLE Image,\r
244 IN UINT8 IpVersion\r
245 )\r
246{\r
247 EFI_STATUS Status;\r
248 EFI_GUID *IpServiceBindingGuid;\r
249 EFI_GUID *TcpServiceBindingGuid;\r
250 TCP_SERVICE_DATA *TcpServiceData;\r
251 IP_IO_OPEN_DATA OpenData;\r
252\r
253 if (IpVersion == IP_VERSION_4) {\r
254 IpServiceBindingGuid = &gEfiIp4ServiceBindingProtocolGuid;\r
255 TcpServiceBindingGuid = &gEfiTcp4ServiceBindingProtocolGuid;\r
256 } else {\r
257 IpServiceBindingGuid = &gEfiIp6ServiceBindingProtocolGuid;\r
258 TcpServiceBindingGuid = &gEfiTcp6ServiceBindingProtocolGuid;\r
259 }\r
260\r
261 Status = gBS->OpenProtocol (\r
262 Controller,\r
263 TcpServiceBindingGuid,\r
264 NULL,\r
265 Image,\r
266 Controller,\r
267 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
268 );\r
269 if (!EFI_ERROR (Status)) {\r
270 return EFI_ALREADY_STARTED;\r
271 }\r
272\r
273 Status = gBS->OpenProtocol (\r
274 Controller,\r
275 IpServiceBindingGuid,\r
276 NULL,\r
277 Image,\r
278 Controller,\r
279 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
280 );\r
281 if (EFI_ERROR (Status)) {\r
282 return EFI_UNSUPPORTED;\r
283 }\r
284\r
285 //\r
286 // Create the TCP service data.\r
287 //\r
288 TcpServiceData = AllocateZeroPool (sizeof (TCP_SERVICE_DATA));\r
289 if (TcpServiceData == NULL) {\r
290 return EFI_OUT_OF_RESOURCES;\r
291 }\r
292\r
293 TcpServiceData->Signature = TCP_DRIVER_SIGNATURE;\r
294 TcpServiceData->ControllerHandle = Controller;\r
295 TcpServiceData->DriverBindingHandle = Image;\r
296 TcpServiceData->IpVersion = IpVersion;\r
297 CopyMem (\r
298 &TcpServiceData->ServiceBinding,\r
299 &gTcpServiceBinding,\r
300 sizeof (EFI_SERVICE_BINDING_PROTOCOL)\r
301 );\r
302\r
303 TcpServiceData->IpIo = IpIoCreate (Image, Controller, IpVersion);\r
304 if (TcpServiceData->IpIo == NULL) {\r
305 Status = EFI_OUT_OF_RESOURCES;\r
306 goto ON_ERROR;\r
307 }\r
308\r
309\r
310 InitializeListHead (&TcpServiceData->SocketList);\r
311 ZeroMem (&OpenData, sizeof (IP_IO_OPEN_DATA));\r
312\r
313 if (IpVersion == IP_VERSION_4) {\r
314 CopyMem (\r
315 &OpenData.IpConfigData.Ip4CfgData,\r
316 &mIp4IoDefaultIpConfigData,\r
317 sizeof (EFI_IP4_CONFIG_DATA)\r
318 );\r
319 OpenData.IpConfigData.Ip4CfgData.DefaultProtocol = EFI_IP_PROTO_TCP;\r
320 } else {\r
321 CopyMem (\r
322 &OpenData.IpConfigData.Ip6CfgData,\r
323 &mIp6IoDefaultIpConfigData,\r
324 sizeof (EFI_IP6_CONFIG_DATA)\r
325 );\r
326 OpenData.IpConfigData.Ip6CfgData.DefaultProtocol = EFI_IP_PROTO_TCP;\r
327 }\r
328\r
329 OpenData.PktRcvdNotify = TcpRxCallback;\r
330 Status = IpIoOpen (TcpServiceData->IpIo, &OpenData);\r
331 if (EFI_ERROR (Status)) {\r
332 goto ON_ERROR;\r
333 }\r
334\r
335 Status = TcpCreateTimer ();\r
336 if (EFI_ERROR (Status)) {\r
337 goto ON_ERROR;\r
338 }\r
339\r
340 Status = gBS->InstallMultipleProtocolInterfaces (\r
341 &Controller,\r
342 TcpServiceBindingGuid,\r
343 &TcpServiceData->ServiceBinding,\r
344 NULL\r
345 );\r
346 if (EFI_ERROR (Status)) {\r
347 TcpDestroyTimer ();\r
348\r
349 goto ON_ERROR;\r
350 }\r
351\r
a3bcde70
HT
352 return EFI_SUCCESS;\r
353\r
354ON_ERROR:\r
355\r
356 if (TcpServiceData->IpIo != NULL) {\r
357 IpIoDestroy (TcpServiceData->IpIo);\r
216f7970 358 TcpServiceData->IpIo = NULL;\r
a3bcde70
HT
359 }\r
360\r
361 FreePool (TcpServiceData);\r
362\r
363 return Status;\r
364}\r
365\r
216f7970 366/**\r
367 Callback function which provided by user to remove one node in NetDestroyLinkList process.\r
f75a7f56 368\r
216f7970 369 @param[in] Entry The entry to be removed.\r
370 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.\r
371\r
372 @retval EFI_SUCCESS The entry has been removed successfully.\r
373 @retval Others Fail to remove the entry.\r
374\r
375**/\r
376EFI_STATUS\r
1f7eb561 377EFIAPI\r
216f7970 378TcpDestroyChildEntryInHandleBuffer (\r
379 IN LIST_ENTRY *Entry,\r
380 IN VOID *Context\r
1f7eb561 381 )\r
216f7970 382{\r
383 SOCKET *Sock;\r
384 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
385 UINTN NumberOfChildren;\r
386 EFI_HANDLE *ChildHandleBuffer;\r
387\r
388 if (Entry == NULL || Context == NULL) {\r
389 return EFI_INVALID_PARAMETER;\r
390 }\r
391\r
392 Sock = NET_LIST_USER_STRUCT_S (Entry, SOCKET, Link, SOCK_SIGNATURE);\r
393 ServiceBinding = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;\r
394 NumberOfChildren = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;\r
395 ChildHandleBuffer = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;\r
396\r
397 if (!NetIsInHandleBuffer (Sock->SockHandle, NumberOfChildren, ChildHandleBuffer)) {\r
398 return EFI_SUCCESS;\r
399 }\r
400\r
401 return ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);\r
402}\r
403\r
a3bcde70
HT
404/**\r
405 Destroy a TCP6 or TCP4 service binding instance. It will release all\r
406 the resources allocated by the instance.\r
407\r
408 @param[in] Controller Controller handle of device to bind driver to.\r
409 @param[in] ImageHandle The TCP driver's image handle.\r
216f7970 410 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number\r
a3bcde70 411 of children is zero stop the entire bus driver.\r
216f7970 412 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL\r
f75a7f56 413 if NumberOfChildren is 0.\r
a3bcde70
HT
414 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6\r
415\r
416 @retval EFI_SUCCESS The resources used by the instance were cleaned up.\r
417 @retval Others Failed to clean up some of the resources.\r
418\r
419**/\r
420EFI_STATUS\r
421TcpDestroyService (\r
422 IN EFI_HANDLE Controller,\r
423 IN EFI_HANDLE ImageHandle,\r
424 IN UINTN NumberOfChildren,\r
216f7970 425 IN EFI_HANDLE *ChildHandleBuffer, OPTIONAL\r
a3bcde70
HT
426 IN UINT8 IpVersion\r
427 )\r
428{\r
429 EFI_HANDLE NicHandle;\r
430 EFI_GUID *IpProtocolGuid;\r
431 EFI_GUID *ServiceBindingGuid;\r
432 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
433 TCP_SERVICE_DATA *TcpServiceData;\r
434 EFI_STATUS Status;\r
216f7970 435 LIST_ENTRY *List;\r
436 TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;\r
a3bcde70
HT
437\r
438 ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));\r
439\r
440 if (IpVersion == IP_VERSION_4) {\r
441 IpProtocolGuid = &gEfiIp4ProtocolGuid;\r
442 ServiceBindingGuid = &gEfiTcp4ServiceBindingProtocolGuid;\r
443 } else {\r
444 IpProtocolGuid = &gEfiIp6ProtocolGuid;\r
445 ServiceBindingGuid = &gEfiTcp6ServiceBindingProtocolGuid;\r
446 }\r
447\r
448 NicHandle = NetLibGetNicHandle (Controller, IpProtocolGuid);\r
449 if (NicHandle == NULL) {\r
216f7970 450 return EFI_SUCCESS;\r
a3bcde70
HT
451 }\r
452\r
453 Status = gBS->OpenProtocol (\r
454 NicHandle,\r
455 ServiceBindingGuid,\r
456 (VOID **) &ServiceBinding,\r
457 ImageHandle,\r
458 Controller,\r
459 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
460 );\r
461 if (EFI_ERROR (Status)) {\r
462 return EFI_DEVICE_ERROR;\r
463 }\r
464\r
465 TcpServiceData = TCP_SERVICE_FROM_THIS (ServiceBinding);\r
466\r
216f7970 467 if (NumberOfChildren != 0) {\r
468 List = &TcpServiceData->SocketList;\r
469 Context.ServiceBinding = ServiceBinding;\r
470 Context.NumberOfChildren = NumberOfChildren;\r
471 Context.ChildHandleBuffer = ChildHandleBuffer;\r
472 Status = NetDestroyLinkList (\r
473 List,\r
474 TcpDestroyChildEntryInHandleBuffer,\r
475 &Context,\r
476 NULL\r
477 );\r
478 } else if (IsListEmpty (&TcpServiceData->SocketList)) {\r
a3bcde70
HT
479 //\r
480 // Uninstall TCP servicebinding protocol\r
481 //\r
482 gBS->UninstallMultipleProtocolInterfaces (\r
483 NicHandle,\r
484 ServiceBindingGuid,\r
485 ServiceBinding,\r
486 NULL\r
487 );\r
488\r
489 //\r
490 // Destroy the IpIO consumed by TCP driver\r
491 //\r
492 IpIoDestroy (TcpServiceData->IpIo);\r
216f7970 493 TcpServiceData->IpIo = NULL;\r
a3bcde70
HT
494\r
495 //\r
496 // Destroy the heartbeat timer.\r
497 //\r
498 TcpDestroyTimer ();\r
499\r
a3bcde70
HT
500 //\r
501 // Release the TCP service data\r
502 //\r
503 FreePool (TcpServiceData);\r
a3bcde70 504\r
216f7970 505 Status = EFI_SUCCESS;\r
a3bcde70
HT
506 }\r
507\r
216f7970 508 return Status;\r
a3bcde70
HT
509}\r
510\r
511/**\r
512 Test to see if this driver supports ControllerHandle.\r
513\r
514 @param[in] This Protocol instance pointer.\r
515 @param[in] ControllerHandle Handle of device to test.\r
516 @param[in] RemainingDevicePath Optional parameter use to pick a specific\r
517 child device to start.\r
518\r
519 @retval EFI_SUCCESS This driver supports this device.\r
520 @retval EFI_ALREADY_STARTED This driver is already running on this device.\r
521 @retval other This driver does not support this device.\r
522\r
523**/\r
524EFI_STATUS\r
525EFIAPI\r
6879581d 526Tcp4DriverBindingSupported (\r
a3bcde70
HT
527 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
528 IN EFI_HANDLE ControllerHandle,\r
529 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
530 )\r
531{\r
532 EFI_STATUS Status;\r
a3bcde70
HT
533\r
534 //\r
535 // Test for the Tcp4ServiceBinding Protocol\r
536 //\r
537 Status = gBS->OpenProtocol (\r
538 ControllerHandle,\r
539 &gEfiTcp4ServiceBindingProtocolGuid,\r
540 NULL,\r
541 This->DriverBindingHandle,\r
542 ControllerHandle,\r
543 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
544 );\r
6879581d 545 if (!EFI_ERROR (Status)) {\r
546 return EFI_ALREADY_STARTED;\r
547 }\r
f75a7f56 548\r
6879581d 549 //\r
550 // Test for the Ip4ServiceBinding Protocol\r
551 //\r
552 Status = gBS->OpenProtocol (\r
553 ControllerHandle,\r
554 &gEfiIp4ServiceBindingProtocolGuid,\r
555 NULL,\r
556 This->DriverBindingHandle,\r
557 ControllerHandle,\r
558 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
559 );\r
560 return Status;\r
561}\r
a3bcde70 562\r
6879581d 563/**\r
564 Start this driver on ControllerHandle.\r
565\r
566 @param[in] This Protocol instance pointer.\r
567 @param[in] ControllerHandle Handle of device to bind driver to.\r
568 @param[in] RemainingDevicePath Optional parameter use to pick a specific child\r
569 device to start.\r
570\r
571 @retval EFI_SUCCESS The driver is added to ControllerHandle.\r
572 @retval EFI_OUT_OF_RESOURCES There are not enough resources to start the\r
573 driver.\r
574 @retval other The driver cannot be added to ControllerHandle.\r
575\r
576**/\r
577EFI_STATUS\r
578EFIAPI\r
579Tcp4DriverBindingStart (\r
580 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
581 IN EFI_HANDLE ControllerHandle,\r
582 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
583 )\r
584{\r
585 EFI_STATUS Status;\r
586\r
587 Status = TcpCreateService (ControllerHandle, This->DriverBindingHandle, IP_VERSION_4);\r
588 if ((Status == EFI_ALREADY_STARTED) || (Status == EFI_UNSUPPORTED)) {\r
589 Status = EFI_SUCCESS;\r
a3bcde70
HT
590 }\r
591\r
6879581d 592 return Status;\r
593}\r
594\r
595/**\r
596 Stop this driver on ControllerHandle.\r
597\r
598 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
599 @param[in] ControllerHandle A handle to the device being stopped. The handle must\r
600 support a bus specific I/O protocol for the driver\r
601 to use to stop the device.\r
602 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.\r
603 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL\r
604 if NumberOfChildren is 0.\r
605\r
606 @retval EFI_SUCCESS The device was stopped.\r
607 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
608\r
609**/\r
610EFI_STATUS\r
611EFIAPI\r
612Tcp4DriverBindingStop (\r
613 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
614 IN EFI_HANDLE ControllerHandle,\r
615 IN UINTN NumberOfChildren,\r
616 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL\r
617 )\r
618{\r
619 return TcpDestroyService (\r
620 ControllerHandle,\r
621 This->DriverBindingHandle,\r
622 NumberOfChildren,\r
623 ChildHandleBuffer,\r
624 IP_VERSION_4\r
625 );\r
626}\r
627\r
628/**\r
629 Test to see if this driver supports ControllerHandle.\r
630\r
631 @param[in] This Protocol instance pointer.\r
632 @param[in] ControllerHandle Handle of device to test.\r
633 @param[in] RemainingDevicePath Optional parameter use to pick a specific\r
634 child device to start.\r
635\r
636 @retval EFI_SUCCESS This driver supports this device.\r
637 @retval EFI_ALREADY_STARTED This driver is already running on this device.\r
638 @retval other This driver does not support this device.\r
639\r
640**/\r
641EFI_STATUS\r
642EFIAPI\r
643Tcp6DriverBindingSupported (\r
644 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
645 IN EFI_HANDLE ControllerHandle,\r
646 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
647 )\r
648{\r
649 EFI_STATUS Status;\r
650\r
a3bcde70 651 //\r
6879581d 652 // Test for the Tcp6ServiceBinding Protocol\r
a3bcde70
HT
653 //\r
654 Status = gBS->OpenProtocol (\r
655 ControllerHandle,\r
656 &gEfiTcp6ServiceBindingProtocolGuid,\r
657 NULL,\r
658 This->DriverBindingHandle,\r
659 ControllerHandle,\r
660 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
661 );\r
6879581d 662 if (!EFI_ERROR (Status)) {\r
a3bcde70
HT
663 return EFI_ALREADY_STARTED;\r
664 }\r
f75a7f56 665\r
6879581d 666 //\r
667 // Test for the Ip6ServiceBinding Protocol\r
668 //\r
669 Status = gBS->OpenProtocol (\r
670 ControllerHandle,\r
671 &gEfiIp6ServiceBindingProtocolGuid,\r
672 NULL,\r
673 This->DriverBindingHandle,\r
674 ControllerHandle,\r
675 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
676 );\r
677 return Status;\r
a3bcde70
HT
678}\r
679\r
680/**\r
681 Start this driver on ControllerHandle.\r
682\r
683 @param[in] This Protocol instance pointer.\r
684 @param[in] ControllerHandle Handle of device to bind driver to.\r
685 @param[in] RemainingDevicePath Optional parameter use to pick a specific child\r
686 device to start.\r
687\r
688 @retval EFI_SUCCESS The driver is added to ControllerHandle.\r
689 @retval EFI_OUT_OF_RESOURCES There are not enough resources to start the\r
690 driver.\r
691 @retval other The driver cannot be added to ControllerHandle.\r
692\r
693**/\r
694EFI_STATUS\r
695EFIAPI\r
6879581d 696Tcp6DriverBindingStart (\r
a3bcde70
HT
697 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
698 IN EFI_HANDLE ControllerHandle,\r
699 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
700 )\r
701{\r
6879581d 702 EFI_STATUS Status;\r
a3bcde70 703\r
6879581d 704 Status = TcpCreateService (ControllerHandle, This->DriverBindingHandle, IP_VERSION_6);\r
705 if ((Status == EFI_ALREADY_STARTED) || (Status == EFI_UNSUPPORTED)) {\r
706 Status = EFI_SUCCESS;\r
a3bcde70
HT
707 }\r
708\r
6879581d 709 return Status;\r
a3bcde70
HT
710}\r
711\r
712/**\r
713 Stop this driver on ControllerHandle.\r
714\r
715 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
716 @param[in] ControllerHandle A handle to the device being stopped. The handle must\r
717 support a bus specific I/O protocol for the driver\r
718 to use to stop the device.\r
719 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.\r
720 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL\r
721 if NumberOfChildren is 0.\r
722\r
723 @retval EFI_SUCCESS The device was stopped.\r
724 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
725\r
726**/\r
727EFI_STATUS\r
728EFIAPI\r
6879581d 729Tcp6DriverBindingStop (\r
a3bcde70
HT
730 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
731 IN EFI_HANDLE ControllerHandle,\r
732 IN UINTN NumberOfChildren,\r
733 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL\r
734 )\r
735{\r
6879581d 736 return TcpDestroyService (\r
737 ControllerHandle,\r
738 This->DriverBindingHandle,\r
739 NumberOfChildren,\r
740 ChildHandleBuffer,\r
741 IP_VERSION_6\r
742 );\r
a3bcde70
HT
743}\r
744\r
745/**\r
746 The Callback funtion called after the TCP socket was created.\r
747\r
748 @param[in] This Pointer to the socket just created\r
749 @param[in] Context Context of the socket\r
750\r
751 @retval EFI_SUCCESS This protocol installed successfully.\r
752 @retval other An error occured.\r
753\r
754**/\r
755EFI_STATUS\r
756TcpCreateSocketCallback (\r
757 IN SOCKET *This,\r
758 IN VOID *Context\r
759 )\r
760{\r
761 EFI_STATUS Status;\r
762 TCP_SERVICE_DATA *TcpServiceData;\r
763 EFI_GUID *IpProtocolGuid;\r
764 VOID *Ip;\r
765\r
766 if (This->IpVersion == IP_VERSION_4) {\r
767 IpProtocolGuid = &gEfiIp4ProtocolGuid;\r
768 } else {\r
769 IpProtocolGuid = &gEfiIp6ProtocolGuid;\r
770 }\r
771\r
772 TcpServiceData = ((TCP_PROTO_DATA *) This->ProtoReserved)->TcpService;\r
773\r
774 //\r
775 // Open the default IP protocol of IP_IO BY_DRIVER.\r
776 //\r
777 Status = gBS->OpenProtocol (\r
778 TcpServiceData->IpIo->ChildHandle,\r
779 IpProtocolGuid,\r
780 &Ip,\r
781 TcpServiceData->DriverBindingHandle,\r
782 This->SockHandle,\r
783 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
784 );\r
785 if (EFI_ERROR (Status)) {\r
786 return Status;\r
787 }\r
788\r
789 //\r
790 // Open the device path on the handle where service binding resides on.\r
791 //\r
792 Status = gBS->OpenProtocol (\r
793 TcpServiceData->ControllerHandle,\r
794 &gEfiDevicePathProtocolGuid,\r
795 (VOID **) &This->ParentDevicePath,\r
796 TcpServiceData->DriverBindingHandle,\r
797 This->SockHandle,\r
bf1400b9 798 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
a3bcde70
HT
799 );\r
800 if (EFI_ERROR (Status)) {\r
801 gBS->CloseProtocol (\r
802 TcpServiceData->IpIo->ChildHandle,\r
803 IpProtocolGuid,\r
804 TcpServiceData->DriverBindingHandle,\r
805 This->SockHandle\r
806 );\r
807 } else {\r
808 //\r
809 // Insert this socket into the SocketList.\r
810 //\r
811 InsertTailList (&TcpServiceData->SocketList, &This->Link);\r
812 }\r
813\r
814 return Status;\r
815}\r
816\r
817/**\r
818 The callback function called before the TCP socket was to be destroyed.\r
819\r
820 @param[in] This The TCP socket to be destroyed.\r
821 @param[in] Context The context of the socket.\r
822\r
823**/\r
824VOID\r
825TcpDestroySocketCallback (\r
826 IN SOCKET *This,\r
827 IN VOID *Context\r
828 )\r
829{\r
830 TCP_SERVICE_DATA *TcpServiceData;\r
831 EFI_GUID *IpProtocolGuid;\r
832\r
833 if (This->IpVersion == IP_VERSION_4) {\r
834 IpProtocolGuid = &gEfiIp4ProtocolGuid;\r
835 } else {\r
836 IpProtocolGuid = &gEfiIp6ProtocolGuid;\r
837 }\r
838\r
839 TcpServiceData = ((TCP_PROTO_DATA *) This->ProtoReserved)->TcpService;\r
840\r
841 //\r
842 // Remove this node from the list.\r
843 //\r
844 RemoveEntryList (&This->Link);\r
845\r
a3bcde70
HT
846 //\r
847 // Close the IP protocol.\r
848 //\r
849 gBS->CloseProtocol (\r
850 TcpServiceData->IpIo->ChildHandle,\r
851 IpProtocolGuid,\r
852 TcpServiceData->DriverBindingHandle,\r
853 This->SockHandle\r
854 );\r
855}\r
856\r
857/**\r
858 Creates a child handle with a set of TCP services.\r
859\r
860 The CreateChild() function installs a protocol on ChildHandle.\r
861 If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.\r
862 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.\r
863\r
864 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
865 @param[in, out] ChildHandle Pointer to the handle of the child to create.\r
866 If it is NULL, then a new handle is created.\r
867 If it is a pointer to an existing UEFI handle,\r
868 then the protocol is added to the existing UEFI handle.\r
869\r
870 @retval EFI_SUCCES The protocol was added to ChildHandle.\r
871 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.\r
c2adf51f 872 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create\r
a3bcde70
HT
873 the child.\r
874 @retval other The child handle was not created.\r
875\r
876**/\r
877EFI_STATUS\r
878EFIAPI\r
879TcpServiceBindingCreateChild (\r
880 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
881 IN OUT EFI_HANDLE *ChildHandle\r
882 )\r
883{\r
884 SOCKET *Sock;\r
885 TCP_SERVICE_DATA *TcpServiceData;\r
886 TCP_PROTO_DATA TcpProto;\r
887 EFI_STATUS Status;\r
888 EFI_TPL OldTpl;\r
889\r
890 if (NULL == This || NULL == ChildHandle) {\r
891 return EFI_INVALID_PARAMETER;\r
892 }\r
893\r
894 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
895\r
896 Status = EFI_SUCCESS;\r
897 TcpServiceData = TCP_SERVICE_FROM_THIS (This);\r
898 TcpProto.TcpService = TcpServiceData;\r
899 TcpProto.TcpPcb = NULL;\r
900\r
901 //\r
902 // Create a tcp instance with defualt Tcp default\r
903 // sock init data and TcpProto\r
904 //\r
905 mTcpDefaultSockData.ProtoData = &TcpProto;\r
906 mTcpDefaultSockData.DataSize = sizeof (TCP_PROTO_DATA);\r
907 mTcpDefaultSockData.DriverBinding = TcpServiceData->DriverBindingHandle;\r
908 mTcpDefaultSockData.IpVersion = TcpServiceData->IpVersion;\r
909\r
910 if (TcpServiceData->IpVersion == IP_VERSION_4) {\r
911 mTcpDefaultSockData.Protocol = &gTcp4ProtocolTemplate;\r
912 } else {\r
913 mTcpDefaultSockData.Protocol = &gTcp6ProtocolTemplate;\r
914 }\r
915\r
916 Sock = SockCreateChild (&mTcpDefaultSockData);\r
917 if (NULL == Sock) {\r
918 DEBUG (\r
919 (EFI_D_ERROR,\r
920 "TcpDriverBindingCreateChild: No resource to create a Tcp Child\n")\r
921 );\r
922\r
923 Status = EFI_OUT_OF_RESOURCES;\r
924 } else {\r
925 *ChildHandle = Sock->SockHandle;\r
926 }\r
927\r
928 mTcpDefaultSockData.ProtoData = NULL;\r
929\r
930 gBS->RestoreTPL (OldTpl);\r
931 return Status;\r
932}\r
933\r
934/**\r
935 Destroys a child handle with a set of TCP services.\r
936\r
937 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol\r
938 that was installed by CreateChild() from ChildHandle. If the removed protocol is the\r
939 last protocol on ChildHandle, then ChildHandle is destroyed.\r
940\r
941 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
942 @param ChildHandle Handle of the child to be destroyed.\r
943\r
944 @retval EFI_SUCCES The protocol was removed from ChildHandle.\r
945 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.\r
15ee13fc 946 @retval EFI_INVALID_PARAMETER Child handle is NULL.\r
a3bcde70
HT
947 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle\r
948 because its services are being used.\r
949 @retval other The child handle was not destroyed.\r
950\r
951**/\r
952EFI_STATUS\r
953EFIAPI\r
954TcpServiceBindingDestroyChild (\r
955 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
956 IN EFI_HANDLE ChildHandle\r
957 )\r
958{\r
959 EFI_STATUS Status;\r
960 VOID *Tcp;\r
961 SOCKET *Sock;\r
a3bcde70
HT
962\r
963 if (NULL == This || NULL == ChildHandle) {\r
964 return EFI_INVALID_PARAMETER;\r
965 }\r
966\r
a3bcde70
HT
967 //\r
968 // retrieve the Tcp4 protocol from ChildHandle\r
969 //\r
970 Status = gBS->OpenProtocol (\r
971 ChildHandle,\r
972 &gEfiTcp4ProtocolGuid,\r
973 &Tcp,\r
6879581d 974 gTcp4DriverBinding.DriverBindingHandle,\r
a3bcde70
HT
975 ChildHandle,\r
976 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
977 );\r
978 if (EFI_ERROR (Status)) {\r
979 //\r
980 // No Tcp4, try the Tcp6 protocol\r
981 //\r
982 Status = gBS->OpenProtocol (\r
983 ChildHandle,\r
984 &gEfiTcp6ProtocolGuid,\r
985 &Tcp,\r
6879581d 986 gTcp6DriverBinding.DriverBindingHandle,\r
a3bcde70
HT
987 ChildHandle,\r
988 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
989 );\r
990 if (EFI_ERROR (Status)) {\r
991 Status = EFI_UNSUPPORTED;\r
992 }\r
993 }\r
994\r
995 if (!EFI_ERROR (Status)) {\r
996 //\r
997 // destroy this sock and related Tcp protocol control\r
998 // block\r
999 //\r
1000 Sock = SOCK_FROM_THIS (Tcp);\r
1001\r
1002 SockDestroyChild (Sock);\r
1003 }\r
1004\r
a3bcde70
HT
1005 return Status;\r
1006}\r