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