]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c
Clean codes per ECC.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / ArpDxe / ArpDriver.c
1 /** @file
2
3 Copyright (c) 2006 - 2008, 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
8
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.
11
12 Module Name:
13
14 ArpDriver.c
15
16 Abstract:
17
18
19 **/
20
21
22 #include "ArpDriver.h"
23 #include "ArpImpl.h"
24
25 EFI_DRIVER_BINDING_PROTOCOL gArpDriverBinding = {
26 ArpDriverBindingSupported,
27 ArpDriverBindingStart,
28 ArpDriverBindingStop,
29 0xa,
30 NULL,
31 NULL
32 };
33
34
35 /**
36 Create and initialize the arp service context data.
37
38 @param ImageHandle The image handle representing the loaded driver
39 image.
40 @param ControllerHandle The controller handle the driver binds to.
41 @param ArpService Pointer to the buffer containing the arp service
42 context data.
43
44 @retval EFI_SUCCESS The arp service context is initialized.
45 @retval other Failed to initialize the arp service context.
46
47 **/
48 EFI_STATUS
49 ArpCreateService (
50 IN EFI_HANDLE ImageHandle,
51 IN EFI_HANDLE ControllerHandle,
52 IN ARP_SERVICE_DATA *ArpService
53 )
54 {
55 EFI_STATUS Status;
56
57 ASSERT (ArpService != NULL);
58
59 ArpService->Signature = ARP_SERVICE_DATA_SIGNATURE;
60
61 //
62 // Init the servicebinding protocol members.
63 //
64 ArpService->ServiceBinding.CreateChild = ArpServiceBindingCreateChild;
65 ArpService->ServiceBinding.DestroyChild = ArpServiceBindingDestroyChild;
66
67 //
68 // Save the handles.
69 //
70 ArpService->ImageHandle = ImageHandle;
71 ArpService->ControllerHandle = ControllerHandle;
72
73 //
74 // Create a MNP child instance.
75 //
76 Status = NetLibCreateServiceChild (
77 ControllerHandle,
78 ImageHandle,
79 &gEfiManagedNetworkServiceBindingProtocolGuid,
80 &ArpService->MnpChildHandle
81 );
82 if (EFI_ERROR (Status)) {
83 return Status;
84 }
85
86 //
87 // Open the MNP protocol.
88 //
89 Status = gBS->OpenProtocol (
90 ArpService->MnpChildHandle,
91 &gEfiManagedNetworkProtocolGuid,
92 (VOID **)&ArpService->Mnp,
93 ImageHandle,
94 ControllerHandle,
95 EFI_OPEN_PROTOCOL_BY_DRIVER
96 );
97 if (EFI_ERROR (Status)) {
98 goto ERROR_EXIT;
99 }
100
101 //
102 // Get the underlayer Snp mode data.
103 //
104 Status = ArpService->Mnp->GetModeData (ArpService->Mnp, NULL, &ArpService->SnpMode);
105 if ((Status != EFI_NOT_STARTED) && EFI_ERROR (Status)) {
106 goto ERROR_EXIT;
107 }
108
109 if (ArpService->SnpMode.IfType != NET_IFTYPE_ETHERNET) {
110 //
111 // Only support the ethernet.
112 //
113 Status = EFI_UNSUPPORTED;
114 goto ERROR_EXIT;
115 }
116
117 //
118 // Set the Mnp config parameters.
119 //
120 ArpService->MnpConfigData.ReceivedQueueTimeoutValue = 0;
121 ArpService->MnpConfigData.TransmitQueueTimeoutValue = 0;
122 ArpService->MnpConfigData.ProtocolTypeFilter = ARP_ETHER_PROTO_TYPE;
123 ArpService->MnpConfigData.EnableUnicastReceive = TRUE;
124 ArpService->MnpConfigData.EnableMulticastReceive = FALSE;
125 ArpService->MnpConfigData.EnableBroadcastReceive = TRUE;
126 ArpService->MnpConfigData.EnablePromiscuousReceive = FALSE;
127 ArpService->MnpConfigData.FlushQueuesOnReset = TRUE;
128 ArpService->MnpConfigData.EnableReceiveTimestamps = FALSE;
129 ArpService->MnpConfigData.DisableBackgroundPolling = FALSE;
130
131 //
132 // Configure the Mnp child.
133 //
134 Status = ArpService->Mnp->Configure (ArpService->Mnp, &ArpService->MnpConfigData);
135 if (EFI_ERROR (Status)) {
136 goto ERROR_EXIT;
137 }
138
139 //
140 // Create the event used in the RxToken.
141 //
142 Status = gBS->CreateEvent (
143 EVT_NOTIFY_SIGNAL,
144 TPL_NOTIFY,
145 ArpOnFrameRcvd,
146 ArpService,
147 &ArpService->RxToken.Event
148 );
149 if (EFI_ERROR (Status)) {
150 goto ERROR_EXIT;
151 }
152
153 //
154 // Create the Arp heartbeat timer.
155 //
156 Status = gBS->CreateEvent (
157 EVT_NOTIFY_SIGNAL | EVT_TIMER,
158 TPL_CALLBACK,
159 ArpTimerHandler,
160 ArpService,
161 &ArpService->PeriodicTimer
162 );
163 if (EFI_ERROR (Status)) {
164 goto ERROR_EXIT;
165 }
166
167 //
168 // Start the heartbeat timer.
169 //
170 Status = gBS->SetTimer (
171 ArpService->PeriodicTimer,
172 TimerPeriodic,
173 ARP_PERIODIC_TIMER_INTERVAL
174 );
175 if (EFI_ERROR (Status)) {
176 goto ERROR_EXIT;
177 }
178
179 //
180 // Init the lists.
181 //
182 InitializeListHead (&ArpService->ChildrenList);
183 InitializeListHead (&ArpService->PendingRequestTable);
184 InitializeListHead (&ArpService->DeniedCacheTable);
185 InitializeListHead (&ArpService->ResolvedCacheTable);
186
187 ERROR_EXIT:
188
189 return Status;
190 }
191
192
193 /**
194 Clean the arp service context data.
195
196 @param ArpService Pointer to the buffer containing the arp service
197 context data.
198
199 @return None.
200
201 **/
202 VOID
203 ArpCleanService (
204 IN ARP_SERVICE_DATA *ArpService
205 )
206 {
207 NET_CHECK_SIGNATURE (ArpService, ARP_SERVICE_DATA_SIGNATURE);
208
209 if (ArpService->PeriodicTimer != NULL) {
210 //
211 // Cancle and close the PeriodicTimer.
212 //
213 gBS->SetTimer (ArpService->PeriodicTimer, TimerCancel, 0);
214 gBS->CloseEvent (ArpService->PeriodicTimer);
215 }
216
217 if (ArpService->RxToken.Event != NULL) {
218 //
219 // Cancle the RxToken and close the event in the RxToken.
220 //
221 ArpService->Mnp->Cancel (ArpService->Mnp, NULL);
222 gBS->CloseEvent (ArpService->RxToken.Event);
223 }
224
225 if (ArpService->Mnp != NULL) {
226 //
227 // Reset the Mnp child and close the Mnp protocol.
228 //
229 ArpService->Mnp->Configure (ArpService->Mnp, NULL);
230 gBS->CloseProtocol (
231 ArpService->MnpChildHandle,
232 &gEfiManagedNetworkProtocolGuid,
233 ArpService->ImageHandle,
234 ArpService->ControllerHandle
235 );
236 }
237
238 if (ArpService->MnpChildHandle != NULL) {
239 //
240 // Destroy the mnp child.
241 //
242 NetLibDestroyServiceChild(
243 ArpService->ControllerHandle,
244 ArpService->ImageHandle,
245 &gEfiManagedNetworkServiceBindingProtocolGuid,
246 ArpService->MnpChildHandle
247 );
248 }
249 }
250
251
252 /**
253 Test to see if this driver supports ControllerHandle.
254
255 @param This Protocol instance pointer.
256 @param ControllerHandle Handle of device to test.
257 @param RemainingDevicePath Optional parameter use to pick a specific child
258 device to start.
259
260 @retval EFI_SUCCES This driver supports this device
261 @retval EFI_ALREADY_STARTED This driver is already running on this device.
262 @retval other This driver does not support this device.
263
264 **/
265 EFI_STATUS
266 EFIAPI
267 ArpDriverBindingSupported (
268 IN EFI_DRIVER_BINDING_PROTOCOL *This,
269 IN EFI_HANDLE ControllerHandle,
270 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
271 )
272 {
273 EFI_STATUS Status;
274
275 //
276 // Test to see if Arp SB is already installed.
277 //
278 Status = gBS->OpenProtocol (
279 ControllerHandle,
280 &gEfiArpServiceBindingProtocolGuid,
281 NULL,
282 This->DriverBindingHandle,
283 ControllerHandle,
284 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
285 );
286 if (Status == EFI_SUCCESS) {
287 return EFI_ALREADY_STARTED;
288 }
289
290 //
291 // Test to see if MNP SB is installed.
292 //
293 Status = gBS->OpenProtocol (
294 ControllerHandle,
295 &gEfiManagedNetworkServiceBindingProtocolGuid,
296 NULL,
297 This->DriverBindingHandle,
298 ControllerHandle,
299 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
300 );
301
302 return Status;
303 }
304
305
306 /**
307 Start this driver on ControllerHandle.
308
309 @param This Protocol instance pointer.
310 @param ControllerHandle Handle of device to bind driver to
311 @param RemainingDevicePath Optional parameter use to pick a specific child
312 device to start.
313
314 @retval EFI_SUCCES This driver is added to ControllerHandle
315 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
316 @retval other This driver does not support this device
317
318 **/
319 EFI_STATUS
320 EFIAPI
321 ArpDriverBindingStart (
322 IN EFI_DRIVER_BINDING_PROTOCOL *This,
323 IN EFI_HANDLE ControllerHandle,
324 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
325 )
326 {
327 EFI_STATUS Status;
328 ARP_SERVICE_DATA *ArpService;
329
330 //
331 // Allocate a zero pool for ArpService.
332 //
333 ArpService = AllocateZeroPool (sizeof(ARP_SERVICE_DATA));
334 if (ArpService == NULL) {
335 return EFI_OUT_OF_RESOURCES;
336 }
337
338 //
339 // Initialize the arp service context data.
340 //
341 Status = ArpCreateService (This->DriverBindingHandle, ControllerHandle, ArpService);
342 if (EFI_ERROR (Status)) {
343 goto ERROR;
344 }
345
346 //
347 // Install the ARP service binding protocol.
348 //
349 Status = gBS->InstallMultipleProtocolInterfaces (
350 &ControllerHandle,
351 &gEfiArpServiceBindingProtocolGuid,
352 &ArpService->ServiceBinding,
353 NULL
354 );
355 if (EFI_ERROR (Status)) {
356 goto ERROR;
357 }
358
359 //
360 // OK, start to receive arp packets from Mnp.
361 //
362 Status = ArpService->Mnp->Receive (ArpService->Mnp, &ArpService->RxToken);
363 if (EFI_ERROR (Status)) {
364 goto ERROR;
365 }
366
367 return Status;
368
369 ERROR:
370
371 //
372 // On error, clean the arp service context data, and free the memory allocated.
373 //
374 ArpCleanService (ArpService);
375 gBS->FreePool (ArpService);
376
377 return Status;
378 }
379
380
381 /**
382 Stop this driver on ControllerHandle.
383
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.
389
390 @retval EFI_SUCCES This driver is removed ControllerHandle
391 @retval other This driver was not removed from this device
392
393 **/
394 EFI_STATUS
395 EFIAPI
396 ArpDriverBindingStop (
397 IN EFI_DRIVER_BINDING_PROTOCOL *This,
398 IN EFI_HANDLE ControllerHandle,
399 IN UINTN NumberOfChildren,
400 IN EFI_HANDLE *ChildHandleBuffer
401 )
402 {
403 EFI_STATUS Status;
404 EFI_HANDLE NicHandle;
405 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
406 ARP_SERVICE_DATA *ArpService;
407 ARP_INSTANCE_DATA *Instance;
408
409 //
410 // Get the NicHandle which the arp servicebinding is installed on.
411 //
412 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
413 if (NicHandle == NULL) {
414 return EFI_DEVICE_ERROR;
415 }
416
417 //
418 // Try to get the arp servicebinding protocol on the NicHandle.
419 //
420 Status = gBS->OpenProtocol (
421 NicHandle,
422 &gEfiArpServiceBindingProtocolGuid,
423 (VOID **)&ServiceBinding,
424 This->DriverBindingHandle,
425 ControllerHandle,
426 EFI_OPEN_PROTOCOL_GET_PROTOCOL
427 );
428 if (EFI_ERROR (Status)) {
429 DEBUG ((EFI_D_ERROR, "ArpDriverBindingStop: Open ArpSb failed, %r.\n", Status));
430 return EFI_DEVICE_ERROR;
431 }
432
433 ArpService = ARP_SERVICE_DATA_FROM_THIS (ServiceBinding);
434
435 if (NumberOfChildren == 0) {
436 //
437 // Uninstall the ARP ServiceBinding protocol.
438 //
439 gBS->UninstallMultipleProtocolInterfaces (
440 NicHandle,
441 &gEfiArpServiceBindingProtocolGuid,
442 &ArpService->ServiceBinding,
443 NULL
444 );
445
446 //
447 // Clean the arp servicebinding context data and free the memory allocated.
448 //
449 ArpCleanService (ArpService);
450
451 gBS->FreePool (ArpService);
452 } else {
453
454 while (!IsListEmpty (&ArpService->ChildrenList)) {
455 Instance = NET_LIST_HEAD (&ArpService->ChildrenList, ARP_INSTANCE_DATA, List);
456
457 ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
458 }
459
460 ASSERT (IsListEmpty (&ArpService->PendingRequestTable));
461 ASSERT (IsListEmpty (&ArpService->DeniedCacheTable));
462 ASSERT (IsListEmpty (&ArpService->ResolvedCacheTable));
463 }
464
465 return EFI_SUCCESS;
466 }
467
468 /**
469 Creates a child handle with a set of I/O services.
470
471 @param This Protocol instance pointer.
472 @param ChildHandle Pointer to the handle of the child to create. If
473 it is NULL, then a new handle is created. If it is
474 not NULL, then the I/O services are added to the
475 existing child handle.
476
477 @retval EFI_SUCCES The child handle was created with the I/O
478 services.
479 @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create
480 the child.
481 @retval other The child handle was not created.
482
483 **/
484 EFI_STATUS
485 EFIAPI
486 ArpServiceBindingCreateChild (
487 IN EFI_SERVICE_BINDING_PROTOCOL *This,
488 IN EFI_HANDLE *ChildHandle
489 )
490 {
491 EFI_STATUS Status;
492 ARP_SERVICE_DATA *ArpService;
493 ARP_INSTANCE_DATA *Instance;
494 VOID *Mnp;
495 EFI_TPL OldTpl;
496
497 if ((This == NULL) || (ChildHandle == NULL)) {
498 return EFI_INVALID_PARAMETER;
499 }
500
501 ArpService = ARP_SERVICE_DATA_FROM_THIS (This);
502
503 //
504 // Allocate memory for the instance context data.
505 //
506 Instance = AllocateZeroPool (sizeof(ARP_INSTANCE_DATA));
507 if (Instance == NULL) {
508 DEBUG ((EFI_D_ERROR, "ArpSBCreateChild: Failed to allocate memory for Instance.\n"));
509
510 return EFI_OUT_OF_RESOURCES;
511 }
512
513 //
514 // Init the instance context data.
515 //
516 ArpInitInstance (ArpService, Instance);
517
518 //
519 // Install the ARP protocol onto the ChildHandle.
520 //
521 Status = gBS->InstallMultipleProtocolInterfaces (
522 ChildHandle,
523 &gEfiArpProtocolGuid,
524 (VOID *)&Instance->ArpProto,
525 NULL
526 );
527 if (EFI_ERROR (Status)) {
528 DEBUG ((EFI_D_ERROR, "ArpSBCreateChild: faild to install ARP protocol, %r.\n", Status));
529
530 gBS->FreePool (Instance);
531 return Status;
532 }
533
534 //
535 // Save the ChildHandle.
536 //
537 Instance->Handle = *ChildHandle;
538
539 //
540 // Open the Managed Network protocol BY_CHILD.
541 //
542 Status = gBS->OpenProtocol (
543 ArpService->MnpChildHandle,
544 &gEfiManagedNetworkProtocolGuid,
545 (VOID **) &Mnp,
546 gArpDriverBinding.DriverBindingHandle,
547 Instance->Handle,
548 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
549 );
550 if (EFI_ERROR (Status)) {
551 goto ERROR;
552 }
553
554 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
555
556 //
557 // Insert the instance into children list managed by the arp service context data.
558 //
559 InsertTailList (&ArpService->ChildrenList, &Instance->List);
560 ArpService->ChildrenNumber++;
561
562 gBS->RestoreTPL (OldTpl);
563
564 ERROR:
565
566 if (EFI_ERROR (Status)) {
567
568 gBS->CloseProtocol (
569 ArpService->MnpChildHandle,
570 &gEfiManagedNetworkProtocolGuid,
571 gArpDriverBinding.DriverBindingHandle,
572 Instance->Handle
573 );
574
575 gBS->UninstallMultipleProtocolInterfaces (
576 Instance->Handle,
577 &gEfiArpProtocolGuid,
578 &Instance->ArpProto,
579 NULL
580 );
581
582 //
583 // Free the allocated memory.
584 //
585 gBS->FreePool (Instance);
586 }
587
588 return Status;
589 }
590
591
592 /**
593 Destroys a child handle with a set of I/O services.
594
595 @param This Protocol instance pointer.
596 @param ChildHandle Handle of the child to destroy.
597
598 @retval EFI_SUCCES The I/O services were removed from the child
599 handle.
600 @retval EFI_UNSUPPORTED The child handle does not support the I/O services
601 that are being removed.
602 @retval EFI_INVALID_PARAMETER Child handle is not a valid EFI Handle.
603 @retval EFI_ACCESS_DENIED The child handle could not be destroyed because
604 its I/O services are being used.
605 @retval other The child handle was not destroyed.
606
607 **/
608 EFI_STATUS
609 EFIAPI
610 ArpServiceBindingDestroyChild (
611 IN EFI_SERVICE_BINDING_PROTOCOL *This,
612 IN EFI_HANDLE ChildHandle
613 )
614 {
615 EFI_STATUS Status;
616 ARP_SERVICE_DATA *ArpService;
617 ARP_INSTANCE_DATA *Instance;
618 EFI_ARP_PROTOCOL *Arp;
619 EFI_TPL OldTpl;
620
621 if ((This == NULL) || (ChildHandle == NULL)) {
622 return EFI_INVALID_PARAMETER;
623 }
624
625 ArpService = ARP_SERVICE_DATA_FROM_THIS (This);
626
627 //
628 // Get the arp protocol.
629 //
630 Status = gBS->OpenProtocol (
631 ChildHandle,
632 &gEfiArpProtocolGuid,
633 (VOID **)&Arp,
634 ArpService->ImageHandle,
635 ChildHandle,
636 EFI_OPEN_PROTOCOL_GET_PROTOCOL
637 );
638 if (EFI_ERROR (Status)) {
639 return EFI_UNSUPPORTED;
640 }
641
642 Instance = ARP_INSTANCE_DATA_FROM_THIS (Arp);
643
644 if (Instance->Destroyed) {
645 return EFI_SUCCESS;
646 }
647
648 //
649 // Use the Destroyed as a flag to avoid re-entrance.
650 //
651 Instance->Destroyed = TRUE;
652
653 //
654 // Close the Managed Network protocol.
655 //
656 gBS->CloseProtocol (
657 ArpService->MnpChildHandle,
658 &gEfiManagedNetworkProtocolGuid,
659 gArpDriverBinding.DriverBindingHandle,
660 ChildHandle
661 );
662
663 //
664 // Uninstall the ARP protocol.
665 //
666 Status = gBS->UninstallMultipleProtocolInterfaces (
667 ChildHandle,
668 &gEfiArpProtocolGuid,
669 &Instance->ArpProto,
670 NULL
671 );
672 if (EFI_ERROR (Status)) {
673 DEBUG ((EFI_D_ERROR, "ArpSBDestroyChild: Failed to uninstall the arp protocol, %r.\n",
674 Status));
675
676 Instance->Destroyed = FALSE;
677 return Status;
678 }
679
680 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
681
682 if (Instance->Configured) {
683 //
684 // Delete the related cache entry.
685 //
686 ArpDeleteCacheEntry (Instance, FALSE, NULL, TRUE);
687
688 //
689 // Reset the instance configuration.
690 //
691 ArpConfigureInstance (Instance, NULL);
692 }
693
694 //
695 // Remove this instance from the ChildrenList.
696 //
697 RemoveEntryList (&Instance->List);
698 ArpService->ChildrenNumber--;
699
700 gBS->RestoreTPL (OldTpl);
701
702 gBS->FreePool (Instance);
703
704 return Status;
705 }
706
707 /**
708 The entry point for Arp driver which installs the driver binding and component name
709 protocol on its ImageHandle.
710
711 @param ImageHandle The image handle of the driver.
712 @param SystemTable The system table.
713
714 @retval EFI_SUCCES if the driver binding and component name protocols are successfully
715 @retval Others Failed to install the protocols.
716
717 **/
718 EFI_STATUS
719 EFIAPI
720 ArpDriverEntryPoint (
721 IN EFI_HANDLE ImageHandle,
722 IN EFI_SYSTEM_TABLE *SystemTable
723 )
724 {
725 return EfiLibInstallDriverBindingComponentName2 (
726 ImageHandle,
727 SystemTable,
728 &gArpDriverBinding,
729 ImageHandle,
730 &gArpComponentName,
731 &gArpComponentName2
732 );
733 }
734