TianoCore EDK2 master
Loading...
Searching...
No Matches
MnpConfig.c
Go to the documentation of this file.
1
9#include "MnpImpl.h"
10#include "MnpVlan.h"
11
12EFI_SERVICE_BINDING_PROTOCOL mMnpServiceBindingProtocol = {
15};
16
17EFI_MANAGED_NETWORK_PROTOCOL mMnpProtocolTemplate = {
26};
27
28EFI_MANAGED_NETWORK_CONFIG_DATA mMnpDefaultConfigData = {
29 10000000,
30 10000000,
31 0,
32 FALSE,
33 FALSE,
34 FALSE,
35 FALSE,
36 FALSE,
37 FALSE,
38 FALSE
39};
40
55 IN OUT MNP_DEVICE_DATA *MnpDeviceData,
56 IN UINTN Count
57 )
58{
59 EFI_STATUS Status;
60 UINTN Index;
61 NET_BUF *Nbuf;
62
63 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
64 ASSERT ((Count > 0) && (MnpDeviceData->BufferLength > 0));
65
66 Status = EFI_SUCCESS;
67 for (Index = 0; Index < Count; Index++) {
68 Nbuf = NetbufAlloc (MnpDeviceData->BufferLength + MnpDeviceData->PaddingSize);
69 if (Nbuf == NULL) {
70 DEBUG ((DEBUG_ERROR, "MnpAddFreeNbuf: NetBufAlloc failed.\n"));
71
72 Status = EFI_OUT_OF_RESOURCES;
73 break;
74 }
75
76 if (MnpDeviceData->PaddingSize > 0) {
77 //
78 // Pad padding bytes before the media header
79 //
80 NetbufAllocSpace (Nbuf, MnpDeviceData->PaddingSize, NET_BUF_TAIL);
81 NetbufTrim (Nbuf, MnpDeviceData->PaddingSize, NET_BUF_HEAD);
82 }
83
84 NetbufQueAppend (&MnpDeviceData->FreeNbufQue, Nbuf);
85 }
86
87 MnpDeviceData->NbufCnt += Index;
88 return Status;
89}
90
102NET_BUF *
104 IN OUT MNP_DEVICE_DATA *MnpDeviceData
105 )
106{
107 EFI_STATUS Status;
108 NET_BUF_QUEUE *FreeNbufQue;
109 NET_BUF *Nbuf;
110 EFI_TPL OldTpl;
111
112 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
113
114 FreeNbufQue = &MnpDeviceData->FreeNbufQue;
115 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
116
117 //
118 // Check whether there are available buffers, or else try to add some.
119 //
120 if (FreeNbufQue->BufNum == 0) {
121 if ((MnpDeviceData->NbufCnt + MNP_NET_BUFFER_INCREASEMENT) > MNP_MAX_NET_BUFFER_NUM) {
122 DEBUG (
123 (DEBUG_ERROR,
124 "MnpAllocNbuf: The maximum NET_BUF size is reached for MNP driver instance %p.\n",
125 MnpDeviceData)
126 );
127
128 Nbuf = NULL;
129 goto ON_EXIT;
130 }
131
132 Status = MnpAddFreeNbuf (MnpDeviceData, MNP_NET_BUFFER_INCREASEMENT);
133 if (EFI_ERROR (Status)) {
134 DEBUG (
135 (DEBUG_ERROR,
136 "MnpAllocNbuf: Failed to add NET_BUFs into the FreeNbufQue, %r.\n",
137 Status)
138 );
139
140 //
141 // Don't return NULL, perhaps MnpAddFreeNbuf does add some NET_BUFs but
142 // the amount is less than MNP_NET_BUFFER_INCREASEMENT.
143 //
144 }
145 }
146
147 Nbuf = NetbufQueRemove (FreeNbufQue);
148
149 //
150 // Increase the RefCnt.
151 //
152 if (Nbuf != NULL) {
153 NET_GET_REF (Nbuf);
154 }
155
156ON_EXIT:
157 gBS->RestoreTPL (OldTpl);
158
159 return Nbuf;
160}
161
169VOID
171 IN OUT MNP_DEVICE_DATA *MnpDeviceData,
172 IN OUT NET_BUF *Nbuf
173 )
174{
175 EFI_TPL OldTpl;
176
177 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
178 ASSERT (Nbuf->RefCnt > 1);
179
180 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
181
182 NET_PUT_REF (Nbuf);
183
184 if (Nbuf->RefCnt == 1) {
185 //
186 // Trim all buffer contained in the Nbuf, then append it to the NbufQue.
187 //
188 NetbufTrim (Nbuf, Nbuf->TotalSize, NET_BUF_TAIL);
189
190 if (NetbufAllocSpace (Nbuf, NET_VLAN_TAG_LEN, NET_BUF_HEAD) != NULL) {
191 //
192 // There is space reserved for vlan tag in the head, reclaim it
193 //
194 NetbufTrim (Nbuf, NET_VLAN_TAG_LEN, NET_BUF_TAIL);
195 }
196
197 NetbufQueAppend (&MnpDeviceData->FreeNbufQue, Nbuf);
198 }
199
200 gBS->RestoreTPL (OldTpl);
201}
202
216 IN OUT MNP_DEVICE_DATA *MnpDeviceData,
217 IN UINTN Count
218 )
219{
220 EFI_STATUS Status;
221 UINT32 Index;
222 MNP_TX_BUF_WRAP *TxBufWrap;
223
224 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
225 ASSERT ((Count > 0) && (MnpDeviceData->BufferLength > 0));
226
227 Status = EFI_SUCCESS;
228 for (Index = 0; Index < Count; Index++) {
229 TxBufWrap = (MNP_TX_BUF_WRAP *)AllocatePool (OFFSET_OF (MNP_TX_BUF_WRAP, TxBuf) + MnpDeviceData->BufferLength);
230 if (TxBufWrap == NULL) {
231 DEBUG ((DEBUG_ERROR, "MnpAddFreeTxBuf: TxBuf Alloc failed.\n"));
232
233 Status = EFI_OUT_OF_RESOURCES;
234 break;
235 }
236
237 DEBUG ((DEBUG_VERBOSE, "MnpAddFreeTxBuf: Add TxBufWrap %p, TxBuf %p\n", TxBufWrap, TxBufWrap->TxBuf));
238 TxBufWrap->Signature = MNP_TX_BUF_WRAP_SIGNATURE;
239 TxBufWrap->InUse = FALSE;
240 InsertTailList (&MnpDeviceData->FreeTxBufList, &TxBufWrap->WrapEntry);
241 InsertTailList (&MnpDeviceData->AllTxBufList, &TxBufWrap->AllEntry);
242 }
243
244 MnpDeviceData->TxBufCount += Index;
245 return Status;
246}
247
259UINT8 *
261 IN OUT MNP_DEVICE_DATA *MnpDeviceData
262 )
263{
264 EFI_TPL OldTpl;
265 UINT8 *TxBuf;
266 EFI_STATUS Status;
267 LIST_ENTRY *Entry;
268 MNP_TX_BUF_WRAP *TxBufWrap;
269
270 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
271
272 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
273
274 if (IsListEmpty (&MnpDeviceData->FreeTxBufList)) {
275 //
276 // First try to recycle some TX buffer from SNP
277 //
278 Status = MnpRecycleTxBuf (MnpDeviceData);
279 if (EFI_ERROR (Status)) {
280 TxBuf = NULL;
281 goto ON_EXIT;
282 }
283
284 //
285 // If still no free TX buffer, allocate more.
286 //
287 if (IsListEmpty (&MnpDeviceData->FreeTxBufList)) {
288 if ((MnpDeviceData->TxBufCount + MNP_TX_BUFFER_INCREASEMENT) > MNP_MAX_TX_BUFFER_NUM) {
289 DEBUG (
290 (DEBUG_ERROR,
291 "MnpAllocTxBuf: The maximum TxBuf size is reached for MNP driver instance %p.\n",
292 MnpDeviceData)
293 );
294
295 TxBuf = NULL;
296 goto ON_EXIT;
297 }
298
299 Status = MnpAddFreeTxBuf (MnpDeviceData, MNP_TX_BUFFER_INCREASEMENT);
300 if (IsListEmpty (&MnpDeviceData->FreeTxBufList)) {
301 DEBUG (
302 (DEBUG_ERROR,
303 "MnpAllocNbuf: Failed to add TxBuf into the FreeTxBufList, %r.\n",
304 Status)
305 );
306
307 TxBuf = NULL;
308 goto ON_EXIT;
309 }
310 }
311 }
312
313 ASSERT (!IsListEmpty (&MnpDeviceData->FreeTxBufList));
314 Entry = MnpDeviceData->FreeTxBufList.ForwardLink;
315 RemoveEntryList (MnpDeviceData->FreeTxBufList.ForwardLink);
316 TxBufWrap = NET_LIST_USER_STRUCT_S (Entry, MNP_TX_BUF_WRAP, WrapEntry, MNP_TX_BUF_WRAP_SIGNATURE);
317 TxBufWrap->InUse = TRUE;
318 TxBuf = TxBufWrap->TxBuf;
319
320ON_EXIT:
321 gBS->RestoreTPL (OldTpl);
322
323 return TxBuf;
324}
325
333VOID
335 IN OUT MNP_DEVICE_DATA *MnpDeviceData,
336 IN OUT UINT8 *TxBuf
337 )
338{
339 MNP_TX_BUF_WRAP *TxBufWrap;
340 EFI_TPL OldTpl;
341
342 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
343
344 if (TxBuf == NULL) {
345 return;
346 }
347
348 TxBufWrap = NET_LIST_USER_STRUCT (TxBuf, MNP_TX_BUF_WRAP, TxBuf);
349 if (TxBufWrap->Signature != MNP_TX_BUF_WRAP_SIGNATURE) {
350 DEBUG (
351 (DEBUG_ERROR,
352 "MnpFreeTxBuf: Signature check failed in MnpFreeTxBuf.\n")
353 );
354 return;
355 }
356
357 if (!TxBufWrap->InUse) {
358 DEBUG (
359 (DEBUG_WARN,
360 "MnpFreeTxBuf: Duplicated recycle report from SNP.\n")
361 );
362 return;
363 }
364
365 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
366 InsertTailList (&MnpDeviceData->FreeTxBufList, &TxBufWrap->WrapEntry);
367 TxBufWrap->InUse = FALSE;
368 gBS->RestoreTPL (OldTpl);
369}
370
382 IN OUT MNP_DEVICE_DATA *MnpDeviceData
383 )
384{
385 UINT8 *TxBuf;
387 EFI_STATUS Status;
388
389 Snp = MnpDeviceData->Snp;
390 ASSERT (Snp != NULL);
391
392 do {
393 TxBuf = NULL;
394 Status = Snp->GetStatus (Snp, NULL, (VOID **)&TxBuf);
395 if (EFI_ERROR (Status)) {
396 return Status;
397 }
398
399 if (TxBuf != NULL) {
400 MnpFreeTxBuf (MnpDeviceData, TxBuf);
401 }
402 } while (TxBuf != NULL);
403
404 return EFI_SUCCESS;
405}
406
421 IN OUT MNP_DEVICE_DATA *MnpDeviceData,
422 IN EFI_HANDLE ImageHandle,
423 IN EFI_HANDLE ControllerHandle
424 )
425{
426 EFI_STATUS Status;
429
430 MnpDeviceData->Signature = MNP_DEVICE_DATA_SIGNATURE;
431 MnpDeviceData->ImageHandle = ImageHandle;
432 MnpDeviceData->ControllerHandle = ControllerHandle;
433
434 //
435 // Copy the MNP Protocol interfaces from the template.
436 //
437 CopyMem (&MnpDeviceData->VlanConfig, &mVlanConfigProtocolTemplate, sizeof (EFI_VLAN_CONFIG_PROTOCOL));
438
439 //
440 // Open the Simple Network protocol.
441 //
442 Status = gBS->OpenProtocol (
443 ControllerHandle,
444 &gEfiSimpleNetworkProtocolGuid,
445 (VOID **)&Snp,
446 ImageHandle,
447 ControllerHandle,
448 EFI_OPEN_PROTOCOL_BY_DRIVER
449 );
450 if (EFI_ERROR (Status)) {
451 return EFI_UNSUPPORTED;
452 }
453
454 //
455 // Get MTU from Snp.
456 //
457 SnpMode = Snp->Mode;
458 MnpDeviceData->Snp = Snp;
459
460 //
461 // Initialize the lists.
462 //
463 InitializeListHead (&MnpDeviceData->ServiceList);
464 InitializeListHead (&MnpDeviceData->GroupAddressList);
465
466 //
467 // Get the buffer length used to allocate NET_BUF to hold data received
468 // from SNP. Do this before fill the FreeNetBufQue.
469 //
470 //
471 MnpDeviceData->BufferLength = SnpMode->MediaHeaderSize + NET_VLAN_TAG_LEN + SnpMode->MaxPacketSize + NET_ETHER_FCS_SIZE;
472
473 //
474 // Make sure the protocol headers immediately following the media header
475 // 4-byte aligned, and also preserve additional space for VLAN tag
476 //
477 MnpDeviceData->PaddingSize = ((4 - SnpMode->MediaHeaderSize) & 0x3) + NET_VLAN_TAG_LEN;
478
479 //
480 // Initialize MAC string which will be used as VLAN configuration variable name
481 //
482 Status = NetLibGetMacString (ControllerHandle, ImageHandle, &MnpDeviceData->MacString);
483 if (EFI_ERROR (Status)) {
484 goto ERROR;
485 }
486
487 //
488 // Initialize the FreeNetBufQue and pre-allocate some NET_BUFs.
489 //
490 NetbufQueInit (&MnpDeviceData->FreeNbufQue);
491 Status = MnpAddFreeNbuf (MnpDeviceData, MNP_INIT_NET_BUFFER_NUM);
492 if (EFI_ERROR (Status)) {
493 DEBUG ((DEBUG_ERROR, "MnpInitializeDeviceData: MnpAddFreeNbuf failed, %r.\n", Status));
494
495 goto ERROR;
496 }
497
498 //
499 // Get one NET_BUF from the FreeNbufQue for rx cache.
500 //
501 MnpDeviceData->RxNbufCache = MnpAllocNbuf (MnpDeviceData);
503 MnpDeviceData->RxNbufCache,
504 MnpDeviceData->BufferLength,
505 NET_BUF_TAIL
506 );
507
508 //
509 // Allocate buffer pool for tx.
510 //
511 InitializeListHead (&MnpDeviceData->FreeTxBufList);
512 InitializeListHead (&MnpDeviceData->AllTxBufList);
513 MnpDeviceData->TxBufCount = 0;
514
515 //
516 // Create the system poll timer.
517 //
518 Status = gBS->CreateEvent (
519 EVT_NOTIFY_SIGNAL | EVT_TIMER,
520 TPL_CALLBACK,
522 MnpDeviceData,
523 &MnpDeviceData->PollTimer
524 );
525 if (EFI_ERROR (Status)) {
526 DEBUG ((DEBUG_ERROR, "MnpInitializeDeviceData: CreateEvent for poll timer failed.\n"));
527
528 goto ERROR;
529 }
530
531 //
532 // Create the timer for packet timeout check.
533 //
534 Status = gBS->CreateEvent (
535 EVT_NOTIFY_SIGNAL | EVT_TIMER,
536 TPL_CALLBACK,
538 MnpDeviceData,
539 &MnpDeviceData->TimeoutCheckTimer
540 );
541 if (EFI_ERROR (Status)) {
542 DEBUG ((DEBUG_ERROR, "MnpInitializeDeviceData: CreateEvent for packet timeout check failed.\n"));
543
544 goto ERROR;
545 }
546
547 //
548 // Create the timer for media detection.
549 //
550 Status = gBS->CreateEvent (
551 EVT_NOTIFY_SIGNAL | EVT_TIMER,
552 TPL_CALLBACK,
554 MnpDeviceData,
555 &MnpDeviceData->MediaDetectTimer
556 );
557 if (EFI_ERROR (Status)) {
558 DEBUG ((DEBUG_ERROR, "MnpInitializeDeviceData: CreateEvent for media detection failed.\n"));
559
560 goto ERROR;
561 }
562
563ERROR:
564 if (EFI_ERROR (Status)) {
565 //
566 // Free the dynamic allocated resources if necessary.
567 //
568 if (MnpDeviceData->MacString != NULL) {
569 FreePool (MnpDeviceData->MacString);
570 }
571
572 if (MnpDeviceData->TimeoutCheckTimer != NULL) {
573 gBS->CloseEvent (MnpDeviceData->TimeoutCheckTimer);
574 }
575
576 if (MnpDeviceData->MediaDetectTimer != NULL) {
577 gBS->CloseEvent (MnpDeviceData->MediaDetectTimer);
578 }
579
580 if (MnpDeviceData->PollTimer != NULL) {
581 gBS->CloseEvent (MnpDeviceData->PollTimer);
582 }
583
584 if (MnpDeviceData->RxNbufCache != NULL) {
585 MnpFreeNbuf (MnpDeviceData, MnpDeviceData->RxNbufCache);
586 }
587
588 if (MnpDeviceData->FreeNbufQue.BufNum != 0) {
589 NetbufQueFlush (&MnpDeviceData->FreeNbufQue);
590 }
591
592 //
593 // Close the Simple Network Protocol.
594 //
595 gBS->CloseProtocol (
596 ControllerHandle,
597 &gEfiSimpleNetworkProtocolGuid,
598 ImageHandle,
599 ControllerHandle
600 );
601 }
602
603 return Status;
604}
605
613VOID
615 IN OUT MNP_DEVICE_DATA *MnpDeviceData,
616 IN EFI_HANDLE ImageHandle
617 )
618{
619 LIST_ENTRY *Entry;
620 LIST_ENTRY *NextEntry;
621 MNP_TX_BUF_WRAP *TxBufWrap;
622
623 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
624
625 //
626 // Free Vlan Config variable name string
627 //
628 if (MnpDeviceData->MacString != NULL) {
629 FreePool (MnpDeviceData->MacString);
630 }
631
632 //
633 // The GroupAddressList must be empty.
634 //
635 ASSERT (IsListEmpty (&MnpDeviceData->GroupAddressList));
636
637 //
638 // Close the event.
639 //
640 gBS->CloseEvent (MnpDeviceData->TimeoutCheckTimer);
641 gBS->CloseEvent (MnpDeviceData->MediaDetectTimer);
642 gBS->CloseEvent (MnpDeviceData->PollTimer);
643
644 //
645 // Free the Tx buffer pool.
646 //
647 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &MnpDeviceData->AllTxBufList) {
648 TxBufWrap = NET_LIST_USER_STRUCT (Entry, MNP_TX_BUF_WRAP, AllEntry);
649 RemoveEntryList (Entry);
650 FreePool (TxBufWrap);
651 MnpDeviceData->TxBufCount--;
652 }
653 ASSERT (IsListEmpty (&MnpDeviceData->AllTxBufList));
654 ASSERT (MnpDeviceData->TxBufCount == 0);
655
656 //
657 // Free the RxNbufCache.
658 //
659 MnpFreeNbuf (MnpDeviceData, MnpDeviceData->RxNbufCache);
660
661 //
662 // Flush the FreeNbufQue.
663 //
664 MnpDeviceData->NbufCnt -= MnpDeviceData->FreeNbufQue.BufNum;
665 NetbufQueFlush (&MnpDeviceData->FreeNbufQue);
666
667 //
668 // Close the Simple Network Protocol.
669 //
670 gBS->CloseProtocol (
671 MnpDeviceData->ControllerHandle,
672 &gEfiSimpleNetworkProtocolGuid,
673 ImageHandle,
674 MnpDeviceData->ControllerHandle
675 );
676}
677
691 IN MNP_DEVICE_DATA *MnpDeviceData,
692 IN UINT16 VlanId,
693 IN UINT8 Priority OPTIONAL
694 )
695{
696 EFI_HANDLE MnpServiceHandle;
697 MNP_SERVICE_DATA *MnpServiceData;
698 EFI_STATUS Status;
700 EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
701
702 //
703 // Initialize the Mnp Service Data.
704 //
705 MnpServiceData = AllocateZeroPool (sizeof (MNP_SERVICE_DATA));
706 if (MnpServiceData == NULL) {
707 DEBUG ((DEBUG_ERROR, "MnpCreateServiceData: Failed to allocate memory for the new Mnp Service Data.\n"));
708
709 return NULL;
710 }
711
712 //
713 // Add to MNP service list
714 //
715 InsertTailList (&MnpDeviceData->ServiceList, &MnpServiceData->Link);
716
717 MnpServiceData->Signature = MNP_SERVICE_DATA_SIGNATURE;
718 MnpServiceData->MnpDeviceData = MnpDeviceData;
719
720 //
721 // Copy the ServiceBinding structure.
722 //
723 CopyMem (&MnpServiceData->ServiceBinding, &mMnpServiceBindingProtocol, sizeof (EFI_SERVICE_BINDING_PROTOCOL));
724
725 //
726 // Initialize the lists.
727 //
728 InitializeListHead (&MnpServiceData->ChildrenList);
729
730 SnpMode = MnpDeviceData->Snp->Mode;
731 if (VlanId != 0) {
732 //
733 // Create VLAN child handle
734 //
735 MnpServiceHandle = MnpCreateVlanChild (
736 MnpDeviceData->ImageHandle,
737 MnpDeviceData->ControllerHandle,
738 VlanId,
739 &MnpServiceData->DevicePath
740 );
741 if (MnpServiceHandle == NULL) {
742 DEBUG ((DEBUG_ERROR, "MnpCreateServiceData: Failed to create child handle.\n"));
743
744 return NULL;
745 }
746
747 //
748 // Open VLAN Config Protocol by child
749 //
750 Status = gBS->OpenProtocol (
751 MnpDeviceData->ControllerHandle,
752 &gEfiVlanConfigProtocolGuid,
753 (VOID **)&VlanConfig,
754 MnpDeviceData->ImageHandle,
755 MnpServiceHandle,
756 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
757 );
758 if (EFI_ERROR (Status)) {
759 goto Exit;
760 }
761
762 //
763 // Reduce MTU for VLAN device
764 //
765 MnpServiceData->Mtu = SnpMode->MaxPacketSize - NET_VLAN_TAG_LEN;
766 } else {
767 //
768 // VlanId set to 0 means rx/tx untagged frame
769 //
770 MnpServiceHandle = MnpDeviceData->ControllerHandle;
771 MnpServiceData->Mtu = SnpMode->MaxPacketSize;
772 }
773
774 MnpServiceData->ServiceHandle = MnpServiceHandle;
775 MnpServiceData->VlanId = VlanId;
776 MnpServiceData->Priority = Priority;
777
778 //
779 // Install the MNP Service Binding Protocol
780 //
781 Status = gBS->InstallMultipleProtocolInterfaces (
782 &MnpServiceHandle,
783 &gEfiManagedNetworkServiceBindingProtocolGuid,
784 &MnpServiceData->ServiceBinding,
785 NULL
786 );
787
788Exit:
789 if (EFI_ERROR (Status)) {
790 MnpDestroyServiceData (MnpServiceData);
791 MnpServiceData = NULL;
792 }
793
794 return MnpServiceData;
795}
796
808 IN OUT MNP_SERVICE_DATA *MnpServiceData
809 )
810{
811 EFI_STATUS Status;
812
813 //
814 // Uninstall the MNP Service Binding Protocol
815 //
816 Status = gBS->UninstallMultipleProtocolInterfaces (
817 MnpServiceData->ServiceHandle,
818 &gEfiManagedNetworkServiceBindingProtocolGuid,
819 &MnpServiceData->ServiceBinding,
820 NULL
821 );
822 if (EFI_ERROR (Status)) {
823 return Status;
824 }
825
826 if (MnpServiceData->VlanId != 0) {
827 //
828 // Close VlanConfig Protocol opened by VLAN child handle
829 //
830 Status = gBS->CloseProtocol (
831 MnpServiceData->MnpDeviceData->ControllerHandle,
832 &gEfiVlanConfigProtocolGuid,
833 MnpServiceData->MnpDeviceData->ImageHandle,
834 MnpServiceData->ServiceHandle
835 );
836 if (EFI_ERROR (Status)) {
837 return Status;
838 }
839
840 //
841 // Uninstall Device Path Protocol to destroy the VLAN child handle
842 //
843 Status = gBS->UninstallMultipleProtocolInterfaces (
844 MnpServiceData->ServiceHandle,
845 &gEfiDevicePathProtocolGuid,
846 MnpServiceData->DevicePath,
847 NULL
848 );
849 if (EFI_ERROR (Status)) {
850 return Status;
851 }
852
853 if (MnpServiceData->DevicePath != NULL) {
854 FreePool (MnpServiceData->DevicePath);
855 }
856 }
857
858 //
859 // Remove from MnpDeviceData service list
860 //
861 RemoveEntryList (&MnpServiceData->Link);
862
863 FreePool (MnpServiceData);
864
865 return Status;
866}
867
879EFIAPI
881 IN LIST_ENTRY *Entry,
882 IN VOID *Context
883 )
884{
885 MNP_INSTANCE_DATA *Instance;
886 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
887
888 ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *)Context;
889 Instance = CR (Entry, MNP_INSTANCE_DATA, InstEntry, MNP_INSTANCE_DATA_SIGNATURE);
890 return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
891}
892
904 IN OUT MNP_SERVICE_DATA *MnpServiceData
905 )
906{
907 LIST_ENTRY *List;
908 EFI_STATUS Status;
909 UINTN ListLength;
910
911 List = &MnpServiceData->ChildrenList;
912
913 Status = NetDestroyLinkList (
914 List,
916 &MnpServiceData->ServiceBinding,
917 &ListLength
918 );
919 if (EFI_ERROR (Status) || (ListLength != 0)) {
920 return EFI_DEVICE_ERROR;
921 }
922
923 return EFI_SUCCESS;
924}
925
937 IN MNP_DEVICE_DATA *MnpDeviceData,
938 IN UINT16 VlanId
939 )
940{
941 LIST_ENTRY *Entry;
942 MNP_SERVICE_DATA *MnpServiceData;
943
944 NET_LIST_FOR_EACH (Entry, &MnpDeviceData->ServiceList) {
945 //
946 // Check VLAN ID of each Mnp Service Data
947 //
948 MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);
949 if (MnpServiceData->VlanId == VlanId) {
950 return MnpServiceData;
951 }
952 }
953
954 return NULL;
955}
956
965VOID
967 IN MNP_SERVICE_DATA *MnpServiceData,
968 IN OUT MNP_INSTANCE_DATA *Instance
969 )
970{
971 NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
972 ASSERT (Instance != NULL);
973
974 //
975 // Set the signature.
976 //
977 Instance->Signature = MNP_INSTANCE_DATA_SIGNATURE;
978
979 //
980 // Copy the MNP Protocol interfaces from the template.
981 //
982 CopyMem (&Instance->ManagedNetwork, &mMnpProtocolTemplate, sizeof (Instance->ManagedNetwork));
983
984 //
985 // Copy the default config data.
986 //
987 CopyMem (&Instance->ConfigData, &mMnpDefaultConfigData, sizeof (Instance->ConfigData));
988
989 //
990 // Initialize the lists.
991 //
992 InitializeListHead (&Instance->GroupCtrlBlkList);
993 InitializeListHead (&Instance->RcvdPacketQueue);
994 InitializeListHead (&Instance->RxDeliveredPacketQueue);
995
996 //
997 // Initialize the RxToken Map.
998 //
999 NetMapInit (&Instance->RxTokenMap);
1000
1001 //
1002 // Save the MnpServiceData info.
1003 //
1004 Instance->MnpServiceData = MnpServiceData;
1005}
1006
1022EFIAPI
1024 IN NET_MAP *Map,
1025 IN NET_MAP_ITEM *Item,
1026 IN VOID *Arg
1027 )
1028{
1031
1033 TokenInItem = (EFI_MANAGED_NETWORK_COMPLETION_TOKEN *)Item->Key;
1034
1035 if ((Token == TokenInItem) || (Token->Event == TokenInItem->Event)) {
1036 //
1037 // The token is the same either the two tokens equals or the Events in
1038 // the two tokens are the same.
1039 //
1040 return EFI_ACCESS_DENIED;
1041 }
1042
1043 return EFI_SUCCESS;
1044}
1045
1062EFIAPI
1064 IN OUT NET_MAP *Map,
1065 IN OUT NET_MAP_ITEM *Item,
1066 IN VOID *Arg
1067 )
1068{
1070
1071 if ((Arg != NULL) && (Item->Key != Arg)) {
1072 //
1073 // The token in Item is not the token specified by Arg.
1074 //
1075 return EFI_SUCCESS;
1076 }
1077
1078 TokenToCancel = (EFI_MANAGED_NETWORK_COMPLETION_TOKEN *)Item->Key;
1079
1080 //
1081 // Remove the item from the map.
1082 //
1083 NetMapRemoveItem (Map, Item, NULL);
1084
1085 //
1086 // Cancel this token with status set to EFI_ABORTED.
1087 //
1088 TokenToCancel->Status = EFI_ABORTED;
1089 gBS->SignalEvent (TokenToCancel->Event);
1090
1091 if (Arg != NULL) {
1092 //
1093 // Only abort the token specified by Arg if Arg isn't NULL.
1094 //
1095 return EFI_ABORTED;
1096 }
1097
1098 return EFI_SUCCESS;
1099}
1100
1113 )
1114{
1115 EFI_STATUS Status;
1116
1117 ASSERT (Snp != NULL);
1118
1119 //
1120 // Start the simple network.
1121 //
1122 Status = Snp->Start (Snp);
1123
1124 if (!EFI_ERROR (Status)) {
1125 //
1126 // Initialize the simple network.
1127 //
1128 Status = Snp->Initialize (Snp, 0, 0);
1129 }
1130
1131 return Status;
1132}
1133
1145 IN MNP_DEVICE_DATA *MnpDeviceData
1146 )
1147{
1148 EFI_STATUS Status;
1150
1151 Snp = MnpDeviceData->Snp;
1152 ASSERT (Snp != NULL);
1153
1154 //
1155 // Recycle all the transmit buffer from SNP.
1156 //
1157 Status = MnpRecycleTxBuf (MnpDeviceData);
1158 if (EFI_ERROR (Status)) {
1159 return Status;
1160 }
1161
1162 //
1163 // Shut down the simple network.
1164 //
1165 Status = Snp->Shutdown (Snp);
1166 if (!EFI_ERROR (Status)) {
1167 //
1168 // Stop the simple network.
1169 //
1170 Status = Snp->Stop (Snp);
1171 }
1172
1173 return Status;
1174}
1175
1192 IN OUT MNP_SERVICE_DATA *MnpServiceData,
1193 IN BOOLEAN IsConfigUpdate,
1194 IN BOOLEAN EnableSystemPoll
1195 )
1196{
1197 EFI_STATUS Status;
1198 EFI_TIMER_DELAY TimerOpType;
1199 MNP_DEVICE_DATA *MnpDeviceData;
1200
1201 NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
1202
1203 Status = EFI_SUCCESS;
1204 MnpDeviceData = MnpServiceData->MnpDeviceData;
1205
1206 if (!IsConfigUpdate) {
1207 //
1208 // If it's not a configuration update, increase the configured children number.
1209 //
1210 MnpDeviceData->ConfiguredChildrenNumber++;
1211
1212 if (MnpDeviceData->ConfiguredChildrenNumber == 1) {
1213 //
1214 // It's the first configured child, start the simple network.
1215 //
1216 Status = MnpStartSnp (MnpDeviceData->Snp);
1217 if (EFI_ERROR (Status)) {
1218 DEBUG ((DEBUG_ERROR, "MnpStart: MnpStartSnp failed, %r.\n", Status));
1219
1220 goto ErrorExit;
1221 }
1222
1223 //
1224 // Start the timeout timer.
1225 //
1226 Status = gBS->SetTimer (
1227 MnpDeviceData->TimeoutCheckTimer,
1229 MNP_TIMEOUT_CHECK_INTERVAL
1230 );
1231 if (EFI_ERROR (Status)) {
1232 DEBUG (
1233 (DEBUG_ERROR,
1234 "MnpStart, gBS->SetTimer for TimeoutCheckTimer %r.\n",
1235 Status)
1236 );
1237
1238 goto ErrorExit;
1239 }
1240
1241 //
1242 // Start the media detection timer.
1243 //
1244 Status = gBS->SetTimer (
1245 MnpDeviceData->MediaDetectTimer,
1247 MNP_MEDIA_DETECT_INTERVAL
1248 );
1249 if (EFI_ERROR (Status)) {
1250 DEBUG (
1251 (DEBUG_ERROR,
1252 "MnpStart, gBS->SetTimer for MediaDetectTimer %r.\n",
1253 Status)
1254 );
1255
1256 goto ErrorExit;
1257 }
1258 }
1259 }
1260
1261 if (MnpDeviceData->EnableSystemPoll ^ EnableSystemPoll) {
1262 //
1263 // The EnableSystemPoll differs with the current state, disable or enable
1264 // the system poll.
1265 //
1266 TimerOpType = EnableSystemPoll ? TimerPeriodic : TimerCancel;
1267
1268 Status = gBS->SetTimer (MnpDeviceData->PollTimer, TimerOpType, MNP_SYS_POLL_INTERVAL);
1269 if (EFI_ERROR (Status)) {
1270 DEBUG ((DEBUG_ERROR, "MnpStart: gBS->SetTimer for PollTimer failed, %r.\n", Status));
1271
1272 goto ErrorExit;
1273 }
1274
1275 MnpDeviceData->EnableSystemPoll = EnableSystemPoll;
1276 }
1277
1278 //
1279 // Change the receive filters if need.
1280 //
1281 Status = MnpConfigReceiveFilters (MnpDeviceData);
1282
1283ErrorExit:
1284 return Status;
1285}
1286
1298 IN OUT MNP_SERVICE_DATA *MnpServiceData
1299 )
1300{
1301 EFI_STATUS Status;
1302 MNP_DEVICE_DATA *MnpDeviceData;
1303
1304 NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
1305 MnpDeviceData = MnpServiceData->MnpDeviceData;
1306 ASSERT (MnpDeviceData->ConfiguredChildrenNumber > 0);
1307
1308 //
1309 // Configure the receive filters.
1310 //
1311 MnpConfigReceiveFilters (MnpDeviceData);
1312
1313 //
1314 // Decrease the children number.
1315 //
1316 MnpDeviceData->ConfiguredChildrenNumber--;
1317
1318 if (MnpDeviceData->ConfiguredChildrenNumber > 0) {
1319 //
1320 // If there are other configured children, return and keep the timers and
1321 // simple network unchanged.
1322 //
1323 return EFI_SUCCESS;
1324 }
1325
1326 //
1327 // No configured children now.
1328 //
1329 if (MnpDeviceData->EnableSystemPoll) {
1330 //
1331 // The system poll in on, cancel the poll timer.
1332 //
1333 Status = gBS->SetTimer (MnpDeviceData->PollTimer, TimerCancel, 0);
1334 MnpDeviceData->EnableSystemPoll = FALSE;
1335 }
1336
1337 //
1338 // Cancel the timeout timer.
1339 //
1340 Status = gBS->SetTimer (MnpDeviceData->TimeoutCheckTimer, TimerCancel, 0);
1341
1342 //
1343 // Cancel the media detect timer.
1344 //
1345 Status = gBS->SetTimer (MnpDeviceData->MediaDetectTimer, TimerCancel, 0);
1346
1347 //
1348 // Stop the simple network.
1349 //
1350 Status = MnpStopSnp (MnpDeviceData);
1351 return Status;
1352}
1353
1360VOID
1362 IN OUT MNP_INSTANCE_DATA *Instance
1363 )
1364{
1365 EFI_TPL OldTpl;
1366 MNP_RXDATA_WRAP *RxDataWrap;
1367
1368 NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);
1369
1370 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1371
1372 while (!IsListEmpty (&Instance->RcvdPacketQueue)) {
1373 //
1374 // Remove all the Wraps.
1375 //
1376 RxDataWrap = NET_LIST_HEAD (&Instance->RcvdPacketQueue, MNP_RXDATA_WRAP, WrapEntry);
1377
1378 //
1379 // Recycle the RxDataWrap.
1380 //
1381 MnpRecycleRxData (NULL, (VOID *)RxDataWrap);
1382 Instance->RcvdPacketQueueSize--;
1383 }
1384
1385 ASSERT (Instance->RcvdPacketQueueSize == 0);
1386
1387 gBS->RestoreTPL (OldTpl);
1388}
1389
1405 IN OUT MNP_INSTANCE_DATA *Instance,
1406 IN EFI_MANAGED_NETWORK_CONFIG_DATA *ConfigData OPTIONAL
1407 )
1408{
1409 EFI_STATUS Status;
1410 MNP_SERVICE_DATA *MnpServiceData;
1411 MNP_DEVICE_DATA *MnpDeviceData;
1412 EFI_MANAGED_NETWORK_CONFIG_DATA *OldConfigData;
1413 EFI_MANAGED_NETWORK_CONFIG_DATA *NewConfigData;
1414 BOOLEAN IsConfigUpdate;
1415
1416 NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);
1417
1418 if ((ConfigData != NULL) && ConfigData->EnableReceiveTimestamps) {
1419 //
1420 // Don't support timestamp.
1421 //
1422 return EFI_UNSUPPORTED;
1423 }
1424
1425 Status = EFI_SUCCESS;
1426
1427 MnpServiceData = Instance->MnpServiceData;
1428 MnpDeviceData = MnpServiceData->MnpDeviceData;
1429 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
1430
1431 IsConfigUpdate = (BOOLEAN)((Instance->Configured) && (ConfigData != NULL));
1432
1433 OldConfigData = &Instance->ConfigData;
1434 NewConfigData = ConfigData;
1435 if (NewConfigData == NULL) {
1436 //
1437 // Restore back the default config data if a reset of this instance
1438 // is required.
1439 //
1440 NewConfigData = &mMnpDefaultConfigData;
1441 }
1442
1443 //
1444 // Reset the instance's receive filter.
1445 //
1446 Instance->ReceiveFilter = 0;
1447
1448 //
1449 // Clear the receive counters according to the old ConfigData.
1450 //
1451 if (OldConfigData->EnableUnicastReceive) {
1452 MnpDeviceData->UnicastCount--;
1453 }
1454
1455 if (OldConfigData->EnableMulticastReceive) {
1456 MnpDeviceData->MulticastCount--;
1457 }
1458
1459 if (OldConfigData->EnableBroadcastReceive) {
1460 MnpDeviceData->BroadcastCount--;
1461 }
1462
1463 if (OldConfigData->EnablePromiscuousReceive) {
1464 MnpDeviceData->PromiscuousCount--;
1465 }
1466
1467 //
1468 // Set the receive filter counters and the receive filter of the
1469 // instance according to the new ConfigData.
1470 //
1471 if (NewConfigData->EnableUnicastReceive) {
1472 MnpDeviceData->UnicastCount++;
1473 Instance->ReceiveFilter |= MNP_RECEIVE_UNICAST;
1474 }
1475
1476 if (NewConfigData->EnableMulticastReceive) {
1477 MnpDeviceData->MulticastCount++;
1478 }
1479
1480 if (NewConfigData->EnableBroadcastReceive) {
1481 MnpDeviceData->BroadcastCount++;
1482 Instance->ReceiveFilter |= MNP_RECEIVE_BROADCAST;
1483 }
1484
1485 if (NewConfigData->EnablePromiscuousReceive) {
1486 MnpDeviceData->PromiscuousCount++;
1487 }
1488
1489 if (OldConfigData->FlushQueuesOnReset) {
1490 MnpFlushRcvdDataQueue (Instance);
1491 }
1492
1493 if (ConfigData == NULL) {
1494 Instance->ManagedNetwork.Cancel (&Instance->ManagedNetwork, NULL);
1495 }
1496
1497 if (!NewConfigData->EnableMulticastReceive) {
1498 MnpGroupOp (Instance, FALSE, NULL, NULL);
1499 }
1500
1501 //
1502 // Save the new configuration data.
1503 //
1504 CopyMem (OldConfigData, NewConfigData, sizeof (*OldConfigData));
1505
1506 Instance->Configured = (BOOLEAN)(ConfigData != NULL);
1507 if (Instance->Configured) {
1508 //
1509 // The instance is configured, start the Mnp.
1510 //
1511 Status = MnpStart (
1512 MnpServiceData,
1513 IsConfigUpdate,
1514 (BOOLEAN) !NewConfigData->DisableBackgroundPolling
1515 );
1516 } else {
1517 //
1518 // The instance is changed to the unconfigured state, stop the Mnp.
1519 //
1520 Status = MnpStop (MnpServiceData);
1521 }
1522
1523 return Status;
1524}
1525
1539 IN MNP_DEVICE_DATA *MnpDeviceData
1540 )
1541{
1542 EFI_STATUS Status;
1544 EFI_MAC_ADDRESS *MCastFilter;
1545 UINT32 MCastFilterCnt;
1546 UINT32 EnableFilterBits;
1547 UINT32 DisableFilterBits;
1548 BOOLEAN ResetMCastFilters;
1549 LIST_ENTRY *Entry;
1550 UINT32 Index;
1551 MNP_GROUP_ADDRESS *GroupAddress;
1552
1553 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
1554
1555 Snp = MnpDeviceData->Snp;
1556
1557 //
1558 // Initialize the enable filter and disable filter.
1559 //
1560 EnableFilterBits = 0;
1561 DisableFilterBits = Snp->Mode->ReceiveFilterMask;
1562
1563 if (MnpDeviceData->UnicastCount != 0) {
1564 //
1565 // Enable unicast if any instance wants to receive unicast.
1566 //
1567 EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
1568 }
1569
1570 if (MnpDeviceData->BroadcastCount != 0) {
1571 //
1572 // Enable broadcast if any instance wants to receive broadcast.
1573 //
1574 EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
1575 }
1576
1577 MCastFilter = NULL;
1578 MCastFilterCnt = 0;
1579 ResetMCastFilters = TRUE;
1580
1581 if ((MnpDeviceData->MulticastCount != 0) && (MnpDeviceData->GroupAddressCount != 0)) {
1582 //
1583 // There are instances configured to receive multicast and already some group
1584 // addresses are joined.
1585 //
1586
1587 ResetMCastFilters = FALSE;
1588
1589 if (MnpDeviceData->GroupAddressCount <= Snp->Mode->MaxMCastFilterCount) {
1590 //
1591 // The joind group address is less than simple network's maximum count.
1592 // Just configure the snp to do the multicast filtering.
1593 //
1594
1595 EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST;
1596
1597 //
1598 // Allocate pool for the multicast addresses.
1599 //
1600 MCastFilterCnt = MnpDeviceData->GroupAddressCount;
1601 MCastFilter = AllocatePool (sizeof (EFI_MAC_ADDRESS) * MCastFilterCnt);
1602 if (MCastFilter == NULL) {
1603 DEBUG ((DEBUG_ERROR, "MnpConfigReceiveFilters: Failed to allocate memory resource for MCastFilter.\n"));
1604
1605 return EFI_OUT_OF_RESOURCES;
1606 }
1607
1608 //
1609 // Fill the multicast HW address buffer.
1610 //
1611 Index = 0;
1612 NET_LIST_FOR_EACH (Entry, &MnpDeviceData->GroupAddressList) {
1613 GroupAddress = NET_LIST_USER_STRUCT (Entry, MNP_GROUP_ADDRESS, AddrEntry);
1614 CopyMem (MCastFilter + Index, &GroupAddress->Address, sizeof (*(MCastFilter + Index)));
1615 Index++;
1616
1617 ASSERT (Index <= MCastFilterCnt);
1618 }
1619 } else {
1620 //
1621 // The maximum multicast is reached, set the filter to be promiscuous
1622 // multicast.
1623 //
1624
1625 if ((Snp->Mode->ReceiveFilterMask & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
1626 EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
1627 } else {
1628 //
1629 // Either MULTICAST or PROMISCUOUS_MULTICAST is not supported by Snp,
1630 // set the NIC to be promiscuous although this will tremendously degrade
1631 // the performance.
1632 //
1633 EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;
1634 }
1635 }
1636 }
1637
1638 if (MnpDeviceData->PromiscuousCount != 0) {
1639 //
1640 // Enable promiscuous if any instance wants to receive promiscuous.
1641 //
1642 EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;
1643 }
1644
1645 //
1646 // Set the disable filter.
1647 //
1648 DisableFilterBits ^= EnableFilterBits;
1649
1650 //
1651 // Configure the receive filters of SNP.
1652 //
1653 Status = Snp->ReceiveFilters (
1654 Snp,
1655 EnableFilterBits,
1656 DisableFilterBits,
1657 ResetMCastFilters,
1658 MCastFilterCnt,
1659 MCastFilter
1660 );
1662 if (EFI_ERROR (Status)) {
1663 DEBUG (
1664 (DEBUG_ERROR,
1665 "MnpConfigReceiveFilters: Snp->ReceiveFilters failed, %r.\n",
1666 Status)
1667 );
1668 }
1669
1670 DEBUG_CODE_END ();
1671
1672 if (MCastFilter != NULL) {
1673 //
1674 // Free the buffer used to hold the group addresses.
1675 //
1676 FreePool (MCastFilter);
1677 }
1678
1679 return Status;
1680}
1681
1698 IN OUT MNP_INSTANCE_DATA *Instance,
1700 IN OUT MNP_GROUP_ADDRESS *GroupAddress OPTIONAL,
1701 IN EFI_MAC_ADDRESS *MacAddress,
1702 IN UINT32 HwAddressSize
1703 )
1704{
1705 MNP_DEVICE_DATA *MnpDeviceData;
1706
1707 NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);
1708
1709 MnpDeviceData = Instance->MnpServiceData->MnpDeviceData;
1710 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
1711
1712 if (GroupAddress == NULL) {
1713 ASSERT (MacAddress != NULL);
1714
1715 //
1716 // Allocate a new GroupAddress to be added into MNP's GroupAddressList.
1717 //
1718 GroupAddress = AllocatePool (sizeof (MNP_GROUP_ADDRESS));
1719 if (GroupAddress == NULL) {
1720 DEBUG ((DEBUG_ERROR, "MnpGroupOpFormCtrlBlk: Failed to allocate memory resource.\n"));
1721
1722 return EFI_OUT_OF_RESOURCES;
1723 }
1724
1725 CopyMem (&GroupAddress->Address, MacAddress, sizeof (GroupAddress->Address));
1726 GroupAddress->RefCnt = 0;
1728 &MnpDeviceData->GroupAddressList,
1729 &GroupAddress->AddrEntry
1730 );
1731 MnpDeviceData->GroupAddressCount++;
1732 }
1733
1734 //
1735 // Increase the RefCnt.
1736 //
1737 GroupAddress->RefCnt++;
1738
1739 //
1740 // Add the CtrlBlk into the instance's GroupCtrlBlkList.
1741 //
1742 CtrlBlk->GroupAddress = GroupAddress;
1743 InsertTailList (&Instance->GroupCtrlBlkList, &CtrlBlk->CtrlBlkEntry);
1744
1745 return EFI_SUCCESS;
1746}
1747
1758BOOLEAN
1760 IN MNP_INSTANCE_DATA *Instance,
1762 )
1763{
1764 MNP_DEVICE_DATA *MnpDeviceData;
1765 MNP_GROUP_ADDRESS *GroupAddress;
1766
1767 NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);
1768
1769 MnpDeviceData = Instance->MnpServiceData->MnpDeviceData;
1770 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
1771
1772 //
1773 // Remove and free the CtrlBlk.
1774 //
1775 GroupAddress = CtrlBlk->GroupAddress;
1776 RemoveEntryList (&CtrlBlk->CtrlBlkEntry);
1777 FreePool (CtrlBlk);
1778
1779 ASSERT (GroupAddress->RefCnt > 0);
1780
1781 //
1782 // Count down the RefCnt.
1783 //
1784 GroupAddress->RefCnt--;
1785
1786 if (GroupAddress->RefCnt == 0) {
1787 //
1788 // Free this GroupAddress entry if no instance uses it.
1789 //
1790 MnpDeviceData->GroupAddressCount--;
1791 RemoveEntryList (&GroupAddress->AddrEntry);
1792 FreePool (GroupAddress);
1793
1794 return TRUE;
1795 }
1796
1797 return FALSE;
1798}
1799
1817 IN OUT MNP_INSTANCE_DATA *Instance,
1818 IN BOOLEAN JoinFlag,
1819 IN EFI_MAC_ADDRESS *MacAddress OPTIONAL,
1820 IN MNP_GROUP_CONTROL_BLOCK *CtrlBlk OPTIONAL
1821 )
1822{
1823 MNP_DEVICE_DATA *MnpDeviceData;
1824 LIST_ENTRY *Entry;
1825 LIST_ENTRY *NextEntry;
1826 MNP_GROUP_ADDRESS *GroupAddress;
1827 EFI_SIMPLE_NETWORK_MODE *SnpMode;
1828 MNP_GROUP_CONTROL_BLOCK *NewCtrlBlk;
1829 EFI_STATUS Status;
1830 BOOLEAN AddressExist;
1831 BOOLEAN NeedUpdate;
1832
1833 NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);
1834
1835 MnpDeviceData = Instance->MnpServiceData->MnpDeviceData;
1836 SnpMode = MnpDeviceData->Snp->Mode;
1837
1838 if (JoinFlag) {
1839 //
1840 // A new group address is to be added.
1841 //
1842 GroupAddress = NULL;
1843 AddressExist = FALSE;
1844
1845 //
1846 // Allocate memory for the control block.
1847 //
1848 NewCtrlBlk = AllocatePool (sizeof (MNP_GROUP_CONTROL_BLOCK));
1849 if (NewCtrlBlk == NULL) {
1850 DEBUG ((DEBUG_ERROR, "MnpGroupOp: Failed to allocate memory resource.\n"));
1851
1852 return EFI_OUT_OF_RESOURCES;
1853 }
1854
1855 NET_LIST_FOR_EACH (Entry, &MnpDeviceData->GroupAddressList) {
1856 //
1857 // Check whether the MacAddress is already joined by other instances.
1858 //
1859 GroupAddress = NET_LIST_USER_STRUCT (Entry, MNP_GROUP_ADDRESS, AddrEntry);
1860 if (CompareMem (MacAddress, &GroupAddress->Address, SnpMode->HwAddressSize) == 0) {
1861 AddressExist = TRUE;
1862 break;
1863 }
1864 }
1865
1866 if (!AddressExist) {
1867 GroupAddress = NULL;
1868 }
1869
1870 //
1871 // Add the GroupAddress for this instance.
1872 //
1873 Status = MnpGroupOpAddCtrlBlk (
1874 Instance,
1875 NewCtrlBlk,
1876 GroupAddress,
1877 MacAddress,
1878 SnpMode->HwAddressSize
1879 );
1880 if (EFI_ERROR (Status)) {
1881 return Status;
1882 }
1883
1884 NeedUpdate = TRUE;
1885 } else {
1886 if (MacAddress != NULL) {
1887 ASSERT (CtrlBlk != NULL);
1888
1889 //
1890 // Leave the specific multicast mac address.
1891 //
1892 NeedUpdate = MnpGroupOpDelCtrlBlk (Instance, CtrlBlk);
1893 } else {
1894 //
1895 // Leave all multicast mac addresses.
1896 //
1897 NeedUpdate = FALSE;
1898
1899 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Instance->GroupCtrlBlkList) {
1900 NewCtrlBlk = NET_LIST_USER_STRUCT (
1901 Entry,
1903 CtrlBlkEntry
1904 );
1905 //
1906 // Update is required if the group address left is no longer used
1907 // by other instances.
1908 //
1909 NeedUpdate = MnpGroupOpDelCtrlBlk (Instance, NewCtrlBlk);
1910 }
1911 }
1912 }
1913
1914 Status = EFI_SUCCESS;
1915
1916 if (NeedUpdate) {
1917 //
1918 // Reconfigure the receive filters if necessary.
1919 //
1920 Status = MnpConfigReceiveFilters (MnpDeviceData);
1921 }
1922
1923 return Status;
1924}
UINT64 UINTN
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OFFSET_OF(TYPE, Field)
Definition: Base.h:758
#define OUT
Definition: Base.h:284
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:564
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE_END()
Definition: DebugLib.h:578
#define CR(Record, TYPE, Field, TestSignature)
Definition: DebugLib.h:659
EFI_STATUS MnpStopSnp(IN MNP_DEVICE_DATA *MnpDeviceData)
Definition: MnpConfig.c:1144
VOID MnpFreeTxBuf(IN OUT MNP_DEVICE_DATA *MnpDeviceData, IN OUT UINT8 *TxBuf)
Definition: MnpConfig.c:334
EFI_STATUS MnpGroupOpAddCtrlBlk(IN OUT MNP_INSTANCE_DATA *Instance, IN OUT MNP_GROUP_CONTROL_BLOCK *CtrlBlk, IN OUT MNP_GROUP_ADDRESS *GroupAddress OPTIONAL, IN EFI_MAC_ADDRESS *MacAddress, IN UINT32 HwAddressSize)
Definition: MnpConfig.c:1697
EFI_STATUS EFIAPI MnpCancelTokens(IN OUT NET_MAP *Map, IN OUT NET_MAP_ITEM *Item, IN VOID *Arg)
Definition: MnpConfig.c:1063
BOOLEAN MnpGroupOpDelCtrlBlk(IN MNP_INSTANCE_DATA *Instance, IN MNP_GROUP_CONTROL_BLOCK *CtrlBlk)
Definition: MnpConfig.c:1759
EFI_STATUS MnpGroupOp(IN OUT MNP_INSTANCE_DATA *Instance, IN BOOLEAN JoinFlag, IN EFI_MAC_ADDRESS *MacAddress OPTIONAL, IN MNP_GROUP_CONTROL_BLOCK *CtrlBlk OPTIONAL)
Definition: MnpConfig.c:1816
MNP_SERVICE_DATA * MnpFindServiceData(IN MNP_DEVICE_DATA *MnpDeviceData, IN UINT16 VlanId)
Definition: MnpConfig.c:936
EFI_STATUS MnpDestroyServiceChild(IN OUT MNP_SERVICE_DATA *MnpServiceData)
Definition: MnpConfig.c:903
UINT8 * MnpAllocTxBuf(IN OUT MNP_DEVICE_DATA *MnpDeviceData)
Definition: MnpConfig.c:260
EFI_STATUS MnpStartSnp(IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp)
Definition: MnpConfig.c:1111
EFI_STATUS MnpDestroyServiceData(IN OUT MNP_SERVICE_DATA *MnpServiceData)
Definition: MnpConfig.c:807
EFI_STATUS EFIAPI MnpTokenExist(IN NET_MAP *Map, IN NET_MAP_ITEM *Item, IN VOID *Arg)
Definition: MnpConfig.c:1023
EFI_STATUS MnpConfigReceiveFilters(IN MNP_DEVICE_DATA *MnpDeviceData)
Definition: MnpConfig.c:1538
EFI_STATUS MnpAddFreeTxBuf(IN OUT MNP_DEVICE_DATA *MnpDeviceData, IN UINTN Count)
Definition: MnpConfig.c:215
EFI_STATUS MnpStart(IN OUT MNP_SERVICE_DATA *MnpServiceData, IN BOOLEAN IsConfigUpdate, IN BOOLEAN EnableSystemPoll)
Definition: MnpConfig.c:1191
EFI_STATUS MnpAddFreeNbuf(IN OUT MNP_DEVICE_DATA *MnpDeviceData, IN UINTN Count)
Definition: MnpConfig.c:54
VOID MnpDestroyDeviceData(IN OUT MNP_DEVICE_DATA *MnpDeviceData, IN EFI_HANDLE ImageHandle)
Definition: MnpConfig.c:614
EFI_STATUS MnpInitializeDeviceData(IN OUT MNP_DEVICE_DATA *MnpDeviceData, IN EFI_HANDLE ImageHandle, IN EFI_HANDLE ControllerHandle)
Definition: MnpConfig.c:420
EFI_STATUS EFIAPI MnpDestoryChildEntry(IN LIST_ENTRY *Entry, IN VOID *Context)
Definition: MnpConfig.c:880
EFI_STATUS MnpConfigureInstance(IN OUT MNP_INSTANCE_DATA *Instance, IN EFI_MANAGED_NETWORK_CONFIG_DATA *ConfigData OPTIONAL)
Definition: MnpConfig.c:1404
VOID MnpFreeNbuf(IN OUT MNP_DEVICE_DATA *MnpDeviceData, IN OUT NET_BUF *Nbuf)
Definition: MnpConfig.c:170
MNP_SERVICE_DATA * MnpCreateServiceData(IN MNP_DEVICE_DATA *MnpDeviceData, IN UINT16 VlanId, IN UINT8 Priority OPTIONAL)
Definition: MnpConfig.c:690
EFI_STATUS MnpRecycleTxBuf(IN OUT MNP_DEVICE_DATA *MnpDeviceData)
Definition: MnpConfig.c:381
NET_BUF * MnpAllocNbuf(IN OUT MNP_DEVICE_DATA *MnpDeviceData)
Definition: MnpConfig.c:103
VOID MnpInitializeInstanceData(IN MNP_SERVICE_DATA *MnpServiceData, IN OUT MNP_INSTANCE_DATA *Instance)
Definition: MnpConfig.c:966
VOID MnpFlushRcvdDataQueue(IN OUT MNP_INSTANCE_DATA *Instance)
Definition: MnpConfig.c:1361
EFI_STATUS MnpStop(IN OUT MNP_SERVICE_DATA *MnpServiceData)
Definition: MnpConfig.c:1297
EFI_STATUS EFIAPI MnpServiceBindingDestroyChild(IN EFI_SERVICE_BINDING_PROTOCOL *This, IN EFI_HANDLE ChildHandle)
Definition: MnpDriver.c:546
EFI_STATUS EFIAPI MnpServiceBindingCreateChild(IN EFI_SERVICE_BINDING_PROTOCOL *This, IN OUT EFI_HANDLE *ChildHandle)
Definition: MnpDriver.c:430
EFI_STATUS EFIAPI MnpMcastIpToMac(IN EFI_MANAGED_NETWORK_PROTOCOL *This, IN BOOLEAN Ipv6Flag, IN EFI_IP_ADDRESS *IpAddress, OUT EFI_MAC_ADDRESS *MacAddress)
Definition: MnpMain.c:217
VOID EFIAPI MnpCheckMediaStatus(IN EFI_EVENT Event, IN VOID *Context)
Definition: MnpIo.c:1064
EFI_STATUS EFIAPI MnpTransmit(IN EFI_MANAGED_NETWORK_PROTOCOL *This, IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token)
Definition: MnpMain.c:508
EFI_STATUS EFIAPI MnpGetModeData(IN EFI_MANAGED_NETWORK_PROTOCOL *This, OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL, OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL)
Definition: MnpMain.c:38
EFI_STATUS EFIAPI MnpConfigure(IN EFI_MANAGED_NETWORK_PROTOCOL *This, IN EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL)
Definition: MnpMain.c:144
VOID EFIAPI MnpRecycleRxData(IN EFI_EVENT Event, IN VOID *Context)
Definition: MnpIo.c:424
VOID EFIAPI MnpSystemPoll(IN EFI_EVENT Event, IN VOID *Context)
Definition: MnpIo.c:1096
EFI_STATUS EFIAPI MnpReceive(IN EFI_MANAGED_NETWORK_PROTOCOL *This, IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token)
Definition: MnpMain.c:600
EFI_STATUS EFIAPI MnpCancel(IN EFI_MANAGED_NETWORK_PROTOCOL *This, IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token OPTIONAL)
Definition: MnpMain.c:683
EFI_STATUS EFIAPI MnpPoll(IN EFI_MANAGED_NETWORK_PROTOCOL *This)
Definition: MnpMain.c:752
EFI_STATUS EFIAPI MnpGroups(IN EFI_MANAGED_NETWORK_PROTOCOL *This, IN BOOLEAN JoinFlag, IN EFI_MAC_ADDRESS *MacAddress OPTIONAL)
Definition: MnpMain.c:343
VOID EFIAPI MnpCheckPacketTimeout(IN EFI_EVENT Event, IN VOID *Context)
Definition: MnpIo.c:997
EFI_HANDLE MnpCreateVlanChild(IN EFI_HANDLE ImageHandle, IN EFI_HANDLE ControllerHandle, IN UINT16 VlanId, OUT EFI_DEVICE_PATH_PROTOCOL **Devicepath OPTIONAL)
Definition: MnpVlan.c:42
VOID EFIAPI NetbufQueInit(IN OUT NET_BUF_QUEUE *NbufQue)
Definition: NetBuffer.c:1300
UINT32 EFIAPI NetbufTrim(IN OUT NET_BUF *Nbuf, IN UINT32 Len, IN BOOLEAN FromHead)
Definition: NetBuffer.c:1134
EFI_STATUS EFIAPI NetLibGetMacString(IN EFI_HANDLE ServiceHandle, IN EFI_HANDLE ImageHandle OPTIONAL, OUT CHAR16 **MacString)
Definition: DxeNetLib.c:2363
VOID EFIAPI NetbufQueFlush(IN OUT NET_BUF_QUEUE *NbufQue)
Definition: NetBuffer.c:1592
NET_BUF *EFIAPI NetbufAlloc(IN UINT32 Len)
Definition: NetBuffer.c:89
VOID EFIAPI NetMapInit(IN OUT NET_MAP *Map)
Definition: DxeNetLib.c:1343
UINT8 *EFIAPI NetbufAllocSpace(IN OUT NET_BUF *Nbuf, IN UINT32 Len, IN BOOLEAN FromHead)
Definition: NetBuffer.c:1015
VOID *EFIAPI NetMapRemoveItem(IN OUT NET_MAP *Map, IN OUT NET_MAP_ITEM *Item, OUT VOID **Value OPTIONAL)
Definition: DxeNetLib.c:1671
EFI_STATUS EFIAPI NetDestroyLinkList(IN LIST_ENTRY *List, IN NET_DESTROY_LINK_LIST_CALLBACK CallBack, IN VOID *Context OPTIONAL, OUT UINTN *ListLength OPTIONAL)
Definition: DxeNetLib.c:1236
VOID EFIAPI NetbufQueAppend(IN OUT NET_BUF_QUEUE *NbufQue, IN OUT NET_BUF *Nbuf)
Definition: NetBuffer.c:1374
NET_BUF *EFIAPI NetbufQueRemove(IN OUT NET_BUF_QUEUE *NbufQue)
Definition: NetBuffer.c:1399
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
VOID EFIAPI Exit(IN EFI_STATUS Status)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
UINTN EFI_TPL
Definition: UefiBaseType.h:41
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_TIMER_DELAY
Definition: UefiSpec.h:527
@ TimerCancel
Definition: UefiSpec.h:531
@ TimerPeriodic
Definition: UefiSpec.h:535
EFI_SIMPLE_NETWORK_MODE * Mode