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