]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c
move protocol close process from MnpDriverBindingStart() to MnpFlushServiceData().
[mirror_edk2.git] / MdeModulePkg / Universal / Network / MnpDxe / MnpConfig.c
1 /** @file
2
3 Copyright (c) 2005 - 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 MnpConfig.c
15
16 Abstract:
17
18 Implementation of Managed Network Protocol private services.
19
20
21 **/
22
23
24 #include "MnpImpl.h"
25
26 EFI_SERVICE_BINDING_PROTOCOL mMnpServiceBindingProtocol = {
27 MnpServiceBindingCreateChild,
28 MnpServiceBindingDestroyChild
29 };
30
31 EFI_MANAGED_NETWORK_PROTOCOL mMnpProtocolTemplate = {
32 MnpGetModeData,
33 MnpConfigure,
34 MnpMcastIpToMac,
35 MnpGroups,
36 MnpTransmit,
37 MnpReceive,
38 MnpCancel,
39 MnpPoll
40 };
41
42 EFI_MANAGED_NETWORK_CONFIG_DATA mMnpDefaultConfigData = {
43 10000,
44 10000,
45 0,
46 FALSE,
47 FALSE,
48 FALSE,
49 FALSE,
50 FALSE,
51 FALSE,
52 FALSE
53 };
54
55 STATIC
56 EFI_STATUS
57 MnpAddFreeNbuf (
58 IN MNP_SERVICE_DATA *MnpServiceData,
59 IN UINTN Count
60 );
61
62 STATIC
63 EFI_STATUS
64 MnpStartSnp (
65 IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp
66 );
67
68 STATIC
69 EFI_STATUS
70 MnpStopSnp (
71 IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp
72 );
73
74 STATIC
75 EFI_STATUS
76 MnpStart (
77 IN MNP_SERVICE_DATA *MnpServiceData,
78 IN BOOLEAN IsConfigUpdate,
79 IN BOOLEAN EnableSystemPoll
80 );
81
82 STATIC
83 EFI_STATUS
84 MnpStop (
85 IN MNP_SERVICE_DATA *MnpServiceData
86 );
87
88 STATIC
89 EFI_STATUS
90 MnpConfigReceiveFilters (
91 IN MNP_SERVICE_DATA *MnpServiceData
92 );
93
94 STATIC
95 EFI_STATUS
96 MnpGroupOpAddCtrlBlk (
97 IN MNP_INSTANCE_DATA *Instance,
98 IN MNP_GROUP_CONTROL_BLOCK *CtrlBlk,
99 IN MNP_GROUP_ADDRESS *GroupAddress OPTIONAL,
100 IN EFI_MAC_ADDRESS *MacAddress,
101 IN UINT32 HwAddressSize
102 );
103
104 STATIC
105 BOOLEAN
106 MnpGroupOpDelCtrlBlk (
107 IN MNP_INSTANCE_DATA *Instance,
108 IN MNP_GROUP_CONTROL_BLOCK *CtrlBlk
109 );
110
111
112 /**
113 Add some NET_BUF into MnpServiceData->FreeNbufQue. The buffer length of
114 the NET_BUF is specified by MnpServiceData->BufferLength.
115
116 @param MnpServiceData Pointer to the MNP_SERVICE_DATA.
117 @param Count Number of NET_BUFFERs to add.
118
119 @retval EFI_SUCCESS The specified amount of NET_BUFs are allocated and
120 added into MnpServiceData->FreeNbufQue.
121 @retval EFI_OUT_OF_RESOURCES Failed to allocate a NET_BUF structure.
122
123 **/
124 STATIC
125 EFI_STATUS
126 MnpAddFreeNbuf (
127 IN MNP_SERVICE_DATA *MnpServiceData,
128 IN UINTN Count
129 )
130 {
131 EFI_STATUS Status;
132 UINTN Index;
133 NET_BUF *Nbuf;
134
135 NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
136 ASSERT ((Count > 0) && (MnpServiceData->BufferLength > 0));
137
138 Status = EFI_SUCCESS;
139
140 for (Index = 0; Index < Count; Index++) {
141
142 Nbuf = NetbufAlloc (MnpServiceData->BufferLength + MnpServiceData->PaddingSize);
143 if (Nbuf == NULL) {
144
145 DEBUG ((EFI_D_ERROR, "MnpAddFreeNbuf: NetBufAlloc failed.\n"));
146 Status = EFI_OUT_OF_RESOURCES;
147 break;
148 }
149
150 if (MnpServiceData->PaddingSize > 0) {
151 //
152 // Pad padding bytes before the media header
153 //
154 NetbufAllocSpace (Nbuf, MnpServiceData->PaddingSize, NET_BUF_TAIL);
155 NetbufTrim (Nbuf, MnpServiceData->PaddingSize, NET_BUF_HEAD);
156 }
157
158 NetbufQueAppend (&MnpServiceData->FreeNbufQue, Nbuf);
159 }
160
161 MnpServiceData->NbufCnt += Index;
162
163 return Status;
164 }
165
166
167 /**
168 Allocate a free NET_BUF from MnpServiceData->FreeNbufQue. If there is none
169 in the queue, first try to allocate some and add them into the queue, then
170 fetch the NET_BUF from the updated FreeNbufQue.
171
172 @param MnpServiceData Pointer to the MNP_SERVICE_DATA.
173
174 @return Pointer to the allocated free NET_BUF structure, if NULL the operation is failed.
175
176 **/
177 NET_BUF *
178 MnpAllocNbuf (
179 IN MNP_SERVICE_DATA *MnpServiceData
180 )
181 {
182 EFI_STATUS Status;
183 NET_BUF_QUEUE *FreeNbufQue;
184 NET_BUF *Nbuf;
185 EFI_TPL OldTpl;
186
187 NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
188
189 FreeNbufQue = &MnpServiceData->FreeNbufQue;
190
191 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
192
193 //
194 // Check whether there are available buffers, or else try to add some.
195 //
196 if (FreeNbufQue->BufNum == 0) {
197
198 if ((MnpServiceData->NbufCnt + MNP_NET_BUFFER_INCREASEMENT) > MNP_MAX_NET_BUFFER_NUM) {
199
200 DEBUG (
201 (EFI_D_ERROR,
202 "MnpAllocNbuf: The maximum NET_BUF size is reached for MNP driver instance %p.\n",
203 MnpServiceData)
204 );
205
206 Nbuf = NULL;
207 goto ON_EXIT;
208 }
209
210 Status = MnpAddFreeNbuf (MnpServiceData, MNP_NET_BUFFER_INCREASEMENT);
211 if (EFI_ERROR (Status)) {
212
213 DEBUG (
214 (EFI_D_ERROR,
215 "MnpAllocNbuf: Failed to add NET_BUFs into the FreeNbufQue, %r.\n",
216 Status)
217 );
218 //
219 // Don't return NULL, perhaps MnpAddFreeNbuf does add some NET_BUFs but
220 // the amount is less than MNP_NET_BUFFER_INCREASEMENT.
221 //
222 }
223 }
224
225 Nbuf = NetbufQueRemove (FreeNbufQue);
226
227 //
228 // Increase the RefCnt.
229 //
230 if (Nbuf != NULL) {
231 NET_GET_REF (Nbuf);
232 }
233
234 ON_EXIT:
235 gBS->RestoreTPL (OldTpl);
236
237 return Nbuf;
238 }
239
240
241 /**
242 Try to reclaim the Nbuf into the buffer pool.
243
244 @param MnpServiceData Pointer to the mnp service context data.
245 @param Nbuf Pointer to the NET_BUF to free.
246
247 @return None.
248
249 **/
250 VOID
251 MnpFreeNbuf (
252 IN MNP_SERVICE_DATA *MnpServiceData,
253 IN NET_BUF *Nbuf
254 )
255 {
256 EFI_TPL OldTpl;
257
258 NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
259 ASSERT (Nbuf->RefCnt > 1);
260
261 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
262
263 NET_PUT_REF (Nbuf);
264
265 if (Nbuf->RefCnt == 1) {
266 //
267 // Trim all buffer contained in the Nbuf, then append it to the NbufQue.
268 //
269 NetbufTrim (Nbuf, Nbuf->TotalSize, NET_BUF_TAIL);
270 NetbufQueAppend (&MnpServiceData->FreeNbufQue, Nbuf);
271 }
272
273 gBS->RestoreTPL (OldTpl);
274 }
275
276
277 /**
278 Initialize the mnp service context data.
279
280 @param MnpServiceData Pointer to the mnp service context data.
281 @param Snp Pointer to the simple network protocol.
282
283 @retval EFI_SUCCESS The mnp service context is initialized.
284 @retval Other Some error occurs.
285
286 **/
287 EFI_STATUS
288 MnpInitializeServiceData (
289 IN MNP_SERVICE_DATA *MnpServiceData,
290 IN EFI_HANDLE ImageHandle,
291 IN EFI_HANDLE ControllerHandle
292 )
293 {
294 EFI_STATUS Status;
295 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
296 EFI_SIMPLE_NETWORK_MODE *SnpMode;
297
298 MnpServiceData->Signature = MNP_SERVICE_DATA_SIGNATURE;
299
300 MnpServiceData->ControllerHandle = ControllerHandle;
301
302 //
303 // Copy the ServiceBinding structure.
304 //
305 MnpServiceData->ServiceBinding = mMnpServiceBindingProtocol;
306
307 //
308 // Open the Simple Network protocol.
309 //
310 Status = gBS->OpenProtocol (
311 ControllerHandle,
312 &gEfiSimpleNetworkProtocolGuid,
313 (VOID **) &Snp,
314 ImageHandle,
315 ControllerHandle,
316 EFI_OPEN_PROTOCOL_BY_DRIVER
317 );
318 if (EFI_ERROR (Status)) {
319 return EFI_UNSUPPORTED;
320 }
321
322 //
323 // Get MTU from Snp.
324 //
325 SnpMode = Snp->Mode;
326 MnpServiceData->Snp = Snp;
327 MnpServiceData->Mtu = SnpMode->MaxPacketSize;
328
329 //
330 // Initialize the lists.
331 //
332 InitializeListHead (&MnpServiceData->GroupAddressList);
333 InitializeListHead (&MnpServiceData->ChildrenList);
334
335 //
336 // Get the buffer length used to allocate NET_BUF to hold data received
337 // from SNP. Do this before fill the FreeNetBufQue.
338 //
339 MnpServiceData->BufferLength = MnpServiceData->Mtu + SnpMode->MediaHeaderSize + NET_ETHER_FCS_SIZE;
340
341 //
342 // Make sure the protocol headers immediately following the media header
343 // 4-byte aligned
344 //
345 MnpServiceData->PaddingSize = (4 - SnpMode->MediaHeaderSize) & 0x3;
346
347 //
348 // Initialize the FreeNetBufQue and pre-allocate some NET_BUFs.
349 //
350 NetbufQueInit (&MnpServiceData->FreeNbufQue);
351 Status = MnpAddFreeNbuf (MnpServiceData, MNP_INIT_NET_BUFFER_NUM);
352 if (EFI_ERROR (Status)) {
353
354 DEBUG ((EFI_D_ERROR, "MnpInitializeServiceData: MnpAddFreeNbuf failed, %r.\n", Status));
355 goto ERROR;
356 }
357 //
358 // Get one NET_BUF from the FreeNbufQue for rx cache.
359 //
360 MnpServiceData->RxNbufCache = MnpAllocNbuf (MnpServiceData);
361 NetbufAllocSpace (
362 MnpServiceData->RxNbufCache,
363 MnpServiceData->BufferLength,
364 NET_BUF_TAIL
365 );
366
367 //
368 // Allocate buffer pool for tx.
369 //
370 MnpServiceData->TxBuf = AllocatePool (MnpServiceData->Mtu + SnpMode->MediaHeaderSize);
371 if (MnpServiceData->TxBuf == NULL) {
372
373 DEBUG ((EFI_D_ERROR, "MnpInitializeServiceData: AllocatePool failed.\n"));
374 Status = EFI_OUT_OF_RESOURCES;
375
376 goto ERROR;
377 }
378
379 //
380 // Create the system poll timer.
381 //
382 Status = gBS->CreateEvent (
383 EVT_NOTIFY_SIGNAL | EVT_TIMER,
384 TPL_CALLBACK,
385 MnpSystemPoll,
386 MnpServiceData,
387 &MnpServiceData->PollTimer
388 );
389 if (EFI_ERROR (Status)) {
390
391 DEBUG ((EFI_D_ERROR, "MnpInitializeServiceData: CreateEvent for poll timer failed.\n"));
392 goto ERROR;
393 }
394
395 //
396 // Create the timer for packet timeout check.
397 //
398 Status = gBS->CreateEvent (
399 EVT_NOTIFY_SIGNAL | EVT_TIMER,
400 TPL_CALLBACK,
401 MnpCheckPacketTimeout,
402 MnpServiceData,
403 &MnpServiceData->TimeoutCheckTimer
404 );
405 if (EFI_ERROR (Status)) {
406
407 DEBUG ((EFI_D_ERROR, "MnpInitializeServiceData: CreateEvent for packet timeout check failed.\n"));
408 goto ERROR;
409 }
410
411 //
412 // Create the timer for tx timeout check.
413 //
414 Status = gBS->CreateEvent (
415 EVT_TIMER,
416 TPL_CALLBACK,
417 NULL,
418 NULL,
419 &MnpServiceData->TxTimeoutEvent
420 );
421 if (EFI_ERROR (Status)) {
422
423 DEBUG ((EFI_D_ERROR, "MnpInitializeServiceData: CreateEvent for tx timeout event failed.\n"));
424 }
425
426 ERROR:
427
428 if (EFI_ERROR (Status)) {
429 //
430 // Free the dynamic allocated resources if necessary.
431 //
432 if (MnpServiceData->TimeoutCheckTimer != NULL) {
433
434 gBS->CloseEvent (MnpServiceData->TimeoutCheckTimer);
435 }
436
437 if (MnpServiceData->PollTimer != NULL) {
438
439 gBS->CloseEvent (MnpServiceData->PollTimer);
440 }
441
442 if (MnpServiceData->TxBuf != NULL) {
443
444 gBS->FreePool (MnpServiceData->TxBuf);
445 }
446
447 if (MnpServiceData->RxNbufCache != NULL) {
448
449 MnpFreeNbuf (MnpServiceData, MnpServiceData->RxNbufCache);
450 }
451
452 if (MnpServiceData->FreeNbufQue.BufNum != 0) {
453
454 NetbufQueFlush (&MnpServiceData->FreeNbufQue);
455 }
456 }
457
458 return Status;
459 }
460
461
462 /**
463 Flush the mnp service context data.
464
465 @param MnpServiceData Pointer to the mnp service context data.
466
467 @return None.
468
469 **/
470 VOID
471 MnpFlushServiceData (
472 MNP_SERVICE_DATA *MnpServiceData
473 )
474 {
475 NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
476
477 //
478 // The GroupAddressList must be empty.
479 //
480 ASSERT (IsListEmpty (&MnpServiceData->GroupAddressList));
481
482 //
483 // Close the event.
484 //
485 gBS->CloseEvent (&MnpServiceData->TxTimeoutEvent);
486 gBS->CloseEvent (&MnpServiceData->TimeoutCheckTimer);
487 gBS->CloseEvent (&MnpServiceData->PollTimer);
488
489 //
490 // Free the tx buffer.
491 //
492 gBS->FreePool (MnpServiceData->TxBuf);
493
494 //
495 // Free the RxNbufCache.
496 //
497 MnpFreeNbuf (MnpServiceData, MnpServiceData->RxNbufCache);
498
499 //
500 // Flush the FreeNbufQue.
501 //
502 MnpServiceData->NbufCnt -= MnpServiceData->FreeNbufQue.BufNum;
503 NetbufQueFlush (&MnpServiceData->FreeNbufQue);
504
505 DEBUG_CODE (
506
507 if (MnpServiceData->NbufCnt != 0) {
508
509 DEBUG ((EFI_D_WARN, "MnpFlushServiceData: Memory leak, MnpServiceData->NbufCnt != 0.\n"));
510 }
511 );
512
513 //
514 // Close the Simple Network Protocol.
515 //
516 gBS->CloseProtocol (
517 MnpServiceData->ControllerHandle,
518 &gEfiSimpleNetworkProtocolGuid,
519 This->DriverBindingHandle,
520 MnpServiceData->ControllerHandle
521 );
522 }
523
524
525 /**
526 Initialize the mnp instance context data.
527
528 @param MnpServiceData Pointer to the mnp service context data.
529 @param Instance Pointer to the mnp instance context data to
530 initialize.
531
532 @return None.
533
534 **/
535 VOID
536 MnpInitializeInstanceData (
537 IN MNP_SERVICE_DATA *MnpServiceData,
538 IN MNP_INSTANCE_DATA *Instance
539 )
540 {
541 NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
542 ASSERT (Instance != NULL);
543
544 //
545 // Set the signature.
546 //
547 Instance->Signature = MNP_INSTANCE_DATA_SIGNATURE;
548
549 //
550 // Copy the MNP Protocol interfaces from the template.
551 //
552 CopyMem (&Instance->ManagedNetwork, &mMnpProtocolTemplate, sizeof (Instance->ManagedNetwork));
553
554 //
555 // Copy the default config data.
556 //
557 CopyMem (&Instance->ConfigData, &mMnpDefaultConfigData, sizeof (Instance->ConfigData));
558
559 //
560 // Initialize the lists.
561 //
562 InitializeListHead (&Instance->GroupCtrlBlkList);
563 InitializeListHead (&Instance->RcvdPacketQueue);
564 InitializeListHead (&Instance->RxDeliveredPacketQueue);
565
566 //
567 // Initialize the RxToken Map.
568 //
569 NetMapInit (&Instance->RxTokenMap);
570
571 //
572 // Save the MnpServiceData info.
573 //
574 Instance->MnpServiceData = MnpServiceData;
575 }
576
577
578 /**
579 Check whether the token specified by Arg maches the token in Item.
580
581 @param Map Pointer to the NET_MAP.
582 @param Item Pointer to the NET_MAP_ITEM
583 @param Arg Pointer to the Arg, it's a pointer to the token to
584 check.
585
586 @retval EFI_SUCCESS The token specified by Arg is different from the
587 token in Item.
588 @retval EFI_ACCESS_DENIED The token specified by Arg is the same as that in
589 Item.
590
591 **/
592 EFI_STATUS
593 MnpTokenExist (
594 IN NET_MAP *Map,
595 IN NET_MAP_ITEM *Item,
596 IN VOID *Arg
597 )
598 {
599 EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token;
600 EFI_MANAGED_NETWORK_COMPLETION_TOKEN *TokenInItem;
601
602 Token = (EFI_MANAGED_NETWORK_COMPLETION_TOKEN *) Arg;
603 TokenInItem = (EFI_MANAGED_NETWORK_COMPLETION_TOKEN *) Item->Key;
604
605 if ((Token == TokenInItem) || (Token->Event == TokenInItem->Event)) {
606 //
607 // The token is the same either the two tokens equals or the Events in
608 // the two tokens are the same.
609 //
610 return EFI_ACCESS_DENIED;
611 }
612
613 return EFI_SUCCESS;
614 }
615
616
617 /**
618 Cancel the token specified by Arg if it matches the token in Item.
619
620 @param Map Pointer to the NET_MAP.
621 @param Item Pointer to the NET_MAP_ITEM
622 @param Arg Pointer to the Arg, it's a pointer to the token to
623 cancel.
624
625 @retval EFI_SUCCESS The Arg is NULL, and the token in Item is
626 cancelled, or the Arg isn't NULL, and the token in
627 Item is different from the Arg.
628 @retval EFI_ABORTED The Arg isn't NULL, the token in Item mathces the
629 Arg, and the token is cancelled.
630
631 **/
632 EFI_STATUS
633 MnpCancelTokens (
634 IN NET_MAP *Map,
635 IN NET_MAP_ITEM *Item,
636 IN VOID *Arg
637 )
638 {
639 EFI_MANAGED_NETWORK_COMPLETION_TOKEN *TokenToCancel;
640
641 if ((Arg != NULL) && (Item->Key != Arg)) {
642 //
643 // The token in Item is not the token specified by Arg.
644 //
645 return EFI_SUCCESS;
646 }
647
648 TokenToCancel = (EFI_MANAGED_NETWORK_COMPLETION_TOKEN *) Item->Key;
649
650 //
651 // Remove the item from the map.
652 //
653 NetMapRemoveItem (Map, Item, NULL);
654
655 //
656 // Cancel this token with status set to EFI_ABORTED.
657 //
658 TokenToCancel->Status = EFI_ABORTED;
659 gBS->SignalEvent (TokenToCancel->Event);
660
661 if (Arg != NULL) {
662 //
663 // Only abort the token specified by Arg if Arg isn't NULL.
664 //
665 return EFI_ABORTED;
666 }
667
668 return EFI_SUCCESS;
669 }
670
671
672 /**
673 Start and initialize the simple network.
674
675 @param Snp Pointer to the simple network protocol.
676
677 @retval EFI_SUCCESS The simple network protocol is started.
678 @retval Other Some error occurs.
679
680 **/
681 STATIC
682 EFI_STATUS
683 MnpStartSnp (
684 IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp
685 )
686 {
687 EFI_STATUS Status;
688
689 ASSERT (Snp != NULL);
690
691 //
692 // Start the simple network.
693 //
694 Status = Snp->Start (Snp);
695
696 if (!EFI_ERROR (Status)) {
697 //
698 // Initialize the simple network.
699 //
700 Status = Snp->Initialize (Snp, 0, 0);
701 }
702
703 return Status;
704 }
705
706
707 /**
708 Stop the simple network.
709
710 @param Snp Pointer to the simple network protocol.
711
712 @retval EFI_SUCCESS The simple network is stopped.
713 @retval Other Some error occurs.
714
715 **/
716 STATIC
717 EFI_STATUS
718 MnpStopSnp (
719 IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp
720 )
721 {
722 EFI_STATUS Status;
723
724 ASSERT (Snp != NULL);
725
726 //
727 // Shut down the simple network.
728 //
729 Status = Snp->Shutdown (Snp);
730
731 if (!EFI_ERROR (Status)) {
732 //
733 // Stop the simple network.
734 //
735 Status = Snp->Stop (Snp);
736 }
737
738 return Status;
739 }
740
741
742 /**
743 Start the managed network, this function is called when one instance is configured
744 or reconfigured.
745
746 @param MnpServiceData Pointer to the mnp service context data.
747 @param IsConfigUpdate The instance is reconfigured or it's the first time
748 the instanced is configured.
749 @param EnableSystemPoll Enable the system polling or not.
750
751 @retval EFI_SUCCESS The managed network is started and some
752 configuration is updated.
753 @retval Other Some error occurs.
754
755 **/
756 STATIC
757 EFI_STATUS
758 MnpStart (
759 IN MNP_SERVICE_DATA *MnpServiceData,
760 IN BOOLEAN IsConfigUpdate,
761 IN BOOLEAN EnableSystemPoll
762 )
763 {
764 EFI_STATUS Status;
765 EFI_TIMER_DELAY TimerOpType;
766
767 NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
768
769 Status = EFI_SUCCESS;
770
771 if (!IsConfigUpdate) {
772 //
773 // If it's not a configuration update, increase the configured children number.
774 //
775 MnpServiceData->ConfiguredChildrenNumber++;
776
777 if (MnpServiceData->ConfiguredChildrenNumber == 1) {
778 //
779 // It's the first configured child, start the simple network.
780 //
781 Status = MnpStartSnp (MnpServiceData->Snp);
782 if (EFI_ERROR (Status)) {
783
784 DEBUG ((EFI_D_ERROR, "MnpStart: MnpStartSnp failed, %r.\n", Status));
785 goto ErrorExit;
786 }
787
788 //
789 // Start the timeout timer.
790 //
791 Status = gBS->SetTimer (
792 MnpServiceData->TimeoutCheckTimer,
793 TimerPeriodic,
794 MNP_TIMEOUT_CHECK_INTERVAL
795 );
796 if (EFI_ERROR (Status)) {
797
798 DEBUG (
799 (EFI_D_ERROR,
800 "MnpStart, gBS->SetTimer for TimeoutCheckTimer %r.\n",
801 Status)
802 );
803 goto ErrorExit;
804 }
805 }
806 }
807
808 if (MnpServiceData->EnableSystemPoll ^ EnableSystemPoll) {
809 //
810 // The EnableSystemPoll differs with the current state, disable or enable
811 // the system poll.
812 //
813 TimerOpType = EnableSystemPoll ? TimerPeriodic : TimerCancel;
814
815 Status = gBS->SetTimer (MnpServiceData->PollTimer, TimerOpType, MNP_SYS_POLL_INTERVAL);
816 if (EFI_ERROR (Status)) {
817
818 DEBUG ((EFI_D_ERROR, "MnpStart: gBS->SetTimer for PollTimer failed, %r.\n", Status));
819 goto ErrorExit;
820 }
821
822 MnpServiceData->EnableSystemPoll = EnableSystemPoll;
823 }
824
825 //
826 // Change the receive filters if need.
827 //
828 Status = MnpConfigReceiveFilters (MnpServiceData);
829
830 ErrorExit:
831
832 return Status;
833 }
834
835
836 /**
837 Stop the managed network.
838
839 @param MnpServiceData Pointer to the mnp service context data.
840
841 @retval EFI_SUCCESS The managed network is stopped.
842 @retval Other Some error occurs.
843
844 **/
845 STATIC
846 EFI_STATUS
847 MnpStop (
848 IN MNP_SERVICE_DATA *MnpServiceData
849 )
850 {
851 EFI_STATUS Status;
852
853 NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
854 ASSERT (MnpServiceData->ConfiguredChildrenNumber > 0);
855
856 //
857 // Configure the receive filters.
858 //
859 MnpConfigReceiveFilters (MnpServiceData);
860
861 //
862 // Decrease the children number.
863 //
864 MnpServiceData->ConfiguredChildrenNumber--;
865
866 if (MnpServiceData->ConfiguredChildrenNumber > 0) {
867 //
868 // If there are other configured chilren, return and keep the timers and
869 // simple network unchanged.
870 //
871 return EFI_SUCCESS;
872 }
873
874 //
875 // No configured children now.
876 //
877
878 if (MnpServiceData->EnableSystemPoll) {
879 //
880 // The system poll in on, cancel the poll timer.
881 //
882 Status = gBS->SetTimer (MnpServiceData->PollTimer, TimerCancel, 0);
883 MnpServiceData->EnableSystemPoll = FALSE;
884 }
885
886 //
887 // Cancel the timeout timer.
888 //
889 Status = gBS->SetTimer (MnpServiceData->TimeoutCheckTimer, TimerCancel, 0);
890
891 //
892 // Stop the simple network.
893 //
894 Status = MnpStopSnp (MnpServiceData->Snp);
895
896 return Status;
897 }
898
899
900 /**
901 Flush the instance's received data.
902
903 @param Instance Pointer to the mnp instance context data.
904
905 @return None.
906
907 **/
908 VOID
909 MnpFlushRcvdDataQueue (
910 IN MNP_INSTANCE_DATA *Instance
911 )
912 {
913 EFI_TPL OldTpl;
914 MNP_RXDATA_WRAP *RxDataWrap;
915
916 NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);
917
918 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
919
920 while (!IsListEmpty (&Instance->RcvdPacketQueue)) {
921 //
922 // Remove all the Wraps.
923 //
924 RxDataWrap = NET_LIST_HEAD (&Instance->RcvdPacketQueue, MNP_RXDATA_WRAP, WrapEntry);
925
926 //
927 // Recycle the RxDataWrap.
928 //
929 MnpRecycleRxData (NULL, (VOID *) RxDataWrap);
930 Instance->RcvdPacketQueueSize--;
931 }
932
933 ASSERT (Instance->RcvdPacketQueueSize == 0);
934
935 gBS->RestoreTPL (OldTpl);
936 }
937
938
939 /**
940 Configure the Instance using ConfigData.
941
942 @param Instance Pointer to the mnp instance context data.
943 @param ConfigData Pointer to the configuration data used to configure
944 the isntance.
945
946 @retval EFI_SUCCESS The Instance is configured.
947 @retval EFI_UNSUPPORTED EnableReceiveTimestamps is on and the
948 implementation doesn't support it.
949 @retval Other Some error occurs.
950
951 **/
952 EFI_STATUS
953 MnpConfigureInstance (
954 IN MNP_INSTANCE_DATA *Instance,
955 IN EFI_MANAGED_NETWORK_CONFIG_DATA *ConfigData OPTIONAL
956 )
957 {
958 EFI_STATUS Status;
959 MNP_SERVICE_DATA *MnpServiceData;
960 EFI_MANAGED_NETWORK_CONFIG_DATA *OldConfigData;
961 EFI_MANAGED_NETWORK_CONFIG_DATA *NewConfigData;
962 BOOLEAN IsConfigUpdate;
963
964 NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);
965
966 if ((ConfigData != NULL) && ConfigData->EnableReceiveTimestamps) {
967 //
968 // Don't support timestamp.
969 //
970 return EFI_UNSUPPORTED;
971 }
972
973 Status = EFI_SUCCESS;
974
975 MnpServiceData = Instance->MnpServiceData;
976 NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
977
978 IsConfigUpdate = (BOOLEAN) ((Instance->Configured) && (ConfigData != NULL));
979
980 OldConfigData = &Instance->ConfigData;
981 NewConfigData = ConfigData;
982 if (NewConfigData == NULL) {
983 //
984 // Restore back the default config data if a reset of this instance
985 // is required.
986 //
987 NewConfigData = &mMnpDefaultConfigData;
988 }
989
990 //
991 // Reset the instance's receive filter.
992 //
993 Instance->ReceiveFilter = 0;
994
995 //
996 // Clear the receive counters according to the old ConfigData.
997 //
998 if (OldConfigData->EnableUnicastReceive) {
999 MnpServiceData->UnicastCount--;
1000 }
1001
1002 if (OldConfigData->EnableMulticastReceive) {
1003 MnpServiceData->MulticastCount--;
1004 }
1005
1006 if (OldConfigData->EnableBroadcastReceive) {
1007 MnpServiceData->BroadcastCount--;
1008 }
1009
1010 if (OldConfigData->EnablePromiscuousReceive) {
1011 MnpServiceData->PromiscuousCount--;
1012 }
1013
1014 //
1015 // Set the receive filter counters and the receive filter of the
1016 // instance according to the new ConfigData.
1017 //
1018 if (NewConfigData->EnableUnicastReceive) {
1019 MnpServiceData->UnicastCount++;
1020 Instance->ReceiveFilter |= MNP_RECEIVE_UNICAST;
1021 }
1022
1023 if (NewConfigData->EnableMulticastReceive) {
1024 MnpServiceData->MulticastCount++;
1025 }
1026
1027 if (NewConfigData->EnableBroadcastReceive) {
1028 MnpServiceData->BroadcastCount++;
1029 Instance->ReceiveFilter |= MNP_RECEIVE_BROADCAST;
1030 }
1031
1032 if (NewConfigData->EnablePromiscuousReceive) {
1033 MnpServiceData->PromiscuousCount++;
1034 }
1035
1036 if (OldConfigData->FlushQueuesOnReset) {
1037
1038 MnpFlushRcvdDataQueue (Instance);
1039 }
1040
1041 if (ConfigData == NULL) {
1042
1043 Instance->ManagedNetwork.Cancel (&Instance->ManagedNetwork, NULL);
1044 }
1045
1046 if (!NewConfigData->EnableMulticastReceive) {
1047
1048 MnpGroupOp (Instance, FALSE, NULL, NULL);
1049 }
1050
1051 //
1052 // Save the new configuration data.
1053 //
1054 CopyMem (OldConfigData, NewConfigData, sizeof (*OldConfigData));
1055
1056 Instance->Configured = (BOOLEAN) (ConfigData != NULL);
1057
1058 if (Instance->Configured) {
1059 //
1060 // The instance is configured, start the Mnp.
1061 //
1062 Status = MnpStart (
1063 MnpServiceData,
1064 IsConfigUpdate,
1065 (BOOLEAN) !NewConfigData->DisableBackgroundPolling
1066 );
1067 } else {
1068 //
1069 // The instance is changed to the unconfigured state, stop the Mnp.
1070 //
1071 Status = MnpStop (MnpServiceData);
1072 }
1073
1074 return Status;
1075 }
1076
1077
1078 /**
1079 Configure the Snp receive filters according to the instances' receive filter
1080 settings.
1081
1082 @param MnpServiceData Pointer to the mnp service context data.
1083
1084 @retval EFI_SUCCESS The receive filters is configured.
1085 @retval EFI_OUT_OF_RESOURCES The receive filters can't be configured due to lack
1086 of memory resource.
1087
1088 **/
1089 STATIC
1090 EFI_STATUS
1091 MnpConfigReceiveFilters (
1092 IN MNP_SERVICE_DATA *MnpServiceData
1093 )
1094 {
1095 EFI_STATUS Status;
1096 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
1097 EFI_MAC_ADDRESS *MCastFilter;
1098 UINT32 MCastFilterCnt;
1099 UINT32 EnableFilterBits;
1100 UINT32 DisableFilterBits;
1101 BOOLEAN ResetMCastFilters;
1102 LIST_ENTRY *Entry;
1103 UINT32 Index;
1104 MNP_GROUP_ADDRESS *GroupAddress;
1105
1106 NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
1107
1108 Snp = MnpServiceData->Snp;
1109
1110 //
1111 // Initialize the enable filter and disable filter.
1112 //
1113 EnableFilterBits = 0;
1114 DisableFilterBits = Snp->Mode->ReceiveFilterMask;
1115
1116 if (MnpServiceData->UnicastCount != 0) {
1117 //
1118 // Enable unicast if any instance wants to receive unicast.
1119 //
1120 EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
1121 }
1122
1123 if (MnpServiceData->BroadcastCount != 0) {
1124 //
1125 // Enable broadcast if any instance wants to receive broadcast.
1126 //
1127 EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
1128 }
1129
1130 MCastFilter = NULL;
1131 MCastFilterCnt = 0;
1132 ResetMCastFilters = TRUE;
1133
1134 if ((MnpServiceData->MulticastCount != 0) && (MnpServiceData->GroupAddressCount != 0)) {
1135 //
1136 // There are instances configured to receive multicast and already some group
1137 // addresses are joined.
1138 //
1139
1140 ResetMCastFilters = FALSE;
1141
1142 if (MnpServiceData->GroupAddressCount <= Snp->Mode->MaxMCastFilterCount) {
1143 //
1144 // The joind group address is less than simple network's maximum count.
1145 // Just configure the snp to do the multicast filtering.
1146 //
1147
1148 EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST;
1149
1150 //
1151 // Allocate pool for the mulicast addresses.
1152 //
1153 MCastFilterCnt = MnpServiceData->GroupAddressCount;
1154 MCastFilter = AllocatePool (sizeof (EFI_MAC_ADDRESS) * MCastFilterCnt);
1155 if (MCastFilter == NULL) {
1156
1157 DEBUG ((EFI_D_ERROR, "MnpConfigReceiveFilters: Failed to allocate memory resource for MCastFilter.\n"));
1158 return EFI_OUT_OF_RESOURCES;
1159 }
1160
1161 //
1162 // Fill the multicast HW address buffer.
1163 //
1164 Index = 0;
1165 NET_LIST_FOR_EACH (Entry, &MnpServiceData->GroupAddressList) {
1166
1167 GroupAddress = NET_LIST_USER_STRUCT (Entry, MNP_GROUP_ADDRESS, AddrEntry);
1168 CopyMem (MCastFilter + Index, &GroupAddress->Address, sizeof (*(MCastFilter + Index)));
1169 Index++;
1170
1171 ASSERT (Index <= MCastFilterCnt);
1172 }
1173 } else {
1174 //
1175 // The maximum multicast is reached, set the filter to be promiscuous
1176 // multicast.
1177 //
1178
1179 if (Snp->Mode->ReceiveFilterMask & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) {
1180 EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
1181 } else {
1182 //
1183 // Either MULTICAST or PROMISCUOUS_MULTICAST is not supported by Snp,
1184 // set the NIC to be promiscuous although this will tremendously degrade
1185 // the performance.
1186 //
1187 EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;
1188 }
1189 }
1190 }
1191
1192 if (MnpServiceData->PromiscuousCount != 0) {
1193 //
1194 // Enable promiscuous if any instance wants to receive promiscuous.
1195 //
1196 EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;
1197 }
1198
1199 //
1200 // Set the disable filter.
1201 //
1202 DisableFilterBits ^= EnableFilterBits;
1203
1204 //
1205 // Configure the receive filters of SNP.
1206 //
1207 Status = Snp->ReceiveFilters (
1208 Snp,
1209 EnableFilterBits,
1210 DisableFilterBits,
1211 ResetMCastFilters,
1212 MCastFilterCnt,
1213 MCastFilter
1214 );
1215 DEBUG_CODE (
1216 if (EFI_ERROR (Status)) {
1217
1218 DEBUG (
1219 (EFI_D_ERROR,
1220 "MnpConfigReceiveFilters: Snp->ReceiveFilters failed, %r.\n",
1221 Status)
1222 );
1223 }
1224 );
1225
1226 if (MCastFilter != NULL) {
1227 //
1228 // Free the buffer used to hold the group addresses.
1229 //
1230 gBS->FreePool (MCastFilter);
1231 }
1232
1233 return Status;
1234 }
1235
1236
1237 /**
1238 Add a group address control block which controls the MacAddress for
1239 this instance.
1240
1241 @param Instance Pointer to the mnp instance context data.
1242 @param CtrlBlk Pointer to the group address control block.
1243 @param GroupAddress Pointer to the group adress.
1244 @param MacAddress Pointer to the mac address.
1245 @param HwAddressSize The hardware address size.
1246
1247 @retval EFI_SUCCESS The group address control block is added.
1248 @retval EFI_OUT_OF_RESOURCE Failed due to lack of memory resources.
1249
1250 **/
1251 STATIC
1252 EFI_STATUS
1253 MnpGroupOpAddCtrlBlk (
1254 IN MNP_INSTANCE_DATA *Instance,
1255 IN MNP_GROUP_CONTROL_BLOCK *CtrlBlk,
1256 IN MNP_GROUP_ADDRESS *GroupAddress OPTIONAL,
1257 IN EFI_MAC_ADDRESS *MacAddress,
1258 IN UINT32 HwAddressSize
1259 )
1260 {
1261 MNP_SERVICE_DATA *MnpServiceData;
1262
1263 NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);
1264
1265 MnpServiceData = Instance->MnpServiceData;
1266 NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
1267
1268 if (GroupAddress == NULL) {
1269
1270 ASSERT (MacAddress != NULL);
1271
1272 //
1273 // Allocate a new GroupAddress to be added into MNP's GroupAddressList.
1274 //
1275 GroupAddress = AllocatePool (sizeof (MNP_GROUP_ADDRESS));
1276 if (GroupAddress == NULL) {
1277
1278 DEBUG ((EFI_D_ERROR, "MnpGroupOpFormCtrlBlk: Failed to allocate memory resource.\n"));
1279
1280 return EFI_OUT_OF_RESOURCES;
1281 }
1282
1283 CopyMem (&GroupAddress->Address, MacAddress, sizeof (GroupAddress->Address));
1284 GroupAddress->RefCnt = 0;
1285 InsertTailList (
1286 &MnpServiceData->GroupAddressList,
1287 &GroupAddress->AddrEntry
1288 );
1289 MnpServiceData->GroupAddressCount++;
1290 }
1291
1292 //
1293 // Increase the RefCnt.
1294 //
1295 GroupAddress->RefCnt++;
1296
1297 //
1298 // Add the CtrlBlk into the instance's GroupCtrlBlkList.
1299 //
1300 CtrlBlk->GroupAddress = GroupAddress;
1301 InsertTailList (&Instance->GroupCtrlBlkList, &CtrlBlk->CtrlBlkEntry);
1302
1303 return EFI_SUCCESS;
1304 }
1305
1306
1307 /**
1308 Delete a group control block from the instance. If the controlled group address's
1309 reference count reaches zero, the group address is removed too.
1310
1311 @param Instance Pointer to the instance context data.
1312 @param CtrlBlk Pointer to the group control block to delete.
1313
1314 @return The group address controlled by the control block is no longer used or not.
1315
1316 **/
1317 STATIC
1318 BOOLEAN
1319 MnpGroupOpDelCtrlBlk (
1320 IN MNP_INSTANCE_DATA *Instance,
1321 IN MNP_GROUP_CONTROL_BLOCK *CtrlBlk
1322 )
1323 {
1324 MNP_SERVICE_DATA *MnpServiceData;
1325 MNP_GROUP_ADDRESS *GroupAddress;
1326
1327 NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);
1328
1329 MnpServiceData = Instance->MnpServiceData;
1330 NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
1331
1332 //
1333 // Remove and free the CtrlBlk.
1334 //
1335 GroupAddress = CtrlBlk->GroupAddress;
1336 RemoveEntryList (&CtrlBlk->CtrlBlkEntry);
1337 gBS->FreePool (CtrlBlk);
1338
1339 ASSERT (GroupAddress->RefCnt > 0);
1340
1341 //
1342 // Count down the RefCnt.
1343 //
1344 GroupAddress->RefCnt--;
1345
1346 if (GroupAddress->RefCnt == 0) {
1347 //
1348 // Free this GroupAddress entry if no instance uses it.
1349 //
1350 MnpServiceData->GroupAddressCount--;
1351 RemoveEntryList (&GroupAddress->AddrEntry);
1352 gBS->FreePool (GroupAddress);
1353
1354 return TRUE;
1355 }
1356
1357 return FALSE;
1358 }
1359
1360
1361 /**
1362 Do the group operations for this instance.
1363
1364 @param Instance Pointer to the instance context data.
1365 @param JoinFlag Set to TRUE to join a group. Set to TRUE to leave a
1366 group/groups.
1367 @param MacAddress Pointer to the group address to join or leave.
1368 @param CtrlBlk Pointer to the group control block if JoinFlag if
1369 FALSE.
1370
1371 @retval EFI_SUCCESS The group operation finished.
1372 @retval Other Some error occurs.
1373
1374 **/
1375 EFI_STATUS
1376 MnpGroupOp (
1377 IN MNP_INSTANCE_DATA *Instance,
1378 IN BOOLEAN JoinFlag,
1379 IN EFI_MAC_ADDRESS *MacAddress OPTIONAL,
1380 IN MNP_GROUP_CONTROL_BLOCK *CtrlBlk OPTIONAL
1381 )
1382 {
1383 MNP_SERVICE_DATA *MnpServiceData;
1384 LIST_ENTRY *Entry;
1385 LIST_ENTRY *NextEntry;
1386 MNP_GROUP_ADDRESS *GroupAddress;
1387 EFI_SIMPLE_NETWORK_MODE *SnpMode;
1388 MNP_GROUP_CONTROL_BLOCK *NewCtrlBlk;
1389 EFI_STATUS Status;
1390 BOOLEAN AddressExist;
1391 BOOLEAN NeedUpdate;
1392
1393 NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);
1394
1395 MnpServiceData = Instance->MnpServiceData;
1396 SnpMode = MnpServiceData->Snp->Mode;
1397
1398 if (JoinFlag) {
1399 //
1400 // A new gropu address is to be added.
1401 //
1402
1403 GroupAddress = NULL;
1404 AddressExist = FALSE;
1405
1406 //
1407 // Allocate memory for the control block.
1408 //
1409 NewCtrlBlk = AllocatePool (sizeof (MNP_GROUP_CONTROL_BLOCK));
1410 if (NewCtrlBlk == NULL) {
1411
1412 DEBUG ((EFI_D_ERROR, "MnpGroupOp: Failed to allocate memory resource.\n"));
1413 return EFI_OUT_OF_RESOURCES;
1414 }
1415
1416 NET_LIST_FOR_EACH (Entry, &MnpServiceData->GroupAddressList) {
1417 //
1418 // Check whether the MacAddress is already joined by other instances.
1419 //
1420 GroupAddress = NET_LIST_USER_STRUCT (Entry, MNP_GROUP_ADDRESS, AddrEntry);
1421 if (0 == CompareMem (
1422 MacAddress,
1423 &GroupAddress->Address,
1424 SnpMode->HwAddressSize
1425 )) {
1426
1427 AddressExist = TRUE;
1428 break;
1429 }
1430 }
1431
1432 if (!AddressExist) {
1433 GroupAddress = NULL;
1434 }
1435
1436 //
1437 // Add the GroupAddress for this instance.
1438 //
1439 Status = MnpGroupOpAddCtrlBlk (
1440 Instance,
1441 NewCtrlBlk,
1442 GroupAddress,
1443 MacAddress,
1444 SnpMode->HwAddressSize
1445 );
1446 if (EFI_ERROR (Status)) {
1447
1448 return Status;
1449 }
1450
1451 NeedUpdate = TRUE;
1452 } else {
1453
1454 if (MacAddress != NULL) {
1455
1456 ASSERT (CtrlBlk != NULL);
1457
1458 //
1459 // Leave the specific multicast mac address.
1460 //
1461 NeedUpdate = MnpGroupOpDelCtrlBlk (Instance, CtrlBlk);
1462 } else {
1463 //
1464 // Leave all multicast mac addresses.
1465 //
1466 NeedUpdate = FALSE;
1467
1468 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Instance->GroupCtrlBlkList) {
1469
1470 NewCtrlBlk = NET_LIST_USER_STRUCT (
1471 Entry,
1472 MNP_GROUP_CONTROL_BLOCK,
1473 CtrlBlkEntry
1474 );
1475 //
1476 // Update is required if the group address left is no longer used
1477 // by other instances.
1478 //
1479 NeedUpdate = MnpGroupOpDelCtrlBlk (Instance, NewCtrlBlk);
1480 }
1481 }
1482 }
1483
1484 Status = EFI_SUCCESS;
1485
1486 if (NeedUpdate) {
1487 //
1488 // Reconfigure the receive filters if necessary.
1489 //
1490 Status = MnpConfigReceiveFilters (MnpServiceData);
1491 }
1492
1493 return Status;
1494 }